1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-15 15:26:38 +00:00

Add fields to record

This commit is contained in:
SkyHasACat 2025-08-03 13:42:04 -07:00
parent a0585949a9
commit 99ae52e94c
4 changed files with 64 additions and 34 deletions

View file

@ -16,6 +16,7 @@
#include "../context.hpp"
#include "servicesoffered.hpp"
namespace MWLua
{
@ -25,15 +26,6 @@ namespace MWLua
record["servicesOffered"] = sol::readonly_property([context](const T& rec) -> sol::table {
sol::state_view lua = context.sol();
sol::table providedServices(lua, sol::create);
constexpr std::array<std::pair<int, std::string_view>, 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" } } };
int services = rec.mAiData.mServices;
if constexpr (std::is_same_v<T, ESM::NPC>)
@ -42,10 +34,11 @@ namespace MWLua
services
= MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(rec.mClass)->mData.mServices;
}
for (const auto& [flag, name] : serviceNames)
for (const auto& [flag, name] : ServiceNames)
{
providedServices[name] = (services & flag) != 0;
}
providedServices["Travel"] = !rec.getTransport().empty();
return LuaUtil::makeReadOnly(providedServices);
});

View file

@ -2,6 +2,7 @@
#include "actor.hpp"
#include "modelproperty.hpp"
#include "servicesoffered.hpp"
#include <components/esm3/loadfact.hpp>
#include <components/esm3/loadnpc.hpp>
@ -58,6 +59,8 @@ namespace
npc.mHead = ESM::RefId::deserializeText(rec["head"].get<std::string_view>());
if (rec["hair"] != sol::nil)
npc.mHair = ESM::RefId::deserializeText(rec["hair"].get<std::string_view>());
if (rec["primaryFaction"] != sol::nil)
npc.mFaction = ESM::RefId::deserializeText(rec["primaryFaction"].get<std::string_view>());
if (rec["isMale"] != sol::nil)
{
@ -77,6 +80,15 @@ namespace
npc.mFlags &= ~ESM::NPC::Essential;
}
if (rec["autocalc"] != sol::nil)
{
bool respawn = rec["autocalc"];
if (respawn)
npc.mFlags |= ESM::NPC::Autocalc;
else
npc.mFlags &= ~ESM::NPC::Autocalc;
}
if (rec["isRespawning"] != sol::nil)
{
bool respawn = rec["isRespawning"];
@ -95,35 +107,20 @@ namespace
if (rec["bloodType"] != sol::nil)
npc.mBloodType = rec["bloodType"].get<int>();
// Services offered
if (rec["primaryFactionRank"] != sol::nil)
npc.mNpdt.mRank = rec["primaryFactionRank"].get<int>();
if (rec["servicesOffered"] != sol::nil)
{
const sol::table services = rec["servicesOffered"];
int flags = 0;
auto setFlag = [&](std::string_view key, int mask) {
if (services[key] != sol::nil && services[key])
flags |= mask;
};
setFlag("Spells", ESM::NPC::Spells);
setFlag("Spellmaking", ESM::NPC::Spellmaking);
setFlag("Enchanting", ESM::NPC::Enchanting);
setFlag("Training", ESM::NPC::Training);
setFlag("Repair", ESM::NPC::Repair);
setFlag("Barter", ESM::NPC::AllItems);
setFlag("Weapon", ESM::NPC::Weapon);
setFlag("Armor", ESM::NPC::Armor);
setFlag("Clothing", ESM::NPC::Clothing);
setFlag("Books", ESM::NPC::Books);
setFlag("Ingredients", ESM::NPC::Ingredients);
setFlag("Picks", ESM::NPC::Picks);
setFlag("Probes", ESM::NPC::Probes);
setFlag("Lights", ESM::NPC::Lights);
setFlag("Apparatus", ESM::NPC::Apparatus);
setFlag("RepairItem", ESM::NPC::RepairItem);
setFlag("Misc", ESM::NPC::Misc);
setFlag("Potions", ESM::NPC::Potions);
setFlag("MagicItems", ESM::NPC::MagicItems);
for (const auto& [mask, key] : ServiceNames)
{
sol::object value = services[key];
if (value != sol::nil && value.as<bool>())
flags |= mask;
}
npc.mAiData.mServices = flags;
}
@ -198,9 +195,20 @@ namespace MWLua
= sol::readonly_property([](const ESM::NPC& rec) -> int { return (int)rec.mNpdt.mDisposition; });
record["head"]
= sol::readonly_property([](const ESM::NPC& rec) -> std::string { return rec.mHead.serializeText(); });
record["primaryFaction"] = sol::readonly_property(
[](const ESM::NPC& rec) -> sol::optional<std::string> { return LuaUtil::serializeRefId(rec.mFaction); });
record["primaryFactionRank"]
= sol::readonly_property([](const ESM::NPC& rec, sol::this_state s) -> sol::object {
sol::state_view lua(s);
if (rec.mFaction.empty())
return sol::make_object(lua, sol::nil); // return nil
return sol::make_object(lua, rec.mNpdt.mRank); // return the rank as a number
});
addModelProperty(record);
record["isEssential"]
= sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.mFlags & ESM::NPC::Essential; });
record["autocalc"]
= sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.mFlags & ESM::NPC::Autocalc; });
record["isMale"] = sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.isMale(); });
record["isRespawning"]
= sol::readonly_property([](const ESM::NPC& rec) -> bool { return rec.mFlags & ESM::NPC::Respawn; });

View file

@ -0,0 +1,26 @@
#pragma once
#include <array>
#include <string_view>
#include <components/esm3/loadnpc.hpp> // for ESM::NPC constants
inline constexpr std::array<std::pair<int, std::string_view>, 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" }
}};

View file

@ -861,6 +861,9 @@
-- @field #boolean canWalk whether the creature can walk
-- @field #boolean canUseWeapons whether the creature can use weapons and shields
-- @field #boolean isBiped whether the creature is a biped
-- @field #boolean autocalc If true, the actors stats will be automatically calculated based on level and class.
-- @field #string primaryFaction Faction ID of the NPCs default faction. Nil if no faction
-- @field #number primaryFactionRank Faction rank of the NPCs default faction. Nil if no faction
-- @field #boolean isEssential whether the creature is essential
-- @field #boolean isRespawning whether the creature respawns after death
-- @field #number bloodType integer representing the blood type of the Creature. Used to generate the correct blood vfx.