HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Leak Check

10-21-2008, 12:31 AM#1
WNxCryptic
How does this spell look? I made it for the spell contest, but I like to make sure that my stuff doesn't leak before calling it 'done' :)

Collapse JASS:
library TransferSoul initializer init requires xecast, xecollider, TimerUtils
    //==================================================================================
    // Config:
    //
    globals
        private constant integer SPELL_ID = 'A000' //The triggerer spell id
        private constant integer CAST_ABILITY_ID = 'A001' //Spell for dummy cast
        private xecast cast
    endglobals
    
    // struct to hold local handles of a particular instantiation of trigger
    public struct inst
        unit tar
        unit caster
    endstruct
    
    // Missile Struct
    private struct Soul extends xecollider 
        unit castingHero
        integer level 

        method onUnitHit takes unit hitunit returns nothing
            // verify we're colliding with the target unit
            if (this.targetUnit == hitunit ) then
                // Add death coil special effect on the target (victim) of spell
                call DestroyEffect( AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl",this.castingHero, "origin") ) 
                
                call this.terminate()
            endif
        endmethod
    endstruct

    //==================================================================================
    // Code
    //    
    private function spawnMissile takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local inst i = GetTimerData(t)
        local Soul s
        local real x
        local real y
        local xecast xc = xecast.createA()
        set cast.owningplayer = GetOwningPlayer(i.caster)
        set xc.level = GetUnitAbilityLevel(i.caster, SPELL_ID )
        
        // if we're still channeling, go forth and create missiles!
        if GetUnitCurrentOrder(i.caster) == OrderId("blizzard") then
            call cast.castOnTarget(i.tar)
            
            set x = GetUnitX(i.tar)
            set y = GetUnitY(i.tar)
            set s = Soul.create( x, y, GetRandomReal(0, 2*bj_PI))
            set s.fxpath = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
            set s.speed = 100.0
            set s.acceleration = 100.0
            set s.maxSpeed = 500.0
            set s.z = GetRandomReal(100.0, 300.0)
            set s.angleSpeed = 1.0
            set s.targetUnit = i.caster
            set s.expirationTime = 6
            set s.castingHero = i.tar 
            set s.level = GetUnitAbilityLevel(i.caster, SPELL_ID)
      
            call TriggerSleepAction(0.0)
            call SetUnitAnimation(i.caster, "attack")
        endif
    set t = null
    endfunction
    
    private function onSpellEffect takes nothing returns nothing
        local inst i = inst.create()
        local timer t
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl", i.tar, "origin"))
        
        set i.tar = GetSpellTargetUnit()
        set i.caster = GetTriggerUnit()
        
        set t = NewTimer()
        call SetTimerData(t, i)
        call TimerStart(t, .5, true, function spawnMissile)
        
        set t=null
    endfunction
    //==================================================================================
    // Init/Conditions
    //
    private function spellIdMatch takes nothing returns boolean
      return (GetSpellAbilityId() == SPELL_ID)
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t=CreateTrigger()
            //preload ability
            call XE_PreloadAbility(CAST_ABILITY_ID)
            set cast = xecast.create()
            set cast.abilityid = CAST_ABILITY_ID
            set cast.orderid = OrderId("parasite")
            
            //Setting up the spell's trigger:
            call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CHANNEL)
            call TriggerAddCondition(t, Condition(function spellIdMatch))
            call TriggerAddAction(t, function onSpellEffect)
        set t=null
    endfunction
endlibrary
10-21-2008, 12:58 AM#2
Joker
You don't need to null timers if your using TimerUtils/CSSafety.
10-21-2008, 01:30 AM#3
Zerzax
Yeah, since the timers are global. Instead of declaring the variable outright in your timer function, try "local inst i=GetTimerData(GetExpiredTimer())" since I don't think you use your "t" variable anywhere else. This is being unnecessarily picky, but you dont need both a condition and action for your spell in the init.
Instead of
Collapse JASS:
private function spellIdMatch takes nothing returns boolean
      return (GetSpellAbilityId() == SPELL_ID)
endfunction
// inside the init
            call TriggerAddCondition(t, Condition(function spellIdMatch))
            call TriggerAddAction(t, function onSpellEffect)

You can try this, it will create one less handle:
Collapse JASS:
// inside the init
call TriggerAddCondition(t, Condition(function onSpellEffect))


private function onSpellEffect takes nothing returns boolean
        local inst i
        local timer t
        if GetSpellAbilityId()==SPELL_ID then
            set i=inst.create()
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl", i.tar, "origin"))
        
            set i.tar = GetSpellTargetUnit()
            set i.caster = GetTriggerUnit()
        
            set t = NewTimer()
            call SetTimerData(t, i)
            call TimerStart(t, .5, true, function spawnMissile)
        endif
    return false
endfunction

10-21-2008, 11:52 PM#4
Bobo_The_Kodo
WHO CARES ABOUT ONE HANDLE WHEN ITS NOT DYNAMIC?

srry... it needed to be said
10-22-2008, 12:10 AM#5
WNxCryptic
Not using CSSafety, so I nulled the timer just in case.

Still unnecessary?
10-22-2008, 12:42 AM#6
Zerzax
Lol Bobo I did warn him it was overdose in the post...

TimerUtils is an updated CSSafety as well as attachment through hashing.... you still don't need to null the timers.