tron@2186: /* $Id$ */ tron@2186: rubidium@10429: /** @file order_base.h Base class for orders. */ celestar@2214: rubidium@9280: #ifndef ORDER_BASE_H rubidium@9280: #define ORDER_BASE_H truelight@1024: rubidium@9267: #include "order_type.h" matthijs@5216: #include "oldpool.h" rubidium@8609: #include "core/bitmath_func.hpp" rubidium@8615: #include "cargo_type.h" rubidium@9332: #include "depot_type.h" rubidium@9328: #include "station_type.h" rubidium@9328: #include "vehicle_type.h" rubidium@9332: #include "waypoint_type.h" truelight@1314: rubidium@7887: DECLARE_OLD_POOL(Order, Order, 6, 1000) rubidium@7887: truelight@1024: /* If you change this, keep in mind that it is saved on 3 places: tron@4077: * - Load_ORDR, all the global orders tron@4077: * - Vehicle -> current_order maedhros@7476: * - REF_ORDER (all REFs are currently limited to 16 bits!!) tron@4077: */ rubidium@7887: struct Order : PoolItem { rubidium@9332: private: rubidium@9332: friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. rubidium@9332: friend void Load_VEHS(); ///< Loading of ancient vehicles. rubidium@9332: friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders. rubidium@9332: rubidium@10117: uint8 type; ///< The type of order + non-stop flags rubidium@10117: uint8 flags; ///< Load/unload types, depot order/action types. rubidium@9336: DestinationID dest; ///< The destination of the order. rubidium@9334: rubidium@9334: CargoID refit_cargo; ///< Refit CargoID rubidium@9334: byte refit_subtype; ///< Refit subtype rubidium@9332: rubidium@9332: public: rubidium@6574: Order *next; ///< Pointer to next order. If NULL, end of list tron@6189: maedhros@7476: uint16 wait_time; ///< How long in ticks to wait at the destination. maedhros@7476: uint16 travel_time; ///< How long in ticks the journey to this destination should take. maedhros@7476: rubidium@7887: Order() : refit_cargo(CT_NO_REFIT) {} rubidium@7887: ~Order() { this->type = OT_NOTHING; } rubidium@7887: rubidium@7992: /** rubidium@9335: * Create an order based on a packed representation of that order. rubidium@9335: * @param packed the packed representation. rubidium@9335: */ rubidium@9335: Order(uint32 packed); rubidium@9335: rubidium@9335: /** rubidium@7992: * Check if a Order really exists. rubidium@9332: * @return true if the order is valid. rubidium@7992: */ rubidium@7992: inline bool IsValid() const { return this->type != OT_NOTHING; } rubidium@7992: rubidium@9330: /** rubidium@9332: * Check whether this order is of the given type. rubidium@9332: * @param type the type to check against. rubidium@9332: * @return true if the order matches. rubidium@9332: */ rubidium@10117: inline bool IsType(OrderType type) const { return this->GetType() == type; } rubidium@9332: rubidium@9332: /** rubidium@9332: * Get the type of order of this order. rubidium@9332: * @return the order type. rubidium@9332: */ rubidium@10136: inline OrderType GetType() const { return (OrderType)GB(this->type, 0, 4); } rubidium@9332: rubidium@9332: /** rubidium@9330: * 'Free' the order rubidium@9330: * @note ONLY use on "current_order" vehicle orders! rubidium@9330: */ bjarni@6589: void Free(); rubidium@9330: rubidium@9330: /** rubidium@9332: * Makes this order a Go To Station order. rubidium@9332: * @param destsination the station to go to. rubidium@9332: */ rubidium@9332: void MakeGoToStation(StationID destination); rubidium@9332: rubidium@9332: /** rubidium@9332: * Makes this order a Go To Depot order. rubidium@9332: * @param destination the depot to go to. rubidium@9332: * @param order is this order a 'default' order, or an overriden vehicle order? rubidium@9334: * @param cargo the cargo type to change to. rubidium@9334: * @param subtype the subtype to change to. rubidium@9332: */ rubidium@10079: void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, CargoID cargo = CT_NO_REFIT, byte subtype = 0); rubidium@9332: rubidium@9332: /** rubidium@9332: * Makes this order a Go To Waypoint order. rubidium@9332: * @param destination the waypoint to go to. rubidium@9332: */ rubidium@9332: void MakeGoToWaypoint(WaypointID destination); rubidium@9332: rubidium@9332: /** rubidium@9332: * Makes this order a Loading order. rubidium@9339: * @param ordered is this an ordered stop? rubidium@9332: */ rubidium@9339: void MakeLoading(bool ordered); rubidium@9332: rubidium@9332: /** rubidium@9332: * Makes this order a Leave Station order. rubidium@9332: */ rubidium@9332: void MakeLeaveStation(); rubidium@9332: rubidium@9332: /** rubidium@9332: * Makes this order a Dummy order. rubidium@9332: */ rubidium@9332: void MakeDummy(); rubidium@9332: rubidium@9332: /** rubidium@10136: * Makes this order an conditional order. rubidium@10136: * @param order the order to jump to. rubidium@10136: */ rubidium@10136: void MakeConditional(VehicleOrderID order); rubidium@10136: rubidium@10136: /** rubidium@9330: * Free a complete order chain. rubidium@9330: * @note do not use on "current_order" vehicle orders! rubidium@9330: */ bjarni@6589: void FreeChain(); rubidium@9328: rubidium@9334: /** rubidium@9336: * Gets the destination of this order. rubidium@9336: * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION). rubidium@9336: * @return the destination of the order. rubidium@9336: */ rubidium@9336: inline DestinationID GetDestination() const { return this->dest; } rubidium@9336: rubidium@9336: /** rubidium@9336: * Sets the destination of this order. rubidium@9336: * @param destination the new destination of the order. rubidium@9336: * @pre IsType(OT_GOTO_WAYPOINT) || IsType(OT_GOTO_DEPOT) || IsType(OT_GOTO_STATION). rubidium@9336: */ rubidium@9336: inline void SetDestination(DestinationID destination) { this->dest = destination; } rubidium@9336: rubidium@9336: /** rubidium@9334: * Is this order a refit order. rubidium@9334: * @pre IsType(OT_GOTO_DEPOT) rubidium@9334: * @return true if a refit should happen. rubidium@9334: */ rubidium@9334: inline bool IsRefit() const { return this->refit_cargo < NUM_CARGO; } rubidium@9334: rubidium@9334: /** rubidium@9334: * Get the cargo to to refit to. rubidium@9334: * @pre IsType(OT_GOTO_DEPOT) rubidium@9334: * @return the cargo type. rubidium@9334: */ rubidium@9334: inline CargoID GetRefitCargo() const { return this->refit_cargo; } rubidium@9334: rubidium@9334: /** rubidium@9334: * Get the cargo subtype to to refit to. rubidium@9334: * @pre IsType(OT_GOTO_DEPOT) rubidium@9334: * @return the cargo subtype. rubidium@9334: */ rubidium@9334: inline byte GetRefitSubtype() const { return this->refit_subtype; } rubidium@9334: rubidium@9334: /** rubidium@9334: * Make this depot order also a refit order. rubidium@9334: * @param cargo the cargo type to change to. rubidium@9334: * @param subtype the subtype to change to. rubidium@9334: * @pre IsType(OT_GOTO_DEPOT). rubidium@9334: */ rubidium@9334: void SetRefit(CargoID cargo, byte subtype = 0); rubidium@9334: rubidium@9339: /** How must the consist be loaded? */ rubidium@10117: inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); } rubidium@9339: /** How must the consist be unloaded? */ rubidium@10117: inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); } rubidium@9339: /** Where must we stop? */ rubidium@10117: inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); } rubidium@9339: /** What caused us going to the depot? */ rubidium@10117: inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); } rubidium@9339: /** What are we going to do when in the depot. */ rubidium@10117: inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); } rubidium@10136: /** What variable do we have to compare? */ rubidium@10136: inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); } rubidium@10136: /** What is the comparator to use? */ rubidium@10136: inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); } rubidium@10136: /** Get the order to skip to. */ rubidium@10136: inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; } rubidium@10136: /** Get the value to base the skip on. */ rubidium@10136: inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); } rubidium@9339: rubidium@9339: /** Set how the consist must be loaded. */ rubidium@10117: inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); } rubidium@9339: /** Set how the consist must be unloaded. */ rubidium@10117: inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); } rubidium@9339: /** Set whether we must stop at stations or not. */ rubidium@10117: inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); } rubidium@9339: /** Set the cause to go to the depot. */ rubidium@10117: inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); } rubidium@9339: /** Set what we are going to do in the depot. */ rubidium@10136: inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); } rubidium@10136: /** Set variable we have to compare. */ rubidium@10136: inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); } rubidium@10136: /** Set the comparator to use. */ rubidium@10136: inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); } rubidium@10136: /** Get the order to skip to. */ rubidium@10136: inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; } rubidium@10136: /** Set the value to base the skip on. */ rubidium@10136: inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); } rubidium@9339: rubidium@9328: bool ShouldStopAtStation(const Vehicle *v, StationID station) const; rubidium@9331: rubidium@9331: /** rubidium@9331: * Assign the given order to this one. rubidium@9331: * @param other the data to copy (except next pointer). rubidium@9331: */ rubidium@9331: void AssignOrder(const Order &other); rubidium@9331: rubidium@9331: /** rubidium@9331: * Does this order have the same type, flags and destination? rubidium@9331: * @param other the second order to compare to. rubidium@9331: * @return true if the type, flags and destination match. rubidium@9331: */ rubidium@9331: bool Equals(const Order &other) const; rubidium@9335: rubidium@9335: /** rubidium@9335: * Pack this order into a 32 bits integer, or actually only rubidium@9335: * the type, flags and destination. rubidium@9335: * @return the packed representation. rubidium@9335: * @note unpacking is done in the constructor. rubidium@9335: */ rubidium@9335: uint32 Pack() const; rubidium@10117: rubidium@10117: /** rubidium@10117: * Converts this order from an old savegame's version; rubidium@10117: * it moves all bits to the new location. rubidium@10117: */ rubidium@10117: void ConvertFromOldSavegame(); rubidium@6574: }; truelight@1024: rubidium@6573: static inline VehicleOrderID GetMaxOrderIndex() truelight@4354: { truelight@4354: /* TODO - This isn't the real content of the function, but truelight@4354: * with the new pool-system this will be replaced with one that matthijs@5247: * _really_ returns the highest index. Now it just returns truelight@4354: * the next safe value we are sure about everything is below. truelight@4354: */ matthijs@5247: return GetOrderPoolSize() - 1; matthijs@5247: } matthijs@5247: rubidium@6573: static inline VehicleOrderID GetNumOrders() matthijs@5247: { truelight@4354: return GetOrderPoolSize(); truelight@4354: } truelight@4354: bjarni@6589: #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()) truelight@1314: #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0) truelight@1314: truelight@1024: truelight@1024: #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next) truelight@1024: rubidium@9330: /* (Un)pack routines */ rubidium@9330: Order UnpackOldOrder(uint16 packed); truelight@1024: truelight@1024: #endif /* ORDER_H */