• 🏆 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!

Declaring units in a unit group to a unit variable array

Status
Not open for further replies.
Level 7
Joined
Dec 8, 2008
Messages
243
Hi, I was wondering someone could tell me how to assign units in a unit group to a unit variable.

I'm trying to make a spell which involves every unit in a 550 radius gets added to a unit group, then for every unit in the group, declare the picked unit to a unit variable ++

Ofc, that requires doing something like

Pick every unit in <Unit Group> do actions
Actions- Set UnitVariable[Counter] to Picked unit
Counter = Counter + 1;

But as far as I know, you can't have a forloop in a unit loop.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
So what? You set an own counter variable before the loop to the starting value and use and increase it within each iteration as you have already shown. I guess you meant the For Each Integer A/B loops as "for loop"s but that's not the only way to have a loop with incrementing variables. You can freely set any variable in the ForGroup-block.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
What WaterKnight is saying:

  • Set CountUnits = 0
  • Unit Group - Pick every unit in TempGroup and do (Actions)
    • Loop - Actions
      • Set Unit[CountUnits] = (Picked unit)
      • Set CountUnits = (CountUnits + 1)
OR:

JASS:
function CountUnits takes group g returns nothing
    local integer i = 0
    
    loop
        set udg_Unit[i] = FirstOfGroup(g)
        exitwhen udg_Unit[i] == null
        set i = i+1
    endloop
    
    call DestroyGroup(g)
    set g = null
endfunction


You can use loops in a unit group by the way, I do it regularly.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
ap0calypse.... Someone forgot to remove the unit from the group....

loop
set udg_Unit = FirstOfGroup(g)
exitwhen udg_Unit == null
set i = i+1
endloop

this is an infinite loop as if the group has atleast 1 unit, FirstOfGroup will always return the same unit infinitly as the unit never gets removed from the group.

It was also found that doing that method was less efficent than running an enum due to the expensive nature of removing units from groups.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Haha, you're right DSG ^^
Wanted to be a little too fast I guess :D

DSG said:
It was also found that doing that method was less efficent than running an enum due to the expensive nature of removing units from groups.
Never heard of that before.
So you're saying I'd better use ForGroup(...) than the loop? I guess I'll change a lot of other triggers then (as I use that loop quite often, a long time ago I heard people saying it was the best method).
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Many people recommended that when enuming units with in an area, you run your code in the filter the enum executes rather than breaking appart the group in a loop unit by unit.

I can easilly see how this is possible... Groups seem to consist of 2 parts, a hashtable for adding and removing units quickly and some form of array or list for listing all units in the group. When enuming through a group, it just has to loop through the list. When removing a unit from the group it must probably do a hashtable lookup (slowish) and then shuffle all units in the group to keep it continious (or if it uses a list it changes the pointers).

The proof I saw for this was that groups dramatically slow down for adding and removing units when more than about 64 units are within them (until then it remained the same which points towards hashtable filling up). Enums however were said to execute linearly (no penalty for large groups).
 
Status
Not open for further replies.
Top