Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: GameActionResult does not comply to API specification #19114

Merged
merged 1 commit into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions distribution/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Fix: [#18911] Mini Golf station does not draw correctly from all angles.
- Fix: [#18971] New Game does not prompt for save before quitting.
- Fix: [#19026] Park loan is clamped to a 32-bit integer.
- Fix: [#19114] [Plugin] GameActionResult does not comply to API specification.

0.4.3 (2022-12-14)
------------------------------------------------------------------------
Expand Down
16 changes: 10 additions & 6 deletions distribution/openrct2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ declare global {
queryAction(action: "peepspawnplace", args: PeepSpawnPlaceArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "playerkick", args: PlayerKickArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "playersetgroup", args: PlayerSetGroupArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "ridecreate", args: RideCreateArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "ridecreate", args: RideCreateArgs, callback?: (result: RideCreateActionResult) => void): void;
queryAction(action: "ridedemolish", args: RideDemolishArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "rideentranceexitplace", args: RideEntranceExitPlaceArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "rideentranceexitremove", args: RideEntranceExitRemoveArgs, callback?: (result: GameActionResult) => void): void;
Expand All @@ -342,7 +342,7 @@ declare global {
queryAction(action: "smallsceneryremove", args: SmallSceneryRemoveArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "smallscenerysetcolour", args: SmallScenerySetColourArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "stafffire", args: StaffFireArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "staffhire", args: StaffHireArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "staffhire", args: StaffHireArgs, callback?: (result: StaffHireNewActionResult) => void): void;
queryAction(action: "staffsetcolour", args: StaffSetColourArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "staffsetcostume", args: StaffSetCostumeArgs, callback?: (result: GameActionResult) => void): void;
queryAction(action: "staffsetname", args: StaffSetNameArgs, callback?: (result: GameActionResult) => void): void;
Expand Down Expand Up @@ -414,7 +414,7 @@ declare global {
executeAction(action: "peepspawnplace", args: PeepSpawnPlaceArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "playerkick", args: PlayerKickArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "playersetgroup", args: PlayerSetGroupArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "ridecreate", args: RideCreateArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "ridecreate", args: RideCreateArgs, callback?: (result: RideCreateActionResult) => void): void;
executeAction(action: "ridedemolish", args: RideDemolishArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "rideentranceexitplace", args: RideEntranceExitPlaceArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "rideentranceexitremove", args: RideEntranceExitRemoveArgs, callback?: (result: GameActionResult) => void): void;
Expand All @@ -433,7 +433,7 @@ declare global {
executeAction(action: "smallsceneryremove", args: SmallSceneryRemoveArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "smallscenerysetcolour", args: SmallScenerySetColourArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "stafffire", args: StaffFireArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "staffhire", args: StaffHireArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "staffhire", args: StaffHireArgs, callback?: (result: StaffHireNewActionResult) => void): void;
executeAction(action: "staffsetcolour", args: StaffSetColourArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "staffsetcostume", args: StaffSetCostumeArgs, callback?: (result: GameActionResult) => void): void;
executeAction(action: "staffsetname", args: StaffSetNameArgs, callback?: (result: GameActionResult) => void): void;
Expand Down Expand Up @@ -1296,8 +1296,12 @@ declare global {
expenditureType?: ExpenditureType;
}

interface RideCreateGameActionResult extends GameActionResult {
readonly ride: number;
interface RideCreateActionResult extends GameActionResult {
readonly ride?: number;
}

interface StaffHireNewActionResult extends GameActionResult {
readonly peep?: number;
}

interface NetworkEventArgs {
Expand Down
11 changes: 7 additions & 4 deletions src/openrct2/scripting/ScriptEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,11 +1131,13 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const Gam
DukStackFrame frame(_context);
DukObject obj(_context);

auto player = action.GetPlayer();
if (player != -1)
obj.Set("error", static_cast<duk_int_t>(result.Error));
if (result.Error != GameActions::Status::Ok)
{
obj.Set("player", action.GetPlayer());
obj.Set("errorTitle", result.GetErrorTitle());
obj.Set("errorMessage", result.GetErrorMessage());
}

if (result.Cost != MONEY32_UNDEFINED)
{
obj.Set("cost", result.Cost);
Expand All @@ -1144,12 +1146,12 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const Gam
{
obj.Set("position", ToDuk(_context, result.Position));
}

if (result.Expenditure != ExpenditureType::Count)
{
obj.Set("expenditureType", ExpenditureTypeToString(result.Expenditure));
}

// RideCreateAction only
if (action.GetType() == GameCommand::CreateRide)
{
if (result.Error == GameActions::Status::Ok)
Expand All @@ -1158,6 +1160,7 @@ DukValue ScriptEngine::GameActionResultToDuk(const GameAction& action, const Gam
obj.Set("ride", rideIndex.ToUnderlying());
}
}
// StaffHireNewAction only
else if (action.GetType() == GameCommand::HireNewStaffMember)
{
if (result.Error == GameActions::Status::Ok)
Expand Down
2 changes: 1 addition & 1 deletion src/openrct2/scripting/ScriptEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ namespace OpenRCT2::Scripting
const std::shared_ptr<Plugin>& plugin, std::string_view action, const DukValue& query, const DukValue& execute);
void RunGameActionHooks(const GameAction& action, GameActions::Result& result, bool isExecute);
[[nodiscard]] std::unique_ptr<GameAction> CreateGameAction(const std::string& actionid, const DukValue& args);
[[nodiscard]] DukValue GameActionResultToDuk(const GameAction& action, const GameActions::Result& result);

void SaveSharedStorage();

Expand Down Expand Up @@ -275,7 +276,6 @@ namespace OpenRCT2::Scripting
void ProcessREPL();
void RemoveCustomGameActions(const std::shared_ptr<Plugin>& plugin);
[[nodiscard]] GameActions::Result DukToGameActionResult(const DukValue& d);
[[nodiscard]] DukValue GameActionResultToDuk(const GameAction& action, const GameActions::Result& result);
static std::string_view ExpenditureTypeToString(ExpenditureType expenditureType);
static ExpenditureType StringToExpenditureType(std::string_view expenditureType);

Expand Down
39 changes: 8 additions & 31 deletions src/openrct2/scripting/bindings/game/ScContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,15 @@ namespace OpenRCT2::Scripting
if (isExecute)
{
action->SetCallback(
[this, plugin, callback](const GameAction*, const GameActions::Result* res) -> void {
HandleGameActionResult(plugin, *res, callback);
[this, plugin, callback](const GameAction* act, const GameActions::Result* res) -> void {
HandleGameActionResult(plugin, *act, *res, callback);
});
GameActions::Execute(action.get());
}
else
{
auto res = GameActions::Query(action.get());
HandleGameActionResult(plugin, res, callback);
HandleGameActionResult(plugin, *action, res, callback);
}
}
else
Expand All @@ -362,38 +362,15 @@ namespace OpenRCT2::Scripting
}

void HandleGameActionResult(
const std::shared_ptr<Plugin>& plugin, const GameActions::Result& res, const DukValue& callback)
const std::shared_ptr<Plugin>& plugin, const GameAction& action, const GameActions::Result& res,
const DukValue& callback)
{
// Construct result object
auto& scriptEngine = GetContext()->GetScriptEngine();
auto ctx = scriptEngine.GetContext();
auto objIdx = duk_push_object(ctx);
duk_push_int(ctx, static_cast<duk_int_t>(res.Error));
duk_put_prop_string(ctx, objIdx, "error");

if (res.Error != GameActions::Status::Ok)
{
auto title = res.GetErrorTitle();
duk_push_string(ctx, title.c_str());
duk_put_prop_string(ctx, objIdx, "errorTitle");

auto message = res.GetErrorMessage();
duk_push_string(ctx, message.c_str());
duk_put_prop_string(ctx, objIdx, "errorMessage");
}

duk_push_int(ctx, static_cast<duk_int_t>(res.Cost));
duk_put_prop_string(ctx, objIdx, "cost");

duk_push_int(ctx, static_cast<duk_int_t>(res.Expenditure));
duk_put_prop_string(ctx, objIdx, "expenditureType");

auto args = DukValue::take_from_stack(ctx);

if (callback.is_function())
{
auto& scriptEngine = GetContext()->GetScriptEngine();
auto dukResult = scriptEngine.GameActionResultToDuk(action, res);
// Call the plugin callback and pass the result object
scriptEngine.ExecutePluginCall(plugin, callback, { args }, false);
scriptEngine.ExecutePluginCall(plugin, callback, { dukResult }, false);
}
}

Expand Down