From f683adeb145534ca2107862bfd24e09ab371dd79 Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Wed, 29 May 2024 23:11:56 +0200 Subject: [PATCH 1/3] Add [get,set,mod]BaseDisposition functions to npc type --- apps/openmw/mwlua/types/npc.cpp | 28 ++++++++++++++++++++++++++++ files/lua_api/openmw/types.lua | 21 +++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 29147a826b..d791285cdd 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -107,6 +107,34 @@ namespace MWLua return MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(o.ptr()); }; + npc["getBaseDisposition"] = [](const Object& o, const Object& player) -> int { + if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) + throw std::runtime_error("The argument must be a player!"); + const MWWorld::Class& cls = o.ptr().getClass(); + if (!cls.isNpc()) + throw std::runtime_error("NPC expected"); + return cls.getNpcStats(o.ptr()).getBaseDisposition(); + }; + + npc["setBaseDisposition"] = [](const Object& o, const Object& player, int value) { + if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) + throw std::runtime_error("The argument must be a player!"); + const MWWorld::Class& cls = o.ptr().getClass(); + if (!cls.isNpc()) + throw std::runtime_error("NPC expected"); + cls.getNpcStats(o.ptr()).setBaseDisposition(value); + }; + + npc["modBaseDisposition"] = [](const Object& o, const Object& player, int value) { + if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) + throw std::runtime_error("The argument must be a player!"); + const MWWorld::Class& cls = o.ptr().getClass(); + if (!cls.isNpc()) + throw std::runtime_error("NPC expected"); + auto& stats = cls.getNpcStats(o.ptr()); + stats.setBaseDisposition(stats.getBaseDisposition() + value); + }; + npc["getFactionRank"] = [](const Object& actor, std::string_view faction) { const MWWorld::Ptr ptr = actor.ptr(); ESM::RefId factionId = parseFactionId(faction); diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index 0bfafb17c8..aba3d06363 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -1003,6 +1003,27 @@ -- @param openmw.core#GameObject player The player that you want to check the disposition for. -- @return #number +--- +-- Returns the current base disposition of the provided NPC. This is their base disposition, before modifiers such as personality and faction relations are taken into account. +-- @function [parent=#NPC] getBaseDisposition +-- @param openmw.core#GameObject object +-- @param openmw.core#GameObject player The player that you want to check the disposition for. +-- @return #number + +--- +-- Set the base disposition of the provided NPC. +-- @function [parent=#NPC] setBaseDisposition +-- @param openmw.core#GameObject object +-- @param openmw.core#GameObject player The player that you want to set the disposition for. +-- @param #number value BaseDisposition is set to this value + +--- +-- Modify the base disposition of the provided NPC by a certain amount. +-- @function [parent=#NPC] modBaseDisposition +-- @param openmw.core#GameObject object +-- @param openmw.core#GameObject player The player that you want to modify the disposition for. +-- @param #number value Base disposition modification value + --- -- Get the total weight that the actor can carry. -- @function [parent=#NPC] getCapacity From da4531faa0d82a7785abd6d268f2fecae47ff57e Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Fri, 31 May 2024 18:52:33 +0200 Subject: [PATCH 2/3] rename modBaseDisposition to modifyBaseDisposition --- apps/openmw/mwlua/types/npc.cpp | 2 +- files/lua_api/openmw/types.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index d791285cdd..59e0c1142b 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -125,7 +125,7 @@ namespace MWLua cls.getNpcStats(o.ptr()).setBaseDisposition(value); }; - npc["modBaseDisposition"] = [](const Object& o, const Object& player, int value) { + npc["modifyBaseDisposition"] = [](const Object& o, const Object& player, int value) { if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) throw std::runtime_error("The argument must be a player!"); const MWWorld::Class& cls = o.ptr().getClass(); diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index aba3d06363..f521be71dc 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -1015,11 +1015,11 @@ -- @function [parent=#NPC] setBaseDisposition -- @param openmw.core#GameObject object -- @param openmw.core#GameObject player The player that you want to set the disposition for. --- @param #number value BaseDisposition is set to this value +-- @param #number value Base disposition is set to this value --- -- Modify the base disposition of the provided NPC by a certain amount. --- @function [parent=#NPC] modBaseDisposition +-- @function [parent=#NPC] modifyBaseDisposition -- @param openmw.core#GameObject object -- @param openmw.core#GameObject player The player that you want to modify the disposition for. -- @param #number value Base disposition modification value From ed26708e4da1968940be244f4cf53ac171d3917d Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Wed, 5 Jun 2024 17:14:23 +0200 Subject: [PATCH 3/3] more dry + restrict mutation of disposition to global and on self --- apps/openmw/mwlua/types/npc.cpp | 46 ++++++++++++++++++++------------- files/lua_api/openmw/types.lua | 4 +-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 59e0c1142b..9b500dff4f 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -50,6 +50,18 @@ namespace throw std::runtime_error("Faction '" + std::string(faction) + "' does not exist"); return id; } + + void verifyPlayer(const MWLua::Object& o) + { + if (o.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) + throw std::runtime_error("The argument must be a player!"); + } + + void verifyNpc(const MWWorld::Class& cls) + { + if (!cls.isNpc()) + throw std::runtime_error("The argument must be a NPC!"); + } } namespace MWLua @@ -99,38 +111,36 @@ namespace MWLua }; npc["getDisposition"] = [](const Object& o, const Object& player) -> int { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player!"); const MWWorld::Class& cls = o.ptr().getClass(); - if (!cls.isNpc()) - throw std::runtime_error("NPC expected"); + verifyPlayer(player); + verifyNpc(cls); return MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(o.ptr()); }; npc["getBaseDisposition"] = [](const Object& o, const Object& player) -> int { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player!"); const MWWorld::Class& cls = o.ptr().getClass(); - if (!cls.isNpc()) - throw std::runtime_error("NPC expected"); + verifyPlayer(player); + verifyNpc(cls); return cls.getNpcStats(o.ptr()).getBaseDisposition(); }; - npc["setBaseDisposition"] = [](const Object& o, const Object& player, int value) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player!"); + npc["setBaseDisposition"] = [](Object& o, const Object& player, int value) { + if (dynamic_cast(&o) && !dynamic_cast(&o)) + throw std::runtime_error("Local scripts can modify only self"); + const MWWorld::Class& cls = o.ptr().getClass(); - if (!cls.isNpc()) - throw std::runtime_error("NPC expected"); + verifyPlayer(player); + verifyNpc(cls); cls.getNpcStats(o.ptr()).setBaseDisposition(value); }; - npc["modifyBaseDisposition"] = [](const Object& o, const Object& player, int value) { - if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) - throw std::runtime_error("The argument must be a player!"); + npc["modifyBaseDisposition"] = [](Object& o, const Object& player, int value) { + if (dynamic_cast(&o) && !dynamic_cast(&o)) + throw std::runtime_error("Local scripts can modify only self"); + const MWWorld::Class& cls = o.ptr().getClass(); - if (!cls.isNpc()) - throw std::runtime_error("NPC expected"); + verifyPlayer(player); + verifyNpc(cls); auto& stats = cls.getNpcStats(o.ptr()); stats.setBaseDisposition(stats.getBaseDisposition() + value); }; diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index f521be71dc..9efdeeb018 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -1011,14 +1011,14 @@ -- @return #number --- --- Set the base disposition of the provided NPC. +-- Set the base disposition of the provided NPC (only in global scripts or on self). -- @function [parent=#NPC] setBaseDisposition -- @param openmw.core#GameObject object -- @param openmw.core#GameObject player The player that you want to set the disposition for. -- @param #number value Base disposition is set to this value --- --- Modify the base disposition of the provided NPC by a certain amount. +-- Modify the base disposition of the provided NPC by a certain amount (only in global scripts or on self). -- @function [parent=#NPC] modifyBaseDisposition -- @param openmw.core#GameObject object -- @param openmw.core#GameObject player The player that you want to modify the disposition for.