1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Join Texturing Contest #30 now in a legendary battle of mythological creatures!
    Dismiss Notice
  3. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice
  4. Melee Mapping Contest #3 - Results are out! Congratulate the winners and check plenty of new 4v4 melee maps designed for this competition!
    Dismiss Notice
  5. The winners of our cinematic soundtrack competition have been decided! Step by the Music Contest #11 - Results to check the entries and congratulate the winners!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice

[GUI-friendly] Wayback (Time Travel/Rewind System)

Submitted by _Guhun_
This bundle is marked as pending. It has not been reviewed by a staff member yet.
[GUI-Friendly] Wayback v1.1.0

System Requirements

This system allows you to make units "go back in time" by periodically saving snapshots of their current states in a Linked List created with GLL. When you want to make the unit return to another point in time, the system simply reads the saved data and restores the unit to that point, including (by default) life, mana and position.

You can also make the unit slowly rewind through time, going through each position it had previosuly been in.

For vJASS users, there exists a similar system made by the ever-awesome Bribe: Retro.

Snapshots:

Wayback periodically saves the current state of a unit in a "snapshot", which is identified by a unique ID generated with GMUI (using the generic Recycle Key: 1). Because of the way snapshots are saved, advanced users can save their own data in a snapshot, allowing for more than just unit life, mana and position to be saved and restored.

Hashtable:

Unit Handle ID
0 -> timer
1 -> GLL List
2 -> snapshot counter
3 -> maximum snapshots (determines max rewind time = period * maximum snapshots)

Timer Handle ID
0 -> unit

(negative) Snapshot ID
0 -> unit HP
1 -> unit MP
2 -> unit X
3 -> unit Y


How to Import:

  1. Open World Editor. File -> Preferences -> Tick box for "Automatically create unknown variables (...)"
  2. Copy the "GUI MUI Engine" category into your map.
  3. Open the "GMUI Header" trigger and copy its contents into your map header.
  4. Copy the "GUI Linked Lists" category into your map.
  5. Open the "GLL Header" trigger and copy its contents into your map header, below GMUI.
  6. Copy the trigger category "Wayback System" into your map.
  7. Delete all disabled triggers with "Import" in their name
  8. Done!
Using the System:


  • Since the system needs to save snapshots periodically, it will require more processing power for each unit you want to be able to go back in time. Therefore, you need to manually specify when you want a unit to be able to go back through time.

    Variables before execution:
    Wayback_Unit The unit we wish to register in the system.
    Wayback_Time The maximum time the unit will be able to return in time.
    Wayback_Precision How precise the system will be (time between each snapshot)


    GUI-only method:
    • Actions
      • Set Wayback_Unit = YourUnit
      • Set Wayback_Time = YourMaxTime
      • Set Wayback_Precision = YourDesiredPrecision
      • Trigger - Run Wayback Main <gen> (ignoring conditions)


  • The system saves a lot of data in hashtables, so if you are not gonna have a unit go back through time anymore, you should unregister it. It is especially important to unregister a unit before it is removed from play (to avoid memory leaks). Unregistering a unit also stops the periodic timer that takes snapshots.

    Variables before execution:
    Wayback_Unit The unit we wish to unregister from the system.
    Wayback_Time We set this to a negative number when we want to unregister a unit.


    GUI-only method:
    • Actions
      • Set Wayback_Unit = YourUnit
      • Set Wayback_Time = -1
      • Trigger - Run Wayback Main <gen> (ignoring conditions)


  • This is the main feature of wayback. Using this function, the unit is instantly transported back in time, appearing on the position it had been in at the specified time.

    Variables before execution:
    Wayback_Unit The unit we want to take back through time.
    Wayback_Time The amount of time (in seconds) the unit will go back (0 for maximum). Use a non-negative number.


    GUI-only method:
    • Actions
      • Set Wayback_Unit = YourUnit
      • Set Wayback_Time = YourTime (non-negative, 0 for max)
      • Trigger - Run Wayback Main <gen> (checking conditions)


  • This is another cool feature that allows you to make units slowly go back in time over a specified duration.

    Variables before execution:
    Wayback_Unit The unit we want to take back through time.
    Wayback_Time The amount of time (in seconds) the unit will go back. Use a negative number.
    Wayback_Precision How much time the rewind should take.


    GUI-only method:
    • Actions
      • Set Wayback_Unit = YourUnit
      • Set Wayback_Time = YourTime (negative number)
      • Set Wayback_Precision = YourDuration
      • Trigger - Run Wayback Main <gen> (checking conditions)



  • At the very top of the Wayback Main trigger, you will find this code that allows you to easily configure Wayback to store any value that you want, instead of only the values that the system would normally store!

    Code (vJASS):

    //===========================================================================
    // Easy Configuration
    //===========================================================================

    // Use the functions/textmacros defined here to change the behaviour of the system by changing
    // what data is stored in a snapshot. You could, for example, store the unit's flying height as
    // well by simply adding the commented out lines at the end of each function.

    //! novjass
    function StoreSnapshotData takes integer snapshot, unit whichUnit returns nothing
    //! endnovjass
    //! textmacro StoreSnapshotData
        //Whenever a new snapshot of a unit is created, this code is run to store data.
        //You can alter this function(JASS)/textmacro(vJASS) to store whatever values you need.
     
        call SaveReal(udg_Wayback_Hashtable, snapshot, 0, GetUnitState(whichUnit, UNIT_STATE_LIFE))
        call SaveReal(udg_Wayback_Hashtable, snapshot, 1, GetUnitState(whichUnit, UNIT_STATE_MANA))
        call SaveReal(udg_Wayback_Hashtable, snapshot, 2, GetUnitX(whichUnit))
        call SaveReal(udg_Wayback_Hashtable, snapshot, 3, GetUnitY(whichUnit))
        // Example of user-defined data:
        //call SaveReal(udg_Wayback_Hashtable, snapshot, 4, GetUnitFlyHeight(whichUnit))
    //! endtextmacro
    //! novjass
    endfunction
    //! endnovjass

    //! novjass
    function UnitLoadSnapshot takes integer snapshot, unit whichUnit returns nothing
    //! endnovjass
    //! textmacro UnitLoadSnapshot
        //Whenever a new snapshot of a unit is created, this code is to restore the unit.
        //You can alter this function(JASS)/textmacro(vJASS) to use any custom data you have added.
     
        call SetUnitState(whichUnit, UNIT_STATE_LIFE, LoadReal(udg_Wayback_Hashtable, snapshot, 0))
        call SetUnitState(whichUnit, UNIT_STATE_MANA, LoadReal(udg_Wayback_Hashtable, snapshot, 1))
        call SetUnitX(whichUnit, LoadReal(udg_Wayback_Hashtable, snapshot, 2))
        call SetUnitY(whichUnit, LoadReal(udg_Wayback_Hashtable, snapshot, 3))
        // Example of user-defined data:
        //call SetUnitFlyHeight(whichUnit, LoadReal(udg_Wayback_Hashtable, snapshot, 4))
    //! endtextmacro
    //! novjass
    endfunction
    //! endnovjass
     


  • Code (vJASS):

    //===========================================================================
    // Code and API
    //===========================================================================

    //=======
    //Register Unit functions
    //=======

    //Registers a unit in the System, allowing you to specify a function for the periodic timer
    function Wayback_RegisterUnitEx takes unit whichUnit, real period, integer maxSnapshots, code timerFunc returns nothing
    endfunction

    //Register unit with default timer function
    function Wayback_RegisterUnit takes unit whichUnit, real period, integer maxSnapshots returns nothing
    endfunction

    //Register unit using a duration instead of maximum snapshots and using default timer function
    function Wayback_RegisterUnitDuration takes unit whichUnit, real period, real duration, real period2 returns nothing
    endfunction

    //Register unit using a duration instead of maximum snapshots
    function Wayback_RegisterUnitDurationEx takes unit whichUnit, real period, real duration, real period2, code timerFunc returns nothing
    endfunction

    //Unregisters a unit from the system, deleting all snapshot data and the timer
    function Wayback_UnregisterUnit takes unit whichUnit returns nothing
    endfunction

    //=======
    //Restoring and Rewinding functions
    //=======

    //Instantly restores a unit to their oldest snapshot
    //Returns the ID of the snapshot for extended functionality
    function Wayback_RestoreUnit takes unit whichUnit returns integer
    endfunction

    //Instantly moves unit "time" seconds back in time, up to their oldest snapshot
    //Returns the ID of the snapshot for extended functionality
    function Wayback_RestoreUnitEx takes unit whichUnit, real time returns integer
    endfunction

    //Instantly moves unit a single snapshot back in time
    //The unit ID variable should be the unit's handle ID
    //Returns the ID of the snapshot for extended functionality
    function Wayback_RestoreUnitByIdOneStep takes unit whichUnit, integer unitID returns integer
    endfunction

    //Instantly moves unit a single snapshot back in time
    //Returns the ID of the snapshot for extended functionality
    function Wayback_RestoreUnitOneStep takes unit whichUnit returns integer
    endfunction

    //=======

    //Takes a unit back in "time" seconds in time, snapshot-by-snapshot, over "duration" seconds
    function Wayback_RewindUnit takes unit whichUnit, real time, real duration returns nothing
    endfunction
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //End of Wayback
    ////////////////////////////////////////////////////////////////////////////////////////////////////
     




Test Map:

Command Action
unregister Unregisters all units from the system
register Registers all units in the system
wayback returns a unit 1 second in time
rewind slowly rewinds a unit 2.5 seconds back in time

Units in the test map will automatically go back in time whenever they cast an ability. In addition, you may use the above commands to test wheter the system is correctly registering and unregistering units. An unregistered unit will die and revive at position (0,0) of the map. There's not much else to test, really.

Updates and Version History:
v1:
0.1.0 > Initial Release
1.0.0 > Added function to slowly rewind units and option to return less than the max time
1.0.0a > GLL Import now contains all the correct variables
1.0.0b > Fixed some mistakes in the system description
1.1.0 > Added StoreSnapshot data UnitLoadSnapshot functions for easy config.
Upcoming:
Contents

Guhun's Wayback System (Map)

  1. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    I swear this I'll stop flooding the spell sections with systems for now, I'm just kind of in a coding spree and just wanted to get this last one out, if only to somewhat demonstrate the data structures system.
     
    Last edited: Jan 29, 2018
  2. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,522
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17
    I'll assume it just teleports the user to the old position/state?

    I'd probably love a visual with that. Like Tracer's E from Overwatch
     
  3. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    Yeah, basically it will by default return the unit to its original position and health/mana. But you can add more data to a snapshot. So, if, for example, you are using some sort of debuff system, you could make it so the unit loses all the debuffs it did not have, thought that may require some extra coding. For something like a stun system, though, that would be really easy to implement, I believe.

    As for visuals, right now it just teleports the unit. You could always add special effects to that, but I'm also planning on making an easy way to make the unit slowly go back through time, like Tracer does in the Widow cinematic.
     
  4. Dark_Axl

    Dark_Axl

    Joined:
    Dec 12, 2007
    Messages:
    471
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    so... I assume this will become like a GUI version of Bribe's Retro ?
     
  5. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    Oh, yeah, that's basically what it comes down to, though I'm not too familiar with how retro works. But it doesn't seem like Retro supports instantly taking the unit back in time, though I could be wrong. Another difference is that Retro uses a global precision/max return time, while this system has it specified on a per-unit basis (which is a bit slower per-snapshot recording, but not gonna make that much of a diffrence, I think). Also Retro uses vJASS, so it actually looks like a decent piece of software engineering, unlike JASS ^^


    Either way, I forgot to add it to the description as an alternative vJASS system. Gonna do that now.

    Update:
    Version 1.0.0 >

    -Added function to slowly rewind units back in time
    -Added option to specify a return time lower than the max time
     
    Last edited: Jan 13, 2018
  6. Keiu

    Keiu

    Joined:
    Nov 28, 2017
    Messages:
    12
    Resources:
    0
    Resources:
    0
    Hello, may I ask something... do you need any special program to open/save maps that including JASS code? I am using Warcraft World Editor v1.28f, from the official Warcraft III game disk, but when I try to copy a JASS code spell into a custom map, it always has some script errors. By the way, I clicked the "Automatically create unknown variables (...)" already.
    [​IMG]
    [​IMG]
     
  7. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    It looks like you forgot to put the code in your map Header, thus the functions are not being found when they are referenced.

    "
    1. Copy the "GUI MUI Engine" category into your map.
    2. Open the "GMUI Header" trigger and copy its contents into your map header.
    3. Copy the "GUI Linked Lists" category into your map.
    4. Open the "GLL Header" trigger and copy its contents into your map header, below GMUI.
    "

    The map header is the thing above your triggers which has the same name as your map file.

    IMAGE
     
    Last edited: Jan 13, 2018
  8. Keiu

    Keiu

    Joined:
    Nov 28, 2017
    Messages:
    12
    Resources:
    0
    Resources:
    0
    Thanks for responding. I did all the step you listed in the 'How to Import', but now it has more script errors...
    [​IMG]
     
  9. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    It seems I forgot to add two variables to the variable import trigger, which is the cause of that error. I'll fix this asap.

    It should work once you create an integer variable named : "Lists_RECYCLE_KEY" and another trigger variable named "Lists_Trigger".

    Sorry for the inconvenience.

    PS: If it still doesn't work, you may have copied the GLL map header above the GMUI map header. It should be below.

    Update:
    1.0.0a > GLL Import now contains all the correct variables
     
    Last edited: Jan 13, 2018
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,757
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Hi thanks for your contribution. I actually will be having more free time at i got rid of a toxic game that was dragging me down (Hearthstone) and the GUI Retro rework has been in my sights for some time.

    I haven't done a Teleport thing in Retro as the coordinates are logged in a 4D hashtable, but will make recalling instantly a feature in the system as it's more logical to build that in than to have a separate system for it.

    The add/remove can either be automatic or manual.

    Other stuff like i have in the Time Warp spell-such as effects-will be excluded from the internal system and enabled strictly through add-ons (where they belong).

    The basic API would be a simple add/remove trigger command and for activating it would be a variable set by the user to the travel duration preceded by how much time to go back. The most basic form will look something like:

    Retro__RewindUnit = (TriggeringUnit)
    Retro__RewindTo = 2.00 (seconds ago)
    Retro__RewindRate = 1.00 (takes 1 second to rewind by 2 seconds - 0 for instant).

    I look forward to seeing what other stuff comes up, but i plan to see this at a public release point by end of Feb.
     
  11. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    290
    Resources:
    4
    Spells:
    3
    Tutorials:
    1
    Resources:
    4
    That's great xD
    Being too focused on a game can really be a detriment to productivity (talking from first-hand experience, too!)

    Can't wait for what you come up with :eek::eek:




    Update: Version 1.1.0

    Small update, but might be pretty useful one! Added an easy way to configure what data is stored in a snapshot of a unit by created two new fucntions which a JASS user can edit: Added StoreSnapshot data UnitLoadSnapshot functions for easy config.

    (If vJASS is enabled, the functions are converted to textmacros for better performance.
     
  12. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,172
    Resources:
    3
    Models:
    1
    Icons:
    1
    JASS:
    1
    Resources:
    3
    Edited tags to include GUI/Triggers as one of the tags.