# order_base.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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 /* If you change this, keep in mind that it is saved on 3 places:
    00030  * - Load_ORDR, all the global orders
    00031  * - Vehicle -> current_order
    00032  * - REF_ORDER (all REFs are currently limited to 16 bits!!)
    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 /* ORDER_BASE_H */