tron@2186: /* $Id$ */ tron@2186: celestar@2214: /** @file order.h celestar@2214: */ 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: truelight@1024: /* Order types */ truelight@1024: enum { 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@1024: OT_GOTO_WAYPOINT = 6 truelight@1024: }; 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 */ celestar@2214: 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 celestar@2214: * for descrption of flags, see OrderFlagMasks celestar@2214: * @see OrderFlagMasks celestar@2214: */ 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: celestar@1053: /* Modes for the order checker */ celestar@1053: enum { celestar@1053: OC_INIT = 0, //the order checker can initialize a news message celestar@1053: OC_VALIDATE = 1, //the order checker validates a news message celestar@1053: }; celestar@1053: truelight@1024: /* If you change this, keep in mind that it is saved on 3 places: truelight@1024: - Load_ORDR, all the global orders truelight@1024: - Vehicle -> current_order truelight@1024: - REF_SHEDULE (all REFs are currently limited to 16 bits!!) */ truelight@1024: typedef struct Order { truelight@1024: uint8 type; truelight@1024: uint8 flags; truelight@1024: uint16 station; truelight@1024: truelight@1024: struct Order *next; //! Pointer to next order. If NULL, end of list truelight@1024: truelight@1024: uint16 index; //! Index of the order, is not saved or anything, just for reference truelight@1024: } Order; truelight@1024: Darkvater@2433: #define MAX_BACKUP_ORDER_COUNT 40 Darkvater@2433: truelight@1024: typedef struct { truelight@1024: VehicleID clone; Darkvater@1786: OrderID 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@1024: static inline Order *GetOrder(uint 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@1314: #define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1 < GetOrderPoolSize()) ? GetOrder(order->index + 1) : NULL) 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: { truelight@1024: return order->station << 16 | order->flags << 8 | order->type; truelight@1024: } truelight@1024: truelight@1024: static inline Order UnpackOrder(uint32 packed) truelight@1024: { truelight@1024: Order order; tron@2140: order.type = GB(packed, 0, 8); tron@2140: order.flags = GB(packed, 8, 8); tron@2140: order.station = GB(packed, 16, 16); truelight@1024: order.next = NULL; hackykid@1884: order.index = 0; // avoid compiler warning 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@1024: void DeleteDestinationFromVehicleOrder(Order dest); truelight@1024: void InvalidateVehicleOrder(const Vehicle *v); truelight@1024: bool VehicleHasDepotOrders(const Vehicle *v); celestar@1053: bool CheckOrders(uint data_a, uint data_b); 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 */