order.h
author matthijs
Sat, 07 May 2005 22:00:36 +0000
changeset 1777 f703cf05b5b9
parent 1615 24c6310f887b
child 1786 7cfd46c3fcc4
permissions -rw-r--r--
(svn r2281) - Fix: [ 1115204 ] [NPF] When pressing the goto depot button, trains will now also look behind it if there is no depot in front. If so, the train reverses immediately. This also work anywhere, not just at stations.
- Add: [NPF] Reversing inside of depots now has a penalty. It also applies to trains only, other vehicles shouldn't bother reversing.
- Fix: [NPF] When checking whether to reverse a train, the trackdir of the first loc was used instead of the last vehicle as a starting node for pathfindig.
This might have caused some trains not reversing when they should have (or vice versa). Typo introduced when converting to GetVehicleTrackdir() in r2256.
- CodeChange: [NPF] Removed duplicate code by letting NPFRouteTjoStationOrTile() call NPFRouteToStationOrTileTwoWay().
- Add: [NPF] NPFRouteToDepotBreadthFirstTwoWay() to find a depot while also looking backwards.
- Add: It is now possibly to specify a path cost for aystar starting nodes.
#ifndef ORDER_H
#define ORDER_H

#include "pool.h"

/* Order types */
enum {
	OT_NOTHING       = 0,
	OT_GOTO_STATION  = 1,
	OT_GOTO_DEPOT    = 2,
	OT_LOADING       = 3,
	OT_LEAVESTATION  = 4,
	OT_DUMMY         = 5,
	OT_GOTO_WAYPOINT = 6
};

/* Order flags -- please use OFB instead OF and use HASBIT/SETBIT/CLEARBIT */

/* Order flag masks - these are for direct bit operations */
enum {
	//Flags for stations:
	OF_UNLOAD         = 0x2,
	OF_FULL_LOAD      = 0x4, // Also used when to force an aircraft into a depot

	//Flags for depots:
	OF_PART_OF_ORDERS	= 0x2,
	OF_HALT_IN_DEPOT  = 0x4,

	//Common flags
	OF_NON_STOP  = 0x8
};

/* Order flags bits - these are for the *BIT macros */
enum {
	OFB_UNLOAD         = 1,
	OFB_FULL_LOAD      = 2,
	OFB_PART_OF_ORDERS = 1,
	OFB_HALT_IN_DEPOT  = 2,
	OFB_NON_STOP       = 3
};


/* Possible clone options */
enum {
	CO_SHARE   = 0,
	CO_COPY    = 1,
	CO_UNSHARE = 2
};

/* Modes for the order checker */
enum {
	OC_INIT     = 0, //the order checker can initialize a news message
	OC_VALIDATE = 1, //the order checker validates a news message
};

/* If you change this, keep in mind that it is saved on 3 places:
    - Load_ORDR, all the global orders
    - Vehicle -> current_order
    - REF_SHEDULE (all REFs are currently limited to 16 bits!!) */
typedef struct Order {
	uint8  type;
	uint8  flags;
	uint16 station;

	struct Order *next;   //! Pointer to next order. If NULL, end of list

	uint16 index;         //! Index of the order, is not saved or anything, just for reference
} Order;

typedef struct {
	VehicleID clone;
	byte orderindex;
	Order order[41];
	uint16 service_interval;
	char name[32];
} BackuppedOrders;

VARDEF TileIndex _backup_orders_tile;
VARDEF BackuppedOrders _backup_orders_data[1];

extern MemoryPool _order_pool;

/**
 * Get the pointer to the order with index 'index'
 */
static inline Order *GetOrder(uint index)
{
	return (Order*)GetItemFromPool(&_order_pool, index);
}

/**
 * Get the current size of the OrderPool
 */
static inline uint16 GetOrderPoolSize(void)
{
	return _order_pool.total_items;
}

#define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1 < GetOrderPoolSize()) ? GetOrder(order->index + 1) : NULL)
#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)


#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)

static inline bool HasOrderPoolFree(uint amount)
{
	const Order *order;

	/* There is always room if not all blocks in the pool are reserved */
	if (_order_pool.current_blocks < _order_pool.max_blocks)
		return true;

	FOR_ALL_ORDERS(order)
		if (order->type == OT_NOTHING)
			if (--amount == 0)
				return true;

	return false;
}

static inline bool IsOrderPoolFull(void)
{
	return !HasOrderPoolFree(1);
}

/* Pack and unpack routines */

static inline uint32 PackOrder(const Order *order)
{
	return order->station << 16 | order->flags << 8 | order->type;
}

static inline Order UnpackOrder(uint32 packed)
{
	Order order;
	order.type    = (packed & 0x000000FF);
	order.flags   = (packed & 0x0000FF00) >> 8;
	order.station = (packed & 0xFFFF0000) >> 16;
	order.next    = NULL;
	return order;
}

/* Functions */
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *order);
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *order);
void DeleteDestinationFromVehicleOrder(Order dest);
void InvalidateVehicleOrder(const Vehicle *v);
bool VehicleHasDepotOrders(const Vehicle *v);
bool CheckOrders(uint data_a, uint data_b);
void DeleteVehicleOrders(Vehicle *v);
bool IsOrderListShared(const Vehicle *v);
void AssignOrder(Order *order, Order data);
bool CheckForValidOrders(Vehicle *v);

Order UnpackVersion4Order(uint16 packed);
Order UnpackOldOrder(uint16 packed);

#endif /* ORDER_H */