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 #include "ScenarioSources.h" 11 12 #include "../core/Guard.hpp" 13 #include "../core/String.hpp" 14 #include "Scenario.h" 15 #include "ScenarioRepository.h" 16 17 #include <iterator> 18 19 namespace ScenarioSources 20 { 21 struct ScenarioAlias 22 { 23 const utf8* Original; 24 const utf8* Alternative; 25 }; 26 27 struct ScenarioTitleDescriptor 28 { 29 const uint8_t Id; 30 const utf8* Title; 31 const uint8_t Category; 32 }; 33 34 #pragma region Scenario Data 35 36 // clang-format off 37 static constexpr const ScenarioAlias ScenarioAliases[] = 38 { 39 // UK - US differences: 40 { "Katie's Dreamland", "Katie's World" }, 41 { "Pokey Park", "Dinky Park" }, 42 { "White Water Park", "Aqua Park" }, 43 { "Mystic Mountain", "Mothball Mountain" }, 44 { "Paradise Pier", "Big Pier" }, 45 { "Paradise Pier 2", "Big Pier 2" }, 46 { "Haunted Harbour", "Haunted Harbor" }, 47 { "Mythological - Cradle of Civilisation", "Mythological - Cradle of Civilization" }, 48 49 // RCT1 pack by RCTScenarioLover has a mistake: 50 { "Geoffrey Gardens", "Geoffery Gardens" }, 51 // RCT1 pack by Crappage uses park name to identify Utopia Park, instead of scenario list name: 52 { "Utopia Park", "Utopia" }, 53 54 // CD Projekt Polish Edition 55 { "Alpine Adventures", "Górska przygoda" }, 56 { "Amity Airfield", "Lotnisko Pogięcie" }, 57 { "Botany Breakers", "Wyspa Odludna" }, 58 { "Bumbly Bazaar", "Gwarne targowisko" }, 59 { "Crazy Castle", "Zwariowany zamek" }, 60 { "Dusty Greens", "Zapiaszczone Dołki" }, 61 { "Electric Fields", "Pola elektryczne" }, 62 { "Extreme Heights", "Ekstremalne wysokości" }, 63 { "Factory Capers", "300% normy" }, 64 { "Fungus Woods", "Grzybowe Lasy" }, 65 { "Ghost Town", "Miasto-widmo" }, 66 { "Gravity Gardens", "Ogrody Grawitacji" }, 67 { "Infernal Views", "Piekielny widok" }, 68 { "Lucky Lake", "Jezioro Szczęściarzy" }, 69 { "Rainbow Summit", "Tęczowy Szczyt" }, 70 71 { "Six Flags Belgium", "\"Sześć Flag\" - Belgia" }, 72 { "Six Flags Holland", "\"Sześć Flag\" - Holandia" }, 73 { "Six Flags Magic Mountain", "Czarodziejska góra \"Sześciu Flag\"" }, 74 { "Six Flags Great Adventure", "\"Sześć Flag\" - wielka przygoda" }, 75 { "Six Flags over Texas", "\"Sześć Flag nad Teksasem\"" }, 76 { "Build your own Six Flags Belgium", "Wybuduj własny park \"Sześć Flag\" - Belgia" }, 77 { "Build your own Six Flags Holland", "Wybuduj własny park \"Sześć Flag\" - Holandia" }, 78 { "Build your own Six Flags Magic Mountain", "Wybuduj własny park czarodziejska góra \"Sześciu Flag\"" }, 79 { "Build your own Six Flags Great Adventure", "Wybuduj własny park \"Sześć Flag\" - wielka przygoda" }, 80 { "Build your own Six Flags over Texas", "Wybuduj własny park \"Sześć Flag nad Teksasem\"" }, 81 { "Build your own Six Flags Park", "Wybuduj własny park \"Sześć Flag\"" }, 82 83 { "Africa - African Diamond Mine", "Afryka - kopalnia diamentów" }, 84 { "Africa - Oasis", "Afryka - oaza" }, 85 { "Africa - Victoria Falls", "Afryka - Wodospad Wiktorii" }, 86 { "Antarctic - Ecological Salvage", "Antarktyka - utylizacja" }, 87 { "Asia - Great Wall of China Tourism Enhancement", "Azja - rozwój turystyki wokół Wielkiego Muru Chińskiego" }, 88 { "Asia - Japanese Coastal Reclaim", "Azja - odzysk japońskiego wybrzeża" }, 89 { "Asia - Maharaja Palace", "Azja - pałac maharadży" }, 90 { "Australasia - Ayers Rock", "Australazja - Ayers Rock" }, 91 { "Australasia - Fun at the beach", "Australazja - zabawa na plaży" }, 92 { "Europe - European Cultural Festival", "Europa - Europejski Festiwal Kulturalny" }, 93 { "Europe - Renovation", "Europa - odbudowa" }, 94 { "N. America - Extreme Hawaiian Island", "Ameryka Płn. - ekstremalne Hawaje" }, 95 { "North America - Grand Canyon", "Ameryka Płn. - Wielki Kanion" }, 96 { "North America - Rollercoaster Heaven", "Ameryka Płn. - raj kolejek górskich" }, 97 { "South America - Inca Lost City", "Ameryka Płd. - zaginione miasto Inków" }, 98 { "South America - Rain Forest Plateau", "Ameryka Płd. - tropikalny płaskowyż" }, 99 { "South America - Rio Carnival", "Ameryka Płd. - karnawał w Rio" }, 100 101 { "Dark Age - Castle", "Mroczne Wieki - zamek" }, 102 { "Dark Age - Robin Hood", "Mroczne Wieki - Robin Hood" }, 103 { "Future - First Encounters", "Przyszłość - pierwsze spotkania" }, 104 { "Future - Future World", "Przyszłość - świat przyszłości" }, 105 { "Mythological - Animatronic Film Set", "Mitologia - mechaniczny plan filmowy" }, 106 { "Mythological - Cradle of Civilisation", "Mitologia - kołyska cywilizacji" }, 107 { "Prehistoric - After the Asteroid", "Prehistoria - po asteroidzie" }, 108 { "Prehistoric - Jurassic Safari", "Prehistoria - jurajskie safari" }, 109 { "Prehistoric - Stone Age", "Prehistoria - epoka kamienna" }, 110 { "Roaring Twenties - Prison Island", "Ryczące Dwudziestki - wyspa więzienna" }, 111 { "Roaring Twenties - Schneider Cup", "Ryczące Dwudziestki - puchar Schneidera" }, 112 { "Roaring Twenties - Skyscrapers", "Ryczące Dwudziestki - drapacze chmur" }, 113 { "Rock 'n' Roll - Flower Power", "Rock 'n' Roll - dzieci kwiaty" }, 114 // Skipping Rock 'n' Roll - Rock 'n' Roll as that name matches exactly. 115 116 }; 117 118 // RCT 119 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT1[] = 120 { 121 { SC_FOREST_FRONTIERS, "Forest Frontiers", SCENARIO_CATEGORY_BEGINNER }, 122 { SC_DYNAMITE_DUNES, "Dynamite Dunes", SCENARIO_CATEGORY_BEGINNER }, 123 { SC_LEAFY_LAKE, "Leafy Lake", SCENARIO_CATEGORY_BEGINNER }, 124 { SC_DIAMOND_HEIGHTS, "Diamond Heights", SCENARIO_CATEGORY_BEGINNER }, 125 { SC_EVERGREEN_GARDENS, "Evergreen Gardens", SCENARIO_CATEGORY_BEGINNER }, 126 { SC_BUMBLY_BEACH, "Bumbly Beach", SCENARIO_CATEGORY_BEGINNER }, 127 { SC_TRINITY_ISLANDS, "Trinity Islands", SCENARIO_CATEGORY_CHALLENGING }, 128 { SC_KATIES_DREAMLAND, "Katie's Dreamland", SCENARIO_CATEGORY_CHALLENGING }, 129 { SC_POKEY_PARK, "Pokey Park", SCENARIO_CATEGORY_CHALLENGING }, 130 { SC_WHITE_WATER_PARK, "White Water Park", SCENARIO_CATEGORY_CHALLENGING }, 131 { SC_MILLENNIUM_MINES, "Millennium Mines", SCENARIO_CATEGORY_CHALLENGING }, 132 { SC_KARTS_COASTERS, "Karts & Coasters", SCENARIO_CATEGORY_CHALLENGING }, 133 { SC_MELS_WORLD, "Mel's World", SCENARIO_CATEGORY_CHALLENGING }, 134 { SC_MYSTIC_MOUNTAIN, "Mystic Mountain", SCENARIO_CATEGORY_CHALLENGING }, 135 { SC_PACIFIC_PYRAMIDS, "Pacific Pyramids", SCENARIO_CATEGORY_CHALLENGING }, 136 { SC_CRUMBLY_WOODS, "Crumbly Woods", SCENARIO_CATEGORY_CHALLENGING }, 137 { SC_PARADISE_PIER, "Paradise Pier", SCENARIO_CATEGORY_CHALLENGING }, 138 { SC_LIGHTNING_PEAKS, "Lightning Peaks", SCENARIO_CATEGORY_EXPERT }, 139 { SC_IVORY_TOWERS, "Ivory Towers", SCENARIO_CATEGORY_EXPERT }, 140 { SC_RAINBOW_VALLEY, "Rainbow Valley", SCENARIO_CATEGORY_EXPERT }, 141 { SC_THUNDER_ROCK, "Thunder Rock", SCENARIO_CATEGORY_EXPERT }, 142 { SC_MEGA_PARK, "Mega Park", SCENARIO_CATEGORY_OTHER }, 143 }; 144 145 // RCT: Added Attractions 146 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT1AA[] = 147 { 148 { SC_WHISPERING_CLIFFS, "Whispering Cliffs", SCENARIO_CATEGORY_BEGINNER }, 149 { SC_THREE_MONKEYS_PARK, "Three Monkeys Park", SCENARIO_CATEGORY_BEGINNER }, 150 { SC_CANARY_MINES, "Canary Mines", SCENARIO_CATEGORY_BEGINNER }, 151 { SC_BARONY_BRIDGE, "Barony Bridge", SCENARIO_CATEGORY_BEGINNER }, 152 { SC_FUNTOPIA, "Funtopia", SCENARIO_CATEGORY_BEGINNER }, 153 { SC_HAUNTED_HARBOUR, "Haunted Harbour", SCENARIO_CATEGORY_BEGINNER }, 154 { SC_FUN_FORTRESS, "Fun Fortress", SCENARIO_CATEGORY_BEGINNER }, 155 { SC_FUTURE_WORLD, "Future World", SCENARIO_CATEGORY_BEGINNER }, 156 { SC_GENTLE_GLEN, "Gentle Glen", SCENARIO_CATEGORY_BEGINNER }, 157 { SC_JOLLY_JUNGLE, "Jolly Jungle", SCENARIO_CATEGORY_CHALLENGING }, 158 { SC_HYDRO_HILLS, "Hydro Hills", SCENARIO_CATEGORY_CHALLENGING }, 159 { SC_SPRIGHTLY_PARK, "Sprightly Park", SCENARIO_CATEGORY_CHALLENGING }, 160 { SC_MAGIC_QUARTERS, "Magic Quarters", SCENARIO_CATEGORY_CHALLENGING }, 161 { SC_FRUIT_FARM, "Fruit Farm", SCENARIO_CATEGORY_CHALLENGING }, 162 { SC_BUTTERFLY_DAM, "Butterfly Dam", SCENARIO_CATEGORY_CHALLENGING }, 163 { SC_COASTER_CANYON, "Coaster Canyon", SCENARIO_CATEGORY_CHALLENGING }, 164 { SC_THUNDERSTORM_PARK, "Thunderstorm Park", SCENARIO_CATEGORY_CHALLENGING }, 165 { SC_HARMONIC_HILLS, "Harmonic Hills", SCENARIO_CATEGORY_CHALLENGING }, 166 { SC_ROMAN_VILLAGE, "Roman Village", SCENARIO_CATEGORY_CHALLENGING }, 167 { SC_SWAMP_COVE, "Swamp Cove", SCENARIO_CATEGORY_CHALLENGING }, 168 { SC_ADRENALINE_HEIGHTS, "Adrenaline Heights", SCENARIO_CATEGORY_CHALLENGING }, 169 { SC_UTOPIA_PARK, "Utopia Park", SCENARIO_CATEGORY_CHALLENGING }, 170 { SC_ROTTING_HEIGHTS, "Rotting Heights", SCENARIO_CATEGORY_EXPERT }, 171 { SC_FIASCO_FOREST, "Fiasco Forest", SCENARIO_CATEGORY_EXPERT }, 172 { SC_PICKLE_PARK, "Pickle Park", SCENARIO_CATEGORY_EXPERT }, 173 { SC_GIGGLE_DOWNS, "Giggle Downs", SCENARIO_CATEGORY_EXPERT }, 174 { SC_MINERAL_PARK, "Mineral Park", SCENARIO_CATEGORY_EXPERT }, 175 { SC_COASTER_CRAZY, "Coaster Crazy", SCENARIO_CATEGORY_EXPERT }, 176 { SC_URBAN_PARK, "Urban Park", SCENARIO_CATEGORY_EXPERT }, 177 { SC_GEOFFREY_GARDENS, "Geoffrey Gardens", SCENARIO_CATEGORY_EXPERT }, 178 }; 179 180 // RCT: Loopy Landscapes 181 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT1LL[] = 182 { 183 { SC_ICEBERG_ISLANDS, "Iceberg Islands", SCENARIO_CATEGORY_BEGINNER }, 184 { SC_VOLCANIA, "Volcania", SCENARIO_CATEGORY_BEGINNER }, 185 { SC_ARID_HEIGHTS, "Arid Heights", SCENARIO_CATEGORY_BEGINNER }, 186 { SC_RAZOR_ROCKS, "Razor Rocks", SCENARIO_CATEGORY_BEGINNER }, 187 { SC_CRATER_LAKE, "Crater Lake", SCENARIO_CATEGORY_BEGINNER }, 188 { SC_VERTIGO_VIEWS, "Vertigo Views", SCENARIO_CATEGORY_BEGINNER }, 189 { SC_PARADISE_PIER_2, "Paradise Pier 2", SCENARIO_CATEGORY_CHALLENGING }, 190 { SC_DRAGONS_COVE, "Dragon's Cove", SCENARIO_CATEGORY_CHALLENGING }, 191 { SC_GOOD_KNIGHT_PARK, "Good Knight Park", SCENARIO_CATEGORY_CHALLENGING }, 192 { SC_WACKY_WARREN, "Wacky Warren", SCENARIO_CATEGORY_CHALLENGING }, 193 { SC_GRAND_GLACIER, "Grand Glacier", SCENARIO_CATEGORY_CHALLENGING }, 194 { SC_CRAZY_CRATERS, "Crazy Craters", SCENARIO_CATEGORY_CHALLENGING }, 195 { SC_DUSTY_DESERT, "Dusty Desert", SCENARIO_CATEGORY_CHALLENGING }, 196 { SC_WOODWORM_PARK, "Woodworm Park", SCENARIO_CATEGORY_CHALLENGING }, 197 { SC_ICARUS_PARK, "Icarus Park", SCENARIO_CATEGORY_CHALLENGING }, 198 { SC_SUNNY_SWAMPS, "Sunny Swamps", SCENARIO_CATEGORY_CHALLENGING }, 199 { SC_FRIGHTMARE_HILLS, "Frightmare Hills", SCENARIO_CATEGORY_CHALLENGING }, 200 { SC_THUNDER_ROCKS, "Thunder Rocks", SCENARIO_CATEGORY_CHALLENGING }, 201 { SC_OCTAGON_PARK, "Octagon Park", SCENARIO_CATEGORY_CHALLENGING }, 202 { SC_PLEASURE_ISLAND, "Pleasure Island", SCENARIO_CATEGORY_CHALLENGING }, 203 { SC_ICICLE_WORLDS, "Icicle Worlds", SCENARIO_CATEGORY_CHALLENGING }, 204 { SC_SOUTHERN_SANDS, "Southern Sands", SCENARIO_CATEGORY_CHALLENGING }, 205 { SC_TINY_TOWERS, "Tiny Towers", SCENARIO_CATEGORY_CHALLENGING }, 206 { SC_NEVERMORE_PARK, "Nevermore Park", SCENARIO_CATEGORY_CHALLENGING }, 207 { SC_PACIFICA, "Pacifica", SCENARIO_CATEGORY_CHALLENGING }, 208 { SC_URBAN_JUNGLE, "Urban Jungle", SCENARIO_CATEGORY_EXPERT }, 209 { SC_TERROR_TOWN, "Terror Town", SCENARIO_CATEGORY_EXPERT }, 210 { SC_MEGAWORLD_PARK, "Megaworld Park", SCENARIO_CATEGORY_EXPERT }, 211 { SC_VENUS_PONDS, "Venus Ponds", SCENARIO_CATEGORY_EXPERT }, 212 { SC_MICRO_PARK, "Micro Park", SCENARIO_CATEGORY_EXPERT }, 213 }; 214 215 // RCT2 216 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT2[] = 217 { 218 { SC_UNIDENTIFIED, "Crazy Castle", SCENARIO_CATEGORY_BEGINNER }, 219 { SC_UNIDENTIFIED, "Electric Fields", SCENARIO_CATEGORY_BEGINNER }, 220 { SC_UNIDENTIFIED, "Factory Capers", SCENARIO_CATEGORY_BEGINNER }, 221 { SC_UNIDENTIFIED, "Amity Airfield", SCENARIO_CATEGORY_CHALLENGING }, 222 { SC_UNIDENTIFIED, "Botany Breakers", SCENARIO_CATEGORY_CHALLENGING }, 223 { SC_UNIDENTIFIED, "Bumbly Bazaar", SCENARIO_CATEGORY_CHALLENGING }, 224 { SC_UNIDENTIFIED, "Dusty Greens", SCENARIO_CATEGORY_CHALLENGING }, 225 { SC_UNIDENTIFIED, "Fungus Woods", SCENARIO_CATEGORY_CHALLENGING }, 226 { SC_UNIDENTIFIED, "Gravity Gardens", SCENARIO_CATEGORY_CHALLENGING }, 227 { SC_UNIDENTIFIED, "Infernal Views", SCENARIO_CATEGORY_CHALLENGING }, 228 { SC_UNIDENTIFIED, "Alpine Adventures", SCENARIO_CATEGORY_EXPERT }, 229 { SC_UNIDENTIFIED, "Extreme Heights", SCENARIO_CATEGORY_EXPERT }, 230 { SC_UNIDENTIFIED, "Ghost Town", SCENARIO_CATEGORY_EXPERT }, 231 { SC_UNIDENTIFIED, "Lucky Lake", SCENARIO_CATEGORY_EXPERT }, 232 { SC_UNIDENTIFIED, "Rainbow Summit", SCENARIO_CATEGORY_EXPERT }, 233 }; 234 235 // RCT2: Wacky Worlds 236 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT2WW[] = 237 { 238 { SC_UNIDENTIFIED, "Africa - Victoria Falls", SCENARIO_CATEGORY_BEGINNER }, 239 { SC_UNIDENTIFIED, "Asia - Great Wall of China Tourism Enhancement", SCENARIO_CATEGORY_BEGINNER }, 240 { SC_UNIDENTIFIED, "North America - Grand Canyon", SCENARIO_CATEGORY_BEGINNER }, 241 { SC_UNIDENTIFIED, "South America - Rio Carnival", SCENARIO_CATEGORY_BEGINNER }, 242 { SC_UNIDENTIFIED, "Africa - African Diamond Mine", SCENARIO_CATEGORY_CHALLENGING }, 243 { SC_UNIDENTIFIED, "Asia - Maharaja Palace", SCENARIO_CATEGORY_CHALLENGING }, 244 { SC_UNIDENTIFIED, "Australasia - Ayers Rock", SCENARIO_CATEGORY_CHALLENGING }, 245 { SC_UNIDENTIFIED, "Europe - European Cultural Festival", SCENARIO_CATEGORY_CHALLENGING }, 246 { SC_UNIDENTIFIED, "North America - Rollercoaster Heaven", SCENARIO_CATEGORY_CHALLENGING }, 247 { SC_UNIDENTIFIED, "South America - Inca Lost City", SCENARIO_CATEGORY_CHALLENGING }, 248 { SC_UNIDENTIFIED, "Africa - Oasis", SCENARIO_CATEGORY_EXPERT }, 249 { SC_UNIDENTIFIED, "Antarctic - Ecological Salvage", SCENARIO_CATEGORY_EXPERT }, 250 { SC_UNIDENTIFIED, "Asia - Japanese Coastal Reclaim", SCENARIO_CATEGORY_EXPERT }, 251 { SC_UNIDENTIFIED, "Australasia - Fun at the Beach", SCENARIO_CATEGORY_EXPERT }, 252 { SC_UNIDENTIFIED, "Europe - Renovation", SCENARIO_CATEGORY_EXPERT }, 253 { SC_UNIDENTIFIED, "N. America - Extreme Hawaiian Island", SCENARIO_CATEGORY_EXPERT }, 254 { SC_UNIDENTIFIED, "South America - Rain Forest Plateau", SCENARIO_CATEGORY_EXPERT }, 255 }; 256 257 // RCT2: Time Twister 258 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRCT2TT[] = 259 { 260 { SC_UNIDENTIFIED, "Dark Age - Robin Hood", SCENARIO_CATEGORY_BEGINNER }, 261 { SC_UNIDENTIFIED, "Prehistoric - After the Asteroid", SCENARIO_CATEGORY_BEGINNER }, 262 { SC_UNIDENTIFIED, "Roaring Twenties - Prison Island", SCENARIO_CATEGORY_BEGINNER }, 263 { SC_UNIDENTIFIED, "Rock 'n' Roll - Flower Power", SCENARIO_CATEGORY_BEGINNER }, 264 { SC_UNIDENTIFIED, "Dark Age - Castle", SCENARIO_CATEGORY_CHALLENGING }, 265 { SC_UNIDENTIFIED, "Future - First Encounters", SCENARIO_CATEGORY_CHALLENGING }, 266 { SC_UNIDENTIFIED, "Mythological - Animatronic Film Set", SCENARIO_CATEGORY_CHALLENGING }, 267 { SC_UNIDENTIFIED, "Prehistoric - Jurassic Safari", SCENARIO_CATEGORY_CHALLENGING }, 268 { SC_UNIDENTIFIED, "Roaring Twenties - Schneider Cup", SCENARIO_CATEGORY_CHALLENGING }, 269 { SC_UNIDENTIFIED, "Future - Future World", SCENARIO_CATEGORY_EXPERT }, 270 { SC_UNIDENTIFIED, "Mythological - Cradle of Civilisation", SCENARIO_CATEGORY_EXPERT }, 271 { SC_UNIDENTIFIED, "Prehistoric - Stone Age", SCENARIO_CATEGORY_EXPERT }, 272 { SC_UNIDENTIFIED, "Roaring Twenties - Skyscrapers", SCENARIO_CATEGORY_EXPERT }, 273 { SC_UNIDENTIFIED, "Rock 'n' Roll - Rock 'n' Roll", SCENARIO_CATEGORY_EXPERT }, 274 }; 275 276 // Real parks 277 static constexpr const ScenarioTitleDescriptor ScenarioTitlesRealParks[] = 278 { 279 { SC_ALTON_TOWERS, "Alton Towers", SCENARIO_CATEGORY_REAL }, 280 { SC_HEIDE_PARK, "Heide-Park", SCENARIO_CATEGORY_REAL }, 281 { SC_BLACKPOOL_PLEASURE_BEACH, "Blackpool Pleasure Beach", SCENARIO_CATEGORY_REAL }, 282 { SC_UNIDENTIFIED, "Six Flags Belgium", SCENARIO_CATEGORY_REAL }, 283 { SC_UNIDENTIFIED, "Six Flags Great Adventure", SCENARIO_CATEGORY_REAL }, 284 { SC_UNIDENTIFIED, "Six Flags Holland", SCENARIO_CATEGORY_REAL }, 285 { SC_UNIDENTIFIED, "Six Flags Magic Mountain", SCENARIO_CATEGORY_REAL }, 286 { SC_UNIDENTIFIED, "Six Flags over Texas", SCENARIO_CATEGORY_REAL }, 287 }; 288 289 // Other parks 290 static constexpr const ScenarioTitleDescriptor ScenarioTitlesOtherParks[] = 291 { 292 { SC_FORT_ANACHRONISM, "Fort Anachronism", SCENARIO_CATEGORY_DLC }, 293 { SC_PCPLAYER, "PC Player", SCENARIO_CATEGORY_DLC }, 294 { SC_PCGW, "PC Gaming World", SCENARIO_CATEGORY_DLC }, 295 { SC_GAMEPLAY, "gameplay", SCENARIO_CATEGORY_DLC }, 296 { SC_UNIDENTIFIED, "Panda World", SCENARIO_CATEGORY_DLC }, 297 { SC_UNIDENTIFIED, "Competition Land 1", SCENARIO_CATEGORY_DLC }, 298 { SC_UNIDENTIFIED, "Competition Land 2", SCENARIO_CATEGORY_DLC }, 299 { SC_STEEL_TWISTER_COMPETITION, "Steel Twister Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 300 { SC_GO_KARTS_COMPETITION, "Go Karts Competition", SCENARIO_CATEGORY_DLC }, 301 { SC_STEEL_CORKSCREW_COMPETITION, "Steel Corkscrew Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 302 { SC_MINE_TRAIN_COMPETITION, "Mine Train Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 303 { SC_STEEL_ROLLER_COASTER_COMPETITION, "Steel Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 304 { SC_BOBSLED_COMPETITION, "Bobsled Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 305 { SC_INVERTED_ROLLER_COASTER_COMPETITION, "Inverted Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 306 { SC_SUSPENDED_ROLLER_COASTER_COMPETITION, "Suspended Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 307 { SC_STAND_UP_STEEL_ROLLER_COASTER_COMPETITION, "Stand-Up Steel Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 308 { SC_WOODEN_ROLLER_COASTER_COMPETITION, "Wooden Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 309 { SC_STEEL_MINI_ROLLER_COASTER_COMPETITION, "Steel Mini Roller Coaster Competition", SCENARIO_CATEGORY_DLC }, 310 { SC_UNIDENTIFIED, "Build your own Six Flags Belgium", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 311 { SC_UNIDENTIFIED, "Build your own Six Flags Great Adventure", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 312 { SC_UNIDENTIFIED, "Build your own Six Flags Holland", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 313 { SC_UNIDENTIFIED, "Build your own Six Flags Magic Mountain", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 314 { SC_UNIDENTIFIED, "Build your own Six Flags Park", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 315 { SC_UNIDENTIFIED, "Build your own Six Flags over Texas", SCENARIO_CATEGORY_BUILD_YOUR_OWN }, 316 }; 317 318 #define DEFINE_SCENARIO_TITLE_DESC_GROUP(x) { std::size(x), x } 319 const struct { 320 size_t count; 321 const ScenarioTitleDescriptor * const titles; 322 } ScenarioTitlesBySource[] = { 323 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1), 324 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1AA), 325 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT1LL), 326 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2), 327 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2WW), 328 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRCT2TT), 329 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesRealParks), 330 DEFINE_SCENARIO_TITLE_DESC_GROUP(ScenarioTitlesOtherParks), 331 }; 332 // clang-format on 333 334 #pragma endregion 335 TryGetByName(const utf8 * name,source_desc * outDesc)336 bool TryGetByName(const utf8* name, source_desc* outDesc) 337 { 338 Guard::ArgumentNotNull(outDesc, GUARD_LINE); 339 340 int32_t currentIndex = 0; 341 for (size_t i = 0; i < std::size(ScenarioTitlesBySource); i++) 342 { 343 for (size_t j = 0; j < ScenarioTitlesBySource[i].count; j++) 344 { 345 const ScenarioTitleDescriptor* desc = &ScenarioTitlesBySource[i].titles[j]; 346 if (String::Equals(name, desc->Title, true)) 347 { 348 outDesc->title = desc->Title; 349 outDesc->id = desc->Id; 350 outDesc->source = static_cast<uint8_t>(i); 351 outDesc->index = currentIndex; 352 outDesc->category = desc->Category; 353 return true; 354 } 355 currentIndex++; 356 } 357 } 358 359 outDesc->title = nullptr; 360 outDesc->id = SC_UNIDENTIFIED; 361 outDesc->source = static_cast<uint8_t>(ScenarioSource::Other); 362 outDesc->index = -1; 363 outDesc->category = SCENARIO_CATEGORY_OTHER; 364 return false; 365 } 366 TryGetById(uint8_t id,source_desc * outDesc)367 bool TryGetById(uint8_t id, source_desc* outDesc) 368 { 369 Guard::ArgumentNotNull(outDesc, GUARD_LINE); 370 371 int32_t currentIndex = 0; 372 for (size_t i = 0; i < std::size(ScenarioTitlesBySource); i++) 373 { 374 for (size_t j = 0; j < ScenarioTitlesBySource[i].count; j++) 375 { 376 const ScenarioTitleDescriptor* desc = &ScenarioTitlesBySource[i].titles[j]; 377 if (id == desc->Id) 378 { 379 outDesc->title = desc->Title; 380 outDesc->id = desc->Id; 381 outDesc->source = static_cast<uint8_t>(i); 382 outDesc->index = currentIndex; 383 outDesc->category = desc->Category; 384 return true; 385 } 386 currentIndex++; 387 } 388 } 389 390 outDesc->title = ""; 391 outDesc->id = SC_UNIDENTIFIED; 392 outDesc->source = static_cast<uint8_t>(ScenarioSource::Other); 393 outDesc->index = -1; 394 outDesc->category = SCENARIO_CATEGORY_OTHER; 395 return false; 396 } 397 NormaliseName(utf8 * buffer,size_t bufferSize,const utf8 * name)398 void NormaliseName(utf8* buffer, size_t bufferSize, const utf8* name) 399 { 400 size_t nameLength = String::LengthOf(name); 401 402 // Strip "RCT(1|2)?" prefix off scenario names. 403 if (nameLength >= 3 && (name[0] == 'R' && name[1] == 'C' && name[2] == 'T')) 404 { 405 if (nameLength >= 4 && (name[3] == '1' || name[3] == '2')) 406 { 407 log_verbose("Stripping RCT/1/2 from name: %s", name); 408 String::Set(buffer, bufferSize, name + 4); 409 } 410 else 411 { 412 String::Set(buffer, bufferSize, name + 3); 413 } 414 } 415 416 // Trim (for the sake of the above and WW / TT scenarios 417 String::TrimStart(buffer, bufferSize, name); 418 419 // American scenario titles should be converted to British name 420 // Don't worry, names will be translated using language packs later 421 for (const ScenarioAlias& alias : ScenarioAliases) 422 { 423 if (String::Equals(alias.Alternative, name)) 424 { 425 log_verbose("Found alias: %s; will treat as: %s", name, alias.Original); 426 String::Set(buffer, bufferSize, alias.Original); 427 } 428 } 429 } 430 } // namespace ScenarioSources 431