~ubuntu-branches/debian/squeeze/openttd/squeeze

« back to all changes in this revision

Viewing changes to src/order_base.h

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach, Matthijs Kooijman, Jordi Mallach
  • Date: 2009-04-15 18:22:10 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090415182210-22ktb8kdbp2tf3bm
[ Matthijs Kooijman ]
* New upstream release.
* Remove Debian specific desktop file, upstream provides one now. 
* Add debian/watch file.

[ Jordi Mallach ]
* Bump Standards-Version to 3.8.1, with no changes required.
* Move to debhelper compat 7. Bump Build-Depends accordingly.
* Use dh_prep.
* Add "set -e" to config script.
* Remove a few extra doc files that get installed by upstream Makefile.
* Add more complete copyright information.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: order_base.h 14828 2009-01-04 15:32:25Z smatz $ */
 
2
 
 
3
/** @file order_base.h Base class for orders. */
 
4
 
 
5
#ifndef ORDER_BASE_H
 
6
#define ORDER_BASE_H
 
7
 
 
8
#include "order_type.h"
 
9
#include "oldpool.h"
 
10
#include "core/bitmath_func.hpp"
 
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"
 
16
 
 
17
DECLARE_OLD_POOL(Order, Order, 6, 1000)
 
18
DECLARE_OLD_POOL(OrderList, OrderList, 4, 4000)
 
19
 
 
20
/* If you change this, keep in mind that it is saved on 3 places:
 
21
 * - Load_ORDR, all the global orders
 
22
 * - Vehicle -> current_order
 
23
 * - REF_ORDER (all REFs are currently limited to 16 bits!!)
 
24
 */
 
25
struct Order : PoolItem<Order, OrderID, &_Order_pool> {
 
26
private:
 
27
        friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
 
28
        friend void Load_VEHS();                                             ///< Loading of ancient vehicles.
 
29
        friend const struct SaveLoad *GetOrderDescription();                 ///< Saving and loading of orders.
 
30
 
 
31
        uint8 type;           ///< The type of order + non-stop flags
 
32
        uint8 flags;          ///< Load/unload types, depot order/action types.
 
33
        DestinationID dest;   ///< The destination of the order.
 
34
 
 
35
        CargoID refit_cargo;  ///< Refit CargoID
 
36
        byte refit_subtype;   ///< Refit subtype
 
37
 
 
38
public:
 
39
        Order *next;          ///< Pointer to next order. If NULL, end of list
 
40
 
 
41
        uint16 wait_time;    ///< How long in ticks to wait at the destination.
 
42
        uint16 travel_time;  ///< How long in ticks the journey to this destination should take.
 
43
 
 
44
        Order() : refit_cargo(CT_NO_REFIT) {}
 
45
        ~Order() { this->type = OT_NOTHING; }
 
46
 
 
47
        /**
 
48
         * Create an order based on a packed representation of that order.
 
49
         * @param packed the packed representation.
 
50
         */
 
51
        Order(uint32 packed);
 
52
 
 
53
        /**
 
54
         * Check if a Order really exists.
 
55
         * @return true if the order is valid.
 
56
         */
 
57
        inline bool IsValid() const { return this->type != OT_NOTHING; }
 
58
 
 
59
        /**
 
60
         * Check whether this order is of the given type.
 
61
         * @param type the type to check against.
 
62
         * @return true if the order matches.
 
63
         */
 
64
        inline bool IsType(OrderType type) const { return this->GetType() == type; }
 
65
 
 
66
        /**
 
67
         * Get the type of order of this order.
 
68
         * @return the order type.
 
69
         */
 
70
        inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); }
 
71
 
 
72
        /**
 
73
         * 'Free' the order
 
74
         * @note ONLY use on "current_order" vehicle orders!
 
75
         */
 
76
        void Free();
 
77
 
 
78
        /**
 
79
         * Makes this order a Go To Station order.
 
80
         * @param destsination the station to go to.
 
81
         */
 
82
        void MakeGoToStation(StationID destination);
 
83
 
 
84
        /**
 
85
         * Makes this order a Go To Depot order.
 
86
         * @param destination the depot to go to.
 
87
         * @param order       is this order a 'default' order, or an overriden vehicle order?
 
88
         * @param action      what to do in the depot?
 
89
         * @param cargo       the cargo type to change to.
 
90
         * @param subtype     the subtype to change to.
 
91
         */
 
92
        void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CT_NO_REFIT, byte subtype = 0);
 
93
 
 
94
        /**
 
95
         * Makes this order a Go To Waypoint order.
 
96
         * @param destination the waypoint to go to.
 
97
         */
 
98
        void MakeGoToWaypoint(WaypointID destination);
 
99
 
 
100
        /**
 
101
         * Makes this order a Loading order.
 
102
         * @param ordered is this an ordered stop?
 
103
         */
 
104
        void MakeLoading(bool ordered);
 
105
 
 
106
        /**
 
107
         * Makes this order a Leave Station order.
 
108
         */
 
109
        void MakeLeaveStation();
 
110
 
 
111
        /**
 
112
         * Makes this order a Dummy order.
 
113
         */
 
114
        void MakeDummy();
 
115
 
 
116
        /**
 
117
         * Makes this order an conditional order.
 
118
         * @param order the order to jump to.
 
119
         */
 
120
        void MakeConditional(VehicleOrderID order);
 
121
 
 
122
        /**
 
123
         * Gets the destination of this order.
 
124
         * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION).
 
125
         * @return the destination of the order.
 
126
         */
 
127
        inline DestinationID GetDestination() const { return this->dest; }
 
128
 
 
129
        /**
 
130
         * Sets the destination of this order.
 
131
         * @param destination the new destination of the order.
 
132
         * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION).
 
133
         */
 
134
        inline void SetDestination(DestinationID destination) { this->dest = destination; }
 
135
 
 
136
        /**
 
137
         * Is this order a refit order.
 
138
         * @pre IsType(OT_GOTO_DEPOT)
 
139
         * @return true if a refit should happen.
 
140
         */
 
141
        inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO; }
 
142
 
 
143
        /**
 
144
         * Get the cargo to to refit to.
 
145
         * @pre IsType(OT_GOTO_DEPOT)
 
146
         * @return the cargo type.
 
147
         */
 
148
        inline CargoID GetRefitCargo() const { return this->refit_cargo; }
 
149
 
 
150
        /**
 
151
         * Get the cargo subtype to to refit to.
 
152
         * @pre IsType(OT_GOTO_DEPOT)
 
153
         * @return the cargo subtype.
 
154
         */
 
155
        inline byte GetRefitSubtype() const { return this->refit_subtype; }
 
156
 
 
157
        /**
 
158
         * Make this depot order also a refit order.
 
159
         * @param cargo   the cargo type to change to.
 
160
         * @param subtype the subtype to change to.
 
161
         * @pre IsType(OT_GOTO_DEPOT).
 
162
         */
 
163
        void SetRefit(CargoID cargo, byte subtype = 0);
 
164
 
 
165
        /** How must the consist be loaded? */
 
166
        inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); }
 
167
        /** How must the consist be unloaded? */
 
168
        inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); }
 
169
        /** Where must we stop? */
 
170
        inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
 
171
        /** What caused us going to the depot? */
 
172
        inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); }
 
173
        /** What are we going to do when in the depot. */
 
174
        inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); }
 
175
        /** What variable do we have to compare? */
 
176
        inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); }
 
177
        /** What is the comparator to use? */
 
178
        inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
 
179
        /** Get the order to skip to. */
 
180
        inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
 
181
        /** Get the value to base the skip on. */
 
182
        inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); }
 
183
 
 
184
        /** Set how the consist must be loaded. */
 
185
        inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); }
 
186
        /** Set how the consist must be unloaded. */
 
187
        inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); }
 
188
        /** Set whether we must stop at stations or not. */
 
189
        inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
 
190
        /** Set the cause to go to the depot. */
 
191
        inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); }
 
192
        /** Set what we are going to do in the depot. */
 
193
        inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); }
 
194
        /** Set variable we have to compare. */
 
195
        inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); }
 
196
        /** Set the comparator to use. */
 
197
        inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
 
198
        /** Get the order to skip to. */
 
199
        inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
 
200
        /** Set the value to base the skip on. */
 
201
        inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); }
 
202
 
 
203
        bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
 
204
 
 
205
        /** Checks if this order has travel_time and if needed wait_time set. */
 
206
        inline bool IsCompletelyTimetabled() const
 
207
        {
 
208
                if (this->travel_time == 0 && !this->IsType(OT_CONDITIONAL)) return false;
 
209
                if (this->wait_time == 0 && this->IsType(OT_GOTO_STATION) && !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) return false;
 
210
                return true;
 
211
        }
 
212
 
 
213
        /**
 
214
         * Assign the given order to this one.
 
215
         * @param other the data to copy (except next pointer).
 
216
         */
 
217
        void AssignOrder(const Order &other);
 
218
 
 
219
        /**
 
220
         * Does this order have the same type, flags and destination?
 
221
         * @param other the second order to compare to.
 
222
         * @return true if the type, flags and destination match.
 
223
         */
 
224
        bool Equals(const Order &other) const;
 
225
 
 
226
        /**
 
227
         * Pack this order into a 32 bits integer, or actually only
 
228
         * the type, flags and destination.
 
229
         * @return the packed representation.
 
230
         * @note unpacking is done in the constructor.
 
231
         */
 
232
        uint32 Pack() const;
 
233
 
 
234
        /**
 
235
         * Converts this order from an old savegame's version;
 
236
         * it moves all bits to the new location.
 
237
         */
 
238
        void ConvertFromOldSavegame();
 
239
};
 
240
 
 
241
static inline VehicleOrderID GetMaxOrderIndex()
 
242
{
 
243
        /* TODO - This isn't the real content of the function, but
 
244
         *  with the new pool-system this will be replaced with one that
 
245
         *  _really_ returns the highest index. Now it just returns
 
246
         *  the next safe value we are sure about everything is below.
 
247
         */
 
248
        return GetOrderPoolSize() - 1;
 
249
}
 
250
 
 
251
static inline VehicleOrderID GetNumOrders()
 
252
{
 
253
        return GetOrderPoolSize();
 
254
}
 
255
 
 
256
/** Shared order list linking together the linked list of orders and the list
 
257
 *  of vehicles sharing this order list.
 
258
 */
 
259
struct OrderList : PoolItem<OrderList, OrderListID, &_OrderList_pool> {
 
260
private:
 
261
        friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain
 
262
        friend const struct SaveLoad *GetOrderListDescription(); ///< Saving and loading of order lists.
 
263
 
 
264
        Order *first;                   ///< First order of the order list
 
265
        VehicleOrderID num_orders;      ///< NOSAVE: How many orders there are in the list
 
266
        uint num_vehicles;              ///< NOSAVE: Number of vehicles that share this order list
 
267
        Vehicle *first_shared;          ///< NOSAVE: pointer to the first vehicle in the shared order chain
 
268
 
 
269
        uint timetable_duration;        ///< NOSAVE: Total duration of the order list
 
270
 
 
271
public:
 
272
        /** Default constructor producing an invalid order list. */
 
273
        OrderList()
 
274
                : first(NULL), num_orders(INVALID_VEH_ORDER_ID), num_vehicles(0), first_shared(NULL),
 
275
                  timetable_duration(0) { }
 
276
 
 
277
        /** Create an order list with the given order chain for the given vehicle.
 
278
         *  @param chain is the pointer to the first order of the order chain
 
279
         *  @param v is any vehicle of the shared order vehicle chain (does not need to be the first)
 
280
         */
 
281
        OrderList(Order *chain, Vehicle *v);
 
282
 
 
283
        /** Destructor. Invalidates OrderList for re-usage by the pool. */
 
284
        ~OrderList() { this->num_orders = INVALID_VEH_ORDER_ID; }
 
285
 
 
286
        /** Checks, if this is a valid order list. */
 
287
        inline bool IsValid() const { return this->num_orders != INVALID_VEH_ORDER_ID; }
 
288
 
 
289
        /**
 
290
         * Get the first order of the order chain.
 
291
         * @return the first order of the chain.
 
292
         */
 
293
        inline Order *GetFirstOrder() const { return this->first; }
 
294
 
 
295
        /**
 
296
         * Get a certain order of the order chain.
 
297
         * @param index zero-based index of the order within the chain.
 
298
         * @return the order at position index.
 
299
         */
 
300
        Order *GetOrderAt(int index) const;
 
301
 
 
302
        /**
 
303
         * Get the last order of the order chain.
 
304
         * @return the last order of the chain.
 
305
         */
 
306
        inline Order *GetLastOrder() const { return this->GetOrderAt(this->num_orders - 1); }
 
307
 
 
308
        /**
 
309
         * Get number of orders in the order list.
 
310
         * @return number of orders in the chain. */
 
311
        inline VehicleOrderID GetNumOrders() const { return this->num_orders; }
 
312
 
 
313
        /**
 
314
         * Insert a new order into the order chain.
 
315
         * @param new_order is the order to insert into the chain.
 
316
         * @param index is the position where the order is supposed to be inserted. */
 
317
        void InsertOrderAt(Order *new_order, int index);
 
318
 
 
319
        /**
 
320
         * Remove an order from the order list and delete it.
 
321
         * @param index is the position of the order which is to be deleted.
 
322
         */
 
323
        void DeleteOrderAt(int index);
 
324
 
 
325
        /**
 
326
         * Move an order to another position within the order list.
 
327
         * @param from is the zero-based position of the order to move.
 
328
         * @param to is the zero-based position where the order is moved to. */
 
329
        void MoveOrder(int from, int to);
 
330
 
 
331
        /**
 
332
         * Is this a shared order list?
 
333
         * @return whether this order list is shared among multiple vehicles
 
334
         */
 
335
        inline bool IsShared() const { return this->num_vehicles > 1; };
 
336
 
 
337
        /**
 
338
         * Get the first vehicle of this vehicle chain.
 
339
         * @return the first vehicle of the chain.
 
340
         */
 
341
        inline Vehicle *GetFirstSharedVehicle() const { return this->first_shared; }
 
342
 
 
343
        /**
 
344
         * Return the number of vehicles that share this orders list
 
345
         * @return the count of vehicles that use this shared orders list
 
346
         */
 
347
        inline uint GetNumVehicles() const { return this->num_vehicles; }
 
348
 
 
349
        /**
 
350
         * Checks whether a vehicle is part of the shared vehicle chain.
 
351
         * @param v is the vehicle to search in the shared vehicle chain.
 
352
         */
 
353
        bool IsVehicleInSharedOrdersList(const Vehicle *v) const;
 
354
 
 
355
        /**
 
356
         * Gets the position of the given vehicle within the shared order vehicle list.
 
357
         * @param v is the vehicle of which to get the position
 
358
         * @return position of v within the shared vehicle chain.
 
359
         */
 
360
        int GetPositionInSharedOrderList(const Vehicle *v) const;
 
361
 
 
362
        /**
 
363
         * Adds the given vehicle to this shared order list.
 
364
         * @note This is supposed to be called after the vehicle has been inserted
 
365
         *       into the shared vehicle chain.
 
366
         * @param v vehicle to add to the list
 
367
         */
 
368
        inline void AddVehicle(Vehicle *v) { ++this->num_vehicles; }
 
369
 
 
370
        /**
 
371
         * Removes the vehicle from the shared order list.
 
372
         * @note This is supposed to be called when the vehicle is still in the chain
 
373
         * @param v vehicle to remove from the list
 
374
         */
 
375
        void RemoveVehicle(Vehicle *v);
 
376
 
 
377
        /**
 
378
         * Checks whether all orders of the list have a filled timetable.
 
379
         * @return whether all orders have a filled timetable.
 
380
         */
 
381
        bool IsCompleteTimetable() const;
 
382
 
 
383
        /**
 
384
         * Gets the total duration of the vehicles timetable or -1 is the timetable is not complete.
 
385
         * @return total timetable duration or -1 for incomplete timetables
 
386
         */
 
387
        inline int GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? (int)this->timetable_duration : -1; }
 
388
 
 
389
        /**
 
390
         * Gets the known duration of the vehicles timetable even if the timetable is not complete.
 
391
         * @return known timetable duration
 
392
         */
 
393
        inline int GetTimetableDurationIncomplete() const { return this->timetable_duration; }
 
394
 
 
395
        /**
 
396
         * Must be called if an order's timetable is changed to update internal book keeping.
 
397
         * @param delta By how many ticks has the timetable duration changed
 
398
         */
 
399
        void UpdateOrderTimetable(int delta) { this->timetable_duration += delta; }
 
400
 
 
401
        /**
 
402
         * Must be called if the whole timetable is cleared to update internal book keeping.
 
403
         */
 
404
        void ResetOrderTimetable() { this->timetable_duration = 0; }
 
405
 
 
406
        /**
 
407
         * Free a complete order chain.
 
408
         * @param keep_orderlist If this is true only delete the orders, otherwise also delete the OrderList.
 
409
         * @note do not use on "current_order" vehicle orders!
 
410
         */
 
411
        void FreeChain(bool keep_orderlist = false);
 
412
 
 
413
        /**
 
414
         * Checks for internal consistency of order list. Triggers assertion if something is wrong.
 
415
         */
 
416
        void DebugCheckSanity() const;
 
417
};
 
418
 
 
419
static inline bool IsValidOrderListID(uint index)
 
420
{
 
421
        return index < GetOrderListPoolSize() && GetOrderList(index)->IsValid();
 
422
}
 
423
 
 
424
#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())
 
425
#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
 
426
 
 
427
 
 
428
#define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == NULL) ? NULL : v->orders.list->GetFirstOrder(); order != NULL; order = order->next)
 
429
 
 
430
 
 
431
#define FOR_ALL_ORDER_LISTS_FROM(ol, start) for (ol = GetOrderList(start); ol != NULL; ol = (ol->index + 1U < GetOrderListPoolSize()) ? GetOrderList(ol->index + 1U) : NULL) if (ol->IsValid())
 
432
#define FOR_ALL_ORDER_LISTS(ol) FOR_ALL_ORDER_LISTS_FROM(ol, 0)
 
433
 
 
434
#endif /* ORDER_H */