1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2024-12-28 18:18:52 +00:00

Move Lua index helpers to components and make owner.factiooRank match other ranks

This commit is contained in:
Evil Eye 2024-06-18 21:32:16 +02:00
parent 6653502567
commit d6fc0744c7
16 changed files with 75 additions and 56 deletions

View File

@ -8,6 +8,7 @@
#include <components/lua/l10n.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/serialization.hpp>
#include <components/lua/util.hpp>
#include <components/misc/strings/algorithm.hpp>
#include <components/misc/strings/lower.hpp>
#include <components/version/version.hpp>
@ -33,13 +34,13 @@ namespace MWLua
const std::vector<std::string>& 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<int> {
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 {

View File

@ -8,6 +8,7 @@
#include <components/esm3/loaddial.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/vfs/pathutil.hpp>
@ -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<sol::function>();
@ -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<std::string> {
@ -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<std::string> {

View File

@ -3,6 +3,7 @@
#include <components/esm3/loadfact.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/environment.hpp"
@ -93,8 +94,8 @@ namespace MWLua
});
auto rankT = lua.new_usertype<FactionRank>("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; });

View File

@ -11,6 +11,7 @@
#include <components/esm3/loadspel.hpp>
#include <components/esm3/loadweap.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/color.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/misc/strings/format.hpp>
@ -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* {

View File

@ -1,5 +1,6 @@
#include "menuscripts.hpp"
#include <components/lua/util.hpp>
#include <components/misc/strings/lower.hpp>
#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()

View File

@ -1,6 +1,7 @@
#include "mwscriptbindings.hpp"
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/strings/lower.hpp>
#include "../mwbase/environment.hpp"
@ -174,7 +175,7 @@ namespace MWLua
[](const GlobalStore& store, size_t index) -> sol::optional<float> {
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();

View File

@ -4,6 +4,7 @@
#include <components/esm3/loadnpc.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/shapes/box.hpp>
#include <components/lua/util.hpp>
#include <components/lua/utilpackage.hpp>
#include <components/misc/convert.hpp>
#include <components/misc/mathutil.hpp>
@ -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<ObjectT> {
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<int> {
auto getOwnerFactionRank = [](const OwnerT& o) -> sol::optional<size_t> {
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<int> factionRank) {
auto setOwnerFactionRank = [](const OwnerT& o, sol::optional<size_t> factionRank) {
if (std::is_same_v<ObjectT, LObject> && !dynamic_cast<const SelfObject*>(&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);

View File

@ -1,5 +1,7 @@
#include "postprocessingbindings.hpp"
#include <components/lua/util.hpp>
#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<T>())
throw std::runtime_error("Invalid type for uniform array");
values.push_back(obj.as<T>());

View File

@ -5,6 +5,7 @@
#include <components/esm/defs.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#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));

View File

@ -3,6 +3,7 @@
#include <components/esm3/loadalch.hpp>
#include <components/esm3/loadingr.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
@ -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;
});

View File

@ -1,6 +1,7 @@
#include "types.hpp"
#include <components/esm3/loadlevlist.hpp>
#include <components/lua/util.hpp>
#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(

View File

@ -4,6 +4,7 @@
#include <components/esm3/loadfact.hpp>
#include <components/esm3/loadnpc.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/resourcehelpers.hpp>
#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())
{

View File

@ -2,6 +2,7 @@
#include <components/esm3/loadalch.hpp>
#include <components/lua/luastate.hpp>
#include <components/lua/util.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
@ -47,7 +48,7 @@ namespace
potion.mEffects.mList.resize(numEffects);
for (size_t i = 0; i < numEffects; ++i)
{
potion.mEffects.mList[i] = LuaUtil::cast<ESM::IndexedENAMstruct>(effectsTable[i + 1]);
potion.mEffects.mList[i] = LuaUtil::cast<ESM::IndexedENAMstruct>(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;
});
}

View File

@ -1,5 +1,6 @@
#include "uibindings.hpp"
#include <components/lua/util.hpp>
#include <components/lua_ui/alignment.hpp>
#include <components/lua_ui/content.hpp>
#include <components/lua_ui/element.hpp>
@ -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<MWGui::GuiMode, std::string_view> 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<LObject> arg) {
std::vector<MWGui::GuiMode> newStack(modes.size());
for (unsigned i = 0; i < newStack.size(); ++i)
newStack[i] = nameToMode.at(LuaUtil::cast<std::string_view>(modes[i + 1]));
newStack[i] = nameToMode.at(LuaUtil::cast<std::string_view>(modes[LuaUtil::toLuaIndex(i)]));
luaManager->addAction(
[windowManager, newStack = std::move(newStack), arg = std::move(arg)]() {
MWWorld::Ptr ptr;

20
components/lua/util.hpp Normal file
View File

@ -0,0 +1,20 @@
#ifndef COMPONENTS_LUA_UTIL_H
#define COMPONENTS_LUA_UTIL_H
#include <cstdint>
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

View File

@ -10,6 +10,7 @@
#include <components/misc/mathutil.hpp>
#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; };