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:
parent
77c978c226
commit
dc781bad5d
7 changed files with 62 additions and 62 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue