mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-12 04:14:05 +00:00
accessing references via their ID now also works for references in containers in active cells
This commit is contained in:
parent
aee0336780
commit
e94fcce622
@ -48,7 +48,7 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellS
|
||||
{
|
||||
Ptr ptr = getPtr (name, cellStore);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
if (!ptr.isEmpty() && ptr.isInCell())
|
||||
{
|
||||
mIdCache[mIdCacheIndex].first = name;
|
||||
mIdCache[mIdCacheIndex].second = &cellStore;
|
||||
@ -121,7 +121,8 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getInterior (const std::string& name)
|
||||
return &result->second;
|
||||
}
|
||||
|
||||
MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& cell)
|
||||
MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& cell,
|
||||
bool searchInContainers)
|
||||
{
|
||||
if (cell.mState==Ptr::CellStore::State_Unloaded)
|
||||
cell.preload (mStore, mReader);
|
||||
@ -138,71 +139,69 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce
|
||||
return Ptr();
|
||||
}
|
||||
|
||||
MWWorld::Ptr ptr;
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Activator> *ref = cell.mActivators.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Potion> *ref = cell.mPotions.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Apparatus> *ref = cell.mAppas.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Armor> *ref = cell.mArmors.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Book> *ref = cell.mBooks.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Clothing> *ref = cell.mClothes.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Container> *ref = cell.mContainers.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Creature> *ref = cell.mCreatures.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Door> *ref = cell.mDoors.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Ingredient> *ref = cell.mIngreds.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::CreatureLevList> *ref = cell.mCreatureLists.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::ItemLevList> *ref = cell.mItemLists.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Light> *ref = cell.mLights.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Lockpick> *ref = cell.mLockpicks.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = cell.mMiscItems.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::NPC> *ref = cell.mNpcs.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Probe> *ref = cell.mProbes.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Repair> *ref = cell.mRepairs.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Static> *ref = cell.mStatics.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Weapon> *ref = cell.mWeapons.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (searchInContainers)
|
||||
return cell.searchInContainer (name);
|
||||
|
||||
if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) {
|
||||
return ptr;
|
||||
}
|
||||
return Ptr();
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,8 @@ namespace MWWorld
|
||||
|
||||
CellStore *getInterior (const std::string& name);
|
||||
|
||||
Ptr getPtr (const std::string& name, CellStore& cellStore);
|
||||
Ptr getPtr (const std::string& name, CellStore& cellStore, bool searchInContainers = false);
|
||||
///< \param searchInContainers Only affect loaded cells.
|
||||
|
||||
Ptr getPtr (const std::string& name);
|
||||
};
|
||||
|
@ -7,6 +7,29 @@
|
||||
|
||||
#include "ptr.hpp"
|
||||
#include "esmstore.hpp"
|
||||
#include "class.hpp"
|
||||
#include "containerstore.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
MWWorld::Ptr searchInContainerList (MWWorld::CellRefList<T>& containerList, const std::string& id)
|
||||
{
|
||||
for (typename MWWorld::CellRefList<T>::List::iterator iter (containerList.mList.begin());
|
||||
iter!=containerList.mList.end(); ++iter)
|
||||
{
|
||||
MWWorld::Ptr container (&*iter, 0);
|
||||
|
||||
MWWorld::Ptr ptr =
|
||||
MWWorld::Class::get (container).getContainerStore (container).search (id);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return MWWorld::Ptr();
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
@ -224,4 +247,30 @@ namespace MWWorld
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Ptr CellStore::searchInContainer (const std::string& id)
|
||||
{
|
||||
{
|
||||
Ptr ptr = searchInContainerList (mContainers, id);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
return ptr;
|
||||
}
|
||||
|
||||
{
|
||||
Ptr ptr = searchInContainerList (mCreatures, id);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
return ptr;
|
||||
}
|
||||
|
||||
{
|
||||
Ptr ptr = searchInContainerList (mNpcs, id);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return Ptr();
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,8 @@ namespace MWWorld
|
||||
return mCell->isExterior();
|
||||
}
|
||||
|
||||
Ptr searchInContainer (const std::string& id);
|
||||
|
||||
private:
|
||||
|
||||
template<class Functor, class List>
|
||||
@ -148,6 +150,7 @@ namespace MWWorld
|
||||
void listRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
|
||||
|
||||
void loadRefs(const MWWorld::ESMStore &store, std::vector<ESM::ESMReader> &esm);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <components/esm/loadcont.hpp>
|
||||
#include <components/compiler/locals.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
@ -347,6 +348,25 @@ int MWWorld::ContainerStore::getType (const Ptr& ptr)
|
||||
"Object of type " + ptr.getTypeName() + " can not be placed into a container");
|
||||
}
|
||||
|
||||
MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id)
|
||||
{
|
||||
/// \todo Since we have direct access to the CellRefList here, the performance of this function
|
||||
/// could be improved notably by iterating directly over the CellRefLists instead of using
|
||||
/// a ContainerStoreIterator.
|
||||
|
||||
std::string id2 = Misc::StringUtils::lowerCase (id);
|
||||
|
||||
for (ContainerStoreIterator iter (this); iter!=end(); ++iter)
|
||||
{
|
||||
Ptr ptr = *iter;
|
||||
|
||||
if (Misc::StringUtils::lowerCase (Class::get (ptr).getId (ptr))==id2)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
return Ptr();
|
||||
}
|
||||
|
||||
|
||||
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container)
|
||||
: mType (-1), mMask (0), mContainer (container)
|
||||
|
@ -106,6 +106,8 @@ namespace MWWorld
|
||||
///< This function throws an exception, if ptr does not point to an object, that can be
|
||||
/// put into a container.
|
||||
|
||||
Ptr search (const std::string& id);
|
||||
|
||||
friend class ContainerStoreIterator;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user