rubidium@9837: /* $Id$ */ rubidium@9837: rubidium@9837: /** @file order_base.h */ rubidium@9837: rubidium@9837: #ifndef ORDER_BASE_H rubidium@9837: #define ORDER_BASE_H rubidium@9837: rubidium@9837: #include "order_type.h" rubidium@9837: #include "oldpool.h" rubidium@9837: #include "core/bitmath_func.hpp" rubidium@9837: #include "cargo_type.h" rubidium@9837: rubidium@9837: DECLARE_OLD_POOL(Order, Order, 6, 1000) rubidium@9837: rubidium@9837: /* If you change this, keep in mind that it is saved on 3 places: rubidium@9837: * - Load_ORDR, all the global orders rubidium@9837: * - Vehicle -> current_order rubidium@9837: * - REF_ORDER (all REFs are currently limited to 16 bits!!) rubidium@9837: */ rubidium@9837: struct Order : PoolItem { rubidium@9837: Order *next; ///< Pointer to next order. If NULL, end of list rubidium@9837: rubidium@9837: OrderTypeByte type; rubidium@9837: uint8 flags; rubidium@9837: DestinationID dest; ///< The destionation of the order. rubidium@9837: rubidium@9837: CargoID refit_cargo; // Refit CargoID rubidium@9837: byte refit_subtype; // Refit subtype rubidium@9837: rubidium@9837: uint16 wait_time; ///< How long in ticks to wait at the destination. rubidium@9837: uint16 travel_time; ///< How long in ticks the journey to this destination should take. rubidium@9837: rubidium@9837: Order() : refit_cargo(CT_NO_REFIT) {} rubidium@9837: ~Order() { this->type = OT_NOTHING; } rubidium@9837: rubidium@9837: /** rubidium@9837: * Check if a Order really exists. rubidium@9837: */ rubidium@9837: inline bool IsValid() const { return this->type != OT_NOTHING; } rubidium@9837: rubidium@9837: void Free(); rubidium@9837: void FreeChain(); rubidium@9837: }; rubidium@9837: rubidium@9837: static inline VehicleOrderID GetMaxOrderIndex() rubidium@9837: { rubidium@9837: /* TODO - This isn't the real content of the function, but rubidium@9837: * with the new pool-system this will be replaced with one that rubidium@9837: * _really_ returns the highest index. Now it just returns rubidium@9837: * the next safe value we are sure about everything is below. rubidium@9837: */ rubidium@9837: return GetOrderPoolSize() - 1; rubidium@9837: } rubidium@9837: rubidium@9837: static inline VehicleOrderID GetNumOrders() rubidium@9837: { rubidium@9837: return GetOrderPoolSize(); rubidium@9837: } rubidium@9837: rubidium@9837: inline void Order::Free() rubidium@9837: { rubidium@9837: this->type = OT_NOTHING; rubidium@9837: this->flags = 0; rubidium@9837: this->dest = 0; rubidium@9837: this->next = NULL; rubidium@9837: } rubidium@9837: rubidium@9837: inline void Order::FreeChain() rubidium@9837: { rubidium@9837: if (next != NULL) next->FreeChain(); rubidium@9837: delete this; rubidium@9837: } rubidium@9837: rubidium@9837: #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()) rubidium@9837: #define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0) rubidium@9837: rubidium@9837: rubidium@9837: #define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next) rubidium@9837: rubidium@9837: static inline bool HasOrderPoolFree(uint amount) rubidium@9837: { rubidium@9837: const Order *order; rubidium@9837: rubidium@9837: /* There is always room if not all blocks in the pool are reserved */ rubidium@9837: if (_Order_pool.CanAllocateMoreBlocks()) return true; rubidium@9837: rubidium@9837: FOR_ALL_ORDERS(order) if (!order->IsValid() && --amount == 0) return true; rubidium@9837: rubidium@9837: return false; rubidium@9837: } rubidium@9837: rubidium@9837: rubidium@9837: /* Pack and unpack routines */ rubidium@9837: rubidium@9837: static inline uint32 PackOrder(const Order *order) rubidium@9837: { rubidium@9837: return order->dest << 16 | order->flags << 8 | order->type; rubidium@9837: } rubidium@9837: rubidium@9837: static inline Order UnpackOrder(uint32 packed) rubidium@9837: { rubidium@9837: Order order; rubidium@9837: order.type = (OrderType)GB(packed, 0, 8); rubidium@9837: order.flags = GB(packed, 8, 8); rubidium@9837: order.dest = GB(packed, 16, 16); rubidium@9837: order.next = NULL; rubidium@9837: order.index = 0; // avoid compiler warning rubidium@9837: order.refit_cargo = CT_NO_REFIT; rubidium@9837: order.refit_subtype = 0; rubidium@9837: order.wait_time = 0; rubidium@9837: order.travel_time = 0; rubidium@9837: return order; rubidium@9837: } rubidium@9837: rubidium@9837: void AssignOrder(Order *order, Order data); rubidium@9837: Order UnpackOldOrder(uint16 packed); rubidium@9837: rubidium@9837: #endif /* ORDER_H */