ForGroup, TriggerSleepAction ... how to fix?

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
This is a part from my SupplyCaravan Trigger whats bugging right now is:
1) When it is trying to re-order the failed spell from the ForGroup(failures, u) it detects that the city has mana to provide and picks it up (call IssueTargetOrder(u, "smart", genLastSpellTarget)) however, because of the wait needed to order it away to the other destination it doesn't work. Something with ForGroup, functioncalling and waits are messing it up. So how do I solve that? However, strangely enough: On the second iteration, next periodic trigger it does work.

JASS:
private function GatherSupplies takes nothing returns nothing
        local unit u = genLastSpellCaster
        local integer uId = GetUnitUserData(u)
        local real cityMana = GetUnitState(genLastSpellTarget, UNIT_STATE_MANA)
        if cityMana > 0 then 
            call IssueTargetOrder(u, "smart", genLastSpellTarget)
            set status[uId] = 0
            // THIS PART IS BUGGING, when being ordered from the failure group. They only move on the seond period.
            call TriggerSleepAction(0.1)
            call IssueTargetOrder(u, ORDER_DELIVER, city[cityDest[uId]].u)
        else 
            call BJDebugMsg("failed to gather... added to failures")
            call GroupAddUnit(failures, u)
            call UnitAddAbility(u, WAITING_GATHER)
            set status[uId] = STATUS_W_GATHER
            set lastAttemptTarget[uId] = GetUnitUserData(genLastSpellTarget)
        endif
        set u = null
    endfunction
    
    private function ReCheck takes nothing returns nothing
        local unit u = GetEnumUnit()
        local integer uId = GetUnitUserData(u)
        set genLastSpellCaster = u
        set genLastSpellTarget = city[lastAttemptTarget[uId]].u
        if status[uId] == STATUS_W_GATHER then 
            call GatherSupplies()
        else
            call DeliverSupplies()
        endif
        if status[uId] == 0 then
            call GroupRemoveUnit(failures, u) 
            call UnitRemoveAbility(u, WAITING_GATHER)
            call UnitRemoveAbility(u, WAITING_DELIVER)
        endif
    endfunction
    
    private function Periodic takes nothing returns nothing
        call ForGroup(failures, function ReCheck)
    endfunction

TBH, the whole thing is a cluster fuck, apart from that they actually miracuasly walk to and from a city. Save me! :D

I'm thinking a better solution is to actually check every order that the Caravan unit gives and update its status accordingly.
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,658
Dont use TriggerSleepAction()... NEVER!!!

Instead use this shiny thing that allows you to give an order after a given amount of time.

JASS:
globals
    hashtable udg_DelayedOrder_Hashtable        = InitHashtable()
    integer udg_DelayedOrder_TypeTarget         = 1
    integer udg_DelayedOrder_TypePointTarget    = 2
    integer udg_DelayedOrder_TypeTrain          = 3
    integer udg_DelayedOrder_TypeNoTarget       = 4
endglobals





library delayedorder
    function IssueOrderCallback takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer id = GetHandleId(t)
        local unit whichUnit = LoadUnitHandle(udg_DelayedOrder_Hashtable, id, 0)
        local integer orderType = LoadInteger(udg_DelayedOrder_Hashtable, id, 1)
        local string order = LoadStr(udg_DelayedOrder_Hashtable, id, 2)
        local widget targetWidget
        local location targetLocation
        local integer unitTypeId
        
        if orderType == udg_DelayedOrder_TypeTarget then
            set targetWidget = LoadWidgetHandle(udg_DelayedOrder_Hashtable, id, 3)
            call IssueTargetOrder(whichUnit, order, targetWidget)
            set targetWidget = null
        elseif orderType == udg_DelayedOrder_TypePointTarget then
            set targetLocation = LoadLocationHandle(udg_DelayedOrder_Hashtable, id, 3)
            call IssuePointOrder(whichUnit, order, GetLocationX(targetLocation), GetLocationY(targetLocation))
            call RemoveLocation(targetLocation)
            set targetLocation = null
        elseif orderType == udg_DelayedOrder_TypeTrain then
            set unitTypeId = LoadInteger(udg_DelayedOrder_Hashtable, id, 3)
            call IssueImmediateOrderById(whichUnit, unitTypeId)
        elseif orderType == udg_DelayedOrder_TypeNoTarget then
            call IssueImmediateOrder(whichUnit, order)
        endif
        
        call FlushChildHashtable(udg_DelayedOrder_Hashtable, id)
        call DestroyTimer(t)
        set t = null
        set whichUnit = null
    endfunction
    function IssueTargetOrderDelayed takes unit whichUnit, string order, widget targetWidget, real delay returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        
        call TimerStart(t, delay, false, function IssueOrderCallback)
        call SaveUnitHandle(udg_DelayedOrder_Hashtable, id, 0, whichUnit)
        call SaveInteger(udg_DelayedOrder_Hashtable, id, 1, udg_DelayedOrder_TypeTarget)
        call SaveStr(udg_DelayedOrder_Hashtable, id, 2, order)
        call SaveWidgetHandle(udg_DelayedOrder_Hashtable, id, 3, targetWidget)
        
        set t = null
    endfunction
    function IssuePointOrderDelayed takes unit whichUnit, string order, location targetLocation, real delay returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        
        call TimerStart(t, delay, false, function IssueOrderCallback)
        call SaveUnitHandle(udg_DelayedOrder_Hashtable, id, 0, whichUnit)
        call SaveInteger(udg_DelayedOrder_Hashtable, id, 1, udg_DelayedOrder_TypePointTarget)
        call SaveStr(udg_DelayedOrder_Hashtable, id, 2, order)
        call SaveLocationHandle(udg_DelayedOrder_Hashtable, id, 3, targetLocation)
        
        set t = null
    endfunction
    function IssueTrainOrderDelayed takes unit whichUnit, integer unitTypeId, real delay returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        
        call TimerStart(t, delay, false, function IssueOrderCallback)
        call SaveUnitHandle(udg_DelayedOrder_Hashtable, id, 0, whichUnit)
        call SaveInteger(udg_DelayedOrder_Hashtable, id, 1, udg_DelayedOrder_TypeNoTarget)
        call SaveInteger(udg_DelayedOrder_Hashtable, id, 3, unitTypeId)
        
        set t = null
    endfunction
    function IssueImmediateOrderDelayed takes unit whichUnit, string order, real delay returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        
        call TimerStart(t, delay, false, function IssueOrderCallback)
        call SaveUnitHandle(udg_DelayedOrder_Hashtable, id, 0, whichUnit)
        call SaveInteger(udg_DelayedOrder_Hashtable, id, 1, udg_DelayedOrder_TypeNoTarget)
        call SaveStr(udg_DelayedOrder_Hashtable, id, 2, order)
        
        set t = null
    endfunction
endlibrary

in your case:

call IssueTargetOrder(u, ORDER_DELIVER, city[cityDest[uId]].u)
->
call IssueTargetOrderDelayed(u, ORDER_DELIVER, city[cityDest[uId]].u)

and remove the TriggerSleepAction()

(I think that it is obvious that the big jass part should be in a separate trigger)
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
Another handy snippet from you thanks! :) I will try it,but it won't save me from my own flawed design. I mean while the ZZzzZ are coming out due to waiting, I can just order it away and it will stay marked as failed.

I was thinking while the caravan is either waiting or in transit between two cities it should create trigger events to detect if its being interrupted.
 
I haven't read through the problem in depth, but in case you need an explanation:

TriggerSleepAction is a funny function. Most people will use it without even questioning its name. Why is it named TriggerSleepAction? Well, because it is generally used in the "actions" portion of a trigger. That function won't actually work in callbacks to ForGroup(), TimerStart(), trigger conditions, etc., it will just stop the thread right there and no actions will be called afterward (which explains why the second order is never called).

So you have to use a timer if you want to do it in conjunction with ForGroup(). Even a first-of-group loop wouldn't do what you want in this case.

Also, I'm not sure if this will help you in this case--but all the Issue<Order> natives return a boolean of whether the order was successfully executed (a.k.a. whether the unit attempts the order vs. an error message). Maybe that fact will help you with what you're trying to do? idk. It is useful information regardless.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
I haven't read through the problem in depth, but in case you need an explanation:

TriggerSleepAction is a funny function. Most people will use it without even questioning its name. Why is it named TriggerSleepAction? Well, because it is generally used in the "actions" portion of a trigger. That function won't actually work in callbacks to ForGroup(), TimerStart(), trigger conditions, etc., it will just stop the thread right there and no actions will be called afterward (which explains why the second order is never called).

So you have to use a timer if you want to do it in conjunction with ForGroup(). Even a first-of-group loop wouldn't do what you want in this case.

Also, I'm not sure if this will help you in this case--but all the Issue<Order> natives return a boolean of whether the order was successfully executed (a.k.a. whether the unit attempts the order vs. an error message). Maybe that fact will help you with what you're trying to do? idk. It is useful information regardless.

Well, you are right, I didn't think to question its name, but I knew it was the issue, have actually so far not needed to use a timer and still don't although the solution provided by Wietlol houses a timer.

Sadly I don't think it will help, but the opening question is solved. The issue right now is that its too complex for me.. But I will keep trying.

The abilities are:
Mark Home. (Works)
Mark Destionation (Works)
Clear Route (OK)
Pause/Play Route (NO)

So when i enter destination and press "play" I want the unit status to be set to "working" until its interrupted at which point the ability (pause/play) shall be toggled. and you can move the unit as you want. Need a good efficient way to detect player interruption.

If its in play mode but cant pickup or deliver the goods it should be added to a group that will retry until successful.
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,658
@PurgeandFire
You didn't mention that it is a thread sleep with return-game notification.
So the duration is REAL TIME! (no pause, no gametime speedup, no nothing)
And the notification (continue of the remaining thread) is done in-game and can have a delay.

So it is extremely inaccurate.

@Pinzu
Cant you make a trigger on order events to catch player interruption?
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
@Pinzu
Cant you make a trigger on order events to catch player interruption?

There are so many ways and spells to interrupt with... But I suppose only one allowed order, gonna check a bit more. I think adding the units dynamically to trigger event as they are set to work would be best solution, which is what I have the hardest problem with,

Okey, maybe I can manage this and I'll return to polish the solution. ;P
 
The issue right now is that its too complex for me.. But I will keep trying.
Using timers is neither complex nor hard to learn.

It's literally just this (I'll try to explain it quick and simple):

*Note that everything that comes after the wait (the callback) via timers must be placed above the original function for it to be seen.

JASS:
globals
   hashtable HASH = InitHashtable() //this creates a table... usually, you only need one table for the entire game if you only use it for timer attachment
endglobals

function callback takes nothing returns nothing
   //this is your callback function; basicly everything that comes after the wait goes here
   local timer t = GetExpiredTimer() //this finds out which timer expired
   local integer i = LoadInteger(HASH, GetHandleId(t), 0)
   local unit u = LoadUnitHandle(HASH, GetHandleId(t), 1)
   //these load the variables you stored to the table... make sure the child indices match to what you entered before the wait (0, 1, 2, ...)

   //here be code using the integer "i" and the unit "u" after the wait

   call FlushChildHashtable(HASH, GetHandleId(t)) //this will clear the table entry, as we don't need it anymore
   call DestroyTimer(t) //this will clear the timer, as we won't need it anymore
   set t = null
   set u = null //and don't forget to clean the reference leaks
endfunction

function yourfunc takes nothing returns nothing
   local integer i = 0 //create all variables you want to attach to the timer
   local unit u = someUnit //create all variables you want to attach to the timer
   local timer t = CreateTimer() //and create a timer locally

   //here be your pre-wait code

   call SaveInteger(HASH, GetHandleId(t), 0, i)
   call SaveUnitHandle(HASH, GetHandleId(t), 1, u)
   //this is the magic function that makes all this work: you store your data to a hashtable using the unique index of the created timer (GetHandleId(t)).
   //the second integer will simply be count upwards for every variable you want to store (0, 1, 2, ...)

   call TimerStart(t, 2.0, false, function callback) //this starts your timer; you can attach the callback function here

   set t = null
   set u = null //don't forget to clear the reference leaks
endfunction
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
Using timers is neither complex nor hard to learn.

It's literally just this (I'll try to explain it quick and simple):
I suppose its not that hard, cant cope with the idea of having to call a new function just for a wait. ;P

Sorry, could you explain your problem from start to finish? I don't quite understand what you're trying to accomplish, but I'm sure there is a neat solution. Also include what classifies as a "player interruption".

Basically when you start the supply route it will either be ordered to gather or deliver supply (cast a spell) if any other order is issued then then the latest order it will be classed as interrupted. Once it reaches its destination a new order is declared and it is tasked to do that instead, and so it goes on. I got the interruption down, just some bugs with it staying in the group of failures after it managed to successfully complete the last order as well as the issue of if you interrupt it by casting the current order but on another city it will continue its delivery pattern instead of being "interrupted".

Also the whole thing has become a a bloated mess. ;p
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Using timers is neither complex nor hard to learn.
Using timers is complex. It is a total mess compared with SC2 where you can simply use Wait calls in the middle of a function to get the desired delay.

For a simple 3 stage effect waiting 1 and 2 seconds between stages...

WC3 -> 3 function or a state engine. Need some form of persistent data storage to handle the state.
SC2 -> single function with all actions expressed sequentially. Locals are sufficient to handle state from start to end.

Sure using them is not rocket science, but it still is not anywhere near easy.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
It now work for supply ships as well issues remaining:

1) If the unit is blocked (walled in for example) he will remain active even though the unit is no longer moving. Some sort of way to refresh the order when this happens would be good.

2) Can't check if a point on the map is reachable by land.

3) Can't check if a point is reached by sea.

4) No error messages for the above.

JASS:
scope SupplyCities initializer Init
    globals
        constant integer SUPPLY_CARAVAN         = 'hrdh'
        constant integer SUPPLY_SHIP            = 'hbot'
        constant integer CANCEL_ROUTE           = 'Atau'
        constant integer HOME_DEST              = 'A004'
        constant integer HOME_DEST_UNS          = 'A006'
        constant integer SUPPLY_DEST            = 'A005'
        constant integer SUPPLY_DEST_UNS        = 'A007'
        constant integer DELIVER                = 'A003'
        constant integer DELIVER_SHIP           = 'A00G'
        constant integer GATHER                 = 'A00B'
        constant integer GATHER_SHIP            = 'A00H'
        constant integer WAITING_DELIVER        = 'A00F'
        constant integer WAITING_GATHER         = 'A002'
        constant integer PLAY_PAUSE             = 'A00D'
        constant integer PLAY_PAUSE_SHIP        = 'A00I'
        constant integer STATUS_FREE            = 0        // If only two options exist these can be removed
        constant integer STATUS_WORKING         = 1
        constant string ORDER_GATHER            = "shadowstrike"
        constant string ORDER_DELIVER           = "cripple"
        constant string ORDER_STOP_WORK         = "bearform"
        constant string ORDER_NEW_DEST          = "unholyfrenzy"    // Not sure these are used
        constant string ORDER_NEW_HOME          = "charm"
        constant real PERIOD            = 5.
        constant real GATHER_PERCENT    = 50.
        private integer array cityDest
        private integer array cityHome
        private integer array status      
        private string array order  
        private group failures = CreateGroup()
        private trigger trgPeriodic 
    endglobals

    
    private function Cancel takes nothing returns nothing
        local unit caster = genLastSpellCaster
        local integer uId = GetUnitUserData(caster)
        if cityDest[uId] != 0 then
            set cityDest[uId] = 0
            call UnitAddAbility(caster, SUPPLY_DEST_UNS)
            call UnitRemoveAbility(caster, SUPPLY_DEST) 
        endif   
        if cityHome[uId] != 0 then
            set cityHome[uId] = 0
            call UnitAddAbility(caster, HOME_DEST_UNS)
            call UnitRemoveAbility(caster, HOME_DEST) 
        endif  
        if status[uId] != STATUS_FREE then
            call IssueImmediateOrderDelayed(caster, ORDER_STOP_WORK, 0.05)
        endif
        set caster = null
    endfunction
    
    private function Destination takes nothing returns nothing
        local unit caster = genLastSpellCaster
        local unit target = genLastSpellTarget
        local integer uId = GetUnitUserData(caster)
        if cityDest[uId] == 0 then
            call UnitAddAbility(caster, SUPPLY_DEST)
            call UnitRemoveAbility(caster, SUPPLY_DEST_UNS) 
        endif 
        set cityDest[uId] = GetUnitUserData(target)
        if cityDest[uId] == cityHome[uId] then
            set cityHome[uId] = 0
            call UnitAddAbility(caster, HOME_DEST_UNS)
            call UnitRemoveAbility(caster, HOME_DEST) 
        endif
        set caster = null
        set target = null
    endfunction
    
    private function Home takes nothing returns nothing
        local unit caster = genLastSpellCaster
        local unit target = genLastSpellTarget
        local integer uId = GetUnitUserData(caster)
        if cityHome[uId] == 0 then
            call UnitAddAbility(caster, HOME_DEST)
            call UnitRemoveAbility(caster, HOME_DEST_UNS) 
        endif
        set cityHome[uId] = GetUnitUserData(target)
        if cityHome[uId] == cityDest[uId] then
            set cityDest[uId] = 0
            call UnitAddAbility(caster, SUPPLY_DEST_UNS)
            call UnitRemoveAbility(caster, SUPPLY_DEST) 
        endif
        set caster = null
        set target = null
    endfunction
    
    private function ToggleFailure takes unit u, integer id, boolean toggle returns nothing
        if IsUnitInGroup(u, failures) == true and toggle == false then
            call GroupRemoveUnit(failures, u)
            call UnitRemoveAbility(u, WAITING_GATHER)
            call UnitRemoveAbility(u, WAITING_DELIVER)
            //call BJDebugMsg("Caravan Failure End - Status: " + I2S(status[id]) + "___" + order[id] )
        elseif IsUnitInGroup(u, failures) == false and toggle == true then 
            if order[id] == ORDER_GATHER then
                call UnitAddAbility(u, WAITING_GATHER)
            else 
               call UnitAddAbility(u, WAITING_DELIVER) 
            endif
            call GroupAddUnit(failures, u)
            //call BJDebugMsg("Caravan Failure - Status: " + I2S(status[id]) + "___" + order[id] )
        endif
    endfunction
    
    private function SetFree takes unit u, integer id returns nothing
        if GetUnitTypeId(u) == SUPPLY_CARAVAN then
            call UnitRemoveAbility(u, PLAY_PAUSE)
            call UnitAddAbility(u, PLAY_PAUSE)
        else
            call UnitRemoveAbility(u, PLAY_PAUSE_SHIP)
            call UnitAddAbility(u, PLAY_PAUSE_SHIP)
        endif
        set status[id] = STATUS_FREE
        set order[id] = null
        call ToggleFailure(u, id, false)
    endfunction
    
    
    private function PlayPauseButton takes nothing returns nothing
        local unit caster = genLastSpellCaster
        local integer uId = GetUnitUserData(caster)
        local real mana 
        if cityDest[uId] != 0 and cityHome[uId] != 0 and status[uId] == STATUS_FREE then
            set status[uId] = 1
            set mana = GetUnitState(caster, UNIT_STATE_MANA)
            if mana > 0 then
                set order[uId] = ORDER_DELIVER
                call IssueTargetOrder(caster, ORDER_DELIVER, city[cityDest[uId]].u)
            else
                set order[uId] = ORDER_GATHER
                call IssueTargetOrder(caster, ORDER_GATHER, city[cityHome[uId]].u)
            endif
        else
            call SetFree(caster, uId)
        endif
        set caster = null
    endfunction
    
    private function InterruptionCheck takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local integer uId = GetUnitUserData(u)
        local integer typeId = GetUnitTypeId(u)
        if typeId == SUPPLY_CARAVAN or typeId == SUPPLY_SHIP then 
            if status[uId] == STATUS_WORKING and order[uId] != OrderId2String(GetIssuedOrderId())  then
                // Set Free
                call SetFree(u, uId) 
                // Create Floating Text?
                call BJDebugMsg("interrupted!")
                call IssueImmediateOrder(u, "stop")
            endif
        endif
        set u = null
        return false 
    endfunction
    
    private function GatherSupplies takes nothing returns nothing
        local unit caster = genLastSpellCaster
        local unit target = genLastSpellTarget
        local integer uId = GetUnitUserData(caster)
        local real cityMana = GetUnitState(target, UNIT_STATE_MANA)
        local integer statusIn = status[uId]
        if cityMana/GetUnitState(caster, UNIT_STATE_MAX_MANA)*100 >= GATHER_PERCENT  then 
            set status[uId] = STATUS_FREE
            call IssueTargetOrder(caster, "smart", target)
            if statusIn == STATUS_WORKING then
                set order[uId] = ORDER_DELIVER
                call ToggleFailure(caster, uId, false)
                call IssueTargetOrderDelayed(caster, ORDER_DELIVER, city[cityDest[uId]].u, 0.1)
            else 
                call BJDebugMsg("GatherSupplies: Is this every called? (1)")
                call ToggleFailure(caster, uId, true) 
            endif
            call BJDebugMsg("GatherSupplies: Is this every called? (2)")
            set status[uId] = STATUS_WORKING
        elseif status[uId] == STATUS_WORKING then 
            call ToggleFailure(caster, uId, true) 
        endif
        set target = null
        set caster = null
    endfunction

    private function DeliverSupplies takes nothing returns nothing 
        local unit caster = genLastSpellCaster
        local unit target = genLastSpellTarget
        local integer uId = GetUnitUserData(caster)
        local real cityMana = GetUnitState(target, UNIT_STATE_MANA)
        local real cityManaMax = GetUnitState(target, UNIT_STATE_MAX_MANA)
        local real unitMana = GetUnitState(caster, UNIT_STATE_MANA)
        local integer statusIn = status[uId]
        
        if cityManaMax >= unitMana + cityMana then
            call SetUnitState(target, UNIT_STATE_MANA, unitMana + cityMana)
            call SetUnitState(caster, UNIT_STATE_MANA, 0)
            if cityHome[uId] != 0 and status[uId] == STATUS_WORKING then
                call ToggleFailure(caster, uId, false)
                set order[uId] = ORDER_GATHER
                call IssueTargetOrder(caster, ORDER_GATHER, city[cityHome[uId]].u)
            else 
                call BJDebugMsg("was not working therefor stopped!")
            endif
        else 
            // Delivers what mana posible and toggles failure on
            call SetUnitState(target, UNIT_STATE_MANA, cityManaMax)
            set unitMana = unitMana - cityManaMax + cityMana 
            call SetUnitState(caster, UNIT_STATE_MANA, unitMana)
            call ToggleFailure(caster, uId, true) 
        endif
        set target = null
        set caster = null
    endfunction
    
    private function ReCheck takes nothing returns nothing
        local unit u = GetEnumUnit()
        local integer uId = GetUnitUserData(u)
        if status[uId] == 0 then
            set order[uId] = null
            call ToggleFailure(u, uId, false)
        else
            if order[uId] == ORDER_DELIVER then 
                call IssueTargetOrder(u, ORDER_DELIVER, city[cityDest[uId]].u)
            elseif order[uId] == ORDER_GATHER then
                call IssueTargetOrder(u, ORDER_GATHER, city[cityHome[uId]].u)
            endif
        endif
        set u = null
    endfunction
    
    private function Periodic takes nothing returns nothing
        call ForGroup(failures, function ReCheck)
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        local trigger t2 = CreateTrigger()
        local trigger t3 = CreateTrigger()
        local trigger t4 = CreateTrigger()
        local trigger t5 = CreateTrigger()
        local trigger t6 = CreateTrigger()
        local trigger t7 = CreateTrigger()
        local integer i = 0
        local player p 
        set trgPeriodic = CreateTrigger()
        loop
            set p = Player(i)
            call TriggerRegisterPlayerUnitEvent(t7, p, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(t7, p, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(t7, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
            set i = i + 1
            exitwhen i == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerRegisterTimerEvent(trgPeriodic, PERIOD, true)
        call TrgRegisterGenericSpellFinish(t1, CANCEL_ROUTE)
        call TrgRegisterGenericSpellFinish(t2, SUPPLY_DEST_UNS)
        call TrgRegisterGenericSpellFinish(t2, SUPPLY_DEST)
        call TrgRegisterGenericSpellFinish(t3, HOME_DEST_UNS)
        call TrgRegisterGenericSpellFinish(t3, HOME_DEST)
        call TrgRegisterGenericSpellFinish(t4, DELIVER)
        call TrgRegisterGenericSpellFinish(t4, DELIVER_SHIP)
        call TrgRegisterGenericSpellFinish(t5, GATHER)
        call TrgRegisterGenericSpellFinish(t5, GATHER_SHIP)
        call TrgRegisterGenericSpellFinish(t6, PLAY_PAUSE)
        call TrgRegisterGenericSpellFinish(t6, PLAY_PAUSE_SHIP)
        call TriggerAddAction(t1, function Cancel)
        call TriggerAddAction(t2, function Destination)
        call TriggerAddAction(t3, function Home)
        call TriggerAddAction(t4, function DeliverSupplies)
        call TriggerAddAction(t5, function GatherSupplies)
        call TriggerAddAction(t6, function PlayPauseButton)
        call TriggerAddCondition(t7, Condition(function InterruptionCheck))
        call TriggerAddAction(trgPeriodic, function Periodic) 
    endfunction
endscope
 
Last edited:
Status
Not open for further replies.
Top