package LastOrder import RegisterEvents import OnUnitEnterLeave class OrderQueue private Order array[ORDERS_TO_HOLD] orders private int fp = 0 private int rp = 0 private int size = 0 function get(int index) returns Order return orders[fp + index] function enqueue(Order o) if size < ORDERS_TO_HOLD size++ rp = (rp + 1) mod ORDERS_TO_HOLD orders[rp] = o else destroy dequeue() enqueue(o) function dequeue() returns Order if size > 0 size-- fp = (fp + 1) mod ORDERS_TO_HOLD return orders[fp] else return null ondestroy var e = dequeue() while e != null destroy e e = dequeue() /** How many bast orders to hold. Should be at least 2 */ constant int ORDERS_TO_HOLD = 3 public enum OrderType TARGET POINT IMMEDIATE OrderQueue array orderQueues public class Order unit u int id OrderType otype boolean fin widget tar real x real y construct( unit ordered, int ordid, OrderType ordtype, widget target, real ordx, real ordy ) debugPrint("Allocated instance of Order with : " + OrderId2String(ordid), 3) u = ordered id = ordid otype = ordtype fin = false tar = target x = ordx y = ordy //Handle stored orders in the hashtable let index = ordered.getUserData() if orderQueues[index] == null orderQueues[index] = new OrderQueue() orderQueues[index].enqueue(this) function issue() returns boolean if GetUnitTypeId(u) != 0 and not IsUnitType(u, UNIT_TYPE_DEAD) and otype != OrderType.IMMEDIATE and not fin if otype == OrderType.TARGET return IssueTargetOrderById(u, id, tar) else if otype == OrderType.POINT if id == 851971 //This adjusts for a bug in the point order's boolean return //when issuing a smart order IssuePointOrderById(u, id, x, y) return true else return IssuePointOrderById(u, id, x, y) else if otype == OrderType.IMMEDIATE return IssueImmediateOrderById(u, id) return false public function unit.clearLastOrders() let index = this.getUserData() if orderQueues[index] != null destroy orderQueues[index] public function unit.getPastOrders() returns OrderQueue return orderQueues[this.getUserData()] function badOrderList( int id ) returns boolean return ( id==852055 or id==852056 or id==852064 or id==852065 or id==852067 or id==852068 or id==852076 or id==852077 or id==852090 or id==852091 or id==852100 or id==852102 or id==852103 or id==852107 or id==852108 or id==852129 or id==852130 or id==852133 or id==852134 or id==852136 or id==852137 or id==852150 or id==852151 or id==852174 or id==852158 or id==852159 or id==852162 or id==852163 or id==852174 or id==852175 or id==852177 or id==852178 or id==852191 or id==852192 or id==852198 or id==852199 or id==852203 or id==852204 or id==852212 or id==852213 or id==852244 or id==852245 or id==852249 or id==852250 or id==852255 or id==852256 or id==852458 or id==852459 or id==852478 or id==852479 or id==852484 or id==852485 or id==852515 or id==852516 or id==852522 or id==852523 or id==852540 or id==852541 or id==852543 or id==852544 or id==852546 or id==852547 or id==852549 or id==852550 or id==852552 or id==852553 or id==852562 or id==852563 or id==852571 or id==852578 or id==852579 or id==852589 or id==852590 or id==852602 or id==852603 or id==852671 or id==852672 ) function unit.orderFilter( int id ) returns boolean return (id == 851971 or id == 851986 or id == 851983 or id == 851984 or id == 851990 or id == 851993 or (id >= 852055 and id <= 852762)) and not badOrderList(id) public function unit.abortOrder() returns boolean if IsUnitPaused(this) return false else PauseUnit(this, true) IssueImmediateOrder(this, "stop") PauseUnit(this, false) return true function conditions() returns boolean return GetTriggerUnit().orderFilter(GetIssuedOrderId()) function actions() // if conditions() unit u = GetTriggerUnit() widget t = GetOrderTarget() int oid = GetIssuedOrderId() if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER new Order(u, oid, OrderType.TARGET, t, GetWidgetX(t), GetWidgetY(t)) else if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER new Order(u, oid, OrderType.POINT, null, GetOrderPointX(), GetOrderPointY()) else if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER new Order(u, oid, OrderType.IMMEDIATE, null, GetUnitX(u), GetUnitY(u)) else error("invalid Ordertype") function spellActions() let index = GetTriggerUnit().getUserData() if orderQueues[index] != null //Only do this if the last order actually exists orderQueues[index].get(0).fin = true init registerPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function actions) registerPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, function actions) registerPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function actions) registerPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function spellActions) onLeave(() -> begin let index = getEnterLeaveUnit().getUserData() if orderQueues[index] != null destroy orderQueues[index] orderQueues[index] = null end)