diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 29147a826b..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,14 +111,40 @@ 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 { + const MWWorld::Class& cls = o.ptr().getClass(); + verifyPlayer(player); + verifyNpc(cls); + return cls.getNpcStats(o.ptr()).getBaseDisposition(); + }; + + 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(); + verifyPlayer(player); + verifyNpc(cls); + cls.getNpcStats(o.ptr()).setBaseDisposition(value); + }; + + 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(); + verifyPlayer(player); + verifyNpc(cls); + 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..9efdeeb018 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 (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 (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. +-- @param #number value Base disposition modification value + --- -- Get the total weight that the actor can carry. -- @function [parent=#NPC] getCapacity