src/newgrf_fsmports.h
author richk
Fri, 03 Aug 2007 18:10:15 +0000
branchNewGRF_ports
changeset 6743 cabfaa4a0295
parent 6737 2b971fcc9a08
child 6745 f45a41940079
permissions -rw-r--r--
(svn r10766) [NewGRF_ports] -Sync: with trunk r10651-10765
/* $Id$ */

/** @file newgrf_fsmports.h Header file for NewGRF Finite FSMPORTSe Machine Ports (airports, seaports, landports??) */

#ifndef NEWGRF_FSMPORTS_H
#define NEWGRF_FSMPORTS_H

#include "engine.h"
#include "newgrf_cargo.h"
#include "helpers.hpp"
#include "sprite.h"

enum FSMportsClassID {
	FSMPORTS_CLASS_BEGIN = 0,    ///< the lowest valid value
	FSMPORTS_CLASS_DFLT = 0,     ///< Default FSMports class.
	FSMPORTS_CLASS_WAYP,         ///< Waypoint class.
	FSMPORTS_CLASS_MAX = 32,     ///< Maximum number of classes.
};

static AirportMovingData fsmport_moving_data_dummy[1] = {
	{    0,    0, 5,     {DIR_N} }
};

static byte fsmport_entries_dummy[] = {0, 0, 0, 0};

struct AirportFTAbuildup {
	byte position; // the position that an airplane is at
	byte heading;  // the current orders (eg. TAKEOFF, HANGAR, ENDLANDING, etc.)
	uint64 block;  // the block this position is on on the airport (st->airport_flags)
	byte next;     // next position from this position
};

static AirportFTAbuildup fsmport_fta_dummy[] = {
	{0, 0, 0, 0},
	{ MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
};

/** Define basic enum properties */
template <> struct EnumPropsT<FSMportsClassID> : MakeEnumPropsT<FSMportsClassID, byte, FSMPORTS_CLASS_BEGIN, FSMPORTS_CLASS_MAX, FSMPORTS_CLASS_MAX> {};
typedef TinyEnumT<FSMportsClassID> FSMportsClassIDByte;

/** Allow incrementing of FSMportsClassID variables */
DECLARE_POSTFIX_INCREMENT(FSMportsClassID);

/* FSMports layout for given dimensions - it is a two-dimensional array
 * where index is computed as (x * platforms) + platform. */
typedef byte *FSMportsLayout;

struct FSMportsSpec {
	const struct GRFFile *grffile; ///< ID of GRF file FSMports belongs to.
	int localidx; ///< Index within GRF file of FSMports.

	bool allocated; ///< Flag whether this FSMport has been added to a FSMports class list

	FSMportsClassID sclass; ///< The class to which this spec belongs.
	StringID name; ///< Name of this FSMport.

	/** Number of tile layouts.
	 * A minimum of 8 is required is required for FSMportss.
	 * 0-1 = plain platform
	 * 2-3 = platform with building
	 * 4-5 = platform with roof, left side
	 * 6-7 = platform with roof, right side
	 */
	uint tiles;
	DrawTileSprites *renderdata; ///< Array of tile layouts.
	bool copied_renderdata;

	/** Cargo threshold for choosing between little and lots of cargo
	 * @note little/lots are equivalent to the moving/loading FSMPORTSes for vehicles
	 */
	uint16 cargo_threshold;

	uint32 cargo_triggers; ///< Bitmask of cargo types which cause trigger re-randomizing

	byte callbackmask; ///< Bitmask of callbacks to use, @see newgrf_callbacks.h

	byte flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by FSMports size

	byte lengths;
	byte width;

	FSMportsLayout **layouts;
	bool copied_layouts;

	AirportFTAClass *portFSM;

	/**
	 * NUM_CARGO real cargo plus three pseudo cargo sprite groups.
	 * Used for obtaining the sprite offset of custom sprites, and for
	 * evaluating callbacks.
	 */
	const struct SpriteGroup *spritegroup[NUM_CARGO + 3];
};

/**
 * Struct containing information relating to FSMports classes.
 */
struct FSMportsClass {
	uint32 id;          ///< ID of this class, e.g. 'DFLT', 'WAYP', etc.
	StringID name;      ///< Name of this class.
	uint FSMports;      ///< Number of FSMports in this class.
	FSMportsSpec **spec; ///< Array of FSMports specifications.
};

void ResetFSMportsClasses();
FSMportsClassID AllocateFSMportsClass(uint32 cls);
void SetFSMportsClassName(FSMportsClassID sclass, StringID name);
StringID GetFSMportsClassName(FSMportsClassID sclass);
StringID *BuildFSMportsClassDropdown();

uint GetNumFSMportsClasses();
uint GetNumCustomFSMports(FSMportsClassID sclass);

void SetCustomFSMportsSpec(FSMportsSpec *FSMPORTSspec);
const FSMportsSpec *GetCustomFSMportsSpec(FSMportsClassID sclass, uint FSMports);
const FSMportsSpec *GetCustomFSMportsSpecByGrf(uint32 grfid, byte localidx);

//* Evaluate a tile's position within a FSMports, and return the result a bitstuffed format. */
//uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, int y, bool centred);

/* Get sprite offset for a given custom FSMports and FSMports structure (may be
 * NULL - that means we are in a build dialog). The FSMports structure is used
 * for variational sprite groups. */
SpriteID GetCustomFSMportsRelocation(const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile);
SpriteID GetCustomFSMportsGroundRelocation(const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile);
uint16 GetFSMportsCallback(CallbackID callback, uint32 param1, uint32 param2, const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile);

/* Allocate a FSMportsSpec to a Station. This is called once per build operation. */
int AllocateFSMportsSpecToStation(const FSMportsSpec *FSMPORTSspec, Station *st, bool exec);

/* Deallocate a FSMportsSpec from a FSMports. Called when removing a single FSMports tile. */
void DeallocateSpecFromFSMports(Station* st, byte specindex);

/* Set the spec index, and mark tile as an fsmport */
static inline void SetCustomFSMportsSpecIndex(TileIndex t, byte specindex)
{
	assert(IsTileType(t, MP_STATION));
	_m[t].m4 = specindex;
	_m[t].m6 |= 0x80; // set top bit of m6 to indicate it is an fsmport
}

/* Check if tile has a specindex and is an fsmport */
static inline bool IsCustomFSMportsSpecIndex(TileIndex t)
{
	assert(IsTileType(t, MP_STATION));
	return ((_m[t].m4 != 0) && ((_m[t].m6 & 0x80) == 0x80));
}

/* Draw representation of a FSMports tile for GUI purposes. */
bool DrawFSMportsTile(int x, int y, RailType railtype, Axis axis, FSMportsClassID sclass, uint FSMports);

#endif /* NEWGRF_FSMPORTS_H */