Convert constant effect equipment slots to refnums

esm4-texture
Evil Eye 7 months ago
parent d15be7a685
commit cdfd305ac3

@ -264,8 +264,18 @@ namespace
}
else if (state.mVersion <= ESM::MaxOldCreatureStatsFormatVersion)
{
if constexpr (std::is_same_v<T, ESM::Creature> || std::is_same_v<T, ESM::NPC>)
if constexpr (std::is_same_v<T, ESM::Creature>)
MWWorld::convertStats(state.mCreatureStats);
else if constexpr (std::is_same_v<T, ESM::NPC>)
{
MWWorld::convertStats(state.mCreatureStats);
MWWorld::convertEnchantmentSlots(state.mCreatureStats, state.mInventory);
}
}
else if (state.mVersion <= ESM::MaxActiveSpellSlotIndexFormatVersion)
{
if constexpr (std::is_same_v<T, ESM::NPC>)
MWWorld::convertEnchantmentSlots(state.mCreatureStats, state.mInventory);
}
if (state.mRef.mRefNum.hasContentFile())

@ -11,6 +11,7 @@
#include <components/esm3/npcstate.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/worldmodel.hpp"
#include "../mwmechanics/magiceffects.hpp"
@ -101,13 +102,16 @@ namespace MWWorld
}
creatureStats.mActiveSpells.mSpells.emplace_back(params);
}
std::multimap<ESM::RefId, int> equippedItems;
std::multimap<ESM::RefId, ESM::RefNum> equippedItems;
for (std::size_t i = 0; i < inventory.mItems.size(); ++i)
{
const ESM::ObjectState& item = inventory.mItems[i];
ESM::ObjectState& item = inventory.mItems[i];
auto slot = inventory.mEquipmentSlots.find(i);
if (slot != inventory.mEquipmentSlots.end())
equippedItems.emplace(item.mRef.mRefID, slot->second);
{
MWBase::Environment::get().getWorldModel()->assignSaveFileRefNum(item.mRef);
equippedItems.emplace(item.mRef.mRefID, item.mRef.mRefNum);
}
}
for (const auto& [id, oldMagnitudes] : inventory.mPermanentMagicEffectMagnitudes)
{
@ -161,7 +165,7 @@ namespace MWWorld
auto [begin, end] = equippedItems.equal_range(id);
for (auto it = begin; it != end; ++it)
{
params.mItem = { static_cast<unsigned int>(it->second), 0 };
params.mItem = it->second;
creatureStats.mActiveSpells.mSpells.emplace_back(params);
}
}
@ -229,4 +233,28 @@ namespace MWWorld
for (auto& setting : creatureStats.mAiSettings)
setting.mMod = 0.f;
}
// Versions 17-27 wrote an equipment slot index to mItem
void convertEnchantmentSlots(ESM::CreatureStats& creatureStats, ESM::InventoryState& inventory)
{
for (auto& activeSpell : creatureStats.mActiveSpells.mSpells)
{
if (!activeSpell.mItem.isSet())
continue;
if (activeSpell.mFlags & ESM::ActiveSpells::Flag_Equipment)
{
auto slotIndex = activeSpell.mItem.mIndex;
auto slot = std::find_if(inventory.mEquipmentSlots.begin(), inventory.mEquipmentSlots.end(),
[=](const auto& entry) { return entry.second == slotIndex; });
if (slot != inventory.mEquipmentSlots.end() && slot->first < inventory.mItems.size())
{
ESM::CellRef& ref = inventory.mItems[slot->first].mRef;
MWBase::Environment::get().getWorldModel()->assignSaveFileRefNum(ref);
activeSpell.mItem = ref.mRefNum;
continue;
}
}
activeSpell.mItem = {};
}
}
}

@ -14,6 +14,8 @@ namespace MWWorld
ESM::CreatureStats& creatureStats, ESM::InventoryState& inventory, ESM::NpcStats* npcStats = nullptr);
void convertStats(ESM::CreatureStats& creatureStats);
void convertEnchantmentSlots(ESM::CreatureStats& creatureStats, ESM::InventoryState& inventory);
}
#endif

@ -317,7 +317,12 @@ namespace MWWorld
convertMagicEffects(
player.mObject.mCreatureStats, player.mObject.mInventory, &player.mObject.mNpcStats);
else if (reader.getFormatVersion() <= ESM::MaxOldCreatureStatsFormatVersion)
{
convertStats(player.mObject.mCreatureStats);
convertEnchantmentSlots(player.mObject.mCreatureStats, player.mObject.mInventory);
}
else if (reader.getFormatVersion() <= ESM::MaxActiveSpellSlotIndexFormatVersion)
convertEnchantmentSlots(player.mObject.mCreatureStats, player.mObject.mInventory);
if (!player.mObject.mEnabled)
{

@ -56,6 +56,17 @@ namespace MWWorld
}
}
// For fixing old saves
void assign(ESM::CellRef& ref)
{
if (!ref.mRefNum.isSet())
{
CellRef temp(ref);
temp.getOrAssignRefNum(mLastGenerated);
ref.mRefNum = temp.getRefNum();
}
}
private:
std::size_t mRevision = 0;
std::unordered_map<ESM::RefNum, Ptr> mIndex;

@ -81,6 +81,8 @@ namespace MWWorld
void deregisterLiveCellRef(const LiveCellRefBase& ref) noexcept { mPtrRegistry.remove(ref); }
void assignSaveFileRefNum(ESM::CellRef& ref) { mPtrRegistry.assign(ref); }
template <typename Fn>
void forEachLoadedCellStore(Fn&& fn)
{

@ -168,14 +168,7 @@ namespace ESM
esm.getHNT(params.mFlags, "FLAG");
}
if (esm.peekNextSub("ITEM"))
{
if (format <= MaxActiveSpellSlotIndexFormatVersion)
// Previous versions saved slot index in this record.
// Ignore these values as we can't use them
esm.getFormId(true, "ITEM");
else
params.mItem = esm.getFormId(true, "ITEM");
}
params.mItem = esm.getFormId(true, "ITEM");
}
if (esm.isNextSub("WORS"))
{

Loading…
Cancel
Save