1
0
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:
Marc Zinnschlag 2013-01-21 23:02:45 +01:00
commit 2756d3ee94
9 changed files with 149 additions and 5 deletions

View File

@ -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.

View File

@ -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();

View File

@ -52,6 +52,7 @@ namespace MWWorld
int mStateId;
mutable float mCachedWeight;
mutable bool mWeightUpToDate;
ContainerStoreIterator addImp (const Ptr& ptr);
public:

View File

@ -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();

View File

@ -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).

View File

@ -74,7 +74,7 @@ namespace MWWorld
bool isInCell() const
{
return (mCell != 0);
return (mContainerStore == 0);
}
void setContainerStore (ContainerStore *store);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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.