From 8cf99822edd15654e77236e5081725cbf55fd107 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 2 Nov 2023 17:31:13 +0100 Subject: [PATCH 1/3] Add a death event to the Lua API --- apps/openmw/mwbase/luamanager.hpp | 1 + apps/openmw/mwlua/engineevents.cpp | 10 ++++++++++ apps/openmw/mwlua/engineevents.hpp | 7 ++++++- apps/openmw/mwlua/localscripts.cpp | 2 +- apps/openmw/mwlua/localscripts.hpp | 2 ++ apps/openmw/mwlua/luamanagerimp.hpp | 4 ++++ apps/openmw/mwmechanics/actors.cpp | 2 ++ .../source/reference/lua-scripting/engine_handlers.rst | 2 ++ 8 files changed, 28 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/luamanager.hpp b/apps/openmw/mwbase/luamanager.hpp index 06a68efe4a3..e4b16ff7255 100644 --- a/apps/openmw/mwbase/luamanager.hpp +++ b/apps/openmw/mwbase/luamanager.hpp @@ -53,6 +53,7 @@ namespace MWBase virtual void objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0; virtual void useItem(const MWWorld::Ptr& object, const MWWorld::Ptr& actor, bool force) = 0; virtual void exteriorCreated(MWWorld::CellStore& cell) = 0; + virtual void actorDied(const MWWorld::Ptr& actor) = 0; virtual void questUpdated(const ESM::RefId& questId, int stage) = 0; // `arg` is either forwarded from MWGui::pushGuiMode or empty diff --git a/apps/openmw/mwlua/engineevents.cpp b/apps/openmw/mwlua/engineevents.cpp index 0fbb13f1cff..7250acc8579 100644 --- a/apps/openmw/mwlua/engineevents.cpp +++ b/apps/openmw/mwlua/engineevents.cpp @@ -86,6 +86,16 @@ namespace MWLua void operator()(const OnNewExterior& event) const { mGlobalScripts.onNewExterior(GCell{ &event.mCell }); } + void operator()(const OnDeath& event) const + { + MWWorld::Ptr actor = getPtr(event.mActor); + if (!actor.isEmpty()) + { + if (auto* scripts = getLocalScripts(actor)) + scripts->onDeath(); + } + } + private: MWWorld::Ptr getPtr(ESM::RefNum id) const { diff --git a/apps/openmw/mwlua/engineevents.hpp b/apps/openmw/mwlua/engineevents.hpp index 7c706edcd0f..04a5ab4ebd2 100644 --- a/apps/openmw/mwlua/engineevents.hpp +++ b/apps/openmw/mwlua/engineevents.hpp @@ -51,7 +51,12 @@ namespace MWLua { MWWorld::CellStore& mCell; }; - using Event = std::variant; + struct OnDeath + { + ESM::RefNum mActor; + }; + using Event = std::variant; void clear() { mQueue.clear(); } void addToQueue(Event e) { mQueue.push_back(std::move(e)); } diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index 8cf383e9857..8dc8358aa80 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -170,7 +170,7 @@ namespace MWLua { this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData)); registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers, - &mOnTeleportedHandlers }); + &mOnTeleportedHandlers, &mOnDeathHandlers }); } void LocalScripts::setActive(bool active) diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index b87b628a893..05b34cbb96a 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -71,6 +71,7 @@ namespace MWLua void onConsume(const LObject& consumable) { callEngineHandlers(mOnConsumeHandlers, consumable); } void onActivated(const LObject& actor) { callEngineHandlers(mOnActivatedHandlers, actor); } void onTeleported() { callEngineHandlers(mOnTeleportedHandlers); } + void onDeath() { callEngineHandlers(mOnDeathHandlers); } void applyStatsCache(); @@ -83,6 +84,7 @@ namespace MWLua EngineHandlerList mOnConsumeHandlers{ "onConsume" }; EngineHandlerList mOnActivatedHandlers{ "onActivated" }; EngineHandlerList mOnTeleportedHandlers{ "onTeleported" }; + EngineHandlerList mOnDeathHandlers{ "onDeath" }; }; } diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 404820cc6bb..ed0b4e92578 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -82,6 +82,10 @@ namespace MWLua { mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell }); } + void actorDied(const MWWorld::Ptr& actor) override + { + mEngineEvents.addToQueue(EngineEvents::OnDeath{ getId(actor) }); + } void objectTeleported(const MWWorld::Ptr& ptr) override; void questUpdated(const ESM::RefId& questId, int stage) override; void uiModeChanged(const MWWorld::Ptr& arg) override; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3e7b075e620..73bd331de28 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1730,6 +1730,8 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).notifyDied(); ++mDeathCount[actor.getCellRef().getRefId()]; + + MWBase::Environment::get().getLuaManager()->actorDied(actor); } void Actors::resurrect(const MWWorld::Ptr& ptr) const diff --git a/docs/source/reference/lua-scripting/engine_handlers.rst b/docs/source/reference/lua-scripting/engine_handlers.rst index 1ffa1820f3b..b6e90a6bda4 100644 --- a/docs/source/reference/lua-scripting/engine_handlers.rst +++ b/docs/source/reference/lua-scripting/engine_handlers.rst @@ -79,6 +79,8 @@ Engine handler is a function defined by a script, that can be called by the engi - | Called on an actor when they consume an item (e.g. a potion). | Similarly to onActivated, the item has already been removed | from the actor's inventory, and the count was set to zero. + * - onDeath() + - Called when the actor dies. Note that actors that start out dead are ignored. **Only for local scripts attached to a player** From ad68b7e18bf2f5a9b8f880fc9ecc658c498577d8 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 4 Dec 2023 17:32:38 +0100 Subject: [PATCH 2/3] Turn onDeath the engine handler into OnDeath the regular event --- apps/openmw/mwlua/engineevents.cpp | 10 ---------- apps/openmw/mwlua/engineevents.hpp | 7 +------ apps/openmw/mwlua/localscripts.cpp | 2 +- apps/openmw/mwlua/localscripts.hpp | 2 -- apps/openmw/mwlua/luamanagerimp.cpp | 7 +++++++ apps/openmw/mwlua/luamanagerimp.hpp | 5 +---- .../reference/lua-scripting/engine_handlers.rst | 2 -- docs/source/reference/lua-scripting/events.rst | 12 ++++++++++++ 8 files changed, 22 insertions(+), 25 deletions(-) diff --git a/apps/openmw/mwlua/engineevents.cpp b/apps/openmw/mwlua/engineevents.cpp index 7250acc8579..0fbb13f1cff 100644 --- a/apps/openmw/mwlua/engineevents.cpp +++ b/apps/openmw/mwlua/engineevents.cpp @@ -86,16 +86,6 @@ namespace MWLua void operator()(const OnNewExterior& event) const { mGlobalScripts.onNewExterior(GCell{ &event.mCell }); } - void operator()(const OnDeath& event) const - { - MWWorld::Ptr actor = getPtr(event.mActor); - if (!actor.isEmpty()) - { - if (auto* scripts = getLocalScripts(actor)) - scripts->onDeath(); - } - } - private: MWWorld::Ptr getPtr(ESM::RefNum id) const { diff --git a/apps/openmw/mwlua/engineevents.hpp b/apps/openmw/mwlua/engineevents.hpp index 04a5ab4ebd2..7c706edcd0f 100644 --- a/apps/openmw/mwlua/engineevents.hpp +++ b/apps/openmw/mwlua/engineevents.hpp @@ -51,12 +51,7 @@ namespace MWLua { MWWorld::CellStore& mCell; }; - struct OnDeath - { - ESM::RefNum mActor; - }; - using Event = std::variant; + using Event = std::variant; void clear() { mQueue.clear(); } void addToQueue(Event e) { mQueue.push_back(std::move(e)); } diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index 8dc8358aa80..8cf383e9857 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -170,7 +170,7 @@ namespace MWLua { this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData)); registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers, - &mOnTeleportedHandlers, &mOnDeathHandlers }); + &mOnTeleportedHandlers }); } void LocalScripts::setActive(bool active) diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index 05b34cbb96a..b87b628a893 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -71,7 +71,6 @@ namespace MWLua void onConsume(const LObject& consumable) { callEngineHandlers(mOnConsumeHandlers, consumable); } void onActivated(const LObject& actor) { callEngineHandlers(mOnActivatedHandlers, actor); } void onTeleported() { callEngineHandlers(mOnTeleportedHandlers); } - void onDeath() { callEngineHandlers(mOnDeathHandlers); } void applyStatsCache(); @@ -84,7 +83,6 @@ namespace MWLua EngineHandlerList mOnConsumeHandlers{ "onConsume" }; EngineHandlerList mOnActivatedHandlers{ "onActivated" }; EngineHandlerList mOnTeleportedHandlers{ "onTeleported" }; - EngineHandlerList mOnDeathHandlers{ "onDeath" }; }; } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 48b0c153819..66e8ff7538b 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -344,6 +344,13 @@ namespace MWLua playerScripts->uiModeChanged(argId, false); } + void LuaManager::actorDied(const MWWorld::Ptr& actor) + { + if (actor.isEmpty()) + return; + mLuaEvents.addLocalEvent({ getId(actor), "OnDeath", {} }); + } + void LuaManager::useItem(const MWWorld::Ptr& object, const MWWorld::Ptr& actor, bool force) { MWBase::Environment::get().getWorldModel()->registerPtr(object); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index ed0b4e92578..ae166895628 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -82,13 +82,10 @@ namespace MWLua { mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell }); } - void actorDied(const MWWorld::Ptr& actor) override - { - mEngineEvents.addToQueue(EngineEvents::OnDeath{ getId(actor) }); - } void objectTeleported(const MWWorld::Ptr& ptr) override; void questUpdated(const ESM::RefId& questId, int stage) override; void uiModeChanged(const MWWorld::Ptr& arg) override; + void actorDied(const MWWorld::Ptr& actor) override; MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override; diff --git a/docs/source/reference/lua-scripting/engine_handlers.rst b/docs/source/reference/lua-scripting/engine_handlers.rst index b6e90a6bda4..1ffa1820f3b 100644 --- a/docs/source/reference/lua-scripting/engine_handlers.rst +++ b/docs/source/reference/lua-scripting/engine_handlers.rst @@ -79,8 +79,6 @@ Engine handler is a function defined by a script, that can be called by the engi - | Called on an actor when they consume an item (e.g. a potion). | Similarly to onActivated, the item has already been removed | from the actor's inventory, and the count was set to zero. - * - onDeath() - - Called when the actor dies. Note that actors that start out dead are ignored. **Only for local scripts attached to a player** diff --git a/docs/source/reference/lua-scripting/events.rst b/docs/source/reference/lua-scripting/events.rst index 7f0a764b86c..7a08ef4d6e4 100644 --- a/docs/source/reference/lua-scripting/events.rst +++ b/docs/source/reference/lua-scripting/events.rst @@ -6,6 +6,18 @@ Built-in events Actor events ------------ +**OnDeath** + +This event is sent to an actor's local script when that actor dies. + +.. code-block:: Lua + + eventHandlers = { + OnDeath = function() + print('Alas, ye hardly knew me!') + end + } + **StartAIPackage, RemoveAIPackages** Any script can send to any actor (except player, for player will be ignored) events ``StartAIPackage`` and ``RemoveAIPackages``. From efb819b9d2c3de689a6e183b2697286552c2e0fa Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 4 Dec 2023 17:50:18 +0100 Subject: [PATCH 3/3] Rename to Died --- apps/openmw/mwlua/luamanagerimp.cpp | 2 +- docs/source/reference/lua-scripting/events.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 66e8ff7538b..d34518d5589 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -348,7 +348,7 @@ namespace MWLua { if (actor.isEmpty()) return; - mLuaEvents.addLocalEvent({ getId(actor), "OnDeath", {} }); + mLuaEvents.addLocalEvent({ getId(actor), "Died", {} }); } void LuaManager::useItem(const MWWorld::Ptr& object, const MWWorld::Ptr& actor, bool force) diff --git a/docs/source/reference/lua-scripting/events.rst b/docs/source/reference/lua-scripting/events.rst index 7a08ef4d6e4..282e3d1173d 100644 --- a/docs/source/reference/lua-scripting/events.rst +++ b/docs/source/reference/lua-scripting/events.rst @@ -6,14 +6,14 @@ Built-in events Actor events ------------ -**OnDeath** +**Died** This event is sent to an actor's local script when that actor dies. .. code-block:: Lua eventHandlers = { - OnDeath = function() + Died = function() print('Alas, ye hardly knew me!') end }