• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Solved] Respawning trigger JASS/GUI

Status
Not open for further replies.
Level 11
Joined
Jan 2, 2016
Messages
472
JASS:
function TimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer idx = LoadInteger(udg_int_table, GetHandleId(t), 0)
    call BJDebugMsg("Running TimerExpires")
    call CreateUnitAtLoc(Player(PLAYER_NEUTRAL_AGGRESSIVE),GetUnitTypeId(LoadUnitHandle(udg_ghash,GetHandleId(t), 0)), udg_neutral_hostile_pos[idx] , 0)

    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function DelayedRespawn takes integer idx returns nothing
    local timer t = CreateTimer()
    call SaveUnitHandle( udg_ghash, GetHandleId(t), 0, GetTriggerUnit())
    call SaveInteger( udg_int_table, GetHandleId(t), 0, idx)
    call TimerStart(t,3,false,function TimerExpires)
    call BJDebugMsg("Running DelayedRespawn")
    set t = null
endfunction


  • Events
    • Unit - A unit dies
  • Conditions
    • ((Triggering Unit) belongs to an ally of Neutral Hostile) equal to True
  • Actions
    • Custom script: call GetItemPool() // you can ignore this
    • For each (Integer A) from 1 to neutral_unit_idx, do (Actions)
      • Loop - Actions
        • If (All conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Triggering Unit) equal to neutral_hostile_unit[(Integer A)]
          • Then - Actions
            • Custom script: call DelayedRespawn(bj_forLoopAIndex)
          • Else - Actions


Both triggers run, although the unit is not created.I'm new to jass so i might not be doing something right.
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
Are the functions even running (are the messages displayed)?
GetTriggerUnit() could be the problem
Potential problem with GetTriggerUnit: A trigger runs between the creation of the units and overwrites GetTriggerUnit(). This could happen because CreateUnit can trigger a "unit ebters region" event for example.
I would write the GUI trigger in JASS, store GetTriggerUnit() to a local variable at the beginning, because then you don't have to call GetTriggerUnit() so often. Instead of
DelayedRespawn(integer) I would use DelayedRespawn(integer, integer) with your idx and the unit-type of GetTriggerUnit()
The unit you are storing in the hashtable could be null, when the delayed functon is called, because the corpse decayed for example. Storing the unit-type at the beginning would solve this.
Use:
local unit u=GetTriggerUnit()
local integer i = GetUnitTypeId(u)
at the beginning, becaue then it's safer and more efficient, because these functions are not called in the loop.

Why do you use 2 hashtables?
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
If both functions run, one of the following parameters must be wrong:
GetUnitTypeId(LoadUnitHandle(udg_ghash,GetHandleId(t), 0))
- the unit is null (because it decayed or was removed) -> use unit-type instead as explained
- the hashtable was not initialized
udg_neutral_hostile_pos[idx]
- variable was not initiailized for idx
 
Level 11
Joined
Jan 2, 2016
Messages
472
Hm I changed it as you've said still doesn't work.Additionally just to check if my positions run i added a ping action and they work.

As for hashtable initilization, i have no idea if it's initialized.I only use it in the fucntion "DelayedRespawn".

EDIT:
JASS:
function TimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer idx = LoadInteger(udg_ghash, GetHandleId(t), 1)
    local integer unitID = LoadInteger(udg_ghash, GetHandleId(t), 0)
    call BJDebugMsg("Running TimerExpires")
    call CreateUnitAtLoc(Player(PLAYER_NEUTRAL_AGGRESSIVE),unitID, udg_neutral_hostile_pos[idx] , 0)

    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function DelayedRespawn takes integer idx,integer unitID returns nothing
    local timer t = CreateTimer()
    call SaveInteger(udg_ghash, GetHandleId(t), 0, unitID)
    call SaveInteger( udg_ghash, GetHandleId(t), 1, idx)
    call TimerStart(t,3,false,function TimerExpires)
    call BJDebugMsg("Running DelayedRespawn")
    set t = null
endfunction
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
You have to create the hashtable, before you can store anything in it.
This is usually done at map initialization.
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Hash = (Last created hashtable)
If you created the hashtable and it's still not working, please post your triggers.
 
Level 15
Joined
Mar 25, 2016
Messages
1,327
Hashtables are so useful though. It's so easy to attach data to any object in the game.

Also make sure to flush the hashtable, when you no longer need the data.
In this case you want to erase all data attached to the timer, so you call
JASS:
call FlushChildHashtable(hashtable h,integer parentKey)
parentkey would be GetHandleId(t) in your case.

In this case it is more efficient to store GetHandleId(t) in a local integer variable, so you have to call it only once.
 
Level 11
Joined
Jan 2, 2016
Messages
472
Here is the final code.
JASS:
function TimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer hnd_id = GetHandleId(t)
    local integer idx = LoadInteger(udg_ghash, hnd_id, 1)
    local integer unitID = LoadInteger(udg_ghash, hnd_id, 0)
    set udg_neutral_hostile_unit[idx] = CreateUnitAtLoc(Player(PLAYER_NEUTRAL_AGGRESSIVE),unitID, udg_neutral_hostile_pos[idx] , 0)
   
    call FlushChildHashtable(udg_ghash, hnd_id)
    call PauseTimer(t)
    call DestroyTimer(t)
   
    set t = null
endfunction

function DelayedRespawn takes integer idx,integer unitID returns nothing
    local timer t = CreateTimer()
    local integer hnd_id = GetHandleId(t)
    call SaveInteger(udg_ghash, hnd_id, 0, unitID)
    call SaveInteger( udg_ghash, hnd_id, 1, idx)
    call TimerStart(t,25,false,function TimerExpires)
   
    set t = null
endfunction

  • Events
    • Unit - A unit dies
  • Conditions
    • ((Triggering Unit) belongs to an ally of Neutral Hostile) equal to True
  • Actions
    • Custom script: local unit u = GetTriggerUnit()
    • Custom script: local integer unitID = GetUnitTypeId(u)
    • Custom script: call GetItemPool() // you can ignore this
    • For each (Integer A) from 1 to neutral_unit_idx, do (Actions)
      • Loop - Actions
        • If (All conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Triggering Unit) equal to neutral_hostile_unit[(Integer A)]
          • Then - Actions
            • Custom script: call DelayedRespawn(bj_forLoopAIndex,unitID)
          • Else - Actions
    • Custom script: set u = null
 
Status
Not open for further replies.
Top