• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[JASS] *sigh* leaky spell..

Status
Not open for further replies.
Level 7
Joined
Oct 14, 2008
Messages
340
I can't find what's leaking here, but it's pretty bad, after about 20-30 casts, my fps drops to like 15.. BTW i know it is not MUI..

basically he chucks an axe forward and it damages and slows the first enemy it comes in contact with.

JASS:
function Trig_VengefulAxe_cast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A01J'
endfunction

function isTarget takes nothing returns boolean
    return ( GetUnitLifePercent(GetFilterUnit()) > 0 ) and ( IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(udg_Axe_unit)) ) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

function MoveAxe takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit axe = udg_Axe_unit
    local unit caster = udg_Avenger
    local location l = GetUnitLoc(axe)
    local location b
    local unit target
    local unit dummy = udg_Axedummy
    local real a = udg_Axe_angle
    local group g = GetUnitsInRangeOfLocMatching(70.0, l, Condition(function isTarget))
    local real dmg = 50 + 50*GetUnitAbilityLevel(caster, 'A01J')
    if FirstOfGroup(g) == null then
        set b = PolarProjectionBJ(l, 8, a)
        call SetUnitPositionLoc(axe, b)
        call RemoveLocation(b)
        call RemoveLocation(l)
        call DestroyGroup(g)
        set b = null
        set l = null
        set g = null
        set t = null
        set axe = null
        set caster = null
        set target = null
        set dummy = null
    else
        set target = FirstOfGroup(g)
        call RemoveUnit(axe)
        call UnitDamageTarget(udg_Avenger, target, dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLifeBJ( 1.0, 'BTLF', dummy )
        call RemoveLocation(b)
        call RemoveLocation(l)
        call DestroyGroup(g)
        call PauseTimer(t)
        call DestroyTimer(t)
        set b = null
        set l = null
        set g = null
        set t = null
        set axe = null
        set caster = null
        set target = null
        set dummy = null
    endif
endfunction

function Trig_VengefulAxe_cast_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local location l = GetUnitLoc(caster)
    local location m = GetSpellTargetLoc()
    local real a = AngleBetweenPoints(l, m)
    local location b = PolarProjectionBJ( l, 35, a)
    local integer Pid = GetPlayerId(GetOwningPlayer(caster))
    local real x = GetLocationX(b)
    local real y = GetLocationY(b)
    local unit axe = CreateUnit(Player(Pid), 'n00G', x, y, a)
    local timer t = CreateTimer()
    set udg_Axedummy = CreateUnitAtLoc(Player(Pid), 'hpea', l, a)
    call UnitAddAbility(udg_Axedummy, 'A07Y')
    set udg_Axe_angle = a
    set udg_Axe_unit = axe
    call TimerStart(t, .01, true, function MoveAxe)
    call RemoveLocation(l)
    call RemoveLocation(b)
    call RemoveLocation(m)
    set l = null
    set b = null
    set m = null
    call TriggerSleepAction(1.4)
    call DestroyTimer(t)
    set t = null
    call RemoveUnit(axe)
    call RemoveUnit(udg_Axedummy)
endfunction

//===========================================================================
function InitTrig_VengefulAxe_cast takes nothing returns nothing
    set gg_trg_VengefulAxe_cast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_VengefulAxe_cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_VengefulAxe_cast, Condition( function Trig_VengefulAxe_cast_Conditions ) )
    call TriggerAddAction( gg_trg_VengefulAxe_cast, function Trig_VengefulAxe_cast_Actions )
endfunction
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Avoid using locations where possiable and use X/Y, this prevents leaks and improves spell speed drastically.
null all local handles at the end of a function, although this is not always needed, it certainly prevents handle index leaks which seem to be present in your function (you do it to same local handles but not all.
Avoid using BJs as some leak and almost all are slower than just using the natives they use.
Avoid running timers at 0.01 delay, that means they fire 100 times a second which is a great load on ones computer and most monitors can not even update that fast (let alone humans see that). 0.016 seconds is a good delay if you want it to update every frame if the frame rate is maxed on most PCs. However for demanding opperations, I would recommend 0.03 to 0.05 delay for the timer as that is a lot less opperations per second and so saves a lot of computational power and is almost not at all visable to the players.
TriggerSleepAction is inaccurate in multiplayer, so a 1.4 delay in multiplayer can be 3-4 seconds.

After you have done the above, the code should already lag less, and from then you should aim to optimize it which should remove any remaining lag it causes (FPS reduction).
 
Level 7
Joined
Oct 14, 2008
Messages
340
thanks for the tip, I'll reduce the rate the timer fires at, which handle leaks am i not clearing?

I thought i got them all?
 
Level 7
Joined
Jul 20, 2008
Messages
377
Do as Super Good says and stop using locations. Trust me on this.

PolarProjectionBJ is a really bad function to use too.
 
Status
Not open for further replies.
Top