HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

EasyGroups - group enumeration made simple

07-26-2007, 09:00 PM#1
SFilip
If you have a group/force and want to something to all of its members the best thing to use is ForGroup/ForForce.
However this requires a separate function which can sometimes be a pain.
The alternative is using FirstOfGroup and removing units which can probably be slow, but does the job.

This system is somewhat a mix of the two, it uses ForGroup to fill an array and then loops through it to perform the desired actions. Requires vJass.

The use is quite simple, all you need to do is put your code between two runtextmacros - GroupEnumBegin and GroupEnumEnd.
Alternatively running GroupEnumFillArray and GroupEnumStartLoop is the same as GroupEnumBegin, but you can check the number of units in the group between them (stored as GroupPicksCount).
All of these also have Force equivalents.

Example:
Collapse JASS:
function myfunc takes nothing returns nothing
    local unit u = null
    local group mygroup = CreateGroup()
    call GroupEnumUnitsOfPlayer(mygroup, Player(0), null)

    //! runtextmacro GroupEnumBegin("mygroup", "u")
    call KillUnit(u)
    //! runtextmacro GroupEnumEnd()

    call DestroyGroup(mygroup)
    set u = null
    set mygroup = null
endfunction

And the system itself:
Hidden information:
Collapse JASS:
library EasyGroups

    globals
        integer GroupPicksCount = 0
        integer ForcePicksCount = 0
        unit array GroupPicks
        player array ForcePicks
    endglobals

    function FillGroupPicks takes nothing returns nothing
        if GroupPicksCount < 8191 then
            set GroupPicks[GroupPicksCount] = GetEnumUnit()
        endif    
        set GroupPicksCount = GroupPicksCount + 1
    endfunction

    function FillForcePicks takes nothing returns nothing
        if ForcePicksCount < 8191 then
            set ForcePicks[ForcePicksCount] = GetEnumPlayer()
        endif    
        set ForcePicksCount = ForcePicksCount + 1
    endfunction
    
    // ---------- Groups ----------

    //! textmacro GroupEnumFillArray takes WHICHGROUP
    set GroupPicksCount = 0
        call ForGroup($WHICHGROUP$, function FillGroupPicks)
    //! endtextmacro
    
    //! textmacro GroupEnumStartLoop takes ENUMUNIT
    loop
            exitwhen GroupPicksCount == -1
            set $ENUMUNIT$ = GroupPicks[GroupPicksCount]
    //! endtextmacro

    //! textmacro GroupEnumBegin takes WHICHGROUP, ENUMUNIT
    set GroupPicksCount = 0
        call ForGroup($WHICHGROUP$, function FillGroupPicks)
    loop
            exitwhen GroupPicksCount == -1
            set $ENUMUNIT$ = GroupPicks[GroupPicksCount]
    //! endtextmacro

    //! textmacro GroupEnumEnd	
        set GroupPicksCount = GroupPicksCount - 1
        endloop
    //! endtextmacro
    
    // ---------- Forces ----------
    
    //! textmacro ForceEnumFillArray takes WHICHFORCE
    set ForcePicksCount = 0
        call ForForce($WHICHFORCE$, function FillForcePicks)
    //! endtextmacro
    
    //! textmacro ForceEnumStartLoop takes ENUMPLAYER
    loop
            exitwhen ForcePicksCount == -1
            set $ENUMPLAYER$ = ForcePicks[ForcePicksCount]
    //! endtextmacro

    //! textmacro ForceEnumBegin takes WHICHFORCE, ENUMPLAYER
    set ForcePicksCount = 0
        call ForForce($WHICHFORCE$, function FillForcePicks)
    loop
            exitwhen ForcePicksCount == -1
            set $ENUMPLAYER$ = ForcePicks[ForcePicksCount]
    //! endtextmacro

    //! textmacro ForceEnumEnd	
        set ForcePicksCount = ForcePicksCount - 1
        endloop
    //! endtextmacro

endlibrary
07-26-2007, 11:24 PM#2
PipeDream
That's cool, nice idea.

Reminder of this issue: http://www.wc3campaigns.net/showthread.php?t=90186
07-26-2007, 11:58 PM#3
DioD
single active force\group at time?
07-27-2007, 05:33 PM#4
SFilip
Yes, but that can only become a problem if you use waits.
07-27-2007, 11:29 PM#5
DioD
sorry system too "hardcoded" you have to use something like this...

Code:
globals
    integer GroupPicksCount = 0
    unit array GroupPicks
    group Ex_SomeGlobalGroup = CreateGroup()
    
    boolean Ex_CRUSH = false
endglobals

function Echo takes string Text returns nothing
endfunction

function FillGroupPicks takes nothing returns boolean
    
    if GroupPicksCount > 8191 then
        call Echo("GPC:CRITICAL ERROR:OUT OF MEMORY:GAME WILL CRUSH ON LOAD")     //debug
        set Ex_CRUSH = true                                                       //debug
    endif
    set GroupPicks[GroupPicksCount] = GetFilterUnit()
    set GroupPicksCount = GroupPicksCount + 1
    return true
    
endfunction

function myfunc takes nothing returns nothing
    
    call GroupClear(Ex_SomeGlobalGroup)
    set GroupPicksCount = 0
    call GroupEnumUnitsOfPlayer(Ex_SomeGlobalGroup, Player(0), Condition(function FillGroupPicks))
    
    loop
        exitwhen GroupPicksCount == -1
        call KillUnit(GroupPicks[GroupPicksCount])
        set GroupPicksCount = GroupPicksCount - 1
    endloop
    
endfunction