OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

order_base.h
Go to the documentation of this file.
1 /* $Id: order_base.h 26547 2014-05-01 14:49:16Z fonsinchen $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
9
12 #ifndef ORDER_BASE_H
13 #define ORDER_BASE_H
14
15 #include "order_type.h"
16 #include "core/pool_type.hpp"
17 #include "core/bitmath_func.hpp"
18 #include "cargo_type.h"
19 #include "depot_type.h"
20 #include "station_type.h"
21 #include "vehicle_type.h"
22 #include "date_type.h"
23
24 typedef Pool<Order, OrderID, 256, 64000> OrderPool;
25 typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
26 extern OrderPool _order_pool;
27 extern OrderListPool _orderlist_pool;
28
29 /* If you change this, keep in mind that it is saved on 3 places:
30 * - Load_ORDR, all the global orders
31 * - Vehicle -> current_order
32 * - REF_ORDER (all REFs are currently limited to 16 bits!!)
33 */
34 struct Order : OrderPool::PoolItem<&_order_pool> {
35 private:
36 friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
37 friend void Load_VEHS();
38 friend const struct SaveLoad *GetOrderDescription();
39
40 uint8 type;
41 uint8 flags;
42 DestinationID dest;
43
44 CargoID refit_cargo;
45
46 uint16 wait_time;
47 uint16 travel_time;
48 uint16 max_speed;
49
50 public:
51 Order *next;
52
53 Order() : refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {}
54 ~Order();
55
56 Order(uint32 packed);
57
63 inline bool IsType(OrderType type) const { return this->GetType() == type; }
64
69 inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); }
70
71 void Free();
72
73 void MakeGoToStation(StationID destination);
74 void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CT_NO_REFIT);
75 void MakeGoToWaypoint(StationID destination);
76 void MakeLoading(bool ordered);
77 void MakeLeaveStation();
78 void MakeDummy();
79 void MakeConditional(VehicleOrderID order);
80 void MakeImplicit(StationID destination);
81
86 inline bool IsGotoOrder() const
87 {
88 return IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION);
89 }
90
96 inline DestinationID GetDestination() const { return this->dest; }
97
103 inline void SetDestination(DestinationID destination) { this->dest = destination; }
104
110 inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO || this->refit_cargo == CT_AUTO_REFIT; }
111
117 inline bool IsAutoRefit() const { return this->refit_cargo == CT_AUTO_REFIT; }
118
124 inline CargoID GetRefitCargo() const { return this->refit_cargo; }
125
126 void SetRefit(CargoID cargo);
127
129 inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 3); }
131 inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 3); }
133 inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
135 inline OrderStopLocation GetStopLocation() const { return (OrderStopLocation)GB(this->type, 4, 2); }
137 inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 3); }
139 inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 3); }
141 inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); }
143 inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
145 inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
147 inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); }
148
150 inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 3, load_type); }
152 inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 3, unload_type); }
154 inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
156 inline void SetStopLocation(OrderStopLocation stop_location) { SB(this->type, 4, 2, stop_location); }
158 inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 3, depot_order_type); }
160 inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 3, depot_service_type); }
162 inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); }
164 inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
166 inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
168 inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); }
169
170 /* As conditional orders write their "skip to" order all over the flags, we cannot check the
171 * flags to find out if timetabling is enabled. However, as conditional orders are never
172 * autofilled we can be sure that any non-zero values for their wait_time and travel_time are
173 * explicitly set (but travel_time is actually unused for conditionals). */
174
176 inline bool IsWaitTimetabled() const { return this->IsType(OT_CONDITIONAL) ? this->wait_time > 0 : HasBit(this->flags, 3); }
178 inline bool IsTravelTimetabled() const { return this->IsType(OT_CONDITIONAL) ? this->travel_time > 0 : HasBit(this->flags, 7); }
179
181 inline uint16 GetTimetabledWait() const { return this->IsWaitTimetabled() ? this->wait_time : 0; }
183 inline uint16 GetTimetabledTravel() const { return this->IsTravelTimetabled() ? this->travel_time : 0; }
185 inline uint16 GetWaitTime() const { return this->wait_time; }
187 inline uint16 GetTravelTime() const { return this->travel_time; }
188
194 inline uint16 GetMaxSpeed() const { return this->max_speed; }
195
197 inline void SetWaitTimetabled(bool timetabled) { if (!this->IsType(OT_CONDITIONAL)) SB(this->flags, 3, 1, timetabled ? 1 : 0); }
199 inline void SetTravelTimetabled(bool timetabled) { if (!this->IsType(OT_CONDITIONAL)) SB(this->flags, 7, 1, timetabled ? 1 : 0); }
200
205 inline void SetWaitTime(uint16 time) { this->wait_time = time; }
206
211 inline void SetTravelTime(uint16 time) { this->travel_time = time; }
212
218 inline void SetMaxSpeed(uint16 speed) { this->max_speed = speed; }
219
220 bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
221 bool CanLoadOrUnload() const;
222 bool CanLeaveWithCargo(bool has_cargo) const;
223
224 TileIndex GetLocation(const Vehicle *v, bool airport = false) const;
225
227 inline bool IsCompletelyTimetabled() const
228 {
229 if (!this->IsTravelTimetabled() && !this->IsType(OT_CONDITIONAL)) return false;
230 if (!this->IsWaitTimetabled() && this->IsType(OT_GOTO_STATION) &&
231 !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) {
232 return false;
233 }
234 return true;
235 }
236
237 void AssignOrder(const Order &other);
238 bool Equals(const Order &other) const;
239
240 uint32 Pack() const;
241 uint16 MapOldOrder() const;
242 void ConvertFromOldSavegame();
243 };
244
245 void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord);
246 void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord);
247
252 struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
253 private:
254 friend void AfterLoadVehicles(bool part_of_load);
255 friend const struct SaveLoad *GetOrderListDescription();
256
257 StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const;
258
259 Order *first;
260 VehicleOrderID num_orders;
261 VehicleOrderID num_manual_orders;
262 uint num_vehicles;
263 Vehicle *first_shared;
264
265 Ticks timetable_duration;
266 Ticks total_duration;
267
268 public:
270 OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID)
271 : first(NULL), num_orders(num_orders), num_manual_orders(0), num_vehicles(0), first_shared(NULL),
272 timetable_duration(0), total_duration(0) { }
273
279 OrderList(Order *chain, Vehicle *v) { this->Initialize(chain, v); }
280
282 ~OrderList() {}
283
284 void Initialize(Order *chain, Vehicle *v);
285
290 inline Order *GetFirstOrder() const { return this->first; }
291
292 Order *GetOrderAt(int index) const;
293
298 inline Order *GetLastOrder() const { return this->GetOrderAt(this->num_orders - 1); }
299
306 inline const Order *GetNext(const Order *curr) const { return (curr->next == NULL) ? this->GetFirstOrder() : curr->next; }
307
312 inline VehicleOrderID GetNumOrders() const { return this->num_orders; }
313
318 inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; }
319
320 StationIDStack GetNextStoppingStation(const Vehicle *v, const Order *first = NULL, uint hops = 0) const;
321 const Order *GetNextDecisionNode(const Order *next, uint hops) const;
322
323 void InsertOrderAt(Order *new_order, int index);
324 void DeleteOrderAt(int index);
325 void MoveOrder(int from, int to);
326
331 inline bool IsShared() const { return this->num_vehicles > 1; };
332
337 inline Vehicle *GetFirstSharedVehicle() const { return this->first_shared; }
338
343 inline uint GetNumVehicles() const { return this->num_vehicles; }
344
345 bool IsVehicleInSharedOrdersList(const Vehicle *v) const;
346 int GetPositionInSharedOrderList(const Vehicle *v) const;
347
354 inline void AddVehicle(Vehicle *v) { ++this->num_vehicles; }
355
356 void RemoveVehicle(Vehicle *v);
357
358 bool IsCompleteTimetable() const;
359
364 inline Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : INVALID_TICKS; }
365
370 inline Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; }
371
376 inline Ticks GetTotalDuration() const { return this->total_duration; }
377
382 void UpdateTimetableDuration(Ticks delta) { this->timetable_duration += delta; }
383
388 void UpdateTotalDuration(Ticks delta) { this->total_duration += delta; }
389
390 void FreeChain(bool keep_orderlist = false);
391
392 void DebugCheckSanity() const;
393 };
394
395 #define FOR_ALL_ORDERS_FROM(var, start) FOR_ALL_ITEMS_FROM(Order, order_index, var, start)
396 #define FOR_ALL_ORDERS(var) FOR_ALL_ORDERS_FROM(var, 0)
397
398
399 #define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == NULL) ? NULL : v->orders.list->GetFirstOrder(); order != NULL; order = order->next)
400
401
402 #define FOR_ALL_ORDER_LISTS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderList, orderlist_index, var, start)
403 #define FOR_ALL_ORDER_LISTS(var) FOR_ALL_ORDER_LISTS_FROM(var, 0)
404
405 #endif /* ORDER_BASE_H */