richk@6734: /* $Id$ */ richk@6722: richk@6722: /** @file newgrf_fsmports.h Header file for NewGRF Finite FSMPORTSe Machine Ports (airports, seaports, landports??) */ richk@6722: richk@6722: #ifndef NEWGRF_FSMPORTS_H richk@6722: #define NEWGRF_FSMPORTS_H richk@6722: rubidium@6872: #include "core/enum_type.hpp" rubidium@6872: #include "tile_type.h" rubidium@6872: #include "map_type.h" rubidium@6872: #include "map_func.h" rubidium@6872: #include "tile_map.h" richk@6722: #include "newgrf_cargo.h" richk@6722: #include "sprite.h" richk@6807: #include "airport.h" richk@10184: #include "station_type.h" richk@10184: #include "strings_func.h" richk@6874: #include "widgets/dropdown_type.h" richk@6722: richk@6793: enum FSMportClass { richk@6793: SYSTEM_HIDDEN_CLASS = 0x53595354 ///< SYST is a hidden class for things like oilrigs that need FSMs, but should not appear in picker lists richk@6793: }; richk@6793: richk@6722: enum FSMportsClassID { richk@6722: FSMPORTS_CLASS_BEGIN = 0, ///< the lowest valid value richk@6722: FSMPORTS_CLASS_DFLT = 0, ///< Default FSMports class. richk@6795: FSMPORTS_CLASS_SYST = 31, ///< SYST hidden class richk@6722: FSMPORTS_CLASS_MAX = 32, ///< Maximum number of classes. richk@6722: }; richk@6722: richk@6722: /** Define basic enum properties */ richk@6722: template <> struct EnumPropsT : MakeEnumPropsT {}; richk@6722: typedef TinyEnumT FSMportsClassIDByte; richk@6722: richk@6722: /** Allow incrementing of FSMportsClassID variables */ richk@6722: DECLARE_POSTFIX_INCREMENT(FSMportsClassID); richk@6722: richk@6722: /* FSMports layout for given dimensions - it is a two-dimensional array richk@6722: * where index is computed as (x * platforms) + platform. */ richk@6722: typedef byte *FSMportsLayout; richk@6722: richk@6722: struct FSMportsSpec { richk@6722: const struct GRFFile *grffile; ///< ID of GRF file FSMports belongs to. richk@6722: int localidx; ///< Index within GRF file of FSMports. richk@6722: richk@6722: bool allocated; ///< Flag whether this FSMport has been added to a FSMports class list richk@6722: richk@6722: FSMportsClassID sclass; ///< The class to which this spec belongs. richk@6722: StringID name; ///< Name of this FSMport. richk@6722: richk@6722: /** Number of tile layouts. richk@6722: * A minimum of 8 is required is required for FSMportss. richk@6722: * 0-1 = plain platform richk@6722: * 2-3 = platform with building richk@6722: * 4-5 = platform with roof, left side richk@6722: * 6-7 = platform with roof, right side richk@6722: */ richk@6722: uint tiles; richk@6722: DrawTileSprites *renderdata; ///< Array of tile layouts. richk@6722: bool copied_renderdata; richk@6722: richk@6722: /** Cargo threshold for choosing between little and lots of cargo richk@6722: * @note little/lots are equivalent to the moving/loading FSMPORTSes for vehicles richk@6722: */ richk@6722: uint16 cargo_threshold; richk@6722: richk@6722: uint32 cargo_triggers; ///< Bitmask of cargo types which cause trigger re-randomizing richk@6722: richk@6722: byte callbackmask; ///< Bitmask of callbacks to use, @see newgrf_callbacks.h richk@6722: richk@6722: byte flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by FSMports size richk@6722: richk@6745: byte *size_x; richk@6745: byte *size_y; richk@6722: richk@6745: byte numlayouts; rubidium@6801: FSMportsLayout *layouts; richk@6722: bool copied_layouts; richk@6722: rubidium@6801: FSMportsLayout *layout_mask; richk@6770: richk@6734: AirportFTAClass *portFSM; richk@6734: richk@10280: uint8 anim_frames; richk@10280: uint8 anim_status; richk@10280: uint8 anim_speed; richk@10280: uint16 anim_triggers; richk@10280: richk@6722: /** richk@6722: * NUM_CARGO real cargo plus three pseudo cargo sprite groups. richk@6722: * Used for obtaining the sprite offset of custom sprites, and for richk@6722: * evaluating callbacks. richk@6722: */ richk@6722: const struct SpriteGroup *spritegroup[NUM_CARGO + 3]; richk@6722: }; richk@6722: richk@6722: /** richk@6722: * Struct containing information relating to FSMports classes. richk@6722: */ richk@6722: struct FSMportsClass { richk@6722: uint32 id; ///< ID of this class, e.g. 'DFLT', 'WAYP', etc. richk@6722: StringID name; ///< Name of this class. richk@6734: uint FSMports; ///< Number of FSMports in this class. richk@6722: FSMportsSpec **spec; ///< Array of FSMports specifications. richk@6722: }; richk@6722: richk@6722: void ResetFSMportsClasses(); richk@6722: FSMportsClassID AllocateFSMportsClass(uint32 cls); richk@6722: void SetFSMportsClassName(FSMportsClassID sclass, StringID name); richk@6722: StringID GetFSMportsClassName(FSMportsClassID sclass); richk@6874: DropDownList *BuildFSMportsClassDropdown(); richk@6722: richk@6722: uint GetNumFSMportsClasses(); richk@6722: uint GetNumCustomFSMports(FSMportsClassID sclass); richk@6722: richk@6722: void SetCustomFSMportsSpec(FSMportsSpec *FSMPORTSspec); richk@6760: FSMportsSpec *GetCustomFSMportsSpec(FSMportsClassID sclass, uint FSMports); richk@6722: const FSMportsSpec *GetCustomFSMportsSpecByGrf(uint32 grfid, byte localidx); richk@6722: richk@6746: /* Rotate a position depending on the FSM_orientation */ richk@6746: TileIndexDiffC RotateFSMPosition(TileIndexDiffC position, byte size_x, byte size_y, byte FSM_orientation); richk@6722: richk@6722: /* Get sprite offset for a given custom FSMports and FSMports structure (may be richk@6722: * NULL - that means we are in a build dialog). The FSMports structure is used richk@6722: * for variational sprite groups. */ richk@6722: SpriteID GetCustomFSMportsRelocation(const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile); richk@6722: SpriteID GetCustomFSMportsGroundRelocation(const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile); richk@6743: uint16 GetFSMportsCallback(CallbackID callback, uint32 param1, uint32 param2, const FSMportsSpec *FSMPORTSspec, const Station *st, TileIndex tile); richk@6722: richk@6722: /* Allocate a FSMportsSpec to a Station. This is called once per build operation. */ richk@6722: int AllocateFSMportsSpecToStation(const FSMportsSpec *FSMPORTSspec, Station *st, bool exec); richk@6722: richk@10346: /* Deallocate a FSMportsSpec from a Station. */ richk@6722: void DeallocateSpecFromFSMports(Station* st, byte specindex); richk@6722: richk@10346: /* Deallocate a FSMportsSpec from a Station, referenced by the spec itself. Use when specindex unknown. */ richk@10346: void RemoveFSMSpecFromStationList(Station *st, const FSMportsSpec *fsmportspec); richk@10346: richk@6722: /* Set the spec index, and mark tile as an fsmport */ richk@6722: static inline void SetCustomFSMportsSpecIndex(TileIndex t, byte specindex) richk@6722: { richk@6722: assert(IsTileType(t, MP_STATION)); richk@6722: _m[t].m4 = specindex; richk@6722: _m[t].m6 |= 0x80; // set top bit of m6 to indicate it is an fsmport richk@6722: } richk@6722: richk@6722: /* Check if tile has a specindex and is an fsmport */ richk@6722: static inline bool IsCustomFSMportsSpecIndex(TileIndex t) richk@6722: { richk@6722: return ((_m[t].m4 != 0) && ((_m[t].m6 & 0x80) == 0x80)); richk@6722: } richk@6722: richk@6722: /* Draw representation of a FSMports tile for GUI purposes. */ richk@6745: bool DrawFSMportsTile(int x, int y, byte tile, FSMportsClassID sclass, uint FSMports); richk@6722: richk@6722: #endif /* NEWGRF_FSMPORTS_H */