00001
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
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
00036 template <> struct EnumPropsT<OrderType> : MakeEnumPropsT<OrderType, byte, OT_BEGIN, OT_END, OT_END> {};
00037 typedef TinyEnumT<OrderType> OrderTypeByte;
00038
00039
00040
00041
00043 enum OrderFlagMasks {
00044
00046 OFB_TRANSFER = 0x1,
00049 OFB_UNLOAD = 0x2,
00052 OFB_FULL_LOAD = 0x4,
00053
00054
00056 OFB_PART_OF_ORDERS = 0x2,
00058 OFB_HALT_IN_DEPOT = 0x4,
00060 OFB_SERVICE_IF_NEEDED = 0x4,
00061
00062
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
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
00094
00095
00096
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;
00106 byte 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
00141
00142
00143
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
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
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;
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
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