1 /*****************************************************************************
2  * Copyright (c) 2014-2020 OpenRCT2 developers
3  *
4  * For a complete list of all authors, please refer to contributors.md
5  * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6  *
7  * OpenRCT2 is licensed under the GNU General Public License version 3.
8  *****************************************************************************/
9 
10 #pragma once
11 
12 #define TRACK_COLOUR_PRESETS(...)                                                                                              \
13     {                                                                                                                          \
14         static_cast<uint8_t>(std::size<TrackColour>({ __VA_ARGS__ })),                                                         \
15         {                                                                                                                      \
16             __VA_ARGS__                                                                                                        \
17         }                                                                                                                      \
18     }
19 #define DEFAULT_FLAT_RIDE_COLOUR_PRESET TRACK_COLOUR_PRESETS({ COLOUR_BRIGHT_RED, COLOUR_LIGHT_BLUE, COLOUR_YELLOW })
20 #define DEFAULT_STALL_COLOUR_PRESET TRACK_COLOUR_PRESETS({ COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED })
21 
22 #include "../audio/audio.h"
23 #include "../common.h"
24 #include "../localisation/StringIds.h"
25 #include "../sprites.h"
26 #include "../util/Util.h"
27 #include "Ride.h"
28 #include "ShopItem.h"
29 #include "Track.h"
30 #include "TrackPaint.h"
31 
32 enum class ResearchCategory : uint8_t;
33 
34 using ride_ratings_calculation = void (*)(Ride* ride, RideRatingUpdateState& state);
35 
36 struct RideComponentName
37 {
38     rct_string_id singular;
39     rct_string_id plural;
40     rct_string_id capitalised;
41     rct_string_id capitalised_plural;
42     rct_string_id count;
43     rct_string_id count_plural;
44     rct_string_id number;
45 };
46 
47 enum class RideComponentType
48 {
49     Train,
50     Boat,
51     Track,
52     DockingPlatform,
53     Station,
54     Car,
55     Building,
56     Structure,
57     Ship,
58     Cabin,
59     Wheel,
60     Ring,
61     Player,
62     Course,
63     Count
64 };
65 
66 enum class RideColourKey : uint8_t
67 {
68     Ride,
69     Food,
70     Drink,
71     Shop,
72     InfoKiosk,
73     FirstAid,
74     CashMachine,
75     Toilets
76 };
77 
78 struct RideNameConvention
79 {
80     RideComponentType vehicle;
81     RideComponentType structure;
82     RideComponentType station;
83 };
84 
85 struct RideBuildCost
86 {
87     uint16_t TrackPrice;
88     uint16_t SupportPrice;
89     uint8_t PriceEstimateMultiplier;
90 };
91 
92 struct RideHeights
93 {
94     uint8_t MaxHeight;
95     uint8_t ClearanceHeight;
96     int8_t VehicleZOffset;
97     uint8_t PlatformHeight;
98 };
99 
100 struct rct_ride_lift_data
101 {
102     OpenRCT2::Audio::SoundId sound_id;
103     uint8_t minimum_speed;
104     uint8_t maximum_speed;
105 };
106 
107 struct RideColourPreview
108 {
109     uint32_t Track;
110     uint32_t Supports;
111 };
112 
113 struct UpkeepCostsDescriptor
114 {
115     /**
116      * Data about ride running costs. This is widely adjusted by the upkeep
117      * function, so values that don't make much sense here (a roller coaster having
118      * cheaper upkeep than a car ride) are fixed later on.
119      *
120      * Data generation script: https://gist.github.com/kevinburke/6bcf4a8fcc95faad7bac
121      */
122     uint8_t BaseCost;
123     /** rct2: 0x0097E3AC */
124     uint8_t TrackLengthMultiplier;
125     uint8_t CostPerTrackPiece;
126     /** rct2: 0x0097E3B4 */
127     uint8_t CostPerTrain;
128     /** rct2: 0x0097E3B6 */
129     uint8_t CostPerCar;
130     /** rct2: 0x0097E3B8 */
131     uint8_t CostPerStation;
132 };
133 
134 struct RideTypeDescriptor
135 {
136     uint8_t AlternateType;
137     uint8_t Category;
138     /** rct2: 0x0097C468 (0 - 31) and 0x0097C5D4 (32 - 63) */
139     uint64_t EnabledTrackPieces;
140     // Pieces that this ride type _can_ draw, but are disabled because their vehicles lack the relevant sprites,
141     // or because they are not realistic for the ride type (e.g. LIM boosters in Mini Roller Coasters).
142     uint64_t ExtraTrackPieces;
143     uint64_t CoveredTrackPieces;
144     /** rct2: 0x0097CC68 */
145     uint64_t StartTrackPiece;
146     TRACK_PAINT_FUNCTION_GETTER TrackPaintFunction;
147     uint64_t Flags;
148     /** rct2: 0x0097C8AC */
149     uint64_t RideModes;
150     RideMode DefaultMode;
151     /** rct2: 0x0097CF40 */
152     RideOperatingSettings OperatingSettings;
153     RideNaming Naming;
154     RideNameConvention NameConvention;
155     const char* EnumName;
156     uint8_t AvailableBreakdowns;
157     /** rct2: 0x0097D218 */
158     RideHeights Heights;
159     uint8_t MaxMass;
160     /** rct2: 0x0097D7C8, 0x0097D7C9, 0x0097D7CA */
161     rct_ride_lift_data LiftData;
162     // rct2: 0x0097E050
163     ride_ratings_calculation RatingsCalculationFunction;
164     // rct2: 0x0097CD1E
165     RatingTuple RatingsMultipliers;
166     UpkeepCostsDescriptor UpkeepCosts;
167     // rct2: 0x0097DD78
168     RideBuildCost BuildCosts;
169     money16 DefaultPrices[NUM_SHOP_ITEMS_PER_RIDE];
170     std::string_view DefaultMusic;
171     /** rct2: 0x0097D7CB */
172     ShopItemIndex PhotoItem;
173     /** rct2: 0x0097D21E */
174     uint8_t BonusValue;
175     track_colour_preset_list ColourPresets;
176     RideColourPreview ColourPreview;
177     RideColourKey ColourKey;
178 
179     bool HasFlag(uint64_t flag) const;
180     uint64_t GetAvailableTrackPieces() const;
181     bool SupportsTrackPiece(const uint64_t trackPiece) const;
182     ResearchCategory GetResearchCategory() const;
183 };
184 
185 #ifdef _WIN32
186 #    define SET_FIELD(fieldname, ...) __VA_ARGS__
187 #else
188 #    define SET_FIELD(fieldname, ...) .fieldname = __VA_ARGS__
189 #endif
190 
191 extern const RideTypeDescriptor RideTypeDescriptors[RIDE_TYPE_COUNT];
192 
193 enum
194 {
195     RIDE_TYPE_NO_ALTERNATIVES = 0,
196     RIDE_TYPE_ALTERNATIVE_TRACK_PIECES = 1, // Dinghy slide and Water Coaster
197     RIDE_TYPE_ALTERNATIVE_TRACK_TYPE = 2,   // Flying RC, Lay-down RC, Multi-dimension RC
198 };
199 
200 enum ride_type_flags : uint64_t
201 {
202     RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN = (1ULL << 0),
203     RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL = (1ULL << 1),
204     RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS = (1ULL << 2),
205     RIDE_TYPE_FLAG_HAS_SINGLE_PIECE_STATION = (1ULL << 3), // Set by flat rides, tower rides and shops/stalls.
206     RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION = (1ULL << 4),
207     RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS = (1ULL << 5),
208     RIDE_TYPE_FLAG_TRACK_MUST_BE_ON_WATER = (1ULL << 6), // used only by boat Hire and submarine ride
209     RIDE_TYPE_FLAG_HAS_G_FORCES = (1ULL << 7),
210     RIDE_TYPE_FLAG_CANNOT_HAVE_GAPS = (1ULL << 8), // used by rides that can't have gaps, like those with a vertical tower, such
211                                                    // as the observation tower
212     RIDE_TYPE_FLAG_HAS_DATA_LOGGING = (1ULL << 9),
213     RIDE_TYPE_FLAG_HAS_DROPS = (1ULL << 10),
214     RIDE_TYPE_FLAG_NO_TEST_MODE = (1ULL << 11),
215     RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES = (1ULL << 12), // used by rides with two varieties, like the u and o
216                                                                      // shapes of the dinghy slide and the dry and submerged
217                                                                      // track of the water coaster
218     RIDE_TYPE_FLAG_NO_VEHICLES = (1ULL << 13),                       // used only by maze, spiral slide and shops
219     RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS = (1ULL << 14),
220     RIDE_TYPE_FLAG_HAS_NO_TRACK = (1ULL << 15),
221     RIDE_TYPE_FLAG_VEHICLE_IS_INTEGRAL = (1ULL << 16), // Set by flat rides where the vehicle is integral to the structure, like
222     // Merry-go-round and swinging ships. (Contrast with rides like dodgems.)
223     RIDE_TYPE_FLAG_IS_SHOP = (1ULL << 17),
224     RIDE_TYPE_FLAG_TRACK_NO_WALLS = (1ULL << 18), // if set, wall scenery can not share a tile with the ride's track
225     RIDE_TYPE_FLAG_FLAT_RIDE = (1ULL << 19),
226     RIDE_TYPE_FLAG_PEEP_WILL_RIDE_AGAIN = (1ULL << 20), // whether or not guests will go on the ride again if they liked it
227                                                         // (this is
228     // usually applied to everything apart from transport rides)
229     RIDE_TYPE_FLAG_PEEP_SHOULD_GO_INSIDE_FACILITY = (1ULL << 21), // used by toilets and first aid to mark that peep should go
230                                                                   // inside the building (rather than 'buying' at the counter)
231     RIDE_TYPE_FLAG_IN_RIDE = (1ULL << 22),                        // peeps are "IN" (ride) rather than "ON" (ride)
232     RIDE_TYPE_FLAG_SELLS_FOOD = (1ULL << 23),
233     RIDE_TYPE_FLAG_SELLS_DRINKS = (1ULL << 24),
234     RIDE_TYPE_FLAG_IS_TOILET = (1ULL << 25),
235     RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS = (1ULL << 26), // whether or not vehicle colours can be set
236     RIDE_TYPE_FLAG_CHECK_FOR_STALLING = (1ULL << 27),
237     RIDE_TYPE_FLAG_HAS_TRACK = (1ULL << 28),
238     RIDE_TYPE_FLAG_ALLOW_EXTRA_TOWER_BASES = (1ULL << 29), // Only set by lift
239     RIDE_TYPE_FLAG_HAS_LARGE_CURVES = (1ULL << 30),        // whether the ride supports large (45 degree turn) curves
240     RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR = (1ULL << 31),
241 
242     RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK = (1ULL << 32),
243     RIDE_TYPE_FLAG_MUSIC_ON_DEFAULT = (1ULL << 33),
244     RIDE_TYPE_FLAG_ALLOW_MUSIC = (1ULL << 34),
245     RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE = (1ULL << 35), // Used by the Flying RC, Lay-down RC, Multi-dimension RC
246     RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES = (1ULL << 36),
247     RIDE_TYPE_FLAG_HAS_ENTRANCE_EXIT = (1ULL << 37),
248     RIDE_TYPE_FLAG_ALLOW_MORE_VEHICLES_THAN_STATION_FITS = (1ULL << 38),
249     RIDE_TYPE_FLAG_HAS_AIR_TIME = (1ULL << 39),
250     RIDE_TYPE_FLAG_SINGLE_SESSION = (1ULL << 40),
251     RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS = (1ULL << 41),
252     RIDE_TYPE_FLAG_ALLOW_CABLE_LIFT_HILL = (1ULL << 42),
253     RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER = (1ULL << 43),
254     RIDE_TYPE_FLAG_TRANSPORT_RIDE = (1ULL << 44),
255     RIDE_TYPE_FLAG_INTERESTING_TO_LOOK_AT = (1ULL << 45),
256     RIDE_TYPE_FLAG_SLIGHTLY_INTERESTING_TO_LOOK_AT = (1ULL << 46),
257     RIDE_TYPE_FLAG_START_CONSTRUCTION_INVERTED = (1ULL << 47), // This is only set on the Flying RC and its alternative type.
258 
259     RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY = (1ULL << 48),
260     RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS = (1ULL << 49),
261     RIDE_TYPE_FLAG_IS_SUSPENDED = (1ULL << 50),
262     RIDE_TYPE_FLAG_HAS_LANDSCAPE_DOORS = (1ULL << 51),
263 };
264 
265 // Set on ride types that have a main colour, additional colour and support colour.
266 constexpr const uint64_t RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS = RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN
267     | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS;
268 // Set on _all_ roller coaster ride types, including the _ALT types used for constructing upside down.
269 constexpr const uint64_t RIDE_TYPE_FLAGS_COMMON_COASTER = RIDE_TYPE_FLAG_HAS_G_FORCES | RIDE_TYPE_FLAG_HAS_DATA_LOGGING
270     | RIDE_TYPE_FLAG_HAS_DROPS | RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS | RIDE_TYPE_FLAG_PEEP_WILL_RIDE_AGAIN
271     | RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS | RIDE_TYPE_FLAG_CHECK_FOR_STALLING | RIDE_TYPE_FLAG_HAS_TRACK
272     | RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR | RIDE_TYPE_FLAG_ALLOW_MUSIC | RIDE_TYPE_FLAG_INTERESTING_TO_LOOK_AT
273     | RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS;
274 // Set on all roller coaster ride types, excluding the _ALT types used for constructing upside down.
275 constexpr const uint64_t RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT = RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER
276     | RIDE_TYPE_FLAG_HAS_AIR_TIME | RIDE_TYPE_FLAG_HAS_ENTRANCE_EXIT;
277 
278 // clang-format off
279 constexpr const RideComponentName RideComponentNames[] =
280 {
281     { 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 },
282     { 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 },
283     { 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 },
284     { 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 },
285     { 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 },
286     { 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 },
287     { 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 },
288     { 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 },
289     { 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 },
290     { 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 },
291     { 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 },
292     { 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 },
293     { 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 },
294     { 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 },
295 };
296 // clang-format on
297 
298 constexpr std::string_view MUSIC_OBJECT_DODGEMS = "rct2.music.dodgems";
299 constexpr std::string_view MUSIC_OBJECT_EGYPTIAN = "rct2.music.egyptian";
300 constexpr std::string_view MUSIC_OBJECT_FAIRGROUND = "rct2.music.fairground";
301 constexpr std::string_view MUSIC_OBJECT_GENTLE = "rct2.music.gentle";
302 constexpr std::string_view MUSIC_OBJECT_HORROR = "rct2.music.horror";
303 constexpr std::string_view MUSIC_OBJECT_PIRATE = "rct2.music.pirate";
304 constexpr std::string_view MUSIC_OBJECT_ROCK_1 = "rct2.music.rock1";
305 constexpr std::string_view MUSIC_OBJECT_ROCK_2 = "rct2.music.rock2";
306 constexpr std::string_view MUSIC_OBJECT_ROCK_3 = "rct2.music.rock3";
307 constexpr std::string_view MUSIC_OBJECT_SUMMER = "rct2.music.summer";
308 constexpr std::string_view MUSIC_OBJECT_TECHNO = "rct2.music.techno";
309 constexpr std::string_view MUSIC_OBJECT_WATER = "rct2.music.water";
310 constexpr std::string_view MUSIC_OBJECT_WILD_WEST = "rct2.music.wildwest";
311 
GetRideComponentName(const RideComponentType type)312 constexpr const RideComponentName& GetRideComponentName(const RideComponentType type)
313 {
314     return RideComponentNames[EnumValue(type)];
315 }
316 
317 constexpr const uint64_t AllRideModesAvailable = EnumsToFlags(
318     RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle,
319     RideMode::PoweredLaunchPasstrough, RideMode::Shuttle, RideMode::Normal, RideMode::BoatHire, RideMode::UpwardLaunch,
320     RideMode::RotatingLift, RideMode::StationToStation, RideMode::SingleRidePerAdmission, RideMode::UnlimitedRidesPerAdmission,
321     RideMode::Maze, RideMode::Race, RideMode::Dodgems, RideMode::Swing, RideMode::ShopStall, RideMode::Rotation,
322     RideMode::ForwardRotation, RideMode::BackwardRotation, RideMode::FilmAvengingAviators, RideMode::MouseTails3DFilm,
323     RideMode::SpaceRings, RideMode::Beginners, RideMode::LimPoweredLaunch, RideMode::FilmThrillRiders,
324     RideMode::StormChasers3DFilm, RideMode::SpaceRaiders3DFilm, RideMode::Intense, RideMode::Berserk, RideMode::HauntedHouse,
325     RideMode::Circus, RideMode::DownwardLaunch, RideMode::CrookedHouse, RideMode::FreefallDrop, RideMode::PoweredLaunch,
326     RideMode::PoweredLaunchBlockSectioned);
327 
328 extern const rct_ride_entry_vehicle CableLiftVehicle;
329 
330 extern const uint16_t RideFilmLength[3];
331 
332 extern const rct_string_id RideModeNames[static_cast<uint8_t>(RideMode::Count)];
333 
334 // clang-format off
335 constexpr const RideTypeDescriptor DummyRTD =
336 {
337     SET_FIELD(AlternateType, RIDE_TYPE_NULL),
338     SET_FIELD(Category, RIDE_CATEGORY_NONE),
339     SET_FIELD(EnabledTrackPieces, 0),
340     SET_FIELD(ExtraTrackPieces, 0),
341     SET_FIELD(CoveredTrackPieces, 0),
342     SET_FIELD(StartTrackPiece, TrackElemType::EndStation),
343     SET_FIELD(TrackPaintFunction, nullptr),
344     SET_FIELD(Flags, 0),
345     SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit)),
346     SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
347     SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 0, 0 }),
348     SET_FIELD(Naming, { STR_UNKNOWN_RIDE, STR_RIDE_DESCRIPTION_UNKNOWN }),
349     SET_FIELD(NameConvention, { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }),
350     SET_FIELD(EnumName, "(INVALID)"),
351     SET_FIELD(AvailableBreakdowns, 0),
352     SET_FIELD(Heights, { 12, 64, 0, 0, }),
353     SET_FIELD(MaxMass, 255),
354     SET_FIELD(LiftData, { OpenRCT2::Audio::SoundId::Null, 5, 5 }),
355     SET_FIELD(RatingsCalculationFunction, nullptr),
356     SET_FIELD(RatingsMultipliers, { 0, 0, 0 }),
357     SET_FIELD(UpkeepCosts, { 50, 1, 0, 0, 0, 0 }),
358     SET_FIELD(BuildCosts, { 0, 0, 1 }),
359     SET_FIELD(DefaultPrices, { 20, 20 }),
360     SET_FIELD(DefaultMusic, MUSIC_OBJECT_GENTLE),
361     SET_FIELD(PhotoItem, ShopItem::Photo),
362     SET_FIELD(BonusValue, 0),
363     SET_FIELD(ColourPresets, DEFAULT_FLAT_RIDE_COLOUR_PRESET),
364     SET_FIELD(ColourPreview, { static_cast<uint32_t>(SPR_NONE), static_cast<uint32_t>(SPR_NONE) }),
365     SET_FIELD(ColourKey, RideColourKey::Ride)
366 };
367 // clang-format on
368 
GetRideTypeDescriptor(ObjectEntryIndex rideType)369 constexpr const RideTypeDescriptor& GetRideTypeDescriptor(ObjectEntryIndex rideType)
370 {
371     if (rideType >= std::size(RideTypeDescriptors))
372         return DummyRTD;
373 
374     return RideTypeDescriptors[rideType];
375 }
376 
RideTypeIsValid(ObjectEntryIndex rideType)377 constexpr bool RideTypeIsValid(ObjectEntryIndex rideType)
378 {
379     return rideType < std::size(RideTypeDescriptors);
380 }
381