7 |
7 |
8 #include "order_type.h" |
8 #include "order_type.h" |
9 #include "oldpool.h" |
9 #include "oldpool.h" |
10 #include "core/bitmath_func.hpp" |
10 #include "core/bitmath_func.hpp" |
11 #include "cargo_type.h" |
11 #include "cargo_type.h" |
|
12 #include "depot_type.h" |
|
13 #include "station_type.h" |
|
14 #include "vehicle_type.h" |
|
15 #include "waypoint_type.h" |
12 |
16 |
13 DECLARE_OLD_POOL(Order, Order, 6, 1000) |
17 DECLARE_OLD_POOL(Order, Order, 6, 1000) |
14 |
18 |
15 /* If you change this, keep in mind that it is saved on 3 places: |
19 /* If you change this, keep in mind that it is saved on 3 places: |
16 * - Load_ORDR, all the global orders |
20 * - Load_ORDR, all the global orders |
17 * - Vehicle -> current_order |
21 * - Vehicle -> current_order |
18 * - REF_ORDER (all REFs are currently limited to 16 bits!!) |
22 * - REF_ORDER (all REFs are currently limited to 16 bits!!) |
19 */ |
23 */ |
20 struct Order : PoolItem<Order, OrderID, &_Order_pool> { |
24 struct Order : PoolItem<Order, OrderID, &_Order_pool> { |
|
25 private: |
|
26 friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. |
|
27 friend void Load_VEHS(); ///< Loading of ancient vehicles. |
|
28 friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders. |
|
29 |
|
30 OrderTypeByte type; ///< The type of order |
|
31 uint8 flags; ///< 'Sub'type of order |
|
32 DestinationID dest; ///< The destination of the order. |
|
33 |
|
34 CargoID refit_cargo; ///< Refit CargoID |
|
35 byte refit_subtype; ///< Refit subtype |
|
36 |
|
37 public: |
21 Order *next; ///< Pointer to next order. If NULL, end of list |
38 Order *next; ///< Pointer to next order. If NULL, end of list |
22 |
|
23 OrderTypeByte type; |
|
24 uint8 flags; |
|
25 DestinationID dest; ///< The destionation of the order. |
|
26 |
|
27 CargoID refit_cargo; // Refit CargoID |
|
28 byte refit_subtype; // Refit subtype |
|
29 |
39 |
30 uint16 wait_time; ///< How long in ticks to wait at the destination. |
40 uint16 wait_time; ///< How long in ticks to wait at the destination. |
31 uint16 travel_time; ///< How long in ticks the journey to this destination should take. |
41 uint16 travel_time; ///< How long in ticks the journey to this destination should take. |
32 |
42 |
33 Order() : refit_cargo(CT_NO_REFIT) {} |
43 Order() : refit_cargo(CT_NO_REFIT) {} |
34 ~Order() { this->type = OT_NOTHING; } |
44 ~Order() { this->type = OT_NOTHING; } |
35 |
45 |
36 /** |
46 /** |
|
47 * Create an order based on a packed representation of that order. |
|
48 * @param packed the packed representation. |
|
49 */ |
|
50 Order(uint32 packed); |
|
51 |
|
52 /** |
37 * Check if a Order really exists. |
53 * Check if a Order really exists. |
|
54 * @return true if the order is valid. |
38 */ |
55 */ |
39 inline bool IsValid() const { return this->type != OT_NOTHING; } |
56 inline bool IsValid() const { return this->type != OT_NOTHING; } |
40 |
57 |
|
58 /** |
|
59 * Check whether this order is of the given type. |
|
60 * @param type the type to check against. |
|
61 * @return true if the order matches. |
|
62 */ |
|
63 inline bool IsType(OrderType type) const { return this->type == type; } |
|
64 |
|
65 /** |
|
66 * Get the type of order of this order. |
|
67 * @return the order type. |
|
68 */ |
|
69 inline OrderType GetType() const { return this->type; } |
|
70 |
|
71 /** |
|
72 * 'Free' the order |
|
73 * @note ONLY use on "current_order" vehicle orders! |
|
74 */ |
41 void Free(); |
75 void Free(); |
|
76 |
|
77 /** |
|
78 * Makes this order a Go To Station order. |
|
79 * @param destsination the station to go to. |
|
80 */ |
|
81 void MakeGoToStation(StationID destination); |
|
82 |
|
83 /** |
|
84 * Makes this order a Go To Depot order. |
|
85 * @param destination the depot to go to. |
|
86 * @param order is this order a 'default' order, or an overriden vehicle order? |
|
87 * @param cargo the cargo type to change to. |
|
88 * @param subtype the subtype to change to. |
|
89 */ |
|
90 void MakeGoToDepot(DepotID destination, bool order, CargoID cargo = CT_NO_REFIT, byte subtype = 0); |
|
91 |
|
92 /** |
|
93 * Makes this order a Go To Waypoint order. |
|
94 * @param destination the waypoint to go to. |
|
95 */ |
|
96 void MakeGoToWaypoint(WaypointID destination); |
|
97 |
|
98 /** |
|
99 * Makes this order a Loading order. |
|
100 * @param ordered is this an ordered stop? |
|
101 */ |
|
102 void MakeLoading(bool ordered); |
|
103 |
|
104 /** |
|
105 * Makes this order a Leave Station order. |
|
106 */ |
|
107 void MakeLeaveStation(); |
|
108 |
|
109 /** |
|
110 * Makes this order a Dummy order. |
|
111 */ |
|
112 void MakeDummy(); |
|
113 |
|
114 /** |
|
115 * Free a complete order chain. |
|
116 * @note do not use on "current_order" vehicle orders! |
|
117 */ |
42 void FreeChain(); |
118 void FreeChain(); |
|
119 |
|
120 /** |
|
121 * Gets the destination of this order. |
|
122 * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION). |
|
123 * @return the destination of the order. |
|
124 */ |
|
125 inline DestinationID GetDestination() const { return this->dest; } |
|
126 |
|
127 /** |
|
128 * Sets the destination of this order. |
|
129 * @param destination the new destination of the order. |
|
130 * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION). |
|
131 */ |
|
132 inline void SetDestination(DestinationID destination) { this->dest = destination; } |
|
133 |
|
134 /** |
|
135 * Is this order a refit order. |
|
136 * @pre IsType(OT_GOTO_DEPOT) |
|
137 * @return true if a refit should happen. |
|
138 */ |
|
139 inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO; } |
|
140 |
|
141 /** |
|
142 * Get the cargo to to refit to. |
|
143 * @pre IsType(OT_GOTO_DEPOT) |
|
144 * @return the cargo type. |
|
145 */ |
|
146 inline CargoID GetRefitCargo() const { return this->refit_cargo; } |
|
147 |
|
148 /** |
|
149 * Get the cargo subtype to to refit to. |
|
150 * @pre IsType(OT_GOTO_DEPOT) |
|
151 * @return the cargo subtype. |
|
152 */ |
|
153 inline byte GetRefitSubtype() const { return this->refit_subtype; } |
|
154 |
|
155 /** |
|
156 * Make this depot order also a refit order. |
|
157 * @param cargo the cargo type to change to. |
|
158 * @param subtype the subtype to change to. |
|
159 * @pre IsType(OT_GOTO_DEPOT). |
|
160 */ |
|
161 void SetRefit(CargoID cargo, byte subtype = 0); |
|
162 |
|
163 /** How must the consist be loaded? */ |
|
164 inline byte GetLoadType() const { return this->flags & OFB_FULL_LOAD; } |
|
165 /** How must the consist be unloaded? */ |
|
166 inline byte GetUnloadType() const { return GB(this->flags, 0, 2); } |
|
167 /** Where must we stop? */ |
|
168 inline byte GetNonStopType() const { return this->flags & OFB_NON_STOP; } |
|
169 /** What caused us going to the depot? */ |
|
170 inline byte GetDepotOrderType() const { return this->flags; } |
|
171 /** What are we going to do when in the depot. */ |
|
172 inline byte GetDepotActionType() const { return this->flags; } |
|
173 |
|
174 /** Set how the consist must be loaded. */ |
|
175 inline void SetLoadType(byte load_type) { SB(this->flags, 2, 1, !!load_type); } |
|
176 /** Set how the consist must be unloaded. */ |
|
177 inline void SetUnloadType(byte unload_type) { SB(this->flags, 0, 2, unload_type); } |
|
178 /** Set whether we must stop at stations or not. */ |
|
179 inline void SetNonStopType(byte non_stop_type) { SB(this->flags, 3, 1, !!non_stop_type); } |
|
180 /** Set the cause to go to the depot. */ |
|
181 inline void SetDepotOrderType(byte depot_order_type) { this->flags = depot_order_type; } |
|
182 /** Set what we are going to do in the depot. */ |
|
183 inline void SetDepotActionType(byte depot_service_type) { this->flags = depot_service_type; } |
|
184 |
|
185 bool ShouldStopAtStation(const Vehicle *v, StationID station) const; |
|
186 |
|
187 /** |
|
188 * Assign the given order to this one. |
|
189 * @param other the data to copy (except next pointer). |
|
190 */ |
|
191 void AssignOrder(const Order &other); |
|
192 |
|
193 /** |
|
194 * Does this order have the same type, flags and destination? |
|
195 * @param other the second order to compare to. |
|
196 * @return true if the type, flags and destination match. |
|
197 */ |
|
198 bool Equals(const Order &other) const; |
|
199 |
|
200 /** |
|
201 * Pack this order into a 32 bits integer, or actually only |
|
202 * the type, flags and destination. |
|
203 * @return the packed representation. |
|
204 * @note unpacking is done in the constructor. |
|
205 */ |
|
206 uint32 Pack() const; |
43 }; |
207 }; |
44 |
208 |
45 static inline VehicleOrderID GetMaxOrderIndex() |
209 static inline VehicleOrderID GetMaxOrderIndex() |
46 { |
210 { |
47 /* TODO - This isn't the real content of the function, but |
211 /* TODO - This isn't the real content of the function, but |
55 static inline VehicleOrderID GetNumOrders() |
219 static inline VehicleOrderID GetNumOrders() |
56 { |
220 { |
57 return GetOrderPoolSize(); |
221 return GetOrderPoolSize(); |
58 } |
222 } |
59 |
223 |
60 inline void Order::Free() |
|
61 { |
|
62 this->type = OT_NOTHING; |
|
63 this->flags = 0; |
|
64 this->dest = 0; |
|
65 this->next = NULL; |
|
66 } |
|
67 |
|
68 inline void Order::FreeChain() |
|
69 { |
|
70 if (next != NULL) next->FreeChain(); |
|
71 delete this; |
|
72 } |
|
73 |
|
74 #define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) if (order->IsValid()) |
224 #define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) if (order->IsValid()) |
75 #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0) |
225 #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0) |
76 |
226 |
77 |
227 |
78 #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next) |
228 #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next) |
79 |
229 |
80 static inline bool HasOrderPoolFree(uint amount) |
230 /* (Un)pack routines */ |
81 { |
|
82 const Order *order; |
|
83 |
|
84 /* There is always room if not all blocks in the pool are reserved */ |
|
85 if (_Order_pool.CanAllocateMoreBlocks()) return true; |
|
86 |
|
87 FOR_ALL_ORDERS(order) if (!order->IsValid() && --amount == 0) return true; |
|
88 |
|
89 return false; |
|
90 } |
|
91 |
|
92 |
|
93 /* Pack and unpack routines */ |
|
94 |
|
95 static inline uint32 PackOrder(const Order *order) |
|
96 { |
|
97 return order->dest << 16 | order->flags << 8 | order->type; |
|
98 } |
|
99 |
|
100 static inline Order UnpackOrder(uint32 packed) |
|
101 { |
|
102 Order order; |
|
103 order.type = (OrderType)GB(packed, 0, 8); |
|
104 order.flags = GB(packed, 8, 8); |
|
105 order.dest = GB(packed, 16, 16); |
|
106 order.next = NULL; |
|
107 order.index = 0; // avoid compiler warning |
|
108 order.refit_cargo = CT_NO_REFIT; |
|
109 order.refit_subtype = 0; |
|
110 order.wait_time = 0; |
|
111 order.travel_time = 0; |
|
112 return order; |
|
113 } |
|
114 |
|
115 void AssignOrder(Order *order, Order data); |
|
116 Order UnpackOldOrder(uint16 packed); |
231 Order UnpackOldOrder(uint16 packed); |
117 |
232 |
118 #endif /* ORDER_H */ |
233 #endif /* ORDER_H */ |