1. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  2. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  3. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Lua] Perfect PolledWait (GUI-friendly)

Discussion in 'Submissions' started by Bribe, Jul 7, 2019.

  1. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Hi folks,

    First off, this is NOT my idea. Credit goes to @DoctorGester for the idea which I saw an implementation of from @MindWorX for writing this initially in TypeScript. I've coded it to use Lua and the new Lua TimerUtils library I made, in addition to overwriting the default in-game behavior rather than rely on the user to make a fancy implementation themselves.

    This is completely GUI-friendly so it will take ZERO custom script to need to be added to any GUI triggers. It overwrites the
    PolledWait
    aka "Wait - Game Time" action in GUI.

    Edit 8 July 2019: For reasons related to compatibility, it is also necessary to override the default scripts which normally sleep the thread (ie. TriggerSleepAction and SyncSelections). It is safe to do either one from an ExecuteFunc thread, so I've updated the script. Regular sleep now defaults to the same PolledWait behavior.

    Edit 10 July 2019 - Added compatibility to force-enable Wait functions even when using Lua Fast Triggers. Bear in mind the function "EnableWaits" is actually found within the Fast Triggers script and not this one.

    Requires [Lua] TimerUtils

    Code (Lua):

    -- Requires https://www.hiveworkshop.com/threads/lua-timerutils.316957/

    do
        local oldWait = PolledWait
        function PolledWait(duration)
            local thread = coroutine.running()
            if thread then
                TimerStart(NewTimer(thread), duration, false, function()
                    coroutine.resume(ReleaseTimer())
                end)
                coroutine.yield(thread)
            else
                oldWait(duration)
            end
        end
     
        local oldTSA = TriggerSleepAction
        function TriggerSleepAction(duration) PolledWait(duration) end
     
        local thread
        local oldSync = SyncSelections
        function SyncSelectionsHelper()
            local t = thread
            oldSync()
            coroutine.resume(t)
        end
        function SyncSelections()
            thread = coroutine.running()
            if thread then
                ExecuteFunc("SyncSelectionsHelper")
                coroutine.yield(thread)
            else
                oldSync()
            end
        end
     
        if not EnableWaits then --Added this check to ensure compatibilitys with Lua Fast Triggers
            local oldAction = TriggerAddAction
            function TriggerAddAction(whichTrig, userAction)
                oldAction(whichTrig, function()
                    coroutine.resume(coroutine.create(function()
                        userAction()
                    end))
                end)
            end
        end
    end
     
    Example usage:

    • NormalTrigger
      • Events
      • Conditions
      • Actions
        • Wait - 3.00 seconds of game time (waits exactly 3 seconds)
        • Wait - 0.03 seconds of game time (waits exactly 0.03 seconds - previously not possible to have waits be this short)
     
    Last edited: Jul 13, 2019
  2. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,563
    Resources:
    9
    Models:
    1
    Icons:
    2
    Maps:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    9
    Tested this with TimerUtils [Lua], and this is crazy!

    A perfect polled wait could be considered a dream come true for GUI users (since they won't have to create separate triggers just for timer management), and suffice to say, this will be enough to deprecate a lot of timer attachment resources.

    Great Job!
     
  3. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Thank you - I'm glad this has the potential to make a difference!

    I added some stuff to the script to compensate for issues like SyncSelections crashing the thread. Also, the vanilla TriggerSleepAction is now doing the exact same thing as a PolledWait (otherwise the thread crashes).
     
  4. blink

    blink

    Joined:
    Mar 6, 2012
    Messages:
    61
    Resources:
    3
    Models:
    3
    Resources:
    3
    wait lua can overwrite gui functions? welp, bye jass.
     
  5. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeah, the days of JASS are completely over for those using 1.31. Lua is amazing! Totally new frontier for us.
     
    Last edited: Jul 9, 2019
  6. ZiBitheWand3r3r

    ZiBitheWand3r3r

    Joined:
    Nov 21, 2012
    Messages:
    919
    Resources:
    15
    Maps:
    7
    Spells:
    8
    Resources:
    15
    Hey guys, what version of Lua manual should I look for to learn? To work with War3 of course
     
  7. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,834
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    Warcraft III is using Lua version 5.3.4.
     
  8. Uncle

    Uncle

    Joined:
    Aug 10, 2018
    Messages:
    2,474
    Resources:
    0
    Resources:
    0
    Wow, this is great. Thank you!
     
  9. LtCabble

    LtCabble

    Joined:
    Jul 23, 2019
    Messages:
    7
    Resources:
    0
    Resources:
    0
    Hey,

    so i just imported your LUA Code into my map. I dont know why, but many of my triggers with waits in it dont seem to work anymore.

    The moment i deactivate it everything runs fine, any ideas why this is happening? Do you have any example maps for this?

    Thanks in advance
     
    Last edited: Jul 23, 2019
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The Lua Damage Engine map is what I use to test all this stuff and you can find it all in use there (though I might have a few tests disabled).

    Are you able to provide me examples of your triggers where the waits don’t work? Also if you could please let me know what other Lua resources you use (besides Lua Timer Utils).
     
  11. LtCabble

    LtCabble

    Joined:
    Jul 23, 2019
    Messages:
    7
    Resources:
    0
    Resources:
    0
    Hey, thanks for replying.

    My Editor is in German, so im sorry for that. Attached is a propably really bad trigger, but i think it is a good example.

    It should fire when a unit is casting a certain spell. Then it waits for 0.75 Seconds and casts the spell again. This trigger worked without any problems for years.

    Trigger.png

    The posted trigger does not work at all when your LUA Code is active. (I saw you using the 'Wait x seconds of game time' action, so i tried changing this aswell but it did nothing)

    Did i import your Script the right way? Im really not shure if i did it right.

    Lua Timer.png


    Im using the Garbage Collection Script from Dr Super Good, but i already deactivated it for testing and the problem was still there.

    Thanks for you help.
     
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The issue is that you need to set event responses before doing the wait.

    Set TempCaster = (Triggering unit)

    I should improve the documentation to note this stuff. I've been inactive the past couple weeks and I'll resume my work in the second week of August when I am back from vacation.

    Keep in mind with this you may want to do stuff like consider making it MUI. You can do it with local variables or indexing.
     
    Last edited: Jul 25, 2019
  13. LtCabble

    LtCabble

    Joined:
    Jul 23, 2019
    Messages:
    7
    Resources:
    0
    Resources:
    0
    Oh wow, i have to rework so much things now. But there is no way around i think, the waits became so weird since the new wc3 version. I guess thats the price i have to pay.

    And again, thank you very much.
     
  14. Daffa

    Daffa

    Joined:
    Jan 30, 2013
    Messages:
    8,213
    Resources:
    31
    Packs:
    1
    Maps:
    9
    Spells:
    18
    Tutorials:
    3
    Resources:
    31
    Can we have Wait as a real thing in spell section now? :p
     
  15. GetLocalPlayer

    GetLocalPlayer

    Joined:
    Apr 11, 2018
    Messages:
    20
    Resources:
    0
    Resources:
    0
    Does this preserve trigger data that can be obtained via GetTriggerUnit, GetDamageEvent, e.t.c.?
     
  16. Uncle

    Uncle

    Joined:
    Aug 10, 2018
    Messages:
    2,474
    Resources:
    0
    Resources:
    0
    @GetLocalPlayer No, you have to store those as variables before issuing a Wait. Local variables would be your best option.
     
  17. GetLocalPlayer

    GetLocalPlayer

    Joined:
    Apr 11, 2018
    Messages:
    20
    Resources:
    0
    Resources:
    0
    @Uncle This isn't perfect, then.
     
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,399
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Good point. @MyPad please rename to Precise Polled Wait.
     
  19. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,563
    Resources:
    9
    Models:
    1
    Icons:
    2
    Maps:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    9
    Can't do. I have no power here. @Jampion
     
  20. GetLocalPlayer

    GetLocalPlayer

    Joined:
    Apr 11, 2018
    Messages:
    20
    Resources:
    0
    Resources:
    0
    Would you add "WaitIndex" global variable that could be used to save data for each next wait execution? Like we did it with timers "GetHandeId(timer)". Easier and may be cheaper than overriding all the thread functions such as "GetTrigger..."