- Joined
- Jan 28, 2012
- Messages
- 266
OrderQueueLite, is a simple system that replicates the functionality of shift orders, with the advantage that it is uninteruptable, and you can issue them by triggers.
Why Lite? I am making another version that will use a linked list, enable you to change the order, and have a memory of previous Orders(the size of the memory will be user definable.)
Why Lite? I am making another version that will use a linked list, enable you to change the order, and have a memory of previous Orders(the size of the memory will be user definable.)
JASS:
library OrderQueueLite /* v 1.0.0.5
**************************************************************
* ___ _____ *
* | \ | ____| *
* | / \\ / / | |__ _ _ __ _ _ _ *
* | \ \\/ / | __| | \| | | \ / \ | |/ / *
* |___/ / / | |___ | \ \ | | | | |__/ | / *
* / / |_____| |_|\ \| |___/ \__\ |_| *
* *
**************************************************************
* */ uses /*
* */ CTL /* hiveworkshop.com/forums/jass-resources-412/snippet-constant-timer-loop-32-a-201381/
* */ Table /* hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/?highlight=Table
* */ UnitIndexer /* hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/
* * Order Id Repo * hiveworkshop.com/forums/jass-resources-412/repo-order-ids-197002/
**************************************************************
*
* Credits- Almia for giving some useful suggestions.
*
**************************************************************
*
* what is OrderQueueLite?
* - it is a system that copies shift order functionallity
* - Unlike OrderQueue(not released yet) it can not
* insert new orders in the units order chain.
*
***************************************************************
*
* struct OrderQueue extends array
*
* readonly integer last
* readonly integer current
*
* static method create takes unit u returns thistype
* - a unit will only ever have one unit queue
* - order queues are destroyed automatically
* so call create whenever you want to
* add new orders to an OrderQueue
*
* static method isValidOrder takes integer i returns boolean
* - tells you whether i is valid Order for a Queue.
*
* method getOrderId takes integer i returns integer
* - gives you the orderId of a specific order
*
* method getOrderType takes integer i returns integer
* - tells you what Type of order is in that slot
*
* method destroy takes nothing returns nothing
* -destroys the OrderQueue
*
* method pop takes nothing returns nothing
* removes the Current Order the Unit is doing
* and orders them to do the next
*
*
*
* method issuePointOrder takes integer order, real x, real y returns nothing
* method issueTargetOrder takes integer order, widget target returns nothing
* method issueImmediateOrder takes integer order returns nothing
* method issueItemPointOrder takes item toUse, real x, real y returns nothing
* method issueItemTargetOrder takes item toUse, widget target returns nothing
* method issueItemOrder takes item toUse returns nothing
*
***************************************************************/
private module OrderQueueInit
static method onInit takes nothing returns nothing
set tg = TimerGroup32.create(function thistype.periodic)
call TriggerRegisterAnyUnitEventBJ(stopOrder, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerRegisterAnyUnitEventBJ(stopOrder, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(stopOrder, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(stopOrder, Condition(function thistype.stopOrders))
endmethod
endmodule
struct OrderQueue extends array
private static constant integer Point = 0
private static constant integer Target = 1
private static constant integer Immediate = 2
private static constant integer ItemPoint = 3
private static constant integer ItemTarget = 4
private static constant integer Item = 5
private static constant integer totalC = 4
private static TimerGroup32 tg
static trigger stopOrder = CreateTrigger()
private Table list
private integer count
private integer recycle
readonly integer current
readonly integer last
boolean active
boolean paused
thistype nex
thistype pre
method operator canOrder takes nothing returns boolean
return (not paused) and (GetUnitCurrentOrder(GetUnitById(this))==0)
endmethod
private method getRecycle takes integer i returns integer
return list[i+2]
endmethod
private method setRecycle takes integer i, integer toWhat returns nothing
set list[i+2]=toWhat
endmethod
private method next takes integer i returns integer
return list[i]
endmethod
private method setNext takes integer i, integer a returns nothing
set list[i]=a
endmethod
static method isValidOrder takes integer i returns boolean
return (R2I(I2R(i)/I2R(totalC)) == i/totalC)
endmethod
method getOrderId takes integer i returns integer
debug if not isValidOrder(i) then
debug call BJDebugMsg(I2S(i) + " Is an invalid order")
debug return 1/0
debug endif
return list[i+1]
endmethod
method getOrderType takes integer i returns integer
debug if not isValidOrder(i) then
debug call BJDebugMsg(I2S(i) + " Is an invalid order")
debug return 1/0
debug endif
return list[i+3]
endmethod
method pause takes nothing returns nothing
local integer i = 0
set paused = true
if current != 0 then
call setNext(0,current)
set current = 0
endif
endmethod
method unpause takes nothing returns nothing
set paused = false
endmethod
static method create takes unit u returns thistype
local thistype this = GetUnitUserData(u)
if active then
return this
endif
if .nex == 0 then
call tg.start()
endif
set paused = false
call UnitIndex(this).lock()
set list = Table.create()
set active = true
set .nex = 0
set .pre = thistype(0).pre
set thistype(0).pre = this
set .pre.nex = this
return this
endmethod
method destroy takes nothing returns nothing
if not active then
return
endif
if thistype(0).nex == this and thistype(0).pre == this then
call tg.stop()
endif
set active = false
call UnitIndex(this).unlock()
call list.destroy()
set .current = 0
set .last = 0
set .pre.nex = .nex
set .nex.pre = .pre
endmethod
method pop takes nothing returns nothing
local integer i = current
local integer n = next(i)
local integer b = totalC-1
local integer s = list[n+3]
set current = n
if i != 0 then
call setRecycle(i,recycle)
set recycle = i
call list.handle.remove(i)
call list.handle.remove(i+1)
endif
if s > Immediate then
if s < Item then
if s == ItemPoint then
call UnitUseItemPoint(GetUnitById(this),list.item[n+1],list.real[n],list.real[n+1])
return
endif
call UnitUseItemTarget(GetUnitById(this),list.item[n+1],list.widget[n])
return
endif
call UnitUseItem(GetUnitById(this),list.item[n+1])
return
else
if s < Immediate then
if s == Point then
call IssuePointOrderById(GetUnitById(this),list[n+1],list.real[n],list.real[n+1])
return
endif
call IssueTargetOrderById(GetUnitById(this),list[n+1],list.widget[n])
return
endif
call IssueImmediateOrderById(GetUnitById(this),list[n+1])
endif
endmethod
private method push takes nothing returns integer
local integer i = recycle
if i == 0 then
set i = count+totalC
set count = i
else
set recycle = getRecycle(i)
endif
call setNext(last,i)
set last = i
return i
endmethod
static method periodic takes nothing returns boolean
local thistype this = thistype(0).nex
call DisableTrigger(stopOrder)
loop
exitwhen this ==0
if .canOrder then
if current == last then
call destroy()
else
call pop()
endif
endif
set this = .nex
endloop
call EnableTrigger(stopOrder)
return false
endmethod
method issuePointOrderById takes integer order, real x, real y returns nothing
local integer i = push()
set list.real[i] = x
set list.real[i + 1]= y
set list[i + 1] = order
set list[i + 3] = Point
endmethod
method issueImmediateOrderById takes integer order returns nothing
local integer i = push()
set list[i + 1] = order
set list[i + 3] = Immediate
endmethod
method issueTargetOrderById takes integer order, widget target returns nothing
local integer i= push()
set list.widget[i] = target
set list[i + 1] = order
set list[i + 3] = Target
endmethod
method issueItemPointOrder takes item toUse, real x, real y returns nothing
local integer i = push()
set list.real[i] = x
set list.real[i + 1] = y
set list.item[i + 1] = toUse
set list[i + 3] = ItemPoint
endmethod
method issueItemOrder takes item toUse returns nothing
local integer i = push()
set list.item[i + 1] = toUse
set list[i + 3] = Item
endmethod
method issueItemTargetOrder takes item toUse, widget target returns nothing
local integer i= push()
set list.widget[i]= target
set list.item[i + 1] = toUse
set list[i + 3] = ItemTarget
endmethod
private static method stopOrders takes nothing returns boolean
local thistype this =GetUnitUserData(GetTriggerUnit())
local integer n = .current
local integer s
if n != 0 then
call DisableTrigger(stopOrder)
set s = list[n+3]
if s > Immediate then
if s < Item then
if s == ItemPoint then
call UnitUseItemPoint(GetUnitById(this),list.item[n+1],list.real[n],list.real[n+1])
else
call UnitUseItemTarget(GetUnitById(this),list.item[n+1],list.widget[n])
endif
else
call UnitUseItem(GetUnitById(this),list.item[n+1])
endif
else
if s < Immediate then
if s == Point then
call IssuePointOrderById(GetUnitById(this),list[n+1],list.real[n],list.real[n+1])
else
call IssueTargetOrderById(GetUnitById(this),list[n+1],list.widget[n])
endif
else
call IssueImmediateOrderById(GetUnitById(this),list[n+1])
endif
endif
call EnableTrigger(stopOrder)
endif
return false
endmethod
private method deindex takes nothing returns nothing
call this.destroy()
endmethod
implement UnitIndexStruct
implement OrderQueueInit
endstruct
endlibrary
Uploaded
Fixed spacing
-fixed a bug involving the binary tree
-added pause and unpause
-added pause and unpause
Fixedd a minor bug with issueTargetOrder
Made Sys RegisterAnyUnitEvent
added a link to an awsome Repository by Nestherus
added a link to an awsome Repository by Nestherus
Removed some changes from previous version
JASS:
scope TestOrderQueue initializer init
globals
private integer count = 21
private OrderQueue pauseThis
endglobals
private function wait takes nothing returns nothing
call pauseThis.unpause()
call DestroyTimer(GetExpiredTimer())
endfunction
private function createLots takes nothing returns nothing
local unit u = CreateUnit(Player(0),'hfoo',0,0,0)
local OrderQueue this = OrderQueue.create(u)
local integer i = 10
loop
call this.issuePointOrderById(851986 , 700, -700)
call this.issuePointOrderById(851986 , 700, 700)
call this.issuePointOrderById(851986 , -700, 700)
call this.issuePointOrderById(851986 , -700, -700)
call this.issuePointOrderById(851986 , 700, -700)
set i =i-1
exitwhen i == 0
endloop
set u = null
set count = count-1
if count == 0 then
set pauseThis = this
call this.pause()
call TimerStart(CreateTimer(),1,false,function wait)
call DestroyTimer(GetExpiredTimer())
endif
endfunction
private function init takes nothing returns nothing
call createLots()
call TimerStart(CreateTimer(),1,true,function createLots)
endfunction
endscope
Last edited: