• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[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 16
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 16
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 16
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 16
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