00001
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
00021
00022
00023
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
00252
00253
00254
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