Order System

Executor

I see you
Reaction score
57
Hi,

do you think the following OrderSystem could be useful?

JASS:
    interface BaseOrder
        string  c
        unit    u
        method issue takes nothing returns nothing defaults nothing
    endinterface
    
    struct DynamicOrder extends BaseOrder
        string cp
        string cw
        method issuePoint takes real x, real y returns nothing
            call IssuePointOrder(.u,.cp,x,y)
        endmethod
        method issueWidget takes widget w returns nothing
            call IssueTargetOrder(.u, .cw, w)
        endmethod
        method issueImmed takes nothing returns nothing
            call IssueImmediateOrder(.u, .c)
        endmethod
        static method NewDynamicOrder takes unit u, string cp, string cw, string c  returns Order
            local thistype this = thistype.allocate()
            local Order o   = Order.create()
            set .u = u
            set .c = c
            set .cp = cp
            set .cw = cw
            set o.Dynamic = this
            set o.TheOrder = this
            return o
        endmethod
    endstruct
    
    struct NonTargetedOrder extends BaseOrder
        method issueOnPoint takes real x, real y returns nothing
            call IssuePointOrder(.u, .c, x , y )
        endmethod
        method issueOnWidget takes widget w returns nothing
            call IssueTargetOrder(.u, .c, w)
        endmethod
        method issueImmed takes nothing returns nothing
            call IssueImmediateOrder(.u, .c)
        endmethod
        static method NewNonTargetedOrder takes unit u, string c returns Order
            local thistype this = thistype.allocate()
            local Order o   = Order.create()
            set .u              = u
            set .c              = c
            set o.NonTargeted   = this
            set o.TheOrder      = this
            return o
        endmethod
    endstruct
        
    struct PointOrder extends BaseOrder
        real x
        real y
        method issue takes nothing returns nothing
            call IssuePointOrder(.u, .c, .x , .y)
        endmethod
        static method NewPointOrder takes unit u, string c, real x, real y returns Order
            local thistype this = thistype.allocate()
            local Order o   = Order.create()
            set .u = u
            set .c = c
            set .x = x
            set .y = y
            set o.Point = this
            set o.TheOrder = this
            return o
        endmethod
    endstruct
    
    private struct ImmedOrder extends BaseOrder
        method issue takes nothing returns nothing
            call IssueImmediateOrder(.u, .c)
        endmethod
        static method NewImmedOrder takes unit u ,string c returns Order
            local thistype this = thistype.allocate()
            local Order o   = Order.create()
            set .u = u
            set .c = c
            set o.Immed = this
            set o.TheOrder = this
            return o
        endmethod
    endstruct
    
    private struct WidgetOrder extends BaseOrder
        widget w
        method issue takes nothing returns nothing
            call IssueTargetOrder(.u, .c, .w)
        endmethod
        static method NewWidgetOrder takes unit u, string c, widget w returns Order
            local thistype this = thistype.allocate()
            local Order o   = Order.create()
            set .u = u
            set .w = w
            set .c = c
            set o.Widget = this
            set o.TheOrder = this
            return o
        endmethod
    endstruct
    
    struct Order
        BaseOrder TheOrder            = 0
        method issue takes nothing returns nothing
            call TheOrder.issue()
        endmethod
        delegate PointOrder         Point       = 0
        delegate WidgetOrder        Widget      = 0
        delegate ImmedOrder         Immed       = 0
        delegate DynamicOrder       Dynamic     = 0
        delegate NonTargetedOrder   NonTargeted = 0
    endstruct


JASS:
scope Test initializer INIT
    private function TheTest1 takes nothing returns nothing
        local Order T = Order.NewDynamicOrder(gg_unit_hpea_0001,"move","attack","stop")
        
        call TriggerSleepAction(1.)
        call T.issuePoint(1000.,1000.)  // worker moves to 1000/1000
        call TriggerSleepAction(2.)
        call T.issueImmed()             // he stops
        call TriggerSleepAction(1.)
        call T.issueWidget(gg_unit_hpea_0002) // he attacks another worker
        call TriggerSleepAction(6.)
        call T.issueImmed()             // he stops
    endfunction
    private function TheTest2 takes nothing returns nothing
        local Order T = Order.NewPointOrder(gg_unit_hpea_0003,"move",1000.,1000.)
        
        call T.issue()
    endfunction
    private function INIT takes nothing returns nothing
        call TheTest1.execute()
        call TheTest2.execute()
    endfunction
endscope
 

Executor

I see you
Reaction score
57
Basically yes, but the important thing is that it saves the parameters. Could be helpful here for example.
 

Viikuna

No Marlo no game.
Reaction score
265
Order systems are pretty useful actually.

You could for example have some list issued orders for each unit, so you can find out units previous orders and maybe re-order them if needed or some stuff like that.
 

SerraAvenger

Cuz I can
Reaction score
234
I'd think it could be more usefull if you don't have to create one per unit you are issuing targets...
But I guess thats the whole point of the code, so well.
It is quite fancy indeed, but I don't see many uses out there.
 

Executor

I see you
Reaction score
57
I'ld think it could be more usefull if you don't have to create one per unit you are issuing targets...

So you want a more general order type?

JASS:
local Order T = Order.NewWidgetOrder("attack")

call T.issue(unit, unit)


Well imo this type of order has definitly the least amount of uses.
 

SerraAvenger

Cuz I can
Reaction score
234
So you want a more general order type?

JASS:

local Order T = Order.NewWidgetOrder("attack")

call T.issue(unit, unit)


Well imo this type of order has definitly the least amount of uses.

You could plant it statically into a struct, and then use
JASS:

struct dummy
 static Order cast = Order.NewBlaBlaOrder( "thunderclap" )
endstruct

local dummy d = dummy.create( 0, 0 )
call dummy.cast( )


But well, using orders manually is most probably fairly good enough.
 

Executor

I see you
Reaction score
57
You could plant it statically into a struct, and then use
JASS:

struct dummy
 static Order cast = Order.NewBlaBlaOrder( "thunderclap" )
endstruct

local dummy d = dummy.create( 0, 0 )
call dummy.cast( )


But well, using orders manually is most probably fairly good enough.

Is somehow equal to

JASS:

local Order T = Order.NewImmedOrder(CreateUnit(..),"thunderclap")
call T.issue()


When I allow access to the Order data it IS equal.
 

SerraAvenger

Cuz I can
Reaction score
234
The interface is the same, yet the underlying structure is quite much different. You have one order struct per dummy, I have one for all dummies. Its just a little bit less traffic and no struct recycling in such a scenario (consider spawning units, like in an AoS)

What ever. I don't think you could have 8k Order structs out there anyway.

Have fun, Serra
 

Executor

I see you
Reaction score
57
Ah yes, completely ignored the point with static and .. hm .. just misunderstood you.
But imo this kind of primitive things can be done on the normal way more easily. My sys could maybe help when handling more complex problems.

Some more opinions to the topic "OrderSystem"?
 

Jesus4Lyf

Good Idea™
Reaction score
397
The only thing useful about an order system is getting a list of a unit's previous orders, and being able to re-order them (which means knowing if they were targetted, ground target or no target and implementing functionality to just say call [LJASS]GetUnitLastOrder(unit,2).reorder() // Reorders the unit's second last order.[/LJASS]).
 

Executor

I see you
Reaction score
57
Well mb "OrderUtils", "Orders" or "vOrder" :)P)

I want to include maybe more than just the types and the OrderRecorder.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I want to include maybe more than just the types and the OrderRecorder.
Please don't just wrap stuff.
JASS:
    private function TheTest1 takes nothing returns nothing
        local Order T = Order.NewDynamicOrder(gg_unit_hpea_0001,"move","attack","stop")
        
        call TriggerSleepAction(1.)
        call T.issuePoint(1000.,1000.)  // worker moves to 1000/1000
        call TriggerSleepAction(2.)
        call T.issueImmed()             // he stops
        call TriggerSleepAction(1.)
        call T.issueWidget(gg_unit_hpea_0002) // he attacks another worker
        call TriggerSleepAction(6.)
        call T.issueImmed()             // he stops
    endfunction
I don't like that stuff, honestly. It is obscurely specific to the situation and generally unhelpful.

I think making an "Order System" is annoying, but a last order tracking thing would be cool. :thup:
 
Reaction score
341
I think making an "Order System" is annoying, but a last order tracking thing would be cool

I know you can't go on wc3c.net but I think Rising_Dusk made a LastOrder script.

EDIT: Yup.

JASS:
library LastOrder initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* LastOrder is a library that was designed to allow interfacing with the last
//* N orders any unit on your map has received. This library was also designed
//* to be used as a means to reissue lost orders to a unit either after
//* preventing a spell cast or in many other situations.
//* 
//* There are two configuration constants for you to play with in using this
//* script. ORDERS_TO_HOLD is basically the size of the game's memory for each
//* individual unit. The larger the number is, the further back you can retrace
//* a unit's order list. Setting this value to 3 suffices for all actual
//* mechanics purposes. Raise it only if you have a specific application where
//* you need more. Lowering it to 2 covers most cases, but may miss a few, and
//* lowering it to 1 prevents you from adequately canceling spells and properly
//* reissuing previous orders. I recommend leaving it alone at 3. The MAX_ORDERS
//* constant is the number of orders that the system holds over all units at a
//* given time. If you are worried about running out, go ahead and increase it,
//* but be aware that it will use big arrays (which are slower) if you use a
//* number over 8191. Don't lower it under 8191, there's no reason to. Don't
//* change the non-private constants, there's no reason to.
//* 
//*     function GetPastOrder takes unit u, integer whichOrder returns order
//*     function GetPastOrderId takes unit u, integer whichOrder returns integer
//*     function GetPastOrderString takes unit u, integer whichOrder returns string
//*     function GetPastOrderType takes unit u, integer whichOrder returns integer
//*     function GetPastOrderX takes unit u, integer whichOrder returns real
//*     function GetPastOrderY takes unit u, integer whichOrder returns real
//*     function GetPastOrderTarget takes unit u, integer whichOrder returns widget
//* 
//* The above API is the main list of functions the user can use to interface
//* with past orders. If you want the immediate last order for a player, use 1
//* for the whichOrder integer. The 'order' returned by GetPastOrder is a struct
//* that contains all information of an issued order. If you want to interface
//* directly with the struct and skip all of the interfacing wrappers, you have
//* access to them via the following commands:
//* 
//*     [unit]     .u       The unit being ordered.
//*     [integer]  .id      The order id of the past order.
//*     [integer]  .typ     The type of the past order. (See constants)
//*     [boolean]  .fin     A flag indicating whether the order was finished.
//*     [widget]   .tar     The target widget of the past order.
//*     [real]     .x       The x coordinate of the target point of the order.
//*     [real]     .y       The y coordinate of the target point of the order.
//* 
//* There is also a sizable API for backwards compatibility with older versions
//* of the library. This API assumes that you're talking about a specific past
//* order, either the lastmost order or the second lastmost. In most cases,
//* these are still useful because they remove an argument from the call.
//* 
//*     function GetLastOrder takes unit u returns order
//*     function GetLastOrderId takes unit u returns integer
//*     function GetLastOrderString takes unit u returns string
//*     function GetLastOrderType takes unit u returns integer
//*     function GetLastOrderX takes unit u returns real
//*     function GetLastOrderY takes unit u returns real
//*     function GetLastOrderTarget takes unit u returns widget
//*     function IsLastOrderFinished takes unit u returns boolean
//* 
//* Besides being able to get information about all of the past orders a unit
//* has been issued, the most useful part of this system is actually reissuing
//* those orders as a means to fix lost orders or intercept and prevent spell
//* casting. The following API is then available to the user:
//* 
//*     function IssuePastOrder takes unit u, integer whichOrder returns boolean
//*     function IssueLastOrder takes unit u returns boolean
//*     function IssueSecondLastOrder takes unit u returns boolean
//*     function AbortOrder takes unit u returns boolean
//* 
//* If you want to reissue an arbitrary past order, IssuePastOrder is the
//* function that you'll want to use on a unit. To issue the last or second last
//* orders, there are functions for those as well. (They mostly exist for
//* backwards compatibility) AbortOrder is a means for anyone using this script
//* to stop a unit from running any given order that they happen to have at any
//* moment. AbortOrder is used in conjunction with a supplementary library,
//* AbortSpell, to seamlessly replicate WC3's spell error messages.
//* 
//* If you have any further questions regarding LastOrder or how to use it, feel
//* free to visit <a href="http://www.wc3c.net" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.wc3c.net</a> and ask questions there. This library should only
//* ever be released at WC3C and at no other site. Please give credits if this
//* library finds its way into your maps, and otherwise thanks for reading!
//* 
//* Enjoy!
//* 
globals    
    //Order type variables
            constant integer ORDER_TYPE_TARGET    = 1
            constant integer ORDER_TYPE_POINT     = 2
            constant integer ORDER_TYPE_IMMEDIATE = 3
    
    //System constants
    private constant integer ORDERS_TO_HOLD       = 3    //How many past orders the
                                                         //system holds for each unit.
                                                         //Should be at least 2.
    private constant integer MAX_ORDERS           = 8191 //The max number of orders
                                                         //the system can maintain.
                                                         //Going over 8191 uses big
                                                         //arrays, which are slower
                                                         //than normal arrays.
endglobals

globals
    private hashtable ht = InitHashtable()
endglobals

struct order[MAX_ORDERS]
    unit    u
    integer id
    integer typ
    boolean fin
    widget  tar
    real    x
    real    y
    static method create takes unit ordered, integer ordid, integer ordtyp, widget target, real ordx, real ordy returns order
        local order   o   = order.allocate()
        local integer i   = ORDERS_TO_HOLD
        local integer hid = GetHandleId(ordered)
        
        set o.u   = ordered
        set o.id  = ordid
        set o.typ = ordtyp
        set o.fin = false
        set o.tar = target
        set o.x   = ordx
        set o.y   = ordy
        //Handle stored orders in the hashtable
        loop
            //We hold up to the constant ORDERS_TO_HOLD in the table
            exitwhen i == 1
            //Moves the N-1th order to the Nth slot, etc. except storing new last order
            if HaveSavedInteger(ht, hid, i-1) then
                if i == ORDERS_TO_HOLD and HaveSavedInteger(ht, hid, i) then
                    //Destroy lastmost order struct
                    call order.destroy(order(LoadInteger(ht, hid, i)))
                endif
                //Can only do this if the N-1th order exists
                call SaveInteger(ht, hid, i, LoadInteger(ht, hid, i-1))
            endif
            set i = i - 1
        endloop
        //Store the new order to the hashtable as 1th last order
        call SaveInteger(ht, hid, 1, integer(o))
        return o
    endmethod
endstruct

//******************************************************************************

//! textmacro LastOrderDebug takes ORDER, RETURN
    debug if $ORDER$ &gt; ORDERS_TO_HOLD then
    debug     call BJDebugMsg(SCOPE_PREFIX+&quot;Error: Order out of range&quot;)
    debug     return $RETURN$
    debug endif
    debug if not HaveSavedInteger(ht, GetHandleId(u), $ORDER$) then
    debug     call BJDebugMsg(SCOPE_PREFIX+&quot;Error: The &quot;+I2S($ORDER$)+&quot;th order doesn&#039;t exist&quot;)
    debug     return $RETURN$
    debug endif
//! endtextmacro

function GetPastOrder takes unit u, integer whichOrder returns order
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;0&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder))
endfunction
function GetPastOrderId takes unit u, integer whichOrder returns integer
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;0&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder)).id
endfunction
function GetPastOrderString takes unit u, integer whichOrder returns string
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;\&quot;\&quot;&quot;)
    return OrderId2String(order(LoadInteger(ht, GetHandleId(u), 1)).id)
endfunction
function GetPastOrderType takes unit u, integer whichOrder returns integer
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;0&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder)).typ
endfunction
function GetPastOrderX takes unit u, integer whichOrder returns real
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;0.&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder)).x
endfunction
function GetPastOrderY takes unit u, integer whichOrder returns real
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;0.&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder)).y
endfunction
function GetPastOrderTarget takes unit u, integer whichOrder returns widget
    //! runtextmacro LastOrderDebug(&quot;whichOrder&quot;, &quot;null&quot;)
    return order(LoadInteger(ht, GetHandleId(u), whichOrder)).tar
endfunction

//******************************************************************************

function GetLastOrder takes unit u returns order
    return GetPastOrder(u, 1)
endfunction
function GetLastOrderId takes unit u returns integer
    return GetPastOrderId(u, 1)
endfunction
function GetLastOrderString takes unit u returns string
    return GetPastOrderString(u, 1)
endfunction
function GetLastOrderType takes unit u returns integer
    return GetPastOrderType(u, 1)
endfunction
function GetLastOrderX takes unit u returns real
    return GetPastOrderX(u, 1)
endfunction
function GetLastOrderY takes unit u returns real
    return GetPastOrderY(u, 1)
endfunction
function GetLastOrderTarget takes unit u returns widget
    return GetPastOrderTarget(u, 1)
endfunction
function IsLastOrderFinished takes unit u returns boolean
    //! runtextmacro LastOrderDebug(&quot;1&quot;, &quot;false&quot;)
    return GetUnitCurrentOrder(u) == 0 or order(LoadInteger(ht, GetHandleId(u), 1)).fin
endfunction

//******************************************************************************

private function OrderFilter takes unit u, integer id returns boolean
    //* Excludes specific orders or unit types from registering with the system
    //* 
    //* 851972: stop
    //*         Stop is excluded from the system because it is the order that
    //*         tells a unit to do nothing. It should be ignored by the system.
    //* 
    //* 851971: smart
    //* 851986: move
    //* 851983: attack
    //* 851984: attackground
    //* 851990: patrol
    //* 851993: holdposition
    //*         These are the UI orders that are passed to the system.
    //*
    //* 851973: stunned
    //*         This order is issued when a unit is stunned onto the stunner
    //*         It&#039;s ignored by the system, since you&#039;d never want to reissue it
    //* 
    //* &gt;= 852055, &lt;= 852762
    //*         These are all spell IDs from defend to incineratearrowoff with
    //*         a bit of leeway at the ends for orders with no strings.
    //* 
    return id == 851971 or id == 851986 or id == 851983 or id == 851984 or id == 851990 or id == 851993 or (id &gt;= 852055 and id &lt;= 852762)
endfunction

private function IssuePastOrderFilter takes unit u, integer whichOrder returns boolean
    //* Some criteria for whether or not a unit&#039;s last order should be given
    //* 
    //* INSTANT type orders are excluded because generally, reissuing an instant
    //* order doesn&#039;t make sense. You can remove that check below if you&#039;d like,
    //* though.
    //* 
    //* The Type check is really just to ensure that no spell recursion can
    //* occur with IssueLastOrder. The problem with intercepting the spell cast
    //* event is that it happens after the order is &#039;caught&#039; and registered to
    //* this system. Therefore, to just IssueLastOrder tells it to recast the
    //* spell! That&#039;s a problem, so we need a method to eliminate it.
    //* 
    return GetUnitTypeId(u) != 0 and not IsUnitType(u, UNIT_TYPE_DEAD) and GetPastOrderType(u, whichOrder) != 0 and GetPastOrderType(u, whichOrder) != ORDER_TYPE_IMMEDIATE
endfunction

//******************************************************************************

function IssuePastOrder takes unit u, integer whichOrder returns boolean
    local order o = GetPastOrder(u, whichOrder)
    if IssuePastOrderFilter(u, whichOrder) and not o.fin then
        if o.typ == ORDER_TYPE_TARGET then
            return IssueTargetOrderById(u, o.id, o.tar)
        elseif o.typ == ORDER_TYPE_POINT then
            if o.id == 851971 then
                //This adjusts for a bug in the point order&#039;s boolean return 
                //when issuing a smart order
                call IssuePointOrderById(u, o.id, o.x, o.y)
                return true
            else
                return IssuePointOrderById(u, o.id, o.x, o.y)
            endif
        elseif o.typ == ORDER_TYPE_IMMEDIATE then
            return IssueImmediateOrderById(u, o.id)
        endif
    endif
    return false
endfunction

function IssueLastOrder takes unit u returns boolean
    return IssuePastOrder(u, 1)
endfunction

function IssueSecondLastOrder takes unit u returns boolean
    return IssuePastOrder(u, 2)
endfunction

function AbortOrder takes unit u returns boolean
    if IsUnitPaused(u) then
        return false
    else
        call PauseUnit(u, true)
        call IssueImmediateOrder(u, &quot;stop&quot;)
        call PauseUnit(u, false)
    endif
    return true
endfunction

//**********************************************************

private function Conditions takes nothing returns boolean
    return OrderFilter(GetTriggerUnit(), GetIssuedOrderId())
endfunction

private function Actions takes nothing returns nothing
    local unit    u   = GetTriggerUnit()
    local widget  t   = GetOrderTarget()
    local integer oid = GetIssuedOrderId()
    local integer oty = 0
    
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
        call order.create(u, oid, ORDER_TYPE_TARGET, t, GetWidgetX(t), GetWidgetY(t))
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
        call order.create(u, oid, ORDER_TYPE_POINT, null, GetOrderPointX(), GetOrderPointY())
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER then
        call order.create(u, oid, ORDER_TYPE_IMMEDIATE, null, GetUnitX(u), GetUnitY(u))
    debug else
        debug call BJDebugMsg(SCOPE_PREFIX+&quot;Error: Invalid order type&quot;)
    endif
    
    set u = null
    set t = null
endfunction

//**********************************************************

private function SpellActions takes nothing returns nothing
    local order o = GetPastOrder(GetTriggerUnit(), 1)
    set o.fin = true
endfunction

//**********************************************************

private function OnAdd takes nothing returns boolean
    local integer hid = GetHandleId(GetFilterUnit())
    local integer i   = ORDERS_TO_HOLD
    
    //Handle stored orders in the hashtable
    loop
        //We hold up to the constant ORDERS_TO_HOLD in the table
        exitwhen i == 0
        //If any of the N orders exist for this handle id, kill them all
        if HaveSavedInteger(ht, hid, i) then
            call order.destroy(order(LoadInteger(ht, hid, i)))
            call RemoveSavedInteger(ht, hid, i)
        endif
        set i = i - 1
    endloop
    
    return false
endfunction

//**********************************************************

private function Init takes nothing returns nothing
    local trigger trg = CreateTrigger()
    local region  re  = CreateRegion()
    local rect    m   = GetWorldBounds()
    
    //Main order catching trigger
    call TriggerAddAction(trg, function Actions)
    call TriggerAddCondition(trg, Condition(function Conditions))
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    
    //Spell trigger to set a flag that indicates a spell order&#039;s completion
    set trg = CreateTrigger()
    call TriggerAddAction(trg, function SpellActions)
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    
    //Entering world trigger that clears old data from handle ids
    set trg = CreateTrigger()
    call RegionAddRect(re, m)
    call TriggerRegisterEnterRegion(trg, re, Condition(function OnAdd))
    call RemoveRect(m)
    
    set trg = null
    set re  = null
    set m   = null
endfunction
endlibrary
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I know you can't go on wc3c.net but I think Rising_Dusk made a LastOrder script.
Actually, I can go on. I just can't post.

That's not as object oriented as I would like... but I wouldn't use this stuff anyway, I imagine. It is probably most useful for creep AI or something.

It would be cool just to get a GetTriggerOrder() event response that returns an order, containing in it the target, type, etc, with a .issueTo(unit) method. But then you'd need to destroy it and stuff also.

Is any of this that useful? lol...
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top