src/newgrf_fsmports.h
author richk
Tue, 17 Jun 2008 13:41:57 +0000
branchNewGRF_ports
changeset 10995 311b38c7f9a7
parent 10346 a1e9f8871c05
permissions -rw-r--r--
(svn r13549) [NewGRF_ports] -Change: Make recolouring of groundtile (0x0f80) specific to NewGRF_ports only.
Also base groundsprite on airport_tile of station. This prevents mixed colour groundtiles in an airport.
/* $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 "core/enum_type.hpp"
#include "tile_type.h"
#include "map_type.h"
#include "map_func.h"
#include "tile_map.h"
#include "newgrf_cargo.h"
#include "sprite.h"
#include "airport.h"
#include "station_type.h"
#include "strings_func.h"
#include "widgets/dropdown_type.h"

enum FSMportClass {
	SYSTEM_HIDDEN_CLASS = 0x53595354  ///< SYST is a hidden class for things like oilrigs that need FSMs, but should not appear in picker lists
};

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

/** 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 *size_x;
	byte *size_y;

	byte numlayouts;
	FSMportsLayout *layouts;
	bool copied_layouts;

	FSMportsLayout *layout_mask;

	AirportFTAClass *portFSM;

	uint8  anim_frames;
	uint8  anim_status;
	uint8  anim_speed;
	uint16 anim_triggers;

	/**
	 * 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);
DropDownList *BuildFSMportsClassDropdown();

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

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

/* Rotate a position depending on the FSM_orientation */
TileIndexDiffC RotateFSMPosition(TileIndexDiffC position, byte size_x, byte size_y, byte FSM_orientation);

/* 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 Station. */
void DeallocateSpecFromFSMports(Station* st, byte specindex);

/* Deallocate a FSMportsSpec from a Station, referenced by the spec itself. Use when specindex unknown. */
void RemoveFSMSpecFromStationList(Station *st, const FSMportsSpec *fsmportspec);

/* 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)
{
	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, byte tile, FSMportsClassID sclass, uint FSMports);

#endif /* NEWGRF_FSMPORTS_H */