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" truelight@1314: #include "pool.h" truelight@1314: bjarni@4408: enum { bjarni@4712: INVALID_VEH_ORDER_ID = 0xFF, bjarni@4712: INVALID_ORDER = 0xFFFF, bjarni@4408: }; bjarni@4408: truelight@1024: /* Order types */ truelight@4421: enum OrderTypes { 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, truelight@4421: }; truelight@4421: /* It needs to be 8bits, because we save and load it as such */ truelight@4421: typedef uint8 OrderType; 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 { truelight@4351: OrderType 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: truelight@1314: extern MemoryPool _order_pool; truelight@1024: truelight@1314: /** truelight@1314: * Get the pointer to the order with index 'index' truelight@1314: */ truelight@4392: static inline Order *GetOrder(OrderID index) truelight@1024: { truelight@1314: return (Order*)GetItemFromPool(&_order_pool, index); truelight@1024: } truelight@1024: truelight@1314: /** truelight@1314: * Get the current size of the OrderPool truelight@1314: */ truelight@1314: static inline uint16 GetOrderPoolSize(void) truelight@1314: { truelight@1314: return _order_pool.total_items; truelight@1314: } truelight@1314: truelight@4391: static inline VehicleOrderID GetOrderArraySize(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 truelight@4354: * _really_ returns the highest index + 1. Now it just returns truelight@4354: * the next safe value we are sure about everything is below. truelight@4354: */ 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: truelight@4346: #define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1 < GetOrderPoolSize()) ? GetOrder(order->index + 1) : 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 */ truelight@1314: 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@4715: order.refit_cargo = CT_INVALID; 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 */