From 134f4ac43e2ce03c439007bcbda464bc5333b5a9 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Mon, 25 Aug 2025 22:16:55 +0200 Subject: [PATCH] Start moving game actions into GameActions namespace --- .../interface/ViewportInteraction.cpp | 2 +- src/openrct2-ui/windows/Scenery.cpp | 8 +- src/openrct2/actions/BalloonPressAction.cpp | 89 +++--- src/openrct2/actions/BalloonPressAction.h | 25 +- src/openrct2/actions/BannerPlaceAction.cpp | 286 +++++++++--------- src/openrct2/actions/BannerPlaceAction.h | 43 +-- src/openrct2/scripting/ScriptEngine.cpp | 2 +- 7 files changed, 232 insertions(+), 223 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 19fee88198..6e1e733d8d 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -222,7 +222,7 @@ namespace OpenRCT2::Ui { if (GameIsNotPaused()) { - auto balloonPress = BalloonPressAction(entity->Id); + auto balloonPress = GameActions::BalloonPressAction(entity->Id); GameActions::Execute(&balloonPress); } } diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 47e03b4edf..8b05b93a44 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -2216,7 +2216,7 @@ namespace OpenRCT2::Ui::Windows // 6e2612 auto primaryColour = _sceneryPrimaryColour; - auto bannerPlaceAction = BannerPlaceAction(loc, entryIndex, primaryColour); + auto bannerPlaceAction = GameActions::BannerPlaceAction(loc, entryIndex, primaryColour); bannerPlaceAction.SetFlags( GAME_COMMAND_FLAG_GHOST | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND); auto res = GameActions::Execute(&bannerPlaceAction); @@ -3224,12 +3224,12 @@ namespace OpenRCT2::Ui::Windows CoordsXYZD loc{ gridPos, z, direction }; auto primaryColour = _sceneryPrimaryColour; - auto bannerPlaceAction = BannerPlaceAction(loc, selectedScenery, primaryColour); + auto bannerPlaceAction = GameActions::BannerPlaceAction(loc, selectedScenery, primaryColour); bannerPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) { if (result->Error == GameActions::Status::Ok) { - auto data = result->GetData(); - OpenRCT2::Audio::Play3D(OpenRCT2::Audio::SoundId::PlaceItem, result->Position); + auto data = result->GetData(); + Audio::Play3D(Audio::SoundId::PlaceItem, result->Position); ContextOpenDetailWindow(WD_BANNER, data.bannerId.ToUnderlying()); } }); diff --git a/src/openrct2/actions/BalloonPressAction.cpp b/src/openrct2/actions/BalloonPressAction.cpp index 331be6ab82..5dd82179e2 100644 --- a/src/openrct2/actions/BalloonPressAction.cpp +++ b/src/openrct2/actions/BalloonPressAction.cpp @@ -14,52 +14,53 @@ #include "../entity/EntityRegistry.h" #include "GameAction.h" -using namespace OpenRCT2; - -BalloonPressAction::BalloonPressAction(EntityId spriteIndex) - : _spriteIndex(spriteIndex) +namespace OpenRCT2::GameActions { -} - -void BalloonPressAction::AcceptParameters(GameActionParameterVisitor& visitor) -{ - visitor.Visit("id", _spriteIndex); -} - -uint16_t BalloonPressAction::GetActionFlags() const -{ - return GameAction::GetActionFlags(); -} - -void BalloonPressAction::Serialise(DataSerialiser& stream) -{ - GameAction::Serialise(stream); - stream << DS_TAG(_spriteIndex); -} - -GameActions::Result BalloonPressAction::Query() const -{ - auto balloon = TryGetEntity(_spriteIndex); - if (balloon == nullptr) + BalloonPressAction::BalloonPressAction(EntityId spriteIndex) + : _spriteIndex(spriteIndex) { - LOG_ERROR("Balloon not found for spriteIndex %u", _spriteIndex); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_ERR_INVALID_PARAMETER, STR_ERR_BALLOON_NOT_FOUND); - } - return GameActions::Result(); -} - -GameActions::Result BalloonPressAction::Execute() const -{ - auto balloon = TryGetEntity(_spriteIndex); - if (balloon == nullptr) - { - LOG_ERROR("Balloon not found for spriteIndex %u", _spriteIndex); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_ERR_INVALID_PARAMETER, STR_ERR_BALLOON_NOT_FOUND); } - balloon->Press(); + void BalloonPressAction::AcceptParameters(GameActionParameterVisitor& visitor) + { + visitor.Visit("id", _spriteIndex); + } - return GameActions::Result(); -} + uint16_t BalloonPressAction::GetActionFlags() const + { + return GameAction::GetActionFlags(); + } + + void BalloonPressAction::Serialise(DataSerialiser& stream) + { + GameAction::Serialise(stream); + stream << DS_TAG(_spriteIndex); + } + + GameActions::Result BalloonPressAction::Query() const + { + auto balloon = TryGetEntity(_spriteIndex); + if (balloon == nullptr) + { + LOG_ERROR("Balloon not found for spriteIndex %u", _spriteIndex); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_ERR_INVALID_PARAMETER, STR_ERR_BALLOON_NOT_FOUND); + } + return GameActions::Result(); + } + + GameActions::Result BalloonPressAction::Execute() const + { + auto balloon = TryGetEntity(_spriteIndex); + if (balloon == nullptr) + { + LOG_ERROR("Balloon not found for spriteIndex %u", _spriteIndex); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_ERR_INVALID_PARAMETER, STR_ERR_BALLOON_NOT_FOUND); + } + + balloon->Press(); + + return GameActions::Result(); + } +} // namespace OpenRCT2::GameActions diff --git a/src/openrct2/actions/BalloonPressAction.h b/src/openrct2/actions/BalloonPressAction.h index 6520ae1cfe..c3a2e6870d 100644 --- a/src/openrct2/actions/BalloonPressAction.h +++ b/src/openrct2/actions/BalloonPressAction.h @@ -12,19 +12,22 @@ #include "../Identifiers.h" #include "GameAction.h" -class BalloonPressAction final : public GameActionBase +namespace OpenRCT2::GameActions { - EntityId _spriteIndex{ EntityId::GetNull() }; + class BalloonPressAction final : public GameActionBase + { + EntityId _spriteIndex{ EntityId::GetNull() }; -public: - BalloonPressAction() = default; - BalloonPressAction(EntityId spriteIndex); + public: + BalloonPressAction() = default; + BalloonPressAction(EntityId spriteIndex); - void AcceptParameters(GameActionParameterVisitor& visitor) override; + void AcceptParameters(GameActionParameterVisitor& visitor) override; - uint16_t GetActionFlags() const override; + uint16_t GetActionFlags() const override; - void Serialise(DataSerialiser& stream) override; - OpenRCT2::GameActions::Result Query() const override; - OpenRCT2::GameActions::Result Execute() const override; -}; + void Serialise(DataSerialiser& stream) override; + OpenRCT2::GameActions::Result Query() const override; + OpenRCT2::GameActions::Result Execute() const override; + }; +} // namespace OpenRCT2::GameActions diff --git a/src/openrct2/actions/BannerPlaceAction.cpp b/src/openrct2/actions/BannerPlaceAction.cpp index dad84d99d8..aeb17a5440 100644 --- a/src/openrct2/actions/BannerPlaceAction.cpp +++ b/src/openrct2/actions/BannerPlaceAction.cpp @@ -22,166 +22,168 @@ #include "../world/tile_element/PathElement.h" #include "GameAction.h" -using namespace OpenRCT2; - -BannerPlaceAction::BannerPlaceAction(const CoordsXYZD& loc, ObjectEntryIndex bannerType, colour_t primaryColour) - : _loc(loc) - , _bannerType(bannerType) - , _primaryColour(primaryColour) +namespace OpenRCT2::GameActions { -} - -void BannerPlaceAction::AcceptParameters(GameActionParameterVisitor& visitor) -{ - visitor.Visit(_loc); - visitor.Visit("object", _bannerType); - visitor.Visit("primaryColour", _primaryColour); -} - -uint16_t BannerPlaceAction::GetActionFlags() const -{ - return GameAction::GetActionFlags(); -} - -void BannerPlaceAction::Serialise(DataSerialiser& stream) -{ - GameAction::Serialise(stream); - - stream << DS_TAG(_loc) << DS_TAG(_bannerType) << DS_TAG(_primaryColour); -} - -GameActions::Result BannerPlaceAction::Query() const -{ - auto res = GameActions::Result(); - res.Position.x = _loc.x + 16; - res.Position.y = _loc.y + 16; - res.Position.z = _loc.z; - res.Expenditure = ExpenditureType::landscaping; - res.ErrorTitle = STR_CANT_POSITION_THIS_HERE; - - if (!LocationValid(_loc)) + BannerPlaceAction::BannerPlaceAction(const CoordsXYZD& loc, ObjectEntryIndex bannerType, colour_t primaryColour) + : _loc(loc) + , _bannerType(bannerType) + , _primaryColour(primaryColour) { - return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP); } - if (!MapCheckCapacityAndReorganise(_loc)) + void BannerPlaceAction::AcceptParameters(GameActionParameterVisitor& visitor) { - LOG_ERROR("No free map elements."); - return GameActions::Result( - GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); + visitor.Visit(_loc); + visitor.Visit("object", _bannerType); + visitor.Visit("primaryColour", _primaryColour); } - auto pathElement = GetValidPathElement(); - - if (pathElement == nullptr) + uint16_t BannerPlaceAction::GetActionFlags() const { - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS); + return GameAction::GetActionFlags(); } - if (!MapCanBuildAt(_loc)) + void BannerPlaceAction::Serialise(DataSerialiser& stream) { - return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_bannerType) << DS_TAG(_primaryColour); } - auto baseHeight = _loc.z + kPathHeightStep; - BannerElement* existingBannerElement = MapGetBannerElementAt({ _loc.x, _loc.y, baseHeight }, _loc.direction); - if (existingBannerElement != nullptr) + GameActions::Result BannerPlaceAction::Query() const { - return GameActions::Result( - GameActions::Status::ItemAlreadyPlaced, STR_CANT_POSITION_THIS_HERE, STR_BANNER_SIGN_IN_THE_WAY); + auto res = GameActions::Result(); + res.Position.x = _loc.x + 16; + res.Position.y = _loc.y + 16; + res.Position.z = _loc.z; + res.Expenditure = ExpenditureType::landscaping; + res.ErrorTitle = STR_CANT_POSITION_THIS_HERE; + + if (!LocationValid(_loc)) + { + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP); + } + + if (!MapCheckCapacityAndReorganise(_loc)) + { + LOG_ERROR("No free map elements."); + return GameActions::Result( + GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); + } + + auto pathElement = GetValidPathElement(); + + if (pathElement == nullptr) + { + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS); + } + + if (!MapCanBuildAt(_loc)) + { + return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); + } + + auto baseHeight = _loc.z + kPathHeightStep; + BannerElement* existingBannerElement = MapGetBannerElementAt({ _loc.x, _loc.y, baseHeight }, _loc.direction); + if (existingBannerElement != nullptr) + { + return GameActions::Result( + GameActions::Status::ItemAlreadyPlaced, STR_CANT_POSITION_THIS_HERE, STR_BANNER_SIGN_IN_THE_WAY); + } + + if (HasReachedBannerLimit()) + { + LOG_ERROR("No free banners available"); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + } + + auto* bannerEntry = OpenRCT2::ObjectManager::GetObjectEntry(_bannerType); + if (bannerEntry == nullptr) + { + LOG_ERROR("Banner entry not found for bannerType %u", _bannerType); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + } + res.Cost = bannerEntry->price; + res.SetData(BannerPlaceActionResult{}); + + return res; } - if (HasReachedBannerLimit()) + GameActions::Result BannerPlaceAction::Execute() const { - LOG_ERROR("No free banners available"); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + auto res = GameActions::Result(); + res.Position.x = _loc.x + 16; + res.Position.y = _loc.y + 16; + res.Position.z = _loc.z; + res.Expenditure = ExpenditureType::landscaping; + res.ErrorTitle = STR_CANT_POSITION_THIS_HERE; + + if (!MapCheckCapacityAndReorganise(_loc)) + { + LOG_ERROR("No free map elements."); + return GameActions::Result( + GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); + } + + auto* bannerEntry = OpenRCT2::ObjectManager::GetObjectEntry(_bannerType); + if (bannerEntry == nullptr) + { + LOG_ERROR("Banner entry not found for bannerType %u", _bannerType); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + } + + auto banner = CreateBanner(); + if (banner == nullptr) + { + LOG_ERROR("No free banners available"); + return GameActions::Result( + GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME); + } + banner->flags = {}; + banner->text = {}; + banner->textColour = TextColour::white; + banner->type = _bannerType; // Banner must be deleted after this point in an early return + banner->colour = _primaryColour; + banner->position = TileCoordsXY(_loc); + + res.SetData(BannerPlaceActionResult{ banner->id }); + auto* bannerElement = TileElementInsert({ _loc, _loc.z + (2 * kCoordsZStep) }, 0b0000); + Guard::Assert(bannerElement != nullptr); + + bannerElement->SetClearanceZ(_loc.z + kPathClearance); + bannerElement->SetPosition(_loc.direction); + bannerElement->ResetAllowedEdges(); + bannerElement->SetIndex(banner->id); + bannerElement->SetGhost(GetFlags() & GAME_COMMAND_FLAG_GHOST); + + MapInvalidateTileFull(_loc); + MapAnimations::MarkTileForInvalidation(TileCoordsXY(_loc)); + + res.Cost = bannerEntry->price; + return res; } - auto* bannerEntry = OpenRCT2::ObjectManager::GetObjectEntry(_bannerType); - if (bannerEntry == nullptr) + PathElement* BannerPlaceAction::GetValidPathElement() const { - LOG_ERROR("Banner entry not found for bannerType %u", _bannerType); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_ERR_BANNER_ELEMENT_NOT_FOUND); + for (auto* pathElement : TileElementsView(_loc)) + { + if (pathElement->GetBaseZ() != _loc.z && pathElement->GetBaseZ() != _loc.z - kPathHeightStep) + continue; + + if (!(pathElement->GetEdges() & (1 << _loc.direction))) + continue; + + if (pathElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + continue; + + return pathElement; + } + + return nullptr; } - res.Cost = bannerEntry->price; - res.SetData(BannerPlaceActionResult{}); - - return res; -} - -GameActions::Result BannerPlaceAction::Execute() const -{ - auto res = GameActions::Result(); - res.Position.x = _loc.x + 16; - res.Position.y = _loc.y + 16; - res.Position.z = _loc.z; - res.Expenditure = ExpenditureType::landscaping; - res.ErrorTitle = STR_CANT_POSITION_THIS_HERE; - - if (!MapCheckCapacityAndReorganise(_loc)) - { - LOG_ERROR("No free map elements."); - return GameActions::Result( - GameActions::Status::NoFreeElements, STR_CANT_POSITION_THIS_HERE, STR_TILE_ELEMENT_LIMIT_REACHED); - } - - auto* bannerEntry = OpenRCT2::ObjectManager::GetObjectEntry(_bannerType); - if (bannerEntry == nullptr) - { - LOG_ERROR("Banner entry not found for bannerType %u", _bannerType); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_ERR_BANNER_ELEMENT_NOT_FOUND); - } - - auto banner = CreateBanner(); - if (banner == nullptr) - { - LOG_ERROR("No free banners available"); - return GameActions::Result( - GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_TOO_MANY_BANNERS_IN_GAME); - } - banner->flags = {}; - banner->text = {}; - banner->textColour = TextColour::white; - banner->type = _bannerType; // Banner must be deleted after this point in an early return - banner->colour = _primaryColour; - banner->position = TileCoordsXY(_loc); - - res.SetData(BannerPlaceActionResult{ banner->id }); - auto* bannerElement = TileElementInsert({ _loc, _loc.z + (2 * kCoordsZStep) }, 0b0000); - Guard::Assert(bannerElement != nullptr); - - bannerElement->SetClearanceZ(_loc.z + kPathClearance); - bannerElement->SetPosition(_loc.direction); - bannerElement->ResetAllowedEdges(); - bannerElement->SetIndex(banner->id); - bannerElement->SetGhost(GetFlags() & GAME_COMMAND_FLAG_GHOST); - - MapInvalidateTileFull(_loc); - MapAnimations::MarkTileForInvalidation(TileCoordsXY(_loc)); - - res.Cost = bannerEntry->price; - return res; -} - -PathElement* BannerPlaceAction::GetValidPathElement() const -{ - for (auto* pathElement : TileElementsView(_loc)) - { - if (pathElement->GetBaseZ() != _loc.z && pathElement->GetBaseZ() != _loc.z - kPathHeightStep) - continue; - - if (!(pathElement->GetEdges() & (1 << _loc.direction))) - continue; - - if (pathElement->IsGhost() && !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) - continue; - - return pathElement; - } - - return nullptr; -} +} // namespace OpenRCT2::GameActions diff --git a/src/openrct2/actions/BannerPlaceAction.h b/src/openrct2/actions/BannerPlaceAction.h index 8fcde8a294..ae7915a1c5 100644 --- a/src/openrct2/actions/BannerPlaceAction.h +++ b/src/openrct2/actions/BannerPlaceAction.h @@ -11,30 +11,33 @@ #include "GameAction.h" -struct BannerPlaceActionResult +namespace OpenRCT2::GameActions { - BannerIndex bannerId = BannerIndex::GetNull(); -}; + struct BannerPlaceActionResult + { + BannerIndex bannerId = BannerIndex::GetNull(); + }; -class BannerPlaceAction final : public GameActionBase -{ -private: - CoordsXYZD _loc; - OpenRCT2::ObjectEntryIndex _bannerType{ kBannerNull }; - uint8_t _primaryColour{}; + class BannerPlaceAction final : public GameActionBase + { + private: + CoordsXYZD _loc; + OpenRCT2::ObjectEntryIndex _bannerType{ kBannerNull }; + uint8_t _primaryColour{}; -public: - BannerPlaceAction() = default; - BannerPlaceAction(const CoordsXYZD& loc, OpenRCT2::ObjectEntryIndex bannerType, colour_t primaryColour); + public: + BannerPlaceAction() = default; + BannerPlaceAction(const CoordsXYZD& loc, OpenRCT2::ObjectEntryIndex bannerType, colour_t primaryColour); - void AcceptParameters(GameActionParameterVisitor& visitor) override; + void AcceptParameters(GameActionParameterVisitor& visitor) override; - uint16_t GetActionFlags() const override; + uint16_t GetActionFlags() const override; - void Serialise(DataSerialiser& stream) override; - OpenRCT2::GameActions::Result Query() const override; - OpenRCT2::GameActions::Result Execute() const override; + void Serialise(DataSerialiser& stream) override; + OpenRCT2::GameActions::Result Query() const override; + OpenRCT2::GameActions::Result Execute() const override; -private: - OpenRCT2::PathElement* GetValidPathElement() const; -}; + private: + OpenRCT2::PathElement* GetValidPathElement() const; + }; +} // namespace OpenRCT2::GameActions diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index bcaa6fdb01..ced148ede9 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -1246,7 +1246,7 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const Gam switch (action.GetType()) { case GameCommand::PlaceBanner: - bannerId = result.GetData().bannerId; + bannerId = result.GetData().bannerId; break; case GameCommand::PlaceLargeScenery: bannerId = result.GetData().bannerId;