mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +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>
|
||||
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());
|
||||
iter!=actorList.mList.end(); ++iter)
|
||||
{
|
||||
MWWorld::Ptr actor (&*iter, cell);
|
||||
|
||||
if (toIgnore.find(&*iter) != toIgnore.end())
|
||||
continue;
|
||||
|
||||
if (actor.getClass().getCreatureStats (actor).matchesActorId (actorId) && actor.getRefData().getCount() > 0)
|
||||
return actor;
|
||||
}
|
||||
@ -181,6 +184,7 @@ namespace MWWorld
|
||||
|
||||
void CellStore::moveFrom(const Ptr &object, CellStore *from)
|
||||
{
|
||||
mHasState = true;
|
||||
MovedRefTracker::iterator found = mMovedToAnotherCell.find(object.getBase());
|
||||
if (found != mMovedToAnotherCell.end())
|
||||
{
|
||||
@ -192,10 +196,27 @@ namespace MWWorld
|
||||
{
|
||||
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());
|
||||
if (found != mMovedHere.end())
|
||||
{
|
||||
@ -208,21 +229,59 @@ namespace MWWorld
|
||||
mMovedHere.erase(found);
|
||||
|
||||
// Now that object is back to its rightful owner, we can move it
|
||||
originalCell->moveTo(object, cellToMoveTo);
|
||||
if (cellToMoveTo != originalCell)
|
||||
{
|
||||
originalCell->moveTo(object, cellToMoveTo);
|
||||
}
|
||||
|
||||
updateMergedRefs();
|
||||
return;
|
||||
return MWWorld::Ptr(object.getBase(), cellToMoveTo);
|
||||
}
|
||||
|
||||
cellToMoveTo->moveFrom(object, this);
|
||||
mMovedToAnotherCell.insert(std::make_pair(object.getBase(), cellToMoveTo));
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
mMergedRefs.clear();
|
||||
MergeFunctor functor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
||||
forEachInternal(functor);
|
||||
functor.merge();
|
||||
}
|
||||
|
||||
CellStore::CellStore (const ESM::Cell *cell)
|
||||
@ -258,85 +317,50 @@ namespace MWWorld
|
||||
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)
|
||||
{
|
||||
bool oldState = mHasState;
|
||||
|
||||
mHasState = true;
|
||||
|
||||
if (LiveCellRef<ESM::Activator> *ref = mActivators.find (id))
|
||||
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);
|
||||
SearchFunctor searchFunctor;
|
||||
searchFunctor.mIdToFind = id;
|
||||
forEach(searchFunctor);
|
||||
|
||||
mHasState = oldState;
|
||||
|
||||
return Ptr();
|
||||
return searchFunctor.mFound;
|
||||
}
|
||||
|
||||
Ptr CellStore::searchViaActorId (int id)
|
||||
{
|
||||
if (Ptr ptr = ::searchViaActorId (mNpcs, id, this))
|
||||
if (Ptr ptr = ::searchViaActorId (mNpcs, id, this, mMovedToAnotherCell))
|
||||
return ptr;
|
||||
|
||||
if (Ptr ptr = ::searchViaActorId (mCreatures, id, this))
|
||||
if (Ptr ptr = ::searchViaActorId (mCreatures, id, this, mMovedToAnotherCell))
|
||||
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();
|
||||
}
|
||||
|
||||
@ -435,6 +459,8 @@ namespace MWWorld
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't need to check mMovedToAnotherCell because listRefs isn't used for loaded cells.
|
||||
|
||||
mIds.push_back (Misc::StringUtils::lowerCase (ref.mRefID));
|
||||
}
|
||||
}
|
||||
@ -447,6 +473,12 @@ namespace MWWorld
|
||||
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());
|
||||
}
|
||||
|
||||
@ -489,6 +521,8 @@ namespace MWWorld
|
||||
|
||||
loadRef (ref, false, store);
|
||||
}
|
||||
|
||||
updateMergedRefs();
|
||||
}
|
||||
|
||||
bool CellStore::isExterior() const
|
||||
@ -610,11 +644,15 @@ namespace MWWorld
|
||||
writeReferenceCollection<ESM::ObjectState> (writer, mRepairs);
|
||||
writeReferenceCollection<ESM::ObjectState> (writer, mStatics);
|
||||
writeReferenceCollection<ESM::ObjectState> (writer, mWeapons);
|
||||
|
||||
// TODO: write moved references
|
||||
}
|
||||
|
||||
void CellStore::readReferences (ESM::ESMReader& reader,
|
||||
const std::map<int, int>& contentFileMap)
|
||||
{
|
||||
// TODO: read moved references
|
||||
|
||||
mHasState = true;
|
||||
|
||||
while (reader.isNextSub ("OBJE"))
|
||||
|
@ -112,11 +112,64 @@ namespace MWWorld
|
||||
/// Repopulate mMergedRefs.
|
||||
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:
|
||||
|
||||
/// Moves object from this cell to the given cell.
|
||||
/// @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.
|
||||
/// @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;
|
||||
///< May return true for deleted IDs when in preload state. Will return false, if cell is
|
||||
/// 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);
|
||||
///< 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.
|
||||
/// \attention This function also lists deleted (count 0) objects!
|
||||
/// \return Iteration completed?
|
||||
///
|
||||
/// \note Creatures and NPCs are handled last.
|
||||
template<class Functor>
|
||||
bool forEach (Functor& functor)
|
||||
{
|
||||
if (mState != State_Loaded)
|
||||
return false;
|
||||
|
||||
mHasState = true;
|
||||
|
||||
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);
|
||||
}
|
||||
for (unsigned int i=0; i<mMergedRefs.size(); ++i)
|
||||
{
|
||||
if (mMergedRefs[i]->mData.isDeletedByContentFile())
|
||||
continue;
|
||||
|
||||
template<class Functor>
|
||||
bool forEachContainer (Functor& functor)
|
||||
{
|
||||
mHasState = true;
|
||||
|
||||
return
|
||||
forEachImp (functor, mContainers) &&
|
||||
forEachImp (functor, mCreatures) &&
|
||||
forEachImp (functor, mNpcs);
|
||||
if (!functor(MWWorld::Ptr(mMergedRefs[i], this)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \todo add const version of forEach
|
||||
@ -234,20 +266,6 @@ namespace MWWorld
|
||||
|
||||
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
|
||||
void listRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
|
||||
|
||||
@ -261,126 +279,105 @@ namespace MWWorld
|
||||
MWMechanics::PathgridGraph mPathgridGraph;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Activator>(const LiveCellRef<ESM::Activator>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mActivators.insert(*ref);
|
||||
return insertBase(mActivators, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Potion>(const LiveCellRef<ESM::Potion>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mPotions.insert(*ref);
|
||||
return insertBase(mPotions, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Apparatus>(const LiveCellRef<ESM::Apparatus>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mAppas.insert(*ref);
|
||||
return insertBase(mAppas, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Armor>(const LiveCellRef<ESM::Armor>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mArmors.insert(*ref);
|
||||
return insertBase(mArmors, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Book>(const LiveCellRef<ESM::Book>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mBooks.insert(*ref);
|
||||
return insertBase(mBooks, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Clothing>(const LiveCellRef<ESM::Clothing>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mClothes.insert(*ref);
|
||||
return insertBase(mClothes, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Container>(const LiveCellRef<ESM::Container>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mContainers.insert(*ref);
|
||||
return insertBase(mContainers, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Creature>(const LiveCellRef<ESM::Creature>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mCreatures.insert(*ref);
|
||||
return insertBase(mCreatures, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Door>(const LiveCellRef<ESM::Door>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mDoors.insert(*ref);
|
||||
return insertBase(mDoors, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Ingredient>(const LiveCellRef<ESM::Ingredient>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mIngreds.insert(*ref);
|
||||
return insertBase(mIngreds, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::CreatureLevList>(const LiveCellRef<ESM::CreatureLevList>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mCreatureLists.insert(*ref);
|
||||
return insertBase(mCreatureLists, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::ItemLevList>(const LiveCellRef<ESM::ItemLevList>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mItemLists.insert(*ref);
|
||||
return insertBase(mItemLists, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Light>(const LiveCellRef<ESM::Light>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mLights.insert(*ref);
|
||||
return insertBase(mLights, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Lockpick>(const LiveCellRef<ESM::Lockpick>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mLockpicks.insert(*ref);
|
||||
return insertBase(mLockpicks, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Miscellaneous>(const LiveCellRef<ESM::Miscellaneous>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mMiscItems.insert(*ref);
|
||||
return insertBase(mMiscItems, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::NPC>(const LiveCellRef<ESM::NPC>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mNpcs.insert(*ref);
|
||||
return insertBase(mNpcs, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Probe>(const LiveCellRef<ESM::Probe>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mProbes.insert(*ref);
|
||||
return insertBase(mProbes, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Repair>(const LiveCellRef<ESM::Repair>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mRepairs.insert(*ref);
|
||||
return insertBase(mRepairs, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Static>(const LiveCellRef<ESM::Static>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mStatics.insert(*ref);
|
||||
return insertBase(mStatics, ref);
|
||||
}
|
||||
template<>
|
||||
inline LiveCellRefBase* CellStore::insert<ESM::Weapon>(const LiveCellRef<ESM::Weapon>* ref)
|
||||
{
|
||||
mHasState = true;
|
||||
return &mWeapons.insert(*ref);
|
||||
return insertBase(mWeapons, ref);
|
||||
}
|
||||
|
||||
bool operator== (const CellStore& left, const CellStore& right);
|
||||
|
@ -116,7 +116,6 @@ namespace
|
||||
{
|
||||
addObject(ptr, mPhysics, mRendering);
|
||||
updateObjectRotation(ptr, mPhysics, mRendering, false);
|
||||
ptr.getClass().adjustPosition (ptr, false);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@ -129,6 +128,17 @@ namespace
|
||||
|
||||
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);
|
||||
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)
|
||||
|
@ -722,7 +722,7 @@ namespace MWWorld
|
||||
for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt)
|
||||
{
|
||||
FindContainerFunctor functor(ptr);
|
||||
(*cellIt)->forEachContainer(functor);
|
||||
//(*cellIt)->forEachContainer(functor);
|
||||
|
||||
if (!functor.mResult.isEmpty())
|
||||
return functor.mResult;
|
||||
@ -1146,7 +1146,7 @@ namespace MWWorld
|
||||
bool newCellActive = mWorldScene->isCellActive(*newCell);
|
||||
if (!currCellActive && newCellActive)
|
||||
{
|
||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
|
||||
newPtr = currCell->moveTo(ptr, newCell);
|
||||
mWorldScene->addObjectToScene(newPtr);
|
||||
|
||||
std::string script = newPtr.getClass().getScript(newPtr);
|
||||
@ -1162,14 +1162,14 @@ namespace MWWorld
|
||||
removeContainerScripts (ptr);
|
||||
haveToMove = false;
|
||||
|
||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell);
|
||||
newPtr = currCell->moveTo(ptr, newCell);
|
||||
newPtr.getRefData().setBaseNode(0);
|
||||
}
|
||||
else if (!currCellActive && !newCellActive)
|
||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell);
|
||||
newPtr = currCell->moveTo(ptr, newCell);
|
||||
else // both cells active
|
||||
{
|
||||
newPtr = ptr.getClass().copyToCell(ptr, *newCell, pos);
|
||||
newPtr = currCell->moveTo(ptr, newCell);
|
||||
|
||||
mRendering->updatePtr(ptr, newPtr);
|
||||
ptr.getRefData().setBaseNode(NULL);
|
||||
@ -1189,7 +1189,6 @@ namespace MWWorld
|
||||
addContainerScripts (newPtr, newCell);
|
||||
}
|
||||
}
|
||||
ptr.getRefData().setCount(0);
|
||||
}
|
||||
}
|
||||
if (haveToMove && newPtr.getRefData().getBaseNode())
|
||||
|
Loading…
x
Reference in New Issue
Block a user