• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Why is it dangerous to destroy a 'boolexpr'?

Status
Not open for further replies.
Level 12
Joined
Sep 4, 2007
Messages
407
Someone told me that destroying a boolexpr is dangerous. Is it true? If it is, why is that? I have a trigger that only works if I destroy it.

It is this one:

JASS:
 function GUOfPM takes player whichPlayer, boolexpr filter returns group
    call GroupEnumUnitsOfPlayer(udg_GAME_PackG[5], whichPlayer, filter)
    call DestroyBoolExpr(filter)
    return udg_GAME_PackG[5]
endfunction

function Trig_SP_TA_Func001A takes nothing returns boolean
   return GetUnitAbilityLevel(GetFilterUnit(),'A00X') == bj_forLoopAIndex
endfunction

function Trig_SP_TA_Func001B takes nothing returns boolean
   return GetUnitAbilityLevel(GetFilterUnit(),'A00X') == bj_forLoopBIndex
endfunction

function Trig_SP_TA_Actions takes nothing returns nothing
    local unit newpackunit
    local group pack = udg_GAME_PackG[0]
    local group overpack = udg_GAME_PackG[1]
    local integer LoopC
    local integer xlvl
    local integer packcount
    local integer overcount
    local player packowner

    set LoopC = 1
    set bj_forLoopAIndex = 1
    set bj_forLoopBIndex = 1
    loop
        exitwhen LoopC > 12
        if (udg_CC_SocialBehavior[LoopC] == 3) then

                  loop
                      exitwhen bj_forLoopAIndex > 10
                      set packowner = Player(LoopC - 1)
                      set pack = GUOfPM(packowner, Condition(function Trig_SP_TA_Func001A))
                      set packcount = CountUnitsInGroup(pack)
                      if packcount < 5 and packcount != 0 then
                         set xlvl = bj_forLoopAIndex

                         loop
                             exitwhen bj_forLoopBIndex > 10
                             set overpack = GUOfPM(packowner, Condition(function Trig_SP_TA_Func001B))
                             set overcount = CountUnitsInGroup(overpack)
                             if overcount > 5 then
                                 set newpackunit = GroupPickRandomUnit(overpack)
                                 call SetUnitAbilityLevel( newpackunit,'A00X', xlvl )
                                 set pack = GUOfPM(packowner, Condition(function Trig_SP_TA_Func001A))
                                 set packcount = CountUnitsInGroup(pack)
                                 if packcount >= 5 then
                                     set bj_forLoopBIndex = 11                                    
                                 endif
                             else
                                 if overcount + packcount <= 5 then
                                 set newpackunit = GroupPickRandomUnit(overpack)
                                 call SetUnitAbilityLevel( newpackunit,'A00X', xlvl )
                                    if packcount >= 5 then
                                       set bj_forLoopBIndex = 11                                   
                                    endif
                                 endif
                             endif
                             set bj_forLoopBIndex = bj_forLoopBIndex + 1
                         endloop

                      endif
                      set bj_forLoopAIndex = bj_forLoopAIndex + 1
                  endloop  

        endif
        set LoopC = LoopC + 1
    endloop
    set udg_GAME_PackG[5] = null
    set newpackunit = null
    set packowner = null
    set pack = null
    set overpack = null
endfunction

//===========================================================================
function InitTrig_SP_TogetherAdjustment takes nothing returns nothing
    local trigger SP_TogetherAdjustment = CreateTrigger(  )
    set udg_GAME_PackG[0] = CreateGroup()
    set udg_GAME_PackG[1] = CreateGroup()
    set udg_GAME_PackG[5] = CreateGroup()
    call TriggerRegisterTimerEvent( SP_TogetherAdjustment, 0.20, true )
    call TriggerAddAction( SP_TogetherAdjustment, function Trig_SP_TA_Actions )
    set SP_TogetherAdjustment = null
endfunction

If I do not destroy the boolexpr 'filter', the trigger does not work. o_O
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
It's pointless to destroy it. Just do a null when it asks you for the condition. Replace the BJ "CountUnitsInGroup" with this function:

JASS:
function PickAndChoose takes group tg, integer whichIndex returns integer
    local integer i = 0
    local group g = tg
    local unit u
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if GetUnitAbilityLevel(u,'A00X') == whichIndex then
            set i = i + 1
        else
            call GroupRemoveUnit(tg,u)
        endif
    endloop
    call DestroyGroup(g)
    set g = null
    set u = null
    return i
endfunction

and call it likes this:

JASS:
set overcount = PickAndChoose(overpack,bj_forLoopAIndex)
// or 
set packcount = PickAndChoose(pack,bj_forLoopBIndex)
 
Level 12
Joined
Sep 4, 2007
Messages
407
It's pointless to destroy it. Just do a null when it asks you for the condition. Replace the BJ "CountUnitsInGroup" with this function:

JASS:
function PickAndChoose takes group tg, integer whichIndex returns integer
    local integer i = 0
    local group g = tg
    local unit u
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g,u)
        if GetUnitAbilityLevel(u,'A00X') == whichIndex then
            set i = i + 1
        else
            call GroupRemoveUnit(tg,u)
        endif
    endloop
    call DestroyGroup(g)
    set g = null
    set u = null
    return i
endfunction

and call it likes this:

JASS:
set overcount = PickAndChoose(overpack,bj_forLoopAIndex)
// or 
set packcount = PickAndChoose(pack,bj_forLoopBIndex)

gonna try it =)
 
Level 12
Joined
Sep 4, 2007
Messages
407
Remade the trigger using some principles learned here at The Hive.

JASS:
function Trig_SP_TA_Actions takes nothing returns nothing

//=============================================== Declaring Local Variables =====================================================================================================
    local unit newpackunit
    local group pack = udg_GAME_PackG[0]
    local group overpack = udg_GAME_PackG[1]
    local group counter = udg_GAME_PackG[5]
    local unit counterunit
    local integer LoopC
    local integer packcount
    local integer overcount
    local integer LoopD
    local player packowner

    set packcount = 0
    set overcount = 0
    set LoopD = 1
    set LoopC = 1
    set bj_forLoopAIndex = 1
    set bj_forLoopBIndex = 1
//===============================================================================================================================================================================

    loop
        exitwhen LoopC > 12
        if (udg_CC_SocialBehavior[LoopC] == 3) then

                  loop
                      exitwhen bj_forLoopAIndex > 10
                      set packowner = Player(LoopC - 1)

//=============================================== Selecting units for Pack ======================================================================================================
                      loop
                          exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                          if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopAIndex then
                             call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                          endif
                          set LoopD = LoopD + 1
                      endloop
                          set LoopD = 0
//===============================================================================================================================================================================

//=============================================== Counting units in Pack --> Packcount ==========================================================================================
                      loop
                          set counter = pack
                          set counterunit = FirstOfGroup(counter)
                          exitwhen counterunit == null
                          call GroupRemoveUnit(counter, counterunit)
                          set packcount = packcount + 1
                      endloop   
//===============================================================================================================================================================================

                      if packcount < 5 and packcount != 0 then

//=============================================== Selecting units for Overpack ==================================================================================================
                         loop
                             exitwhen bj_forLoopBIndex > 10

                             loop
                                 exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                 if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopBIndex then
                                 call GroupAddUnit(overpack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                 endif
                                 set LoopD = LoopD + 1
                             endloop
                                 set LoopD = 0
//===============================================================================================================================================================================

//=============================================== Counting units in Overpack --> Overcount ======================================================================================
                             loop
                                 set counter = overpack
                                 set counterunit = FirstOfGroup(counter)
                                 exitwhen counterunit == null
                                 call GroupRemoveUnit(counter, counterunit)
                                 set overcount = overcount + 1
                             endloop
//===============================================================================================================================================================================

                             if overcount > 5 then

//=============================================== Selecting Newpackunit =========================================================================================================                          
                             loop
                                 exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                 if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopBIndex then
                                    set newpackunit= LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD)
                                    set LoopD = udg_GAME_UnitNumberForPlayer[LoopC] + 1
                                 else
                                     set LoopD = LoopD + 1
                                 endif
                             endloop
                                 set LoopD = 0
//===============================================================================================================================================================================

//================================================== Transfering Newpackunit from Overpack to Pack ==============================================================================
                                 call SetUnitAbilityLevel( newpackunit,'A00X', bj_forLoopAIndex )
//===============================================================================================================================================================================

//=================================================== Cleaning pack and packcount for recount ===================================================================================
                                 call GroupClear(pack)
                                 set packcount = 0
//===============================================================================================================================================================================

//=============================================== Selecting units for Pack ======================================================================================================
                                 loop
                                     exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                     if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopAIndex then
                                        call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                     endif
                                        set LoopD = LoopD + 1
                                 endloop
                                     set LoopD = 0
//===============================================================================================================================================================================

//=============================================== Counting units in Pack --> Packcount ==========================================================================================
                                 loop
                                     set counter = pack
                                     set counterunit = FirstOfGroup(counter)
                                     exitwhen counterunit == null
                                     call GroupRemoveUnit(counter, counterunit)
                                     set packcount = packcount + 1
                                 endloop
//===============================================================================================================================================================================

//================================================ Stop Sending Units to Pack if it is full =====================================================================================
                                 if packcount >= 5 then
                                     set bj_forLoopBIndex = 11                                    
                                 endif
//===============================================================================================================================================================================

                             else

//================================================ Checking for incomplete groups, if > 1, unite them ===========================================================================
                                 if overcount + packcount <= 5 then
//===============================================================================================================================================================================

//=============================================== Selecting Newpackunit =========================================================================================================                          
                                 loop
                                    exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                    if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopBIndex then
                                       set newpackunit= LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD)
                                       set LoopD = udg_GAME_UnitNumberForPlayer[LoopC] + 1
                                    else
                                       set LoopD = LoopD + 1
                                    endif
                                 endloop
                                    set LoopD = 0
//===============================================================================================================================================================================

//================================================== Transfering Newpackunit from Overpack to Pack ==============================================================================
                                 call SetUnitAbilityLevel( newpackunit,'A00X', bj_forLoopAIndex )
//===============================================================================================================================================================================

//=================================================== Cleaning pack and packcount for recount ===================================================================================
                                 call GroupClear(pack)
                                 set packcount = 0
//===============================================================================================================================================================================

//=============================================== Selecting units for Pack ======================================================================================================
                                 loop
                                     exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                     if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == bj_forLoopAIndex then
                                        call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                     endif
                                        set LoopD = LoopD + 1
                                 endloop
                                     set LoopD = 0
//===============================================================================================================================================================================

//=============================================== Counting units in Pack --> Packcount ==========================================================================================
                                 loop
                                     set counter = pack
                                     set counterunit = FirstOfGroup(counter)
                                     exitwhen counterunit == null
                                     call GroupRemoveUnit(counter, counterunit)
                                     set packcount = packcount + 1
                                 endloop
//===============================================================================================================================================================================

//================================================ Stop Sending Units to Pack if it is full =====================================================================================
                                    if packcount >= 5 then
                                       set bj_forLoopBIndex = 11                                   
                                    endif
//===============================================================================================================================================================================

                                 endif
                             endif

//=================================================== Cleaning overpack and overcount for next round ============================================================================
                             call GroupClear(overpack)
                             set overcount = 0
//===============================================================================================================================================================================

                             set bj_forLoopBIndex = bj_forLoopBIndex + 1
                         endloop
                     endif

//=================================================== Cleaning pack and packcount for next round ================================================================================
                     call GroupClear(pack)
                     set packcount = 0
//===============================================================================================================================================================================

                     set bj_forLoopAIndex = bj_forLoopAIndex + 1
                 endloop  
        endif
        set LoopC = LoopC + 1
    endloop

//=================================================== Cleaning trigger for anti-leak result =====================================================================================
    set counter = null
    set counterunit = null
    set newpackunit = null
    set packowner = null
    set pack = null
    set overpack = null
//===============================================================================================================================================================================

endfunction

//===========================================================================
function InitTrig_SP_TogetherAdjustment takes nothing returns nothing
    local trigger SP_TogetherAdjustment = CreateTrigger(  )
    set udg_GAME_PackG[0] = CreateGroup()
    set udg_GAME_PackG[1] = CreateGroup()
    set udg_GAME_PackG[5] = CreateGroup()
    call TriggerRegisterTimerEvent( SP_TogetherAdjustment, 0.20, true )
    call TriggerAddAction( SP_TogetherAdjustment, function Trig_SP_TA_Actions )
    set SP_TogetherAdjustment = null
endfunction

so what do you think? not using any outer functions and avoids group creation beyond necessary. (Obs: at the creation of any unit, it is stored at a hashtable in which the first integer is equal to the player number and the second integer is the order in which it was created. (the second unit created for "Player(0)" (Player 1) is stored at udg_AllUnitsInMap, 1, 2.)

I said it just in case you asked how the hell my trigger got those LoadHandle actions. it was already there anyway, just saw the opportunity to use it again.
 
Level 12
Joined
Sep 4, 2007
Messages
407
I'm using a lot of loops, i put those to separate them so i dont get confused. try to look at them as one function o_O. It works for me. anyway, next time i post it in here, i'll get rid of them.



now that you mention, yeah, gonna get rid fo those bj_indexes.

Edit: Here it is.

JASS:
function Trig_SP_TA_Actions takes nothing returns nothing
    local unit newpackunit
    local group pack = udg_GAME_PackG[0]
    local group overpack = udg_GAME_PackG[1]
    local group counter = udg_GAME_PackG[5]
    local unit counterunit
    local integer LoopC
    local integer packcount
    local integer overcount
    local integer LoopD
    local integer LoopA
    local integer LoopB
    local player packowner
    set packcount = 0
    set overcount = 0
    set LoopD = 1
    set LoopC = 1
    set LoopA = 1
    set LoopB = 1
    loop
        exitwhen LoopC > 12
        if (udg_CC_SocialBehavior[LoopC] == 3) then

                  loop
                      exitwhen LoopA > 10
                      set packowner = Player(LoopC - 1)
                      loop
                          exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                          if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopA then
                             call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                          endif
                          set LoopD = LoopD + 1
                      endloop
                          set LoopD = 0
                      loop
                          set counter = pack
                          set counterunit = FirstOfGroup(counter)
                          exitwhen counterunit == null
                          call GroupRemoveUnit(counter, counterunit)
                          set packcount = packcount + 1
                      endloop   
                      if packcount < 5 and packcount != 0 then
                         loop
                             exitwhen LoopB > 10
                             loop
                                 exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                 if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopB then
                                 call GroupAddUnit(overpack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                 endif
                                 set LoopD = LoopD + 1
                             endloop
                                 set LoopD = 0
                             loop
                                 set counter = overpack
                                 set counterunit = FirstOfGroup(counter)
                                 exitwhen counterunit == null
                                 call GroupRemoveUnit(counter, counterunit)
                                 set overcount = overcount + 1
                             endloop
                             if overcount > 5 then
                             loop
                                 exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                 if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopB then
                                    set newpackunit= LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD)
                                    set LoopD = udg_GAME_UnitNumberForPlayer[LoopC] + 1
                                 else
                                     set LoopD = LoopD + 1
                                 endif
                             endloop
                                 set LoopD = 0
                                 call SetUnitAbilityLevel( newpackunit,'A00X', LoopA )
                                 call GroupClear(pack)
                                 set packcount = 0
                                 loop
                                     exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                     if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopA then
                                        call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                     endif
                                        set LoopD = LoopD + 1
                                 endloop
                                     set LoopD = 0
                                 loop
                                     set counter = pack
                                     set counterunit = FirstOfGroup(counter)
                                     exitwhen counterunit == null
                                     call GroupRemoveUnit(counter, counterunit)
                                     set packcount = packcount + 1
                                 endloop
                                 if packcount >= 5 then
                                     set LoopB = 11                                    
                                 endif
                             else
                                 if overcount + packcount <= 5 then
                                 loop
                                    exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                    if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopB then
                                       set newpackunit= LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD)
                                       set LoopD = udg_GAME_UnitNumberForPlayer[LoopC] + 1
                                    else
                                       set LoopD = LoopD + 1
                                    endif
                                 endloop
                                    set LoopD = 0
                                 call SetUnitAbilityLevel( newpackunit,'A00X', LoopA )
                                 call GroupClear(pack)
                                 set packcount = 0
                                 loop
                                     exitwhen LoopD > udg_GAME_UnitNumberForPlayer[LoopC]
                                     if GetUnitAbilityLevel(LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD),'A00X') == LoopA then
                                        call GroupAddUnit(pack, LoadUnitHandle(udg_AllUnitsinMap, LoopC, LoopD))
                                     endif
                                        set LoopD = LoopD + 1
                                 endloop
                                     set LoopD = 0
                                 loop
                                     set counter = pack
                                     set counterunit = FirstOfGroup(counter)
                                     exitwhen counterunit == null
                                     call GroupRemoveUnit(counter, counterunit)
                                     set packcount = packcount + 1
                                 endloop
                                    if packcount >= 5 then
                                       set LoopB = 11                                   
                                    endif
                                 endif
                             endif
                             call GroupClear(overpack)
                             set overcount = 0
                             set LoopB = LoopB + 1
                         endloop
                     endif
                     call GroupClear(pack)
                     set packcount = 0
                     set LoopA = LoopA + 1
                 endloop  
        endif
        set LoopC = LoopC + 1
    endloop
    set counter = null
    set counterunit = null
    set newpackunit = null
    set packowner = null
    set pack = null
    set overpack = null
endfunction

//===========================================================================
function InitTrig_SP_TogetherAdjustment takes nothing returns nothing
    local trigger SP_TogetherAdjustment = CreateTrigger(  )
    set udg_GAME_PackG[0] = CreateGroup()
    set udg_GAME_PackG[1] = CreateGroup()
    set udg_GAME_PackG[5] = CreateGroup()
    call TriggerRegisterTimerEvent( SP_TogetherAdjustment, 0.20, true )
    call TriggerAddAction( SP_TogetherAdjustment, function Trig_SP_TA_Actions )
    set SP_TogetherAdjustment = null
endfunction
 
Status
Not open for further replies.
Top