mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 03:39:55 +00:00
Object cell movement tracker works. Savegame handling is still missing and some game functionality is still stubbed out.
This commit is contained in:
parent
64b4926127
commit
3aa53f3cb4
@ -47,13 +47,16 @@ namespace
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
MWWorld::Ptr searchViaActorId (MWWorld::CellRefList<T>& actorList, int actorId,
|
MWWorld::Ptr searchViaActorId (MWWorld::CellRefList<T>& actorList, int actorId,
|
||||||
MWWorld::CellStore *cell)
|
MWWorld::CellStore *cell, const std::map<MWWorld::LiveCellRefBase*, MWWorld::CellStore*>& toIgnore)
|
||||||
{
|
{
|
||||||
for (typename MWWorld::CellRefList<T>::List::iterator iter (actorList.mList.begin());
|
for (typename MWWorld::CellRefList<T>::List::iterator iter (actorList.mList.begin());
|
||||||
iter!=actorList.mList.end(); ++iter)
|
iter!=actorList.mList.end(); ++iter)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr actor (&*iter, cell);
|
MWWorld::Ptr actor (&*iter, cell);
|
||||||
|
|
||||||
|
if (toIgnore.find(&*iter) != toIgnore.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (actor.getClass().getCreatureStats (actor).matchesActorId (actorId) && actor.getRefData().getCount() > 0)
|
if (actor.getClass().getCreatureStats (actor).matchesActorId (actorId) && actor.getRefData().getCount() > 0)
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
@ -181,6 +184,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
void CellStore::moveFrom(const Ptr &object, CellStore *from)
|
void CellStore::moveFrom(const Ptr &object, CellStore *from)
|
||||||
{
|
{
|
||||||
|
mHasState = true;
|
||||||
MovedRefTracker::iterator found = mMovedToAnotherCell.find(object.getBase());
|
MovedRefTracker::iterator found = mMovedToAnotherCell.find(object.getBase());
|
||||||
if (found != mMovedToAnotherCell.end())
|
if (found != mMovedToAnotherCell.end())
|
||||||
{
|
{
|
||||||
@ -192,10 +196,27 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
mMovedHere.insert(std::make_pair(object.getBase(), from));
|
mMovedHere.insert(std::make_pair(object.getBase(), from));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mState == State_Loaded)
|
||||||
|
updateMergedRefs();
|
||||||
|
else if (mState == State_Preloaded)
|
||||||
|
{
|
||||||
|
mIds.push_back(object.getCellRef().getRefId());
|
||||||
|
std::sort(mIds.begin(), mIds.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::moveTo(const Ptr &object, CellStore *cellToMoveTo)
|
MWWorld::Ptr CellStore::moveTo(const Ptr &object, CellStore *cellToMoveTo)
|
||||||
{
|
{
|
||||||
|
if (cellToMoveTo == this)
|
||||||
|
throw std::runtime_error("object is already in this cell");
|
||||||
|
|
||||||
|
// We assume that *this is in State_Loaded since we could hardly have reference to a live object otherwise.
|
||||||
|
if (mState != State_Loaded)
|
||||||
|
throw std::runtime_error("can't move object from a non-loaded cell (how did you get this object anyway?)");
|
||||||
|
|
||||||
|
// TODO: ensure that the object actually exists in the cell
|
||||||
|
|
||||||
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
MovedRefTracker::iterator found = mMovedHere.find(object.getBase());
|
||||||
if (found != mMovedHere.end())
|
if (found != mMovedHere.end())
|
||||||
{
|
{
|
||||||
@ -208,21 +229,59 @@ namespace MWWorld
|
|||||||
mMovedHere.erase(found);
|
mMovedHere.erase(found);
|
||||||
|
|
||||||
// Now that object is back to its rightful owner, we can move it
|
// Now that object is back to its rightful owner, we can move it
|
||||||
|
if (cellToMoveTo != originalCell)
|
||||||
|
{
|
||||||
originalCell->moveTo(object, cellToMoveTo);
|
originalCell->moveTo(object, cellToMoveTo);
|
||||||
|
}
|
||||||
|
|
||||||
updateMergedRefs();
|
updateMergedRefs();
|
||||||
return;
|
return MWWorld::Ptr(object.getBase(), cellToMoveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
cellToMoveTo->moveFrom(object, this);
|
cellToMoveTo->moveFrom(object, this);
|
||||||
mMovedToAnotherCell.insert(std::make_pair(object.getBase(), cellToMoveTo));
|
mMovedToAnotherCell.insert(std::make_pair(object.getBase(), cellToMoveTo));
|
||||||
|
|
||||||
updateMergedRefs();
|
updateMergedRefs();
|
||||||
|
return MWWorld::Ptr(object.getBase(), cellToMoveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MergeFunctor
|
||||||
|
{
|
||||||
|
MergeFunctor(std::vector<LiveCellRefBase*>& mergeTo, const std::map<LiveCellRefBase*, MWWorld::CellStore*>& movedHere,
|
||||||
|
const std::map<LiveCellRefBase*, MWWorld::CellStore*>& movedToAnotherCell)
|
||||||
|
: mMergeTo(mergeTo)
|
||||||
|
, mMovedHere(movedHere)
|
||||||
|
, mMovedToAnotherCell(movedToAnotherCell)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (mMovedToAnotherCell.find(ptr.getBase()) != mMovedToAnotherCell.end())
|
||||||
|
return true;
|
||||||
|
mMergeTo.push_back(ptr.getBase());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void merge()
|
||||||
|
{
|
||||||
|
for (std::map<LiveCellRefBase*, MWWorld::CellStore*>::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it)
|
||||||
|
mMergeTo.push_back(it->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<LiveCellRefBase*>& mMergeTo;
|
||||||
|
|
||||||
|
const std::map<LiveCellRefBase*, MWWorld::CellStore*>& mMovedHere;
|
||||||
|
const std::map<LiveCellRefBase*, MWWorld::CellStore*>& mMovedToAnotherCell;
|
||||||
|
};
|
||||||
|
|
||||||
void CellStore::updateMergedRefs()
|
void CellStore::updateMergedRefs()
|
||||||
{
|
{
|
||||||
|
mMergedRefs.clear();
|
||||||
|
MergeFunctor functor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
||||||
|
forEachInternal(functor);
|
||||||
|
functor.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
CellStore::CellStore (const ESM::Cell *cell)
|
CellStore::CellStore (const ESM::Cell *cell)
|
||||||
@ -258,85 +317,50 @@ namespace MWWorld
|
|||||||
return const_cast<CellStore *> (this)->search (id).isEmpty();
|
return const_cast<CellStore *> (this)->search (id).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SearchFunctor
|
||||||
|
{
|
||||||
|
MWWorld::Ptr mFound;
|
||||||
|
std::string mIdToFind;
|
||||||
|
bool operator()(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (ptr.getCellRef().getRefId() == mIdToFind)
|
||||||
|
{
|
||||||
|
mFound = ptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ptr CellStore::search (const std::string& id)
|
Ptr CellStore::search (const std::string& id)
|
||||||
{
|
{
|
||||||
bool oldState = mHasState;
|
bool oldState = mHasState;
|
||||||
|
|
||||||
mHasState = true;
|
SearchFunctor searchFunctor;
|
||||||
|
searchFunctor.mIdToFind = id;
|
||||||
if (LiveCellRef<ESM::Activator> *ref = mActivators.find (id))
|
forEach(searchFunctor);
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Potion> *ref = mPotions.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Apparatus> *ref = mAppas.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Armor> *ref = mArmors.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Book> *ref = mBooks.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Clothing> *ref = mClothes.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Container> *ref = mContainers.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Creature> *ref = mCreatures.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Door> *ref = mDoors.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Ingredient> *ref = mIngreds.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::CreatureLevList> *ref = mCreatureLists.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::ItemLevList> *ref = mItemLists.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Light> *ref = mLights.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Lockpick> *ref = mLockpicks.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Miscellaneous> *ref = mMiscItems.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::NPC> *ref = mNpcs.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Probe> *ref = mProbes.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Repair> *ref = mRepairs.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Static> *ref = mStatics.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
if (LiveCellRef<ESM::Weapon> *ref = mWeapons.find (id))
|
|
||||||
return Ptr (ref, this);
|
|
||||||
|
|
||||||
mHasState = oldState;
|
mHasState = oldState;
|
||||||
|
return searchFunctor.mFound;
|
||||||
return Ptr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr CellStore::searchViaActorId (int id)
|
Ptr CellStore::searchViaActorId (int id)
|
||||||
{
|
{
|
||||||
if (Ptr ptr = ::searchViaActorId (mNpcs, id, this))
|
if (Ptr ptr = ::searchViaActorId (mNpcs, id, this, mMovedToAnotherCell))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
if (Ptr ptr = ::searchViaActorId (mCreatures, id, this))
|
if (Ptr ptr = ::searchViaActorId (mCreatures, id, this, mMovedToAnotherCell))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
|
for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr actor (it->first, this);
|
||||||
|
if (!actor.getClass().isActor())
|
||||||
|
continue;
|
||||||
|
if (actor.getClass().getCreatureStats (actor).matchesActorId (id) && actor.getRefData().getCount() > 0)
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
|
||||||
return Ptr();
|
return Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,6 +459,8 @@ namespace MWWorld
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't need to check mMovedToAnotherCell because listRefs isn't used for loaded cells.
|
||||||
|
|
||||||
mIds.push_back (Misc::StringUtils::lowerCase (ref.mRefID));
|
mIds.push_back (Misc::StringUtils::lowerCase (ref.mRefID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,6 +473,12 @@ namespace MWWorld
|
|||||||
mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID));
|
mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List runtime moved references
|
||||||
|
for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it)
|
||||||
|
{
|
||||||
|
mIds.push_back(Misc::StringUtils::lowerCase(it->first->mRef.getRefId()));
|
||||||
|
}
|
||||||
|
|
||||||
std::sort (mIds.begin(), mIds.end());
|
std::sort (mIds.begin(), mIds.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +521,8 @@ namespace MWWorld
|
|||||||
|
|
||||||
loadRef (ref, false, store);
|
loadRef (ref, false, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateMergedRefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CellStore::isExterior() const
|
bool CellStore::isExterior() const
|
||||||
@ -610,11 +644,15 @@ namespace MWWorld
|
|||||||
writeReferenceCollection<ESM::ObjectState> (writer, mRepairs);
|
writeReferenceCollection<ESM::ObjectState> (writer, mRepairs);
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mStatics);
|
writeReferenceCollection<ESM::ObjectState> (writer, mStatics);
|
||||||
writeReferenceCollection<ESM::ObjectState> (writer, mWeapons);
|
writeReferenceCollection<ESM::ObjectState> (writer, mWeapons);
|
||||||
|
|
||||||
|
// TODO: write moved references
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::readReferences (ESM::ESMReader& reader,
|
void CellStore::readReferences (ESM::ESMReader& reader,
|
||||||
const std::map<int, int>& contentFileMap)
|
const std::map<int, int>& contentFileMap)
|
||||||
{
|
{
|
||||||
|
// TODO: read moved references
|
||||||
|
|
||||||
mHasState = true;
|
mHasState = true;
|
||||||
|
|
||||||
while (reader.isNextSub ("OBJE"))
|
while (reader.isNextSub ("OBJE"))
|
||||||
|
@ -112,11 +112,64 @@ namespace MWWorld
|
|||||||
/// Repopulate mMergedRefs.
|
/// Repopulate mMergedRefs.
|
||||||
void updateMergedRefs();
|
void updateMergedRefs();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
LiveCellRefBase* insertBase(CellRefList<T>& list, const LiveCellRef<T>* ref)
|
||||||
|
{
|
||||||
|
mHasState = true;
|
||||||
|
LiveCellRefBase* ret = &list.insert(*ref);
|
||||||
|
updateMergedRefs();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function for forEachInternal
|
||||||
|
template<class Functor, class List>
|
||||||
|
bool forEachImp (Functor& functor, List& list)
|
||||||
|
{
|
||||||
|
for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (iter->mData.isDeletedByContentFile())
|
||||||
|
continue;
|
||||||
|
if (!functor (MWWorld::Ptr(&*iter, this)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved objects are accounted for.
|
||||||
|
template<class Functor>
|
||||||
|
bool forEachInternal (Functor& functor)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
forEachImp (functor, mActivators) &&
|
||||||
|
forEachImp (functor, mPotions) &&
|
||||||
|
forEachImp (functor, mAppas) &&
|
||||||
|
forEachImp (functor, mArmors) &&
|
||||||
|
forEachImp (functor, mBooks) &&
|
||||||
|
forEachImp (functor, mClothes) &&
|
||||||
|
forEachImp (functor, mContainers) &&
|
||||||
|
forEachImp (functor, mDoors) &&
|
||||||
|
forEachImp (functor, mIngreds) &&
|
||||||
|
forEachImp (functor, mItemLists) &&
|
||||||
|
forEachImp (functor, mLights) &&
|
||||||
|
forEachImp (functor, mLockpicks) &&
|
||||||
|
forEachImp (functor, mMiscItems) &&
|
||||||
|
forEachImp (functor, mProbes) &&
|
||||||
|
forEachImp (functor, mRepairs) &&
|
||||||
|
forEachImp (functor, mStatics) &&
|
||||||
|
forEachImp (functor, mWeapons) &&
|
||||||
|
forEachImp (functor, mCreatures) &&
|
||||||
|
forEachImp (functor, mNpcs) &&
|
||||||
|
forEachImp (functor, mCreatureLists);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Moves object from this cell to the given cell.
|
/// Moves object from this cell to the given cell.
|
||||||
/// @note automatically updates given cell by calling cellToMoveTo->moveFrom(...)
|
/// @note automatically updates given cell by calling cellToMoveTo->moveFrom(...)
|
||||||
void moveTo(const MWWorld::Ptr& object, MWWorld::CellStore* cellToMoveTo);
|
/// @note throws exception if cellToMoveTo == this
|
||||||
|
/// @return updated MWWorld::Ptr with the new CellStore pointer set.
|
||||||
|
MWWorld::Ptr moveTo(const MWWorld::Ptr& object, MWWorld::CellStore* cellToMoveTo);
|
||||||
|
|
||||||
/// Make a copy of the given object and insert it into this cell.
|
/// Make a copy of the given object and insert it into this cell.
|
||||||
/// @note If you get a linker error here, this means the given type can not be inserted into a cell.
|
/// @note If you get a linker error here, this means the given type can not be inserted into a cell.
|
||||||
@ -136,6 +189,7 @@ namespace MWWorld
|
|||||||
bool hasId (const std::string& id) const;
|
bool hasId (const std::string& id) const;
|
||||||
///< May return true for deleted IDs when in preload state. Will return false, if cell is
|
///< May return true for deleted IDs when in preload state. Will return false, if cell is
|
||||||
/// unloaded.
|
/// unloaded.
|
||||||
|
/// @note Will not account for moved references which may exist in Loaded state. Use search() instead if the cell is loaded.
|
||||||
|
|
||||||
Ptr search (const std::string& id);
|
Ptr search (const std::string& id);
|
||||||
///< Will return an empty Ptr if cell is not loaded. Does not check references in
|
///< Will return an empty Ptr if cell is not loaded. Does not check references in
|
||||||
@ -166,45 +220,23 @@ namespace MWWorld
|
|||||||
/// false will abort the iteration.
|
/// false will abort the iteration.
|
||||||
/// \attention This function also lists deleted (count 0) objects!
|
/// \attention This function also lists deleted (count 0) objects!
|
||||||
/// \return Iteration completed?
|
/// \return Iteration completed?
|
||||||
///
|
|
||||||
/// \note Creatures and NPCs are handled last.
|
|
||||||
template<class Functor>
|
template<class Functor>
|
||||||
bool forEach (Functor& functor)
|
bool forEach (Functor& functor)
|
||||||
{
|
{
|
||||||
|
if (mState != State_Loaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
mHasState = true;
|
mHasState = true;
|
||||||
|
|
||||||
return
|
for (unsigned int i=0; i<mMergedRefs.size(); ++i)
|
||||||
forEachImp (functor, mActivators) &&
|
|
||||||
forEachImp (functor, mPotions) &&
|
|
||||||
forEachImp (functor, mAppas) &&
|
|
||||||
forEachImp (functor, mArmors) &&
|
|
||||||
forEachImp (functor, mBooks) &&
|
|
||||||
forEachImp (functor, mClothes) &&
|
|
||||||
forEachImp (functor, mContainers) &&
|
|
||||||
forEachImp (functor, mDoors) &&
|
|
||||||
forEachImp (functor, mIngreds) &&
|
|
||||||
forEachImp (functor, mItemLists) &&
|
|
||||||
forEachImp (functor, mLights) &&
|
|
||||||
forEachImp (functor, mLockpicks) &&
|
|
||||||
forEachImp (functor, mMiscItems) &&
|
|
||||||
forEachImp (functor, mProbes) &&
|
|
||||||
forEachImp (functor, mRepairs) &&
|
|
||||||
forEachImp (functor, mStatics) &&
|
|
||||||
forEachImp (functor, mWeapons) &&
|
|
||||||
forEachImp (functor, mCreatures) &&
|
|
||||||
forEachImp (functor, mNpcs) &&
|
|
||||||
forEachImp (functor, mCreatureLists);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Functor>
|
|
||||||
bool forEachContainer (Functor& functor)
|
|
||||||
{
|
{
|
||||||
mHasState = true;
|
if (mMergedRefs[i]->mData.isDeletedByContentFile())
|
||||||
|
continue;
|
||||||
|
|
||||||
return
|
if (!functor(MWWorld::Ptr(mMergedRefs[i], this)))
|
||||||
forEachImp (functor, mContainers) &&
|
return false;
|
||||||
forEachImp (functor, mCreatures) &&
|
}
|
||||||
forEachImp (functor, mNpcs);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo add const version of forEach
|
/// \todo add const version of forEach
|
||||||
@ -234,20 +266,6 @@ namespace MWWorld
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<class Functor, class List>
|
|
||||||
bool forEachImp (Functor& functor, List& list)
|
|
||||||
{
|
|
||||||
for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end();
|
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
if (iter->mData.isDeletedByContentFile())
|
|
||||||
continue;
|
|
||||||
if (!functor (MWWorld::Ptr(&*iter, this)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run through references and store IDs
|
/// Run through references and store IDs
|
||||||
void listRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
|
void listRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
|
||||||
|
|
||||||
@ -261,126 +279,105 @@ namespace MWWorld
|
|||||||
MWMechanics::PathgridGraph mPathgridGraph;
|
MWMechanics::PathgridGraph mPathgridGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Activator>(const LiveCellRef<ESM::Activator>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Activator>(const LiveCellRef<ESM::Activator>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mActivators, ref);
|
||||||
return &mActivators.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Potion>(const LiveCellRef<ESM::Potion>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Potion>(const LiveCellRef<ESM::Potion>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mPotions, ref);
|
||||||
return &mPotions.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Apparatus>(const LiveCellRef<ESM::Apparatus>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Apparatus>(const LiveCellRef<ESM::Apparatus>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mAppas, ref);
|
||||||
return &mAppas.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Armor>(const LiveCellRef<ESM::Armor>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Armor>(const LiveCellRef<ESM::Armor>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mArmors, ref);
|
||||||
return &mArmors.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Book>(const LiveCellRef<ESM::Book>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Book>(const LiveCellRef<ESM::Book>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mBooks, ref);
|
||||||
return &mBooks.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Clothing>(const LiveCellRef<ESM::Clothing>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Clothing>(const LiveCellRef<ESM::Clothing>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mClothes, ref);
|
||||||
return &mClothes.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Container>(const LiveCellRef<ESM::Container>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Container>(const LiveCellRef<ESM::Container>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mContainers, ref);
|
||||||
return &mContainers.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Creature>(const LiveCellRef<ESM::Creature>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Creature>(const LiveCellRef<ESM::Creature>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mCreatures, ref);
|
||||||
return &mCreatures.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Door>(const LiveCellRef<ESM::Door>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Door>(const LiveCellRef<ESM::Door>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mDoors, ref);
|
||||||
return &mDoors.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Ingredient>(const LiveCellRef<ESM::Ingredient>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Ingredient>(const LiveCellRef<ESM::Ingredient>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mIngreds, ref);
|
||||||
return &mIngreds.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::CreatureLevList>(const LiveCellRef<ESM::CreatureLevList>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::CreatureLevList>(const LiveCellRef<ESM::CreatureLevList>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mCreatureLists, ref);
|
||||||
return &mCreatureLists.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::ItemLevList>(const LiveCellRef<ESM::ItemLevList>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::ItemLevList>(const LiveCellRef<ESM::ItemLevList>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mItemLists, ref);
|
||||||
return &mItemLists.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Light>(const LiveCellRef<ESM::Light>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Light>(const LiveCellRef<ESM::Light>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mLights, ref);
|
||||||
return &mLights.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Lockpick>(const LiveCellRef<ESM::Lockpick>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Lockpick>(const LiveCellRef<ESM::Lockpick>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mLockpicks, ref);
|
||||||
return &mLockpicks.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Miscellaneous>(const LiveCellRef<ESM::Miscellaneous>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Miscellaneous>(const LiveCellRef<ESM::Miscellaneous>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mMiscItems, ref);
|
||||||
return &mMiscItems.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::NPC>(const LiveCellRef<ESM::NPC>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::NPC>(const LiveCellRef<ESM::NPC>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mNpcs, ref);
|
||||||
return &mNpcs.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Probe>(const LiveCellRef<ESM::Probe>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Probe>(const LiveCellRef<ESM::Probe>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mProbes, ref);
|
||||||
return &mProbes.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Repair>(const LiveCellRef<ESM::Repair>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Repair>(const LiveCellRef<ESM::Repair>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mRepairs, ref);
|
||||||
return &mRepairs.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Static>(const LiveCellRef<ESM::Static>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Static>(const LiveCellRef<ESM::Static>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mStatics, ref);
|
||||||
return &mStatics.insert(*ref);
|
|
||||||
}
|
}
|
||||||
template<>
|
template<>
|
||||||
inline LiveCellRefBase* CellStore::insert<ESM::Weapon>(const LiveCellRef<ESM::Weapon>* ref)
|
inline LiveCellRefBase* CellStore::insert<ESM::Weapon>(const LiveCellRef<ESM::Weapon>* ref)
|
||||||
{
|
{
|
||||||
mHasState = true;
|
return insertBase(mWeapons, ref);
|
||||||
return &mWeapons.insert(*ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator== (const CellStore& left, const CellStore& right);
|
bool operator== (const CellStore& left, const CellStore& right);
|
||||||
|
@ -116,7 +116,6 @@ namespace
|
|||||||
{
|
{
|
||||||
addObject(ptr, mPhysics, mRendering);
|
addObject(ptr, mPhysics, mRendering);
|
||||||
updateObjectRotation(ptr, mPhysics, mRendering, false);
|
updateObjectRotation(ptr, mPhysics, mRendering, false);
|
||||||
ptr.getClass().adjustPosition (ptr, false);
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
@ -129,6 +128,17 @@ namespace
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AdjustPositionFunctor
|
||||||
|
{
|
||||||
|
bool operator() (const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled())
|
||||||
|
ptr.getClass().adjustPosition (ptr, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -553,6 +563,10 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
InsertFunctor functor (cell, rescale, *loadingListener, *mPhysics, mRendering);
|
InsertFunctor functor (cell, rescale, *loadingListener, *mPhysics, mRendering);
|
||||||
cell.forEach (functor);
|
cell.forEach (functor);
|
||||||
|
|
||||||
|
// do adjustPosition (snapping actors to ground) after objects are loaded, so we don't depend on the loading order
|
||||||
|
AdjustPositionFunctor adjustPosFunctor;
|
||||||
|
cell.forEach (adjustPosFunctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::addObjectToScene (const Ptr& ptr)
|
void Scene::addObjectToScene (const Ptr& ptr)
|
||||||
|
@ -722,7 +722,7 @@ namespace MWWorld
|
|||||||
for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt)
|
for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt)
|
||||||
{
|
{
|
||||||
FindContainerFunctor functor(ptr);
|
FindContainerFunctor functor(ptr);
|
||||||
(*cellIt)->forEachContainer(functor);
|
//(*cellIt)->forEachContainer(functor);
|
||||||
|
|
||||||
if (!functor.mResult.isEmpty())
|
if (!functor.mResult.isEmpty())
|
||||||
return functor.mResult;
|
return functor.mResult;
|
||||||
@ -1146,7 +1146,7 @@ namespace MWWorld
|
|||||||
bool newCellActive = mWorldScene->isCellActive(*newCell);
|
bool newCellActive = mWorldScene->isCellActive(*newCell);
|
||||||
if (!currCellActive && newCellActive)
|
if (!currCellActive && newCellActive)
|
||||||
{
|
{
|
||||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
|
newPtr = currCell->moveTo(ptr, newCell);
|
||||||
mWorldScene->addObjectToScene(newPtr);
|
mWorldScene->addObjectToScene(newPtr);
|
||||||
|
|
||||||
std::string script = newPtr.getClass().getScript(newPtr);
|
std::string script = newPtr.getClass().getScript(newPtr);
|
||||||
@ -1162,14 +1162,14 @@ namespace MWWorld
|
|||||||
removeContainerScripts (ptr);
|
removeContainerScripts (ptr);
|
||||||
haveToMove = false;
|
haveToMove = false;
|
||||||
|
|
||||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell);
|
newPtr = currCell->moveTo(ptr, newCell);
|
||||||
newPtr.getRefData().setBaseNode(0);
|
newPtr.getRefData().setBaseNode(0);
|
||||||
}
|
}
|
||||||
else if (!currCellActive && !newCellActive)
|
else if (!currCellActive && !newCellActive)
|
||||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell);
|
newPtr = currCell->moveTo(ptr, newCell);
|
||||||
else // both cells active
|
else // both cells active
|
||||||
{
|
{
|
||||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
|
newPtr = currCell->moveTo(ptr, newCell);
|
||||||
|
|
||||||
mRendering->updatePtr(ptr, newPtr);
|
mRendering->updatePtr(ptr, newPtr);
|
||||||
ptr.getRefData().setBaseNode(NULL);
|
ptr.getRefData().setBaseNode(NULL);
|
||||||
@ -1189,7 +1189,6 @@ namespace MWWorld
|
|||||||
addContainerScripts (newPtr, newCell);
|
addContainerScripts (newPtr, newCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr.getRefData().setCount(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (haveToMove && newPtr.getRefData().getBaseNode())
|
if (haveToMove && newPtr.getRefData().getBaseNode())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user