mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-28 08:37:12 +00:00
Merge branch 'savetheslot' into 'master'
Convert constant effect equipment slots to refnums Closes #7998 See merge request OpenMW/openmw!4130
This commit is contained in:
commit
e7c9574d31
@ -265,7 +265,15 @@ namespace
|
||||
else if (state.mVersion <= ESM::MaxOldCreatureStatsFormatVersion)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, ESM::Creature> || 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::Creature> || 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)
|
||||
{
|
||||
std::int64_t 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
|
||||
|
@ -316,7 +316,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…
x
Reference in New Issue
Block a user