HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Is there any way to speed this up?

02-05-2007, 10:00 AM#1
NmdSnprEnigma
Both these run whenever any unit takes damage, they work, that's not the problem. It's that if there are too many units in the splash radius, the game hangs for a bit with every shot. This second trigger is conditioned so that it only runs when the damage source has a certain item. And this doesn't pose a problem when the damage source doesn't have 'A00G'. When it does though, especially if the unit has a bouncing attacking, the game comes to a screeching halt. Is there a way to speed up the splash ? and is there something in the Caster System that would allow me to dedicate some casters to a specific job or would I have to work that in on my own? Thanks guys.

PS - I know some of the swapped's and BJs can go, but unless those are the problem, i'll get them later.


Collapse JASS:
function Trig_Splash_Damage_Conditions takes nothing returns boolean
    return IsTriggerEnabled(GetTriggeringTrigger()) and GetUnitAbilityLevelSwapped('A00G', GetEventDamageSource()) != 0 
endfunction

function SplashFilter takes nothing returns boolean
    return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetEventDamageSource())) and GetFilterUnit() != GetTriggerUnit()
endfunction

function SplashDamage takes nothing returns nothing
    local real dmg = GetEventDamage() * 0.10 * I2R(GetUnitAbilityLevelSwapped('A00G', GetEventDamageSource()))    
    call UnitDamageTargetBJ( GetEventDamageSource(), GetEnumUnit(), dmg , ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
endfunction

function Trig_Splash_Damage_Actions takes nothing returns nothing
    local group g = GetUnitsInRangeOfLocMatching(200,GetUnitLoc(GetTriggerUnit()),Condition(function SplashFilter))
     
    call DisableTrigger( GetTriggeringTrigger() )
    call ForGroupBJ( g, function SplashDamage )
    call EnableTrigger( GetTriggeringTrigger() )

    call DestroyGroup(g)
    set g = null
endfunction

//===========================================================================
function InitTrig_Splash_Damage takes nothing returns nothing
    set gg_trg_Splash_Damage = CreateTrigger(  )
    call TriggerAddCondition( gg_trg_Splash_Damage, Condition( function Trig_Splash_Damage_Conditions ) )
    call TriggerAddAction( gg_trg_Splash_Damage, function Trig_Splash_Damage_Actions )
endfunction

Collapse JASS:
function Trig_Splash_Frost_Actions takes nothing returns nothing
    call CasterCastAbilityLevel(GetOwningPlayer(GetEventDamageSource()),'A01K',GetUnitAbilityLevelSwapped('A00Y',GetEventDamageSource()),"shadowstrike",GetTriggerUnit(),true)
endfunction
02-05-2007, 10:24 AM#2
Mythic Fr0st
Does this not leak?


Trigger:
local group g = GetUnitsInRangeOfLocMatching(200,GetUnitLoc(GetTriggerUnit()),Condition(function SplashFilter))

shouldnt it be

Trigger:
local location Loc = GetUnitLoc(GetTriggerUnit())

GetUnitsInRangeOfLocMatching(200,Loc,Condition(function SplashFilter))

if it does leak, then mass units, will cause problems

make sure you add

call RemoveLocation(Loc)
set Loc = null

after aswell
02-05-2007, 03:04 PM#3
The)TideHunter(
Yes, GetUnitLoc in a function call will leak, assign it to a variable and clean it up later.
02-05-2007, 03:16 PM#4
wyrmlord
I believe you're also leaking a boolexpr. Condition takes a function and returns a conditionfunc, which is an extension of boolexpr. Here's how you'd fix that:
Collapse JASS:
local boolexpr condition = Condition(function myfunction)
// Put code here using the boolexpr
call DestroyBoolExpr(condition)
02-05-2007, 03:35 PM#5
rain9441
GetUnitsInRange leaks period.

Use GroupEnumUnitsInRangeOfLoc instead, and use a global group variable for the group.

Create the group on map init, don't destroy it.
Collapse JASS:
globals
    group SplashDamageGroup
    boolexpr SplashFilter
    real SplashDamageDamage
    unit SplashDamageSource
endglobals


function SplashDamage takes nothing returns nothing
    // no need to recalculate damage  
    // minimize function calls, reuse SplashDamageSource
    call UnitDamageTargetBJ( SplashDamageSource, GetEnumUnit(), SplashDamageDamage, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
endfunction

function Trig_Splash_Damage_Actions takes nothing returns nothing
    local location loc = GetUnitLoc(GetTriggerUnit())
    call GroupClear(SplashDamageGroup) // just in case
    call GroupEnumUnitsInRangeOfLoc(SplashDamageGroup, loc, 200.0, SplashDamageFilter) // no leakage
    call RemoveLocation(loc)
    set loc = null

    set SplashDamageSource = GetEventDamageSource()
    set SplashDamageDamage = 0.10 * GetEventDamage() * I2R(GetUnitAbilityLevelSwapped('A00G', SplashDamageSource)) // doesnt change per unit, so why calcluate it per unit?

    call DisableTrigger( GetTriggeringTrigger() )
    call ForGroup( SplashDamageGroup, function SplashDamage )
    call EnableTrigger( GetTriggeringTrigger() )

endfunction

function InitTrig_Splash_Damage takes nothing returns nothing
    set gg_trg_Splash_Damage = CreateTrigger(  )
    set SplashDamageGroup = CreateGroup() // init
    set SplashDamageFilter = Condition(function SplashFilter) // init

    call TriggerAddCondition( gg_trg_Splash_Damage, Condition( function Trig_Splash_Damage_Conditions ) )
    call TriggerAddAction( gg_trg_Splash_Damage, function Trig_Splash_Damage_Actions )
endfunction
Theres no threat of MUI problems because thread execution will never be interrupted until all your work is complete. I didn't test this, but the basic idea is to move everything you can out of the ForGroup and place it in global variables. You were recalculating the same value N times when you only needed to do it once.

This should significantly reduce leakage over time and lag on impact.
02-09-2007, 10:01 AM#6
NmdSnprEnigma
Thanks, also found out if the damage source had an innate splash attack, each unit in the natural splash radius would be splashing every unit within 200 of it so 10 guys in the innate radius would be looping 10^2 damage iterations instead of just 10. Fixed that up, too.
02-09-2007, 02:45 PM#7
Feroc1ty
i didnt test it but cleaned everything.

Collapse JASS:
function Trig_Splash_Damage_Conditions takes nothing returns boolean
    return IsTriggerEnabled(GetTriggeringTrigger()) and GetUnitAbilityLevel( GetEventDamageSource() ,'A00G' ) != 0 
endfunction

function SplashFilter takes nothing returns boolean
    return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetEventDamageSource())) and GetFilterUnit() != GetTriggerUnit()
endfunction

function SplashDamage takes nothing returns nothing
    local real dmg = GetEventDamage() * 0.10 * I2R(GetUnitAbilityLevel( GetEventDamageSource() ,'A00G' ))    
    call UnitDamageTarget( GetEventDamageSource(), GetEnumUnit(), dmg , true , false , ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS )
endfunction

function Trig_Splash_Damage_Actions takes nothing returns nothing
    local group g = CreateGroup()
    set g = GroupEnumUnitsInRangeOfLoc(g, etUnitLoc(GetTriggerUnit()), 200, Condition(function SplashFilter)) 

    call DisableTrigger( GetTriggeringTrigger() )
    call ForGroupBJ( g, function SplashDamage )
    call EnableTrigger( GetTriggeringTrigger() )

    call DestroyGroup(g)
    set g = null
endfunction
02-09-2007, 03:28 PM#8
Anitarf
rain9441's suggestion seems best, however, it still has the cost of allocating memory for a new handle (the location), which can be avoided by using GroupEnumUnitsInRange in combination with GetUnitX and GetUnitY.
02-09-2007, 05:12 PM#9
Vexorian
Bad:

Collapse JASS:
function Trig_Splash_Damage_Actions takes nothing returns nothing
    local group g = CreateGroup()
    set g = GroupEnumUnitsInRangeOfLoc(g, etUnitLoc(GetTriggerUnit()), 200, Condition(function SplashFilter)) 

    call DisableTrigger( GetTriggeringTrigger() )
    call ForGroupBJ( g, function SplashDamage )
    call EnableTrigger( GetTriggeringTrigger() )

    call DestroyGroup(g)
    set g = null
endfunction

good:

Collapse JASS:
globals
     group enumgroup = CreateGroup()
     boolexpr bexSplashFilter
endglobals

function Trig_Splash_Damage_Actions takes nothing returns nothing
    call ClearGroup(enumgroup)
    call GroupEnumUnitsInRange(enumgrouo, GetUnitX(GetTriggerUnit()) , GetUnitY(GetTriggerUnit()), 200, bexSplashFilter) 

    call DisableTrigger( GetTriggeringTrigger() )
    call ForGroup( enumgroup, function SplashDamage )
    call EnableTrigger( GetTriggeringTrigger() )

endfunction

function init takes nothing returns nothing
  set bexSplashFilter = Condition(function SplashFilter)
endfunction