1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 20:43:04 +01:00

Allow game actions to store custom data instead of using inheritance

This commit is contained in:
ζeh Matt
2021-09-12 18:24:55 +03:00
parent 28681eebc0
commit 42254d774d
4 changed files with 22 additions and 32 deletions

View File

@@ -1983,11 +1983,12 @@ static void window_top_toolbar_scenery_tool_down(const ScreenCoordsXY& windowPos
CoordsXYZD loc{ gridPos, z, direction };
auto primaryColour = gWindowSceneryPrimaryColour;
auto bannerPlaceAction = BannerPlaceAction(loc, selectedScenery, primaryColour);
bannerPlaceAction.SetCallback([=](const GameAction* ga, const BannerPlaceActionResult* result) {
bannerPlaceAction.SetCallback([=](const GameAction* ga, const GameActions::Result* result) {
if (result->Error == GameActions::Status::Ok)
{
auto data = result->GetData<BannerPlaceActionResult>();
OpenRCT2::Audio::Play3D(OpenRCT2::Audio::SoundId::PlaceItem, result->Position);
context_open_detail_window(WD_BANNER, result->bannerId);
context_open_detail_window(WD_BANNER, data.bannerId);
}
});
GameActions::Execute(&bannerPlaceAction);

View File

@@ -18,26 +18,6 @@
using namespace OpenRCT2;
BannerPlaceActionResult::BannerPlaceActionResult()
: GameActions::Result(GameActions::Status::Ok, STR_CANT_POSITION_THIS_HERE)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err)
: GameActions::Result(err, STR_CANT_POSITION_THIS_HERE)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err, rct_string_id msg)
: GameActions::Result(err, STR_CANT_POSITION_THIS_HERE, msg)
{
}
BannerPlaceActionResult::BannerPlaceActionResult(GameActions::Status err, rct_string_id title, rct_string_id message)
: GameActions::Result(err, title, message)
{
}
BannerPlaceAction::BannerPlaceAction(const CoordsXYZD& loc, ObjectEntryIndex bannerType, colour_t primaryColour)
: _loc(loc)
, _bannerType(bannerType)
@@ -117,6 +97,7 @@ GameActions::Result::Ptr BannerPlaceAction::Query() const
return MakeResult(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE);
}
res->Cost = bannerEntry->price;
return res;
}
@@ -155,8 +136,7 @@ GameActions::Result::Ptr BannerPlaceAction::Execute() const
banner->colour = _primaryColour;
banner->position = TileCoordsXY(_loc);
res->bannerId = banner->id;
res->SetData(BannerPlaceActionResult{ banner->id });
auto* bannerElement = TileElementInsert<BannerElement>({ _loc, _loc.z + (2 * COORDS_Z_STEP) }, 0b0000);
Guard::Assert(bannerElement != nullptr);

View File

@@ -11,18 +11,12 @@
#include "GameAction.h"
class BannerPlaceActionResult final : public GameActions::Result
struct BannerPlaceActionResult
{
public:
BannerPlaceActionResult();
BannerPlaceActionResult(GameActions::Status err);
BannerPlaceActionResult(GameActions::Status err, rct_string_id msg);
BannerPlaceActionResult(GameActions::Status err, rct_string_id title, rct_string_id message);
BannerIndex bannerId = BANNER_INDEX_NULL;
};
DEFINE_GAME_ACTION(BannerPlaceAction, GameCommand::PlaceBanner, BannerPlaceActionResult)
DEFINE_GAME_ACTION(BannerPlaceAction, GameCommand::PlaceBanner, GameActions::Result)
{
private:
CoordsXYZD _loc;

View File

@@ -16,6 +16,7 @@
#include "../localisation/StringIds.h"
#include "../world/Map.h"
#include <any>
#include <array>
#include <functional>
#include <memory>
@@ -130,6 +131,7 @@ namespace GameActions
CoordsXYZ Position = { LOCATION_NULL, LOCATION_NULL, LOCATION_NULL };
money32 Cost = 0;
ExpenditureType Expenditure = ExpenditureType::Count;
std::any ResultData;
Result() = default;
Result(GameActions::Status error, rct_string_id message);
@@ -140,6 +142,19 @@ namespace GameActions
std::string GetErrorTitle() const;
std::string GetErrorMessage() const;
// It is recommended to use strong types since a type alias such as 'using MyType = uint32_t'
// is still just uint32_t, this guarantees the data is associated with the correct type.
template<typename T> void SetData(const T&& data)
{
ResultData = std::forward<const T&&>(data);
}
// This function will throw std::bad_any_cast if the type mismatches.
template<typename T> T GetData() const
{
return std::any_cast<T>(ResultData);
}
};
class ConstructClearResult final : public Result