1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-02 03:06:43 +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 Ptr;
class TimeStamp; class TimeStamp;
class ESMStore; class ESMStore;
class RefData;
} }
namespace MWBase namespace MWBase
@ -138,6 +139,9 @@ namespace MWBase
virtual std::string getCurrentCellName() const = 0; 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; virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
///< Return a pointer to a liveCellRef with the given name. ///< Return a pointer to a liveCellRef with the given name.
/// \param activeOnly do non search inactive cells. /// \param activeOnly do non search inactive cells.

View file

@ -15,6 +15,8 @@
#include "manualref.hpp" #include "manualref.hpp"
#include "refdata.hpp" #include "refdata.hpp"
#include "class.hpp" #include "class.hpp"
#include "localscripts.hpp"
#include "player.hpp"
namespace 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 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); 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) ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
add (ref.getPtr()); addImp (ref.getPtr());
} }
flagAsModified(); flagAsModified();

View file

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

View file

@ -3,6 +3,10 @@
#include "esmstore.hpp" #include "esmstore.hpp"
#include "cellstore.hpp" #include "cellstore.hpp"
#include "class.hpp"
#include "containerstore.hpp"
namespace namespace
{ {
template<typename T> 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) {} 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->mBooks, cell);
listCellScripts (*this, cell->mClothes, cell); listCellScripts (*this, cell->mClothes, cell);
listCellScripts (*this, cell->mContainers, cell); listCellScripts (*this, cell->mContainers, cell);
listCellScriptsCont (*this, cell->mContainers, cell);
listCellScripts (*this, cell->mCreatures, cell); listCellScripts (*this, cell->mCreatures, cell);
listCellScriptsCont (*this, cell->mCreatures, cell);
listCellScripts (*this, cell->mDoors, cell); listCellScripts (*this, cell->mDoors, cell);
listCellScripts (*this, cell->mIngreds, cell); listCellScripts (*this, cell->mIngreds, cell);
listCellScripts (*this, cell->mLights, cell); listCellScripts (*this, cell->mLights, cell);
listCellScripts (*this, cell->mLockpicks, cell); listCellScripts (*this, cell->mLockpicks, cell);
listCellScripts (*this, cell->mMiscItems, cell); listCellScripts (*this, cell->mMiscItems, cell);
listCellScripts (*this, cell->mNpcs, cell); listCellScripts (*this, cell->mNpcs, cell);
listCellScriptsCont (*this, cell->mNpcs, cell);
listCellScripts (*this, cell->mProbes, cell); listCellScripts (*this, cell->mProbes, cell);
listCellScripts (*this, cell->mRepairs, cell); listCellScripts (*this, cell->mRepairs, cell);
listCellScripts (*this, cell->mWeapons, cell); listCellScripts (*this, cell->mWeapons, cell);
@ -101,7 +134,7 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
while (iter!=mScripts.end()) while (iter!=mScripts.end())
{ {
if (iter->second.getCell()==cell) if (iter->second.mCell==cell)
{ {
if (iter==mIter) if (iter==mIter)
++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) void MWWorld::LocalScripts::remove (const Ptr& ptr)
{ {
for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin(); for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();

View file

@ -10,6 +10,7 @@ namespace MWWorld
{ {
struct ESMStore; struct ESMStore;
class CellStore; class CellStore;
class RefData;
/// \brief List of active local scripts /// \brief List of active local scripts
class LocalScripts class LocalScripts
@ -47,6 +48,8 @@ namespace MWWorld
void clearCell (CellStore *cell); void clearCell (CellStore *cell);
///< Remove all scripts belonging to \a cell. ///< Remove all scripts belonging to \a cell.
void remove (RefData *ref);
void remove (const Ptr& ptr); void remove (const Ptr& ptr);
///< Remove script for given reference (ignored if reference does not have a scirpt listed). ///< 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 bool isInCell() const
{ {
return (mCell != 0); return (mContainerStore == 0);
} }
void setContainerStore (ContainerStore *store); void setContainerStore (ContainerStore *store);

View file

@ -6,6 +6,9 @@
#include "customdata.hpp" #include "customdata.hpp"
#include "cellstore.hpp" #include "cellstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWWorld namespace MWWorld
{ {
void RefData::copy (const RefData& refData) void RefData::copy (const RefData& refData)
@ -107,6 +110,9 @@ namespace MWWorld
void RefData::setCount (int count) void RefData::setCount (int count)
{ {
if(count == 0)
MWBase::Environment::get().getWorld()->removeRefScript(this);
mCount = count; mCount = count;
} }

View file

@ -341,6 +341,11 @@ namespace MWWorld
return name; return name;
} }
void World::removeRefScript (MWWorld::RefData *ref)
{
mLocalScripts.remove (ref);
}
Ptr World::getPtr (const std::string& name, bool activeOnly) Ptr World::getPtr (const std::string& name, bool activeOnly)
{ {
// the player is always in an active cell. // the player is always in an active cell.
@ -396,23 +401,62 @@ namespace MWWorld
return MWWorld::Ptr(); 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) void World::enable (const Ptr& reference)
{ {
if (!reference.getRefData().isEnabled()) if (!reference.getRefData().isEnabled())
{ {
reference.getRefData().enable(); reference.getRefData().enable();
if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end() && reference.getRefData().getCount()) if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
mWorldScene->addObjectToScene (reference); 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) void World::disable (const Ptr& reference)
{ {
if (reference.getRefData().isEnabled()) if (reference.getRefData().isEnabled())
{ {
reference.getRefData().disable(); reference.getRefData().disable();
if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount()) if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
mWorldScene->removeObjectFromScene (reference); mWorldScene->removeObjectFromScene (reference);
} }
@ -635,6 +679,7 @@ namespace MWWorld
{ {
mWorldScene->removeObjectFromScene (ptr); mWorldScene->removeObjectFromScene (ptr);
mLocalScripts.remove (ptr); mLocalScripts.remove (ptr);
removeContainerScripts (ptr);
} }
} }
} }
@ -648,6 +693,8 @@ namespace MWWorld
CellStore *currCell = ptr.getCell(); CellStore *currCell = ptr.getCell();
bool isPlayer = ptr == mPlayer->getPlayer(); bool isPlayer = ptr == mPlayer->getPlayer();
bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer; bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
removeContainerScripts(ptr);
if (*currCell != newCell) if (*currCell != newCell)
{ {
@ -675,6 +722,8 @@ namespace MWWorld
MWWorld::Ptr copy = MWWorld::Ptr copy =
MWWorld::Class::get(ptr).copyToCell(ptr, newCell); MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
addContainerScripts(copy, &newCell);
mRendering->moveObjectToCell(copy, vec, currCell); mRendering->moveObjectToCell(copy, vec, currCell);
if (MWWorld::Class::get(ptr).isActor()) if (MWWorld::Class::get(ptr).isActor())
@ -1283,6 +1332,7 @@ namespace MWWorld
if (!script.empty()) { if (!script.empty()) {
mLocalScripts.add(script, dropped); mLocalScripts.add(script, dropped);
} }
addContainerScripts(dropped, &cell);
} }
} }

View file

@ -105,6 +105,9 @@ namespace MWWorld
float getNpcActivationDistance (); float getNpcActivationDistance ();
float getObjectActivationDistance (); float getObjectActivationDistance ();
void removeContainerScripts(const Ptr& reference);
void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
public: public:
World (OEngine::Render::OgreRenderer& renderer, World (OEngine::Render::OgreRenderer& renderer,
@ -172,6 +175,9 @@ namespace MWWorld
virtual std::vector<std::string> getGlobals () const; virtual std::vector<std::string> getGlobals () const;
virtual std::string getCurrentCellName () 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); virtual Ptr getPtr (const std::string& name, bool activeOnly);
///< Return a pointer to a liveCellRef with the given name. ///< Return a pointer to a liveCellRef with the given name.