From dafe858cb4e115f8acaa83147284793d275bf1e0 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 31 Oct 2023 10:28:52 +0100 Subject: [PATCH] Add types.Player.sendMenuEvent --- apps/openmw/mwlua/luaevents.cpp | 9 ++++++++ apps/openmw/mwlua/luaevents.hpp | 8 +++++++- apps/openmw/mwlua/luamanagerimp.cpp | 1 + apps/openmw/mwlua/luamanagerimp.hpp | 2 +- apps/openmw/mwlua/types/player.cpp | 32 ++++++++++++++++------------- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwlua/luaevents.cpp b/apps/openmw/mwlua/luaevents.cpp index 02ea3415d2..4ffb4fc1cc 100644 --- a/apps/openmw/mwlua/luaevents.cpp +++ b/apps/openmw/mwlua/luaevents.cpp @@ -13,6 +13,7 @@ #include "globalscripts.hpp" #include "localscripts.hpp" +#include "menuscripts.hpp" namespace MWLua { @@ -23,6 +24,7 @@ namespace MWLua mLocalEventBatch.clear(); mNewGlobalEventBatch.clear(); mNewLocalEventBatch.clear(); + mMenuEvents.clear(); } void LuaEvents::finalizeEventBatch() @@ -51,6 +53,13 @@ namespace MWLua mLocalEventBatch.clear(); } + void LuaEvents::callMenuEventHandlers() + { + for (const Global& e : mMenuEvents) + mMenuScripts.receiveEvent(e.mEventName, e.mEventData); + mMenuEvents.clear(); + } + template static void saveEvent(ESM::ESMWriter& esm, ESM::RefNum dest, const Event& event) { diff --git a/apps/openmw/mwlua/luaevents.hpp b/apps/openmw/mwlua/luaevents.hpp index 5eeae46538..3890b45b6d 100644 --- a/apps/openmw/mwlua/luaevents.hpp +++ b/apps/openmw/mwlua/luaevents.hpp @@ -23,12 +23,14 @@ namespace MWLua { class GlobalScripts; + class MenuScripts; class LuaEvents { public: - explicit LuaEvents(GlobalScripts& globalScripts) + explicit LuaEvents(GlobalScripts& globalScripts, MenuScripts& menuScripts) : mGlobalScripts(globalScripts) + , mMenuScripts(menuScripts) { } @@ -45,11 +47,13 @@ namespace MWLua }; void addGlobalEvent(Global event) { mNewGlobalEventBatch.push_back(std::move(event)); } + void addMenuEvent(Global event) { mMenuEvents.push_back(std::move(event)); } void addLocalEvent(Local event) { mNewLocalEventBatch.push_back(std::move(event)); } void clear(); void finalizeEventBatch(); void callEventHandlers(); + void callMenuEventHandlers(); void load(lua_State* lua, ESM::ESMReader& esm, const std::map& contentFileMapping, const LuaUtil::UserdataSerializer* serializer); @@ -57,10 +61,12 @@ namespace MWLua private: GlobalScripts& mGlobalScripts; + MenuScripts& mMenuScripts; std::vector mNewGlobalEventBatch; std::vector mNewLocalEventBatch; std::vector mGlobalEventBatch; std::vector mLocalEventBatch; + std::vector mMenuEvents; }; } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 77ddfcc4a7..52b5dace3b 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -229,6 +229,7 @@ namespace MWLua playerScripts->processInputEvent(event); } mInputEvents.clear(); + mLuaEvents.callMenuEventHandlers(); mMenuScripts.update(0); if (playerScripts) playerScripts->onFrame(MWBase::Environment::get().getWorld()->getTimeManager()->isPaused() diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index b16e81082b..53031516a8 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -172,7 +172,7 @@ namespace MWLua MWWorld::Ptr mPlayer; - LuaEvents mLuaEvents{ mGlobalScripts }; + LuaEvents mLuaEvents{ mGlobalScripts, mMenuScripts }; EngineEvents mEngineEvents{ mGlobalScripts }; std::vector mInputEvents; diff --git a/apps/openmw/mwlua/types/player.cpp b/apps/openmw/mwlua/types/player.cpp index cef0753817..3acfec12b7 100644 --- a/apps/openmw/mwlua/types/player.cpp +++ b/apps/openmw/mwlua/types/player.cpp @@ -35,14 +35,18 @@ namespace sol namespace MWLua { + static void verifyPlayer(const Object& player) + { + if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) + throw std::runtime_error("The argument must be a player!"); + } void addPlayerQuestBindings(sol::table& player, const Context& context) { MWBase::Journal* const journal = MWBase::Environment::get().getJournal(); player["quests"] = [](const Object& player) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player!"); + verifyPlayer(player); bool allowChanges = dynamic_cast(&player) != nullptr || dynamic_cast(&player) != nullptr; return Quests{ .mMutable = allowChanges }; @@ -134,28 +138,28 @@ namespace MWLua MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); player["getControlSwitch"] = [input](const Object& player, std::string_view key) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player."); + verifyPlayer(player); return input->getControlSwitch(key); }; + player["setControlSwitch"] = [input](const Object& player, std::string_view key, bool v) { + verifyPlayer(player); + if (dynamic_cast(&player) && !dynamic_cast(&player)) + throw std::runtime_error("Only player and global scripts can toggle control switches."); + input->toggleControlSwitch(key, v); + }; player["isTeleportingEnabled"] = [](const Object& player) -> bool { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player."); + verifyPlayer(player); return MWBase::Environment::get().getWorld()->isTeleportingEnabled(); }; player["setTeleportingEnabled"] = [](const Object& player, bool state) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player."); + verifyPlayer(player); if (dynamic_cast(&player) && !dynamic_cast(&player)) throw std::runtime_error("Only player and global scripts can toggle teleportation."); MWBase::Environment::get().getWorld()->enableTeleporting(state); }; - player["setControlSwitch"] = [input](const Object& player, std::string_view key, bool v) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player."); - if (dynamic_cast(&player) && !dynamic_cast(&player)) - throw std::runtime_error("Only player and global scripts can toggle control switches."); - input->toggleControlSwitch(key, v); + player["sendMenuEvent"] = [context](const Object& player, std::string eventName, const sol::object& eventData) { + verifyPlayer(player); + context.mLuaEvents->addMenuEvent({ std::move(eventName), LuaUtil::serialize(eventData) }); }; }