HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

A few questions.

02-29-2008, 04:43 PM#1
Gwypaas
First question:
How do I make so this part doesn't try to divide by zero if the string length is something else then 6?
Collapse JASS:
local real r1b
local real r2b
local real r3b        
set r1b = S2R(SubString(GetEventPlayerChatString(), 0,2))
set r2b = S2R(SubString(GetEventPlayerChatString(), 2,4))
set r3b = S2R(SubString(GetEventPlayerChatString(), 4,6))

Second question:
Why does this crash WE on startup? This is a basic Jump spell that I use in my map.
Collapse JASS:
scope JumpSpell
globals
    private constant integer SPELLID = 'A002'
    private constant integer SPEED = 30
    private constant integer CROWFORMID = 'Amrf'
    private constant integer DUMMYID = 'h002'
endglobals

// HSAS functions used:
//! runtextmacro HSAS_Static("1")
// End HSAS

private struct JumpStruct
    unit caster
    player castp
    real xt
    real yt
    real a
    real xc
    real yc
    real disttotal
    real facing
    real distdone = 0
    timer t = CreateTimer()
    static method Create takes unit castingunit, real targetx, real targety returns JumpStruct
        local JumpStruct j = JumpStruct.allocate()
        set j.xt = targetx
        set j.yt = targety
        set j.caster = castingunit
        set j.castp = GetOwningPlayer(j.caster)
        return j
    endmethod
endstruct



private function Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local JumpStruct j = GetAttachedStruct1(t)
    local real height = ParabolicMovement(j.disttotal, j.disttotal, j.distdone)
    local unit Dummy 
    local real x
    local real y
    set j.xc = j.xc+SPEED*Cos(j.a)
    set j.yc = j.yc+SPEED*Sin(j.a)
    
    if j.distdone >= j.disttotal then
        set x = GetUnitX(j.caster)
        set y = GetUnitY(j.caster)
        
        call SetUnitFlyHeight(j.caster, 0, 0)
        
        call DestroyTimer(j.t)
        call DestroyTimer(t)
        set t = null
        set j.t = null
        
        set Dummy = CreateUnit(j.castp, DUMMYID, x, y, j.facing)
        call UnitApplyTimedLife( Dummy, 'BTLF', 3 )
        
        call TriggerSleepAction(3)
        call RemoveUnit(Dummy)
        set Dummy = null
        set j.caster = null
        set j.castp = null
        call j.destroy()
    else
        call SetUnitFlyHeight(j.caster, height, 0)
        call SetUnitX(j.caster, j.xc)
        call SetUnitY(j.caster, j.yc)
        set j.distdone = j.distdone+SPEED
    endif
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELLID
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local location l = GetSpellTargetLoc()
    local real tarx = GetLocationX(l)
    local real tary = GetLocationY(l)
    local real castx = GetUnitX(u)
    local real casty = GetUnitY(u)
    local real tmp1
    local real tmp2
    local JumpStruct j = JumpStruct.Create(u, tarx, tary)
    call RemoveLocation(l)
    set l = null
    set tmp1 = j.xt-castx
    set tmp2 = j.yt-casty
    set j.xc = castx
    set j.yc = casty
    set j.disttotal = SquareRoot(tmp1*tmp1+tmp2*tmp2)
    set j.a = Atan2(tary - casty, tarx - castx)
    set j.facing = GetUnitFacing(j.caster)
    call UnitAddAbility(j.caster, CROWFORMID)
    call UnitRemoveAbility(j.caster, CROWFORMID)
    //call BJDebugMsg("Jump Length:"+ R2S(j.disttotal))
    call AttachStruct1(j.t, j)
    call TimerStart(j.t, 0.02, true, function Move)
    set u = null
endfunction


public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local integer i = 0
    local player p
    loop
        exitwhen i >=9
        call TriggerRegisterPlayerUnitEvent(Trig, p, EVENT_PLAYER_UNIT_SPELL_CAST, null)
        
        set i = i+1
        set p = Player(i)
    endloop
    call TriggerAddCondition( Trig, Condition( function Conditions ) )
    call TriggerAddAction( Trig, function Actions )
endfunction

endscope

And the last question:
Why does that script leak 2 handles? I know it's something about the event but I can't find out a way making it leakless.
Collapse JASS:
scope MoveBackIn
private function MoveBackInR1 takes nothing returns nothing
    local integer i = 0
    local rect Spawn = gg_rct_SpawnPlace1
    local real x = GetRandomReal(GetRectMinX(Spawn), GetRectMaxX(Spawn))
    local real y = GetRandomReal(GetRectMinY(Spawn), GetRectMaxY(Spawn))
    local region r = CreateRegion()
    call RegionAddRect(r, Spawn)

    loop
        exitwhen (i >= 4)
        if IsUnitInRegion(r, runners[i]) == false then
            call SetUnitX(runners[i], x)
            call SetUnitY(runners[i], y)
        endif
        set i = i+1
    endloop

    call RemoveRegion(r)
    call RemoveRect(Spawn)
endfunction

private function MoveBackInR2 takes nothing returns nothing
    local integer i = 5
    local rect Spawn = gg_rct_SpawnPlace2
    local real x = GetRandomReal(GetRectMinX(Spawn), GetRectMaxX(Spawn))
    local real y = GetRandomReal(GetRectMinY(Spawn), GetRectMaxY(Spawn))
    local region r = CreateRegion()
    call RegionAddRect(r, Spawn)
    loop
        exitwhen (i >= 9)
        if IsUnitInRegion(r, runners[i]) == false then
            call SetUnitX(runners[i], x)
            call SetUnitY(runners[i], y)
        endif
        set i = i+1
    endloop
    call RemoveRegion(r)
    call RemoveRect(Spawn)
endfunction



public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local trigger Trig2 = CreateTrigger()
    local trigger Trig3 = CreateTrigger()
    local region r = CreateRegion()
    local region r2 = CreateRegion()
    call RegionAddRect(r, gg_rct_SpawnPlace1)
    call RegionAddRect(r2, gg_rct_SpawnPlace2)
    
    call TriggerRegisterLeaveRegion( Trig, r, null )
    call TriggerRegisterLeaveRegion( Trig2, r2, null )
    call TriggerAddAction( Trig, function MoveBackInR1 )
    call TriggerAddAction( Trig2, function MoveBackInR2)

endfunction

endscope
02-29-2008, 08:34 PM#2
XieLong
Quote:
Originally Posted by Gwypaas
First question:
How do I make so this part doesn't try to divide by zero if the string length is something else then 6?
Collapse JASS:
local real r1b
local real r2b
local real r3b        
set r1b = S2R(SubString(GetEventPlayerChatString(), 0,2))
set r2b = S2R(SubString(GetEventPlayerChatString(), 2,4))
set r3b = S2R(SubString(GetEventPlayerChatString(), 4,6))

Umh, there's no division? And no devision = no divide by zero error... If the string is shorter than 6 it will every missing character take as '0', but that has nothing to do with division?

Quote:
Originally Posted by Gwypaas
Second question:
Why does this crash WE on startup? This is a basic Jump spell that I use in my map.
Collapse JASS:
scope JumpSpell
globals
    private constant integer SPELLID = 'A002'
    private constant integer SPEED = 30
    private constant integer CROWFORMID = 'Amrf'
    private constant integer DUMMYID = 'h002'
endglobals

// HSAS functions used:
//! runtextmacro HSAS_Static("1")
// End HSAS

private struct JumpStruct
    unit caster
    player castp
    real xt
    real yt
    real a
    real xc
    real yc
    real disttotal
    real facing
    real distdone = 0
    timer t = CreateTimer()
    static method Create takes unit castingunit, real targetx, real targety returns JumpStruct
        local JumpStruct j = JumpStruct.allocate()
        set j.xt = targetx
        set j.yt = targety
        set j.caster = castingunit
        set j.castp = GetOwningPlayer(j.caster)
        return j
    endmethod
endstruct



private function Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local JumpStruct j = GetAttachedStruct1(t)
    local real height = ParabolicMovement(j.disttotal, j.disttotal, j.distdone)
    local unit Dummy 
    local real x
    local real y
    set j.xc = j.xc+SPEED*Cos(j.a)
    set j.yc = j.yc+SPEED*Sin(j.a)
    
    if j.distdone >= j.disttotal then
        set x = GetUnitX(j.caster)
        set y = GetUnitY(j.caster)
        
        call SetUnitFlyHeight(j.caster, 0, 0)
        
        call DestroyTimer(j.t)
        call DestroyTimer(t)
        set t = null
        set j.t = null
        
        set Dummy = CreateUnit(j.castp, DUMMYID, x, y, j.facing)
        call UnitApplyTimedLife( Dummy, 'BTLF', 3 )
        
        call TriggerSleepAction(3)
        call RemoveUnit(Dummy)
        set Dummy = null
        set j.caster = null
        set j.castp = null
        call j.destroy()
    else
        call SetUnitFlyHeight(j.caster, height, 0)
        call SetUnitX(j.caster, j.xc)
        call SetUnitY(j.caster, j.yc)
        set j.distdone = j.distdone+SPEED
    endif
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELLID
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local location l = GetSpellTargetLoc()
    local real tarx = GetLocationX(l)
    local real tary = GetLocationY(l)
    local real castx = GetUnitX(u)
    local real casty = GetUnitY(u)
    local real tmp1
    local real tmp2
    local JumpStruct j = JumpStruct.Create(u, tarx, tary)
    call RemoveLocation(l)
    set l = null
    set tmp1 = j.xt-castx
    set tmp2 = j.yt-casty
    set j.xc = castx
    set j.yc = casty
    set j.disttotal = SquareRoot(tmp1*tmp1+tmp2*tmp2)
    set j.a = Atan2(tary - casty, tarx - castx)
    set j.facing = GetUnitFacing(j.caster)
    call UnitAddAbility(j.caster, CROWFORMID)
    call UnitRemoveAbility(j.caster, CROWFORMID)
    //call BJDebugMsg("Jump Length:"+ R2S(j.disttotal))
    call AttachStruct1(j.t, j)
    call TimerStart(j.t, 0.02, true, function Move)
    set u = null
endfunction


public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local integer i = 0
    local player p
    loop
        exitwhen i >=9
        call TriggerRegisterPlayerUnitEvent(Trig, p, EVENT_PLAYER_UNIT_SPELL_CAST, null)
        
        set i = i+1
        set p = Player(i)
    endloop
    call TriggerAddCondition( Trig, Condition( function Conditions ) )
    call TriggerAddAction( Trig, function Actions )
endfunction

endscope
Collapse JASS:
public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local integer i = 0
    local player p
    loop
        exitwhen i >=9
        call TriggerRegisterPlayerUnitEvent(Trig, p, EVENT_PLAYER_UNIT_SPELL_CAST, null)
        
        set i = i+1
        set p = Player(i)
    endloop
    call TriggerAddCondition( Trig, Condition( function Conditions ) )
    call TriggerAddAction( Trig, function Actions )
endfunction
Within this init-function you will call an uninited player variable... you should do it this way:
Collapse JASS:
public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local integer i = 0
    loop

        call TriggerRegisterPlayerUnitEvent(Trig, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
        
        set i = i+1
        exitwhen i == 9
    endloop
    call TriggerAddCondition( Trig, Condition( function Conditions ) )
    call TriggerAddAction( Trig, function Actions )
endfunction

Quote:
Originally Posted by Gwypaas
And the last question:
Why does that script leak 2 handles? I know it's something about the event but I can't find out a way making it leakless.
Collapse JASS:
scope MoveBackIn
private function MoveBackInR1 takes nothing returns nothing
    local integer i = 0
    local rect Spawn = gg_rct_SpawnPlace1
    local real x = GetRandomReal(GetRectMinX(Spawn), GetRectMaxX(Spawn))
    local real y = GetRandomReal(GetRectMinY(Spawn), GetRectMaxY(Spawn))
    local region r = CreateRegion()
    call RegionAddRect(r, Spawn)

    loop
        exitwhen (i >= 4)
        if IsUnitInRegion(r, runners[i]) == false then
            call SetUnitX(runners[i], x)
            call SetUnitY(runners[i], y)
        endif
        set i = i+1
    endloop

    call RemoveRegion(r)
    call RemoveRect(Spawn)
endfunction

private function MoveBackInR2 takes nothing returns nothing
    local integer i = 5
    local rect Spawn = gg_rct_SpawnPlace2
    local real x = GetRandomReal(GetRectMinX(Spawn), GetRectMaxX(Spawn))
    local real y = GetRandomReal(GetRectMinY(Spawn), GetRectMaxY(Spawn))
    local region r = CreateRegion()
    call RegionAddRect(r, Spawn)
    loop
        exitwhen (i >= 9)
        if IsUnitInRegion(r, runners[i]) == false then
            call SetUnitX(runners[i], x)
            call SetUnitY(runners[i], y)
        endif
        set i = i+1
    endloop
    call RemoveRegion(r)
    call RemoveRect(Spawn)
endfunction



public function InitTrig takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local trigger Trig2 = CreateTrigger()
    local trigger Trig3 = CreateTrigger()
    local region r = CreateRegion()
    local region r2 = CreateRegion()
    call RegionAddRect(r, gg_rct_SpawnPlace1)
    call RegionAddRect(r2, gg_rct_SpawnPlace2)
    
    call TriggerRegisterLeaveRegion( Trig, r, null )
    call TriggerRegisterLeaveRegion( Trig2, r2, null )
    call TriggerAddAction( Trig, function MoveBackInR1 )
    call TriggerAddAction( Trig2, function MoveBackInR2)

endfunction

endscope
This function does not really leak to handles. But the 2 regions are never destroyed; but this is correct cause otherwise the trigger would never run.
But you should null the used handle variables...
Collapse JASS:
    set Trig = null
    set Trig1 = null
    set Trig2 = null
    set r = null
    set r2 = null
at the end of the function.
03-01-2008, 12:47 AM#3
Pyrogasm
Technically speaking, XieLong, he doesn't even have to null those as they are (for all practical purposes) references to global objects.

And those don't need to be nulled.