From 960bea7aaeeb3232ac6d8a75e3ecdfe0af4d19db Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 6 Sep 2024 23:04:14 +0200 Subject: [PATCH] Prefer using passed game state in save import classes (#22682) * Wrap global game state in a unique_ptr * Make ImportTileElements, SetTileElements use game state passed * Make ImportParkName, ImportSavedView use game state passed * Make ImportPeepSpawns use game state passed * Make FixEntrancePositions use game state passed --- src/openrct2/GameState.cpp | 9 +++++++-- src/openrct2/GameState.h | 1 + src/openrct2/park/ParkFile.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 27 ++++++++++++--------------- src/openrct2/rct2/S6Importer.cpp | 11 +++++------ src/openrct2/ride/TrackDesign.cpp | 6 ++++-- src/openrct2/world/Map.cpp | 21 ++++++++++++++------- src/openrct2/world/Map.h | 7 ++++++- 8 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index 5164e744ac..e0c78d0ebc 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -33,11 +33,16 @@ using namespace OpenRCT2::Scripting; namespace OpenRCT2 { - static GameState_t _gameState{}; + static auto _gameState = std::make_unique(); GameState_t& GetGameState() { - return _gameState; + return *_gameState; + } + + void SwapGameState(std::unique_ptr& otherState) + { + _gameState.swap(otherState); } /** diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index 4e01ed7769..12e31d1219 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -149,6 +149,7 @@ namespace OpenRCT2 }; GameState_t& GetGameState(); + void SwapGameState(std::unique_ptr& otherState); void gameStateInitAll(GameState_t& gameState, const TileCoordsXY& mapSize); void gameStateTick(); diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 3927da8714..654b16a10b 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -1071,7 +1071,7 @@ namespace OpenRCT2 std::vector tileElements; tileElements.resize(numElements); cs.Read(tileElements.data(), tileElements.size() * sizeof(TileElement)); - SetTileElements(std::move(tileElements)); + SetTileElements(gameState, std::move(tileElements)); { TileElementIterator it; TileElementIteratorBegin(&it); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index f29a763531..70fb15516c 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -182,16 +182,16 @@ namespace OpenRCT2::RCT1 ImportRides(); ImportRideMeasurements(); ImportEntities(); - ImportTileElements(); - ImportPeepSpawns(); + ImportTileElements(gameState); + ImportPeepSpawns(gameState); ImportFinance(gameState); ImportResearch(gameState); - ImportParkName(); + ImportParkName(gameState); ImportParkFlags(gameState); ImportClimate(gameState); ImportScenarioNameDetails(gameState); ImportScenarioObjective(gameState); - ImportSavedView(); + ImportSavedView(gameState); RCT12::FetchAndApplyScenarioPatch(_s4Path, _isScenario); FixNextGuestNumber(gameState); @@ -1405,9 +1405,8 @@ namespace OpenRCT2::RCT1 dst->z = src->z; } - void ImportPeepSpawns() + void ImportPeepSpawns(GameState_t& gameState) { - auto& gameState = GetGameState(); gameState.PeepSpawns.clear(); for (size_t i = 0; i < Limits::kMaxPeepSpawns; i++) { @@ -1517,7 +1516,7 @@ namespace OpenRCT2::RCT1 return result; } - void ImportTileElements() + void ImportTileElements(GameState_t& gameState) { // Build tile pointer cache (needed to get the first element at a certain location) auto tilePointerIndex = TilePointerIndex( @@ -1565,8 +1564,8 @@ namespace OpenRCT2::RCT1 } } - SetTileElements(std::move(tileElements)); - FixEntrancePositions(); + SetTileElements(gameState, std::move(tileElements)); + FixEntrancePositions(gameState); } size_t ImportTileElement(TileElement* dst, const RCT12TileElement* src) @@ -2121,7 +2120,7 @@ namespace OpenRCT2::RCT1 } } - void ImportParkName() + void ImportParkName(GameState_t& gameState) { std::string parkName = std::string(_s4.ScenarioName); if (IsUserStringID(static_cast(_s4.ParkNameStringIndex))) @@ -2133,7 +2132,7 @@ namespace OpenRCT2::RCT1 } } - auto& park = GetGameState().Park; + auto& park = gameState.Park; park.Name = std::move(parkName); } @@ -2371,9 +2370,8 @@ namespace OpenRCT2::RCT1 gameState.ScenarioObjective.RideId = GetBuildTheBestRideId(); } - void ImportSavedView() + void ImportSavedView(GameState_t& gameState) { - auto& gameState = GetGameState(); gameState.SavedView = ScreenCoordsXY{ _s4.ViewX, _s4.ViewY }; gameState.SavedViewZoom = ZoomLevel{ static_cast(_s4.ViewZoom) }; gameState.SavedViewRotation = _s4.ViewRotation; @@ -2440,9 +2438,8 @@ namespace OpenRCT2::RCT1 dst->position.y = src->y; } - void FixEntrancePositions() + void FixEntrancePositions(GameState_t& gameState) { - auto& gameState = GetGameState(); gameState.Park.Entrances.clear(); TileElementIterator it; TileElementIteratorBegin(&it); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index cf3a5dbf3c..383e383cf2 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -329,7 +329,7 @@ namespace OpenRCT2::RCT2 ScenarioRandSeed(_s6.ScenarioSrand0, _s6.ScenarioSrand1); DetermineFlatRideStatus(); - ImportTileElements(); + ImportTileElements(gameState); ImportEntities(); gameState.InitialCash = ToMoney64(_s6.InitialCash); @@ -352,7 +352,7 @@ namespace OpenRCT2::RCT2 // Pad013573EE // rct1_park_entrance_z - ImportPeepSpawns(); + ImportPeepSpawns(gameState); gameState.GuestChangeModifier = _s6.GuestCountChangeModifier; gameState.ResearchFundingLevel = _s6.CurrentResearchLevel; @@ -1098,7 +1098,7 @@ namespace OpenRCT2::RCT2 * Imports guest entry points. * Includes fixes for incorrectly set guest entry points in some scenarios. */ - void ImportPeepSpawns() + void ImportPeepSpawns(GameState_t& gameState) { // Many WW and TT have scenario_filename fields containing an incorrect filename. Check for both this filename // and the corrected filename. @@ -1129,7 +1129,6 @@ namespace OpenRCT2::RCT2 _s6.PeepSpawns[0].z = 7; } - auto& gameState = GetGameState(); gameState.PeepSpawns.clear(); for (size_t i = 0; i < Limits::kMaxPeepSpawns; i++) { @@ -1162,7 +1161,7 @@ namespace OpenRCT2::RCT2 dst->num_riders = numRiders; } - void ImportTileElements() + void ImportTileElements(GameState_t& gameState) { // Build tile pointer cache (needed to get the first element at a certain location) auto tilePointerIndex = TilePointerIndex( @@ -1232,7 +1231,7 @@ namespace OpenRCT2::RCT2 } } } - SetTileElements(std::move(tileElements)); + SetTileElements(gameState, std::move(tileElements)); } void ImportTileElement(TileElement* dst, const RCT12TileElement* src, bool invisible) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 974a7e7301..7363b3473b 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -2152,7 +2152,8 @@ static void TrackDesignPreviewClearMap() { auto numTiles = kMaximumMapSizeTechnical * kMaximumMapSizeTechnical; - GetGameState().MapSize = TRACK_DESIGN_PREVIEW_MAP_SIZE; + auto& gameState = GetGameState(); + gameState.MapSize = TRACK_DESIGN_PREVIEW_MAP_SIZE; // Reserve ~8 elements per tile std::vector tileElements; @@ -2171,7 +2172,8 @@ static void TrackDesignPreviewClearMap() element->AsSurface()->SetOwnership(OWNERSHIP_OWNED); element->AsSurface()->SetParkFences(0); } - SetTileElements(std::move(tileElements)); + + SetTileElements(gameState, std::move(tileElements)); } bool TrackDesignAreEntranceAndExitPlaced() diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 3178e51f7c..5120c603ca 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -147,9 +147,8 @@ const std::vector& GetTileElements() return GetGameState().TileElements; } -void SetTileElements(std::vector&& tileElements) +void SetTileElements(GameState_t& gameState, std::vector&& tileElements) { - auto& gameState = GetGameState(); gameState.TileElements = std::move(tileElements); _tileIndex = TilePointerIndex( kMaximumMapSizeTechnical, gameState.TileElements.data(), gameState.TileElements.size()); @@ -211,7 +210,7 @@ std::vector GetReorganisedTileElementsWithoutGhosts() return newElements; } -static void ReorganiseTileElements(size_t capacity) +static void ReorganiseTileElements(GameState_t& gameState, size_t capacity) { ContextSetCurrentCursor(CursorID::ZZZ); @@ -236,12 +235,19 @@ static void ReorganiseTileElements(size_t capacity) } } - SetTileElements(std::move(newElements)); + SetTileElements(gameState, std::move(newElements)); +} + +static void ReorganiseTileElements(size_t capacity) +{ + auto& gameState = GetGameState(); + ReorganiseTileElements(gameState, capacity); } void ReorganiseTileElements() { - ReorganiseTileElements(GetGameState().TileElements.size()); + auto& gameState = GetGameState(); + ReorganiseTileElements(gameState, gameState.TileElements.size()); } static bool MapCheckFreeElementsAndReorganise(size_t numElementsOnTile, size_t numNewElements) @@ -454,9 +460,9 @@ BannerElement* MapGetBannerElementAt(const CoordsXYZ& bannerPos, uint8_t positio void MapInit(const TileCoordsXY& size) { auto numTiles = kMaximumMapSizeTechnical * kMaximumMapSizeTechnical; - SetTileElements(std::vector(numTiles, GetDefaultSurfaceElement())); auto& gameState = GetGameState(); + SetTileElements(gameState, std::vector(numTiles, GetDefaultSurfaceElement())); gameState.GrassSceneryTileLoopPosition = 0; gameState.WidePathTileLoopPosition = {}; @@ -2294,7 +2300,8 @@ void ShiftMap(const TileCoordsXY& amount) } } } - SetTileElements(std::move(newElements)); + + SetTileElements(gameState, std::move(newElements)); MapRemoveOutOfRangeElements(); for (auto& spawn : gameState.PeepSpawns) diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 2f4e75f033..6f978ae2e7 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -111,9 +111,14 @@ extern uint32_t gLandRemainingConstructionSales; extern bool gMapLandRightsUpdateSuccess; +namespace OpenRCT2 +{ + struct GameState_t; +} + void ReorganiseTileElements(); const std::vector& GetTileElements(); -void SetTileElements(std::vector&& tileElements); +void SetTileElements(OpenRCT2::GameState_t& gameState, std::vector&& tileElements); void StashMap(); void UnstashMap(); std::vector GetReorganisedTileElementsWithoutGhosts();