diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 8bc104d25..16ab6321d 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -128,6 +128,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index b3a1af288..8580d61ce 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -148,7 +148,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Apparatus::canSell (const MWWorld::Ptr& item, int npcServices) const diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index e3974f243..550151e43 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -333,11 +333,11 @@ namespace MWClass if(weapon->getTypeName() == typeid(ESM::Weapon).name() && (weapon->get()->mBase->mData.mType == ESM::Weapon::LongBladeTwoHand || - weapon->get()->mBase->mData.mType == ESM::Weapon::BluntTwoClose || - weapon->get()->mBase->mData.mType == ESM::Weapon::BluntTwoWide || + weapon->get()->mBase->mData.mType == ESM::Weapon::BluntTwoClose || + weapon->get()->mBase->mData.mType == ESM::Weapon::BluntTwoWide || weapon->get()->mBase->mData.mType == ESM::Weapon::SpearTwoWide || - weapon->get()->mBase->mData.mType == ESM::Weapon::AxeTwoHand || - weapon->get()->mBase->mData.mType == ESM::Weapon::MarksmanBow || + weapon->get()->mBase->mData.mType == ESM::Weapon::AxeTwoHand || + weapon->get()->mBase->mData.mType == ESM::Weapon::MarksmanBow || weapon->get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)) { return std::make_pair(3,""); @@ -363,7 +363,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } int Armor::getEnchantmentPoints (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 0e6506514..ebc3b18e6 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -186,7 +186,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } int Book::getEnchantmentPoints (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index ab98d05ae..18a40d5d3 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -276,7 +276,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } int Clothing::getEnchantmentPoints (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 546d6538c..715784b7c 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -257,7 +257,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 516a4c510..2939a5431 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -680,7 +680,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Creature::isFlying(const MWWorld::Ptr &ptr) const diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index e9ac39f1d..3cd8237e7 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -258,6 +258,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index faf29bc83..e15424c38 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -30,7 +30,7 @@ namespace MWClass return ref->mBase->mId; } - + void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); @@ -89,16 +89,16 @@ namespace MWClass return ref->mBase->mData.mValue; } - + boost::shared_ptr Ingredient::use (const MWWorld::Ptr& ptr) const { boost::shared_ptr action (new MWWorld::ActionEat (ptr)); action->setSound ("Swallow"); - return action; + return action; } - + void Ingredient::registerSelf() { boost::shared_ptr instance (new Ingredient); @@ -189,7 +189,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Ingredient::canSell (const MWWorld::Ptr& item, int npcServices) const diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index ddb2c16d6..72de620e4 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -227,7 +227,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } void Light::ensureCustomData (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 795b66052..60ffec7b9 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -169,7 +169,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Lockpick::canSell (const MWWorld::Ptr& item, int npcServices) const diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index e58716f1c..e568bf869 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -218,13 +218,13 @@ namespace MWClass MWWorld::ManualRef newRef(store, base); MWWorld::LiveCellRef *ref = newRef.getPtr().get(); - newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell); + newPtr = MWWorld::Ptr(&cell.get().insert(*ref), &cell); newPtr.getCellRef().mGoldValue = goldAmount; newPtr.getRefData().setCount(1); } else { MWWorld::LiveCellRef *ref = ptr.get(); - newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell); + newPtr = MWWorld::Ptr(&cell.get().insert(*ref), &cell); } return newPtr; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e00c3b720..20c7d9a0e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1253,7 +1253,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index d68db4e45..216f815cd 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -185,7 +185,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Potion::canSell (const MWWorld::Ptr& item, int npcServices) const diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 4209c1431..d376270cb 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -168,7 +168,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } bool Probe::canSell (const MWWorld::Ptr& item, int npcServices) const diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 5f2065c3c..af79a9691 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -163,7 +163,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } boost::shared_ptr Repair::use (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index f8677dc20..4ac41350f 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -58,6 +58,6 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mStatics.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index af0234cd5..e9b0c8f3c 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -426,7 +426,7 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); - return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell); + return MWWorld::Ptr(&cell.get().insert(*ref), &cell); } int Weapon::getEnchantmentPoints (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwworld/cellreflist.hpp b/apps/openmw/mwworld/cellreflist.hpp index 8240fbd2d..264929bfb 100644 --- a/apps/openmw/mwworld/cellreflist.hpp +++ b/apps/openmw/mwworld/cellreflist.hpp @@ -38,6 +38,16 @@ namespace MWWorld mList.push_back(item); return mList.back(); } + + LiveCellRef *searchViaHandle (const std::string& handle) + { + for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter) + if (iter->mData.getCount()>0 && iter->mData.getBaseNode() && + iter->mData.getHandle()==handle) + return &*iter; + + return 0; + } }; } diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 91bda79af..8b0740d3b 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -233,6 +233,71 @@ namespace MWWorld return Ptr(); } + Ptr CellStore::searchViaHandle (const std::string& handle) + { + if (LiveCellRef *ref = mActivators.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mPotions.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mAppas.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mArmors.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mBooks.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mClothes.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mContainers.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mCreatures.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mDoors.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mIngreds.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mCreatureLists.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mItemLists.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mLights.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mLockpicks.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mMiscItems.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mNpcs.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mProbes.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mRepairs.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mStatics.searchViaHandle (handle)) + return Ptr (ref, this); + + if (LiveCellRef *ref = mWeapons.searchViaHandle (handle)) + return Ptr (ref, this); + + return Ptr(); + } + float CellStore::getWaterLevel() const { return mWaterLevel; @@ -243,6 +308,31 @@ namespace MWWorld mWaterLevel = level; } + int CellStore::count() const + { + return + mActivators.mList.size() + + mPotions.mList.size() + + mAppas.mList.size() + + mArmors.mList.size() + + mBooks.mList.size() + + mClothes.mList.size() + + mContainers.mList.size() + + mDoors.mList.size() + + mIngreds.mList.size() + + mCreatureLists.mList.size() + + mItemLists.mList.size() + + mLights.mList.size() + + mLockpicks.mList.size() + + mMiscItems.mList.size() + + mProbes.mList.size() + + mRepairs.mList.size() + + mStatics.mList.size() + + mWeapons.mList.size() + + mCreatures.mList.size() + + mNpcs.mList.size(); + } + void CellStore::load (const MWWorld::ESMStore &store, std::vector &esm) { if (mState!=State_Loaded) diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index c576a0609..5ff63c582 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "livecellref.hpp" #include "esmstore.hpp" @@ -34,6 +35,27 @@ namespace MWWorld std::vector mIds; float mWaterLevel; + CellRefList mActivators; + CellRefList mPotions; + CellRefList mAppas; + CellRefList mArmors; + CellRefList mBooks; + CellRefList mClothes; + CellRefList mContainers; + CellRefList mCreatures; + CellRefList mDoors; + CellRefList mIngreds; + CellRefList mCreatureLists; + CellRefList mItemLists; + CellRefList mLights; + CellRefList mLockpicks; + CellRefList mMiscItems; + CellRefList mNpcs; + CellRefList mProbes; + CellRefList mRepairs; + CellRefList mStatics; + CellRefList mWeapons; + public: CellStore (const ESM::Cell *cell_); @@ -50,31 +72,16 @@ namespace MWWorld ///< Will return an empty Ptr if cell is not loaded. Does not check references in /// containers. + Ptr searchViaHandle (const std::string& handle); + ///< Will return an empty Ptr if cell is not loaded. + float getWaterLevel() const; void setWaterLevel (float level); - // Lists for each individual object type - CellRefList mActivators; - CellRefList mPotions; - CellRefList mAppas; - CellRefList mArmors; - CellRefList mBooks; - CellRefList mClothes; - CellRefList mContainers; - CellRefList mCreatures; - CellRefList mDoors; - CellRefList mIngreds; - CellRefList mCreatureLists; - CellRefList mItemLists; - CellRefList mLights; - CellRefList mLockpicks; - CellRefList mMiscItems; - CellRefList mNpcs; - CellRefList mProbes; - CellRefList mRepairs; - CellRefList mStatics; - CellRefList mWeapons; + int count() const; + ///< Return total number of references, including deleted ones. + void load (const MWWorld::ESMStore &store, std::vector &esm); @@ -83,6 +90,8 @@ namespace MWWorld /// Call functor (ref) for each reference. functor must return a bool. Returning /// false will abort the iteration. /// \return Iteration completed? + /// + /// \note Creatures and NPCs are handled last. template bool forEach (Functor& functor) { @@ -94,19 +103,19 @@ namespace MWWorld forEachImp (functor, mBooks) && forEachImp (functor, mClothes) && forEachImp (functor, mContainers) && - forEachImp (functor, mCreatures) && forEachImp (functor, mDoors) && forEachImp (functor, mIngreds) && - forEachImp (functor, mCreatureLists) && forEachImp (functor, mItemLists) && forEachImp (functor, mLights) && forEachImp (functor, mLockpicks) && forEachImp (functor, mMiscItems) && - forEachImp (functor, mNpcs) && forEachImp (functor, mProbes) && forEachImp (functor, mRepairs) && forEachImp (functor, mStatics) && - forEachImp (functor, mWeapons); + forEachImp (functor, mWeapons) && + forEachImp (functor, mCreatures) && + forEachImp (functor, mNpcs) && + forEachImp (functor, mCreatureLists); } bool operator==(const CellStore &cell) { @@ -133,6 +142,11 @@ namespace MWWorld void readReferences (ESM::ESMReader& reader, const std::map& contentFileMap); + template + CellRefList& get() { + throw std::runtime_error ("Storage for this type not exist in cells"); + } + private: template @@ -159,6 +173,126 @@ namespace MWWorld /// /// Invalid \a ref objects are silently dropped. }; + + template<> + inline CellRefList& CellStore::get() + { + return mActivators; + } + + template<> + inline CellRefList& CellStore::get() + { + return mPotions; + } + + template<> + inline CellRefList& CellStore::get() + { + return mAppas; + } + + template<> + inline CellRefList& CellStore::get() + { + return mArmors; + } + + template<> + inline CellRefList& CellStore::get() + { + return mBooks; + } + + template<> + inline CellRefList& CellStore::get() + { + return mClothes; + } + + template<> + inline CellRefList& CellStore::get() + { + return mContainers; + } + + template<> + inline CellRefList& CellStore::get() + { + return mCreatures; + } + + template<> + inline CellRefList& CellStore::get() + { + return mDoors; + } + + template<> + inline CellRefList& CellStore::get() + { + return mIngreds; + } + + template<> + inline CellRefList& CellStore::get() + { + return mCreatureLists; + } + + template<> + inline CellRefList& CellStore::get() + { + return mItemLists; + } + + template<> + inline CellRefList& CellStore::get() + { + return mLights; + } + + template<> + inline CellRefList& CellStore::get() + { + return mLockpicks; + } + + template<> + inline CellRefList& CellStore::get() + { + return mMiscItems; + } + + template<> + inline CellRefList& CellStore::get() + { + return mNpcs; + } + + template<> + inline CellRefList& CellStore::get() + { + return mProbes; + } + + template<> + inline CellRefList& CellStore::get() + { + return mRepairs; + } + + template<> + inline CellRefList& CellStore::get() + { + return mStatics; + } + + template<> + inline CellRefList& CellStore::get() + { + return mWeapons; + } } #endif diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index 997e9e32c..844e2b18b 100644 --- a/apps/openmw/mwworld/localscripts.cpp +++ b/apps/openmw/mwworld/localscripts.cpp @@ -101,26 +101,26 @@ void MWWorld::LocalScripts::add (const std::string& scriptName, const Ptr& ptr) void MWWorld::LocalScripts::addCell (CellStore *cell) { - listCellScripts (*this, cell->mActivators, cell); - listCellScripts (*this, cell->mPotions, cell); - listCellScripts (*this, cell->mAppas, cell); - listCellScripts (*this, cell->mArmors, cell); - listCellScripts (*this, cell->mBooks, cell); - listCellScripts (*this, cell->mClothes, cell); - listCellScripts (*this, cell->mContainers, cell); - listCellScriptsCont (*this, cell->mContainers, cell); - listCellScripts (*this, cell->mCreatures, cell); - listCellScriptsCont (*this, cell->mCreatures, cell); - listCellScripts (*this, cell->mDoors, cell); - listCellScripts (*this, cell->mIngreds, cell); - listCellScripts (*this, cell->mLights, cell); - listCellScripts (*this, cell->mLockpicks, cell); - listCellScripts (*this, cell->mMiscItems, cell); - listCellScripts (*this, cell->mNpcs, cell); - listCellScriptsCont (*this, cell->mNpcs, cell); - listCellScripts (*this, cell->mProbes, cell); - listCellScripts (*this, cell->mRepairs, cell); - listCellScripts (*this, cell->mWeapons, cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScriptsCont (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScriptsCont (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScriptsCont (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); + listCellScripts (*this, cell->get(), cell); } void MWWorld::LocalScripts::clear() diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 248d452c1..10afbc675 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -22,6 +22,63 @@ namespace { + struct InsertFunctor + { + MWWorld::CellStore& mCell; + bool mRescale; + Loading::Listener& mLoadingListener; + MWWorld::PhysicsSystem& mPhysics; + MWRender::RenderingManager& mRendering; + + InsertFunctor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener, + MWWorld::PhysicsSystem& physics, MWRender::RenderingManager& rendering); + + bool operator() (const MWWorld::Ptr& ptr); + }; + + InsertFunctor::InsertFunctor (MWWorld::CellStore& cell, bool rescale, + Loading::Listener& loadingListener, MWWorld::PhysicsSystem& physics, + MWRender::RenderingManager& rendering) + : mCell (cell), mRescale (rescale), mLoadingListener (loadingListener), + mPhysics (physics), mRendering (rendering) + {} + + bool InsertFunctor::InsertFunctor::operator() (const MWWorld::Ptr& ptr) + { + if (mRescale) + { + if (ptr.getCellRef().mScale<0.5) + ptr.getCellRef().mScale = 0.5; + else if (ptr.getCellRef().mScale>2) + ptr.getCellRef().mScale = 2; + } + + if (ptr.getRefData().getCount() && ptr.getRefData().isEnabled()) + { + try + { + mRendering.addObject (ptr); + ptr.getClass().insertObject (ptr, mPhysics); + + float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees(); + float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees(); + float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees(); + MWBase::Environment::get().getWorld()->localRotateObject (ptr, ax, ay, az); + + MWBase::Environment::get().getWorld()->scaleObject (ptr, ptr.getCellRef().mScale); + ptr.getClass().adjustPosition (ptr); + } + catch (const std::exception& e) + { + std::string error ("error during rendering: "); + std::cerr << error + e.what() << std::endl; + } + } + + mLoadingListener.increaseProgress (1); + + return true; + } template void insertCellRefList(MWRender::RenderingManager& rendering, @@ -267,7 +324,7 @@ namespace MWWorld } if (iter==mActiveCells.end()) - refsToLoad += countRefs(*MWBase::Environment::get().getWorld()->getExterior(x, y)); + refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count(); } loadingListener->setProgressRange(refsToLoad); @@ -403,7 +460,7 @@ namespace MWWorld ++current; } - int refsToLoad = countRefs(*cell); + int refsToLoad = cell->count(); loadingListener->setProgressRange(refsToLoad); // Load cell. @@ -451,55 +508,10 @@ namespace MWWorld mCellChanged = false; } - int Scene::countRefs (const CellStore& cell) - { - return cell.mActivators.mList.size() - + cell.mPotions.mList.size() - + cell.mAppas.mList.size() - + cell.mArmors.mList.size() - + cell.mBooks.mList.size() - + cell.mClothes.mList.size() - + cell.mContainers.mList.size() - + cell.mDoors.mList.size() - + cell.mIngreds.mList.size() - + cell.mCreatureLists.mList.size() - + cell.mItemLists.mList.size() - + cell.mLights.mList.size() - + cell.mLockpicks.mList.size() - + cell.mMiscItems.mList.size() - + cell.mProbes.mList.size() - + cell.mRepairs.mList.size() - + cell.mStatics.mList.size() - + cell.mWeapons.mList.size() - + cell.mCreatures.mList.size() - + cell.mNpcs.mList.size(); - } - void Scene::insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener) { - // Loop through all references in the cell - insertCellRefList(mRendering, cell.mActivators, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mPotions, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mAppas, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mArmors, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mBooks, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mClothes, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mContainers, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mDoors, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mIngreds, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mItemLists, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mLights, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mLockpicks, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mMiscItems, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mProbes, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mRepairs, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mStatics, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mWeapons, cell, *mPhysics, rescale, loadingListener); - // Load NPCs and creatures _after_ everything else (important for adjustPosition to work correctly) - insertCellRefList(mRendering, cell.mCreatures, cell, *mPhysics, rescale, loadingListener); - insertCellRefList(mRendering, cell.mNpcs, cell, *mPhysics, rescale, loadingListener); - // Since this adds additional creatures, load afterwards, or they would be loaded twice - insertCellRefList(mRendering, cell.mCreatureLists, cell, *mPhysics, rescale, loadingListener); + InsertFunctor functor (cell, rescale, *loadingListener, *mPhysics, mRendering); + cell.forEach (functor); } void Scene::addObjectToScene (const Ptr& ptr) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index af833f331..16d4877a9 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -63,8 +63,6 @@ namespace MWWorld void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener); - int countRefs (const CellStore& cell); - public: Scene (MWRender::RenderingManager& rendering, PhysicsSystem *physics); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e258d8503..b51e224f8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -48,27 +48,6 @@ using namespace Ogre; -namespace -{ - template - MWWorld::LiveCellRef *searchViaHandle (const std::string& handle, - MWWorld::CellRefList& refList) - { - typedef typename MWWorld::CellRefList::List::iterator iterator; - - for (iterator iter (refList.mList.begin()); iter!=refList.mList.end(); ++iter) - { - if (iter->mData.getCount() > 0 && iter->mData.getBaseNode()){ - if (iter->mData.getHandle()==handle) - { - return &*iter; - } - } - } - return 0; - } -} - namespace MWWorld { struct GameContentLoader : public ContentLoader @@ -103,52 +82,6 @@ namespace MWWorld LoadersContainer mLoaders; }; - Ptr World::getPtrViaHandle (const std::string& handle, CellStore& cell) - { - if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.mActivators)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mPotions)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mAppas)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mArmors)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mBooks)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mClothes)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.mContainers)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.mCreatures)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mDoors)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = - searchViaHandle (handle, cell.mIngreds)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mLights)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mLockpicks)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mMiscItems)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mNpcs)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mProbes)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mRepairs)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mStatics)) - return Ptr (ref, &cell); - if (MWWorld::LiveCellRef *ref = searchViaHandle (handle, cell.mWeapons)) - return Ptr (ref, &cell); - return Ptr(); - } - - int World::getDaysPerMonth (int month) const { switch (month) @@ -579,7 +512,7 @@ namespace MWWorld iter!=mWorldScene->getActiveCells().end(); ++iter) { CellStore* cellstore = *iter; - Ptr ptr = getPtrViaHandle (handle, *cellstore); + Ptr ptr = cellstore->searchViaHandle (handle); if (!ptr.isEmpty()) return ptr; @@ -1505,7 +1438,7 @@ namespace MWWorld Ogre::Vector2 World::getNorthVector (CellStore* cell) { - MWWorld::CellRefList& statics = cell->mStatics; + MWWorld::CellRefList& statics = cell->get(); MWWorld::LiveCellRef* ref = statics.find("northmarker"); if (!ref) return Vector2(0, 1); @@ -1517,7 +1450,7 @@ namespace MWWorld void World::getDoorMarkers (CellStore* cell, std::vector& out) { - MWWorld::CellRefList& doors = cell->mDoors; + MWWorld::CellRefList& doors = cell->get(); CellRefList::List& refList = doors.mList; for (CellRefList::List::iterator it = refList.begin(); it != refList.end(); ++it) { @@ -1900,7 +1833,7 @@ namespace MWWorld const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells(); for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt) { - MWWorld::CellRefList& containers = (*cellIt)->mContainers; + MWWorld::CellRefList& containers = (*cellIt)->get(); CellRefList::List& refList = containers.mList; for (CellRefList::List::iterator container = refList.begin(); container != refList.end(); ++container) { @@ -1972,7 +1905,7 @@ namespace MWWorld if (0 == cellStore) { return false; } - const DoorList &doors = cellStore->mDoors.mList; + const DoorList &doors = cellStore->get().mList; for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) { if (!it->mRef.mTeleport) { continue; @@ -1994,7 +1927,7 @@ namespace MWWorld if (0 != source) { // Find door leading to our current teleport door // and use it destination to position inside cell. - const DoorList &doors = source->mDoors.mList; + const DoorList &doors = source->get().mList; for (DoorList::const_iterator jt = doors.begin(); jt != doors.end(); ++jt) { if (it->mRef.mTeleport && Misc::StringUtils::ciEqual(name, jt->mRef.mDestCell)) @@ -2402,7 +2335,7 @@ namespace MWWorld { if (cell->isExterior()) return false; - MWWorld::CellRefList& doors = cell->mDoors; + MWWorld::CellRefList& doors = cell->get(); CellRefList::List& refList = doors.mList; // Check if any door in the cell leads to an exterior directly