2005-07-24 14:12:37 +00:00
|
|
|
/* $Id$ */
|
|
|
|
|
2005-07-28 06:09:15 +00:00
|
|
|
/** @file order.h
|
|
|
|
*/
|
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
#ifndef ORDER_H
|
|
|
|
#define ORDER_H
|
|
|
|
|
2005-07-21 22:15:02 +00:00
|
|
|
#include "macros.h"
|
2005-02-06 10:24:57 +00:00
|
|
|
#include "pool.h"
|
|
|
|
|
2006-08-26 22:28:40 +00:00
|
|
|
enum {
|
|
|
|
INVALID_ORDER = 0xFFFF,
|
|
|
|
};
|
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
/* Order types */
|
2006-08-22 17:13:49 +00:00
|
|
|
typedef enum OrderTypes {
|
2005-01-15 19:06:22 +00:00
|
|
|
OT_NOTHING = 0,
|
|
|
|
OT_GOTO_STATION = 1,
|
|
|
|
OT_GOTO_DEPOT = 2,
|
|
|
|
OT_LOADING = 3,
|
|
|
|
OT_LEAVESTATION = 4,
|
|
|
|
OT_DUMMY = 5,
|
|
|
|
OT_GOTO_WAYPOINT = 6
|
2006-08-22 17:13:49 +00:00
|
|
|
} OrderType;
|
2005-01-15 19:06:22 +00:00
|
|
|
|
|
|
|
/* Order flags -- please use OFB instead OF and use HASBIT/SETBIT/CLEARBIT */
|
2005-04-02 01:08:01 +00:00
|
|
|
|
2005-07-28 06:09:15 +00:00
|
|
|
/** Order flag masks - these are for direct bit operations */
|
|
|
|
enum OrderFlagMasks {
|
2005-03-20 08:43:29 +00:00
|
|
|
//Flags for stations:
|
2005-07-28 06:09:15 +00:00
|
|
|
/** vehicle will transfer cargo (i. e. not deliver to nearby industry/town even if accepted there) */
|
|
|
|
OF_TRANSFER = 0x1,
|
|
|
|
/** If OF_TRANSFER is not set, drop any cargo loaded. If accepted, deliver, otherwise cargo remains at the station.
|
|
|
|
* No new cargo is loaded onto the vehicle whatsoever */
|
|
|
|
OF_UNLOAD = 0x2,
|
|
|
|
/** Wait for full load of all vehicles, or of at least one cargo type, depending on patch setting
|
|
|
|
* @todo make this two different flags */
|
|
|
|
OF_FULL_LOAD = 0x4,
|
2005-03-20 08:43:29 +00:00
|
|
|
|
|
|
|
//Flags for depots:
|
2005-07-28 06:09:15 +00:00
|
|
|
/** The current depot-order was initiated because it was in the vehicle's order list */
|
2006-08-22 14:38:37 +00:00
|
|
|
OF_PART_OF_ORDERS = 0x2,
|
2005-07-28 06:09:15 +00:00
|
|
|
/** if OF_PART_OF_ORDERS is not set, this will cause the vehicle to be stopped in the depot */
|
|
|
|
OF_HALT_IN_DEPOT = 0x4,
|
|
|
|
/** if OF_PART_OF_ORDERS is set, this will cause the order only be come active if the vehicle needs servicing */
|
|
|
|
OF_SERVICE_IF_NEEDED = 0x4, //used when OF_PART_OF_ORDERS is set.
|
2005-03-20 08:43:29 +00:00
|
|
|
|
|
|
|
//Common flags
|
2005-07-28 06:09:15 +00:00
|
|
|
/** This causes the vehicle not to stop at intermediate OR the destination station (depending on patch settings)
|
|
|
|
* @todo make this two different flags */
|
|
|
|
OF_NON_STOP = 0x8
|
2005-01-15 19:06:22 +00:00
|
|
|
};
|
|
|
|
|
2005-07-28 06:09:15 +00:00
|
|
|
/** Order flags bits - these are for the *BIT macros
|
2006-06-27 21:25:53 +00:00
|
|
|
* for descrption of flags, see OrderFlagMasks
|
|
|
|
* @see OrderFlagMasks
|
|
|
|
*/
|
2005-01-15 19:06:22 +00:00
|
|
|
enum {
|
2005-07-28 06:09:15 +00:00
|
|
|
OFB_TRANSFER = 0,
|
|
|
|
OFB_UNLOAD = 1,
|
|
|
|
OFB_FULL_LOAD = 2,
|
|
|
|
OFB_PART_OF_ORDERS = 1,
|
|
|
|
OFB_HALT_IN_DEPOT = 2,
|
|
|
|
OFB_SERVICE_IF_NEEDED = 2,
|
|
|
|
OFB_NON_STOP = 3
|
2005-01-15 19:06:22 +00:00
|
|
|
};
|
|
|
|
|
2005-04-02 01:08:01 +00:00
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
/* Possible clone options */
|
|
|
|
enum {
|
|
|
|
CO_SHARE = 0,
|
|
|
|
CO_COPY = 1,
|
|
|
|
CO_UNSHARE = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
/* If you change this, keep in mind that it is saved on 3 places:
|
2006-06-27 21:25:53 +00:00
|
|
|
* - Load_ORDR, all the global orders
|
|
|
|
* - Vehicle -> current_order
|
|
|
|
* - REF_SHEDULE (all REFs are currently limited to 16 bits!!)
|
|
|
|
*/
|
2005-01-15 19:06:22 +00:00
|
|
|
typedef struct Order {
|
2006-08-22 17:13:49 +00:00
|
|
|
OrderType type;
|
2005-01-15 19:06:22 +00:00
|
|
|
uint8 flags;
|
2006-08-26 16:34:03 +00:00
|
|
|
DestinationID dest; ///< The destionation of the order.
|
2005-01-15 19:06:22 +00:00
|
|
|
|
2006-03-09 20:37:51 +00:00
|
|
|
struct Order *next; ///< Pointer to next order. If NULL, end of list
|
2005-01-15 19:06:22 +00:00
|
|
|
|
2006-08-26 17:16:51 +00:00
|
|
|
OrderID index; ///< Index of the order, is not saved or anything, just for reference
|
2005-01-15 19:06:22 +00:00
|
|
|
} Order;
|
|
|
|
|
2005-09-16 16:03:18 +00:00
|
|
|
#define MAX_BACKUP_ORDER_COUNT 40
|
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
typedef struct {
|
|
|
|
VehicleID clone;
|
2006-08-26 17:12:24 +00:00
|
|
|
VehicleOrderID orderindex;
|
2005-09-16 16:03:18 +00:00
|
|
|
Order order[MAX_BACKUP_ORDER_COUNT + 1];
|
2005-01-15 19:06:22 +00:00
|
|
|
uint16 service_interval;
|
|
|
|
char name[32];
|
|
|
|
} BackuppedOrders;
|
|
|
|
|
|
|
|
VARDEF TileIndex _backup_orders_tile;
|
|
|
|
VARDEF BackuppedOrders _backup_orders_data[1];
|
|
|
|
|
2005-02-06 10:24:57 +00:00
|
|
|
extern MemoryPool _order_pool;
|
2005-01-15 19:06:22 +00:00
|
|
|
|
2005-02-06 10:24:57 +00:00
|
|
|
/**
|
|
|
|
* Get the pointer to the order with index 'index'
|
|
|
|
*/
|
2006-08-26 17:16:51 +00:00
|
|
|
static inline Order *GetOrder(OrderID index)
|
2005-01-15 19:06:22 +00:00
|
|
|
{
|
2005-02-06 10:24:57 +00:00
|
|
|
return (Order*)GetItemFromPool(&_order_pool, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the current size of the OrderPool
|
|
|
|
*/
|
|
|
|
static inline uint16 GetOrderPoolSize(void)
|
|
|
|
{
|
|
|
|
return _order_pool.total_items;
|
2005-01-15 19:06:22 +00:00
|
|
|
}
|
|
|
|
|
2006-08-26 17:12:24 +00:00
|
|
|
static inline VehicleOrderID GetOrderArraySize(void)
|
2006-08-22 20:41:26 +00:00
|
|
|
{
|
|
|
|
/* 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 + 1. Now it just returns
|
|
|
|
* the next safe value we are sure about everything is below.
|
|
|
|
*/
|
|
|
|
return GetOrderPoolSize();
|
|
|
|
}
|
|
|
|
|
2006-08-22 15:33:35 +00:00
|
|
|
/**
|
|
|
|
* Check if a Order really exists.
|
|
|
|
*/
|
|
|
|
static inline bool IsValidOrder(const Order *o)
|
|
|
|
{
|
|
|
|
return o->type != OT_NOTHING;
|
|
|
|
}
|
|
|
|
|
2006-08-26 14:22:54 +00:00
|
|
|
static inline void DeleteOrder(Order *o)
|
|
|
|
{
|
|
|
|
o->type = OT_NOTHING;
|
|
|
|
o->next = NULL;
|
|
|
|
}
|
|
|
|
|
2006-08-22 15:33:35 +00:00
|
|
|
#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))
|
2005-02-06 10:24:57 +00:00
|
|
|
#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
|
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
|
|
|
|
#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
|
|
|
|
|
|
|
|
static inline bool HasOrderPoolFree(uint amount)
|
|
|
|
{
|
2005-01-16 14:42:53 +00:00
|
|
|
const Order *order;
|
2005-01-15 19:06:22 +00:00
|
|
|
|
2005-02-06 10:24:57 +00:00
|
|
|
/* There is always room if not all blocks in the pool are reserved */
|
|
|
|
if (_order_pool.current_blocks < _order_pool.max_blocks)
|
|
|
|
return true;
|
|
|
|
|
2005-01-15 19:06:22 +00:00
|
|
|
FOR_ALL_ORDERS(order)
|
|
|
|
if (order->type == OT_NOTHING)
|
|
|
|
if (--amount == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-01-22 20:23:18 +00:00
|
|
|
static inline bool IsOrderPoolFull(void)
|
2005-01-15 19:06:22 +00:00
|
|
|
{
|
|
|
|
return !HasOrderPoolFree(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Pack and unpack routines */
|
|
|
|
|
|
|
|
static inline uint32 PackOrder(const Order *order)
|
|
|
|
{
|
2006-08-26 16:34:03 +00:00
|
|
|
return order->dest.station << 16 | order->flags << 8 | order->type;
|
2005-01-15 19:06:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline Order UnpackOrder(uint32 packed)
|
|
|
|
{
|
|
|
|
Order order;
|
2006-08-22 17:13:49 +00:00
|
|
|
order.type = (OrderType)GB(packed, 0, 8);
|
2005-07-20 15:29:28 +00:00
|
|
|
order.flags = GB(packed, 8, 8);
|
2006-08-26 16:34:03 +00:00
|
|
|
order.dest.station = GB(packed, 16, 16);
|
2005-01-15 19:06:22 +00:00
|
|
|
order.next = NULL;
|
2005-06-01 11:52:44 +00:00
|
|
|
order.index = 0; // avoid compiler warning
|
2005-01-15 19:06:22 +00:00
|
|
|
return order;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Functions */
|
2005-05-12 23:46:01 +00:00
|
|
|
void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order);
|
2005-11-13 13:43:55 +00:00
|
|
|
void RestoreVehicleOrders(const Vehicle* v, const BackuppedOrders* order);
|
2006-08-26 16:34:03 +00:00
|
|
|
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
|
2005-01-15 19:06:22 +00:00
|
|
|
void InvalidateVehicleOrder(const Vehicle *v);
|
|
|
|
bool VehicleHasDepotOrders(const Vehicle *v);
|
2006-03-04 11:15:44 +00:00
|
|
|
void CheckOrders(const Vehicle*);
|
2005-01-15 19:06:22 +00:00
|
|
|
void DeleteVehicleOrders(Vehicle *v);
|
|
|
|
bool IsOrderListShared(const Vehicle *v);
|
|
|
|
void AssignOrder(Order *order, Order data);
|
2005-11-13 13:43:55 +00:00
|
|
|
bool CheckForValidOrders(const Vehicle* v);
|
2005-01-15 19:06:22 +00:00
|
|
|
|
|
|
|
Order UnpackOldOrder(uint16 packed);
|
|
|
|
|
|
|
|
#endif /* ORDER_H */
|