Return Triggering Rect?

DioD

New Member
Reaction score
57
1) one trigger
2) one rect
3) hashtables
4) GetTriggeringTrigger()
5) ???
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
There isn't a GetTriggering/Entering/LeavingRect() function =).

I guess you would have to use 86 triggers and 86 action functions instead.

Edit: Or one trigger array and one boolexpr array but still 86 condition functions.
 

Risen

New Member
Reaction score
4
Actually, I have the movement and such already done, (0 conditions) I just need that triggering rect.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
>Actually, I have the movement and such already done
Post the code?
 

Risen

New Member
Reaction score
4
JASS:
private struct movement
    location l
    unit u
    unit u2
        method onDestroy takes nothing returns nothing
            call RemoveLocation( .l )
            set .l = null
            set .u = null
            set .u2 = null
        endmethod
endstruct

private function Movement takes nothing returns nothing
local integer i
local string s = "move"
local movement m = movement.create()
set m.u = GetTriggerUnit()
set m.u2 = GetEnteringUnit()
//local rect r 
set i = RegisterRect
//set r = R<i>
        if i &lt; 9 then 
            if i == 73 then
                set PlayerLives[0] = PlayerLives[0] - 1 
                call KillUnit( m.u2 )
            elseif i == 72 then
                set i = 73
            elseif i == 9 then
                set i = 72
        else
            set i = i + 1
            endif
        endif
            
        if i &gt;= 9 and i &lt; 18 then
            if i == 17 then
                set i = 74
            elseif i == 74 then
                set i = 75
        else 
                set i = i + 1
            endif
        endif
            
        if i &gt;= 18 and i &lt; 27 then
            if i == 26 then
                set i = 76
            elseif i == 76 then
                set i = 77
        else 
                set i = i + 1
            endif
        endif
            
        if i &gt;= 27 and i &lt; 36 then 
            if i == 35 then
                set i = 78
            elseif i == 78 then
                set i = 79
        else 
                set i = i + 1
            endif
        endif

        if i &gt;= 36 and i &lt; 45 then
            if i == 44 then
                set i = 80
            elseif i == 80 then
                set i = 81
        else 
                set i = i + 1
            endif
        endif
            
        if i &gt;= 45 and i &lt; 54 then
            if i == 53 then
                set i = 82
            elseif i == 82 then
                set i = 83
        else 
                set i = i + 1
            endif
        endif
        
        if i &gt;= 54 and i &lt; 63 then
            if i == 62 then
                set i = 84
            elseif i == 84 then
                set i = 85
        else 
                set i = i + 1
            endif
        endif
        
        if i &gt;= 63 and i &lt; 72 then
            if i == 71 then
                set i = 86
            elseif i == 86 then
                set i = 87
        else 
                set i = i + 1
            endif
        endif
    
        if i == 75 then
            set PlayerLives[1] = PlayerLives[1] - 1 
        elseif i == 77 then
            set PlayerLives[2] = PlayerLives[2] - 1
        elseif i == 79 then
            set PlayerLives[3] = PlayerLives[3] - 1 
        elseif i == 81 then
            set PlayerLives[4] = PlayerLives[4] - 1 
        elseif i == 83 then
            set PlayerLives[5] = PlayerLives[5] - 1
        elseif i == 85 then
            set PlayerLives[6] = PlayerLives[6] - 1 
        elseif i == 87 then
            set PlayerLives[7] = PlayerLives[7] - 1 
        endif
        set m.l = Location( GetRectCenterX( RECT<i> ), GetRectCenterY( RECT<i> ) )
        call IssuePointOrderLoc( m.u, s, m.l )
    call m.destroy()</i></i></i>


It probably needs a little debugging but I can do that part on my own.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Oh my I see you are in love with magic numbers.

But the facts are that there really is no GetTriggerRect() // RegisterRect

Also
set m.u = GetTriggerUnit()
set m.u2 = GetEnteringUnit()

GetTriggerUnit() in this case is equivalent to GetEnteringUnit()

so I think you have some design problems here (no offense)
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
If you create a separate trigger for each rect, you could do this with an attachment system, merely grabbing the rect attached to the [ljass]GetTriggeringTrigger()[/ljass]. Here's a dumbed-down example of what I use:

JASS:
struct Waypoint

        trigger onEnter //GetTriggeringTrigger
        rect whichRect //The entered rect
        region whichRegion //The entered region

        static method Actions takes nothing returns nothing
            local Waypoint this = GetData(GetTriggeringTrigger()) //Get Data attached to triggering trigger
            // Do stuff with the members of the struct
        endmethod

        static method create takes rect whichRect returns Waypoint
            local Waypoint this = Waypoint.allocate()
            set this.whichRect = whichRect
            set this.whichRegion = CreateRegion()
            call RegionAddRect(this.whichRegion,whichRect)
            set this.onEnter = CreateTrigger()
            call TriggerRegisterEnterRegion(this.onEnter,this.whichRegion,null)
            call TriggerAddAction(this.onEnter,function Waypoint.Actions)
            call SetData(this.onEnter,this) //Attach data to triggering trigger (only one rect for every event/trigger)
            return this
        endmethod
    endstruct


I don't know of a method that doesn't require individual triggers.
 

DrEvil

FCRI Associate!
Reaction score
111
couldnt you do a search O(n) to check the GetTriggerUnit() location and if hes in a certain rect?
Which would work... unless you have rects overlapping each other... in which case would either return 1 of x rects or x amount of containable rects.

JASS:
function actions takes nothing returns nothing
   local integer n=0
   local unit u=GetTriggerUnit()
   local integer whichRect
   loop
      exitwhen n==X
      
      if(rectContainsUnit(R[n],u))then
         set whichRect=n// or a local rect = R[n] either way its just an example
      endif
      set n=n+1
   endloop
endfunction
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Iterating over all your rects might do the trick (DrEvil's idea)

JASS:
function GetTriggeringRect takes unit u returns integer
    local integer i = 0
    local real ux = GetUnitX(u)
    local real uy = GetUnitY(u)

    loop
        exitwhen i &gt;= MAX_RECTS // 86

        // if the unit is in that rect then return it&#039;s index in the R array
        if GetRectMinX(R<i>) &lt;= ux and GetRectMaxX(R<i>) &gt;= ux and GetRectMinY(R<i>) &lt;= uy and GetRectMaxY(R<i>) &gt;= uy then
            return i
        endif

        set i = i + 1
    endloop

    // oops
    return -1
endfunction
</i></i></i></i>


But still doesn't look right...
 

DrEvil

FCRI Associate!
Reaction score
111
@above me...
thats the whole point... if he could get the region/rect he wouldn't need to attach anything xD

@DioD
well theres 2 situations that are possible here:
1: Make sure no rects overlap and then iterating over all of them would be fine
2: Having 1 trigger for each rect... as its the only way to get the rect (attaching data to trigger)
 

DrEvil

FCRI Associate!
Reaction score
111
ohh... well I feel stupid now.
yeah attaching the rect data to the regions handle id would work perfectly xD

well all in all it depends on how he wants to structure it now, he has 3 options. which attaching to the region would be the easiest :)
 

Risen

New Member
Reaction score
4
If you create a separate trigger for each rect, you could do this with an attachment system, merely grabbing the rect attached to the [ljass]GetTriggeringTrigger()[/ljass]. Here's a dumbed-down example of what I use:

JASS:
struct Waypoint

        trigger onEnter //GetTriggeringTrigger
        rect whichRect //The entered rect
        region whichRegion //The entered region

        static method Actions takes nothing returns nothing
            local Waypoint this = GetData(GetTriggeringTrigger()) //Get Data attached to triggering trigger
            // Do stuff with the members of the struct
        endmethod

        static method create takes rect whichRect returns Waypoint
            local Waypoint this = Waypoint.allocate()
            set this.whichRect = whichRect
            set this.whichRegion = CreateRegion()
            call RegionAddRect(this.whichRegion,whichRect)
            set this.onEnter = CreateTrigger()
            call TriggerRegisterEnterRegion(this.onEnter,this.whichRegion,null)
            call TriggerAddAction(this.onEnter,function Waypoint.Actions)
            call SetData(this.onEnter,this) //Attach data to triggering trigger (only one rect for every event/trigger)
            return this
        endmethod
    endstruct


I don't know of a method that doesn't require individual triggers.

I used this method because it allowed me to use the GetTriggeringTrigger(), however, I have one question.

How exactly would I call this from another trigger? The idea I have at the moment is to use the event I have (in the first post) and just add Waypoint.create or Waypoint.Actions to the TriggerAddAction but I'm unsure which one to add.

I'm a little new to vJass.

Also, where do GetData and SetData come from?
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
I used this method because it allowed me to use the GetTriggeringTrigger(), however, I have one question.

How exactly would I call this from another trigger? The idea I have at the moment is to use the event I have (in the first post) and just add Waypoint.create or Waypoint.Actions to the TriggerAddAction but I'm unsure which one to add.

Essentially, when I'm setting up the rect/region trigger event thing, I call the Waypoint.create method, which returns a Waypoint. The Waypoint struct already has a trigger ('onEnter') set up to run whenever a unit enters the rect ('whichRect'). The region containing the rect is also stored ('whichRegion').

Thus, all you need to do is modify the Actions method, which will run whenever a unit enters the region, and refer to the individual components with 'this.' + the variable.

It would be rather simple to break it up into pieces, I simply copied it from Forest CTF, and removed all the unnecessary stuff. I also put it into a struct, for easy attachment. structs are integers, so you might need a slightly modified version of the code to directly attach a rect.

Also, where do GetData and SetData come from?

They are generic handle attachment functions, which you could replace with your own personal attachment system functions calls. Here's the source for those two functions in my map. They just use a hashtable:

JASS:

library Data
    globals        
        private hashtable hash
        private key HANDLES
    endglobals
    
    private struct DATA
        private static method onInit takes nothing returns nothing
            set hash = InitHashtable() //In an empty struct for auto-initialization
        endmethod
    endstruct
    
    function SetData takes handle h, integer data returns nothing
        //Attaches data to a handle
        call SaveInteger(hash,HANDLES,GetHandleId(h),data)
    endfunction
    
    function GetData takes handle h returns integer
        //Gets attached data to given handle
        return LoadInteger(hash,HANDLES,GetHandleId(h))
    endfunction
endlibrary
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top