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

[Solved] How to Group unit without uses boolenexplr

Status
Not open for further replies.
Level 16
Joined
Mar 3, 2006
Messages
1,564
Use FirstOfGroup.

<<< EDIT >>>
here is an example
JASS:
globals
    group g = CreateGroup()
endglobals

// ===========================================================

function MatchingUnit takes unit u returns boolean
    return u == UNIT_TYPE_HERO // this is just an example you will have to set your own filter
endfunction

function example takes real x, real y, real radius returns nothing
    local unit u
    call GroupEnumUnitsInRange(g,x,y,radius,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if MatchingUnit(u) then @/*EDIT:you could also apply the filter here and no need for another function call*/@
            // Do stuff here
        endif
        call GroupRemoveUnit(g,u)
    endloop
endfunction
 
Last edited:
Level 5
Joined
Jan 4, 2009
Messages
118
OK thanks you, I have question about Event Every times X second. Can I use other function instead. Because I use this event for many trigger. I worry its slow my map and causes many leak. How can I fix that problem?

Sorry for my language.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Mmmm depends. There are ways to avoid having to create long if/else chains, but it's "doable" if isn't a very used action.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
No. There are systems here in hive for recipe Items. The way it works is with loops and pre-saved data. It's something like having a list of 100 values, and you tell the system "Find value 5 in the list of 100 values"... sort of.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
if the loop is instant, bj_lastCreatedGroup is fine than creating a group...

about X seconds, you could use timers instead then pause the timer if you dont use the function...
Optimization is great and all, but sometimes just write clean code...

Also he'd presumably not be using a global at all if it were anything but instant.

(Oh, and to the OP, the method a few posts up is really bad [not that I can blame him, he gave you what you asked for]... just use a boolexpr, there's really no reason not to)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
... just use a boolexpr, there's really no reason not to)

I disagree, there are reasons to avoid it.
First, it's much faster because each time the boolexpr is evaluated a new thread is created, while it's not with a null filter, but yeah 99 % of times it doesn't matter at all.

It doesn't split the code, then you can use your locals without temp globals.
I agree that the loop is verbose, but still less than writing a boolexpr, and with Cohadar's jasshelper this loop is just like that :

for <unit> in <group>
// filter and do stuff with <unit>
endfor
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I think that, what Troll-Brain means is that the "Matching" part isn't really needed outside the GroupEnum to work with the units. You can filter the units inside the group as someone said before in this same thread.

JASS:
    call GroupEnumUnitsInRange(g,x,y,radius,null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if (First comparison) and (Second comparison) and (Third comparison), etc. then
            // Do stuff here
        endif
        call GroupRemoveUnit(g,u)
    endloop
endfunction
 
Level 5
Joined
Jan 4, 2009
Messages
118
Err I wonder Value X and Y on function GroupEnumUnitsInRange Tell me more about agrument of that function.

JASS:
function Trig_CountUnitGroup_Actions takes nothing returns nothing
    
    local unit u
    local group g =CreateGroup()
    local integer unitCount
    
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
            if(GetUnitTypeId(u) == 'hf00')then
                set unitCount =unitCount + 1
                call BJDebugMsg(I2S(unitCount))
            endif
            call GroupRemoveUnit(g,u)
    endloop
endfunction

//===========================================================================
function InitTrig_CountUnitGroup takes nothing returns nothing
    set gg_trg_CountUnitGroup = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(gg_trg_CountUnitGroup, Player(0), "-uc", true)
    call TriggerAddAction( gg_trg_CountUnitGroup, function Trig_CountUnitGroup_Actions )
endfunction
 
Level 16
Joined
Mar 3, 2006
Messages
1,564
GroupEnumUnitsInRange(g,x,y,r,filter)

g: group, it is the group that the picked unit will be added to.
x: real, the X coordinate of the centre point of the picking circle.
y: real, the Y coordinate of the centre point of the picking circle.
r: real, is the radius the circle that the function will pick units from.
filter: boolexpr, if you want the unit to has special condition, but we regularly avoid this to prevent creation of another thread so we use FirstOfGroup and match the unit one by one.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
With Cohadar's jasshelper :

Instead of :

JASS:
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
            if(GetUnitTypeId(u) == 'hf00')then
                set unitCount =unitCount + 1
                call BJDebugMsg(I2S(unitCount))
            endif
            call GroupRemoveUnit(g,u)
    endloop

->

JASS:
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    for u in g

        if(GetUnitTypeId(u) == 'hf00')then
            set unitCount =unitCount + 1
            call BJDebugMsg(I2S(unitCount))
        endif

    endfor

When the vJass code will be converted to jass code the result will be exactly the same, but it is simply less verbose and error prone.
 
Level 5
Joined
Jan 4, 2009
Messages
118

Ahh I'try use that code to count unit on group, but It's doesn't work, why and How I can do fixed it.

JASS:
function Trig_CountUnitGroup_Actions takes nothing returns nothing
    
    local unit u
    local group g =CreateGroup()
    local integer unitCount
    local integer i
    
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        set i = i + 1
            if(GetUnitTypeId(u) == 'hf00')then
                set unitCount =unitCount + 1
                call BJDebugMsg("COUNT IS : "+I2S(unitCount))
            else
                call BJDebugMsg("LOOP :"+I2S(i))
            endif
            call GroupRemoveUnit(g,u)
    endloop
endfunction

//===========================================================================
function InitTrig_CountUnitGroup takes nothing returns nothing
    set gg_trg_CountUnitGroup = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(gg_trg_CountUnitGroup, Player(0), "-uc", true)
    call TriggerAddAction( gg_trg_CountUnitGroup, function Trig_CountUnitGroup_Actions )
endfunction


Tell me plz!!
 
Level 5
Joined
Jan 4, 2009
Messages
118
JASS:
function Trig_CountUnitGroup_Actions takes nothing returns nothing
    
    local unit u
    local group g =CreateGroup()
    local integer unitCount
    local integer i
    
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        set i = i + 1
            if(GetUnitTypeId(u) == 'hf00')then
                set unitCount =unitCount + 1
                call BJDebugMsg("COUNT IS : "+I2S(unitCount))
            endif
            call GroupRemoveUnit(g,u)
    endloop
    
    call DestroyGroup(g)
    set g -= null
endfunction

//===========================================================================
function InitTrig_CountUnitGroup takes nothing returns nothing
    set gg_trg_CountUnitGroup = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(gg_trg_CountUnitGroup, Player(0), "-uc", true)
    call TriggerAddAction( gg_trg_CountUnitGroup, function Trig_CountUnitGroup_Actions )
endfunction

I don't know why don't display text in loop or loop is infinite?

Are the 'hf00' units in the map?

'hfoo' is footman they have really.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
'hf00' is nothing.
'hfoo' is footman.

Also (I just noticed this) If the local integer variable has no value it will mess the whole thing. It's probably doing the Enum but not displaying any message, since the message to display contains "null", which I tough should be naturally 0 but now noticed that isnt.

JASS:
    local unit u
    local group g =CreateGroup()
    local integer i = 0
    
    call GroupEnumUnitsInRange(g, 0, 0, 1000000000, null)
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
            set i = i + 1
            if(GetUnitTypeId(u) == 'hfoo')then
                set i = i + 1
                call BJDebugMsg("COUNT IS : " + I2S(i))
            endif
        call GroupRemoveUnit(g,u)
    endloop
    
    call DestroyGroup(g)
 
Status
Not open for further replies.
Top