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

[Trigger] Need to Find an Alternate 'Wait' Method for Unit Respawn

Status
Not open for further replies.
Level 3
Joined
Feb 25, 2019
Messages
35
I can't recall where from, but I found this as a tutorial method for respawn of creeps (RPG style). I've really enjoyed the concept and have used it quite creatively in many of the triggers for this game (using the CV for stuff.. etc.) I only just recently learned that Wait Game-Time second causes a leak due to a bug. I'd replaced its overuse in all of my triggers, never thinking to check this one...

Thus, here we are. I need to replace the 'wait game-time seconds' with a new method of waiting the duration of that variable before performing those actions without losing the information.

Countdown timers make no sense to me. I don't understand how they work at all. If they are the solution, please also answer the following questions for me:

  1. I've read that they must be 'destroyed after use' and that you must pause them first in order to do so. Is this true, and if so, how do I destroy it? Is this done in custom script?
  2. Does that mean that setting a variable for a timer is sort of like opening up a vacancy for a timer that can then be set/started via "start timer as a one-shot timer?" If that is the case, would that action be unavailable until the first timer started finishes?
  3. An extension of question 2, is this where I've read that timers need their array sizes changed so additional values can be initialized?
  4. Do I 'have' to interact with a timer window when making a timer or is that only when I want the timer to be visible in the top right corner, in-game?
  5. If I end up using timers, wouldn't that also require me to add the event, "timer (the one started in the respawn trigger) expires" each time a unit dies & needs to be respawned?
I feel like the answer could also be hashtables which terrifies me as well. Either way, any feedback is appreciated, thank you!

Respawn
Events
Unit - A unit Dies
Conditions
(Owner of (Triggering unit)) Equal to Neutral Hostile
(Custom value of (Triggering unit)) Greater than 0
Actions
Custom script: local integer i = GetUnitTypeId(GetTriggerUnit())
Custom script: local integer ii = GetUnitUserData(GetTriggerUnit())
Wait Respawn_Time game-time seconds
Custom script: call SetUnitUserData(CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE),i,GetLocationX(udg_Creep_Point[ii]),GetLocationY(udg_Creep_Point[ii]),udg_Creep_Facing[ii]),ii)
Unit - Set the custom value of (Last created unit) to (Custom value of (Triggering unit))
 
Level 7
Joined
Apr 17, 2017
Messages
316
1)Gui Timers are created at map initialization so you don't need to destroy them if you are going to use. So each time your trigger is run, you are simply starting your timer over and over again. To sum it up: you don't need to destroy a global timer if you are using gui.
2)Timers don't basically add "wait function" in the same trigger. So you need 2 triggers. 1 for the actions before timers, then 1 for what will happen after that timer is expired.
4)You don't have to interact with timer window.
5)Yes it would, unless you know jass.
Also, an alternative to timers, you can use periodic timer event and set a counter, but it's not that that efficient. If you are going to use timers, since you will have 2 triggers, you need to get rid of those local variables which means you need either some kind of indexing or hashtables. Because if another unit dies before your timer is expired then you will have some problems.
 
Level 3
Joined
Feb 25, 2019
Messages
35
1)Gui Timers are created at map initialization so you don't need to destroy them if you are going to use. So each time your trigger is run, you are simply starting your timer over and over again. To sum it up: you don't need to destroy a global timer if you are using gui.
2)Timers don't basically add "wait function" in the same trigger. So you need 2 triggers. 1 for the actions before timers, then 1 for what will happen after that timer is expired.
4)You don't have to interact with timer window.
5)Yes it would, unless you know jass.
Also, an alternative to timers, you can use periodic timer event and set a counter, but it's not that that efficient. If you are going to use timers, since you will have 2 triggers, you need to get rid of those local variables which means you need either some kind of indexing or hashtables. Because if another unit dies before your timer is expired then you will have some problems.
I see, thank you. Yeah, I originally tried setting up a periodic trigger... but I couldn't quite figure the details out. I'm not sure how I'd go about making it run separate counters through for each unit... Unit[custom value] perhaps? but how do I make it so only once the first trigger runs, the second trigger starts adding value to the Unit[custom value]?
 
Level 8
Joined
Aug 17, 2013
Messages
112
Alternative is making a dummy unit/structure for neutral hostile that can train the units "respawning"

If/then/else actions can define which kinda unit died and tell the dummy what to train

Add a generic timer to your dummy equal to the "build time" of the unit aka the respawn time.
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,873
It seems you have difficulty in finding things which are right in front of you:
  • Actions
    • Wait 2.00 seconds
    • Wait 2.00 game-time seconds
The first wait does the job nicely, no leaks due to "bugs". While the second one, as you said, it is best to avoid it. So use the former.
While there are alternatives, they're too overcomplicated, specially for you at the moment, and in my opinion, they're absurd and ridiculous. Dynamic Indexing will help you dealing with waits.
 
Level 3
Joined
Feb 25, 2019
Messages
35
It seems you have difficulty in finding things which are right in front of you:
  • Actions
    • Wait 2.00 seconds
    • Wait 2.00 game-time seconds
The first wait does the job nicely, no leaks due to "bugs". While the second one, as you said, it is best to avoid it. So use the former.
While there are alternatives, they're too overcomplicated, specially for you at the moment, and in my opinion, they're absurd and ridiculous. Dynamic Indexing will help you dealing with waits.
This is poetic. The reason your reply is a waste of time to consider is 'right in front of you.' I explained that I used 'both' those functions and I also explained why I was seeking alternatives. You said to use the former, but it can't be used for the purposes I required when writing this post. The wait has to be in game time, which has "leaks due to bugs." I figured it out with the help of the many capable individuals who were kind enough to offer helpful suggestions.
 
Level 39
Joined
Feb 27, 2007
Messages
5,008
For future reference the only thing wrong with Wait Game-Time is one relatively minor reference leak; it's not a 'bug' so much as it is 'the guys who wrote the GUI functions didn't give a flying fuck about reference leaks'. You can put this fixed version of the game-time wait function into you map's custom script section (or into another trigger) and then call it manually with a custom script:
JASS:
library GameTimeWaitFix
function GameWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call PauseTimer(t)
        call DestroyTimer(t)
        set t = null
    endif
endfunction
endlibrary
  • Custom script: call GameWait(2.00)
  • -------- or you can use a variable to make it easier when the duration involves some GUI functions --------
  • Set TIME = 2.00*(Real(Intelligence of (Triggering Unit)))
  • Custom script: call GameWait(udg_TIME)
 
Status
Not open for further replies.
Top