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

Timer Reset Problem

Status
Not open for further replies.
Level 6
Joined
May 15, 2009
Messages
191
Hello fellow members, it's Battlehound asking for help again.

This trigger im making works alright - the first time it runs. What is supposed to do is; whenever something dies near a specific hero (BAR_Ram_U) he will gain additional armor for X seconds. This all works very fine, but the problem is, I need the timer that counts down towards the removal of the armor, to be somewhat resat whenever something dies.

'Cause if two additional units die whilst the armor buff is active, the old timer will still be running, and they will yield nothing. And for whatever reason, the trigger completely stops working after functioning once.

So yeah, im pretty lost. Help is much appreciated.

  • Rampage Per Die
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Set BAR_Ram_Tempp = (Position of (Triggering unit))
      • Unit Group - Pick every unit in (Units within 900.00 of BAR_Ram_Tempp matching ((Matching unit) Equal to BAR_Ram_U)) and do (Actions)
        • Loop - Actions
          • Unit Group - Add (Picked unit) to BAR_Ram_Tempg
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in BAR_Ram_Tempg) Equal to 1
        • Then - Actions
          • Unit - Add Rampage Armor Bonus to BAR_Ram_U
          • Unit - Set level of Rampage Armor Bonus for BAR_Ram_U to (Level of Rampage for BAR_Ram_U)
          • Countdown Timer - Start BAR_Ram_Timer as a One-shot timer that will expire in (4.00 + (Real((Level of Rampage for BAR_Ram_U)))) seconds
        • Else - Actions
      • Custom script: call RemoveLocation(udg_BAR_Ram_Tempp)
      • Custom script: call DestroyGroup(udg_BAR_Ram_Tempg)
      • Trigger - Turn off (This trigger)
  • Rampage Remove
    • Events
      • Time - BAR_Ram_Timer expires
    • Conditions
    • Actions
      • Unit - Remove Rampage Armor Bonus from BAR_Ram_U
      • Trigger - Turn on Rampage Per Die <gen>
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
What you want is each armor bonus last for an own an specific amount of time?
Is it a cummulative bonus?
Is it supposed to work for more than 1 hero at the same time?
What exactly are you trying to achieve?

Replace your first trigger with the following. It's, by far, more efficient.

  • Rampage Per Die
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Set Point1 = (Position of (Triggering Unit))
      • Set Point2 = (Position of BAR_Ram_U)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Distance between Point1 and Point2 is less than or equal to 900
        • Then - Actions
          • Unit - Add Rampage Armor Bonus to BAR_Ram_U
          • Unit - Set level of Rampage Armor Bonus for BAR_Ram_U to (Level of Rampage for BAR_Ram_U)
          • Countdown Timer - Start BAR_Ram_Timer as a One-shot timer that will expire in (4.00 + (Real((Level of Rampage for BAR_Ram_U)))) seconds
        • Else - Actions
      • Custom script: call RemoveLocation(Point1)
      • Custom script: call RemoveLocation(Point2)
      • Trigger - Turn off (This trigger)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Yeh, I was waiting for his response to finish the trigger. I just wanted to show him the distance comparison and avoid those UnitGroups
 
Level 6
Joined
May 15, 2009
Messages
191
Thx for the tips guys, I will work on making the trigger more efficient, like you said Spartipilo. And also, after Kingz pointed out my turn off trigger mistake, I figured I was gonna need an If/Then/Else function somewhere? So that the trigger only actually runs if BAR_Ram_U is around.

So yeah, thx for the help. It works a charm now. Just gonna post the trigger, in case anyone wanna take a look.

  • Rampage Per Die
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Set BAR_Ram_Tempp = (Position of (Triggering unit))
      • Set BAR_Ram_Tempp2 = (Position of BAR_Ram_U)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between BAR_Ram_Tempp and BAR_Ram_Tempp2) Less than or equal to 900.00
        • Then - Actions
          • Unit - Add Rampage Armor Bonus to BAR_Ram_U
          • Unit - Set level of Rampage Armor Bonus for BAR_Ram_U to (Level of Rampage for BAR_Ram_U)
          • Special Effect - Create a special effect attached to the origin of BAR_Ram_U using Abilities\Spells\NightElf\BattleRoar\RoarCaster.mdl
          • Special Effect - Destroy (Last created special effect)
          • Countdown Timer - Start BAR_Ram_Timer as a One-shot timer that will expire in (4.00 + (Real((Level of Rampage for BAR_Ram_U)))) seconds
          • Trigger - Turn off (This trigger)
        • Else - Actions
      • Custom script: call RemoveLocation(udg_BAR_Ram_Tempp)
      • Custom script: call RemoveLocation(udg_BAR_Ram_Tempp2)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Don't create temporal variables for each ability. Use global generic points for all your abilities. Doesn't matter, since they will be removed at the end of the trigger. So, replace BAR_Ram_Tempp and BAR_Ram_TEmpp2 for temporal global point variables (an do the same for all your other abilities). As long as you don't use any "Wait" action, or need a point set in one trigger, to work with it with another trigger, use the same temporal variables.

3 generic temporal point global variables should be enough for almost anything you wan't to do.

Variables takes up memory space, so, it's better to have as less as possible, and make good use of them. That's why we use some variables as "temporals", since the value the variable hold is just need for a small while, in this case, just to be able to clean the leak it produces at the end of the trigger.

Another thing: You didn't declare "BAR_Ram_U" anywhere in this trigger.
 
Level 6
Joined
May 15, 2009
Messages
191
Ok, I thought that temporal variables simply ment and they would be deleted at the end of the trigger, and not be carried on to another trigger (Such as triggers that require loops and what not) and also, I thought I had to create variables for each trigger, so that when you run two triggers at the time, they won't overwrite the variables, or is that not possible?

And also, the reason why BAR_Ram_U is not set to an actual unit anywhere in this trigger, is because it was already preset. I have a trigger which runs as soon as the Barbarian(BAR_RAM_U) learns the matching ability, and then it saves him into that variable. And since he will have to learn this Rampage ability, before he can enjoy it's benefits, I figured I would just set the Unit-variable then.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Globals aren't deleted at the end of the trigger. All globals variables takes a certain amount of memory when they're created, even if you haven't assigned any value to it.

What if you have 2 barbarians on the game? The 2nd barbarian would replace the first one on the variable. What if noone picks the barbarian? You would have a global variable taking space you're not using.

Most triggers that require loops uses a UnitGroup and a Hashtable. 1 Trigger to set the data on the Hashtable, and the loop, wich retrieves the data from the Hash and uses it.

If the barbarian has to learn the ability to use it, there's no use in setting him into an specific variable, since the only way to cast the ability is knowing it. You just need to detect the level of the ability for the dying unit. If level is > 0 then it's the barbarian, for sure, and he has the ability, for sure. From there on you use the Temporal Unit variable to avoid repetitive callings
 
Level 6
Joined
May 15, 2009
Messages
191
What if you have 2 barbarians on the game? The 2nd barbarian would replace the first one on the variable. What if noone picks the barbarian? You would have a global variable taking space you're not using.

I probaly should've mentioned this earlier; two barbarians is not an option in this map, but you are right about the variable taking up space if noone picks the barbarian.

If the barbarian has to learn the ability to use it, there's no use in setting him into an specific variable, since the only way to cast the ability is knowing it. You just need to detect the level of the ability for the dying unit. If level is > 0 then it's the barbarian, for sure, and he has the ability, for sure. From there on you use the Temporal Unit variable to avoid repetitive callings

I've got a feeling that one of us misunderstood the other here. How would I know where the Barbarian was when a unit died, without having the Barbarian saved into a variable? This is not an active ability, it is a passive for the hero, which will jump into effect when something dies in his vicinity. And there is no event for "A unit dies near BAR_RAM_U."

And also, what did you mean when you said temporal unit variable? If it is stuff like event response units and so on, then I don't see anyway of calling the Barbarian, without him being saved in a variable.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
there is no event for "A unit dies near BAR_RAM_U."

That's right. In that case, where Only 1 barbarian can be on the game at a time, and you need to detect the distance between this unit and the dying unit, your solution is nearly as good as it can be in GUI.

Remember to replace these
- Set BAR_Ram_Tempp = (Position of (Triggering unit))
- Set BAR_Ram_Tempp2 = (Position of BAR_Ram_U)

with Temp Point variables (for use in any trigger)

-*Set Point1 = (Position of (Triggering Unit))
-*Set Point2 = (Position of BAR_Ram_U)

Using a Hashtable would give you more "power" in general, since you can use the same hash for any amount of units and values. And the memory the hashtable uses is directly related to the data stored in it. Using one Hashtable for several units and abilities would be better than having several global variables for each unit and ability. Depends on your map requirements :)
 
Level 6
Joined
May 15, 2009
Messages
191
So. If I had just 3 point variables, and I used the same two in two diffrent triggers, there would be no chance that the triggers overwrote eachother? Can't two diffrent triggers run at the same time? Before the variables are done being used in one trigger?¨

If not, then I've got some optimizing to do...
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
If you use TempUnit in two triggers with "A unit dies event" and you add 100000 further actions in each trigger using the "TempUnit" each trigger will run using the "TempUnit" assigned in that same trigger. Since only 1 function can take place a the time, one of those triggers will happen, when it finishes, it will go to the other, so, the value of the variable will be overwritten by the last function that uses it, but not before the first function has finished using it.

That's why people use TempVariables, because they have a value just in that trigger, and don't need that value for others. If you need the value of a variable for other trigger, you can use an Specific Global for that only trigger, if you reaaaally need to, or you can use a Hashtable.

Note: This happens ONLY if there's no time gap (any wait action) in the trigger.
 
Status
Not open for further replies.
Top