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