1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-05-21 21:11:29 +00:00

Use fixed size unsigned ints for inventory offsets

This commit is contained in:
Evil Eye 2023-10-24 17:51:12 +02:00
parent 77c978c226
commit dc781bad5d
7 changed files with 62 additions and 62 deletions

View file

@ -9,15 +9,14 @@ namespace ESSImport
void convertInventory(const Inventory& inventory, ESM::InventoryState& state) void convertInventory(const Inventory& inventory, ESM::InventoryState& state)
{ {
int index = 0; uint32_t index = 0;
for (const auto& item : inventory.mItems) for (const auto& item : inventory.mItems)
{ {
ESM::ObjectState objstate; ESM::ObjectState objstate;
objstate.blank(); objstate.blank();
objstate.mRef = item; objstate.mRef = item;
objstate.mRef.mRefID = ESM::RefId::stringRefId(item.mId); objstate.mRef.mRefID = ESM::RefId::stringRefId(item.mId);
objstate.mCount = std::abs(item.mCount); // restocking items have negative count in the savefile objstate.mCount = item.mCount;
// openmw handles them differently, so no need to set any flags
state.mItems.push_back(objstate); state.mItems.push_back(objstate);
if (item.mRelativeEquipmentSlot != -1) if (item.mRelativeEquipmentSlot != -1)
// Note we should really write the absolute slot here, which we do not know about // Note we should really write the absolute slot here, which we do not know about

View file

@ -111,12 +111,12 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState(
} }
void MWWorld::ContainerStore::storeEquipmentState( void MWWorld::ContainerStore::storeEquipmentState(
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const const MWWorld::LiveCellRefBase& ref, size_t index, ESM::InventoryState& inventory) const
{ {
} }
void MWWorld::ContainerStore::readEquipmentState( void MWWorld::ContainerStore::readEquipmentState(
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) const MWWorld::ContainerStoreIterator& iter, size_t index, const ESM::InventoryState& inventory)
{ {
} }
@ -128,7 +128,7 @@ void MWWorld::ContainerStore::storeState(const LiveCellRef<T>& ref, ESM::ObjectS
template <typename T> template <typename T>
void MWWorld::ContainerStore::storeStates( void MWWorld::ContainerStore::storeStates(
const CellRefList<T>& collection, ESM::InventoryState& inventory, int& index, bool equipable) const const CellRefList<T>& collection, ESM::InventoryState& inventory, size_t& index, bool equipable) const
{ {
for (const LiveCellRef<T>& liveCellRef : collection.mList) for (const LiveCellRef<T>& liveCellRef : collection.mList)
{ {
@ -926,7 +926,7 @@ void MWWorld::ContainerStore::writeState(ESM::InventoryState& state) const
{ {
state.mItems.clear(); state.mItems.clear();
int index = 0; size_t index = 0;
storeStates(potions, state, index); storeStates(potions, state, index);
storeStates(appas, state, index); storeStates(appas, state, index);
storeStates(armors, state, index, true); storeStates(armors, state, index, true);
@ -947,12 +947,12 @@ void MWWorld::ContainerStore::readState(const ESM::InventoryState& inventory)
mModified = true; mModified = true;
mResolved = true; mResolved = true;
int index = 0; size_t index = 0;
for (const ESM::ObjectState& state : inventory.mItems) for (const ESM::ObjectState& state : inventory.mItems)
{ {
int type = MWBase::Environment::get().getESMStore()->find(state.mRef.mRefID); int type = MWBase::Environment::get().getESMStore()->find(state.mRef.mRefID);
int thisIndex = index++; size_t thisIndex = index++;
switch (type) switch (type)
{ {

View file

@ -161,16 +161,16 @@ namespace MWWorld
void storeState(const LiveCellRef<T>& ref, ESM::ObjectState& state) const; void storeState(const LiveCellRef<T>& ref, ESM::ObjectState& state) const;
template <typename T> template <typename T>
void storeStates( void storeStates(const CellRefList<T>& collection, ESM::InventoryState& inventory, size_t& index,
const CellRefList<T>& collection, ESM::InventoryState& inventory, int& index, bool equipable = false) const; bool equipable = false) const;
void updateRechargingItems(); void updateRechargingItems();
virtual void storeEquipmentState( virtual void storeEquipmentState(
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; const MWWorld::LiveCellRefBase& ref, size_t index, ESM::InventoryState& inventory) const;
virtual void readEquipmentState( virtual void readEquipmentState(
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); const MWWorld::ContainerStoreIterator& iter, size_t index, const ESM::InventoryState& inventory);
public: public:
ContainerStore(); ContainerStore();

View file

@ -46,12 +46,12 @@ void MWWorld::InventoryStore::initSlots(TSlots& slots_)
} }
void MWWorld::InventoryStore::storeEquipmentState( void MWWorld::InventoryStore::storeEquipmentState(
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const const MWWorld::LiveCellRefBase& ref, size_t index, ESM::InventoryState& inventory) const
{ {
for (int i = 0; i < static_cast<int>(mSlots.size()); ++i) for (int32_t i = 0; i < MWWorld::InventoryStore::Slots; ++i)
if (mSlots[i].getType() != -1 && mSlots[i]->getBase() == &ref)
{ {
inventory.mEquipmentSlots[index] = i; if (mSlots[i].getType() != -1 && mSlots[i]->getBase() == &ref)
inventory.mEquipmentSlots[static_cast<uint32_t>(index)] = i;
} }
if (mSelectedEnchantItem.getType() != -1 && mSelectedEnchantItem->getBase() == &ref) if (mSelectedEnchantItem.getType() != -1 && mSelectedEnchantItem->getBase() == &ref)
@ -59,19 +59,19 @@ void MWWorld::InventoryStore::storeEquipmentState(
} }
void MWWorld::InventoryStore::readEquipmentState( void MWWorld::InventoryStore::readEquipmentState(
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) const MWWorld::ContainerStoreIterator& iter, size_t index, const ESM::InventoryState& inventory)
{ {
if (index == inventory.mSelectedEnchantItem) if (index == inventory.mSelectedEnchantItem)
mSelectedEnchantItem = iter; mSelectedEnchantItem = iter;
std::map<int, int>::const_iterator found = inventory.mEquipmentSlots.find(index); auto found = inventory.mEquipmentSlots.find(index);
if (found != inventory.mEquipmentSlots.end()) if (found != inventory.mEquipmentSlots.end())
{ {
if (found->second < 0 || found->second >= MWWorld::InventoryStore::Slots) if (found->second < 0 || found->second >= MWWorld::InventoryStore::Slots)
throw std::runtime_error("Invalid slot index in inventory state"); throw std::runtime_error("Invalid slot index in inventory state");
// make sure the item can actually be equipped in this slot // make sure the item can actually be equipped in this slot
int slot = found->second; int32_t slot = found->second;
std::pair<std::vector<int>, bool> allowedSlots = iter->getClass().getEquipmentSlots(*iter); std::pair<std::vector<int>, bool> allowedSlots = iter->getClass().getEquipmentSlots(*iter);
if (!allowedSlots.first.size()) if (!allowedSlots.first.size())
return; return;

View file

@ -81,9 +81,9 @@ namespace MWWorld
void fireEquipmentChangedEvent(); void fireEquipmentChangedEvent();
void storeEquipmentState( void storeEquipmentState(
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const override; const MWWorld::LiveCellRefBase& ref, size_t index, ESM::InventoryState& inventory) const override;
void readEquipmentState( void readEquipmentState(
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) override; const MWWorld::ContainerStoreIterator& iter, size_t index, const ESM::InventoryState& inventory) override;
ContainerStoreIterator findSlot(int slot) const; ContainerStoreIterator findSlot(int slot) const;

View file

@ -7,22 +7,25 @@
namespace ESM namespace ESM
{ {
namespace
{
constexpr uint32_t sInvalidSlot = -1;
}
void InventoryState::load(ESMReader& esm) void InventoryState::load(ESMReader& esm)
{ {
// obsolete // obsolete
int index = 0; uint32_t index = 0;
while (esm.isNextSub("IOBJ")) while (esm.isNextSub("IOBJ"))
{ {
int unused; // no longer used esm.skip(4);
esm.getHT(unused);
ObjectState state; ObjectState state;
// obsolete // obsolete
if (esm.isNextSub("SLOT")) if (esm.isNextSub("SLOT"))
{ {
int slot; int32_t slot;
esm.getHT(slot); esm.getHT(slot);
mEquipmentSlots[index] = slot; mEquipmentSlots[index] = slot;
} }
@ -38,9 +41,9 @@ namespace ESM
++index; ++index;
} }
int itemsCount = 0; uint32_t itemsCount = 0;
esm.getHNOT(itemsCount, "ICNT"); esm.getHNOT(itemsCount, "ICNT");
for (int i = 0; i < itemsCount; i++) for (; itemsCount > 0; --itemsCount)
{ {
ObjectState state; ObjectState state;
@ -62,7 +65,7 @@ namespace ESM
{ {
// Get its name // Get its name
ESM::RefId id = esm.getRefId(); ESM::RefId id = esm.getRefId();
int count; int32_t count;
std::string parentGroup; std::string parentGroup;
// Then get its count // Then get its count
esm.getHNT(count, "COUN"); esm.getHNT(count, "COUN");
@ -91,9 +94,9 @@ namespace ESM
while (esm.isNextSub("EQUI")) while (esm.isNextSub("EQUI"))
{ {
esm.getSubHeader(); esm.getSubHeader();
int equipIndex; int32_t equipIndex;
esm.getT(equipIndex); esm.getT(equipIndex);
int slot; int32_t slot;
esm.getT(slot); esm.getT(slot);
mEquipmentSlots[equipIndex] = slot; mEquipmentSlots[equipIndex] = slot;
} }
@ -101,20 +104,24 @@ namespace ESM
if (esm.isNextSub("EQIP")) if (esm.isNextSub("EQIP"))
{ {
esm.getSubHeader(); esm.getSubHeader();
int slotsCount = 0; uint32_t slotsCount = 0;
esm.getT(slotsCount); esm.getT(slotsCount);
for (int i = 0; i < slotsCount; i++) for (; slotsCount > 0; --slotsCount)
{ {
int equipIndex; int32_t equipIndex;
esm.getT(equipIndex); esm.getT(equipIndex);
int slot; int32_t slot;
esm.getT(slot); esm.getT(slot);
mEquipmentSlots[equipIndex] = slot; mEquipmentSlots[equipIndex] = slot;
} }
} }
mSelectedEnchantItem = -1; uint32_t selectedEnchantItem = sInvalidSlot;
esm.getHNOT(mSelectedEnchantItem, "SELE"); esm.getHNOT(selectedEnchantItem, "SELE");
if (selectedEnchantItem == sInvalidSlot)
mSelectedEnchantItem.reset();
else
mSelectedEnchantItem = selectedEnchantItem;
// Old saves had restocking levelled items in a special map // Old saves had restocking levelled items in a special map
// This turns items from that map into negative quantities // This turns items from that map into negative quantities
@ -132,7 +139,7 @@ namespace ESM
void InventoryState::save(ESMWriter& esm) const void InventoryState::save(ESMWriter& esm) const
{ {
int itemsCount = static_cast<int>(mItems.size()); uint32_t itemsCount = static_cast<uint32_t>(mItems.size());
if (itemsCount > 0) if (itemsCount > 0)
{ {
esm.writeHNT("ICNT", itemsCount); esm.writeHNT("ICNT", itemsCount);
@ -149,34 +156,32 @@ namespace ESM
esm.writeHNString("LGRP", it->first.second); esm.writeHNString("LGRP", it->first.second);
} }
for (TEffectMagnitudes::const_iterator it = mPermanentMagicEffectMagnitudes.begin(); for (const auto& [id, params] : mPermanentMagicEffectMagnitudes)
it != mPermanentMagicEffectMagnitudes.end(); ++it)
{ {
esm.writeHNRefId("MAGI", it->first); esm.writeHNRefId("MAGI", id);
const std::vector<std::pair<float, float>>& params = it->second; for (const auto& [rand, mult] : params)
for (std::vector<std::pair<float, float>>::const_iterator pIt = params.begin(); pIt != params.end(); ++pIt)
{ {
esm.writeHNT("RAND", pIt->first); esm.writeHNT("RAND", rand);
esm.writeHNT("MULT", pIt->second); esm.writeHNT("MULT", mult);
} }
} }
int slotsCount = static_cast<int>(mEquipmentSlots.size()); uint32_t slotsCount = static_cast<uint32_t>(mEquipmentSlots.size());
if (slotsCount > 0) if (slotsCount > 0)
{ {
esm.startSubRecord("EQIP"); esm.startSubRecord("EQIP");
esm.writeT(slotsCount); esm.writeT(slotsCount);
for (std::map<int, int>::const_iterator it = mEquipmentSlots.begin(); it != mEquipmentSlots.end(); ++it) for (const auto& [index, slot] : mEquipmentSlots)
{ {
esm.writeT(it->first); esm.writeT(index);
esm.writeT(it->second); esm.writeT(slot);
} }
esm.endRecord("EQIP"); esm.endRecord("EQIP");
} }
if (mSelectedEnchantItem != -1) if (mSelectedEnchantItem)
esm.writeHNT("SELE", mSelectedEnchantItem); esm.writeHNT("SELE", *mSelectedEnchantItem);
} }
} }

View file

@ -2,6 +2,7 @@
#define OPENMW_ESM_INVENTORYSTATE_H #define OPENMW_ESM_INVENTORYSTATE_H
#include <map> #include <map>
#include <optional>
#include "objectstate.hpp" #include "objectstate.hpp"
#include <components/esm/refid.hpp> #include <components/esm/refid.hpp>
@ -19,20 +20,15 @@ namespace ESM
std::vector<ObjectState> mItems; std::vector<ObjectState> mItems;
// <Index in mItems, equipment slot> // <Index in mItems, equipment slot>
std::map<int, int> mEquipmentSlots; std::map<uint32_t, int32_t> mEquipmentSlots;
std::map<std::pair<ESM::RefId, std::string>, int> mLevelledItemMap; std::map<std::pair<ESM::RefId, std::string>, int32_t> mLevelledItemMap;
typedef std::map<ESM::RefId, std::vector<std::pair<float, float>>> TEffectMagnitudes; std::map<ESM::RefId, std::vector<std::pair<float, float>>> mPermanentMagicEffectMagnitudes;
TEffectMagnitudes mPermanentMagicEffectMagnitudes;
int mSelectedEnchantItem; // For inventories only std::optional<uint32_t> mSelectedEnchantItem; // For inventories only
InventoryState() virtual ~InventoryState() = default;
: mSelectedEnchantItem(-1)
{
}
virtual ~InventoryState() {}
virtual void load(ESMReader& esm); virtual void load(ESMReader& esm);
virtual void save(ESMWriter& esm) const; virtual void save(ESMWriter& esm) const;