From 9f80d68795ef93ad549b3a358807a12a89815aff Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Fri, 1 Sep 2023 16:39:33 -0500 Subject: [PATCH 01/16] add servicesOffered to npc and creature records --- apps/openmw/mwlua/types/creature.cpp | 47 ++++++++++++++++++++++++++ apps/openmw/mwlua/types/npc.cpp | 49 ++++++++++++++++++++++++++++ files/lua_api/openmw/types.lua | 2 ++ 3 files changed, 98 insertions(+) diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index 08c0dd021c..484de9d969 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -1,6 +1,7 @@ #include "types.hpp" #include +#include #include #include #include @@ -48,5 +49,51 @@ namespace MWLua record["soulValue"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mSoul; }); record["type"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mType; }); record["baseGold"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mGold; }); + record["servicesOffered"] = sol::readonly_property([](const ESM::Creature& rec) { + std::vector providedServices; + + int mServices = rec.mAiData.mServices; + if (mServices & ESM::NPC::Spells) + providedServices.push_back("Spells"); + if (mServices & ESM::NPC::Spellmaking) + providedServices.push_back("Spellmaking"); + if (mServices & ESM::NPC::Enchanting) + providedServices.push_back("Enchanting"); + if (mServices & ESM::NPC::Repair) + providedServices.push_back("Repair"); + if (mServices & ESM::NPC::AllItems) + providedServices.push_back("Barter"); + + if (mServices & ESM::NPC::Weapon) + providedServices.push_back("Weapon"); + if (mServices & ESM::NPC::Armor) + providedServices.push_back("Armor"); + if (mServices & ESM::NPC::Clothing) + providedServices.push_back("Clothing"); + if (mServices & ESM::NPC::Books) + providedServices.push_back("Books"); + if (mServices & ESM::NPC::Ingredients) + providedServices.push_back("Ingredients"); + if (mServices & ESM::NPC::Picks) + providedServices.push_back("Picks"); + if (mServices & ESM::NPC::Probes) + providedServices.push_back("Probes"); + if (mServices & ESM::NPC::Lights) + providedServices.push_back("Lights"); + if (mServices & ESM::NPC::Apparatus) + providedServices.push_back("Apparatus"); + if (mServices & ESM::NPC::RepairItem) + providedServices.push_back("RepairItem"); + if (mServices & ESM::NPC::Misc) + providedServices.push_back("Misc"); + if (mServices & ESM::NPC::Potions) + providedServices.push_back("Potions"); + if (mServices & ESM::NPC::MagicItems) + providedServices.push_back("MagicItems"); + if (rec.getTransport().size() > 0) + providedServices.push_back("Travel"); + + return providedServices; + }); } } diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index d1a91cabc9..6d7b62b222 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -3,6 +3,7 @@ #include #include +#include "apps/openmw/mwworld/worldmodel.hpp" #include #include #include @@ -57,6 +58,54 @@ namespace MWLua else throw std::runtime_error("NPC or Player expected"); }; + record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) { + std::vector providedServices; + + int mServices = rec.mAiData.mServices; + if (mServices & ESM::NPC::Spells) + providedServices.push_back("Spells"); + if (mServices & ESM::NPC::Spellmaking) + providedServices.push_back("Spellmaking"); + if (mServices & ESM::NPC::Enchanting) + providedServices.push_back("Enchanting"); + if (mServices & ESM::NPC::Training) + providedServices.push_back("Training"); + if (mServices & ESM::NPC::Repair) + providedServices.push_back("Repair"); + if (mServices & ESM::NPC::AllItems) + providedServices.push_back("Barter"); + + if (mServices & ESM::NPC::Weapon) + providedServices.push_back("Weapon"); + if (mServices & ESM::NPC::Armor) + providedServices.push_back("Armor"); + if (mServices & ESM::NPC::Clothing) + providedServices.push_back("Clothing"); + if (mServices & ESM::NPC::Books) + providedServices.push_back("Books"); + if (mServices & ESM::NPC::Ingredients) + providedServices.push_back("Ingredients"); + if (mServices & ESM::NPC::Picks) + providedServices.push_back("Picks"); + if (mServices & ESM::NPC::Probes) + providedServices.push_back("Probes"); + if (mServices & ESM::NPC::Lights) + providedServices.push_back("Lights"); + if (mServices & ESM::NPC::Apparatus) + providedServices.push_back("Apparatus"); + if (mServices & ESM::NPC::RepairItem) + providedServices.push_back("RepairItem"); + if (mServices & ESM::NPC::Misc) + providedServices.push_back("Misc"); + if (mServices & ESM::NPC::Potions) + providedServices.push_back("Potions"); + if (mServices & ESM::NPC::MagicItems) + providedServices.push_back("MagicItems"); + if (rec.getTransport().size() > 0) + providedServices.push_back("Travel"); + + return providedServices; + }); npc["getDisposition"] = [](const Object& o, const Object& player) -> int { if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index ea5368efde..b4b21dcab9 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -701,6 +701,7 @@ -- @field #number soulValue The soul value of the creature record -- @field #number type The @{#Creature.TYPE} of the creature -- @field #number baseGold The base barter gold of the creature +-- @field #list<#string> servicesOffered The services of the creature, in a table. Possible entries are: Spells, Spellmaking, Enchanting, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. --- @{#NPC} functions @@ -750,6 +751,7 @@ -- @field #number baseGold The base barter gold of the NPC -- @field #number baseDisposition NPC's starting disposition -- @field #bool isMale The gender setting of the NPC +-- @field #list<#string> servicesOffered The services of the creature, in a table. Possible entries are: Spells, Spellmaking, Enchanting, Training, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. -------------------------------------------------------------------------------- From aba63c0145ddb363a62326948c696e7699dcf9e2 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Fri, 1 Sep 2023 16:44:58 -0500 Subject: [PATCH 02/16] Shorten, move to the correct place --- apps/openmw/mwlua/types/creature.cpp | 55 +++++++-------------- apps/openmw/mwlua/types/npc.cpp | 71 +++++++++------------------- 2 files changed, 39 insertions(+), 87 deletions(-) diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index 484de9d969..8e8e875745 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -51,48 +51,25 @@ namespace MWLua record["baseGold"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mGold; }); record["servicesOffered"] = sol::readonly_property([](const ESM::Creature& rec) { std::vector providedServices; + std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, + { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, + { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, + { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, + { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, + { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, + { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, + { ESM::NPC::MagicItems, "MagicItems" } }; int mServices = rec.mAiData.mServices; - if (mServices & ESM::NPC::Spells) - providedServices.push_back("Spells"); - if (mServices & ESM::NPC::Spellmaking) - providedServices.push_back("Spellmaking"); - if (mServices & ESM::NPC::Enchanting) - providedServices.push_back("Enchanting"); - if (mServices & ESM::NPC::Repair) - providedServices.push_back("Repair"); - if (mServices & ESM::NPC::AllItems) - providedServices.push_back("Barter"); - - if (mServices & ESM::NPC::Weapon) - providedServices.push_back("Weapon"); - if (mServices & ESM::NPC::Armor) - providedServices.push_back("Armor"); - if (mServices & ESM::NPC::Clothing) - providedServices.push_back("Clothing"); - if (mServices & ESM::NPC::Books) - providedServices.push_back("Books"); - if (mServices & ESM::NPC::Ingredients) - providedServices.push_back("Ingredients"); - if (mServices & ESM::NPC::Picks) - providedServices.push_back("Picks"); - if (mServices & ESM::NPC::Probes) - providedServices.push_back("Probes"); - if (mServices & ESM::NPC::Lights) - providedServices.push_back("Lights"); - if (mServices & ESM::NPC::Apparatus) - providedServices.push_back("Apparatus"); - if (mServices & ESM::NPC::RepairItem) - providedServices.push_back("RepairItem"); - if (mServices & ESM::NPC::Misc) - providedServices.push_back("Misc"); - if (mServices & ESM::NPC::Potions) - providedServices.push_back("Potions"); - if (mServices & ESM::NPC::MagicItems) - providedServices.push_back("MagicItems"); - if (rec.getTransport().size() > 0) + for (const auto& entry : serviceNames) + { + if (mServices & entry.first) + { + providedServices.push_back(entry.second); + } + } + if (!rec.getTransport().empty()) providedServices.push_back("Travel"); - return providedServices; }); } diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 6d7b62b222..5b24005e16 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -50,6 +50,29 @@ namespace MWLua record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); + record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) { + std::vector providedServices; + std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, + { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, + { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, + { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, + { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, + { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, + { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, + { ESM::NPC::MagicItems, "MagicItems" } }; + + int mServices = rec.mAiData.mServices; + for (const auto& entry : serviceNames) + { + if (mServices & entry.first) + { + providedServices.push_back(entry.second); + } + } + if (!rec.getTransport().empty()) + providedServices.push_back("Travel"); + return providedServices; + }); // This function is game-specific, in future we should replace it with something more universal. npc["isWerewolf"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); @@ -58,54 +81,6 @@ namespace MWLua else throw std::runtime_error("NPC or Player expected"); }; - record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) { - std::vector providedServices; - - int mServices = rec.mAiData.mServices; - if (mServices & ESM::NPC::Spells) - providedServices.push_back("Spells"); - if (mServices & ESM::NPC::Spellmaking) - providedServices.push_back("Spellmaking"); - if (mServices & ESM::NPC::Enchanting) - providedServices.push_back("Enchanting"); - if (mServices & ESM::NPC::Training) - providedServices.push_back("Training"); - if (mServices & ESM::NPC::Repair) - providedServices.push_back("Repair"); - if (mServices & ESM::NPC::AllItems) - providedServices.push_back("Barter"); - - if (mServices & ESM::NPC::Weapon) - providedServices.push_back("Weapon"); - if (mServices & ESM::NPC::Armor) - providedServices.push_back("Armor"); - if (mServices & ESM::NPC::Clothing) - providedServices.push_back("Clothing"); - if (mServices & ESM::NPC::Books) - providedServices.push_back("Books"); - if (mServices & ESM::NPC::Ingredients) - providedServices.push_back("Ingredients"); - if (mServices & ESM::NPC::Picks) - providedServices.push_back("Picks"); - if (mServices & ESM::NPC::Probes) - providedServices.push_back("Probes"); - if (mServices & ESM::NPC::Lights) - providedServices.push_back("Lights"); - if (mServices & ESM::NPC::Apparatus) - providedServices.push_back("Apparatus"); - if (mServices & ESM::NPC::RepairItem) - providedServices.push_back("RepairItem"); - if (mServices & ESM::NPC::Misc) - providedServices.push_back("Misc"); - if (mServices & ESM::NPC::Potions) - providedServices.push_back("Potions"); - if (mServices & ESM::NPC::MagicItems) - providedServices.push_back("MagicItems"); - if (rec.getTransport().size() > 0) - providedServices.push_back("Travel"); - - return providedServices; - }); npc["getDisposition"] = [](const Object& o, const Object& player) -> int { if (player.ptr() != MWBase::Environment::get().getWorld()->getPlayerPtr()) From 85d47dd715b54b87f6844291e1f17a8a71e7505a Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Fri, 1 Sep 2023 17:53:28 -0500 Subject: [PATCH 03/16] Add return value --- apps/openmw/mwlua/types/creature.cpp | 2 +- apps/openmw/mwlua/types/npc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index 8e8e875745..e6ed260a30 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -49,7 +49,7 @@ namespace MWLua record["soulValue"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mSoul; }); record["type"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mType; }); record["baseGold"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mGold; }); - record["servicesOffered"] = sol::readonly_property([](const ESM::Creature& rec) { + record["servicesOffered"] = sol::readonly_property([](const ESM::Creature& rec) -> std::vector { std::vector providedServices; std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 5b24005e16..167658aefa 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -50,7 +50,7 @@ namespace MWLua record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); - record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) { + record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) -> std::vector { std::vector providedServices; std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, From 44303ed8ca3c934603224b31c773bcbef118a019 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 14:10:50 -0500 Subject: [PATCH 04/16] Move services to new HPP --- apps/openmw/mwlua/types/actor.hpp | 54 ++++++++++++++++++++++++++++ apps/openmw/mwlua/types/creature.cpp | 25 ++----------- apps/openmw/mwlua/types/npc.cpp | 29 ++------------- 3 files changed, 59 insertions(+), 49 deletions(-) create mode 100644 apps/openmw/mwlua/types/actor.hpp diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp new file mode 100644 index 0000000000..9e009395da --- /dev/null +++ b/apps/openmw/mwlua/types/actor.hpp @@ -0,0 +1,54 @@ +#ifndef MWLUA_ACTOR_H +#define MWLUA_ACTOR_H + +#include + +#include +#include + +#include +#include + +#include "../context.hpp" +#include "../object.hpp" +namespace MWLua +{ + + template + void addActorServicesBindings(sol::usertype& record, const Context& context) + { + record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::vector { + std::vector providedServices; + std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, + { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, + { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, + { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, + { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, + { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, + { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, + { ESM::NPC::MagicItems, "MagicItems" } }; + + int services = rec.mAiData.mServices; + if constexpr (std::is_same_v) + { + if (rec.mFlags & ESM::NPC::Autocalc) + services = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(rec.mClass) + ->mData.mServices; + } + for (const auto& [flag, name] : serviceNames) + { + if (services & flag) + providedServices.push_back(name); + } + + if (!rec.getTransport().empty()) + providedServices.push_back("Travel"); + return providedServices; + }); + } +} +#endif // MWLUA_TYPES_H \ No newline at end of file diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index e6ed260a30..fb87e1d375 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -1,4 +1,5 @@ #include "types.hpp" +#include "actor.hpp" #include #include @@ -49,28 +50,6 @@ namespace MWLua record["soulValue"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mSoul; }); record["type"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mType; }); record["baseGold"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mGold; }); - record["servicesOffered"] = sol::readonly_property([](const ESM::Creature& rec) -> std::vector { - std::vector providedServices; - std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, - { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, - { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, - { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, - { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, - { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, - { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, - { ESM::NPC::MagicItems, "MagicItems" } }; - - int mServices = rec.mAiData.mServices; - for (const auto& entry : serviceNames) - { - if (mServices & entry.first) - { - providedServices.push_back(entry.second); - } - } - if (!rec.getTransport().empty()) - providedServices.push_back("Travel"); - return providedServices; - }); + addActorServicesBindings(record, context); } } diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 167658aefa..7e8958e6c5 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -1,5 +1,5 @@ #include "types.hpp" - +#include "actor.hpp" #include #include @@ -49,31 +49,8 @@ namespace MWLua = sol::readonly_property([](const ESM::NPC& rec) -> std::string { return rec.mHead.serializeText(); }); record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); - - record["servicesOffered"] = sol::readonly_property([](const ESM::NPC& rec) -> std::vector { - std::vector providedServices; - std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, - { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, - { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, - { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, - { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, - { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, - { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, - { ESM::NPC::MagicItems, "MagicItems" } }; - - int mServices = rec.mAiData.mServices; - for (const auto& entry : serviceNames) - { - if (mServices & entry.first) - { - providedServices.push_back(entry.second); - } - } - if (!rec.getTransport().empty()) - providedServices.push_back("Travel"); - return providedServices; - }); - // This function is game-specific, in future we should replace it with something more universal. + addActorServicesBindings(record, context); + // This function is game-specific, in future we should replace it with something more universal. npc["isWerewolf"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); if (cls.isNpc()) From 9c4ffa82565d887871095bfd28ca52cf8e1d3891 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 14:23:57 -0500 Subject: [PATCH 05/16] Map by service name --- apps/openmw/mwlua/types/actor.hpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index 9e009395da..3b90a6bfb0 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -17,9 +17,9 @@ namespace MWLua template void addActorServicesBindings(sol::usertype& record, const Context& context) { - record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::vector { - std::vector providedServices; - std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, + record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::map { + std::map providedServices; + const static std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, @@ -41,12 +41,9 @@ namespace MWLua } for (const auto& [flag, name] : serviceNames) { - if (services & flag) - providedServices.push_back(name); + providedServices[name] = (services & flag) != 0; } - - if (!rec.getTransport().empty()) - providedServices.push_back("Travel"); + providedServices["Travel"] = !rec.getTransport().empty(); return providedServices; }); } From e50532691bd5cda789389948d6ccea32af66c445 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 14:55:04 -0500 Subject: [PATCH 06/16] Fix define endif --- apps/openmw/mwlua/types/actor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index 3b90a6bfb0..4e87a20473 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -48,4 +48,4 @@ namespace MWLua }); } } -#endif // MWLUA_TYPES_H \ No newline at end of file +#endif // MWLUA_ACTOR_H \ No newline at end of file From bbe7702dbc20cb114b6ae84107d32762c812b98c Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:13:46 -0500 Subject: [PATCH 07/16] Use string_view --- apps/openmw/mwlua/types/actor.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index 4e87a20473..c322fe3760 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -17,16 +17,17 @@ namespace MWLua template void addActorServicesBindings(sol::usertype& record, const Context& context) { - record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::map { - std::map providedServices; - const static std::map serviceNames = { { ESM::NPC::Spells, "Spells" }, + record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::map { + std::map providedServices; + constexpr std::array, 19> serviceNames = { { { ESM::NPC::Spells, + "Spells" }, { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, { ESM::NPC::Training, "Training" }, { ESM::NPC::Repair, "Repair" }, { ESM::NPC::AllItems, "Barter" }, { ESM::NPC::Weapon, "Weapon" }, { ESM::NPC::Armor, "Armor" }, { ESM::NPC::Clothing, "Clothing" }, { ESM::NPC::Books, "Books" }, { ESM::NPC::Ingredients, "Ingredients" }, { ESM::NPC::Picks, "Picks" }, { ESM::NPC::Probes, "Probes" }, { ESM::NPC::Lights, "Lights" }, { ESM::NPC::Apparatus, "Apparatus" }, { ESM::NPC::RepairItem, "RepairItem" }, { ESM::NPC::Misc, "Misc" }, { ESM::NPC::Potions, "Potions" }, - { ESM::NPC::MagicItems, "MagicItems" } }; + { ESM::NPC::MagicItems, "MagicItems" } } }; int services = rec.mAiData.mServices; if constexpr (std::is_same_v) From 40925fa912a66ab8460133403b7c4b58bd8ee861 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:15:30 -0500 Subject: [PATCH 08/16] Add line --- apps/openmw/mwlua/types/actor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index c322fe3760..f5b78fe5c0 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -49,4 +49,4 @@ namespace MWLua }); } } -#endif // MWLUA_ACTOR_H \ No newline at end of file +#endif // MWLUA_ACTOR_H From e139135fdc76e7eada4d3d00acfe667048b65b19 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:16:41 -0500 Subject: [PATCH 09/16] Revert unneeded changes --- apps/openmw/mwlua/types/npc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 7e8958e6c5..761afcc881 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -1,9 +1,9 @@ #include "types.hpp" #include "actor.hpp" + #include #include -#include "apps/openmw/mwworld/worldmodel.hpp" #include #include #include @@ -50,7 +50,7 @@ namespace MWLua record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); addActorServicesBindings(record, context); - // This function is game-specific, in future we should replace it with something more universal. + // This function is game-specific, in future we should replace it with something more universal. npc["isWerewolf"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); if (cls.isNpc()) From 070c600a8379863e53d01cad2512cecb846ee208 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:16:59 -0500 Subject: [PATCH 10/16] Formatting --- apps/openmw/mwlua/types/npc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 761afcc881..d7072569c6 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -1,5 +1,5 @@ -#include "types.hpp" #include "actor.hpp" +#include "types.hpp" #include #include From 6c6885c39488af34429a0d7e776b34cd28f3431a Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:17:14 -0500 Subject: [PATCH 11/16] Formatting --- apps/openmw/mwlua/types/creature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index fb87e1d375..0ded34cac5 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -1,5 +1,5 @@ -#include "types.hpp" #include "actor.hpp" +#include "types.hpp" #include #include From ee5983f64a7f59dd2988fcf44e0f1edc8f936f11 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:21:03 -0500 Subject: [PATCH 12/16] Docs fixes --- apps/openmw/mwlua/types/npc.cpp | 1 + files/lua_api/openmw/types.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index d7072569c6..c9bde4d946 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -50,6 +50,7 @@ namespace MWLua record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); addActorServicesBindings(record, context); + // This function is game-specific, in future we should replace it with something more universal. npc["isWerewolf"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); diff --git a/files/lua_api/openmw/types.lua b/files/lua_api/openmw/types.lua index b4b21dcab9..557bbabd86 100644 --- a/files/lua_api/openmw/types.lua +++ b/files/lua_api/openmw/types.lua @@ -701,7 +701,7 @@ -- @field #number soulValue The soul value of the creature record -- @field #number type The @{#Creature.TYPE} of the creature -- @field #number baseGold The base barter gold of the creature --- @field #list<#string> servicesOffered The services of the creature, in a table. Possible entries are: Spells, Spellmaking, Enchanting, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. +-- @field #list<#string> servicesOffered The services of the creature, in a table. Value is if the service is provided or not, and they are indexed by: Spells, Spellmaking, Enchanting, Training, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. --- @{#NPC} functions @@ -751,7 +751,7 @@ -- @field #number baseGold The base barter gold of the NPC -- @field #number baseDisposition NPC's starting disposition -- @field #bool isMale The gender setting of the NPC --- @field #list<#string> servicesOffered The services of the creature, in a table. Possible entries are: Spells, Spellmaking, Enchanting, Training, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. +-- @field #list<#string> servicesOffered The services of the NPC, in a table. Value is if the service is provided or not, and they are indexed by: Spells, Spellmaking, Enchanting, Training, Repair, Barter, Weapon, Armor, Clothing, Books, Ingredients, Picks, Probes, Lights, Apparatus, RepairItems, Misc, Potions, MagicItems, Travel. -------------------------------------------------------------------------------- From 1db236b5fd3e979db68fecad2e67d3b3698479b8 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:30:02 -0500 Subject: [PATCH 13/16] Fix docs, dependancies --- apps/openmw/mwlua/types/actor.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index f5b78fe5c0..32a18931c0 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -6,6 +6,9 @@ #include #include +#include "apps/openmw/mwworld/esmstore.hpp" +#include +#include #include #include From ecc69b54793af3338ad8d463c9739379e6d5362f Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sat, 2 Sep 2023 15:33:06 -0500 Subject: [PATCH 14/16] Fix line --- apps/openmw/mwlua/types/npc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index c9bde4d946..e612f228e0 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -50,7 +50,7 @@ namespace MWLua record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); }); record["baseGold"] = sol::readonly_property([](const ESM::NPC& rec) -> int { return rec.mNpdt.mGold; }); addActorServicesBindings(record, context); - + // This function is game-specific, in future we should replace it with something more universal. npc["isWerewolf"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); From 208cd14cfe989c72d9a9e8a0fbf4311721e8bb20 Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Sun, 3 Sep 2023 11:26:10 -0500 Subject: [PATCH 15/16] Use lua table, getESMStore --- apps/openmw/mwlua/types/actor.hpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwlua/types/actor.hpp b/apps/openmw/mwlua/types/actor.hpp index 32a18931c0..409559475f 100644 --- a/apps/openmw/mwlua/types/actor.hpp +++ b/apps/openmw/mwlua/types/actor.hpp @@ -20,8 +20,9 @@ namespace MWLua template void addActorServicesBindings(sol::usertype& record, const Context& context) { - record["servicesOffered"] = sol::readonly_property([](const T& rec) -> std::map { - std::map providedServices; + record["servicesOffered"] = sol::readonly_property([context](const T& rec) -> sol::table { + sol::state_view& lua = context.mLua->sol(); + sol::table providedServices(lua, sol::create); constexpr std::array, 19> serviceNames = { { { ESM::NPC::Spells, "Spells" }, { ESM::NPC::Spellmaking, "Spellmaking" }, { ESM::NPC::Enchanting, "Enchanting" }, @@ -36,12 +37,8 @@ namespace MWLua if constexpr (std::is_same_v) { if (rec.mFlags & ESM::NPC::Autocalc) - services = MWBase::Environment::get() - .getWorld() - ->getStore() - .get() - .find(rec.mClass) - ->mData.mServices; + services + = MWBase::Environment::get().getESMStore()->get().find(rec.mClass)->mData.mServices; } for (const auto& [flag, name] : serviceNames) { From 7df43f28eda5d4d03d97428713684b1af7614dbc Mon Sep 17 00:00:00 2001 From: Zackhasacat Date: Mon, 4 Sep 2023 10:47:47 -0500 Subject: [PATCH 16/16] Remove unused include --- apps/openmw/mwlua/types/creature.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index 0ded34cac5..332a9b9b14 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -2,7 +2,6 @@ #include "types.hpp" #include -#include #include #include #include