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

[vJASS] TriggerRegisterEnterRegion not firing

Status
Not open for further replies.
Level 2
Joined
Jul 1, 2012
Messages
25
Hi there, first post, anyway I have a slightly annoying problem. I got this trigger that won't fire and I have no idea why.


JASS:
function Entering_Conditions takes nothing returns boolean
    return true // GetTriggeringRegion() == LoadRegionHandle(udg_PH_HT, GetHandleId(GetTriggerUnit()), 7)
endfunction


function Trig_Enters_Region_Actions takes nothing returns nothing
call BJDebugMsg("success")
endfunction

//===========================================================================
function InitTrig_Enters_Region takes nothing returns nothing
 local trigger t = CreateTrigger(  )
    call TriggerRegisterEnterRegion(t, AREGION1, null)
    call TriggerRegisterEnterRegion(t, AREGION2, null)
    call TriggerRegisterEnterRegion(t, AREGION3, null)
    call TriggerRegisterEnterRegion(t, AREGION4, null)
    call TriggerRegisterEnterRegion(t, AREGION5, null)
    call TriggerRegisterEnterRegion(t, AREGION6, null)
    call TriggerRegisterEnterRegion(t, AREGIONX1, null)
    call TriggerRegisterEnterRegion(t, AREGIONX2, null)
    //call TriggerAddCondition( t, Condition(function Entering_Conditions ))
    call TriggerAddAction( t, function Trig_Enters_Region_Actions )
set t = null
endfunction

That's the trigger and it will never show the "success" message.
The condition currently always return true for testing purposes.
I declare the globals in the global decleration like this.

JASS:
globals
region AREGION1 = null
region AREGION2 = null
region AREGION3 = null
region AREGION4 = null
region AREGION5 = null
region AREGION6 = null
region AREGIONX1 = null
region AREGIONX2 = null
endglobals

While googling my problem i noticed that other people don't seem to need to set the regions to null, if I don't however the initz crashes. Here is a part of the Initz.
JASS:
local unit u
local integer int
local integer int2
local region rgn
set udg_TownID_HT = InitHashtable()
set udg_Wall_HT = InitHashtable()
set udg_PH_HT = InitHashtable()
set AREGION1 = CreateRegion()
set AREGION2 = CreateRegion()
set AREGION3 = CreateRegion()
set AREGION4 = CreateRegion()
set AREGION5 = CreateRegion()
set AREGION6 = CreateRegion()
set AREGIONX1 = CreateRegion()
set AREGIONX2 = CreateRegion()
    set u = gg_unit_h003_0000
    call RegionAddRect(AREGION1, gg_rct_ARegion1)
    set rgn = AREGION1
    set int = GetHandleId(u)
    set int2 = GetHandleId(rgn)
    //Link town to its Region
    call SaveRegionHandle(udg_TownID_HT, int, 10, rgn)
    call SaveUnitHandle(udg_TownID_HT, int2, 10, u)

I first Create the region then i add a pre-placed rect to it.

JASS:
set u = gg_unit_h003_0000
    call RegionAddRect(AREGION1, gg_rct_ARegion1)
    set rgn = AREGION1
    set int = GetHandleId(u)
    set int2 = GetHandleId(rgn)
    //Link town to its Region
    call SaveRegionHandle(udg_TownID_HT, int, 10, rgn)
    call SaveUnitHandle(udg_TownID_HT, int2, 10, u)

That part is done for all the regions with different rects and units ofc.

So anyone see any problem?
 
Level 2
Joined
Jul 1, 2012
Messages
25
All actions but the trigger that does not fire are in the initialization :/ or did i misunderstand you?
 
Level 2
Joined
Jul 1, 2012
Messages
25
When debugging i tried to check if a point in the pre-placed rects was also in its respective region and it was. So it does get set correctly. I tried delayin the whole initz by a 0 timer anyways and nothing changed :/
 
Level 5
Joined
Jun 16, 2004
Messages
108
The fact that the map was crashing when you did not set the regions to null was a hint, but here is an explanation.

Compare the two triggers:
JASS:
function Trig_region_Actions takes nothing returns nothing
    call BJDebugMsg("entered region")
endfunction

//===========================================================================
function InitTrig_region takes nothing returns nothing
    local region r = CreateRegion()
    call RegionAddRect(r, gg_rct_fail)
    set gg_trg_region = CreateTrigger(  )
    call TriggerRegisterEnterRegion(gg_trg_region, r, null)
    call TriggerAddAction( gg_trg_region, function Trig_region_Actions )
endfunction

JASS:
globals
    region enter2 = null
endglobals

function enter_region takes nothing returns nothing
    call BJDebugMsg("entered region 2")
endfunction

// runs on map initialization via the check box 
// [url]http://puu.sh/Fd0W[/url]
function region_init takes nothing returns nothing
    set enter2 = CreateRegion()
    call RegionAddRect(enter2, gg_rct_fail)
endfunction

//===========================================================================
function InitTrig_region2 takes nothing returns nothing
    local trigger t
    set gg_trg_region2 = CreateTrigger(  )
    call TriggerAddAction( gg_trg_region2, function region_init )
    
    set t = CreateTrigger()
    call TriggerRegisterEnterRegion(t, enter2, null)
    
    call BJDebugMsg("Region handle was: " + I2S(GetHandleId(enter2)))
endfunction

The first creates and sets up the region right before registering the region event, both in the same function.

The second initializes the region to null and registers the region event in the trigger's initialization function, then leaves initializing the region to the trigger's "run on map initialization" option. As the BJDebugMsg will note if you try copying this trigger, the handle of the registered region is 0 (ie, it was null). Simply, the trigger's initialization function runs before a trigger's action "run on map initialization". Which makes sense, you should initialize triggers before running their actions.

Setting the region to null stopped the crash because triggers allow registering null things apparently. If you simply left the region declaration with no initial value, the trigger registration on the region variable would attempt to register whatever value the region variable starts with when declared but not initialized. Not sure if the value is completely arbitrary or not, but it causes a crash if you use it as a region.

(edit: well the thread is supposed to crash as mentioned below, but Wc3 itself is not supposed to)

I do believe PurgeandFire111 has been giving you working advice. If you put your trigger initialization function on a timer like he said, it probably would have worked. Whatever your "initz" function is, you are probably referring to the registered trigger action for "run on map initialization" or something, instead of the trigger initialization function, which is this: "InitTrig_Enters_Region". Delaying your other function is pointless because it already runs after the InitTrig function.

Alternatively, you can just move the trigger region event registrations to the end of your "initz" function.
 
Last edited:
Level 26
Joined
Aug 18, 2009
Messages
4,097
Setting the region to null stopped the crash because triggers allow registering null things apparently. If you simply left the region declaration with no initial value, the trigger registration on the region variable would attempt to register whatever value the region variable starts with when declared but not initialized. Not sure if the value is completely arbitrary or not, but it causes a crash if you use it as a region.

The declaration value is not arbitrary but simply empty and the current thread will halt when reading such an unset variable.
 
Level 5
Joined
Jun 16, 2004
Messages
108
Decided to open up Wc3 in a debugger and see if variables with no set value had anything in the value spot, looks like it is set to 0 by default. Which is what null's integer value is as well, as far as I remember. So yeah, I suppose the only thing stopping it from being treated as null is that Wc3 tries to skip over it.
 
Level 5
Joined
Jun 16, 2004
Messages
108
Not really sure what that was in response to. Guess I will clarify what I meant, though. What I was verifying was that when this sort of thing is done:
JASS:
globals
    region r
endglobals
The value r has is 0, though Wc3 simply skips over it in the code because it has a variable type check in place that fails, or something to that effect.

Likewise, in this:
JASS:
globals
    region r = null
endglobals
The value r has is again 0, though this time the type check that failed before with a value of 0 has a value of 7 (handle type).

In other words, if you patched one spot in Wc3 memory, variables with no value would be treated as 0 / null. Although in the first case I am not actually sure if the value is always 0, particularly in the case of local variables. The idea interested me and I wanted to know if it was similar to C++, in which uninitialized variables would simply have the last value put there. Despite Wc3 keeping track of whether a variable is initialized or not, it seems to zero that space anyway, which might just be a side effect of how Wc3 initializes space for variables.

Also, as far as Wc3 is concerned, null == 0, similarly to how in C++ NULL is effectively 0.

On a different note, I was able to crash Wc3 once while forming the test code I first posted, though I have not been able to reproduce it. Not sure what that was about.
 
Last edited:
Level 2
Joined
Jul 1, 2012
Messages
25
Thanks all and you're right i did just delay the Main Initialization trigger which ofc proved pointless.
 
Status
Not open for further replies.
Top