# order_base.h

Go to the documentation of this file.

    00001 /* $Id: order_base.h 16638 2009-06-23 20:48:48Z rubidium $ */
    00002
    00005 #ifndef ORDER_BASE_H
    00006 #define ORDER_BASE_H
    00007
    00008 #include "order_type.h"
    00009 #include "oldpool.h"
    00010 #include "core/bitmath_func.hpp"
    00011 #include "cargo_type.h"
    00012 #include "depot_type.h"
    00013 #include "station_type.h"
    00014 #include "vehicle_type.h"
    00015 #include "waypoint_type.h"
    00016
    00017 DECLARE_OLD_POOL(Order, Order, 6, 1000)
    00018 DECLARE_OLD_POOL(OrderList, OrderList, 4, 4000)
    00019
    00020 /* If you change this, keep in mind that it is saved on 3 places:
    00021  * - Load_ORDR, all the global orders
    00022  * - Vehicle -> current_order
    00023  * - REF_ORDER (all REFs are currently limited to 16 bits!!)
    00024  */
    00025 struct Order : PoolItem<Order, OrderID, &_Order_pool> {
    00026 private:
    00027   friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
    00028   friend void Load_VEHS();
    00029   friend const struct SaveLoad *GetOrderDescription();
    00030
    00031   uint8 type;
    00032   uint8 flags;
    00033   DestinationID dest;
    00034
    00035   CargoID refit_cargo;
    00036   byte refit_subtype;
    00037
    00038 public:
    00039   Order *next;
    00040
    00041   uint16 wait_time;
    00042   uint16 travel_time;
    00043
    00044   Order() : refit_cargo(CT_NO_REFIT) {}
    00045   ~Order() { this->type = OT_NOTHING; }
    00046
    00051   Order(uint32 packed);
    00052
    00057   inline bool IsValid() const { return this->type != OT_NOTHING; }
    00058
    00064   inline bool IsType(OrderType type) const { return this->GetType() == type; }
    00065
    00070   inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); }
    00071
    00076   void Free();
    00077
    00082   void MakeGoToStation(StationID destination);
    00083
    00093   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, byte subtype = 0);
    00094
    00099   void MakeGoToWaypoint(WaypointID destination);
    00100
    00105   void MakeLoading(bool ordered);
    00106
    00110   void MakeLeaveStation();
    00111
    00115   void MakeDummy();
    00116
    00121   void MakeConditional(VehicleOrderID order);
    00122
    00128   inline DestinationID GetDestination() const { return this->dest; }
    00129
    00135   inline void SetDestination(DestinationID destination) { this->dest = destination; }
    00136
    00142   inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO; }
    00143
    00149   inline CargoID GetRefitCargo() const { return this->refit_cargo; }
    00150
    00156   inline byte GetRefitSubtype() const { return this->refit_subtype; }
    00157
    00164   void SetRefit(CargoID cargo, byte subtype = 0);
    00165
    00167   inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); }
    00169   inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); }
    00171   inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
    00173   inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); }
    00175   inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); }
    00177   inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); }
    00179   inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
    00181   inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
    00183   inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); }
    00184
    00186   inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); }
    00188   inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); }
    00190   inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
    00192   inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); }
    00194   inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); }
    00196   inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); }
    00198   inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
    00200   inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
    00202   inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); }
    00203
    00204   bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
    00205
    00207   inline bool IsCompletelyTimetabled() const
    00208   {
    00209     if (this->travel_time == 0 && !this->IsType(OT_CONDITIONAL)) return false;
    00210     if (this->wait_time == 0 && this->IsType(OT_GOTO_STATION) && !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) return false;
    00211     return true;
    00212   }
    00213
    00218   void AssignOrder(const Order &other);
    00219
    00225   bool Equals(const Order &other) const;
    00226
    00233   uint32 Pack() const;
    00234
    00240   uint16 MapOldOrder() const;
    00241
    00246   void ConvertFromOldSavegame();
    00247 };
    00248
    00249 static inline VehicleOrderID GetMaxOrderIndex()
    00250 {
    00251   /* TODO - This isn't the real content of the function, but
    00252    *  with the new pool-system this will be replaced with one that
    00253    *  _really_ returns the highest index. Now it just returns
    00254    *  the next safe value we are sure about everything is below.
    00255    */
    00256   return GetOrderPoolSize() - 1;
    00257 }
    00258
    00259 static inline VehicleOrderID GetNumOrders()
    00260 {
    00261   return GetOrderPoolSize();
    00262 }
    00263
    00267 struct OrderList : PoolItem<OrderList, OrderListID, &_OrderList_pool> {
    00268 private:
    00269   friend void AfterLoadVehicles(bool part_of_load);
    00270   friend const struct SaveLoad *GetOrderListDescription();
    00271
    00272   Order *first;
    00273   VehicleOrderID num_orders;
    00274   uint num_vehicles;
    00275   Vehicle *first_shared;
    00276
    00277   uint timetable_duration;
    00278
    00279 public:
    00281   OrderList()
    00282     : first(NULL), num_orders(INVALID_VEH_ORDER_ID), num_vehicles(0), first_shared(NULL),
    00283       timetable_duration(0) { }
    00284
    00289   OrderList(Order *chain, Vehicle *v);
    00290
    00292   ~OrderList() { this->num_orders = INVALID_VEH_ORDER_ID; }
    00293
    00295   inline bool IsValid() const { return this->num_orders != INVALID_VEH_ORDER_ID; }
    00296
    00301   inline Order *GetFirstOrder() const { return this->first; }
    00302
    00308   Order *GetOrderAt(int index) const;
    00309
    00314   inline Order *GetLastOrder() const { return this->GetOrderAt(this->num_orders - 1); }
    00315
    00319   inline VehicleOrderID GetNumOrders() const { return this->num_orders; }
    00320
    00325   void InsertOrderAt(Order *new_order, int index);
    00326
    00331   void DeleteOrderAt(int index);
    00332
    00337   void MoveOrder(int from, int to);
    00338
    00343   inline bool IsShared() const { return this->num_vehicles > 1; };
    00344
    00349   inline Vehicle *GetFirstSharedVehicle() const { return this->first_shared; }
    00350
    00355   inline uint GetNumVehicles() const { return this->num_vehicles; }
    00356
    00361   bool IsVehicleInSharedOrdersList(const Vehicle *v) const;
    00362
    00368   int GetPositionInSharedOrderList(const Vehicle *v) const;
    00369
    00376   inline void AddVehicle(Vehicle *v) { ++this->num_vehicles; }
    00377
    00383   void RemoveVehicle(Vehicle *v);
    00384
    00389   bool IsCompleteTimetable() const;
    00390
    00395   inline int GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? (int)this->timetable_duration : -1; }
    00396
    00401   inline int GetTimetableDurationIncomplete() const { return this->timetable_duration; }
    00402
    00407   void UpdateOrderTimetable(int delta) { this->timetable_duration += delta; }
    00408
    00412   void ResetOrderTimetable() { this->timetable_duration = 0; }
    00413
    00419   void FreeChain(bool keep_orderlist = false);
    00420
    00424   void DebugCheckSanity() const;
    00425 };
    00426
    00427 static inline bool IsValidOrderListID(uint index)
    00428 {
    00429   return index < GetOrderListPoolSize() && GetOrderList(index)->IsValid();
    00430 }
    00431
    00432 #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())
    00433 #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
    00434
    00435
    00436 #define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == NULL) ? NULL : v->orders.list->GetFirstOrder(); order != NULL; order = order->next)
    00437
    00438
    00439 #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())
    00440 #define FOR_ALL_ORDER_LISTS(ol) FOR_ALL_ORDER_LISTS_FROM(ol, 0)
    00441
    00442 #endif /* ORDER_H */