HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

GUI vs. jass approaches, limited AoE buff

01-06-2005, 12:00 AM#1
Panto
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 = null
Code:
//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
PitzerMike
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
Panto
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!