mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 07:21:12 +00:00
Merge remote-tracking branch 'wheybags/containerscripts'
This commit is contained in:
commit
2756d3ee94
@ -45,6 +45,7 @@ namespace MWWorld
|
||||
class Ptr;
|
||||
class TimeStamp;
|
||||
class ESMStore;
|
||||
class RefData;
|
||||
}
|
||||
|
||||
namespace MWBase
|
||||
@ -138,6 +139,9 @@ namespace MWBase
|
||||
|
||||
virtual std::string getCurrentCellName() const = 0;
|
||||
|
||||
virtual void removeRefScript (MWWorld::RefData *ref) = 0;
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
||||
virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "manualref.hpp"
|
||||
#include "refdata.hpp"
|
||||
#include "class.hpp"
|
||||
#include "localscripts.hpp"
|
||||
#include "player.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -71,6 +73,31 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|
||||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = addImp(ptr);
|
||||
MWWorld::Ptr item = *it;
|
||||
|
||||
std::string script = MWWorld::Class::get(item).getScript(item);
|
||||
if(script != "")
|
||||
{
|
||||
CellStore *cell;
|
||||
|
||||
Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
|
||||
// Items in players inventory have cell set to 0, so their scripts will never be removed
|
||||
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
|
||||
cell = 0;
|
||||
else
|
||||
cell = player.getCell();
|
||||
|
||||
item.mCell = cell;
|
||||
item.mContainerStore = 0;
|
||||
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
|
||||
{
|
||||
int type = getType(ptr);
|
||||
|
||||
@ -162,7 +189,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWor
|
||||
}
|
||||
|
||||
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
|
||||
add (ref.getPtr());
|
||||
addImp (ref.getPtr());
|
||||
}
|
||||
|
||||
flagAsModified();
|
||||
|
@ -52,6 +52,7 @@ namespace MWWorld
|
||||
int mStateId;
|
||||
mutable float mCachedWeight;
|
||||
mutable bool mWeightUpToDate;
|
||||
ContainerStoreIterator addImp (const Ptr& ptr);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
#include "esmstore.hpp"
|
||||
#include "cellstore.hpp"
|
||||
|
||||
#include "class.hpp"
|
||||
#include "containerstore.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
@ -19,6 +23,32 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds scripts for items in containers (containers/npcs/creatures)
|
||||
template<typename T>
|
||||
void listCellScriptsCont (MWWorld::LocalScripts& localScripts,
|
||||
MWWorld::CellRefList<T>& cellRefList, MWWorld::Ptr::CellStore *cell)
|
||||
{
|
||||
for (typename MWWorld::CellRefList<T>::List::iterator iter (
|
||||
cellRefList.mList.begin());
|
||||
iter!=cellRefList.mList.end(); ++iter)
|
||||
{
|
||||
|
||||
MWWorld::Ptr containerPtr (&*iter, cell);
|
||||
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(containerPtr).getContainerStore(containerPtr);
|
||||
for(MWWorld::ContainerStoreIterator it3 = container.begin(); it3 != container.end(); ++it3)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it3).getScript(*it3);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it3;
|
||||
item.mCell = cell;
|
||||
localScripts.add (script, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::LocalScripts::LocalScripts (const MWWorld::ESMStore& store) : mStore (store) {}
|
||||
@ -78,13 +108,16 @@ void MWWorld::LocalScripts::addCell (Ptr::CellStore *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);
|
||||
@ -101,7 +134,7 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
|
||||
|
||||
while (iter!=mScripts.end())
|
||||
{
|
||||
if (iter->second.getCell()==cell)
|
||||
if (iter->second.mCell==cell)
|
||||
{
|
||||
if (iter==mIter)
|
||||
++mIter;
|
||||
@ -113,6 +146,20 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
|
||||
}
|
||||
}
|
||||
|
||||
void MWWorld::LocalScripts::remove (RefData *ref)
|
||||
{
|
||||
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||
iter!=mScripts.end(); ++iter)
|
||||
if (&(iter->second.getRefData()) == ref)
|
||||
{
|
||||
if (iter==mIter)
|
||||
++mIter;
|
||||
|
||||
mScripts.erase (iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MWWorld::LocalScripts::remove (const Ptr& ptr)
|
||||
{
|
||||
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
|
||||
|
@ -10,6 +10,7 @@ namespace MWWorld
|
||||
{
|
||||
struct ESMStore;
|
||||
class CellStore;
|
||||
class RefData;
|
||||
|
||||
/// \brief List of active local scripts
|
||||
class LocalScripts
|
||||
@ -47,6 +48,8 @@ namespace MWWorld
|
||||
|
||||
void clearCell (CellStore *cell);
|
||||
///< Remove all scripts belonging to \a cell.
|
||||
|
||||
void remove (RefData *ref);
|
||||
|
||||
void remove (const Ptr& ptr);
|
||||
///< Remove script for given reference (ignored if reference does not have a scirpt listed).
|
||||
|
@ -74,7 +74,7 @@ namespace MWWorld
|
||||
|
||||
bool isInCell() const
|
||||
{
|
||||
return (mCell != 0);
|
||||
return (mContainerStore == 0);
|
||||
}
|
||||
|
||||
void setContainerStore (ContainerStore *store);
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include "customdata.hpp"
|
||||
#include "cellstore.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
void RefData::copy (const RefData& refData)
|
||||
@ -107,6 +110,9 @@ namespace MWWorld
|
||||
|
||||
void RefData::setCount (int count)
|
||||
{
|
||||
if(count == 0)
|
||||
MWBase::Environment::get().getWorld()->removeRefScript(this);
|
||||
|
||||
mCount = count;
|
||||
}
|
||||
|
||||
|
@ -341,6 +341,11 @@ namespace MWWorld
|
||||
return name;
|
||||
}
|
||||
|
||||
void World::removeRefScript (MWWorld::RefData *ref)
|
||||
{
|
||||
mLocalScripts.remove (ref);
|
||||
}
|
||||
|
||||
Ptr World::getPtr (const std::string& name, bool activeOnly)
|
||||
{
|
||||
// the player is always in an active cell.
|
||||
@ -396,23 +401,62 @@ namespace MWWorld
|
||||
return MWWorld::Ptr();
|
||||
}
|
||||
|
||||
void World::addContainerScripts(const Ptr& reference, Ptr::CellStore * cell)
|
||||
{
|
||||
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
||||
reference.getTypeName()==typeid (ESM::NPC).name() ||
|
||||
reference.getTypeName()==typeid (ESM::Creature).name())
|
||||
{
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
|
||||
for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it).getScript(*it);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it;
|
||||
item.mCell = cell;
|
||||
mLocalScripts.add (script, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::enable (const Ptr& reference)
|
||||
{
|
||||
if (!reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.getRefData().enable();
|
||||
|
||||
|
||||
if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
|
||||
mWorldScene->addObjectToScene (reference);
|
||||
}
|
||||
}
|
||||
|
||||
void World::removeContainerScripts(const Ptr& reference)
|
||||
{
|
||||
if( reference.getTypeName()==typeid (ESM::Container).name() ||
|
||||
reference.getTypeName()==typeid (ESM::NPC).name() ||
|
||||
reference.getTypeName()==typeid (ESM::Creature).name())
|
||||
{
|
||||
MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
|
||||
for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
|
||||
{
|
||||
std::string script = MWWorld::Class::get(*it).getScript(*it);
|
||||
if(script != "")
|
||||
{
|
||||
MWWorld::Ptr item = *it;
|
||||
mLocalScripts.remove (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::disable (const Ptr& reference)
|
||||
{
|
||||
if (reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.getRefData().disable();
|
||||
|
||||
|
||||
if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
|
||||
mWorldScene->removeObjectFromScene (reference);
|
||||
}
|
||||
@ -635,6 +679,7 @@ namespace MWWorld
|
||||
{
|
||||
mWorldScene->removeObjectFromScene (ptr);
|
||||
mLocalScripts.remove (ptr);
|
||||
removeContainerScripts (ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,6 +693,8 @@ namespace MWWorld
|
||||
CellStore *currCell = ptr.getCell();
|
||||
bool isPlayer = ptr == mPlayer->getPlayer();
|
||||
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
|
||||
|
||||
removeContainerScripts(ptr);
|
||||
|
||||
if (*currCell != newCell)
|
||||
{
|
||||
@ -675,6 +722,8 @@ namespace MWWorld
|
||||
MWWorld::Ptr copy =
|
||||
MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
|
||||
|
||||
addContainerScripts(copy, &newCell);
|
||||
|
||||
mRendering->moveObjectToCell(copy, vec, currCell);
|
||||
|
||||
if (MWWorld::Class::get(ptr).isActor())
|
||||
@ -1283,6 +1332,7 @@ namespace MWWorld
|
||||
if (!script.empty()) {
|
||||
mLocalScripts.add(script, dropped);
|
||||
}
|
||||
addContainerScripts(dropped, &cell);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,9 @@ namespace MWWorld
|
||||
float getNpcActivationDistance ();
|
||||
float getObjectActivationDistance ();
|
||||
|
||||
void removeContainerScripts(const Ptr& reference);
|
||||
void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
|
||||
|
||||
public:
|
||||
|
||||
World (OEngine::Render::OgreRenderer& renderer,
|
||||
@ -172,6 +175,9 @@ namespace MWWorld
|
||||
virtual std::vector<std::string> getGlobals () const;
|
||||
|
||||
virtual std::string getCurrentCellName () const;
|
||||
|
||||
virtual void removeRefScript (MWWorld::RefData *ref);
|
||||
//< Remove the script attached to ref from mLocalScripts
|
||||
|
||||
virtual Ptr getPtr (const std::string& name, bool activeOnly);
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
|
Loading…
x
Reference in New Issue
Block a user