• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] [SNIPPET] IssuedOrder

Status
Not open for further replies.
Level 7
Joined
Apr 5, 2011
Messages
245
It's a small configurable snippet for handy detection issued orders.

Here you proc your global event onUnitIssuesOrder:
JASS:
//==============
//=== Events ===
//==============

library Events
    function onUnitIssuesOrder takes nothing returns nothing
        call BJDebugMsg(Orders.String[IssuedOrder.id])
        if Orders.Type[IssuedOrder.id] == ORDER_TYPE_IMMEDIATE then
            call IssuePointOrderById(GetTriggerUnit(), ORDER_MOVE, 0, 0)
        endif
    endfunction
endlibrary
You may use
- GetTriggerUnit()
- IssuedOrder.id
- Orders.Type[]
- Orders.String[]
to get some data about event.

Here you write all data about orders you need in your map:
JASS:
//==============
//=== Orders ===
//=== v0.900 ===

library Orders
    globals
//--- Settings ---
        private constant boolean STRINGS = true
//----------------
        //Order types declaration
        constant integer ORDER_TYPE_IMMEDIATE = 0
        constant integer ORDER_TYPE_POINT = 1
        constant integer ORDER_TYPE_TARGET = 2
        constant integer ORDER_TYPE_SMART = 3
        constant integer ORDERS_OFFSET = 851970
        //Orders declaration
        constant integer ORDER_STOP = 2
        constant integer ORDER_MOVE = 1
        constant integer ORDER_ATTACK = 13
        constant integer ORDER_SMART = 16
        constant integer ORDER_HOLDPOSITION = 23
        constant integer ORDER_PATROL = 20
    endglobals
    struct Orders extends array
        readonly static integer array Type
        static if STRINGS then
            readonly static string array String
        endif
        private static method onInit takes nothing returns nothing
            //Orders data
            static if STRINGS then
                set String[ORDER_STOP] = "stop"
                set String[ORDER_MOVE] = "move"
                set String[ORDER_ATTACK] = "attack"
                set String[ORDER_SMART] = "smart"
                set String[ORDER_HOLDPOSITION] = "holdposition"
                set String[ORDER_PATROL] = "patrol"
            endif
            set Type[ORDER_STOP] = ORDER_TYPE_IMMEDIATE
            set Type[ORDER_MOVE] = ORDER_TYPE_SMART
            set Type[ORDER_ATTACK] = ORDER_TYPE_SMART
            set Type[ORDER_SMART] = ORDER_TYPE_SMART
            set Type[ORDER_HOLDPOSITION] = ORDER_TYPE_IMMEDIATE
            set Type[ORDER_PATROL] = ORDER_TYPE_SMART
        endmethod
    endstruct
endlibrary
As you see all in-game order integers become small, it seems more handy and efficient. Turn "STRINGS" false if you don't need to store strings for orders.

Here is order detection:
JASS:
//===================
//=== IssuedOrder ===
//===== v1.000 ======

library IssuedOrder requires NExt
    struct IssuedOrder extends array
        readonly static integer id
        private static trigger t
        
        static method imitate takes unit u returns nothing
            if     Orders.Type[id] == ORDER_TYPE_IMMEDIATE then
                call IssueImmediateOrderById(u, id + ORDERS_OFFSET)
            elseif Orders.Type[id] == ORDER_TYPE_POINT then
                call IssuePointOrderById(u, id + ORDERS_OFFSET, GetOrderPointX(), GetOrderPointY())
            elseif Orders.Type[id] == ORDER_TYPE_TARGET then
                call IssueTargetOrderById(u, id + ORDERS_OFFSET, GetOrderTarget())
            elseif Orders.Type[id] == ORDER_TYPE_SMART then
                if GetOrderTarget() == null then
                    call IssuePointOrderById(u, id + ORDERS_OFFSET, GetOrderPointX(), GetOrderPointY())
                else
                    call IssueTargetOrderById(u, id + ORDERS_OFFSET, GetOrderTarget())
                endif
            endif
        endmethod

        private static method func takes nothing returns boolean
            set id = GetIssuedOrderId() - ORDERS_OFFSET
            static if LIBRARY_Events then
                call onUnitIssuesOrder()
            endif
            return false
        endmethod
        
        private static method onInit takes nothing returns nothing
            set t = CreateTrigger()
            call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
            call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
            call TriggerRegisterAnyUnitEvent(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
            call TriggerAddCondition(t, Condition(function thistype.func))
        endmethod
    endstruct
endlibrary
You may use IssuedOrder.imitate(unit U) to make U doing the same order as detected.

And support library that I use very often:
JASS:
//======================
//=======[ NExt ]=======
//======= v0.502 =======

library NExt
    globals
        constant integer MAX_PLAYER_INDEX = 13
    endglobals

    function GroupEnumUnits takes group whichGroup, boolexpr filter returns nothing
        local integer i = 0
        loop
            call GroupEnumUnitsOfPlayer(whichGroup, Player(i), filter)
            exitwhen i == MAX_PLAYER_INDEX
            set i = i + 1
        endloop
    endfunction
    
    function TriggerRegisterAnyUnitEvent takes trigger trig, playerunitevent whichEvent, boolexpr filter returns nothing
        local integer i = 0
        loop
            call TriggerRegisterPlayerUnitEvent(trig, Player(i), whichEvent, filter)
            exitwhen i == MAX_PLAYER_INDEX
            set i = i + 1
        endloop
    endfunction

    function MakePlayersAllyWithVision takes player p1, player p2 returns nothing
        call SetPlayerAlliance(p1, p2, ALLIANCE_PASSIVE, true)
        call SetPlayerAlliance(p1, p2, ALLIANCE_HELP_REQUEST, true)
        call SetPlayerAlliance(p1, p2, ALLIANCE_HELP_RESPONSE, true)
        call SetPlayerAlliance(p1, p2, ALLIANCE_SHARED_XP, true)
        call SetPlayerAlliance(p1, p2, ALLIANCE_SHARED_SPELLS, true)
        call SetPlayerAlliance(p1, p2, ALLIANCE_SHARED_VISION, true)
    endfunction
    
    function GetInventoryIndexOfItemType takes unit u, integer id returns integer
        local integer i
        local item it
        set i = 0
        loop
            set it = UnitItemInSlot(u, i)
            if it != null and GetItemTypeId(it) == id then
                return i
            endif
            exitwhen i == 5
            set i = i + 1
        endloop
        return -1
    endfunction

    function Distance takes real x1, real y1, real x2, real y2 returns real
        local real dx = x1 - x2
        local real dy = y1 - y2
        return SquareRoot(dx * dx + dy * dy)
    endfunction    
endlibrary
Is it ok?
How can I post it to Resources if it's ok?
 
Last edited:
You can always just save the large integer numbers for the orders to constants.
I don't see why an offset is needed if you use constants anyway.

I could just use this: constant integer ORDER_STOP = 851972

I also don't see why we need a string array. It's not like those strings are not intuitive by itself.

The NExt library will probably never get approved because it's too small and belongs into "small code snippets".

All in all, I think it provides no real advantage over the normal JASS natives.

Also, Order.Type only works on those basic unit controls, which is a serious flaw in the concept.
 
Level 7
Joined
Apr 5, 2011
Messages
245
You can always just save the large integer numbers for the orders to constants.
In my map I use a lot of arrays storing orders. So, if Warcraft creates arrays by pow(2), it seems more efficient.
I also don't see why we need a string array. It's not like those strings are not intuitive by itself.
Direct address to array seems faster than creating functions.
Also, Order.Type only works on those basic unit controls, which is a serious flaw in the concept.
You can add orders by yourself, I did not do it because it's easy and I don't know what exact orders user needs. Though I can make documentation.
All in all, I think it provides no real advantage over the normal JASS natives.
For example, unit A gets order X. You just need unit B doing the same. Without my snippet you may write:
JASS:
if (GetIssuedOrderId() == '...') or ... then
   call IssueImmediateOrder(...)
elseif (...)
   call IssueTargetOrder(...)
elseif (...)
   call IssuePointOrder(...)
else
   if blabla then
      call IssueTargetOrder(...)
   else
      call IssuePointOrder(...)
   endif
endif
(last one for "smart" order)
With my snippet is would be like:
JASS:
if Orders.Type[IssuedOrder.id] == ORDER_TYPE_IMMEDIATE then
   call IssueImmediateOrder(...)
elseif Orders.Type[IssuedOrder.id] == ORDER_TYPE_TARGET then
   call IssueTargetOrder(...)
elseif Orders.Type[IssuedOrder.id] == ORDER_TYPE_POINT then
   call IssuePointOrder(...)
else
   if blabla then
      call IssueTargetOrder(...)
   else
      call IssuePointOrder(...)
   endif
endif
Added:
Added IssuedOrder.imitate(unit) method.
 
Last edited:
We already have order ids:
http://www.hiveworkshop.com/forums/jass-resources-412/repo-order-ids-197002/
So you don't need to write those constants because they are useless
Btw,if you are going to submit this kind of resource,please visit Jass Resources Forum and go to Submissions sub-forum:http://www.hiveworkshop.com/forums/submissions-414/

Struct Order shall extend array because you are not using the default alloc,extends array removes the generated code.
Struct globals must be camel-cased (ex. static integer array hello instead of Hello

Its useless to create your own TriggerRegisterAnyUnitEvent,we already have TriggerRegisterAnyUnitEventBJ,also,it would look nice if you take code instead of trigger
 
Level 7
Joined
Apr 5, 2011
Messages
245
Struct Order shall extend array because you are not using the default alloc,extends array removes the generated code.
Struct globals must be camel-cased (ex. static integer array hello instead of Hello

Its useless to create your own TriggerRegisterAnyUnitEvent,we already have TriggerRegisterAnyUnitEventBJ,also,it would look nice if you take code instead of trigger
Thanks, I forgot about that.
Its useless to create your own TriggerRegisterAnyUnitEvent,we already have TriggerRegisterAnyUnitEventBJ,also,it would look nice if you take code instead of trigger
That is red-colored, it hurts, my own - black. Also I limit MAX_PLAYER_INDEX by myself. (Some maps need only 2 players, that 8 lines make 7 times less instances for cycle)

Added:
also,it would look nice if you take code instead of trigger
How can I do it?
 
Status
Not open for further replies.
Top