mirror of https://github.com/OpenRCT2/OpenRCT2.git
Start work on custom game actions
This commit is contained in:
parent
07ed0f5c0e
commit
4e4379e6ef
|
@ -98,6 +98,7 @@ enum GAME_COMMAND
|
|||
GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA
|
||||
GAME_COMMAND_GUEST_SET_FLAGS, // GA
|
||||
GAME_COMMAND_SET_DATE, // GA
|
||||
GAME_COMMAND_CUSTOM, // GA
|
||||
GAME_COMMAND_COUNT,
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2020 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __ENABLE_SCRIPTING__
|
||||
|
||||
# include "../Context.h"
|
||||
# include "../scripting/ScriptEngine.h"
|
||||
# include "GameAction.h"
|
||||
|
||||
DEFINE_GAME_ACTION(CustomAction, GAME_COMMAND_CUSTOM, GameActionResult)
|
||||
{
|
||||
private:
|
||||
std::string _id;
|
||||
std::string _json;
|
||||
|
||||
public:
|
||||
CustomAction() = default;
|
||||
CustomAction(const std::string& id, const std::string& json)
|
||||
: _id(id)
|
||||
, _json(json)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t GetActionFlags() const override
|
||||
{
|
||||
return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED;
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser & stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << DS_TAG(_id) << DS_TAG(_json);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
auto& scriptingEngine = OpenRCT2::GetContext()->GetScriptEngine();
|
||||
return scriptingEngine.QueryOrExecuteCustomGameAction(_id, _json, false);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
{
|
||||
auto& scriptingEngine = OpenRCT2::GetContext()->GetScriptEngine();
|
||||
return scriptingEngine.QueryOrExecuteCustomGameAction(_id, _json, true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#include "BannerSetStyleAction.hpp"
|
||||
#include "ClearAction.hpp"
|
||||
#include "ClimateSetAction.hpp"
|
||||
#include "CustomAction.hpp"
|
||||
#include "FootpathPlaceAction.hpp"
|
||||
#include "FootpathPlaceFromTrackAction.hpp"
|
||||
#include "FootpathRemoveAction.hpp"
|
||||
|
@ -171,5 +172,8 @@ namespace GameActions
|
|||
Register<GuestSetFlagsAction>();
|
||||
Register<ParkSetDateAction>();
|
||||
Register<SetCheatAction>();
|
||||
#ifdef __ENABLE_SCRIPTING__
|
||||
Register<CustomAction>();
|
||||
#endif
|
||||
}
|
||||
} // namespace GameActions
|
||||
|
|
|
@ -2997,12 +2997,15 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if player's group permission allows command to run
|
||||
NetworkGroup* group = GetGroupByID(connection.Player->Group);
|
||||
if (group == nullptr || group->CanPerformCommand(actionType) == false)
|
||||
if (actionType != GAME_COMMAND_CUSTOM)
|
||||
{
|
||||
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_PERMISSION_DENIED);
|
||||
return;
|
||||
// Check if player's group permission allows command to run
|
||||
NetworkGroup* group = GetGroupByID(connection.Player->Group);
|
||||
if (group == nullptr || group->CanPerformCommand(actionType) == false)
|
||||
{
|
||||
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_PERMISSION_DENIED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create and enqueue the action.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#ifdef __ENABLE_SCRIPTING__
|
||||
|
||||
# include "../actions/CustomAction.hpp"
|
||||
# include "../actions/ParkSetNameAction.hpp"
|
||||
# include "../actions/SmallSceneryPlaceAction.hpp"
|
||||
# include "Duktape.hpp"
|
||||
|
@ -91,7 +92,7 @@ namespace OpenRCT2::Scripting
|
|||
if (isExecute)
|
||||
{
|
||||
action->SetCallback(
|
||||
[this, &plugin, &callback](const GameAction*, const GameActionResult* res) -> void {
|
||||
[this, plugin, callback](const GameAction*, const GameActionResult* res) -> void {
|
||||
HandleGameActionResult(plugin, *res, callback);
|
||||
});
|
||||
GameActions::Execute(action.get());
|
||||
|
@ -143,7 +144,16 @@ namespace OpenRCT2::Scripting
|
|||
uint8_t secondaryColour = args["secondaryColour"].as_int();
|
||||
return std::make_unique<SmallSceneryPlaceAction>(loc, quadrant, sceneryType, primaryColour, secondaryColour);
|
||||
}
|
||||
return {};
|
||||
else
|
||||
{
|
||||
// Serialise args to json so that it can be sent
|
||||
auto ctx = args.context();
|
||||
args.push();
|
||||
auto jsonz = duk_json_encode(ctx, -1);
|
||||
auto json = std::string(jsonz);
|
||||
duk_pop(ctx);
|
||||
return std::make_unique<CustomAction>(actionid, json);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleGameActionResult(
|
||||
|
|
|
@ -694,6 +694,30 @@ void ScriptEngine::AddNetworkPlugin(const std::string_view& code)
|
|||
LoadPlugin(plugin);
|
||||
}
|
||||
|
||||
std::unique_ptr<GameActionResult> ScriptEngine::QueryOrExecuteCustomGameAction(
|
||||
const std::string_view& id,
|
||||
const std::string_view& args,
|
||||
bool isExecute)
|
||||
{
|
||||
// Deserialise the JSON args
|
||||
std::string argsz(args);
|
||||
duk_push_string(_context, argsz.c_str());
|
||||
duk_json_decode(_context, -1);
|
||||
auto dukArgs = DukValue::take_from_stack(_context);
|
||||
|
||||
// Ready to call plugin handler
|
||||
if (isExecute)
|
||||
{
|
||||
std::printf("EXECUTE: %s(%s)\n", std::string(id).c_str(), std::string(args).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::printf("QUERY: %s(%s)\n", std::string(id).c_str(), std::string(args).c_str());
|
||||
}
|
||||
|
||||
return std::make_unique<GameActionResult>();
|
||||
}
|
||||
|
||||
std::string OpenRCT2::Scripting::Stringify(const DukValue& val)
|
||||
{
|
||||
return ExpressionStringifier::StringifyExpression(val);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
struct duk_hthread;
|
||||
typedef struct duk_hthread duk_context;
|
||||
|
||||
class GameActionResult;
|
||||
class FileWatcher;
|
||||
class InteractiveConsole;
|
||||
|
||||
|
@ -155,6 +156,8 @@ namespace OpenRCT2::Scripting
|
|||
|
||||
void AddNetworkPlugin(const std::string_view& code);
|
||||
|
||||
std::unique_ptr<GameActionResult> QueryOrExecuteCustomGameAction(const std::string_view& id, const std::string_view& args, bool isExecute);
|
||||
|
||||
private:
|
||||
void Initialise();
|
||||
void StartPlugins();
|
||||
|
|
Loading…
Reference in New Issue