# order.h

Go to the documentation of this file.

    00001 /* $Id: order.h 12296 2008-02-27 21:46:57Z glx $ */
    00002
    00005 #ifndef ORDER_H
    00006 #define ORDER_H
    00007
    00008 #include "oldpool.h"
    00009 #include "core/bitmath_func.hpp"
    00010 #include "cargo_type.h"
    00011 #include "vehicle_type.h"
    00012 #include "tile_type.h"
    00013 #include "date_type.h"
    00014
    00015 enum {
    00016   INVALID_VEH_ORDER_ID = 0xFF,
    00017 };
    00018
    00019 static const OrderID INVALID_ORDER = 0xFFFF;
    00020
    00021 /* Order types */
    00022 enum OrderType {
    00023   OT_BEGIN         = 0,
    00024   OT_NOTHING       = 0,
    00025   OT_GOTO_STATION  = 1,
    00026   OT_GOTO_DEPOT    = 2,
    00027   OT_LOADING       = 3,
    00028   OT_LEAVESTATION  = 4,
    00029   OT_DUMMY         = 5,
    00030   OT_GOTO_WAYPOINT = 6,
    00031   OT_END
    00032 };
    00033
    00034 /* It needs to be 8bits, because we save and load it as such */
    00036 template <> struct EnumPropsT<OrderType> : MakeEnumPropsT<OrderType, byte, OT_BEGIN, OT_END, OT_END> {};
    00037 typedef TinyEnumT<OrderType> OrderTypeByte;
    00038
    00039
    00040 /* Order flags -- please use OF instead OF and use HASBIT/SETBIT/CLEARBIT */
    00041
    00043 enum OrderFlagMasks {
    00044   //Flags for stations:
    00046   OFB_TRANSFER           = 0x1,
    00049   OFB_UNLOAD             = 0x2,
    00052   OFB_FULL_LOAD          = 0x4,
    00053
    00054   //Flags for depots:
    00056   OFB_PART_OF_ORDERS     = 0x2,
    00058   OFB_HALT_IN_DEPOT      = 0x4,
    00060   OFB_SERVICE_IF_NEEDED  = 0x4, //used when OFB_PART_OF_ORDERS is set.
    00061
    00062   //Common flags
    00065   OFB_NON_STOP           = 0x8
    00066 };
    00067
    00072 enum {
    00073   OF_TRANSFER          = 0,
    00074   OF_UNLOAD            = 1,
    00075   OF_FULL_LOAD         = 2,
    00076   OF_PART_OF_ORDERS    = 1,
    00077   OF_HALT_IN_DEPOT     = 2,
    00078   OF_SERVICE_IF_NEEDED = 2,
    00079   OF_NON_STOP          = 3
    00080 };
    00081
    00082
    00083 /* Possible clone options */
    00084 enum {
    00085   CO_SHARE   = 0,
    00086   CO_COPY    = 1,
    00087   CO_UNSHARE = 2
    00088 };
    00089
    00090 struct Order;
    00091 DECLARE_OLD_POOL(Order, Order, 6, 1000)
    00092
    00093 /* If you change this, keep in mind that it is saved on 3 places:
    00094  * - Load_ORDR, all the global orders
    00095  * - Vehicle -> current_order
    00096  * - REF_ORDER (all REFs are currently limited to 16 bits!!)
    00097  */
    00098 struct Order : PoolItem<Order, OrderID, &_Order_pool> {
    00099   Order *next;
    00100
    00101   OrderTypeByte type;
    00102   uint8  flags;
    00103   DestinationID dest;
    00104
    00105   CargoID refit_cargo; // Refit CargoID
    00106   byte refit_subtype; // Refit subtype
    00107
    00108   uint16 wait_time;
    00109   uint16 travel_time;
    00110
    00111   Order() : refit_cargo(CT_NO_REFIT) {}
    00112   ~Order() { this->type = OT_NOTHING; }
    00113
    00117   inline bool IsValid() const { return this->type != OT_NOTHING; }
    00118
    00119   void Free();
    00120   void FreeChain();
    00121 };
    00122
    00123 struct BackuppedOrders {
    00124   BackuppedOrders() : order(NULL), name(NULL) { }
    00125   ~BackuppedOrders() { free(order); free(name); }
    00126
    00127   VehicleID clone;
    00128   VehicleOrderID orderindex;
    00129   GroupID group;
    00130   Order *order;
    00131   uint16 service_interval;
    00132   char *name;
    00133 };
    00134
    00135 extern TileIndex _backup_orders_tile;
    00136 extern BackuppedOrders _backup_orders_data;
    00137
    00138 static inline VehicleOrderID GetMaxOrderIndex()
    00139 {
    00140   /* TODO - This isn't the real content of the function, but
    00141    *  with the new pool-system this will be replaced with one that
    00142    *  _really_ returns the highest index. Now it just returns
    00143    *  the next safe value we are sure about everything is below.
    00144    */
    00145   return GetOrderPoolSize() - 1;
    00146 }
    00147
    00148 static inline VehicleOrderID GetNumOrders()
    00149 {
    00150   return GetOrderPoolSize();
    00151 }
    00152
    00153 inline void Order::Free()
    00154 {
    00155   this->type  = OT_NOTHING;
    00156   this->flags = 0;
    00157   this->dest  = 0;
    00158   this->next  = NULL;
    00159 }
    00160
    00161 inline void Order::FreeChain()
    00162 {
    00163   if (next != NULL) next->FreeChain();
    00164   delete this;
    00165 }
    00166
    00167 #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())
    00168 #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
    00169
    00170
    00171 #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
    00172
    00173 static inline bool HasOrderPoolFree(uint amount)
    00174 {
    00175   const Order *order;
    00176
    00177   /* There is always room if not all blocks in the pool are reserved */
    00178   if (_Order_pool.CanAllocateMoreBlocks()) return true;
    00179
    00180   FOR_ALL_ORDERS(order) if (!order->IsValid() && --amount == 0) return true;
    00181
    00182   return false;
    00183 }
    00184
    00185
    00186 /* Pack and unpack routines */
    00187
    00188 static inline uint32 PackOrder(const Order *order)
    00189 {
    00190   return order->dest << 16 | order->flags << 8 | order->type;
    00191 }
    00192
    00193 static inline Order UnpackOrder(uint32 packed)
    00194 {
    00195   Order order;
    00196   order.type    = (OrderType)GB(packed,  0,  8);
    00197   order.flags   = GB(packed,  8,  8);
    00198   order.dest    = GB(packed, 16, 16);
    00199   order.next    = NULL;
    00200   order.index   = 0; // avoid compiler warning
    00201   order.refit_cargo   = CT_NO_REFIT;
    00202   order.refit_subtype = 0;
    00203   order.wait_time     = 0;
    00204   order.travel_time   = 0;
    00205   return order;
    00206 }
    00207
    00208 /* Functions */
    00209 void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order = &_backup_orders_data);
    00210 void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *order = &_backup_orders_data);
    00211 void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
    00212 void InvalidateVehicleOrder(const Vehicle *v);
    00213 bool VehicleHasDepotOrders(const Vehicle *v);
    00214 void CheckOrders(const Vehicle*);
    00215 void DeleteVehicleOrders(Vehicle *v);
    00216 void AssignOrder(Order *order, Order data);
    00217 bool CheckForValidOrders(const Vehicle* v);
    00218
    00219 Order UnpackOldOrder(uint16 packed);
    00220
    00221 #define MIN_SERVINT_PERCENT  5
    00222 #define MAX_SERVINT_PERCENT 90
    00223 #define MIN_SERVINT_DAYS    30
    00224 #define MAX_SERVINT_DAYS   800
    00225
    00233 Date GetServiceIntervalClamped(uint index);
    00234
    00235 #endif /* ORDER_H */