Problem: Using Local Integer in a Loop, in a Function

sevensc

New Member
Reaction score
8
Hey all,

I'm having some trouble with a local integer in a loop, in a function.

This code works just fine, but it uses a global integer (udg_tempInteger):
Code:
    loop        
        if RectContainsUnit(udg_regionsLeft[i], tempUnit) then
            set udg_tempInteger = i
        endif
        exitwhen i == udg_tempInteger
        set i = i + 1
    endloop
When I replace the global with a local, the code no longer functions properly.

Do i need to return the value differently when using a local?

Any help is appreciated.


NOTE: I know this could be done with if statements or separate triggers for each region, but my regions are dynamic and the loop takes care of all possibilities. That being said, if one of those other options I mentioned seems like a better idea, let me know.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
Only reason why it whouldn't work is that you didn't define the local or you haven't initilized it with a value.

However, this code works:

Code:
    loop    
        exitwhen RectContainsUnit(udg_regionsLeft[i], tempUnit)
        set i = i + 1
    endloop
You have to add something that make sure that the loop exit correctly even if the unit isn't in any region.
 

sevensc

New Member
Reaction score
8
I've actually tried that solution and the same problem occurs, so maybe i should better explain this issue.

The full code for the trigger is:
Code:
function Trig_GUI_Left_Regions_Copy_2_Conditions takes nothing returns boolean
    if ( not ( GetUnitTypeId(GetEnteringUnit()) != 'u000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_GUI_Left_Regions_Copy_2_Actions takes nothing returns nothing
    local integer i = 1
    local integer id = 0
    local string order = "move"
    local unit tempUnit = GetEnteringUnit()
    local location tempLocation 

    loop        
        if RectContainsUnit(udg_regionsLeft[i], tempUnit) then
            set udg_tempInteger = i
        endif
        exitwhen i == udg_tempInteger
        set i = i + 1
    endloop

    if GetUnitUserData(GetTriggerUnit()) == 2 then
        set tempLocation = GetRectCenter(udg_regionsMiddle[udg_tempInteger])
        call IssuePointOrderLoc( tempUnit, order, udg_tempLocation )
        call RemoveLocation (tempLocation)
    else
        if GetUnitUserData(GetTriggerUnit()) == 1 then
            call SetUnitUserData( tempUnit, 2 )
            set tempLocation = GetRectCenter(udg_regionsPrevious[udg_tempInteger])
            call SetUnitPositionLoc( tempUnit, udg_tempLocation )
            call RemoveLocation (tempLocation)        
        endif
    endif
    set
    set tempUnit = null
    set tempLocation = null
endfunction

//===========================================================================
function InitTrig_GUI_Left_Regions_Copy_2 takes nothing returns nothing
    set gg_trg_GUI_Left_Regions_Copy_2 = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Red_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Blue_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Teal_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Purple_Left )
    call TriggerAddCondition( gg_trg_GUI_Left_Regions_Copy_2, Condition( function Trig_GUI_Left_Regions_Copy_2_Conditions ) )
    call TriggerAddAction( gg_trg_GUI_Left_Regions_Copy_2, function Trig_GUI_Left_Regions_Copy_2_Actions )
endfunction

As you can see, I am attempting to store the value of "i" when the loop exits so that I can use it as an index below.

Using the a global as shown in the code above works fine, but using the local integer "id" does not work.

Do i need to nest the other ifs in the loop or return the value differently?

Also, is there a way (in the InitTrig) to set it to trigger if a unit enters a region that exists in the array: Left_Regions, rather than listing each possible region the way I do?
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
Ok, a few things.

That code whould crash with an error when you save. (Third last line of Trig_GUI_Left_Regions_Copy_2_Actions)

RectContainsUnit does not work as you think on the event TriggerRegisterEnterRectSimple. The unit that enters the rect doesn't always count as 'in the rect' on the trigger that fires. Adding a TriggerSleepAction(0) solves this, a timer callback is even better.

That code 'should' work with id as well as with udg_tempInteger, I beleive that you get confused because the thing above.
If it still doesn't work after adding the TriggerSleepAction(0) fix then trow in some debug messages and tell us the result.

You can use 'elseif' to avoid the nesting of if statements
 

sevensc

New Member
Reaction score
8
I'm not sure why that extra "set" was in the code, but yea - it's gone now.

Anywho, the problem was with not having "call TriggerSleepAction(0)".

Here is the cleaned up code:

Code:
function Trig_GUI_Left_Regions_Copy_2_Conditions takes nothing returns boolean
    if ( not ( GetUnitTypeId(GetEnteringUnit()) != 'u000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_GUI_Left_Regions_Copy_2_Actions takes nothing returns nothing
    local integer i = 1
    local string order = "move"
    local unit tempUnit = GetEnteringUnit()
    local location tempLocation 

    loop
        call TriggerSleepAction(0)                
        exitwhen RectContainsUnit(udg_regionsLeft[i], tempUnit)
        set i = i + 1
    endloop

    if GetUnitUserData(GetTriggerUnit()) == 2 then
        set tempLocation = GetRectCenter(udg_regionsMiddle[i])
        call IssuePointOrderLoc( tempUnit, order, tempLocation )
        call RemoveLocation (tempLocation)
    elseif GetUnitUserData(GetTriggerUnit()) == 1 then
        call SetUnitUserData( tempUnit, 2 )
        set tempLocation = GetRectCenter(udg_regionsPrevious[i])
        call SetUnitPositionLoc( tempUnit, tempLocation )
        call RemoveLocation (tempLocation)
    endif
    set tempUnit = null
    set tempLocation = null
endfunction

//===========================================================================
function InitTrig_GUI_Left_Regions_Copy_2 takes nothing returns nothing
    set gg_trg_GUI_Left_Regions_Copy_2 = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Red_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Blue_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Teal_Left )
    call TriggerRegisterEnterRectSimple( gg_trg_GUI_Left_Regions_Copy_2, gg_rct_Purple_Left )
    call TriggerAddCondition( gg_trg_GUI_Left_Regions_Copy_2, Condition( function Trig_GUI_Left_Regions_Copy_2_Conditions ) )
    call TriggerAddAction( gg_trg_GUI_Left_Regions_Copy_2, function Trig_GUI_Left_Regions_Copy_2_Actions )
endfunction

Thanks for the help (+rep of course), that should help me with a good number of triggers in my TD.


And as a special bonus, one more question if you feel like answering it:

Is there a way to check if a unit enters a region that is part of a particular region array? Right now I am checking to see if a unit enters any of the possible regions but was wondering if i can get those four lines down to 1.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
You can move the TriggerSleepAction out from the loop, that whould give a somewhat faster result if there is many regions (rects acctualy).

>Is there a way to check if a unit enters a region that is part of a particular region array?
If you find one tell me :)
I bashed against this problem a long time ago and my final solution was very close to your code.

However, if you are a pure jass user then there is nothing to stop your from starting to use regions instead of rects. With regions you can 'attach' data to the region with a handle vars system and then use GetTriggeringRegion() to get the region and then read the data from it.
As you probably understand doing this is somewhat trickier then the current solution :p
 

sevensc

New Member
Reaction score
8
Ok, I pulled the TriggerSleepAction out of the the loop.

As far as being a pure jass user, that is my goal - I do have programming and design experience but the WE and Jass are still new to me.

I will go ahead and try to find and read up on a handle vars system as you mentioned. Being "trickier" isn't enough to stop me :)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top