Fix: GameActionResult does not comply to API specification

This commit is contained in:
Stephan Spengler 2023-01-12 22:14:52 +01:00 committed by GitHub
parent b1bf62177f
commit 9c6032bb36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 42 deletions

View File

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

View File

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

View File

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

View File

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

View File

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