1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  3. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  4. 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.

Trigger Viewer

Respawn System - v1.0b.w3x
Variables
Demo Map
Setup
System
Respawn System
Required Systems
TimerUtils
GUI Demos
Count Creeps
Respawn All
Respawn For 10
Respawn For 11
Respawn For 12
Pause
Resume
Reset
Restart
Enter map-specific custom script code below. This text will be included in the map script after variables are declared and before any trigger code.

		
Name Type Is Array Initial Value
tempInt integer No
Setup
  Events
    Map initialization
  Conditions
  Actions
    Visibility - Disable fog of war
    Visibility - Disable black mask
    Selection - Select Tester 0010 <gen>
    Game - Display to (All players) the text: |cffffcc00Respawn System - v1.0b|r Demo MapCoded by: |cffffcc00Mr_Bean|rFor example usages, please see the Trigger Editor of this demo map.
//TESH.scrollpos=114
//TESH.alwaysfold=0
/*          ======================
            Respawn System - v1.0b
            ======================
           
        Coded by:       Mr_Bean (mrbean987789@gmail.com)
       
    Introduction:
    -------------
This system was originally requested by Peacehagen for his map Rise of the Corruptor ORPG.
He recommended that I upload it because it would help people, which I hope it does!
I added some new features to the system and made it as user-friendly as possible.
This system only works for units that are on the map as soon as the game starts.
Feel free to contact me if something is not clear, or if you find bugs.

    Installation:
    -------------
> Copy this trigger.
> Copy the "TimerUtils" trigger (if you don't have it already).
> Configure the "Configurables" section in this trigger as desired.

    Available Functions:
    --------------------
> RespawnAllCreeps()
    - Immediately respawns all dead creeps.
    - Does not affect countdown timer.

> RespawnAllCreepsForPlayer(player whichPlayer)
    - Immediately respawns all dead creeps for a specified player.
    - Does not affect countdown timer.

> PauseRespawnSystem(real howLong)
    - If all creeps respawn together, you can use this to pause the system.
    - The parameter is how long it is paused for. Use any negative number to pause it forever (until you resume again). Using 0 means no pause.
    - Can only use if RESPAWN_TOGETHER = true.

> ResumeRespawnSystem()
    - This will resume the system.
    - Only works if you used PauseRespawnSystem with a negative number (like PauseRespawnSystem(-1)).
    - Can only use if RESPAWN_TOGETHER = true.
   
> ResetRespawnSystem()
    - This will pause the system and reset the countdown.
    - Needs to be unpaused with ResumeRespawnSystem().
    - Can only use if RESPAWN_TOGETHER = true.
   
> RestartRespawnSystem()
    - This will reset the respawn countdown.
    - Will not pause the system.
    - Can only use if RESPAWN_TOGETHER = true.

> GetAliveCreeps()
    - Returns how many creeps are alive.
   
> GetDeadCreeps()
    - Returns how many creeps are dead.
   
> GetTotalCreeps()
    - Returns how many creeps there are in total.
   
    Contact:
    --------
> mrbean987789@gmail.com
> Mr_Bean987 on the HiveWorkshop.com

*/

library RespawnSystem initializer OnInit requires TimerUtils

    //**************************************************\\
    //*** START OF CONFIGURABLES                     ***\\
    //**************************************************\\
   
    globals
   
        // Delay between unit dying and respawning:
        private constant real    RESPAWN_DELAY      = 30.0
        // Respawn all dead units at once? If set to false, units will respawn individually.
        private constant boolean RESPAWN_TOGETHER   = true
        // Show a countdown window to all players:
        private constant boolean SHOW_TIMER_WINDOW  = false
        // Countdown window text (only applicable if SHOW_TIMER_WINDOW = true):
        private constant string  TIMER_WINDOW_TEXT  = "Creeps respawn in:"
        // Respawn heroes:
        private constant boolean RESPAWN_HEROES     = false
        // Effect created on respawning units (set to "" to have no effect):
        private constant string  RESPAWN_EFFECT     = "Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl"
        // Attachment point of effect on unit:
        private constant string  EFFECT_ATTACHMENT  = "origin"
       
    endglobals
   
    private function CheckOwner takes nothing returns boolean
        local integer playerId = GetPlayerId(GetOwningPlayer(GetFilterUnit()))
        if /*
       
        //------------------------------------------------------\\
        // Add the players that the system respawns creeps for: \\
        // Remember to subtract 1 from GUI player indexes!      \\
        */
 playerId == 10 or /*    // Player 11 in GUI.        \*
        */
 playerId == 11 or /*    // Player 12 in GUI.        \*
        */
 playerId == 12    /*    // Neutral Hostile in GUI.  \*
        //------------------------------------------------------\\
       
        */
then
            return true
        endif
        return false
    endfunction
   
    //**************************************************\\
    //*** END OF CONFIGURABLES                       ***\\
    //**************************************************\\
   
    globals
        private group       deadCreeps      = CreateGroup()
        private group       creeps          = CreateGroup()
        private group       enumG           = CreateGroup()
        private hashtable   ht              = InitHashtable()
        private timer       respawnTimer
        private timerdialog timerWindow
        private integer     tempInt         = 0
    endglobals
   
    private function Increment takes nothing returns nothing
        set tempInt = tempInt + 1
    endfunction
   
    private function EnumerateGroup takes group g returns integer
        set tempInt = 0
        call ForGroup(g, function Increment)
        return tempInt
    endfunction
   
    //**************************************************\\
    //*** GetTotalCreeps                             ***\\
    //**************************************************\\
   
    function GetTotalCreeps takes nothing returns integer
        return EnumerateGroup(creeps) + EnumerateGroup(deadCreeps)
    endfunction
   
    //**************************************************\\
    //*** GetAliveCreeps                             ***\\
    //**************************************************\\
   
    function GetDeadCreeps takes nothing returns integer
        return EnumerateGroup(deadCreeps)
    endfunction
   
    //**************************************************\\
    //*** GetDeadCreeps                              ***\\
    //**************************************************\\
   
    function GetAliveCreeps takes nothing returns integer
        return EnumerateGroup(creeps)
    endfunction
   
    //**************************************************\\
   
    private function RespawnCreepX takes integer handleId returns nothing
        local real x = LoadReal(ht, handleId, StringHash("x"))
        local real y = LoadReal(ht, handleId, StringHash("y"))
        local real angle = LoadReal(ht, handleId, StringHash("facing"))
        local integer owner = LoadInteger(ht, handleId, StringHash("owner"))
        local integer unitType = LoadInteger(ht, handleId, StringHash("type"))
        local unit creep
       
        set creep = CreateUnit(Player(owner), unitType, x, y, angle)
        call FlushChildHashtable(ht, handleId)
        call DestroyEffect(AddSpecialEffectTarget(RESPAWN_EFFECT, creep, EFFECT_ATTACHMENT))
        set handleId = GetHandleId(creep)
        call SaveReal(ht, handleId, StringHash("x"), GetUnitX(creep))
        call SaveReal(ht, handleId, StringHash("y"), GetUnitY(creep))
        call SaveReal(ht, handleId, StringHash("facing"), GetUnitFacing(creep))
        call SaveInteger(ht, handleId, StringHash("owner"), GetPlayerId(GetOwningPlayer(creep)))
        call SaveInteger(ht, handleId, StringHash("type"), GetUnitTypeId(creep))
       
        call GroupRemoveUnit(deadCreeps, creep)
        call GroupAddUnit(creeps, creep)
       
        set creep = null
    endfunction
   
    //**************************************************\\
    //*** ResumeRespawnSystem                        ***\\
    //**************************************************\\
   
    function ResumeRespawnSystem takes nothing returns nothing
        static if RESPAWN_TOGETHER then
            call ResumeTimer(respawnTimer)
        else
            call BJDebugMsg("|cffff0000Respawn System|r: Cannot use ResumeRespawnSystem when RESPAWN_TOGETHER = false.")
        endif
    endfunction
   
    //**************************************************\\
    //*** PauseRespawnSystem                         ***\\
    //**************************************************\\
   
    function PauseRespawnSystem takes real duration returns nothing
        static if RESPAWN_TOGETHER then
            if duration < 0 then
                call PauseTimer(respawnTimer)
            elseif duration > 0 then
                call PauseTimer(respawnTimer)
                call TimerStart(NewTimer(), duration, false, function ResumeRespawnSystem)
            endif
        else
            call BJDebugMsg("|cffff0000Respawn System|r: Cannot use PauseRespawnSystem when RESPAWN_TOGETHER = false.")
        endif
       
    endfunction
   
    //**************************************************\\
    //*** RespawnAllCreepsForPlayer                  ***\\
    //**************************************************\\
   
    function RespawnAllCreepsForPlayer takes player whichPlayer returns nothing
        local unit temp
       
        set enumG = deadCreeps
       
        loop
            set temp = FirstOfGroup(enumG)
            exitwhen temp == null
           
            if GetOwningPlayer(temp) == whichPlayer then
                call RespawnCreepX(GetHandleId(temp))
            endif
       
            call GroupRemoveUnit(enumG, temp)
       
        endloop
       
    endfunction
   
    private function GroupEnumeration takes nothing returns nothing
        call RespawnCreepX(GetHandleId(GetEnumUnit()))
    endfunction
   
    //**************************************************\\
    //*** RespawnAllCreeps                           ***\\
    //**************************************************\\
   
    function RespawnAllCreeps takes nothing returns nothing
        call ForGroup(deadCreeps, function GroupEnumeration)
    endfunction
   
    //**************************************************\\
    //*** ResetRespawnSystem                         ***\\
    //**************************************************\\
   
    function ResetRespawnSystem takes nothing returns nothing
   
        static if RESPAWN_TOGETHER then
            call TimerStart(respawnTimer, RESPAWN_DELAY, true, function RespawnAllCreeps)
            call PauseTimer(respawnTimer)
        else
            call BJDebugMsg("|cffff0000Respawn System|r: Cannot use ResetRespawnSystem when RESPAWN_TOGETHER = false.")
        endif
       
    endfunction
   
    //**************************************************\\
    //*** RestartRespawnSystem                       ***\\
    //**************************************************\\
   
    function RestartRespawnSystem takes nothing returns nothing
        static if RESPAWN_TOGETHER then
            call TimerStart(respawnTimer, RESPAWN_DELAY, true, function RespawnAllCreeps)
        else
            call BJDebugMsg("|cffff0000Respawn System|r: Cannot use RestartRespawnSystem when RESPAWN_TOGETHER = false.")
        endif
    endfunction

    //**************************************************\\
   
    private function TimerExpiration takes nothing returns nothing
        call RespawnCreepX(GetTimerData(GetExpiredTimer()))
        call ReleaseTimer(GetExpiredTimer())
    endfunction
   
    private function CreepDeath takes nothing returns boolean
        local unit u = GetTriggerUnit()
       
        if IsUnitInGroup(u, creeps) then
            call GroupRemoveUnit(creeps, u)
            call GroupAddUnit(deadCreeps, u)
           
            static if not RESPAWN_TOGETHER then
                call TimerStart(NewTimerEx(GetHandleId(u)), RESPAWN_DELAY, false, function TimerExpiration)
            endif
        endif
       
        set u = null
        return false
    endfunction
   
    private function GroupCreeps takes nothing returns nothing
        local unit temp
        local integer handleId
       
        call GroupEnumUnitsInRect(enumG, bj_mapInitialPlayableArea, Condition(function CheckOwner))
       
        loop
            set temp = FirstOfGroup(enumG)
            exitwhen temp == null
           
            if not IsUnitType(temp, UNIT_TYPE_DEAD) then
                set handleId = GetHandleId(temp)
                call SaveReal(ht, handleId, StringHash("x"), GetUnitX(temp))
                call SaveReal(ht, handleId, StringHash("y"), GetUnitY(temp))
                call SaveReal(ht, handleId, StringHash("facing"), GetUnitFacing(temp))
                call SaveInteger(ht, handleId, StringHash("owner"), GetPlayerId(GetOwningPlayer(temp)))
                call SaveInteger(ht, handleId, StringHash("type"), GetUnitTypeId(temp))
                call GroupAddUnit(creeps, temp)
            endif
           
            call GroupRemoveUnit(enumG, temp)
           
        endloop
       
    endfunction
   
    private function CreateDialog takes nothing returns nothing
        set timerWindow = CreateTimerDialog(respawnTimer)
        call TimerDialogSetTitle(timerWindow, TIMER_WINDOW_TEXT)
        call TimerDialogDisplay(timerWindow, true)
    endfunction
   
    private function OnInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerAddCondition(t, Condition(function CreepDeath))
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
        set t = null
       
        call GroupCreeps()
       
        static if RESPAWN_TOGETHER then
       
            set respawnTimer = CreateTimer()
            call TimerStart(respawnTimer, RESPAWN_DELAY, true, function RespawnAllCreeps)
           
            static if SHOW_TIMER_WINDOW then
                call TimerStart(NewTimer(), 0.01, false, function CreateDialog)
            endif
           
        endif
       
    endfunction
   
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//*  To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//*  To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass)   More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//*  * Attaching
//*  * Recycling (with double-free protection)
//*
//* set t=NewTimer()      : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x)   : Get a timer (alternative to CreateTimer), call
//*                            Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t)       : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2)     : Attach value 2 to timer
//* GetTimerData(t)       : Get the timer's value.
//*                         You can assume a timer's value is 0
//*                         after NewTimer.
//*
//* Multi-flavor:
//*    Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************

//================================================================
    globals
        //How to tweak timer utils:
        // USE_HASH_TABLE = true  (new blue)
        //  * SAFEST
        //  * SLOWEST (though hash tables are kind of fast)
        //
        // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true  (orange)
        //  * kinda safe (except there is a limit in the number of timers)
        //  * ALMOST FAST
        //
        // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
        //  * THE FASTEST (though is only  faster than the previous method
        //                  after using the optimizer on the map)
        //  * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
        //                     work)
        //
        private constant boolean USE_HASH_TABLE      = true
        private constant boolean USE_FLEXIBLE_OFFSET = false

        private constant integer OFFSET     = 0x100000
        private          integer VOFFSET    = OFFSET
             
        //Timers to preload at map init:
        private constant integer QUANTITY   = 256
       
        //Changing this  to something big will allow you to keep recycling
        // timers even when there are already AN INCREDIBLE AMOUNT of timers in
        // the stack. But it will make things far slower so that's probably a bad idea...
        private constant integer ARRAY_SIZE = 8190

    endglobals

    //==================================================================================================
    globals
        private integer array data[ARRAY_SIZE]
        private hashtable     ht
    endglobals
   
   

    //It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
    function SetTimerData takes timer t, integer value returns nothing
        static if(USE_HASH_TABLE) then
            // new blue
            call SaveInteger(ht,0,GetHandleId(t), value)
           
        elseif (USE_FLEXIBLE_OFFSET) then
            // orange
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-VOFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            set data[GetHandleId(t)-VOFFSET]=value
        else
            // new red
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-OFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            set data[GetHandleId(t)-OFFSET]=value
        endif        
    endfunction

    function GetTimerData takes timer t returns integer
        static if(USE_HASH_TABLE) then
            // new blue
            return LoadInteger(ht,0,GetHandleId(t) )
           
        elseif (USE_FLEXIBLE_OFFSET) then
            // orange
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-VOFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            return data[GetHandleId(t)-VOFFSET]
        else
            // new red
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-OFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            return data[GetHandleId(t)-OFFSET]
        endif        
    endfunction

    //==========================================================================================
    globals
        private timer array tT[ARRAY_SIZE]
        private integer tN = 0
        private constant integer HELD=0x28829022
        //use a totally random number here, the more improbable someone uses it, the better.
       
        private boolean       didinit = false
    endglobals
    private keyword init

    //==========================================================================================
    // I needed to decide between duplicating code ignoring the "Once and only once" rule
    // and using the ugly textmacros. I guess textmacros won.
    //
    //! textmacro TIMERUTIS_PRIVATE_NewTimerCommon takes VALUE
    // On second thought, no.
    //! endtextmacro

    function NewTimerEx takes integer value returns timer
        if (tN==0) then
            if (not didinit) then
                //This extra if shouldn't represent a major performance drawback
                //because QUANTITY rule is not supposed to be broken every day.
                call init.evaluate()
                set tN = tN - 1
            else
                //If this happens then the QUANTITY rule has already been broken, try to fix the
                // issue, else fail.
                debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
                set tT[0]=CreateTimer()
                static if( not USE_HASH_TABLE) then
                    debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
                    static if( USE_FLEXIBLE_OFFSET) then
                        if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
                            //all right, couldn't fix it
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    else
                        if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
                            //all right, couldn't fix it
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    endif
                endif
            endif
        else
            set tN=tN-1
        endif
        call SetTimerData(tT[tN],value)
     return tT[tN]
    endfunction
   
    function NewTimer takes nothing returns timer
        return NewTimerEx(0)
    endfunction


    //==========================================================================================
    function ReleaseTimer takes timer t returns nothing
        if(t==null) then
            debug call BJDebugMsg("Warning: attempt to release a null timer")
            return
        endif
        if (tN==ARRAY_SIZE) then
            debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")

            //stack is full, the map already has much more troubles than the chance of bug
            call DestroyTimer(t)
        else
            call PauseTimer(t)
            if(GetTimerData(t)==HELD) then
                debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
                return
            endif
            call SetTimerData(t,HELD)
            set tT[tN]=t
            set tN=tN+1
        endif    
    endfunction

    private function init takes nothing returns nothing
     local integer i=0
     local integer o=-1
     local boolean oops = false
        if ( didinit ) then
            return
        else
            set didinit = true
        endif
     
        static if( USE_HASH_TABLE ) then
            set ht = InitHashtable()
            loop
                exitwhen(i==QUANTITY)
                set tT[i]=CreateTimer()
                call SetTimerData(tT[i], HELD)
                set i=i+1
            endloop
            set tN = QUANTITY
        else
            loop
                set i=0
                loop
                    exitwhen (i==QUANTITY)
                    set tT[i] = CreateTimer()
                    if(i==0) then
                        set VOFFSET = GetHandleId(tT[i])
                        static if(USE_FLEXIBLE_OFFSET) then
                            set o=VOFFSET
                        else
                            set o=OFFSET
                        endif
                    endif
                    if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
                        exitwhen true
                    endif
                    if (GetHandleId(tT[i])-o>=0)  then
                        set i=i+1
                    endif
                endloop
                set tN = i
                exitwhen(tN == QUANTITY)
                set oops = true
                exitwhen not USE_FLEXIBLE_OFFSET
                debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")              
            endloop
           
            if(oops) then
                static if ( USE_FLEXIBLE_OFFSET) then
                    debug call BJDebugMsg("The problem has been fixed.")
                    //If this message doesn't appear then there is so much
                    //handle id fragmentation that it was impossible to preload
                    //so many timers and the thread crashed! Therefore this
                    //debug message is useful.
                elseif(DEBUG_MODE) then
                    call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
                    call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
                    call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
                    call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
                endif
            endif
        endif

    endfunction

endlibrary
Count Creeps
  Events
    Player - Player 1 (Red) types a chat message containing -count (stringnoformat) as An exact match
  Conditions
  Actions
    Cinematic - Clear the screen of text messages for (All players).
    Game - Display to (All players) for 30 seconds the text: ==============================
    Custom script: set udg_tempInt = GetAliveCreeps()
    Game - Display to (All players) for 30 seconds the text: (Alive creeps: + (String(tempInt)))
    Custom script: set udg_tempInt = GetDeadCreeps()
    Game - Display to (All players) for 30 seconds the text: (Dead creeps: + (String(tempInt)))
    Custom script: set udg_tempInt = GetTotalCreeps()
    Game - Display to (All players) for 30 seconds the text: (Total creeps: + (String(tempInt)))
    Game - Display to (All players) for 30 seconds the text: ==============================
Respawn All
  Events
    Player - Player 1 (Red) types a chat message containing -respawnall (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call RespawnAllCreeps()
Respawn For 10
  Events
    Player - Player 1 (Red) types a chat message containing -respawn(10) (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call RespawnAllCreepsForPlayer(Player(10))
Respawn For 11
  Events
    Player - Player 1 (Red) types a chat message containing -respawn(11) (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call RespawnAllCreepsForPlayer(Player(11))
Respawn For 12
  Events
    Player - Player 1 (Red) types a chat message containing -respawn(12) (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call RespawnAllCreepsForPlayer(Player(12))
Pause
  Events
    Player - Player 1 (Red) types a chat message containing -pause (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call PauseRespawnSystem(-1)
Resume
  Events
    Player - Player 1 (Red) types a chat message containing -resume (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call ResumeRespawnSystem()
Reset
  Events
    Player - Player 1 (Red) types a chat message containing -reset (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call ResetRespawnSystem()
Restart
  Events
    Player - Player 1 (Red) types a chat message containing -restart (stringnoformat) as An exact match
  Conditions
  Actions
    Custom script: call RestartRespawnSystem()