forked from mirror/openmw-tes3mp
Change save format to store relative equipment index
Store the index for the allowedSlots vector instead of the absolute slot index. This will more gracefully handle edge cases like the available slots for an item having changed when loading the game, or the "allows stacking" property having changed. However the main reason this was done is to ease work on the essimporter.
This commit is contained in:
parent
142a138b75
commit
89d9649b50
7 changed files with 56 additions and 31 deletions
|
@ -466,7 +466,7 @@ namespace MWWorld
|
|||
// List moved references, from separately tracked list.
|
||||
for (ESM::CellRefTracker::const_iterator it = mCell->mLeasedRefs.begin(); it != mCell->mLeasedRefs.end(); ++it)
|
||||
{
|
||||
ESM::CellRef &ref = const_cast<ESM::CellRef&>(*it);
|
||||
const ESM::CellRef &ref = *it;
|
||||
|
||||
mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID));
|
||||
}
|
||||
|
|
|
@ -85,28 +85,29 @@ void MWWorld::ContainerStore::storeState (const LiveCellRef<T>& ref, ESM::Object
|
|||
ref.save (state);
|
||||
}
|
||||
|
||||
/// \todo make this method const once const-correct ContainerStoreIterators are available
|
||||
template<typename T>
|
||||
void MWWorld::ContainerStore::storeStates (const CellRefList<T>& collection,
|
||||
std::vector<std::pair<ESM::ObjectState, int> >& states, bool equipable) const
|
||||
void MWWorld::ContainerStore::storeStates (CellRefList<T>& collection,
|
||||
std::vector<std::pair<ESM::ObjectState, int> >& states, bool equipable)
|
||||
{
|
||||
for (typename CellRefList<T>::List::const_iterator iter (collection.mList.begin());
|
||||
for (typename CellRefList<T>::List::iterator iter (collection.mList.begin());
|
||||
iter!=collection.mList.end(); ++iter)
|
||||
{
|
||||
if (iter->mData.getCount() == 0)
|
||||
continue;
|
||||
ESM::ObjectState state;
|
||||
storeState (*iter, state);
|
||||
int slot = equipable ? getSlot (*iter) : -1;
|
||||
int slot = equipable ? getRelativeSlot (MWWorld::ContainerStoreIterator(this, iter)) : -1;
|
||||
states.push_back (std::make_pair (state, slot));
|
||||
}
|
||||
}
|
||||
|
||||
int MWWorld::ContainerStore::getSlot (const MWWorld::LiveCellRefBase& ref) const
|
||||
int MWWorld::ContainerStore::getRelativeSlot (const MWWorld::ContainerStoreIterator& iter) const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MWWorld::ContainerStore::setSlot (const MWWorld::ContainerStoreIterator& iter, int slot) {}
|
||||
void MWWorld::ContainerStore::setRelativeSlot (const MWWorld::ContainerStoreIterator& iter, int slot) {}
|
||||
|
||||
const std::string MWWorld::ContainerStore::sGoldId = "gold_001";
|
||||
|
||||
|
@ -641,7 +642,7 @@ MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id)
|
|||
return Ptr();
|
||||
}
|
||||
|
||||
void MWWorld::ContainerStore::writeState (ESM::InventoryState& state) const
|
||||
void MWWorld::ContainerStore::writeState (ESM::InventoryState& state)
|
||||
{
|
||||
state.mItems.clear();
|
||||
|
||||
|
@ -678,16 +679,16 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& state)
|
|||
{
|
||||
case ESM::REC_ALCH: getState (potions, iter->first); break;
|
||||
case ESM::REC_APPA: getState (appas, iter->first); break;
|
||||
case ESM::REC_ARMO: setSlot (getState (armors, iter->first), slot); break;
|
||||
case ESM::REC_ARMO: setRelativeSlot (getState (armors, iter->first), slot); break;
|
||||
case ESM::REC_BOOK: getState (books, iter->first); break;
|
||||
case ESM::REC_CLOT: setSlot (getState (clothes, iter->first), slot); break;
|
||||
case ESM::REC_CLOT: setRelativeSlot (getState (clothes, iter->first), slot); break;
|
||||
case ESM::REC_INGR: getState (ingreds, iter->first); break;
|
||||
case ESM::REC_LOCK: setSlot (getState (lockpicks, iter->first), slot); break;
|
||||
case ESM::REC_LOCK: setRelativeSlot (getState (lockpicks, iter->first), slot); break;
|
||||
case ESM::REC_MISC: getState (miscItems, iter->first); break;
|
||||
case ESM::REC_PROB: setSlot (getState (probes, iter->first), slot); break;
|
||||
case ESM::REC_PROB: setRelativeSlot (getState (probes, iter->first), slot); break;
|
||||
case ESM::REC_REPA: getState (repairs, iter->first); break;
|
||||
case ESM::REC_WEAP: setSlot (getState (weapons, iter->first), slot); break;
|
||||
case ESM::REC_LIGH: setSlot (getState (lights, iter->first), slot); break;
|
||||
case ESM::REC_WEAP: setRelativeSlot (getState (weapons, iter->first), slot); break;
|
||||
case ESM::REC_LIGH: setRelativeSlot (getState (lights, iter->first), slot); break;
|
||||
|
||||
default:
|
||||
std::cerr << "invalid item type in inventory state, refid " << state.mRef.mRefID << std::endl;
|
||||
|
|
|
@ -84,15 +84,16 @@ namespace MWWorld
|
|||
template<typename T>
|
||||
void storeState (const LiveCellRef<T>& ref, ESM::ObjectState& state) const;
|
||||
|
||||
/// \todo make this method const once const-correct ContainerStoreIterators are available
|
||||
template<typename T>
|
||||
void storeStates (const CellRefList<T>& collection,
|
||||
void storeStates (CellRefList<T>& collection,
|
||||
std::vector<std::pair<ESM::ObjectState, int> >& states,
|
||||
bool equipable = false) const;
|
||||
bool equipable = false);
|
||||
|
||||
virtual int getSlot (const MWWorld::LiveCellRefBase& ref) const;
|
||||
virtual int getRelativeSlot (const MWWorld::ContainerStoreIterator& iter) const;
|
||||
///< Return inventory slot that \a ref is in or -1 (if \a ref is not in a slot).
|
||||
|
||||
virtual void setSlot (const MWWorld::ContainerStoreIterator& iter, int slot);
|
||||
virtual void setRelativeSlot (const MWWorld::ContainerStoreIterator& iter, int slot);
|
||||
///< Set slot for \a iter. Ignored if \a iter is an end iterator or if slot==-1.
|
||||
|
||||
public:
|
||||
|
@ -171,7 +172,8 @@ namespace MWWorld
|
|||
|
||||
Ptr search (const std::string& id);
|
||||
|
||||
virtual void writeState (ESM::InventoryState& state) const;
|
||||
/// \todo make this method const once const-correct ContainerStoreIterators are available
|
||||
virtual void writeState (ESM::InventoryState& state);
|
||||
|
||||
virtual void readState (const ESM::InventoryState& state);
|
||||
|
||||
|
|
|
@ -49,19 +49,40 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots_)
|
|||
slots_.push_back (end());
|
||||
}
|
||||
|
||||
int MWWorld::InventoryStore::getSlot (const MWWorld::LiveCellRefBase& ref) const
|
||||
int MWWorld::InventoryStore::getRelativeSlot (const MWWorld::ContainerStoreIterator& iter)
|
||||
{
|
||||
for (int i = 0; i<static_cast<int> (mSlots.size()); ++i)
|
||||
if (mSlots[i].getType()!=-1 && mSlots[i]->getBase()==&ref)
|
||||
return i;
|
||||
if (mSlots[i].getType()!=-1 && mSlots[i] == iter)
|
||||
{
|
||||
// linear complexity, but allowedSlots is most of the time just 1 anyway
|
||||
std::vector<int> allowedSlots = iter->getClass().getEquipmentSlots(*iter).first;
|
||||
std::vector<int>::iterator found = std::find(allowedSlots.begin(),allowedSlots.end(),i);
|
||||
if (found == allowedSlots.end())
|
||||
return -1;
|
||||
else
|
||||
return std::distance(allowedSlots.begin(), found);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MWWorld::InventoryStore::setSlot (const MWWorld::ContainerStoreIterator& iter, int slot)
|
||||
void MWWorld::InventoryStore::setRelativeSlot (const MWWorld::ContainerStoreIterator& iter, int relativeSlot)
|
||||
{
|
||||
if (iter!=end() && slot>=0 && slot<Slots)
|
||||
mSlots[slot] = iter;
|
||||
if (relativeSlot < 0 || iter == end())
|
||||
return;
|
||||
|
||||
std::pair<std::vector<int>, bool> allowedSlots = iter->getClass().getEquipmentSlots(*iter);
|
||||
relativeSlot = std::min(int(allowedSlots.first.size()-1), relativeSlot);
|
||||
|
||||
// unstack if required
|
||||
if (!allowedSlots.second && iter->getRefData().getCount() > 1)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator newIter = addNewStack(*iter, 1);
|
||||
iter->getRefData().setCount(iter->getRefData().getCount()-1);
|
||||
mSlots[allowedSlots.first[relativeSlot]] = newIter;
|
||||
}
|
||||
else
|
||||
mSlots[allowedSlots.first[relativeSlot]] = iter;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore::InventoryStore()
|
||||
|
@ -703,7 +724,7 @@ bool MWWorld::InventoryStore::isEquipped(const MWWorld::Ptr &item)
|
|||
return false;
|
||||
}
|
||||
|
||||
void MWWorld::InventoryStore::writeState(ESM::InventoryState &state) const
|
||||
void MWWorld::InventoryStore::writeState(ESM::InventoryState &state)
|
||||
{
|
||||
MWWorld::ContainerStore::writeState(state);
|
||||
|
||||
|
|
|
@ -113,10 +113,10 @@ namespace MWWorld
|
|||
|
||||
void fireEquipmentChangedEvent();
|
||||
|
||||
virtual int getSlot (const MWWorld::LiveCellRefBase& ref) const;
|
||||
virtual int getRelativeSlot (const MWWorld::ContainerStoreIterator& iter);
|
||||
///< Return inventory slot that \a ref is in or -1 (if \a ref is not in a slot).
|
||||
|
||||
virtual void setSlot (const MWWorld::ContainerStoreIterator& iter, int slot);
|
||||
virtual void setRelativeSlot (const MWWorld::ContainerStoreIterator& iter, int relativeSlot);
|
||||
///< Set slot for \a iter. Ignored if \a iter is an end iterator or if slot==-1.
|
||||
|
||||
public:
|
||||
|
@ -209,7 +209,7 @@ namespace MWWorld
|
|||
virtual void clear();
|
||||
///< Empty container.
|
||||
|
||||
virtual void writeState (ESM::InventoryState& state) const;
|
||||
virtual void writeState (ESM::InventoryState& state);
|
||||
|
||||
virtual void readState (const ESM::InventoryState& state);
|
||||
};
|
||||
|
|
|
@ -2031,7 +2031,7 @@ namespace MWWorld
|
|||
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
RefData &refdata = ptr.getRefData();
|
||||
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||
OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||
|
||||
if(!physactor)
|
||||
return false;
|
||||
|
@ -2049,7 +2049,7 @@ namespace MWWorld
|
|||
mPhysEngine);
|
||||
if(tracer.mFraction < 1.0f) // collision, must be close to something below
|
||||
{
|
||||
const_cast<OEngine::Physic::PhysicActor *> (physactor)->setOnGround(true);
|
||||
physactor->setOnGround(true);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace ESM
|
|||
/// \brief State for inventories and containers
|
||||
struct InventoryState
|
||||
{
|
||||
/// <ObjectState, relative equipment slot>
|
||||
std::vector<std::pair<ObjectState, int> > mItems;
|
||||
|
||||
std::map<std::string, int> mLevelledItemMap;
|
||||
|
|
Loading…
Reference in a new issue