tron@2186: /* $Id$ */ tron@2186: rubidium@4549: /** @file order.h */ celestar@2214: truelight@1024: #ifndef ORDER_H truelight@1024: #define ORDER_H truelight@1024: tron@2159: #include "macros.h" matthijs@5216: #include "oldpool.h" truelight@1314: bjarni@4408: enum { bjarni@4712: INVALID_VEH_ORDER_ID = 0xFF, bjarni@4408: }; bjarni@4408: celestar@5650: static const OrderID INVALID_ORDER = 0xFFFF; celestar@5650: truelight@1024: /* Order types */ celestar@5650: enum OrderType { celestar@5650: OT_BEGIN = 0, truelight@1024: OT_NOTHING = 0, truelight@1024: OT_GOTO_STATION = 1, truelight@1024: OT_GOTO_DEPOT = 2, truelight@1024: OT_LOADING = 3, truelight@1024: OT_LEAVESTATION = 4, truelight@1024: OT_DUMMY = 5, truelight@4421: OT_GOTO_WAYPOINT = 6, celestar@5650: OT_END truelight@4421: }; celestar@5650: truelight@4421: /* It needs to be 8bits, because we save and load it as such */ celestar@5650: /** Define basic enum properties */ celestar@5650: template <> struct EnumPropsT : MakeEnumPropsT {}; celestar@5650: typedef TinyEnumT OrderTypeByte; celestar@5650: truelight@1024: truelight@1024: /* Order flags -- please use OFB instead OF and use HASBIT/SETBIT/CLEARBIT */ pasky@1615: celestar@2214: /** Order flag masks - these are for direct bit operations */ celestar@2214: enum OrderFlagMasks { celestar@1530: //Flags for stations: celestar@2214: /** vehicle will transfer cargo (i. e. not deliver to nearby industry/town even if accepted there) */ celestar@2214: OF_TRANSFER = 0x1, celestar@2214: /** If OF_TRANSFER is not set, drop any cargo loaded. If accepted, deliver, otherwise cargo remains at the station. celestar@2214: * No new cargo is loaded onto the vehicle whatsoever */ celestar@2214: OF_UNLOAD = 0x2, celestar@2214: /** Wait for full load of all vehicles, or of at least one cargo type, depending on patch setting celestar@2214: * @todo make this two different flags */ celestar@2214: OF_FULL_LOAD = 0x4, celestar@1530: celestar@1530: //Flags for depots: celestar@2214: /** The current depot-order was initiated because it was in the vehicle's order list */ rubidium@4344: OF_PART_OF_ORDERS = 0x2, celestar@2214: /** if OF_PART_OF_ORDERS is not set, this will cause the vehicle to be stopped in the depot */ celestar@2214: OF_HALT_IN_DEPOT = 0x4, celestar@2214: /** if OF_PART_OF_ORDERS is set, this will cause the order only be come active if the vehicle needs servicing */ celestar@2214: OF_SERVICE_IF_NEEDED = 0x4, //used when OF_PART_OF_ORDERS is set. celestar@1530: celestar@1530: //Common flags celestar@2214: /** This causes the vehicle not to stop at intermediate OR the destination station (depending on patch settings) celestar@2214: * @todo make this two different flags */ celestar@2214: OF_NON_STOP = 0x8 truelight@1024: }; truelight@1024: celestar@2214: /** Order flags bits - these are for the *BIT macros tron@4077: * for descrption of flags, see OrderFlagMasks tron@4077: * @see OrderFlagMasks tron@4077: */ truelight@1024: enum { celestar@2214: OFB_TRANSFER = 0, celestar@2214: OFB_UNLOAD = 1, celestar@2214: OFB_FULL_LOAD = 2, celestar@2214: OFB_PART_OF_ORDERS = 1, celestar@2214: OFB_HALT_IN_DEPOT = 2, celestar@2214: OFB_SERVICE_IF_NEEDED = 2, celestar@2214: OFB_NON_STOP = 3 truelight@1024: }; truelight@1024: pasky@1615: truelight@1024: /* Possible clone options */ truelight@1024: enum { truelight@1024: CO_SHARE = 0, truelight@1024: CO_COPY = 1, truelight@1024: CO_UNSHARE = 2 truelight@1024: }; truelight@1024: 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 tron@4077: * - REF_SHEDULE (all REFs are currently limited to 16 bits!!) tron@4077: */ truelight@1024: typedef struct Order { celestar@5650: OrderTypeByte type; truelight@1024: uint8 flags; truelight@4389: DestinationID dest; ///< The destionation of the order. truelight@1024: peter1138@3173: struct Order *next; ///< Pointer to next order. If NULL, end of list truelight@1024: truelight@4392: OrderID index; ///< Index of the order, is not saved or anything, just for reference bjarni@4712: bjarni@4712: CargoID refit_cargo; // Refit CargoID bjarni@4712: byte refit_subtype; // Refit subtype truelight@1024: } Order; truelight@1024: Darkvater@2433: #define MAX_BACKUP_ORDER_COUNT 40 Darkvater@2433: truelight@1024: typedef struct { truelight@1024: VehicleID clone; truelight@4391: VehicleOrderID orderindex; Darkvater@2433: Order order[MAX_BACKUP_ORDER_COUNT + 1]; truelight@1024: uint16 service_interval; truelight@1024: char name[32]; truelight@1024: } BackuppedOrders; truelight@1024: truelight@1024: VARDEF TileIndex _backup_orders_tile; truelight@1024: VARDEF BackuppedOrders _backup_orders_data[1]; truelight@1024: matthijs@5216: DECLARE_OLD_POOL(Order, Order, 6, 1000) truelight@1314: matthijs@5247: static inline VehicleOrderID GetMaxOrderIndex(void) 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: matthijs@5247: static inline VehicleOrderID GetNumOrders(void) matthijs@5247: { truelight@4354: return GetOrderPoolSize(); truelight@4354: } truelight@4354: truelight@4346: /** truelight@4346: * Check if a Order really exists. truelight@4346: */ truelight@4346: static inline bool IsValidOrder(const Order *o) truelight@4346: { truelight@4346: return o->type != OT_NOTHING; truelight@4346: } truelight@4346: truelight@4384: static inline void DeleteOrder(Order *o) truelight@4384: { truelight@4384: o->type = OT_NOTHING; truelight@4384: o->next = NULL; truelight@4384: } truelight@4384: tron@4977: #define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1U < GetOrderPoolSize()) ? GetOrder(order->index + 1U) : NULL) if (IsValidOrder(order)) 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: truelight@1024: static inline bool HasOrderPoolFree(uint amount) truelight@1024: { truelight@1043: const Order *order; truelight@1024: truelight@1314: /* There is always room if not all blocks in the pool are reserved */ tron@4977: if (_Order_pool.current_blocks < _Order_pool.max_blocks) truelight@1314: return true; truelight@1314: truelight@1024: FOR_ALL_ORDERS(order) truelight@1024: if (order->type == OT_NOTHING) truelight@1024: if (--amount == 0) truelight@1024: return true; truelight@1024: truelight@1024: return false; truelight@1024: } truelight@1024: tron@1093: static inline bool IsOrderPoolFull(void) truelight@1024: { truelight@1024: return !HasOrderPoolFree(1); truelight@1024: } truelight@1024: truelight@1024: /* Pack and unpack routines */ truelight@1024: truelight@1024: static inline uint32 PackOrder(const Order *order) truelight@1024: { tron@4527: return order->dest << 16 | order->flags << 8 | order->type; truelight@1024: } truelight@1024: truelight@1024: static inline Order UnpackOrder(uint32 packed) truelight@1024: { truelight@1024: Order order; truelight@4351: order.type = (OrderType)GB(packed, 0, 8); tron@2140: order.flags = GB(packed, 8, 8); tron@4527: order.dest = GB(packed, 16, 16); truelight@1024: order.next = NULL; hackykid@1884: order.index = 0; // avoid compiler warning bjarni@4780: order.refit_cargo = CT_NO_REFIT; bjarni@4715: order.refit_subtype = 0; truelight@1024: return order; truelight@1024: } truelight@1024: truelight@1024: /* Functions */ Darkvater@1796: void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order); tron@2630: void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* order); truelight@4389: void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination); truelight@1024: void InvalidateVehicleOrder(const Vehicle *v); truelight@1024: bool VehicleHasDepotOrders(const Vehicle *v); tron@3140: void CheckOrders(const Vehicle*); truelight@1024: void DeleteVehicleOrders(Vehicle *v); truelight@1024: bool IsOrderListShared(const Vehicle *v); truelight@1024: void AssignOrder(Order *order, Order data); tron@2630: bool CheckForValidOrders(const Vehicle* v); truelight@1024: truelight@1024: Order UnpackOldOrder(uint16 packed); truelight@1024: truelight@1024: #endif /* ORDER_H */