HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Exitwhens in loops inside loops

04-05-2008, 11:28 PM#1
Burning Rose
I forgot what it's called when you put a loop in a loop or an if/then in an if/then or whatever, so yeah.

So I'm making a trigger that will respawn creeps when they die. I want it to wait for a while, and then start checking to make sure there aren't any nearby Heroes before it respawns. What I'm wondering is, will the
Collapse JASS:
exitwhen free == false
go off while the trigger is still in the lower loop? Or will it wait until the lower loop finishes looping to check the first loop's exitwhen statement?
Collapse JASS:
function Trig_Respawn_Creep_Round_1_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real creepX = GetAttachedReal(u, "creepx")
    local real creepY = GetAttachedReal(u, "creepy")
    local location loc = Location(creepX,creepY)
    local group g
    local unit first
    local boolean free
    set udg_Random = GetRandomInt(1, 4)
    if ( Trig_Respawn_Creep_Round_1_Func002C() ) then
        call CreateItemLoc( ChooseRandomItemExBJ(GetRandomInt(1, 2), ITEM_TYPE_ANY), GetUnitLoc(GetTriggerUnit()) )
    else
    endif
    call TriggerSleepAction( ( 35.00 + GetRandomReal(0.00, 5.00) ) )
    loop
        exitwhen free == false
        set g = GroupEnumUnitsInRange(g,creepX,creepY,300.0, (IsUnitAliveBJ(GetFilterUnit()) )
        loop
            set first = FirstOfGroup(g)
            set free = IsUnitType(first, UNIT_TYPE_HERO)
            exitwhen first == null or free == true
        endloop
    endloop

And yes I know I'm missing some code, I just gave you what's neccisary for the question :P
04-05-2008, 11:52 PM#2
Pyrogasm
The word is "nesting". And "exitwhen"s are checked whenever they are gotten to in the code.

So the line exitwhen free == false would be evaluated at the start of the first loop; if it was false, it would continue on to the second loop. In the second loop it would continue to loop indefinitely until the line exitwhen first == null or free == true was met.

When that was met, it would exit the nested loop and go back to the first loop to evaluate the line exitwhen free == false; if true then it would exit the first loop; if false it would repeat the cycle over again.


In reality, though, your code would crash because "free" isn't initialized; you should have local boolean free = true.
04-06-2008, 12:35 AM#3
Salbrismind
Quote:
Originally Posted by Pyrogasm
In reality, though, your code would crash because "free" isn't initialized; you should have local boolean first = true.

Isn't first a unit variable? And it is declared already?

Edit: Oh you put the wrong word in the jass box, my bad should be:
Collapse JASS:
 local boolean free = true 
04-06-2008, 12:37 AM#4
Pyrogasm
Yeah, yeah... that's what I meant.
04-06-2008, 12:38 AM#5
Burning Rose
Well cool, so I was correct in my assumptions about nesting (thanks :P).
Also, now I'm getting an error that says "Cannot convert Boolean to Boolexpr" on this line:
Collapse JASS:
set g = GroupEnumUnitsInRange(g,creepX,creepY,300.0, (IsUnitAliveBJ(GetFilterUnit()) )
I'm assuming then, that I used the wrong sort of expression on the last arguement. What should I do to make it a Boolexpr?
04-06-2008, 01:26 AM#6
MysticGeneral
Show the line of code before that error. That line of code has nothing to do with a boolean. (Didn't see that, sorry, guess it did)
04-06-2008, 01:42 AM#7
Burning Rose
Actually it does, it has an arguement that requires a boolexpr, and I think I'm giving it a Boolean. It's also telling me on that line specifically, but here ya go anyways:
Collapse JASS:
exitwhen free == false
04-06-2008, 02:03 AM#8
Salbrismind
What it means is that you need to put in there a function call which returns a boolean just like when you set conditions for a trigger. Here is an example from my map:

Collapse JASS:
private function Filter takes nothing returns boolean
        if GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) then
            return true
        else
            return IsUnitEnemy(GetSpellAbilityUnit(), GetOwningPlayer(GetFilterUnit()))
        endif
endfunction


call GroupEnumUnitsInRangeCounted(engroup, ax, ay, 250, Condition(function Filter), udg_hitamount[index])

Just make sure the function is at the top of the trigger (obviously).
04-06-2008, 03:06 AM#9
Burning Rose
Ah, K. Well I tried that, and now I'm getting this message:
"Cannot convert nothing to group". Same line. =_=
Collapse JASS:
function Trig_Respawn_Creep_Round_1_Herocheck takes nothing returns boolean
    if (IsUnitAliveBJ(GetFilterUnit()) ) == true then
        return true
    else 
        return false
    endif
endfunction
Collapse JASS:
set g = GroupEnumUnitsInRange(g,creepX,creepY,300.0, Condition(function Trig_Respawn_Creep_Round_1_Herocheck) )
04-06-2008, 03:15 AM#10
Rising_Dusk
Expand JASS:
Fixes this one.
Expand JASS:
Fixes that one.
04-06-2008, 03:18 AM#11
darkwulfv
You're using GroupEnum... wrong. You want:

Collapse JASS:
local group g = CreateGroup
call GroupEnumUnitsInRange(g,creepX,creepy,300.0, Condition(function Trig_Respawn_Creep_Round_1_Herocheck) )
//do stuff
call DestroyGroup(g)
set g = null

GroupEnum... Doesn't return a group, it manipulates it.

Also, IsUnitAliveBJ(GetFilterUnit()) can be made into: GetWidgetLife(GetFilterUnit()) > .405 It's faster and also a native.
04-06-2008, 03:26 AM#12
Burning Rose
Thanks Wulf, it works! I see the problem now >_>
04-06-2008, 04:13 AM#13
darkwulfv
No problem. That group thing threw me off at first too.