1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Lua] Ridiculously Fast Triggers

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

  1. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,120
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    This exists primarily to improve things such as manual event execution as well as unify GUI actions into Conditions (see further below for how to enable "Wait" calls from your triggers).

    How it works: by overwriting the natives "TriggerAddAction" and "TriggerAddCondition + Condition", I can extract the function that is being passed to the natives and, subsequently, call that function manually instead of letting the trigger spit it out.

    So with GUI triggers with conditions and actions, the conditions will be called manually and the actions will be called manually if the conditions are true.

    Code (Lua):

    do
        local cMap = {}
        local aMap = {}
        local lastCondFunc
        local waitFunc
       
        local oldCond = Condition --If you don't want this Condition-overwrite behavior
        --for any particular resource, use Filter() instead of Condition(). This tool
        --is mainly for GUI users & the GUI->script compiled behavior uses Condition().
        function Condition(func)
            lastCondFunc = func
            return oldCond(func)
        end
       
        local oldTAC = TriggerAddCondition
        function TriggerAddCondition(trig, cond)
            if lastCondFunc then
                cMap[trig] = lastCondFunc --map the condition function to the trigger.
                lastCondFunc = nil
                cond = Filter(function()
                    local t = GetTriggeringTrigger()
                    if cMap[t]() then --Call the triggerconditions manually.
                        waitFunc = aMap[t]
                        waitFunc() --If this was caused by an event, call the trigger actions manually.
                    end
                end)
            end
            return oldTAC(trig, cond) --use the regular event if a boolexpr or Filter
            --was used instead of Condition()
        end
       
        local oldTAA = TriggerAddAction
        function TriggerAddAction(trig, act)
            aMap[trig] = act
            return oldTAA(trig, function()
                waitFunc = aMap[GetTriggeringTrigger()]
                waitFunc() --If this was caused by an event, call the trigger actions manually.
            end)
        end
       
        local oldEval = TriggerEvaluate
        function TriggerEvaluate(trig)
            local f = cMap[trig]
            if f then return f() end
            return oldEval(trig)
        end
       
        local oldExec = TriggerExecute
        function TriggerExecute(trig)
            waitFunc = aMap[trig]
            waitFunc()
        end
       
        function RunTrigger(trig)
            local conds = cMap[trig]
            if IsTriggerEnabled(trig) and not conds or conds() then
                waitFunc = aMap[trig]
                waitFunc()
            end
        end
       
        local skipNext = false
        function EnableWaits()
            if skipNext then
                skipNext = false
                return false
            end
            skipNext = true
            coroutine.resume(coroutine.create(function()
                waitFunc()
            end))
            return true
        end
    end
     
    To enable your trigger actions to use "Waits" again (ie. PolledWait), use the latest version (updated 10 July 2019) of [Lua] Perfect PolledWait (GUI-friendly) and put the following one line of code at the TOP of your trigger actions list: if EnableWaits() then return end. The system will handle the rest.

    • Want to wait
      • Events
        • -------- Some event
      • Conditions
        • -------- Some conditions
      • Actions
        • Custom script: if EnableWaits() then return end
        • Wait - 0.50 seconds of game time
        • -------- Do further actions here.


    The added API "RunTrigger" has been benchmarked as SEVENTEEN TIMES faster than the below. It is also worth noting that the system gets an insane lag when benchmarking the old process in very high numbers, even if the system clock claims to indicate a benchmark time period much less than what was actually impacting the game performance.

    Code (Lua):

        -- This is between 16-18 times slower than the Fast Triggers approach.
        function RunTrigger(trig)
            if IsTriggerEnabled(trig) and TriggerEvaluate(trig) then
                TriggerExecute(trig)
            end
        end
     
     
    Last edited: Jul 10, 2019
  2. Clanzion

    Clanzion

    Joined:
    Jul 4, 2016
    Messages:
    424
    Resources:
    0
    Resources:
    0
    Will this work seamlessly with your gui spell system?
     
  3. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,120
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Spell System is on my to-do list, so definitely you can expect it sometime towards the end of this week or very early next.

    I've updated this script today to enable compatibility with the Lua PerfectWait system if needed.

    EDIT on 28 July 2019 - due to Damage Engine needing some fixes this got delayed quite a bit. Should expect this now by mid to late August when I am back from vacation and have gotten the higher-priority resources done.
     
    Last edited: Jul 28, 2019