From 70eacbbefc666b6366628206028a0b5e9fcd1183 Mon Sep 17 00:00:00 2001 From: uramer Date: Fri, 20 May 2022 19:27:21 +0000 Subject: [PATCH] onObjectActive and onItemActive Lua engine handlers --- apps/openmw/mwlua/globalscripts.hpp | 12 +++++++++- apps/openmw/mwlua/luamanagerimp.cpp | 22 +++++++++++++------ apps/openmw/mwlua/luamanagerimp.hpp | 2 +- apps/openmw/mwlua/worldview.hpp | 3 +++ .../lua-scripting/engine_handlers.rst | 5 +++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwlua/globalscripts.hpp b/apps/openmw/mwlua/globalscripts.hpp index 2737dabaca..2b40aabd9d 100644 --- a/apps/openmw/mwlua/globalscripts.hpp +++ b/apps/openmw/mwlua/globalscripts.hpp @@ -19,15 +19,25 @@ namespace MWLua GlobalScripts(LuaUtil::LuaState* lua) : LuaUtil::ScriptsContainer(lua, "Global", ESM::LuaScriptCfg::sGlobal) { - registerEngineHandlers({&mActorActiveHandlers, &mNewGameHandlers, &mPlayerAddedHandlers}); + registerEngineHandlers({ + &mObjectActiveHandlers, + &mActorActiveHandlers, + &mItemActiveHandlers, + &mNewGameHandlers, + &mPlayerAddedHandlers + }); } void newGameStarted() { callEngineHandlers(mNewGameHandlers); } + void objectActive(const GObject& obj) { callEngineHandlers(mObjectActiveHandlers, obj); } void actorActive(const GObject& obj) { callEngineHandlers(mActorActiveHandlers, obj); } + void itemActive(const GObject& obj) { callEngineHandlers(mItemActiveHandlers, obj); } void playerAdded(const GObject& obj) { callEngineHandlers(mPlayerAddedHandlers, obj); } private: + EngineHandlerList mObjectActiveHandlers{"onObjectActive"}; EngineHandlerList mActorActiveHandlers{"onActorActive"}; + EngineHandlerList mItemActiveHandlers{"onItemActive"}; EngineHandlerList mNewGameHandlers{"onNewGame"}; EngineHandlerList mPlayerAddedHandlers{"onPlayerAdded"}; }; diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 5cfc52d737..6894208c07 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -209,15 +209,23 @@ namespace MWLua mGlobalScripts.newGameStarted(); } - for (ObjectId id : mActorAddedEvents) + for (ObjectId id : mObjectAddedEvents) { GObject obj(id, objectRegistry); if (obj.isValid()) - mGlobalScripts.actorActive(obj); + { + mGlobalScripts.objectActive(obj); + const MWWorld::Class& objClass = obj.ptr().getClass(); + if (objClass.isActor()) + mGlobalScripts.actorActive(obj); + if (mWorldView.isItem(obj.ptr())) + mGlobalScripts.itemActive(obj); + } else if (luaDebug) - Log(Debug::Verbose) << "Can not call onActorActive engine handler: object" << idToString(id) << " is already removed"; + Log(Debug::Verbose) << "Could not resolve a Lua object added event: object" << idToString(id) + << " is already removed"; } - mActorAddedEvents.clear(); + mObjectAddedEvents.clear(); if (!mWorldView.isPaused()) mGlobalScripts.update(frameDuration); @@ -267,7 +275,7 @@ namespace MWLua mLocalEvents.clear(); mGlobalEvents.clear(); mInputEvents.clear(); - mActorAddedEvents.clear(); + mObjectAddedEvents.clear(); mLocalEngineEvents.clear(); mNewGameStarted = false; mPlayerChanged = false; @@ -338,8 +346,8 @@ namespace MWLua mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}}); } - if (ptr.getClass().isActor() && ptr != mPlayer) - mActorAddedEvents.push_back(getId(ptr)); + if (ptr != mPlayer) + mObjectAddedEvents.push_back(getId(ptr)); } void LuaManager::objectRemovedFromScene(const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 0c08deb4fb..871ab0af26 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -162,7 +162,7 @@ namespace MWLua std::unique_ptr mLocalLoader; std::vector mInputEvents; - std::vector mActorAddedEvents; + std::vector mObjectAddedEvents; struct CallbackWithData { diff --git a/apps/openmw/mwlua/worldview.hpp b/apps/openmw/mwlua/worldview.hpp index 004fcfc0c3..accf2758f0 100644 --- a/apps/openmw/mwlua/worldview.hpp +++ b/apps/openmw/mwlua/worldview.hpp @@ -62,6 +62,9 @@ namespace MWLua void load(ESM::ESMReader& esm); void save(ESM::ESMWriter& esm) const; + // TODO: move this functionality to MWClass + bool isItem(const MWWorld::Ptr& ptr) { return chooseGroup(ptr) == &mItemsInScene; } + private: struct ObjectGroup { diff --git a/docs/source/reference/lua-scripting/engine_handlers.rst b/docs/source/reference/lua-scripting/engine_handlers.rst index 524314341c..ca05c9b8e1 100644 --- a/docs/source/reference/lua-scripting/engine_handlers.rst +++ b/docs/source/reference/lua-scripting/engine_handlers.rst @@ -40,8 +40,13 @@ Engine handler is a function defined by a script, that can be called by the engi - New game is started * - onPlayerAdded(player) - Player added to the game world. The argument is a `Game object`. + * - onObjectActive(object) + - Object becomes active. * - onActorActive(actor) - Actor (NPC or Creature) becomes active. + * - onItemActive(item) + - | Item (Weapon, Potion, ...) becomes active in a cell. + | Does not apply to items in inventories or containers. **Only for local scripts**