mirror of https://github.com/OpenRCT2/OpenRCT2.git
600 lines
27 KiB
C++
600 lines
27 KiB
C++
/*****************************************************************************
|
|
* Copyright (c) 2014-2024 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.
|
|
*****************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#define TRACK_COLOUR_PRESETS(...) \
|
|
{ \
|
|
static_cast<uint8_t>(std::size<TrackColour>({ __VA_ARGS__ })), \
|
|
{ \
|
|
__VA_ARGS__ \
|
|
} \
|
|
}
|
|
#define DEFAULT_FLAT_RIDE_COLOUR_PRESET TRACK_COLOUR_PRESETS({ COLOUR_BRIGHT_RED, COLOUR_LIGHT_BLUE, COLOUR_YELLOW })
|
|
#define DEFAULT_STALL_COLOUR_PRESET TRACK_COLOUR_PRESETS({ COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED })
|
|
|
|
#include "../audio/audio.h"
|
|
#include "../common.h"
|
|
#include "../core/BitSet.hpp"
|
|
#include "../entity/Guest.h"
|
|
#include "../localisation/StringIds.h"
|
|
#include "../sprites.h"
|
|
#include "../util/Util.h"
|
|
#include "Ride.h"
|
|
#include "RideAudio.h"
|
|
#include "RideConstruction.h"
|
|
#include "RideEntry.h"
|
|
#include "RideRatings.h"
|
|
#include "ShopItem.h"
|
|
#include "Track.h"
|
|
#include "TrackPaint.h"
|
|
#include "Vehicle.h"
|
|
|
|
enum class ResearchCategory : uint8_t;
|
|
|
|
constexpr const uint8_t DefaultFoodStallHeight = 8 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultDrinksStallHeight = 8 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultShopHeight = 8 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultToiletHeight = 4 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultInformationKioskHeight = 6 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultFirstAidHeight = 6 * COORDS_Z_STEP;
|
|
constexpr const uint8_t DefaultCashMachineHeight = 8 * COORDS_Z_STEP;
|
|
|
|
struct RideComponentName
|
|
{
|
|
StringId singular;
|
|
StringId plural;
|
|
StringId capitalised;
|
|
StringId capitalised_plural;
|
|
StringId count;
|
|
StringId count_plural;
|
|
StringId number;
|
|
};
|
|
|
|
enum class RideComponentType
|
|
{
|
|
Train,
|
|
Boat,
|
|
Track,
|
|
DockingPlatform,
|
|
Station,
|
|
Car,
|
|
Building,
|
|
Structure,
|
|
Ship,
|
|
Cabin,
|
|
Wheel,
|
|
Ring,
|
|
Player,
|
|
Course,
|
|
Count
|
|
};
|
|
|
|
enum class RideColourKey : uint8_t
|
|
{
|
|
Ride,
|
|
Food,
|
|
Drink,
|
|
Shop,
|
|
InfoKiosk,
|
|
FirstAid,
|
|
CashMachine,
|
|
Toilets
|
|
};
|
|
|
|
enum class TrackDesignCreateMode : uint_fast8_t
|
|
{
|
|
Default,
|
|
Maze
|
|
};
|
|
|
|
enum class RatingsCalculationType : uint8_t
|
|
{
|
|
Normal,
|
|
FlatRide,
|
|
Stall,
|
|
};
|
|
|
|
enum class RatingsModifierType : uint8_t
|
|
{
|
|
NoModifier,
|
|
// General Rating Bonuses
|
|
BonusLength,
|
|
BonusSynchronisation,
|
|
BonusTrainLength,
|
|
BonusMaxSpeed,
|
|
BonusAverageSpeed,
|
|
BonusDuration,
|
|
BonusGForces,
|
|
BonusTurns,
|
|
BonusDrops,
|
|
BonusSheltered,
|
|
BonusProximity,
|
|
BonusScenery,
|
|
BonusRotations,
|
|
BonusOperationOption,
|
|
BonusReversedTrains,
|
|
// Ride-specific Rating Bonuses
|
|
BonusGoKartRace,
|
|
BonusTowerRide,
|
|
BonusRotoDrop,
|
|
BonusMazeSize,
|
|
BonusBoatHireNoCircuit,
|
|
BonusSlideUnlimitedRides,
|
|
BonusMotionSimulatorMode,
|
|
Bonus3DCinemaMode,
|
|
BonusTopSpinMode,
|
|
// Number of reversals BONUS for reverser coaster
|
|
BonusReversals,
|
|
// Number of hole BONUS for mini golf
|
|
BonusHoles,
|
|
// Number of cars bonus for dodgems/flying saucers
|
|
BonusNumTrains,
|
|
// Bonus for launched freefall in downward launch mode
|
|
BonusDownwardLaunch,
|
|
// Bonus with further mode-dependent logic for LF
|
|
BonusLaunchedFreefallSpecial,
|
|
// General Rating Requirements
|
|
RequirementLength,
|
|
RequirementDropHeight,
|
|
RequirementNumDrops,
|
|
RequirementMaxSpeed,
|
|
RequirementNegativeGs,
|
|
RequirementLateralGs,
|
|
RequirementInversions,
|
|
RequirementUnsheltered,
|
|
// Number of reversals REQUIREMENT for reverser coaster
|
|
RequirementReversals,
|
|
// Number of hole REQUIREMENT for mini golf
|
|
RequirementHoles,
|
|
// 2 Station requirement for Chairlift
|
|
RequirementStations,
|
|
// Water section requirement for Water Coaster
|
|
RequirementSplashdown,
|
|
PenaltyLateralGs,
|
|
};
|
|
|
|
struct RideNameConvention
|
|
{
|
|
RideComponentType vehicle;
|
|
RideComponentType structure;
|
|
RideComponentType station;
|
|
};
|
|
|
|
struct RideBuildCost
|
|
{
|
|
money64 TrackPrice; // Cost of a single straight piece of track
|
|
money64 SupportPrice;
|
|
uint8_t PriceEstimateMultiplier;
|
|
};
|
|
|
|
struct RideHeights
|
|
{
|
|
uint8_t MaxHeight;
|
|
uint8_t ClearanceHeight;
|
|
int8_t VehicleZOffset;
|
|
uint8_t PlatformHeight;
|
|
};
|
|
|
|
struct RideLiftData
|
|
{
|
|
OpenRCT2::Audio::SoundId sound_id;
|
|
uint8_t minimum_speed;
|
|
uint8_t maximum_speed;
|
|
};
|
|
|
|
struct RideColourPreview
|
|
{
|
|
uint32_t Track;
|
|
uint32_t Supports;
|
|
};
|
|
|
|
struct RideOperatingSettings
|
|
{
|
|
uint8_t MinValue;
|
|
uint8_t MaxValue;
|
|
uint8_t MaxBrakesSpeed;
|
|
uint8_t PoweredLiftAcceleration;
|
|
uint8_t BoosterAcceleration;
|
|
int8_t BoosterSpeedFactor; // The factor to shift the raw booster speed with
|
|
uint16_t AccelerationFactor = 12;
|
|
uint8_t OperatingSettingMultiplier = 1; // Used for the Ride window, cosmetic only.
|
|
};
|
|
|
|
struct RatingsModifier
|
|
{
|
|
RatingsModifierType Type;
|
|
int32_t Threshold;
|
|
int32_t Excitement;
|
|
int32_t Intensity;
|
|
int32_t Nausea;
|
|
};
|
|
|
|
struct RideRatingsDescriptor
|
|
{
|
|
RatingsCalculationType Type;
|
|
RatingTuple BaseRatings;
|
|
uint8_t Unreliability;
|
|
// Used for rides with a set sheltered 8ths value (-1 = normal calculation)
|
|
int8_t RideShelter;
|
|
bool RelaxRequirementsIfInversions;
|
|
RatingsModifier Modifiers[32];
|
|
};
|
|
|
|
struct UpkeepCostsDescriptor
|
|
{
|
|
/**
|
|
* Data about ride running costs. This is widely adjusted by the upkeep
|
|
* function, so values that don't make much sense here (a roller coaster having
|
|
* cheaper upkeep than a car ride) are fixed later on.
|
|
*
|
|
* Data generation script: https://gist.github.com/kevinburke/6bcf4a8fcc95faad7bac
|
|
*/
|
|
money64 BaseCost;
|
|
/** rct2: 0x0097E3AC */
|
|
uint8_t TrackLengthMultiplier;
|
|
money64 CostPerTrackPiece;
|
|
/** rct2: 0x0097E3B4 */
|
|
money64 CostPerTrain;
|
|
/** rct2: 0x0097E3B6 */
|
|
money64 CostPerCar;
|
|
/** rct2: 0x0097E3B8 */
|
|
money64 CostPerStation;
|
|
};
|
|
|
|
using RideTrackGroup = OpenRCT2::BitSet<TRACK_GROUP_COUNT>;
|
|
using UpdateRideApproachVehicleWaypointsFunction = void (*)(Guest&, const CoordsXY&, int16_t&);
|
|
using RideMusicUpdateFunction = void (*)(Ride&);
|
|
using PeepUpdateRideLeaveEntranceFunc = void (*)(Guest*, Ride&, CoordsXYZD&);
|
|
using StartRideMusicFunction = void (*)(const OpenRCT2::RideAudio::ViewportRideMusicInstance&);
|
|
using LightFXAddLightsMagicVehicleFunction = void (*)(const Vehicle* vehicle);
|
|
using RideLocationFunction = CoordsXY (*)(const Vehicle& vehicle, const Ride& ride, const StationIndex& CurrentRideStation);
|
|
using RideUpdateFunction = void (*)(Ride& ride);
|
|
using RideUpdateMeasurementsSpecialElementsFunc = void (*)(Ride& ride, const track_type_t trackType);
|
|
using MusicTrackOffsetLengthFunc = std::pair<size_t, size_t> (*)(const Ride& ride);
|
|
using SpecialElementRatingAdjustmentFunc = void (*)(const Ride& ride, int32_t& excitement, int32_t& intensity, int32_t& nausea);
|
|
|
|
using UpdateRotatingFunction = void (*)(Vehicle& vehicle);
|
|
enum class RideConstructionWindowContext : uint8_t
|
|
{
|
|
Default,
|
|
Maze,
|
|
};
|
|
|
|
struct TrackDrawerEntry
|
|
{
|
|
TRACK_PAINT_FUNCTION_GETTER Drawer = nullptr;
|
|
/** rct2: 0x0097C468 (0 - 31) and 0x0097C5D4 (32 - 63) */
|
|
RideTrackGroup EnabledTrackPieces{};
|
|
// Pieces that this ride type _can_ draw, but are disabled because their vehicles lack the relevant sprites,
|
|
// or because they are not realistic for the ride type (e.g. LIM boosters in Mini Roller Coasters).
|
|
RideTrackGroup ExtraTrackPieces{};
|
|
|
|
void GetAvailableTrackPieces(RideTrackGroup& res) const;
|
|
bool SupportsTrackPiece(const uint64_t trackPiece) const;
|
|
};
|
|
|
|
struct TrackDrawerDescriptor
|
|
{
|
|
TrackDrawerEntry Regular{};
|
|
TrackDrawerEntry Covered{};
|
|
|
|
constexpr TrackDrawerDescriptor()
|
|
{
|
|
}
|
|
|
|
constexpr TrackDrawerDescriptor(TrackDrawerEntry function)
|
|
: Regular(function)
|
|
{
|
|
}
|
|
|
|
constexpr TrackDrawerDescriptor(TrackDrawerEntry entryRegular, TrackDrawerEntry entryCovered)
|
|
: Regular(entryRegular)
|
|
, Covered(entryCovered)
|
|
{
|
|
}
|
|
|
|
bool HasCoveredPieces() const;
|
|
bool SupportsTrackPiece(const uint64_t trackPiece) const;
|
|
};
|
|
|
|
struct RideTypeDescriptor
|
|
{
|
|
uint8_t Category{};
|
|
/** rct2: 0x0097CC68 */
|
|
track_type_t StartTrackPiece{};
|
|
TrackDrawerDescriptor TrackPaintFunctions{};
|
|
TrackDrawerDescriptor InvertedTrackPaintFunctions{};
|
|
uint64_t Flags{};
|
|
/** rct2: 0x0097C8AC */
|
|
uint64_t RideModes{};
|
|
RideMode DefaultMode{};
|
|
/** rct2: 0x0097CF40 */
|
|
RideOperatingSettings OperatingSettings{};
|
|
RideNaming Naming{};
|
|
RideNameConvention NameConvention{};
|
|
const char* EnumName{};
|
|
uint8_t AvailableBreakdowns{};
|
|
/** rct2: 0x0097D218 */
|
|
RideHeights Heights{};
|
|
uint8_t MaxMass{};
|
|
/** rct2: 0x0097D7C8, 0x0097D7C9, 0x0097D7CA */
|
|
RideLiftData LiftData{};
|
|
// rct2: 0x0097CD1E
|
|
RatingTuple RatingsMultipliers{};
|
|
UpkeepCostsDescriptor UpkeepCosts{};
|
|
// rct2: 0x0097DD78
|
|
RideBuildCost BuildCosts{};
|
|
money64 DefaultPrices[RCT2::ObjectLimits::MaxShopItemsPerRideEntry]{};
|
|
std::string_view DefaultMusic{};
|
|
/** rct2: 0x0097D7CB */
|
|
ShopItemIndex PhotoItem{};
|
|
/** rct2: 0x0097D21E */
|
|
uint8_t BonusValue{};
|
|
TrackColourPresetList ColourPresets{};
|
|
RideColourPreview ColourPreview{};
|
|
RideColourKey ColourKey{};
|
|
|
|
// json name lookup
|
|
std::string_view Name{};
|
|
|
|
RideRatingsDescriptor RatingsData{};
|
|
|
|
UpdateRotatingFunction UpdateRotating = UpdateRotatingDefault;
|
|
|
|
LightFXAddLightsMagicVehicleFunction LightFXAddLightsMagicVehicle = nullptr;
|
|
StartRideMusicFunction StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel;
|
|
|
|
TrackDesignCreateMode DesignCreateMode = TrackDesignCreateMode::Default;
|
|
|
|
RideMusicUpdateFunction MusicUpdateFunction = DefaultMusicUpdate;
|
|
RideClassification Classification = RideClassification::Ride;
|
|
|
|
PeepUpdateRideLeaveEntranceFunc UpdateLeaveEntrance = PeepUpdateRideLeaveEntranceDefault;
|
|
SpecialElementRatingAdjustmentFunc SpecialElementRatingAdjustment = SpecialTrackElementRatingsAjustment_Default;
|
|
|
|
RideLocationFunction GetGuestWaypointLocation = GetGuestWaypointLocationDefault;
|
|
|
|
RideConstructionWindowContext ConstructionWindowContext = RideConstructionWindowContext::Default;
|
|
RideUpdateFunction RideUpdate = nullptr;
|
|
|
|
RideUpdateMeasurementsSpecialElementsFunc UpdateMeasurementsSpecialElements = RideUpdateMeasurementsSpecialElements_Default;
|
|
|
|
MusicTrackOffsetLengthFunc MusicTrackOffsetLength = OpenRCT2::RideAudio::RideMusicGetTrackOffsetLength_Default;
|
|
|
|
UpdateRideApproachVehicleWaypointsFunction UpdateRideApproachVehicleWaypoints = UpdateRideApproachVehicleWaypointsDefault;
|
|
|
|
bool HasFlag(uint64_t flag) const;
|
|
/** @deprecated */
|
|
bool SupportsTrackPiece(const uint64_t trackPiece) const;
|
|
ResearchCategory GetResearchCategory() const;
|
|
bool SupportsRideMode(RideMode rideMode) const;
|
|
};
|
|
|
|
extern const RideTypeDescriptor RideTypeDescriptors[RIDE_TYPE_COUNT];
|
|
|
|
enum
|
|
{
|
|
RIDE_TYPE_NO_ALTERNATIVES = 0,
|
|
RIDE_TYPE_ALTERNATIVE_TRACK_PIECES = 1, // Dinghy slide and Water Coaster
|
|
RIDE_TYPE_ALTERNATIVE_TRACK_TYPE = 2, // Flying RC, Lay-down RC, Multi-dimension RC
|
|
};
|
|
|
|
enum ride_type_flags : uint64_t
|
|
{
|
|
RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN = (1uLL << 0),
|
|
RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL = (1uLL << 1),
|
|
RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS = (1uLL << 2),
|
|
RIDE_TYPE_FLAG_HAS_SINGLE_PIECE_STATION = (1uLL << 3), // Set by flat rides, tower rides and shops/stalls.
|
|
RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION = (1uLL << 4),
|
|
RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS = (1uLL << 5),
|
|
RIDE_TYPE_FLAG_TRACK_MUST_BE_ON_WATER = (1uLL << 6), // used only by boat Hire and submarine ride
|
|
RIDE_TYPE_FLAG_HAS_G_FORCES = (1uLL << 7),
|
|
RIDE_TYPE_FLAG_CANNOT_HAVE_GAPS = (1uLL << 8), // used by rides that can't have gaps, like those with a vertical tower, such
|
|
// as the observation tower
|
|
RIDE_TYPE_FLAG_HAS_DATA_LOGGING = (1uLL << 9),
|
|
RIDE_TYPE_FLAG_HAS_DROPS = (1uLL << 10),
|
|
RIDE_TYPE_FLAG_NO_TEST_MODE = (1uLL << 11),
|
|
RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES = (1uLL << 12), // set on rides with two varieties,
|
|
// like the u and o shapes of the dinghy slide
|
|
// and the dry and submerged track of the water
|
|
// coaster
|
|
RIDE_TYPE_FLAG_NO_VEHICLES = (1uLL << 13), // used only by maze, spiral slide and shops
|
|
RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS = (1uLL << 14),
|
|
RIDE_TYPE_FLAG_VEHICLE_IS_INTEGRAL = (1uLL << 16), // Set by flat rides where the vehicle is integral to the structure, like
|
|
// Merry-go-round and swinging ships. (Contrast with rides like dodgems.)
|
|
RIDE_TYPE_FLAG_IS_SHOP_OR_FACILITY = (1uLL << 17),
|
|
RIDE_TYPE_FLAG_TRACK_NO_WALLS = (1uLL << 18), // if set, wall scenery can not share a tile with the ride's track
|
|
RIDE_TYPE_FLAG_FLAT_RIDE = (1uLL << 19),
|
|
RIDE_TYPE_FLAG_PEEP_WILL_RIDE_AGAIN = (1uLL << 20), // whether or not guests will go on the ride again if they liked it
|
|
// (this is
|
|
// usually applied to everything apart from transport rides)
|
|
RIDE_TYPE_FLAG_PEEP_SHOULD_GO_INSIDE_FACILITY = (1uLL << 21), // used by toilets and first aid to mark that peep should go
|
|
// inside the building (rather than 'buying' at the counter)
|
|
RIDE_TYPE_FLAG_IN_RIDE = (1uLL << 22), // peeps are "IN" (ride) rather than "ON" (ride)
|
|
RIDE_TYPE_FLAG_SELLS_FOOD = (1uLL << 23),
|
|
RIDE_TYPE_FLAG_SELLS_DRINKS = (1uLL << 24),
|
|
RIDE_TYPE_FLAG_IS_TOILET = (1uLL << 25),
|
|
RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS = (1uLL << 26), // whether or not vehicle colours can be set
|
|
RIDE_TYPE_FLAG_CHECK_FOR_STALLING = (1uLL << 27),
|
|
RIDE_TYPE_FLAG_HAS_TRACK = (1uLL << 28),
|
|
RIDE_TYPE_FLAG_ALLOW_EXTRA_TOWER_BASES = (1uLL << 29), // Only set by lift
|
|
RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR = (1uLL << 31),
|
|
|
|
RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK = (1uLL << 32),
|
|
RIDE_TYPE_FLAG_MUSIC_ON_DEFAULT = (1uLL << 33),
|
|
RIDE_TYPE_FLAG_ALLOW_MUSIC = (1uLL << 34),
|
|
RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE = (1uLL << 35), // Used by the Flying RC, Lay-down RC, Multi-dimension RC
|
|
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES = (1uLL << 36),
|
|
RIDE_TYPE_FLAG_HAS_ENTRANCE_EXIT = (1uLL << 37),
|
|
RIDE_TYPE_FLAG_ALLOW_MORE_VEHICLES_THAN_STATION_FITS = (1uLL << 38),
|
|
RIDE_TYPE_FLAG_HAS_AIR_TIME = (1uLL << 39),
|
|
RIDE_TYPE_FLAG_SINGLE_SESSION = (1uLL << 40),
|
|
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS = (1uLL << 41),
|
|
RIDE_TYPE_FLAG_ALLOW_CABLE_LIFT_HILL = (1uLL << 42),
|
|
RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER = (1uLL << 43),
|
|
RIDE_TYPE_FLAG_TRANSPORT_RIDE = (1uLL << 44),
|
|
RIDE_TYPE_FLAG_INTERESTING_TO_LOOK_AT = (1uLL << 45),
|
|
RIDE_TYPE_FLAG_SLIGHTLY_INTERESTING_TO_LOOK_AT = (1uLL << 46),
|
|
RIDE_TYPE_FLAG_START_CONSTRUCTION_INVERTED = (1uLL << 47), // This is only set on the Flying RC and its alternative type.
|
|
|
|
RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY = (1uLL << 48),
|
|
RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS = (1uLL << 49),
|
|
RIDE_TYPE_FLAG_IS_SUSPENDED = (1uLL << 50),
|
|
RIDE_TYPE_FLAG_HAS_LANDSCAPE_DOORS = (1uLL << 51),
|
|
RIDE_TYPE_FLAG_UP_INCLINE_REQUIRES_LIFT = (1uLL << 52),
|
|
RIDE_TYPE_FLAG_PEEP_CAN_USE_UMBRELLA = (1uLL << 53),
|
|
RIDE_TYPE_FLAG_IS_CASH_MACHINE = (1uLL << 54),
|
|
RIDE_TYPE_FLAG_HAS_ONE_STATION = (1uLL << 55),
|
|
RIDE_TYPE_FLAG_HAS_SEAT_ROTATION = (1uLL << 56),
|
|
RIDE_TYPE_FLAG_IS_FIRST_AID = (1uLL << 57),
|
|
RIDE_TYPE_FLAG_IS_MAZE = (1uLL << 58),
|
|
RIDE_TYPE_FLAG_IS_SPIRAL_SLIDE = (1uLL << 59),
|
|
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS = (1uLL << 60),
|
|
};
|
|
|
|
// Set on ride types that have a main colour, additional colour and support colour.
|
|
constexpr uint64_t RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS = RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN
|
|
| RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS;
|
|
// Set on _all_ roller coaster ride types, including the _ALT types used for constructing upside down.
|
|
constexpr uint64_t RIDE_TYPE_FLAGS_COMMON_COASTER = RIDE_TYPE_FLAG_HAS_G_FORCES | RIDE_TYPE_FLAG_HAS_DATA_LOGGING
|
|
| RIDE_TYPE_FLAG_HAS_DROPS | RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS | RIDE_TYPE_FLAG_PEEP_WILL_RIDE_AGAIN
|
|
| RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS | RIDE_TYPE_FLAG_CHECK_FOR_STALLING | RIDE_TYPE_FLAG_HAS_TRACK
|
|
| RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR | RIDE_TYPE_FLAG_ALLOW_MUSIC | RIDE_TYPE_FLAG_INTERESTING_TO_LOOK_AT
|
|
| RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS;
|
|
// Set on all roller coaster ride types, excluding the _ALT types used for constructing upside down.
|
|
constexpr uint64_t RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT = RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER | RIDE_TYPE_FLAG_HAS_AIR_TIME
|
|
| RIDE_TYPE_FLAG_HAS_ENTRANCE_EXIT;
|
|
|
|
// clang-format off
|
|
constexpr RideComponentName RideComponentNames[] =
|
|
{
|
|
{ STR_RIDE_COMPONENT_TRAIN, STR_RIDE_COMPONENT_TRAIN_PLURAL, STR_RIDE_COMPONENT_TRAIN_CAPITALISED, STR_RIDE_COMPONENT_TRAIN_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_TRAIN_COUNT, STR_RIDE_COMPONENT_TRAIN_COUNT_PLURAL, STR_RIDE_COMPONENT_TRAIN_NO },
|
|
{ STR_RIDE_COMPONENT_BOAT, STR_RIDE_COMPONENT_BOAT_PLURAL, STR_RIDE_COMPONENT_BOAT_CAPITALISED, STR_RIDE_COMPONENT_BOAT_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_BOAT_COUNT, STR_RIDE_COMPONENT_BOAT_COUNT_PLURAL, STR_RIDE_COMPONENT_BOAT_NO },
|
|
{ STR_RIDE_COMPONENT_TRACK, STR_RIDE_COMPONENT_TRACK_PLURAL, STR_RIDE_COMPONENT_TRACK_CAPITALISED, STR_RIDE_COMPONENT_TRACK_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_TRACK_COUNT, STR_RIDE_COMPONENT_TRACK_COUNT_PLURAL, STR_RIDE_COMPONENT_TRACK_NO },
|
|
{ STR_RIDE_COMPONENT_DOCKING_PLATFORM, STR_RIDE_COMPONENT_DOCKING_PLATFORM_PLURAL, STR_RIDE_COMPONENT_DOCKING_PLATFORM_CAPITALISED, STR_RIDE_COMPONENT_DOCKING_PLATFORM_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_DOCKING_PLATFORM_COUNT, STR_RIDE_COMPONENT_DOCKING_PLATFORM_COUNT_PLURAL, STR_RIDE_COMPONENT_DOCKING_PLATFORM_NO },
|
|
{ STR_RIDE_COMPONENT_STATION, STR_RIDE_COMPONENT_STATION_PLURAL, STR_RIDE_COMPONENT_STATION_CAPITALISED, STR_RIDE_COMPONENT_STATION_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_STATION_COUNT, STR_RIDE_COMPONENT_STATION_COUNT_PLURAL, STR_RIDE_COMPONENT_STATION_NO },
|
|
{ STR_RIDE_COMPONENT_CAR, STR_RIDE_COMPONENT_CAR_PLURAL, STR_RIDE_COMPONENT_CAR_CAPITALISED, STR_RIDE_COMPONENT_CAR_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_CAR_COUNT, STR_RIDE_COMPONENT_CAR_COUNT_PLURAL, STR_RIDE_COMPONENT_CAR_NO },
|
|
{ STR_RIDE_COMPONENT_BUILDING, STR_RIDE_COMPONENT_BUILDING_PLURAL, STR_RIDE_COMPONENT_BUILDING_CAPITALISED, STR_RIDE_COMPONENT_BUILDING_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_BUILDING_COUNT, STR_RIDE_COMPONENT_BUILDING_COUNT_PLURAL, STR_RIDE_COMPONENT_BUILDING_NO },
|
|
{ STR_RIDE_COMPONENT_STRUCTURE, STR_RIDE_COMPONENT_STRUCTURE_PLURAL, STR_RIDE_COMPONENT_STRUCTURE_CAPITALISED, STR_RIDE_COMPONENT_STRUCTURE_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_STRUCTURE_COUNT, STR_RIDE_COMPONENT_STRUCTURE_COUNT_PLURAL, STR_RIDE_COMPONENT_STRUCTURE_NO },
|
|
{ STR_RIDE_COMPONENT_SHIP, STR_RIDE_COMPONENT_SHIP_PLURAL, STR_RIDE_COMPONENT_SHIP_CAPITALISED, STR_RIDE_COMPONENT_SHIP_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_SHIP_COUNT, STR_RIDE_COMPONENT_SHIP_COUNT_PLURAL, STR_RIDE_COMPONENT_SHIP_NO },
|
|
{ STR_RIDE_COMPONENT_CABIN, STR_RIDE_COMPONENT_CABIN_PLURAL, STR_RIDE_COMPONENT_CABIN_CAPITALISED, STR_RIDE_COMPONENT_CABIN_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_CABIN_COUNT, STR_RIDE_COMPONENT_CABIN_COUNT_PLURAL, STR_RIDE_COMPONENT_CABIN_NO },
|
|
{ STR_RIDE_COMPONENT_WHEEL, STR_RIDE_COMPONENT_WHEEL_PLURAL, STR_RIDE_COMPONENT_WHEEL_CAPITALISED, STR_RIDE_COMPONENT_WHEEL_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_WHEEL_COUNT, STR_RIDE_COMPONENT_WHEEL_COUNT_PLURAL, STR_RIDE_COMPONENT_WHEEL_NO },
|
|
{ STR_RIDE_COMPONENT_RING, STR_RIDE_COMPONENT_RING_PLURAL, STR_RIDE_COMPONENT_RING_CAPITALISED, STR_RIDE_COMPONENT_RING_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_RING_COUNT, STR_RIDE_COMPONENT_RING_COUNT_PLURAL, STR_RIDE_COMPONENT_RING_NO },
|
|
{ STR_RIDE_COMPONENT_PLAYER, STR_RIDE_COMPONENT_PLAYER_PLURAL, STR_RIDE_COMPONENT_PLAYER_CAPITALISED, STR_RIDE_COMPONENT_PLAYER_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_PLAYER_COUNT, STR_RIDE_COMPONENT_PLAYER_COUNT_PLURAL, STR_RIDE_COMPONENT_PLAYER_NO },
|
|
{ STR_RIDE_COMPONENT_COURSE, STR_RIDE_COMPONENT_COURSE_PLURAL, STR_RIDE_COMPONENT_COURSE_CAPITALISED, STR_RIDE_COMPONENT_COURSE_CAPITALISED_PLURAL, STR_RIDE_COMPONENT_COURSE_COUNT, STR_RIDE_COMPONENT_COURSE_COUNT_PLURAL, STR_RIDE_COMPONENT_COURSE_NO },
|
|
};
|
|
// clang-format on
|
|
|
|
constexpr std::string_view MUSIC_OBJECT_DODGEMS = "rct2.music.dodgems";
|
|
constexpr std::string_view MUSIC_OBJECT_EGYPTIAN = "rct2.music.egyptian";
|
|
constexpr std::string_view MUSIC_OBJECT_FAIRGROUND = "rct2.music.fairground";
|
|
constexpr std::string_view MUSIC_OBJECT_GENTLE = "rct2.music.gentle";
|
|
constexpr std::string_view MUSIC_OBJECT_HORROR = "rct2.music.horror";
|
|
constexpr std::string_view MUSIC_OBJECT_PIRATE = "rct2.music.pirate";
|
|
constexpr std::string_view MUSIC_OBJECT_ROCK_1 = "rct2.music.rock1";
|
|
constexpr std::string_view MUSIC_OBJECT_ROCK_2 = "rct2.music.rock2";
|
|
constexpr std::string_view MUSIC_OBJECT_ROCK_3 = "rct2.music.rock3";
|
|
constexpr std::string_view MUSIC_OBJECT_SUMMER = "rct2.music.summer";
|
|
constexpr std::string_view MUSIC_OBJECT_TECHNO = "rct2.music.techno";
|
|
constexpr std::string_view MUSIC_OBJECT_WATER = "rct2.music.water";
|
|
constexpr std::string_view MUSIC_OBJECT_WILD_WEST = "rct2.music.wildwest";
|
|
|
|
constexpr const RideComponentName& GetRideComponentName(const RideComponentType type)
|
|
{
|
|
return RideComponentNames[EnumValue(type)];
|
|
}
|
|
|
|
constexpr uint64_t AllRideModesAvailable = EnumsToFlags(
|
|
RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle,
|
|
RideMode::PoweredLaunchPasstrough, RideMode::Shuttle, RideMode::Normal, RideMode::BoatHire, RideMode::UpwardLaunch,
|
|
RideMode::RotatingLift, RideMode::StationToStation, RideMode::SingleRidePerAdmission, RideMode::UnlimitedRidesPerAdmission,
|
|
RideMode::Maze, RideMode::Race, RideMode::Dodgems, RideMode::Swing, RideMode::ShopStall, RideMode::Rotation,
|
|
RideMode::ForwardRotation, RideMode::BackwardRotation, RideMode::FilmAvengingAviators, RideMode::MouseTails3DFilm,
|
|
RideMode::SpaceRings, RideMode::Beginners, RideMode::LimPoweredLaunch, RideMode::FilmThrillRiders,
|
|
RideMode::StormChasers3DFilm, RideMode::SpaceRaiders3DFilm, RideMode::Intense, RideMode::Berserk, RideMode::HauntedHouse,
|
|
RideMode::Circus, RideMode::DownwardLaunch, RideMode::CrookedHouse, RideMode::FreefallDrop, RideMode::PoweredLaunch,
|
|
RideMode::PoweredLaunchBlockSectioned);
|
|
|
|
extern const CarEntry CableLiftVehicle;
|
|
|
|
extern const uint16_t RideFilmLength[3];
|
|
|
|
extern const StringId RideModeNames[EnumValue(RideMode::Count)];
|
|
|
|
// clang-format off
|
|
constexpr RideTypeDescriptor DummyRTD =
|
|
{
|
|
.Category = RIDE_CATEGORY_NONE,
|
|
.StartTrackPiece = TrackElemType::EndStation,
|
|
.TrackPaintFunctions = {},
|
|
.InvertedTrackPaintFunctions = {},
|
|
.Flags = 0,
|
|
.RideModes = EnumsToFlags(RideMode::ContinuousCircuit),
|
|
.DefaultMode = RideMode::ContinuousCircuit,
|
|
.OperatingSettings = { 0, 0, 0, 0, 0, 0 },
|
|
.Naming = { STR_UNKNOWN_RIDE, STR_RIDE_DESCRIPTION_UNKNOWN },
|
|
.NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station },
|
|
.EnumName = "(INVALID)",
|
|
.AvailableBreakdowns = 0,
|
|
.Heights = { 12, 64, 0, 0, },
|
|
.MaxMass = 255,
|
|
.LiftData = { OpenRCT2::Audio::SoundId::Null, 5, 5 },
|
|
.RatingsMultipliers = { 0, 0, 0 },
|
|
.UpkeepCosts = { 50, 1, 0, 0, 0, 0 },
|
|
.BuildCosts = { 0.00_GBP, 0.00_GBP, 1 },
|
|
.DefaultPrices = { 20, 20 },
|
|
.DefaultMusic = MUSIC_OBJECT_GENTLE,
|
|
.PhotoItem = ShopItem::Photo,
|
|
.BonusValue = 0,
|
|
.ColourPresets = DEFAULT_FLAT_RIDE_COLOUR_PRESET,
|
|
.ColourPreview = { static_cast<uint32_t>(SPR_NONE), static_cast<uint32_t>(SPR_NONE) },
|
|
.ColourKey = RideColourKey::Ride,
|
|
.Name = "invalid",
|
|
.RatingsData =
|
|
{
|
|
RatingsCalculationType::FlatRide,
|
|
{ RIDE_RATING(1, 00), RIDE_RATING(1, 00), RIDE_RATING(1, 00) },
|
|
1,
|
|
-1,
|
|
false,
|
|
{
|
|
{ RatingsModifierType::NoModifier, 0, 0, 0, 0 },
|
|
},
|
|
},
|
|
.UpdateRotating = UpdateRotatingDefault,
|
|
.LightFXAddLightsMagicVehicle = nullptr,
|
|
.StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel,
|
|
.DesignCreateMode = TrackDesignCreateMode::Default,
|
|
.MusicUpdateFunction = DefaultMusicUpdate,
|
|
.Classification = RideClassification::Ride,
|
|
.UpdateLeaveEntrance = PeepUpdateRideLeaveEntranceDefault,
|
|
};
|
|
// clang-format on
|
|
|
|
constexpr const RideTypeDescriptor& GetRideTypeDescriptor(ObjectEntryIndex rideType)
|
|
{
|
|
if (rideType >= std::size(RideTypeDescriptors))
|
|
return DummyRTD;
|
|
|
|
return RideTypeDescriptors[rideType];
|
|
}
|
|
|
|
constexpr bool RideTypeIsValid(ObjectEntryIndex rideType)
|
|
{
|
|
return rideType < std::size(RideTypeDescriptors);
|
|
}
|
|
|
|
bool IsTrackEnabled(int32_t trackFlagIndex);
|
|
void UpdateEnabledRidePieces(TrackDrawerDescriptor trackDrawerDescriptor);
|
|
void UpdateDisabledRidePieces(const RideTrackGroup& res);
|
|
|
|
TrackDrawerDescriptor getTrackDrawerDescriptor(const RideTypeDescriptor& rtd, bool isInverted);
|
|
TrackDrawerEntry getTrackDrawerEntry(const RideTypeDescriptor& rtd, bool isInverted = false, bool isCovered = false);
|