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:
commit
2756d3ee94
9 changed files with 149 additions and 5 deletions
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue