1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-19 04:53:12 +01:00

Refactor action result passing for SmallSceneryPlaceAction

This commit is contained in:
ζeh Matt
2021-10-04 17:25:53 +03:00
parent 233b1e99b4
commit 9cb26f7b02
3 changed files with 35 additions and 60 deletions

View File

@@ -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<SmallSceneryPlaceActionResult*>(res.get());
if (sspar == nullptr || res->Error != GameActions::Status::Ok)
if (res->Error != GameActions::Status::Ok)
return MONEY64_UNDEFINED;
const auto placementData = res->GetData<SmallSceneryPlaceActionResult>();
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);

View File

@@ -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<SmallSceneryPlaceActionResult>();
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<SmallSceneryPlaceActionResult>(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<SmallSceneryPlaceActionResult>(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<SmallSceneryPlaceActionResult>(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<SmallSceneryPlaceActionResult>(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<SmallSceneryPlaceActionResult>(
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<SmallSceneryPlaceActionResult>(
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<SmallSceneryPlaceActionResult>(
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<SmallSceneryPlaceActionResult>(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<SmallSceneryPlaceActionResult>(
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<SmallSceneryPlaceActionResult>(
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<SmallSceneryPlaceActionResult>();
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<SmallSceneryPlaceActionResult>(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<SmallSceneryElement>(
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<TileElement>();
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))

View File

@@ -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;