00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef ORDER_BASE_H
00013 #define ORDER_BASE_H
00014
00015 #include "order_type.h"
00016 #include "core/pool_type.hpp"
00017 #include "core/bitmath_func.hpp"
00018 #include "cargo_type.h"
00019 #include "depot_type.h"
00020 #include "station_type.h"
00021 #include "vehicle_type.h"
00022 #include "date_type.h"
00023
00024 typedef Pool<Order, OrderID, 256, 64000> OrderPool;
00025 typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
00026 extern OrderPool _order_pool;
00027 extern OrderListPool _orderlist_pool;
00028
00029
00030
00031
00032
00033
00034 struct Order : OrderPool::PoolItem<&_order_pool> {
00035 private:
00036 friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
00037 friend void Load_VEHS();
00038 friend const struct SaveLoad *GetOrderDescription();
00039
00040 uint8 type;
00041 uint8 flags;
00042 DestinationID dest;
00043
00044 CargoID refit_cargo;
00045 byte refit_subtype;
00046
00047 public:
00048 Order *next;
00049
00050 uint16 wait_time;
00051 uint16 travel_time;
00052 uint16 max_speed;
00053
00054 Order() : refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {}
00055 ~Order();
00056
00057 Order(uint32 packed);
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
00072 void Free();
00073
00074 void MakeGoToStation(StationID destination);
00075 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);
00076 void MakeGoToWaypoint(StationID destination);
00077 void MakeLoading(bool ordered);
00078 void MakeLeaveStation();
00079 void MakeDummy();
00080 void MakeConditional(VehicleOrderID order);
00081 void MakeImplicit(StationID destination);
00082
00087 inline bool IsGotoOrder() const
00088 {
00089 return IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION);
00090 }
00091
00097 inline DestinationID GetDestination() const { return this->dest; }
00098
00104 inline void SetDestination(DestinationID destination) { this->dest = destination; }
00105
00111 inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO || this->refit_cargo == CT_AUTO_REFIT; }
00112
00118 inline bool IsAutoRefit() const { return this->refit_cargo == CT_AUTO_REFIT; }
00119
00125 inline CargoID GetRefitCargo() const { return this->refit_cargo; }
00126
00132 inline byte GetRefitSubtype() const { return this->refit_subtype; }
00133
00134 void SetRefit(CargoID cargo, byte subtype = 0);
00135
00137 inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); }
00139 inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); }
00141 inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
00143 inline OrderStopLocation GetStopLocation() const { return (OrderStopLocation)GB(this->type, 4, 2); }
00145 inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); }
00147 inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); }
00149 inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); }
00151 inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
00153 inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
00155 inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); }
00156
00158 inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); }
00160 inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); }
00162 inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
00164 inline void SetStopLocation(OrderStopLocation stop_location) { SB(this->type, 4, 2, stop_location); }
00166 inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); }
00168 inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); }
00170 inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); }
00172 inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
00174 inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
00176 inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); }
00177
00178 bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
00179 bool CanLoadOrUnload() const;
00180 bool CanLeaveWithCargo(bool has_cargo) const;
00181
00182 TileIndex GetLocation(const Vehicle *v, bool airport = false) const;
00183
00185 inline bool IsCompletelyTimetabled() const
00186 {
00187 if (this->travel_time == 0 && !this->IsType(OT_CONDITIONAL)) return false;
00188 if (this->wait_time == 0 && this->IsType(OT_GOTO_STATION) && !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) return false;
00189 return true;
00190 }
00191
00192 void AssignOrder(const Order &other);
00193 bool Equals(const Order &other) const;
00194
00195 uint32 Pack() const;
00196 uint16 MapOldOrder() const;
00197 void ConvertFromOldSavegame();
00198 };
00199
00200 void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord);
00201 void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord);
00202
00207 struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
00208 private:
00209 friend void AfterLoadVehicles(bool part_of_load);
00210 friend const struct SaveLoad *GetOrderListDescription();
00211
00212 const Order *GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const;
00213
00214 Order *first;
00215 VehicleOrderID num_orders;
00216 VehicleOrderID num_manual_orders;
00217 uint num_vehicles;
00218 Vehicle *first_shared;
00219
00220 Ticks timetable_duration;
00221
00222 public:
00224 OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID)
00225 : first(NULL), num_orders(num_orders), num_manual_orders(0), num_vehicles(0), first_shared(NULL),
00226 timetable_duration(0) { }
00227
00233 OrderList(Order *chain, Vehicle *v) { this->Initialize(chain, v); }
00234
00236 ~OrderList() {}
00237
00238 void Initialize(Order *chain, Vehicle *v);
00239
00244 inline Order *GetFirstOrder() const { return this->first; }
00245
00246 Order *GetOrderAt(int index) const;
00247
00252 inline Order *GetLastOrder() const { return this->GetOrderAt(this->num_orders - 1); }
00253
00260 inline const Order *GetNext(const Order *curr) const { return (curr->next == NULL) ? this->GetFirstOrder() : curr->next; }
00261
00266 inline VehicleOrderID GetNumOrders() const { return this->num_orders; }
00267
00272 inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; }
00273
00274 StationID GetNextStoppingStation(const Vehicle *v) const;
00275 const Order *GetNextStoppingOrder(const Vehicle *v, const Order *next, uint hops, bool is_loading = false) const;
00276
00277 void InsertOrderAt(Order *new_order, int index);
00278 void DeleteOrderAt(int index);
00279 void MoveOrder(int from, int to);
00280
00285 inline bool IsShared() const { return this->num_vehicles > 1; };
00286
00291 inline Vehicle *GetFirstSharedVehicle() const { return this->first_shared; }
00292
00297 inline uint GetNumVehicles() const { return this->num_vehicles; }
00298
00299 bool IsVehicleInSharedOrdersList(const Vehicle *v) const;
00300 int GetPositionInSharedOrderList(const Vehicle *v) const;
00301
00308 inline void AddVehicle(Vehicle *v) { ++this->num_vehicles; }
00309
00310 void RemoveVehicle(Vehicle *v);
00311
00312 bool IsCompleteTimetable() const;
00313
00318 inline Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : INVALID_TICKS; }
00319
00324 inline Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; }
00325
00330 void UpdateOrderTimetable(Ticks delta) { this->timetable_duration += delta; }
00331
00332 void FreeChain(bool keep_orderlist = false);
00333
00334 void DebugCheckSanity() const;
00335 };
00336
00337 #define FOR_ALL_ORDERS_FROM(var, start) FOR_ALL_ITEMS_FROM(Order, order_index, var, start)
00338 #define FOR_ALL_ORDERS(var) FOR_ALL_ORDERS_FROM(var, 0)
00339
00340
00341 #define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == NULL) ? NULL : v->orders.list->GetFirstOrder(); order != NULL; order = order->next)
00342
00343
00344 #define FOR_ALL_ORDER_LISTS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderList, orderlist_index, var, start)
00345 #define FOR_ALL_ORDER_LISTS(var) FOR_ALL_ORDER_LISTS_FROM(var, 0)
00346
00347 #endif