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

[JASS] Can't Pass Global Variable, why?

Status
Not open for further replies.
Level 2
Joined
Dec 1, 2009
Messages
8
I am trying to make a teleporting trigger and I can't get the teleporting trigger to accept the variables stored by another trigger.

The trigger that is supposed to store the variables in global arrays looks like this:
JASS:
globals
    unit array OrderedUnit
    real array OrderX
    real array OrderY
    integer array OrderID
endglobals

scope OrderDetection initializer Init
                    
    private function EventFilter takes nothing returns boolean


        if not( IsUnitType( GetFilterUnit(), UNIT_TYPE_HERO ) ) then
            //call BJDebugMsg("Ordered unit is not a hero.")
            return false
        else
        endif

    return true
    endfunction
    
    private function Actions takes nothing returns nothing
        local integer A = ( GetPlayerId( GetOwningPlayer( GetOrderedUnit() ) ) + 1 )    

        set OrderedUnit[A] = GetOrderedUnit()
        set OrderX[A] = GetOrderPointX()
        set OrderY[A] = GetOrderPointY()
        set OrderID[A] = GetIssuedOrderId()

        //call BJDebugMsg( "Player Nr: " + I2S(A) )
        //call BJDebugMsg( "Unit: " + GetUnitName(OrderedUnit[A]) + ". Order: " + OrderId2String(Order[A]) + "." )
        //call BJDebugMsg( "OrderX: " + R2S(OrderX[A]) + ". OrderY: " + R2S(OrderY[A]) + "." )
        
        set A = 0    
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer I = 0
      
        loop
            exitwhen I == 8
            call TriggerRegisterPlayerUnitEvent( t, Player(I), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, Filter( function EventFilter ) )
            set I = I +1
        endloop
        call TriggerAddAction( t, function Actions )
        set t = null
    endfunction
endscope

Please ignore the commented BJDebugMsg's. Using them as function debugging as I'm fairly new to JASS and really new to vJASS.

Next is the trigger that is supposed to use the stored variables: (trigger is part of a larger scope hence no scope - endscope)
JASS:
globals
    real EnterId = 0
    real ExitId = 0
endglobals

    private function TpConditions takes nothing returns boolean
        local unit tester = GetEnteringUnit()
    
        if not( IsUnitEnemy(tester, Bayus) ) then
            //call BJDebugMsg("Can not teleport; unit not enemy of Bayus")
            set tester = null
            return false
        else
        endif

        if not( IsUnitType(tester, UNIT_TYPE_HERO) ) then
            call BJDebugMsg("Only heroes can teleport")
            set tester = null
            return false
        else
        endif

        set tester = null
        return true
    endfunction

    private struct TpData
        string FxA = null
        string FxB = null
        unit U = null
        real Xa = 0
        real Ya = 0
        real Xb = 0
        real Yb = 0
        player P = null
        boolean Selected = false
    endstruct

    private function AfterWait takes nothing returns boolean
        local TpData d = TpData(KT_GetData())

        
        call DestroyEffect(AddSpecialEffect( d.FxB, d.Xb, d.Yb))        
        call SetUnitPosition( d.U, d.Xb, d.Yb )
        call SetUnitInvulnerable( d.U, false )
        call PauseUnit( d.U, false )
        call ShowUnit( d.U, true )

        if d.Selected == true then
            if (GetLocalPlayer() == d.P ) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ClearSelection()
                call SelectUnit( d.U, true)
            else
            endif
        else
        endif


        call IssuePointOrderById( OrderedUnit[A], OrderID[A], OrderX[A], OrderY[A] ) //<-- This won't so anything because the variables null and 0 respectively.
        
        call d.destroy()
        //set A = 0
        return true // No returning false for a simple wait, it only fires one time.
    endfunction

    private function TpActions takes nothing returns nothing
        local TpData d = TpData.create()
        local real Id = GetHandleId(GetTriggeringRegion())
        local integer A = ( GetPlayerId( GetOwningPlayer( GetEnteringUnit() ) ) + 1 )    
        
        if TpConditions() then
            if Id == ExitId then
                call BJDebugMsg("Your hero is exiting town")
                set d.FxA = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl"
                set d.FxB = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
                set d.U = GetEnteringUnit()
                set d.Xa = GetUnitX( d.U )
                set d.Ya = GetUnitY( d.U )
                set d.Xb = GetRectCenterX( gg_rct_TpHeroCageDest )
                set d.Yb = GetRectCenterY( gg_rct_TpHeroCageDest )
                set d.P = GetOwningPlayer( d.U )
                set d.Selected = IsUnitSelected( d.U, d.P )
                call SetUnitInvulnerable( d.U, true )
                call PauseUnit( d.U, true )
                call DestroyEffect(AddSpecialEffect( d.FxA, d.Xa, d.Ya))
                call ShowUnit( d.U, false )
                call KT_Add(function AfterWait, d, 1.3)
            else
            endif
    
            if Id == EnterId then
                call BJDebugMsg("Your hero is entering town")
                set d.FxA = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl"
                set d.FxB = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
                set d.U = GetEnteringUnit()
                set d.Xa = GetUnitX( d.U )
                set d.Ya = GetUnitY( d.U )
                set d.Xb = GetRectCenterX( gg_rct_TpTownDest )
                set d.Yb = GetRectCenterY( gg_rct_TpTownDest )
                set d.P = GetOwningPlayer( d.U )
                set d.Selected = IsUnitSelected( d.U, d.P )
                call SetUnitInvulnerable( d.U, true )
                call PauseUnit( d.U, true )
                call DestroyEffect(AddSpecialEffect( d.FxA, d.Xa, d.Ya))
                call ShowUnit( d.U, false )
                call KT_Add(function AfterWait, d, 1.3)                
            else
            endif
        else
        endif

        call BJDebugMsg( "Player Nr: " + I2S(A) )
        call BJDebugMsg( "Unit: " + GetUnitName(OrderedUnit[A]) + ". Order: " + OrderId2String(OrderID[A]) + "." )
        call BJDebugMsg( "OrderX: " + R2S(OrderX[A]) + ". OrderY: " + R2S(OrderY[A]) + "." )
        
        set Id = 0
    endfunction

    private function RegisterTp takes nothing returns nothing
        local trigger t = CreateTrigger()
        local region enter = CreateRegion()
        local region exit = CreateRegion()
        call RegionAddRect( enter, gg_rct_TpEnterTown )
        call RegionAddRect( exit, gg_rct_TpExitTown )
        set EnterId = GetHandleId(enter)
        set ExitId = GetHandleId(exit)
        call TriggerRegisterEnterRegion( t, enter, null)
        call TriggerRegisterEnterRegion( t, exit, null)
        call TriggerAddAction( t, function TpActions )
        set t = null
    endfunction

So, any help and explanation would be appreciated greatly.
Please just take into account, that I'm nowhere near any decent level of utilizing JASS and vJASS yet.
 
Do the values just return as 0? Or does the code just not work? (If so, which aspect doesn't work? Unless you mean the entire thing)

Also, which debug messages appear? This will help us find the problem a bit more easily.

Remove the comments after setting the variables and be sure that it displays the proper values after each issued order.
 
Level 2
Joined
Dec 1, 2009
Messages
8
JASS:
globals
    unit array OrderedUnit[8]
    real array OrderX[8]
    real array OrderY[8]
    integer array OrderID[8]
endglobals

scope OrderDetection initializer Init
                    
    private function EventFilter takes nothing returns boolean


        if not( IsUnitType( GetFilterUnit(), UNIT_TYPE_HERO ) ) then
            //call BJDebugMsg("Ordered unit is not a hero.")
            return false
        else
        endif

    return true
    endfunction
    
    private function Actions takes nothing returns nothing
        local integer A = ( GetPlayerId( GetOwningPlayer( GetOrderedUnit() ) ) + 1 )    

        set OrderedUnit[A] = GetOrderedUnit()
        set OrderX[A] = GetOrderPointX()
        set OrderY[A] = GetOrderPointY()
        set OrderID[A] = GetIssuedOrderId()

        call BJDebugMsg( "Player Nr: " + I2S(A) ) // Returns proper values.
        call BJDebugMsg( "Unit: " + GetUnitName(OrderedUnit[A]) + ". Order: " + OrderId2String(Order[A]) + "." ) // returns proper
        call BJDebugMsg( "OrderX: " + R2S(OrderX[A]) + ". OrderY: " + R2S(OrderY[A]) + "." ) // returns proper
        
        set A = 0    
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer I = 0
      
        loop
            exitwhen I == 8
            call TriggerRegisterPlayerUnitEvent( t, Player(I), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, Filter( function EventFilter ) )
            set I = I +1
        endloop
        call TriggerAddAction( t, function Actions )
        set t = null
    endfunction
endscope

JASS:
globals
    real EnterId = 0
    real ExitId = 0
endglobals

    private function TpConditions takes nothing returns boolean
        local unit tester = GetEnteringUnit()
    
        if not( IsUnitEnemy(tester, Bayus) ) then
            //call BJDebugMsg("Can not teleport; unit not enemy of Bayus")
            set tester = null
            return false
        else
        endif

        if not( IsUnitType(tester, UNIT_TYPE_HERO) ) then
            call BJDebugMsg("Only heroes can teleport")
            set tester = null
            return false
        else
        endif

        set tester = null
        return true
    endfunction

    private struct TpData
        string FxA = null
        string FxB = null
        unit U = null
        real Xa = 0
        real Ya = 0
        real Xb = 0
        real Yb = 0
        player P = null
        boolean Selected = false
    endstruct

    private function AfterWait takes nothing returns boolean
        local TpData d = TpData(KT_GetData())

        
        call DestroyEffect(AddSpecialEffect( d.FxB, d.Xb, d.Yb))        
        call SetUnitPosition( d.U, d.Xb, d.Yb )
        call SetUnitInvulnerable( d.U, false )
        call PauseUnit( d.U, false )
        call ShowUnit( d.U, true )

        if d.Selected == true then
            if (GetLocalPlayer() == d.P ) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ClearSelection()
                call SelectUnit( d.U, true)
            else
            endif
        else
        endif


        call IssuePointOrderById( OrderedUnit[A], OrderID[A], OrderX[A], OrderY[A] ) // <-- Does nothing in-game, all likely because there are missing values in the array variables.
        
        call d.destroy()
        //set A = 0
        return true // No returning false for a simple wait, it only fires one time.
    endfunction

    private function TpActions takes nothing returns nothing
        local TpData d = TpData.create()
        local real Id = GetHandleId(GetTriggeringRegion())
        local integer A = ( GetPlayerId( GetOwningPlayer( GetEnteringUnit() ) ) + 1 )    
        
        if TpConditions() then
            if Id == ExitId then
                call BJDebugMsg("Your hero is exiting town")
                set d.FxA = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl"
                set d.FxB = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
                set d.U = GetEnteringUnit()
                set d.Xa = GetUnitX( d.U )
                set d.Ya = GetUnitY( d.U )
                set d.Xb = GetRectCenterX( gg_rct_TpHeroCageDest )
                set d.Yb = GetRectCenterY( gg_rct_TpHeroCageDest )
                set d.P = GetOwningPlayer( d.U )
                set d.Selected = IsUnitSelected( d.U, d.P )
                call SetUnitInvulnerable( d.U, true )
                call PauseUnit( d.U, true )
                call DestroyEffect(AddSpecialEffect( d.FxA, d.Xa, d.Ya))
                call ShowUnit( d.U, false )
                call KT_Add(function AfterWait, d, 1.3)
            else
            endif
    
            if Id == EnterId then
                call BJDebugMsg("Your hero is entering town")
                set d.FxA = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl"
                set d.FxB = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
                set d.U = GetEnteringUnit()
                set d.Xa = GetUnitX( d.U )
                set d.Ya = GetUnitY( d.U )
                set d.Xb = GetRectCenterX( gg_rct_TpTownDest )
                set d.Yb = GetRectCenterY( gg_rct_TpTownDest )
                set d.P = GetOwningPlayer( d.U )
                set d.Selected = IsUnitSelected( d.U, d.P )
                call SetUnitInvulnerable( d.U, true )
                call PauseUnit( d.U, true )
                call DestroyEffect(AddSpecialEffect( d.FxA, d.Xa, d.Ya))
                call ShowUnit( d.U, false )
                call KT_Add(function AfterWait, d, 1.3)                
            else
            endif
        else
        endif

        call BJDebugMsg( "Player Nr: " + I2S(A) ) // returns nothing in-game.
        call BJDebugMsg( "Unit: " + GetUnitName(OrderedUnit[A]) + ". Order: " + OrderId2String(OrderID[A]) + "." ) // both returns nothing in-game.
        call BJDebugMsg( "OrderX: " + R2S(OrderX[A]) + ". OrderY: " + R2S(OrderY[A]) + "." ) // both returns 0 in-game.
        
        set Id = 0
    endfunction

    private function RegisterTp takes nothing returns nothing
        local trigger t = CreateTrigger()
        local region enter = CreateRegion()
        local region exit = CreateRegion()
        call RegionAddRect( enter, gg_rct_TpEnterTown )
        call RegionAddRect( exit, gg_rct_TpExitTown )
        set EnterId = GetHandleId(enter)
        set ExitId = GetHandleId(exit)
        call TriggerRegisterEnterRegion( t, enter, null)
        call TriggerRegisterEnterRegion( t, exit, null)
        call TriggerAddAction( t, function TpActions )
        set t = null
    endfunction

All the values retrieved in the first trigger returns what they should, but all the values in the 2nd returns null for units and 0 for co-ords and orderId's.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Lol I like the set A = 0 part. That's funny.

Try removing the line set t = null like so:

JASS:
call TriggerAddAction(t, function Actions)
//set t = null     <-- Comment out this line.
 
Level 9
Joined
Nov 28, 2008
Messages
704
Setting t to nothing would help exactly not.

You also dont have to set ints to 0, uno.

unit array OrderedUnit[8]
real array OrderX[8]
real array OrderY[8]
integer array OrderID[8]

Why are you putting an [8]? Remove that. See if that fixes it. (It probably will)
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Mooglefrooglian said:
Setting t to nothing would help exactly not.

I remember once having some issue with a trigger not working correctly because I nulled the trigger, but it was awhile ago so I'm just trying to help with what I can --especially since the code seems fine.

The [8] actually does nothing. Global arrays in vJass can be declared to extend the limit of 8191, which is why the syntax is allowed. If you have a number lower than 8191, it will simply declare a normal array.
 
Level 2
Joined
Dec 1, 2009
Messages
8
Commentin out t = null did nothing.
Those [8] were just a memory lapse on my part from an experiment I wanted to try out.
Removing [8] from the array declaration didn´t help either.

-EDIT- Oh didn't know that's what it was for. heh you learn something every day it seems :eek:)
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I copied the code into another map, changed your Order[A] to OrderID[A] and it worked fine. I had to change it because it was giving me a compile error that Order was not defined (plus based on the logic of the script, I think that's what you should be using).

I think I may be looking at the wrong code.

JASS:
        local real Id = GetHandleId(GetTriggeringRegion())

This should be an integer, not a real.

JASS:
    real EnterId = 0
    real ExitId = 0

These global variables should also be integers, since you are using them to store handle IDs, which are integers.

If correcting the types doesn't help any, try printing the value of A and make sure that it is trying to reference the correct index of the array.
 
Level 2
Joined
Dec 1, 2009
Messages
8
LOL soh, my bad I actually have that as OrderID[A], just forget to type it there after I copied the code into thread. :eek:

I copied the code into another map, changed your Order[A] to OrderID[A] and it worked fine. I had to change it because it was giving me a compile error that Order was not defined (plus based on the logic of the script, I think that's what you should be using).

I think I may be looking at the wrong code.

JASS:
        local real Id = GetHandleId(GetTriggeringRegion())

This should be an integer, not a real.

JASS:
    real EnterId = 0
    real ExitId = 0

These global variables should also be integers, since you are using them to store handle IDs, which are integers.

If correcting the types doesn't help any, try printing the value of A and make sure that it is trying to reference the correct index of the array.

Didn't help.
JASS:
         call BJDebugMsg( "Player Nr: " + I2S(A) ) // returns nothing in-game.
Prints the Value of A if I'm not mistaken?
 
Level 9
Joined
Nov 28, 2008
Messages
704
Try rewriting and using structs, maybe? You seem to be doing something similar with global arrays, why not go the full step and use the same-as-global-arrays-but-prettier-syntax structs?
 
Level 2
Joined
Dec 1, 2009
Messages
8
uhm, cause structs still scare me a bit. I'm only slowly getting used to using them and I would have NO idea how to use a struct in that way.

The only reason I even have structs in my script is because of how Jesus4Lyf posted a template for using that struct with a timer.

But if you have the time and patience to nudge me in the right direction, I'd be glad to make a try.
 
Level 9
Joined
Nov 28, 2008
Messages
704
unit array OrderedUnit[8]
real array OrderX[8]
real array OrderY[8]
integer array OrderID[8]

Instead of this, you might do:

JASS:
struct OrderSomething //needs better name
    unit orderedUnit
    real orderX
    real orderY
    integer order
endstruct

Im going to take back that recommendation though. It really doesnt simplify such a simple thing with three arrays, especially if you dont know how to work them and you already have something good enough in place.
 
Level 2
Joined
Dec 1, 2009
Messages
8
@ Berbanog
Then I don't know what you mean.

@ MoogleFrooglian
Well I know how to make that struct, but how to access an instance of it from another trigger.... Something I still need to learn.
 
Level 2
Joined
Dec 1, 2009
Messages
8
could you make an example with different variables, not unlike what I need to do so I might comprehend where all of that goes?

If I want to store all the info I would do?
JASS:
    struct PointOrder
        static hashtable ht
        player p
        integer u
        integer o
        real x
        real y
    
        static method create takes player p returns PointOrder
            local Order current = Order.allocate()
            set current.p = p
            set current.u = GetTriggerUnit()
            set current.o = OrderId(GetTriggerUnit())
            set current.x = GetOrderPointX()
            set current.y = GetOrderPointY()
            call SaveInteger( PointOrder.ht, current.p, 1,current.u )
            call SaveInteger( PointOrder.ht, current.p, 2,current.o )
            call SaveInteger( PointOrder.ht, current.p, 3,current.x )
            call SaveInteger( PointOrder.ht, current.p, 4,current.y )
            return PointOrder
        endmethod
.....
...
 
Status
Not open for further replies.
Top