OpenRCT2/src/openrct2/world/TileElement.h

538 lines
14 KiB
C
Raw Normal View History

2018-05-01 17:47:00 +02:00
/*****************************************************************************
* Copyright (c) 2014-2018 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
2018-05-01 17:47:00 +02:00
#pragma once
#include "../common.h"
2018-09-14 14:54:12 +02:00
#include "Location.hpp"
2018-05-01 17:47:00 +02:00
struct rct_scenery_entry;
struct rct_footpath_entry;
2018-05-01 17:47:00 +02:00
#pragma pack(push, 1)
2018-06-22 23:17:03 +02:00
struct rct_tile_element_path_properties
{
uint8_t type; // 4 0xF0 Path type, 0x08 Ride sign, 0x04 Set when path is diagonal, 0x03 Rotation
uint8_t additions; // 5
uint8_t edges; // 6
union
{
uint8_t addition_status; // 7
uint8_t ride_index;
2018-05-01 17:47:00 +02:00
};
};
assert_struct_size(rct_tile_element_path_properties, 4);
2018-06-22 23:17:03 +02:00
union rct_tile_element_properties
{
2018-05-01 17:47:00 +02:00
rct_tile_element_path_properties path;
};
assert_struct_size(rct_tile_element_properties, 4);
enum
{
TILE_ELEMENT_TYPE_SURFACE = (0 << 2),
TILE_ELEMENT_TYPE_PATH = (1 << 2),
TILE_ELEMENT_TYPE_TRACK = (2 << 2),
TILE_ELEMENT_TYPE_SMALL_SCENERY = (3 << 2),
TILE_ELEMENT_TYPE_ENTRANCE = (4 << 2),
TILE_ELEMENT_TYPE_WALL = (5 << 2),
TILE_ELEMENT_TYPE_LARGE_SCENERY = (6 << 2),
TILE_ELEMENT_TYPE_BANNER = (7 << 2),
// The corrupt element type is used for skipping drawing other following
// elements on a given tile.
TILE_ELEMENT_TYPE_CORRUPT = (8 << 2),
};
enum class TileElementType : uint8_t
{
Surface = (0 << 2),
Path = (1 << 2),
Track = (2 << 2),
SmallScenery = (3 << 2),
Entrance = (4 << 2),
Wall = (5 << 2),
LargeScenery = (6 << 2),
Banner = (7 << 2),
Corrupt = (8 << 2),
};
struct SurfaceElement;
struct PathElement;
struct TrackElement;
struct SmallSceneryElement;
struct LargeSceneryElement;
struct WallElement;
struct EntranceElement;
struct BannerElement;
struct CorruptElement;
struct TileElementBase
2018-06-22 23:17:03 +02:00
{
uint8_t type; // 0
uint8_t flags; // 1
uint8_t base_height; // 2
uint8_t clearance_height; // 3
uint8_t GetType() const;
2018-06-22 23:17:03 +02:00
void SetType(uint8_t newType);
uint8_t GetDirection() const;
2018-06-22 23:17:03 +02:00
void SetDirection(uint8_t direction);
uint8_t GetDirectionWithOffset(uint8_t offset) const;
2018-06-22 23:17:03 +02:00
bool IsLastForTile() const;
bool IsGhost() const;
void Remove();
};
/**
* Map element structure
* size: 0x08
*/
struct rct_tile_element : public TileElementBase
{
2018-09-23 14:05:17 +02:00
union
{
uint8_t pad_04[4];
// TODO: Remove this field.
rct_tile_element_properties properties;
};
2018-09-13 19:42:33 +02:00
template<typename TType, TileElementType TClass> TType* as() const
{
return (TileElementType)GetType() == TClass ? (TType*)this : nullptr;
}
public:
2018-09-13 19:42:33 +02:00
SurfaceElement* AsSurface() const
{
return as<SurfaceElement, TileElementType::Surface>();
}
PathElement* AsPath() const
{
return as<PathElement, TileElementType::Path>();
}
TrackElement* AsTrack() const
{
return as<TrackElement, TileElementType::Track>();
}
SmallSceneryElement* AsSmallScenery() const
{
return as<SmallSceneryElement, TileElementType::SmallScenery>();
}
LargeSceneryElement* AsLargeScenery() const
{
return as<LargeSceneryElement, TileElementType::LargeScenery>();
}
WallElement* AsWall() const
{
return as<WallElement, TileElementType::Wall>();
}
EntranceElement* AsEntrance() const
{
return as<EntranceElement, TileElementType::Entrance>();
}
BannerElement* AsBanner() const
{
return as<BannerElement, TileElementType::Banner>();
}
CorruptElement* AsCorrupt() const
{
return as<CorruptElement, TileElementType::Corrupt>();
}
2018-09-23 14:05:17 +02:00
void ClearAs(uint8_t newType);
2018-05-01 17:47:00 +02:00
};
assert_struct_size(rct_tile_element, 8);
struct SurfaceElement : TileElementBase
{
2018-09-14 14:54:12 +02:00
private:
uint8_t slope; // 4 0xE0 Edge Style, 0x1F Slope
uint8_t terrain; // 5 0xE0 Terrain Style, 0x1F Water height
uint8_t grass_length; // 6
uint8_t ownership; // 7
public:
uint8_t GetSlope() const;
void SetSlope(uint8_t newSlope);
uint32_t GetSurfaceStyle() const;
void SetSurfaceStyle(uint32_t newStyle);
uint32_t GetEdgeStyle() const;
void SetEdgeStyle(uint32_t newStyle);
uint8_t GetGrassLength() const;
void SetGrassLength(uint8_t newLength);
void SetGrassLengthAndInvalidate(uint8_t newLength, CoordsXY coords);
void UpdateGrassLength(CoordsXY coords);
uint8_t GetOwnership() const;
void SetOwnership(uint8_t newOwnership);
uint32_t GetWaterHeight() const;
void SetWaterHeight(uint32_t newWaterHeight);
uint8_t GetParkFences() const;
void SetParkFences(uint8_t newParkFences);
bool HasTrackThatNeedsWater() const;
void SetHasTrackThatNeedsWater(bool on);
};
assert_struct_size(SurfaceElement, 8);
struct PathElement : TileElementBase
{
2018-09-16 16:17:35 +02:00
private:
uint8_t entryIndex; // 4, 0xF0 Path type, 0x08 Ride sign, 0x04 Set when path is sloped, 0x03 Rotation
uint8_t additions; // 5, 0bGSSSAAAA: G = Ghost, S = station index, A = addition (0 means no addition)
uint8_t edges; // 6
union
{
uint8_t additionStatus; // 7
uint8_t rideIndex;
};
public:
uint8_t GetEntryIndex() const;
rct_footpath_entry* GetEntry() const;
void SetEntryIndex(uint8_t newIndex);
uint8_t GetQueueBannerDirection() const;
void SetQueueBannerDirection(uint8_t direction);
bool IsSloped() const;
void SetSloped(bool isSloped);
uint8_t GetSlopeDirection() const;
void SetSlopeDirection(uint8_t newSlope);
uint8_t GetRideIndex() const;
void SetRideIndex(uint8_t newRideIndex);
uint8_t GetStationIndex() const;
void SetStationIndex(uint8_t newStationIndex);
bool IsWide() const;
void SetWide(bool isWide);
2018-10-03 21:45:52 +02:00
2018-10-03 10:57:29 +02:00
bool IsQueue() const;
void SetIsQueue(bool isQueue);
bool HasQueueBanner() const;
void SetHasQueueBanner(bool hasQueueBanner);
2018-10-03 10:57:29 +02:00
bool HasAddition() const;
uint8_t GetAddition() const;
uint8_t GetAdditionEntryIndex() const;
rct_scenery_entry* GetAdditionEntry() const;
void SetAddition(uint8_t newAddition);
bool AdditionIsGhost() const;
void SetAdditionIsGhost(bool isGhost);
2018-10-03 21:45:52 +02:00
uint8_t GetAdditionStatus() const;
void SetAdditionStatus(uint8_t newStatus);
uint8_t GetRCT1PathType() const;
};
assert_struct_size(PathElement, 8);
struct TrackElement : TileElementBase
{
uint8_t trackType; // 4
union
{
struct
{
// The lower 4 bits are the track sequence.
// The upper 4 bits are either station bits or on-ride photo bits.
//
// Station bits:
// - Bit 8 marks green light
// - Bit 5-7 are station index.
//
// On-ride photo bits:
// - Bits 7 and 8 are never set
// - Bits 5 and 6 are set when a vehicle triggers the on-ride photo and act like a countdown from 3.
// - If any of the bits 5-8 are set, the game counts it as a photo being taken.
uint8_t sequence; // 5.
uint8_t colour; // 6
};
uint16_t mazeEntry; // 5
};
uint8_t rideIndex; // 7
2018-09-23 11:55:37 +02:00
public:
uint8_t GetTrackType() const;
void SetTrackType(uint8_t newEntryIndex);
2018-09-23 11:55:37 +02:00
uint8_t GetSequenceIndex() const;
void SetSequenceIndex(uint8_t newSequenceIndex);
2018-09-23 11:55:37 +02:00
uint8_t GetRideIndex() const;
void SetRideIndex(uint8_t newRideIndex);
2018-09-23 11:55:37 +02:00
uint8_t GetColourScheme() const;
void SetColourScheme(uint8_t newColourScheme);
2018-09-23 11:55:37 +02:00
uint8_t GetStationIndex() const;
void SetStationIndex(uint8_t newStationIndex);
2018-09-18 13:01:09 +02:00
bool HasChain() const;
void SetHasChain(bool on);
bool HasCableLift() const;
void SetHasCableLift(bool on);
bool IsInverted() const;
void SetInverted(bool inverted);
uint8_t GetBrakeBoosterSpeed() const;
void SetBrakeBoosterSpeed(uint8_t speed);
uint8_t HasGreenLight() const;
void SetHasGreenLight(uint8_t greenLight);
uint8_t GetSeatRotation() const;
void SetSeatRotation(uint8_t newSeatRotation);
2018-09-18 13:49:58 +02:00
uint16_t GetMazeEntry() const;
void SetMazeEntry(uint16_t newMazeEntry);
void MazeEntryAdd(uint16_t addVal);
void MazeEntrySubtract(uint16_t subVal);
2018-09-18 13:49:58 +02:00
bool IsTakingPhoto() const;
void SetPhotoTimeout();
void DecrementPhotoTimeout();
2018-09-23 11:55:37 +02:00
bool IsHighlighted() const;
void SetHighlight(bool on);
// Used in RCT1, will be reintroduced at some point.
// (See https://github.com/OpenRCT2/OpenRCT2/issues/7059)
uint8_t GetDoorAState() const;
uint8_t GetDoorBState() const;
};
assert_struct_size(TrackElement, 8);
struct SmallSceneryElement : TileElementBase
{
private:
uint8_t entryIndex; // 4
uint8_t age; // 5
uint8_t colour_1; // 6
uint8_t colour_2; // 7
public:
uint8_t GetEntryIndex() const;
void SetEntryIndex(uint8_t newIndex);
rct_scenery_entry* GetEntry() const;
uint8_t GetAge() const;
void SetAge(uint8_t newAge);
void IncreaseAge(int32_t x, int32_t y);
uint8_t GetSceneryQuadrant() const;
void SetSceneryQuadrant(uint8_t newQuadrant);
colour_t GetPrimaryColour() const;
void SetPrimaryColour(colour_t colour);
colour_t GetSecondaryColour() const;
void SetSecondaryColour(colour_t colour);
bool NeedsSupports() const;
void SetNeedsSupports();
};
assert_struct_size(SmallSceneryElement, 8);
struct LargeSceneryElement : TileElementBase
{
2018-09-14 12:12:22 +02:00
private:
uint16_t entryIndex; // 4
uint8_t colour[2]; // 6
public:
uint32_t GetEntryIndex() const;
void SetEntryIndex(uint32_t newIndex);
rct_scenery_entry* GetEntry() const;
uint16_t GetSequenceIndex() const;
void SetSequenceIndex(uint16_t newIndex);
colour_t GetPrimaryColour() const;
void SetPrimaryColour(colour_t colour);
colour_t GetSecondaryColour() const;
void SetSecondaryColour(colour_t colour);
BannerIndex GetBannerIndex() const;
void SetBannerIndex(BannerIndex newIndex);
};
assert_struct_size(LargeSceneryElement, 8);
struct WallElement : TileElementBase
{
2018-09-17 16:12:11 +02:00
private:
uint8_t entryIndex; // 4
union
{
uint8_t colour_3; // 5
BannerIndex banner_index; // 5
};
uint8_t colour_1; // 6 0b_2221_1111 2 = colour_2 (uses flags for rest of colour2), 1 = colour_1
uint8_t animation; // 7 0b_dfff_ft00 d = direction, f = frame num, t = across track flag (not used)
2018-09-13 19:42:33 +02:00
public:
uint8_t GetEntryIndex() const;
void SetEntryIndex(uint8_t newIndex);
rct_scenery_entry* GetEntry() const;
uint8_t GetSlope() const;
void SetSlope(uint8_t newslope);
colour_t GetPrimaryColour() const;
void SetPrimaryColour(colour_t newColour);
colour_t GetSecondaryColour() const;
void SetSecondaryColour(colour_t newColour);
colour_t GetTertiaryColour() const;
void SetTertiaryColour(colour_t newColour);
uint8_t GetAnimationFrame() const;
void SetAnimationFrame(uint8_t frameNum);
BannerIndex GetBannerIndex() const;
void SetBannerIndex(BannerIndex newIndex);
bool IsAcrossTrack() const;
void SetAcrossTrack(bool acrossTrack);
bool AnimationIsBackwards() const;
void SetAnimationIsBackwards(bool isBackwards);
int32_t GetRCT1WallType(int32_t edge) const;
colour_t GetRCT1WallColour() const;
};
assert_struct_size(WallElement, 8);
struct EntranceElement : TileElementBase
{
2018-09-26 12:02:41 +02:00
private:
uint8_t entranceType; // 4
2018-09-26 12:30:27 +02:00
uint8_t index; // 5. 0bUSSS????, S = station index.
2018-09-26 12:02:41 +02:00
uint8_t pathType; // 6
uint8_t rideIndex; // 7
2018-09-23 11:55:37 +02:00
public:
2018-09-26 12:13:44 +02:00
uint8_t GetEntranceType() const;
void SetEntranceType(uint8_t newType);
2018-09-26 12:30:27 +02:00
uint8_t GetRideIndex() const;
void SetRideIndex(uint8_t newRideIndex);
uint8_t GetStationIndex() const;
void SetStationIndex(uint8_t stationIndex);
uint8_t GetSequenceIndex() const;
void SetSequenceIndex(uint8_t newSequenceIndex);
2018-09-26 13:02:51 +02:00
uint8_t GetPathType() const;
void SetPathType(uint8_t newPathType);
};
assert_struct_size(EntranceElement, 8);
struct BannerElement : TileElementBase
{
2018-09-26 14:07:04 +02:00
private:
BannerIndex index; // 4
2018-09-26 14:52:16 +02:00
uint8_t position; // 5
2018-09-26 14:07:04 +02:00
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
2018-09-26 15:44:09 +02:00
uint8_t flags; // 6
uint8_t unused; // 7
2018-09-26 14:07:04 +02:00
#pragma clang diagnostic pop
public:
BannerIndex GetIndex() const;
void SetIndex(BannerIndex newIndex);
2018-09-26 14:52:16 +02:00
uint8_t GetPosition() const;
void SetPosition(uint8_t newPosition);
uint8_t GetAllowedEdges() const;
void SetAllowedEdges(uint8_t newEdges);
void ResetAllowedEdges();
};
assert_struct_size(BannerElement, 8);
struct CorruptElement : TileElementBase
{
uint8_t pad[4];
};
assert_struct_size(CorruptElement, 8);
2018-05-01 17:47:00 +02:00
#pragma pack(pop)
2018-06-22 23:17:03 +02:00
enum
{
2018-05-01 17:47:00 +02:00
TILE_ELEMENT_QUADRANT_SW,
TILE_ELEMENT_QUADRANT_NW,
TILE_ELEMENT_QUADRANT_NE,
TILE_ELEMENT_QUADRANT_SE
};
2018-06-22 23:17:03 +02:00
enum
{
TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6),
SURFACE_ELEMENT_HAS_TRACK_THAT_NEEDS_WATER = (1 << 6),
2018-05-01 17:47:00 +02:00
};
2018-06-22 23:17:03 +02:00
enum
{
2018-05-01 17:47:00 +02:00
TILE_ELEMENT_DIRECTION_WEST,
TILE_ELEMENT_DIRECTION_NORTH,
TILE_ELEMENT_DIRECTION_EAST,
TILE_ELEMENT_DIRECTION_SOUTH
};
2018-06-22 23:17:03 +02:00
enum
{
2018-05-01 17:47:00 +02:00
TILE_ELEMENT_FLAG_GHOST = (1 << 4),
TILE_ELEMENT_FLAG_BROKEN = (1 << 5),
TILE_ELEMENT_FLAG_BLOCK_BRAKE_CLOSED = (1 << 5),
TILE_ELEMENT_FLAG_INDESTRUCTIBLE_TRACK_PIECE = (1 << 6),
TILE_ELEMENT_FLAG_BLOCKED_BY_VEHICLE = (1 << 6),
2018-05-01 17:47:00 +02:00
TILE_ELEMENT_FLAG_LAST_TILE = (1 << 7)
};
2018-06-22 23:17:03 +02:00
enum
{
2018-05-01 17:47:00 +02:00
ENTRANCE_TYPE_RIDE_ENTRANCE,
ENTRANCE_TYPE_RIDE_EXIT,
ENTRANCE_TYPE_PARK_ENTRANCE
};
2018-06-22 23:17:03 +02:00
enum
{
2018-05-01 17:47:00 +02:00
ELEMENT_IS_ABOVE_GROUND = 1 << 0,
ELEMENT_IS_UNDERGROUND = 1 << 1,
ELEMENT_IS_UNDERWATER = 1 << 2,
};
enum
{
MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT = (1 << 7),
};
2018-06-22 23:17:03 +02:00
#define TILE_ELEMENT_QUADRANT_MASK 0b11000000
#define TILE_ELEMENT_TYPE_MASK 0b00111100
2018-05-02 13:30:15 +02:00
#define TILE_ELEMENT_DIRECTION_MASK 0b00000011
2018-05-01 17:47:00 +02:00
2018-06-22 23:17:03 +02:00
#define TILE_ELEMENT_COLOUR_MASK 0b00011111
2018-05-01 17:47:00 +02:00
2018-05-02 13:30:15 +02:00
#define MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK 0b01110000
2018-06-22 23:17:03 +02:00
#define MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK 0b00001111
#define MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK 0b11110000
2018-05-01 17:47:00 +02:00
BannerIndex tile_element_get_banner_index(rct_tile_element* tileElement);
2018-06-22 23:17:03 +02:00
bool tile_element_is_underground(rct_tile_element* tileElement);
2018-05-01 17:47:00 +02:00
// ~Oli414: The banner functions should probably be part of banner.
void tile_element_set_banner_index(rct_tile_element* tileElement, BannerIndex bannerIndex);
2018-06-22 23:17:03 +02:00
void tile_element_remove_banner_entry(rct_tile_element* tileElement);
2018-05-01 17:47:00 +02:00
2018-06-22 23:17:03 +02:00
uint8_t tile_element_get_ride_index(const rct_tile_element* tileElement);