From 9cb26f7b0226542f433705aa2433700f9e2c24c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 4 Oct 2021 17:25:53 +0300 Subject: [PATCH] Refactor action result passing for SmallSceneryPlaceAction --- src/openrct2-ui/windows/TopToolbar.cpp | 12 ++-- .../actions/SmallSceneryPlaceAction.cpp | 68 +++++++------------ .../actions/SmallSceneryPlaceAction.h | 15 ++-- 3 files changed, 35 insertions(+), 60 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index f837b0695f..974ba8532d 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -2464,18 +2464,18 @@ static money64 try_place_ghost_small_scenery( auto smallSceneryPlaceAction = SmallSceneryPlaceAction(loc, quadrant, entryIndex, primaryColour, secondaryColour); smallSceneryPlaceAction.SetFlags(GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); auto res = GameActions::Execute(&smallSceneryPlaceAction); - auto sspar = dynamic_cast(res.get()); - if (sspar == nullptr || res->Error != GameActions::Status::Ok) + if (res->Error != GameActions::Status::Ok) return MONEY64_UNDEFINED; + const auto placementData = res->GetData(); + gSceneryPlaceRotation = loc.direction; gSceneryPlaceObject.SceneryType = SCENERY_TYPE_SMALL; gSceneryPlaceObject.EntryIndex = entryIndex; - TileElement* tileElement = sspar->tileElement; - gSceneryGhostPosition = { loc, tileElement->GetBaseZ() }; - gSceneryQuadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant(); - if (sspar->GroundFlags & ELEMENT_IS_UNDERGROUND) + gSceneryGhostPosition = { loc, placementData.BaseHeight }; + gSceneryQuadrant = placementData.SceneryQuadrant; + if (placementData.GroundFlags & ELEMENT_IS_UNDERGROUND) { // Set underground on viewport_set_visibility(4); diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.cpp b/src/openrct2/actions/SmallSceneryPlaceAction.cpp index 210a9c6ad7..e6e536d19b 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.cpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.cpp @@ -27,26 +27,6 @@ #include "GameAction.h" #include "SmallSceneryRemoveAction.h" -SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult() - : GameActions::Result(GameActions::Status::Ok, STR_CANT_POSITION_THIS_HERE) -{ -} - -SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error) - : GameActions::Result(error, STR_CANT_POSITION_THIS_HERE) -{ -} - -SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message) - : GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message) -{ -} - -SmallSceneryPlaceActionResult::SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args) - : GameActions::Result(error, STR_CANT_POSITION_THIS_HERE, message, args) -{ -} - SmallSceneryPlaceAction::SmallSceneryPlaceAction( const CoordsXYZD& loc, uint8_t quadrant, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour) : _loc(loc) @@ -100,7 +80,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const { surfaceHeight = waterHeight; } - auto res = std::make_unique(); + auto res = MakeResult(); auto centre = _loc.ToTileCentre(); res->Position.x = centre.x; res->Position.y = centre.y; @@ -113,23 +93,23 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const if (!LocationValid(_loc)) { - return MakeResult(GameActions::Status::InvalidParameters); + return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } if (!MapCheckCapacityAndReorganise(_loc)) { - return std::make_unique(GameActions::Status::NoFreeElements); + return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); } if (!_trackDesignDrawingPreview && (_loc.x > GetMapSizeMaxXY() || _loc.y > GetMapSizeMaxXY())) { - return std::make_unique(GameActions::Status::InvalidParameters); + return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } auto* sceneryEntry = get_small_scenery_entry(_sceneryType); if (sceneryEntry == nullptr) { - return std::make_unique(GameActions::Status::InvalidParameters); + return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } auto quadrant = _quadrant; @@ -176,7 +156,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode && !map_is_location_owned({ _loc.x, _loc.y, targetHeight })) { - return std::make_unique(GameActions::Status::NotOwned, STR_LAND_NOT_OWNED_BY_PARK); + return MakeResult(GameActions::Status::NotOwned, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); } auto* surfaceElement = map_get_surface_element_at(_loc); @@ -186,8 +166,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const int32_t water_height = surfaceElement->GetWaterHeight() - 1; if (water_height > targetHeight) { - return std::make_unique( - GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_UNDERWATER); + return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); } } @@ -195,16 +174,15 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const { if (isOnWater) { - return std::make_unique( - GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } if (surfaceElement != nullptr && surfaceElement->GetWaterHeight() > 0) { if (surfaceElement->GetWaterHeight() > targetHeight) { - return std::make_unique( - GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return MakeResult( + GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } } } @@ -212,7 +190,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const if (!gCheatsDisableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) && !supportsRequired && !isOnWater && surfaceElement != nullptr && (surfaceElement->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)) { - return std::make_unique(GameActions::Status::Disallowed, STR_LEVEL_LAND_REQUIRED); + return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED); } if (!gCheatsDisableSupportLimits && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE)) && supportsRequired) @@ -223,15 +201,13 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const { if (surfaceElement->GetWaterHeight() > 0 || (surfaceElement->GetBaseZ()) != targetHeight) { - return std::make_unique( - GameActions::Status::Disallowed, STR_LEVEL_LAND_REQUIRED); + return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED); } } } else { - return std::make_unique( - GameActions::Status::Disallowed, STR_CAN_ONLY_BUILD_THIS_ON_LAND); + return MakeResult(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ON_LAND); } } @@ -281,7 +257,8 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Query() const return canBuild; } - res->GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + const uint8_t groundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + res->SetData(SmallSceneryPlaceActionResult{ groundFlags, 0, 0 }); res->Expenditure = ExpenditureType::Landscaping; res->Cost = (sceneryEntry->price * 10) + canBuild->Cost; @@ -305,7 +282,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const { surfaceHeight = waterHeight; } - auto res = std::make_unique(); + auto res = MakeResult(); auto centre = _loc.ToTileCentre(); res->Position.x = centre.x; res->Position.y = centre.y; @@ -319,7 +296,7 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const auto* sceneryEntry = get_small_scenery_entry(_sceneryType); if (sceneryEntry == nullptr) { - return std::make_unique(GameActions::Status::InvalidParameters); + return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_NONE); } auto quadrant = _quadrant; @@ -417,14 +394,15 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const return canBuild; } - res->GroundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); - res->Expenditure = ExpenditureType::Landscaping; res->Cost = (sceneryEntry->price * 10) + canBuild->Cost; auto* sceneryElement = TileElementInsert( CoordsXYZ{ _loc, zLow }, quarterTile.GetBaseQuarterOccupied()); - Guard::Assert(sceneryElement != nullptr); + if (sceneryElement == nullptr) + { + return MakeResult(GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); + } sceneryElement->SetDirection(_loc.direction); sceneryElement->SetSceneryQuadrant(quadrant); @@ -439,7 +417,9 @@ GameActions::Result::Ptr SmallSceneryPlaceAction::Execute() const sceneryElement->SetNeedsSupports(); } - res->tileElement = sceneryElement->as(); + const uint8_t groundFlags = canBuild->GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); + res->SetData( + SmallSceneryPlaceActionResult{ groundFlags, sceneryElement->GetBaseZ(), sceneryElement->GetSceneryQuadrant() }); map_invalidate_tile_full(_loc); if (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_ANIMATED)) diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.h b/src/openrct2/actions/SmallSceneryPlaceAction.h index dba1923cdb..7807c8f5f5 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.h +++ b/src/openrct2/actions/SmallSceneryPlaceAction.h @@ -12,19 +12,14 @@ #include "../world/TileElement.h" #include "GameAction.h" -class SmallSceneryPlaceActionResult final : public GameActions::Result +struct SmallSceneryPlaceActionResult { -public: - SmallSceneryPlaceActionResult(); - SmallSceneryPlaceActionResult(GameActions::Status error); - SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message); - SmallSceneryPlaceActionResult(GameActions::Status error, rct_string_id message, uint8_t* args); - - uint8_t GroundFlags{ 0 }; - TileElement* tileElement = nullptr; + uint8_t GroundFlags{}; + int32_t BaseHeight{}; + uint8_t SceneryQuadrant{}; }; -DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GameCommand::PlaceScenery, SmallSceneryPlaceActionResult) +DEFINE_GAME_ACTION(SmallSceneryPlaceAction, GameCommand::PlaceScenery, GameActions::Result) { private: CoordsXYZD _loc;