diff --git a/src/dynrpg_easyrpg.cpp b/src/dynrpg_easyrpg.cpp index aeae66e257b..3d0ec736533 100644 --- a/src/dynrpg_easyrpg.cpp +++ b/src/dynrpg_easyrpg.cpp @@ -19,6 +19,7 @@ #include #include "dynrpg_easyrpg.h" +#include "string_view.h" #include "main_data.h" #include "game_variables.h" #include "utils.h" @@ -48,7 +49,7 @@ static bool EasyOput(dyn_arg_list args) { return true; } -bool DynRpg::EasyRpgPlugin::EasyCall(dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) { +bool DynRpg::EasyRpgPlugin::EasyCall(Game_DynRpg& dynrpg_instance, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) { auto func_name = std::get<0>(DynRpg::ParseArgs("call", args)); if (func_name.empty()) { @@ -58,8 +59,8 @@ bool DynRpg::EasyRpgPlugin::EasyCall(dyn_arg_list args, bool& do_yield, Game_Int return true; } - for (auto& plugin: Main_Data::game_dynrpg->plugins) { - if (plugin->Invoke(func_name, args.subspan(1), do_yield, interpreter)) { + for (auto& plugin: dynrpg_instance.plugins) { + if (plugin->Invoke(dynrpg_instance, func_name, args.subspan(1), do_yield, interpreter)) { return true; } } @@ -93,37 +94,50 @@ bool DynRpg::EasyRpgPlugin::EasyRaw(dyn_arg_list args, Game_Interpreter* interpr return true; } - auto func = "raw"; + auto func = "easyrpg_raw"; bool okay = false; - lcf::rpg::EventCommand outputCommand; - std::vector outputParams = {}; + lcf::rpg::EventCommand cmd; + std::vector output_args; - for (std::size_t i = 0; i < args.size(); ++i) { - std::string currValue = DynRpg::ParseVarArg(func, args, i, okay); - Output::Warning("{}", currValue); + if (args.empty()) { + Output::Warning("easyrpg_raw: Command too short"); + return true; + } + + std::tie(cmd.code) = DynRpg::ParseArgs(func, args, &okay); + + if (!okay) { + return true; + } - if (!okay) return true; + if (args.size() >= 2) { + auto [string_arg] = DynRpg::ParseArgs(func, args.subspan(1), &okay); + cmd.string = lcf::DBString(string_arg); - if (i == 0) outputCommand.code = stoi(currValue); - if (i == 1) outputCommand.string = lcf::DBString(currValue); - else outputParams.push_back(stoi(currValue)); + if (!okay) { + return true; + } + + for (size_t i = 2; i < args.size(); ++i) { + auto [int_arg] = DynRpg::ParseArgs(func, args.subspan(i), &okay); + + if (!okay) { + return true; + } + } } - outputCommand.parameters = lcf::DBArray(outputParams.begin(), outputParams.end()); + cmd.parameters = lcf::DBArray(output_args.begin(), output_args.end()); - //FIXME: this will crash when you two interpreters run a raw command in parallel. - // The lack to access the current interpreter frame is a lack in the dynrpg API design. - // Have to fix this. The current frame should be easy to access - std::vector cmdList = { outputCommand }; - interpreter->Push(cmdList, 0, false); + interpreter->Push({ cmd }, 0, false); return true; } -bool DynRpg::EasyRpgPlugin::Invoke(StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) { +bool DynRpg::EasyRpgPlugin::Invoke(Game_DynRpg& dynrpg_instance, StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) { if (func == "call") { - return EasyCall(args, do_yield, interpreter); + return EasyCall(dynrpg_instance, args, do_yield, interpreter); } else if (func == "easyrpg_output") { return EasyOput(args); } else if (func == "easyrpg_add") { diff --git a/src/dynrpg_easyrpg.h b/src/dynrpg_easyrpg.h index aebacf858e2..0f9e41e446f 100644 --- a/src/dynrpg_easyrpg.h +++ b/src/dynrpg_easyrpg.h @@ -31,12 +31,12 @@ namespace DynRpg { public: EasyRpgPlugin() : DynRpgPlugin("EasyRpgPlugin") {} - bool Invoke(StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) override; + bool Invoke(Game_DynRpg& dynrpg_instance, StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) override; void Load(const std::vector& buffer) override; std::vector Save() override; private: - bool EasyCall(dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter); + bool EasyCall(Game_DynRpg& dynrpg_instance, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter); bool EasyRaw(dyn_arg_list args, Game_Interpreter* interpreter); }; } diff --git a/src/dynrpg_textplugin.cpp b/src/dynrpg_textplugin.cpp index 8c017eb98e6..397d6488e56 100644 --- a/src/dynrpg_textplugin.cpp +++ b/src/dynrpg_textplugin.cpp @@ -399,7 +399,7 @@ static bool RemoveAll(dyn_arg_list) { return true; } -bool DynRpg::TextPlugin::Invoke(StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) { +bool DynRpg::TextPlugin::Invoke(Game_DynRpg&, StringView func, dyn_arg_list args, bool&, Game_Interpreter*) { if (func == "write_text") { return WriteText(args); } else if (func == "append_line") { diff --git a/src/dynrpg_textplugin.h b/src/dynrpg_textplugin.h index 2c21b30ad95..82a53438e7b 100644 --- a/src/dynrpg_textplugin.h +++ b/src/dynrpg_textplugin.h @@ -26,7 +26,7 @@ namespace DynRpg { TextPlugin() : DynRpgPlugin("DynTextPlugin") {} ~TextPlugin() override; - bool Invoke(StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) override; + bool Invoke(Game_DynRpg& dynrpg_instance, StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) override; void Update() override; void Load(const std::vector&) override; std::vector Save() override; diff --git a/src/game_dynrpg.cpp b/src/game_dynrpg.cpp index 5f1ac91bb12..964706fecfa 100644 --- a/src/game_dynrpg.cpp +++ b/src/game_dynrpg.cpp @@ -364,7 +364,7 @@ bool Game_DynRpg::Invoke(StringView command, Game_Interpreter* interpreter) { return true; } - return Invoke(function_name, args); + return Invoke(function_name, args, interpreter); } bool Game_DynRpg::Invoke(StringView func, dyn_arg_list args, Game_Interpreter* interpreter) { @@ -373,7 +373,7 @@ bool Game_DynRpg::Invoke(StringView func, dyn_arg_list args, Game_Interpreter* i bool yield = false; for (auto& plugin: plugins) { - if (plugin->Invoke(func, args, yield, interpreter)) { + if (plugin->Invoke(*this, func, args, yield, interpreter)) { return !yield; } } diff --git a/src/game_dynrpg.h b/src/game_dynrpg.h index 7dc8f2f52cf..fd789b214d7 100644 --- a/src/game_dynrpg.h +++ b/src/game_dynrpg.h @@ -137,7 +137,7 @@ class Game_DynRpg { private: friend DynRpg::EasyRpgPlugin; - bool Invoke(StringView func, dyn_arg_list args, Game_Interpreter* interpreter = nullptr); + bool Invoke(StringView func, dyn_arg_list args, Game_Interpreter* interpreter); void InitPlugins(); using dyn_rpg_func = std::unordered_map; @@ -159,7 +159,7 @@ class DynRpgPlugin { virtual ~DynRpgPlugin() = default; StringView GetIdentifier() const { return identifier; } - virtual bool Invoke(StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) = 0; + virtual bool Invoke(Game_DynRpg& dynrpg_instance, StringView func, dyn_arg_list args, bool& do_yield, Game_Interpreter* interpreter) = 0; virtual void Update() {} virtual void Load(const std::vector&) {} virtual std::vector Save() { return {}; } diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index d08ec0ce1b3..c0c1aa9eccd 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -100,7 +100,7 @@ bool Game_Interpreter::IsRunning() const { // Setup. void Game_Interpreter::Push( - const std::vector& _list, + std::vector _list, int event_id, bool started_by_decision_key ) { @@ -114,7 +114,7 @@ void Game_Interpreter::Push( lcf::rpg::SaveEventExecFrame frame; frame.ID = _state.stack.size() + 1; - frame.commands = _list; + frame.commands = std::move(_list); frame.current_command = 0; frame.triggered_by_decision_key = started_by_decision_key; frame.event_id = event_id; diff --git a/src/game_interpreter.h b/src/game_interpreter.h index a24c51e9dd8..8af7b0f86f6 100644 --- a/src/game_interpreter.h +++ b/src/game_interpreter.h @@ -64,9 +64,9 @@ class Game_Interpreter void Update(bool reset_loop_count=true); void Push( - const std::vector& _list, - int _event_id, - bool started_by_decision_key = false + std::vector _list, + int _event_id, + bool started_by_decision_key = false ); void Push(Game_Event* ev); void Push(Game_Event* ev, const lcf::rpg::EventPage* page, bool triggered_by_decision_key); @@ -78,7 +78,6 @@ class Game_Interpreter bool ExecuteCommand(); virtual bool ExecuteCommand(lcf::rpg::EventCommand const& com); - /** * Returns a SaveEventExecState needed for the savefile. * diff --git a/src/player.cpp b/src/player.cpp index 665a9cf2d93..dc4a440c088 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -924,6 +924,7 @@ void Player::ResetGameObjects() { Main_Data::game_quit = std::make_unique(); Main_Data::game_switches_global = std::make_unique(); Main_Data::game_variables_global = std::make_unique(min_var, max_var); + Main_Data::game_dynrpg = std::make_unique(); Main_Data::game_ineluki = std::make_unique(); Game_Clock::ResetFrame(Game_Clock::now()); @@ -1550,4 +1551,3 @@ std::string Player::GetEngineVersion() { if (EngineVersion() > 0) return std::to_string(EngineVersion()); return std::string(); } -