| 01-06-2005, 12:00 AM | #1 |
Greetings. I attempted to make a non-leaky jass trigger to make a spell that would cast a buff on enemy units within a radius, but only up to a certain number of total buffs. My jass trigger failed remarkably... sometimes it would pick friends, sometimes it would do too many more or less buffs, sometimes it wouldn't seem to be doing anything. Then I remade it briefly in a fairly leaky GUI trigger, and it works fine. I'm sure that the problem lies somewhere in the differences between the two approaches, including possibly using a FirstOfGroup-based loop instead of Pick Every Unit. I'ma posting both the triggers. The GUI one works, the jass one doesn't. My goal is to have a fully-functional leakless trigger, either way. Code:
Ambush AoE casters GUI
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Ambush (Conquistadora Pseudo)
Actions
Custom script: local location udg_locDummy
Set playerAmbush = (Owner of (Casting unit))
Set intCasterIncrement = 1
Set intAmbushMax = intArAmbushTargets[(Level of Ambush (Conquistadora Pseudo) for (Casting unit))]
Set locDummy = (Target point of ability being cast)
Unit - Create 1 Caster (Ambush) for (Owner of (Casting unit)) at locDummy facing Default building facing degrees
Set unitCaster = (Last created unit)
Unit Group - Pick every unit in (Units within realArAmbushRange[(Level of Ambush (Conquistadora Pseudo) for (Casting unit))] of locDummy) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Picked unit) is alive) Equal to True
((Picked unit) belongs to an ally of playerAmbush) Equal to False
((Picked unit) has buff Ambush (Conquistadora Air)) Equal to False
((Picked unit) has buff Ensnare (General)) Equal to False
((Picked unit) has buff Ambush (Conquistadora Ground)) Equal to False
intCasterIncrement Less than or equal to intAmbushMax
Then - Actions
Set intCasterIncrement = (intCasterIncrement + 1)
Unit - Order unitCaster to Orc Raider - Ensnare (Picked unit)
Else - Actions
Unit - Kill unitCaster
Unit - Remove unitCaster from the game
Set unitCaster = No unit
Custom script: call RemoveLocation(udg_locDummy)
Custom script: set udg_locDummy = nullCode:
//function Trig_Ambush_AoE_casters_Conditions takes nothing returns boolean
// if (not(GetSpellAbilityId() == 'ANfs')) then
// return false
// endif
// return true
//endfunction
function Trig_Ambush_AoE_casters_Actions takes nothing returns nothing
local location locCaster = GetUnitLoc(GetSpellAbilityUnit())
local location locTarget
local location locSpell = GetSpellTargetLoc()
local integer intLoop
local integer intTargetMax = udg_intArAmbushTargets[GetUnitAbilityLevelSwapped('ANfs', GetSpellAbilityUnit())]
local group groupInRange = GetUnitsInRangeOfLocAll(udg_realArAmbushRange[GetUnitAbilityLevelSwapped('ANfs', GetSpellAbilityUnit())], locSpell)
local group groupTargets = CreateGroup()
local group groupCasters = CreateGroup()
local unit unitPicker
if (GetSpellAbilityId() == 'ANfs') then
// debug
call ClearTextMessagesBJ(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())))
// call AddSpecialEffectLocBJ(locSpell, "Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl" )
call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, "Units in groupInRange: "+I2S(CountUnitsInGroup(groupInRange)))
// call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, "Range of spell: "+R2S(udg_realArAmbushRange[GetUnitAbilityLevelSwapped('ANfs',GetSpellAbilityUnit())]))
// evaluate nearby units for buffs and ownership
loop
set unitPicker = FirstOfGroup(groupInRange)
exitwhen unitPicker == null
if ((UnitHasBuffBJ(unitPicker, 'Bena') == false) and (UnitHasBuffBJ(unitPicker, 'Beng') == false) and (IsPlayerInForce(GetOwningPlayer(unitPicker), GetPlayersAllies(GetOwningPlayer(GetSpellAbilityUnit()))) == false) and (IsUnitType(unitPicker, UNIT_TYPE_MECHANICAL) == false) and (IsUnitDeadBJ(unitPicker) == false)) then
call GroupAddUnitSimple(unitPicker, groupTargets)
call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, ("Accepted: " + GetPlayerName(GetOwningPlayer(unitPicker)) +"'s "+ GetUnitName(unitPicker)))
endif
call GroupRemoveUnitSimple(unitPicker, groupInRange)
endloop
// more debug
call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, "Units in groupTargets: "+I2S(CountUnitsInGroup(groupTargets)))
call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, "udg_intArAmbushTargets: "+I2S(udg_intArAmbushTargets[GetUnitAbilityLevelSwapped('ANfs', GetSpellAbilityUnit())]))
// buff some units
set intLoop = 1
loop
set unitPicker = FirstOfGroup(groupTargets)
call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, ("Targeted: " + GetPlayerName(GetOwningPlayer(unitPicker)) +"'s " + GetUnitName(unitPicker)))
set locTarget = GetUnitLoc(unitPicker)
exitwhen (unitPicker == null) or (intLoop > intTargetMax)
call CreateNUnitsAtLocFacingLocBJ(1, 'nowl', GetOwningPlayer(GetSpellAbilityUnit()), locSpell, locTarget)
// call DisplayTimedTextToForce(GetForceOfPlayer(GetOwningPlayer(GetSpellAbilityUnit())), 30, ("Caster made: "+GetUnitName(bj_lastCreatedUnit)))
call IssueTargetOrderBJ(bj_lastCreatedUnit, "ensnare", unitPicker)
// call AddSpecialEffectTargetUnitBJ("overhead", unitPicker, "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl")
call GroupAddUnitSimple(bj_lastCreatedUnit, groupCasters)
call RemoveLocation(locTarget)
call GroupRemoveUnitSimple(unitPicker, groupTargets)
set intLoop = intLoop + 1
endloop
// give them time to cast
call PolledWait(1.00)
// cleanup
loop
set unitPicker = FirstOfGroup(groupCasters)
exitwhen unitPicker == null
call KillUnit(unitPicker)
call RemoveUnit(unitPicker)
call GroupRemoveUnitSimple(unitPicker, groupCasters)
endloop
endif
call RemoveLocation(locCaster)
call RemoveLocation(locSpell)
set locCaster = null
set locSpell = null
set locTarget = null
call DestroyGroup(groupInRange)
call DestroyGroup(groupTargets)
call DestroyGroup(groupCasters)
set groupInRange = null
set groupTargets = null
set groupCasters = null
endfunction
//===========================================================================
function InitTrig_Ambush_AoE_casters takes nothing returns nothing
set gg_trg_Ambush_AoE_casters = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(gg_trg_Ambush_AoE_casters, EVENT_PLAYER_UNIT_SPELL_EFFECT)
// call TriggerAddCondition(gg_trg_Ambush_AoE_casters, Condition(function Trig_Ambush_AoE_casters_Conditions))
call TriggerAddAction(gg_trg_Ambush_AoE_casters, function Trig_Ambush_AoE_casters_Actions)
endfunction
|
| 01-07-2005, 05:47 PM | #2 |
Ok, the GUI version doesn't look that bad. Simply convert it to jass and replace the leaking part (which would be the group used in ForGroupBJ) Assign this group to a local group variable before passing it to the ForGroup function, this way you can destroy the group afterwards. Also Better use ForGroup instead of ForGroupBJ. Other than that I don't see any major problems. You could of course improve your code in other parts, for example instead of using CreatUnitSaveLast (or whatever it's called) use CreateUnit from common.j and the unit returned, but that'd be only a be small improvement. |
| 01-07-2005, 06:32 PM | #3 |
Thanks. If I use a local group for the ForGroup, won't I be unable to use it inside that function? The function used in a ForGroup has to be declared ahead of time, and I can't use locals from the main function in it, then. Cubasis debugged the jass function... changing virtually nothing. But, as it always goes with Cubasis, his version works where mine didn't. Sigh. Thanks guys! ![]() |
