| 02-05-2007, 10:00 AM | #1 |
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. 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 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 |
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 |
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 |
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: JASS:local boolexpr condition = Condition(function myfunction) // Put code here using the boolexpr call DestroyBoolExpr(condition) |
| 02-05-2007, 03:35 PM | #5 |
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. 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 This should significantly reduce leakage over time and lag on impact. |
| 02-09-2007, 10:01 AM | #6 |
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 |
i didnt test it but cleaned everything. 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 |
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 |
Bad: 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: 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 |
