From d6fc0744c7ce9c8a6fb4383958d2a446865c7397 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 18 Jun 2024 21:32:16 +0200 Subject: [PATCH 1/2] Move Lua index helpers to components and make owner.factiooRank match other ranks --- apps/openmw/mwlua/corebindings.cpp | 5 ++-- apps/openmw/mwlua/dialoguebindings.cpp | 9 +++--- apps/openmw/mwlua/factionbindings.cpp | 5 ++-- apps/openmw/mwlua/magicbindings.cpp | 5 ++-- apps/openmw/mwlua/menuscripts.cpp | 3 +- apps/openmw/mwlua/mwscriptbindings.cpp | 5 ++-- apps/openmw/mwlua/objectbindings.cpp | 12 ++++---- apps/openmw/mwlua/postprocessingbindings.cpp | 4 ++- apps/openmw/mwlua/recordstore.hpp | 3 +- apps/openmw/mwlua/types/ingredient.cpp | 3 +- apps/openmw/mwlua/types/levelledlist.cpp | 3 +- apps/openmw/mwlua/types/npc.cpp | 29 ++++++++------------ apps/openmw/mwlua/types/potion.cpp | 5 ++-- apps/openmw/mwlua/uibindings.cpp | 17 +++--------- components/lua/util.hpp | 20 ++++++++++++++ components/lua/utilpackage.cpp | 3 +- 16 files changed, 75 insertions(+), 56 deletions(-) create mode 100644 components/lua/util.hpp diff --git a/apps/openmw/mwlua/corebindings.cpp b/apps/openmw/mwlua/corebindings.cpp index ebdb0738adb..22c317f7428 100644 --- a/apps/openmw/mwlua/corebindings.cpp +++ b/apps/openmw/mwlua/corebindings.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -33,13 +34,13 @@ namespace MWLua const std::vector& contentList = MWBase::Environment::get().getWorld()->getContentFiles(); sol::table list(lua, sol::create); for (size_t i = 0; i < contentList.size(); ++i) - list[i + 1] = Misc::StringUtils::lowerCase(contentList[i]); + list[LuaUtil::toLuaIndex(i)] = Misc::StringUtils::lowerCase(contentList[i]); sol::table res(lua, sol::create); res["list"] = LuaUtil::makeReadOnly(list); res["indexOf"] = [&contentList](std::string_view contentFile) -> sol::optional { for (size_t i = 0; i < contentList.size(); ++i) if (Misc::StringUtils::ciEqual(contentList[i], contentFile)) - return i + 1; + return LuaUtil::toLuaIndex(i); return sol::nullopt; }; res["has"] = [&contentList](std::string_view contentFile) -> bool { diff --git a/apps/openmw/mwlua/dialoguebindings.cpp b/apps/openmw/mwlua/dialoguebindings.cpp index 20740870dc8..47e3dc941e8 100644 --- a/apps/openmw/mwlua/dialoguebindings.cpp +++ b/apps/openmw/mwlua/dialoguebindings.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -71,7 +72,7 @@ namespace { return nullptr; } - return store.at(index - 1); + return store.at(LuaUtil::fromLuaIndex(index)); }, [](const StoreT& store, std::string_view id) -> const ESM::Dialogue* { return store.search(ESM::RefId::deserializeText(id)); @@ -133,7 +134,7 @@ namespace return nullptr; } ESM::Dialogue::InfoContainer::const_iterator iter{ dialogueRecord.mInfo.cbegin() }; - std::advance(iter, index - 1); + std::advance(iter, LuaUtil::fromLuaIndex(index)); return &(*iter); }; recordInfosBindingsClass[sol::meta_function::ipairs] = lua["ipairsForArray"].template get(); @@ -224,7 +225,7 @@ namespace { return sol::nullopt; } - return rec.mData.mRank + 1; + return LuaUtil::toLuaIndex(rec.mData.mRank); }); recordInfoBindingsClass["filterPlayerCell"] = sol::readonly_property([](const ESM::DialInfo& rec) -> sol::optional { @@ -264,7 +265,7 @@ namespace { return sol::nullopt; } - return rec.mData.mPCrank + 1; + return LuaUtil::toLuaIndex(rec.mData.mPCrank); }); recordInfoBindingsClass["sound"] = sol::readonly_property([](const ESM::DialInfo& rec) -> sol::optional { diff --git a/apps/openmw/mwlua/factionbindings.cpp b/apps/openmw/mwlua/factionbindings.cpp index 8f85671ff5a..701e56f1d35 100644 --- a/apps/openmw/mwlua/factionbindings.cpp +++ b/apps/openmw/mwlua/factionbindings.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" @@ -93,8 +94,8 @@ namespace MWLua }); auto rankT = lua.new_usertype("ESM3_FactionRank"); rankT[sol::meta_function::to_string] = [](const FactionRank& rec) -> std::string { - return "ESM3_FactionRank[" + rec.mFactionId.toDebugString() + ", " + std::to_string(rec.mRankIndex + 1) - + "]"; + return "ESM3_FactionRank[" + rec.mFactionId.toDebugString() + ", " + + std::to_string(LuaUtil::toLuaIndex(rec.mRankIndex)) + "]"; }; rankT["name"] = sol::readonly_property([](const FactionRank& rec) -> std::string_view { return rec.mRankName; }); diff --git a/apps/openmw/mwlua/magicbindings.cpp b/apps/openmw/mwlua/magicbindings.cpp index da689558a2e..89820b5bea4 100644 --- a/apps/openmw/mwlua/magicbindings.cpp +++ b/apps/openmw/mwlua/magicbindings.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -207,7 +208,7 @@ namespace MWLua { sol::table res(lua, sol::create); for (size_t i = 0; i < effects.size(); ++i) - res[i + 1] = effects[i]; // ESM::IndexedENAMstruct (effect params) + res[LuaUtil::toLuaIndex(i)] = effects[i]; // ESM::IndexedENAMstruct (effect params) return res; } @@ -783,7 +784,7 @@ namespace MWLua [](const ActorSpells& spells, size_t index) -> const ESM::Spell* { if (auto* store = spells.getStore()) if (index <= store->count() && index > 0) - return store->at(index - 1); + return store->at(LuaUtil::fromLuaIndex(index)); return nullptr; }, [spellStore](const ActorSpells& spells, std::string_view spellId) -> const ESM::Spell* { diff --git a/apps/openmw/mwlua/menuscripts.cpp b/apps/openmw/mwlua/menuscripts.cpp index 033e56ac97c..e4332848651 100644 --- a/apps/openmw/mwlua/menuscripts.cpp +++ b/apps/openmw/mwlua/menuscripts.cpp @@ -1,5 +1,6 @@ #include "menuscripts.hpp" +#include #include #include "../mwbase/environment.hpp" @@ -88,7 +89,7 @@ namespace MWLua slotInfo["timePlayed"] = slot.mProfile.mTimePlayed; sol::table contentFiles(lua, sol::create); for (size_t i = 0; i < slot.mProfile.mContentFiles.size(); ++i) - contentFiles[i + 1] = Misc::StringUtils::lowerCase(slot.mProfile.mContentFiles[i]); + contentFiles[LuaUtil::toLuaIndex(i)] = Misc::StringUtils::lowerCase(slot.mProfile.mContentFiles[i]); { auto system_time = std::chrono::system_clock::now() diff --git a/apps/openmw/mwlua/mwscriptbindings.cpp b/apps/openmw/mwlua/mwscriptbindings.cpp index 6ed3486c8a1..1d06a5783eb 100644 --- a/apps/openmw/mwlua/mwscriptbindings.cpp +++ b/apps/openmw/mwlua/mwscriptbindings.cpp @@ -1,6 +1,7 @@ #include "mwscriptbindings.hpp" #include +#include #include #include "../mwbase/environment.hpp" @@ -174,7 +175,7 @@ namespace MWLua [](const GlobalStore& store, size_t index) -> sol::optional { if (index < 1 || store.getSize() < index) return sol::nullopt; - auto g = store.at(index - 1); + auto g = store.at(LuaUtil::fromLuaIndex(index)); if (g == nullptr) return sol::nullopt; std::string globalId = g->mId.serializeText(); @@ -190,7 +191,7 @@ namespace MWLua [](const GlobalStore& store, size_t index, float val) { if (index < 1 || store.getSize() < index) return; - auto g = store.at(index - 1); + auto g = store.at(LuaUtil::fromLuaIndex(index)); if (g == nullptr) return; std::string globalId = g->mId.serializeText(); diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index c594af2944a..322098003f9 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -170,7 +171,7 @@ namespace MWLua listT[sol::meta_function::length] = [](const ListT& list) { return list.mIds->size(); }; listT[sol::meta_function::index] = [](const ListT& list, size_t index) -> sol::optional { if (index > 0 && index <= list.mIds->size()) - return ObjectT((*list.mIds)[index - 1]); + return ObjectT((*list.mIds)[LuaUtil::fromLuaIndex(index)]); else return sol::nullopt; }; @@ -257,17 +258,16 @@ namespace MWLua }; ownerT["factionId"] = sol::property(getOwnerFactionId, setOwnerFactionId); - auto getOwnerFactionRank = [](const OwnerT& o) -> sol::optional { + auto getOwnerFactionRank = [](const OwnerT& o) -> sol::optional { int rank = o.mObj.ptr().getCellRef().getFactionRank(); if (rank < 0) return sol::nullopt; - else - return rank; + return LuaUtil::toLuaIndex(rank); }; - auto setOwnerFactionRank = [](const OwnerT& o, sol::optional factionRank) { + auto setOwnerFactionRank = [](const OwnerT& o, sol::optional factionRank) { if (std::is_same_v && !dynamic_cast(&o.mObj)) throw std::runtime_error("Local scripts can set an owner faction rank only on self"); - o.mObj.ptr().getCellRef().setFactionRank(factionRank.value_or(-1)); + o.mObj.ptr().getCellRef().setFactionRank(LuaUtil::fromLuaIndex(factionRank.value_or(0))); }; ownerT["factionRank"] = sol::property(getOwnerFactionRank, setOwnerFactionRank); diff --git a/apps/openmw/mwlua/postprocessingbindings.cpp b/apps/openmw/mwlua/postprocessingbindings.cpp index 74359e3a4bc..0fea46039c2 100644 --- a/apps/openmw/mwlua/postprocessingbindings.cpp +++ b/apps/openmw/mwlua/postprocessingbindings.cpp @@ -1,5 +1,7 @@ #include "postprocessingbindings.hpp" +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwrender/postprocessor.hpp" @@ -78,7 +80,7 @@ namespace MWLua for (size_t i = 0; i < *targetSize; ++i) { - sol::object obj = table[i + 1]; + sol::object obj = table[LuaUtil::toLuaIndex(i)]; if (!obj.is()) throw std::runtime_error("Invalid type for uniform array"); values.push_back(obj.as()); diff --git a/apps/openmw/mwlua/recordstore.hpp b/apps/openmw/mwlua/recordstore.hpp index 3d04de396b9..5756feb5b2f 100644 --- a/apps/openmw/mwlua/recordstore.hpp +++ b/apps/openmw/mwlua/recordstore.hpp @@ -5,6 +5,7 @@ #include #include +#include #include "apps/openmw/mwbase/environment.hpp" #include "apps/openmw/mwbase/world.hpp" @@ -48,7 +49,7 @@ namespace MWLua [](const StoreT& store, size_t index) -> const T* { if (index == 0 || index > store.getSize()) return nullptr; - return store.at(index - 1); // Translate from Lua's 1-based indexing. + return store.at(LuaUtil::fromLuaIndex(index)); }, [](const StoreT& store, std::string_view id) -> const T* { return store.search(ESM::RefId::deserializeText(id)); diff --git a/apps/openmw/mwlua/types/ingredient.cpp b/apps/openmw/mwlua/types/ingredient.cpp index f7c3a8a0500..a76869308b3 100644 --- a/apps/openmw/mwlua/types/ingredient.cpp +++ b/apps/openmw/mwlua/types/ingredient.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ namespace MWLua effect.mData.mMagnMin = 0; effect.mData.mMagnMax = 0; effect.mIndex = i; - res[i + 1] = effect; + res[LuaUtil::toLuaIndex(i)] = effect; } return res; }); diff --git a/apps/openmw/mwlua/types/levelledlist.cpp b/apps/openmw/mwlua/types/levelledlist.cpp index cb3bd7a6bc3..4d9231dae7c 100644 --- a/apps/openmw/mwlua/types/levelledlist.cpp +++ b/apps/openmw/mwlua/types/levelledlist.cpp @@ -1,6 +1,7 @@ #include "types.hpp" #include +#include #include "../../mwbase/environment.hpp" #include "../../mwbase/world.hpp" @@ -45,7 +46,7 @@ namespace MWLua record["creatures"] = sol::readonly_property([&](const ESM::CreatureLevList& rec) -> sol::table { sol::table res(state, sol::create); for (size_t i = 0; i < rec.mList.size(); ++i) - res[i + 1] = rec.mList[i]; + res[LuaUtil::toLuaIndex(i)] = rec.mList[i]; return res; }); record["calculateFromAllLevels"] = sol::readonly_property( diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 9b500dff4f5..7516f91145e 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "apps/openmw/mwbase/environment.hpp" @@ -145,30 +146,24 @@ namespace MWLua stats.setBaseDisposition(stats.getBaseDisposition() + value); }; - npc["getFactionRank"] = [](const Object& actor, std::string_view faction) { + npc["getFactionRank"] = [](const Object& actor, std::string_view faction) -> size_t { const MWWorld::Ptr ptr = actor.ptr(); ESM::RefId factionId = parseFactionId(faction); const MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats(ptr); - - int factionRank = npcStats.getFactionRank(factionId); if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) { if (npcStats.isInFaction(factionId)) - return factionRank + 1; - else - return 0; - } - else - { - ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); - if (factionId == primaryFactionId && factionRank == -1) - return ptr.getClass().getPrimaryFactionRank(ptr); - else if (primaryFactionId == factionId) - return factionRank + 1; - else - return 0; + { + int factionRank = npcStats.getFactionRank(factionId); + return LuaUtil::toLuaIndex(factionRank); + } + return 0; } + ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); + if (factionId == primaryFactionId) + return LuaUtil::toLuaIndex(ptr.getClass().getPrimaryFactionRank(ptr)); + return 0; }; npc["setFactionRank"] = [](Object& actor, std::string_view faction, int value) { @@ -185,7 +180,7 @@ namespace MWLua if (value <= 0 || value > ranksCount) throw std::runtime_error("Requested rank does not exist"); - auto targetRank = std::clamp(value, 1, ranksCount) - 1; + auto targetRank = LuaUtil::fromLuaIndex(std::clamp(value, 1, ranksCount)); if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr()) { diff --git a/apps/openmw/mwlua/types/potion.cpp b/apps/openmw/mwlua/types/potion.cpp index d686bdb1f76..cc4dd5700cd 100644 --- a/apps/openmw/mwlua/types/potion.cpp +++ b/apps/openmw/mwlua/types/potion.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -47,7 +48,7 @@ namespace potion.mEffects.mList.resize(numEffects); for (size_t i = 0; i < numEffects; ++i) { - potion.mEffects.mList[i] = LuaUtil::cast(effectsTable[i + 1]); + potion.mEffects.mList[i] = LuaUtil::cast(effectsTable[LuaUtil::toLuaIndex(i)]); } potion.mEffects.updateIndexes(); } @@ -86,7 +87,7 @@ namespace MWLua record["effects"] = sol::readonly_property([context](const ESM::Potion& rec) -> sol::table { sol::table res(context.mLua->sol(), sol::create); for (size_t i = 0; i < rec.mEffects.mList.size(); ++i) - res[i + 1] = rec.mEffects.mList[i]; // ESM::IndexedENAMstruct (effect params) + res[LuaUtil::toLuaIndex(i)] = rec.mEffects.mList[i]; // ESM::IndexedENAMstruct (effect params) return res; }); } diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp index a8df03ba254..ad92c80cde3 100644 --- a/apps/openmw/mwlua/uibindings.cpp +++ b/apps/openmw/mwlua/uibindings.cpp @@ -1,5 +1,6 @@ #include "uibindings.hpp" +#include #include #include #include @@ -36,16 +37,6 @@ namespace MWLua } } - // Lua arrays index from 1 - inline size_t fromLuaIndex(size_t i) - { - return i - 1; - } - inline size_t toLuaIndex(size_t i) - { - return i + 1; - } - const std::unordered_map modeToName{ { MWGui::GM_Inventory, "Interface" }, { MWGui::GM_Container, "Container" }, @@ -149,7 +140,7 @@ namespace MWLua if (index == LuaUi::Layer::count()) return sol::nullopt; else - return toLuaIndex(index); + return LuaUtil::toLuaIndex(index); }; layersTable["insertAfter"] = [context]( std::string_view afterName, std::string_view name, const sol::object& opt) { @@ -175,7 +166,7 @@ namespace MWLua layersMeta[sol::meta_function::length] = []() { return LuaUi::Layer::count(); }; layersMeta[sol::meta_function::index] = sol::overload( [](const sol::object& self, size_t index) { - index = fromLuaIndex(index); + index = LuaUtil::fromLuaIndex(index); return LuaUi::Layer(index); }, [layersTable]( @@ -242,7 +233,7 @@ namespace MWLua = [windowManager, luaManager = context.mLuaManager](sol::table modes, sol::optional arg) { std::vector newStack(modes.size()); for (unsigned i = 0; i < newStack.size(); ++i) - newStack[i] = nameToMode.at(LuaUtil::cast(modes[i + 1])); + newStack[i] = nameToMode.at(LuaUtil::cast(modes[LuaUtil::toLuaIndex(i)])); luaManager->addAction( [windowManager, newStack = std::move(newStack), arg = std::move(arg)]() { MWWorld::Ptr ptr; diff --git a/components/lua/util.hpp b/components/lua/util.hpp new file mode 100644 index 00000000000..640b5eeeb08 --- /dev/null +++ b/components/lua/util.hpp @@ -0,0 +1,20 @@ +#ifndef COMPONENTS_LUA_UTIL_H +#define COMPONENTS_LUA_UTIL_H + +#include + +namespace LuaUtil +{ + // Lua arrays index from 1 + constexpr inline std::int64_t fromLuaIndex(std::int64_t i) + { + return i - 1; + } + + constexpr inline std::int64_t toLuaIndex(std::int64_t i) + { + return i + 1; + } +} + +#endif diff --git a/components/lua/utilpackage.cpp b/components/lua/utilpackage.cpp index e9b8e886d24..8b456846313 100644 --- a/components/lua/utilpackage.cpp +++ b/components/lua/utilpackage.cpp @@ -10,6 +10,7 @@ #include #include "luastate.hpp" +#include "util.hpp" #include "shapes/box.hpp" @@ -143,7 +144,7 @@ namespace LuaUtil sol::table table(lua, sol::create); const auto vertices = b.vertices(); for (size_t i = 0; i < vertices.size(); ++i) - table[i + 1] = vertices[i]; + table[toLuaIndex(i)] = vertices[i]; return table; }); boxType[sol::meta_function::equal_to] = [](const Box& a, const Box& b) { return a == b; }; From 6aa52c09da0500401a0ad9657b699f4b0adef30a Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 19 Jun 2024 16:47:58 +0200 Subject: [PATCH 2/2] Shuffle code around --- apps/openmw/mwlua/types/npc.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 7516f91145e..f8a1a82e546 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -158,11 +158,13 @@ namespace MWLua int factionRank = npcStats.getFactionRank(factionId); return LuaUtil::toLuaIndex(factionRank); } - return 0; } - ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); - if (factionId == primaryFactionId) - return LuaUtil::toLuaIndex(ptr.getClass().getPrimaryFactionRank(ptr)); + else + { + ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); + if (factionId == primaryFactionId) + return LuaUtil::toLuaIndex(ptr.getClass().getPrimaryFactionRank(ptr)); + } return 0; };