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

Timelapse trigger not working

Status
Not open for further replies.
Level 7
Joined
Jan 11, 2022
Messages
108
Uhh so I can't get this to work and i'm out of ideas to make this work
The idea is that Time Lapse puts a hero back 5 seconds in time returning hp and mana to the state that it was 5 seconds ago

  • Time Lapse GUI
    • Events
      • Unit - A unit starts an effect of the ability
    • Conditions
      • (Ability being cast) Equal to Time Lapse
    • Actions
      • Set CasterPos = (Position of (Triggering unit))
      • Special Effect - Create a special effect at CasterPos using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation (udg_CasterPos)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HPInteger Lesser than or Equal to 6
        • Then - Actions
          • Unit - Set life of (Triggering unit) to HP[1]
          • Unit - Set mana of (Triggering unit) to MP[1]
          • Unit - Move (Triggering unit) instantly to POS[1]
          • Custom script: call RemoveLocation (udg_POS[1])
        • Else - Actions
          • Unit - Set life of (Triggering unit) to HP[(HPInteger - 5)]
          • Unit - Set mana of (Triggering unit) to MP[(MPInteger - 5)]
          • Unit - Move (Triggering unit) instantly to POS[(POSInteger - 5)]
          • Custom script: call RemoveLocation (udg_POS[udg_POSInteger - 5])
      • Set CasterPos = (Position of (Triggering unit))
      • Special Effect - Create a special effect at CasterPos using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation (udg_CasterPos)
      • Unit - Order (Triggering unit) to Stop
  • Enable Time Lapse
    • Events
      • Unit - A unit learns an ability
    • Conditions
      • (Level of Time Lapse for (Triggering unit)) Greater than 0
    • Actions
      • Set Caster = (Triggering unit)
      • Trigger - Turn off (This trigger)
      • Trigger - Turn on Time Lapse Periodic <gen>
  • Time Lapse Periodic
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
      • (Caster is alive) Equal to True
    • Actions
      • Set HPInteger = (HPInteger + 1)
      • Set HP[HPInteger] = (Life of Caster)
      • Set MPInteger = (MPInteger + 1)
      • Set MP[MPInteger] = (Mana of Caster)
      • Set POSInteger = (POSInteger + 1)
      • Set POS[POSInteger] = (Position of Caster)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HPInteger Greater than 6
        • Then - Actions
          • Custom script: call RemoveLocation (udg_POS[udg_POSInteger - 6])
        • Else - Actions
  • Caster Revives
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Dying unit) Equal to Caster
    • Actions
      • Wait until ((Caster is alive) Equal to True), checking every 0.10 seconds
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • Set HP[(HPInteger - (Integer A))] = (Life of Caster)
          • Set MP[(MPInteger - (Integer A))] = (Mana of Caster)
          • Set POS[(POSInteger - (Integer A))] = (Position of Caster)
 
Level 39
Joined
Feb 27, 2007
Messages
5,016
Uhh so I can't get this to work and i'm out of ideas to make this work
It generally helps to describe what doesn't work as you anticipate, what behavior you do see, or what parts of the trigger are working.
  • Instead of (Level of Time Lapse for (Triggering unit)) Greater than 0 you can check (Learned Hero Skill) equal to Time Lapse.
  • This spell will only work for one unit on the map at a time.
  • After 9 hours of continuous gameplay, the integer variables will exceed 2^15 and trying to use them as array indices will crash the game. I realize this is unrealistic but that's a reason this method is not good.
  • Instead of increasing the counter variables indefinitely, it makes far more sense to just reuse/shuffle around data in indices 1-5.
  • The points created by this line in Caster Revives will not ultimately be cleaned up properly (the other points will be): Set POS[(POSInteger - (Integer A))] = (Position of Caster)
  • Wait until... is generally not something you should use, and it absolutely will not check every 0.10 seconds because that is below the minimum wait time. This check and cleanup could simply happen in the periodic trigger if the caster is still dead each time it fires, but ultimately I don't think you need it at all.
  • Since you have the Caster variable defined you might as well just use it instead of Triggering Unit everywhere.
  • Because of the 1 second period this might return the unit to its state a minimum of 4.01 or a maximum of 5.99 seconds ago.
  • No reason to use stuff like Dying Unit and Casting Unit when they are functionally equivalent to Triggering Unit in this context. TU is preferred because it is not a wrapper function.
Something like this:
  • Time Lapse GUI
    • Events
      • Unit - A unit starts an effect of the ability
    • Conditions
      • (Ability being cast) Equal to Time Lapse
    • Actions
      • Set CasterPos = (Position of Caster)
      • Special Effect - Create a special effect at CasterPos using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation (udg_CasterPos)
      • Unit - Set life of Caster to HP[5] //changed these to 5
      • Unit - Set mana of Caster to MP[5]
      • Unit - Move Caster instantly to POS[5]
      • Set CasterPos = (Position of Caster) //this line is actually necessary because the unit might be moved away from POS[5] due to collision or pathing issues
      • Special Effect - Create a special effect at CasterPos using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_CasterPos)
      • Unit - Order Caster to Stop
  • Enable Time Lapse
    • Events
      • Unit - A unit learns an ability
    • Conditions
      • (Learned hero skill) equal to Time Lapse
    • Actions
      • Set Caster = (Triggering unit)
      • Trigger - Turn off (This trigger)
      • Trigger - Turn on Time Lapse Periodic <gen>
  • Time Lapse Periodic
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
      • (Caster is Alive) Equal to True
    • Actions
      • Custom script: call RemoveLocation(udg_POS[5])
      • For each (Integer A) from 0 to 3 do (Actions) //if GUI could loop 'down' this range would be from 5 to 2
        • Loop - Actions
          • Set HP[(5 - (Integer A))] = HP[(4 - (Integer A))]
          • Set MP[(5 - (Integer A))] = MP[(4 - (Integer A))]
          • Set POS[(5 - (Integer A))] = POS[(4 - (Integer A))]
  • Caster Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Triggering unit) Equal to Caster
    • Actions
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • Set HP[(Integer A)] = (Maximum Life of Caster) //max here now
          • Set MP[(Integer A)] = (Maximum Mana of Caster)
          • Custom script: call RemoveLocation(POS[GetForLoopIndexA()])
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
I recreated @Nevanii 's trigger in fresh map (all except for the dying trigger with 'wait until' ) and it worked as expected.
My guess would be that you are reusing any of the variables somewhere else.

Pyro already posted a good solution, but one thing I would like to point out is that you should perhaps also think about the structure of your code. For example this:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • HPInteger Lesser than or Equal to 6
    • Then - Actions
      • Unit - Set life of (Triggering unit) to HP[1]
      • Unit - Set mana of (Triggering unit) to MP[1]
      • Unit - Move (Triggering unit) instantly to POS[1]
      • Custom script: call RemoveLocation (udg_POS[1])
    • Else - Actions
      • Unit - Set life of (Triggering unit) to HP[(HPInteger - 5)]
      • Unit - Set mana of (Triggering unit) to MP[(MPInteger - 5)]
      • Unit - Move (Triggering unit) instantly to POS[(POSInteger - 5)]
      • Custom script: call RemoveLocation (udg_POS[udg_POSInteger - 5])
The only thing that is different in 'Then' and 'Else' block are the indexes. Also, those indexes are all same.
So what you can do is just merge those 3 indexes into single index - i.e. TimeLapseIndex and inside the If/Then/Else just determine the index value:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • TimeLapseIndex Lesser than or Equal to 6
    • Then - Actions
      • Set Index = 1
    • Else - Actions
      • Set Index = TimeLapseIndex - 5
  • Unit - Set life of (Triggering unit) to HP[Index]
  • Unit - Set mana of (Triggering unit) to MP[Index]
  • Unit - Move (Triggering unit) instantly to POS[Index]
  • Custom script: call RemoveLocation (udg_POS[Index])
Now since the If/Then/Else is used only to determine the index, you can actually just use a Math method to get the same result:
  • Set Index = (Max(1, (TimeLapseIndex - 5)))
  • Unit - Set life of (Triggering unit) to HP[Index]
  • Unit - Set mana of (Triggering unit) to MP[Index]
  • Unit - Move (Triggering unit) instantly to POS[Index]
  • Custom script: call RemoveLocation (udg_POS[Index])
 
Level 7
Joined
Jan 11, 2022
Messages
108
This spell will only work for one unit on the map at a time.
Meaning that only one hero can use it during whole gameplay, or that using for example two time lapses at the same time by 2 heros will overwrite each other Time lapses?
I know this trigger isn't MUI, haven't gotten to mui stuff in gui yet and dunno how to make this one fully mui ;/

Also thanks Nichilus for pointing these stuff out. I know my code is sloppy, will work on that for sure to clean it up ;>
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
In your current implementation it will only work for a single hero in the entire game. If multiple heroes are there it will break:
  • In your 'Enable Time Lapse' trigger you set Caster = triggeringUnit(), then turn off the trigger
  • In your 'Time Lapse Periodic' trigger you track stats of Caster
  • In your 'Time Lapse GUI' trigger any unit that casts Time Lapse will move to where the Caster was 5 seconds ago.
Just try it with 2 units that have the skill:
  • Unit_A learns the skill, becoming the Caster
  • Unit_B learns the skill, since the trigger is off, it does not become the Caster (but if it did, it would overwrite the reference to Unit_A)
  • Unit_B uses the skill, teleporting to the place where Unit_A was 5 seconds ago
You should try what Pyro posted, but as I wrote in my previous post, the spell worked for me in a fresh map, so you could also check if all used variables (Caster, HP[], MP[], POS[], HPIndex, MPINdex, POSIndex) are not used by any other trigger.

You could also try to debug it by printing messages (i.e. which index was used during 'Time Lapse GUI' trigger, what are the values in the arrays under given index?)
  • Game - Display to (All players) the text: <something>
 
Level 7
Joined
Jan 11, 2022
Messages
108
Just tried what Pyro posted and it works without any issues! Also noticed that it works after disabling "Caster Dies" Trigger (on the first version that I posted). I'll have to work someday on the MUI version of taht, thanks boys
 
Status
Not open for further replies.
Top