Merge branch 'equipment' into next

This commit is contained in:
Marc Zinnschlag 2012-02-23 13:02:20 +01:00
commit 26bd2be1e8
41 changed files with 505 additions and 313 deletions

View file

@ -43,7 +43,7 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld
refdata world physicssystem scene environment globals class action nullaction actionteleport
containerstore actiontalk actiontake containerstore manualref containerutil player cellfunctors
containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata
)

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -59,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Apparatus::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.appas);
}
std::string Apparatus::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -71,12 +69,6 @@ namespace MWClass
return ref->base->data.health;
}
void Armor::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.armors);
}
std::string Armor::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =

View file

@ -28,10 +28,6 @@ namespace MWClass
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -61,12 +59,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Book::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.books);
}
std::string Book::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -59,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Clothing::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.clothes);
}
std::string Clothing::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -15,7 +15,7 @@ namespace
{
struct CustomData : public MWWorld::CustomData
{
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
MWWorld::ContainerStore mContainerStore;
virtual MWWorld::CustomData *clone() const;
};
@ -79,7 +79,7 @@ namespace MWClass
return ref->base->name;
}
MWWorld::ContainerStore<MWWorld::RefData>& Container::getContainerStore (const MWWorld::Ptr& ptr)
MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr)
const
{
ensureCustomData (ptr);

View file

@ -20,8 +20,7 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
const MWWorld::Ptr& ptr) const;
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
///< Return container store
virtual std::string getScript (const MWWorld::Ptr& ptr) const;

View file

@ -1,28 +0,0 @@
#ifndef GAME_MWCLASS_CONTAINERUTIL_H
#define GAME_MWCLASS_CONTAINERUTIL_H
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/containerstore.hpp"
namespace MWClass
{
template<typename T>
void insertIntoContainerStore (const MWWorld::Ptr& ptr,
ESMS::CellRefList<T, MWWorld::RefData>& containerStore)
{
if (!ptr.isEmpty())
{
// TODO check stacking
ESMS::LiveCellRef<T, MWWorld::RefData> cellRef(ptr.getCellRef(), ptr.get<T>()->base);
cellRef.mData = ptr.getRefData();
containerStore.list.push_back (cellRef);
}
}
}
#endif

View file

@ -17,7 +17,7 @@ namespace
struct CustomData : public MWWorld::CustomData
{
MWMechanics::CreatureStats mCreatureStats;
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
MWWorld::ContainerStore mContainerStore;
virtual MWWorld::CustomData *clone() const;
};
@ -118,7 +118,7 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
MWWorld::ContainerStore<MWWorld::RefData>& Creature::getContainerStore (const MWWorld::Ptr& ptr)
MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr)
const
{
ensureCustomData (ptr);

View file

@ -39,7 +39,7 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
virtual MWWorld::ContainerStore& getContainerStore (
const MWWorld::Ptr& ptr) const;
///< Return container store

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -57,12 +55,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Ingredient::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.ingreds);
}
std::string Ingredient::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -14,8 +14,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -88,12 +86,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Light::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.lights);
}
std::string Light::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =

View file

@ -27,10 +27,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -60,12 +58,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Lockpick::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.lockpicks);
}
std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -59,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Miscellaneous::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.miscItems);
}
std::string Miscellaneous::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -29,7 +29,7 @@ namespace
MWMechanics::NpcStats mNpcStats;
MWMechanics::CreatureStats mCreatureStats;
MWMechanics::Movement mMovement;
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
MWWorld::ContainerStore mContainerStore;
virtual MWWorld::CustomData *clone() const;
};
@ -156,7 +156,7 @@ namespace MWClass
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
MWWorld::ContainerStore<MWWorld::RefData>& Npc::getContainerStore (const MWWorld::Ptr& ptr)
MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr)
const
{
ensureCustomData (ptr);

View file

@ -35,8 +35,7 @@ namespace MWClass
virtual MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const;
///< Return NPC stats
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
const MWWorld::Ptr& ptr) const;
virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const;
///< Return container store
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -59,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Potion::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.potions);
}
std::string Potion::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -8,7 +8,6 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
#include "../mwrender/objects.hpp"
namespace MWClass
@ -20,7 +19,7 @@ namespace MWClass
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects();
@ -58,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Probe::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.probes);
}
std::string Probe::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -59,12 +57,6 @@ namespace MWClass
new MWWorld::ActionTake (ptr));
}
void Repair::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.repairs);
}
std::string Repair::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =

View file

@ -22,10 +22,6 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -10,8 +10,6 @@
#include "../mwrender/objects.hpp"
#include "containerutil.hpp"
namespace MWClass
{
void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -72,12 +70,6 @@ namespace MWClass
return ref->base->data.health;
}
void Weapon::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.weapons);
}
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =

View file

@ -28,10 +28,6 @@ namespace MWClass
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health
virtual void insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const;
///< Insert into a containe
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

View file

@ -11,7 +11,7 @@
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerutil.hpp"
#include "../mwworld/containerstore.hpp"
#include "interpretercontext.hpp"
#include "ref.hpp"
@ -45,8 +45,7 @@ namespace MWScript
ref.getPtr().getRefData().setCount (count);
MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(),
MWWorld::Class::get (ptr).getContainerStore (ptr));
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
}
};
@ -59,25 +58,16 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
std::vector<MWWorld::Ptr> list;
MWWorld::listItemsInContainer (item,
MWWorld::Class::get (ptr).getContainerStore (ptr),
context.getWorld().getStore(), list);
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
Interpreter::Type_Integer sum = 0;
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin()); iter!=list.end();
++iter)
{
sum += iter->getRefData().getCount();
}
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (iter->getCellRef().refID==item)
sum += iter->getRefData().getCount();
runtime.push (sum);
}
@ -92,9 +82,6 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
@ -104,25 +91,23 @@ namespace MWScript
if (count<0)
throw std::runtime_error ("second argument for RemoveItem must be non-negative");
std::vector<MWWorld::Ptr> list;
MWWorld::ContainerStore& store = MWWorld::Class::get (ptr).getContainerStore (ptr);
MWWorld::listItemsInContainer (item,
MWWorld::Class::get (ptr).getContainerStore (ptr),
context.getWorld().getStore(), list);
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin());
iter!=list.end() && count;
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end() && count;
++iter)
{
if (iter->getRefData().getCount()<=count)
if (iter->getCellRef().refID==item)
{
count -= iter->getRefData().getCount();
iter->getRefData().setCount (0);
}
else
{
iter->getRefData().setCount (iter->getRefData().getCount()-count);
count = 0;
if (iter->getRefData().getCount()<=count)
{
count -= iter->getRefData().getCount();
iter->getRefData().setCount (0);
}
else
{
iter->getRefData().setCount (iter->getRefData().getCount()-count);
count = 0;
}
}
}

View file

@ -4,6 +4,7 @@
#include "class.hpp"
#include "environment.hpp"
#include "world.hpp"
#include "containerstore.hpp"
namespace MWWorld
{
@ -14,8 +15,7 @@ namespace MWWorld
// insert into player's inventory
MWWorld::Ptr player = environment.mWorld->getPtr ("player", true);
MWWorld::Class::get (mObject).insertIntoContainer (mObject,
MWWorld::Class::get (player).getContainerStore (player));
MWWorld::Class::get (player).getContainerStore (player).add (mObject);
// remove from world
environment.mWorld->deleteObject (mObject);

View file

@ -7,6 +7,7 @@
#include "ptr.hpp"
#include "nullaction.hpp"
#include "containerstore.hpp"
namespace MWWorld
{
@ -71,16 +72,11 @@ namespace MWWorld
return boost::shared_ptr<Action> (new NullAction);
}
ContainerStore<RefData>& Class::getContainerStore (const Ptr& ptr) const
ContainerStore& Class::getContainerStore (const Ptr& ptr) const
{
throw std::runtime_error ("class does not have a container store");
}
void Class::insertIntoContainer (const Ptr& ptr, ContainerStore<RefData>& containerStore) const
{
throw std::runtime_error ("class does not support inserting into a container");
}
void Class::lock (const Ptr& ptr, int lockLevel) const
{
throw std::runtime_error ("class does not support locking");

View file

@ -7,11 +7,11 @@
#include <boost/shared_ptr.hpp>
#include "action.hpp"
#include "containerstore.hpp"
#include "refdata.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "physicssystem.hpp"
#include "../mwrender/renderinginterface.hpp"
namespace Ogre
{
class Vector3;
@ -33,6 +33,7 @@ namespace MWWorld
{
class Ptr;
class Environment;
class ContainerStore;
/// \brief Base class for referenceable esm records
class Class
@ -61,8 +62,6 @@ namespace MWWorld
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
/// (default implementation: throw an exception)
virtual void insertObjectRendering (const Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const;
///< Add reference into a cell for rendering (default implementation: don't render anything).
@ -105,15 +104,10 @@ namespace MWWorld
///< Generate action for using via inventory menu (default implementation: return a
/// null action).
virtual ContainerStore<RefData>& getContainerStore (const Ptr& ptr) const;
virtual ContainerStore& getContainerStore (const Ptr& ptr) const;
///< Return container store or throw an exception, if class does not have a
/// container store (default implementation: throw an exceoption)
virtual void insertIntoContainer (const Ptr& ptr, ContainerStore<RefData>& containerStore)
const;
///< Insert into a container or throw an exception, if class does not support inserting into
/// a container.
virtual void lock (const Ptr& ptr, int lockLevel) const;
///< Lock object (default implementation: throw an exception)

View file

@ -0,0 +1,342 @@
#include "containerstore.hpp"
#include <cassert>
#include <typeinfo>
#include <stdexcept>
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin (int mask)
{
return ContainerStoreIterator (mask, this);
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end()
{
return ContainerStoreIterator (this);
}
void MWWorld::ContainerStore::add (const Ptr& ptr)
{
/// \todo implement item stocking
switch (getType (ptr))
{
case Type_Potion: potions.list.push_back (*ptr.get<ESM::Potion>()); break;
case Type_Apparatus: appas.list.push_back (*ptr.get<ESM::Apparatus>()); break;
case Type_Armor: armors.list.push_back (*ptr.get<ESM::Armor>()); break;
case Type_Book: books.list.push_back (*ptr.get<ESM::Book>()); break;
case Type_Clothing: clothes.list.push_back (*ptr.get<ESM::Clothing>()); break;
case Type_Ingredient: ingreds.list.push_back (*ptr.get<ESM::Ingredient>()); break;
case Type_Light: lights.list.push_back (*ptr.get<ESM::Light>()); break;
case Type_Lockpick: lockpicks.list.push_back (*ptr.get<ESM::Tool>()); break;
case Type_Miscellaneous: miscItems.list.push_back (*ptr.get<ESM::Miscellaneous>()); break;
case Type_Probe: probes.list.push_back (*ptr.get<ESM::Probe>()); break;
case Type_Repair: repairs.list.push_back (*ptr.get<ESM::Repair>()); break;
case Type_Weapon: weapons.list.push_back (*ptr.get<ESM::Weapon>()); break;
}
}
int MWWorld::ContainerStore::getType (const Ptr& ptr)
{
if (ptr.isEmpty())
throw std::runtime_error ("can't put a non-existent object into a container");
if (ptr.getTypeName()==typeid (ESM::Potion).name())
return Type_Potion;
if (ptr.getTypeName()==typeid (ESM::Apparatus).name())
return Type_Apparatus;
if (ptr.getTypeName()==typeid (ESM::Armor).name())
return Type_Armor;
if (ptr.getTypeName()==typeid (ESM::Book).name())
return Type_Book;
if (ptr.getTypeName()==typeid (ESM::Clothing).name())
return Type_Clothing;
if (ptr.getTypeName()==typeid (ESM::Ingredient).name())
return Type_Ingredient;
if (ptr.getTypeName()==typeid (ESM::Light).name())
return Type_Light;
if (ptr.getTypeName()==typeid (ESM::Tool).name())
return Type_Lockpick;
if (ptr.getTypeName()==typeid (ESM::Miscellaneous).name())
return Type_Miscellaneous;
if (ptr.getTypeName()==typeid (ESM::Probe).name())
return Type_Probe;
if (ptr.getTypeName()==typeid (ESM::Repair).name())
return Type_Repair;
if (ptr.getTypeName()==typeid (ESM::Weapon).name())
return Type_Weapon;
throw std::runtime_error (
"Object of type " + ptr.getTypeName() + " can not be placed into a container");
}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container)
: mType (-1), mMask (0), mContainer (container)
{}
MWWorld::ContainerStoreIterator::ContainerStoreIterator (int mask, ContainerStore *container)
: mType (0), mMask (mask), mContainer (container)
{
nextType();
}
void MWWorld::ContainerStoreIterator::incType()
{
if (mType==0)
mType = 1;
else if (mType!=-1)
{
mType <<= 1;
if (mType>ContainerStore::Type_Last)
mType = -1;
}
}
void MWWorld::ContainerStoreIterator::nextType()
{
while (mType!=-1)
{
incType();
if (mType & mMask)
if (resetIterator())
break;
}
}
bool MWWorld::ContainerStoreIterator::resetIterator()
{
switch (mType)
{
case ContainerStore::Type_Potion:
mPotion = mContainer->potions.list.begin();
return mPotion!=mContainer->potions.list.end();
case ContainerStore::Type_Apparatus:
mApparatus = mContainer->appas.list.begin();
return mApparatus!=mContainer->appas.list.end();
case ContainerStore::Type_Armor:
mArmor = mContainer->armors.list.begin();
return mArmor!=mContainer->armors.list.end();
case ContainerStore::Type_Book:
mBook = mContainer->books.list.begin();
return mBook!=mContainer->books.list.end();
case ContainerStore::Type_Clothing:
mClothing = mContainer->clothes.list.begin();
return mClothing!=mContainer->clothes.list.end();
case ContainerStore::Type_Ingredient:
mIngredient = mContainer->ingreds.list.begin();
return mIngredient!=mContainer->ingreds.list.end();
case ContainerStore::Type_Light:
mLight = mContainer->lights.list.begin();
return mLight!=mContainer->lights.list.end();
case ContainerStore::Type_Lockpick:
mLockpick = mContainer->lockpicks.list.begin();
return mLockpick!=mContainer->lockpicks.list.end();
case ContainerStore::Type_Miscellaneous:
mMiscellaneous = mContainer->miscItems.list.begin();
return mMiscellaneous!=mContainer->miscItems.list.end();
case ContainerStore::Type_Probe:
mProbe = mContainer->probes.list.begin();
return mProbe!=mContainer->probes.list.end();
case ContainerStore::Type_Repair:
mRepair = mContainer->repairs.list.begin();
return mRepair!=mContainer->repairs.list.end();
case ContainerStore::Type_Weapon:
mWeapon = mContainer->weapons.list.begin();
return mWeapon!=mContainer->weapons.list.end();
}
return false;
}
bool MWWorld::ContainerStoreIterator::incIterator()
{
switch (mType)
{
case ContainerStore::Type_Potion:
++mPotion;
return mPotion==mContainer->potions.list.end();
case ContainerStore::Type_Apparatus:
++mApparatus;
return mApparatus==mContainer->appas.list.end();
case ContainerStore::Type_Armor:
++mArmor;
return mArmor==mContainer->armors.list.end();
case ContainerStore::Type_Book:
++mBook;
return mBook==mContainer->books.list.end();
case ContainerStore::Type_Clothing:
++mClothing;
return mClothing==mContainer->clothes.list.end();
case ContainerStore::Type_Ingredient:
++mIngredient;
return mIngredient==mContainer->ingreds.list.end();
case ContainerStore::Type_Light:
++mLight;
return mLight==mContainer->lights.list.end();
case ContainerStore::Type_Lockpick:
++mLockpick;
return mLockpick==mContainer->lockpicks.list.end();
case ContainerStore::Type_Miscellaneous:
++mMiscellaneous;
return mMiscellaneous==mContainer->miscItems.list.end();
case ContainerStore::Type_Probe:
++mProbe;
return mProbe==mContainer->probes.list.end();
case ContainerStore::Type_Repair:
++mRepair;
return mRepair==mContainer->repairs.list.end();
case ContainerStore::Type_Weapon:
++mWeapon;
return mWeapon==mContainer->weapons.list.end();
}
return true;
}
MWWorld::Ptr *MWWorld::ContainerStoreIterator::operator->() const
{
mPtr = **this;
return &mPtr;
}
MWWorld::Ptr MWWorld::ContainerStoreIterator::operator*() const
{
switch (mType)
{
case ContainerStore::Type_Potion: return MWWorld::Ptr (&*mPotion, 0);
case ContainerStore::Type_Apparatus: return MWWorld::Ptr (&*mApparatus, 0);
case ContainerStore::Type_Armor: return MWWorld::Ptr (&*mArmor, 0);
case ContainerStore::Type_Book: return MWWorld::Ptr (&*mBook, 0);
case ContainerStore::Type_Clothing: return MWWorld::Ptr (&*mClothing, 0);
case ContainerStore::Type_Ingredient: return MWWorld::Ptr (&*mIngredient, 0);
case ContainerStore::Type_Light: return MWWorld::Ptr (&*mLight, 0);
case ContainerStore::Type_Lockpick: return MWWorld::Ptr (&*mLockpick, 0);
case ContainerStore::Type_Miscellaneous: return MWWorld::Ptr (&*mMiscellaneous, 0);
case ContainerStore::Type_Probe: return MWWorld::Ptr (&*mProbe, 0);
case ContainerStore::Type_Repair: return MWWorld::Ptr (&*mRepair, 0);
case ContainerStore::Type_Weapon: return MWWorld::Ptr (&*mWeapon, 0);
}
throw std::runtime_error ("invalid pointer");
}
MWWorld::ContainerStoreIterator& MWWorld::ContainerStoreIterator::operator++()
{
do
{
if (incIterator())
nextType();
}
while (mType!=-1 && !(**this).getRefData().getCount());
return *this;
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStoreIterator::operator++ (int)
{
ContainerStoreIterator iter (*this);
++*this;
return iter;
}
bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const
{
assert (mContainer==iter.mContainer);
if (mType!=iter.mType)
return false;
switch (mType)
{
case ContainerStore::Type_Potion: return mPotion==iter.mPotion;
case ContainerStore::Type_Apparatus: return mApparatus==iter.mApparatus;
case ContainerStore::Type_Armor: return mArmor==iter.mArmor;
case ContainerStore::Type_Book: return mBook==iter.mBook;
case ContainerStore::Type_Clothing: return mClothing==iter.mClothing;
case ContainerStore::Type_Ingredient: return mIngredient==iter.mIngredient;
case ContainerStore::Type_Light: return mLight==iter.mLight;
case ContainerStore::Type_Lockpick: return mLockpick==iter.mLockpick;
case ContainerStore::Type_Miscellaneous: return mMiscellaneous==iter.mMiscellaneous;
case ContainerStore::Type_Probe: return mProbe==iter.mProbe;
case ContainerStore::Type_Repair: return mRepair==iter.mRepair;
case ContainerStore::Type_Weapon: return mWeapon==iter.mWeapon;
case -1: return true;
}
return false;
}
int MWWorld::ContainerStoreIterator::getType() const
{
return mType;
}
bool MWWorld::operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right)
{
return left.isEqual (right);
}
bool MWWorld::operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right)
{
return !(left==right);
}

View file

@ -3,24 +3,134 @@
#include <components/esm_store/cell_store.hpp>
#include "refdata.hpp"
#include "ptr.hpp"
namespace MWWorld
{
template<typename D>
struct ContainerStore
class ContainerStoreIterator;
class ContainerStore
{
ESMS::CellRefList<ESM::Potion, D> potions;
ESMS::CellRefList<ESM::Apparatus, D> appas;
ESMS::CellRefList<ESM::Armor, D> armors;
ESMS::CellRefList<ESM::Book, D> books;
ESMS::CellRefList<ESM::Clothing, D> clothes;
ESMS::CellRefList<ESM::Ingredient, D> ingreds;
ESMS::CellRefList<ESM::Light, D> lights;
ESMS::CellRefList<ESM::Tool, D> lockpicks;
ESMS::CellRefList<ESM::Miscellaneous, D> miscItems;
ESMS::CellRefList<ESM::Probe, D> probes;
ESMS::CellRefList<ESM::Repair, D> repairs;
ESMS::CellRefList<ESM::Weapon, D> weapons;
public:
static const int Type_Potion = 0x0001;
static const int Type_Apparatus = 0x0002;
static const int Type_Armor = 0x0004;
static const int Type_Book = 0x0008;
static const int Type_Clothing = 0x0010;
static const int Type_Ingredient = 0x0020;
static const int Type_Light = 0x0040;
static const int Type_Lockpick = 0x0080;
static const int Type_Miscellaneous = 0x0100;
static const int Type_Probe = 0x0200;
static const int Type_Repair = 0x0400;
static const int Type_Weapon = 0x0800;
static const int Type_Last = Type_Weapon;
static const int Type_All = 0xffff;
private:
ESMS::CellRefList<ESM::Potion, RefData> potions;
ESMS::CellRefList<ESM::Apparatus, RefData> appas;
ESMS::CellRefList<ESM::Armor, RefData> armors;
ESMS::CellRefList<ESM::Book, RefData> books;
ESMS::CellRefList<ESM::Clothing, RefData> clothes;
ESMS::CellRefList<ESM::Ingredient, RefData> ingreds;
ESMS::CellRefList<ESM::Light, RefData> lights;
ESMS::CellRefList<ESM::Tool, RefData> lockpicks;
ESMS::CellRefList<ESM::Miscellaneous, RefData> miscItems;
ESMS::CellRefList<ESM::Probe, RefData> probes;
ESMS::CellRefList<ESM::Repair, RefData> repairs;
ESMS::CellRefList<ESM::Weapon, RefData> weapons;
public:
ContainerStoreIterator begin (int mask = Type_All);
ContainerStoreIterator end();
void add (const Ptr& ptr);
///< Add the item pointed to by \a ptr to this container.
///
/// \note The item pointed to is not required to exist beyond this function call.
///
/// \attention Do not add items to an existing stack by increasing the count instead of
/// calling this function!
static int getType (const Ptr& ptr);
///< This function throws an exception, if ptr does not point to an object, that can be
/// put into a container.
friend class ContainerStoreIterator;
};
/// \brief Iteration over a subset of objects in a ContainerStore
///
/// \note The iterator will automatically skip over deleted objects.
class ContainerStoreIterator
{
int mType;
int mMask;
ContainerStore *mContainer;
mutable Ptr mPtr;
ESMS::CellRefList<ESM::Potion, RefData>::List::iterator mPotion;
ESMS::CellRefList<ESM::Apparatus, RefData>::List::iterator mApparatus;
ESMS::CellRefList<ESM::Armor, RefData>::List::iterator mArmor;
ESMS::CellRefList<ESM::Book, RefData>::List::iterator mBook;
ESMS::CellRefList<ESM::Clothing, RefData>::List::iterator mClothing;
ESMS::CellRefList<ESM::Ingredient, RefData>::List::iterator mIngredient;
ESMS::CellRefList<ESM::Light, RefData>::List::iterator mLight;
ESMS::CellRefList<ESM::Tool, RefData>::List::iterator mLockpick;
ESMS::CellRefList<ESM::Miscellaneous, RefData>::List::iterator mMiscellaneous;
ESMS::CellRefList<ESM::Probe, RefData>::List::iterator mProbe;
ESMS::CellRefList<ESM::Repair, RefData>::List::iterator mRepair;
ESMS::CellRefList<ESM::Weapon, RefData>::List::iterator mWeapon;
private:
ContainerStoreIterator (ContainerStore *container);
///< End-iterator
ContainerStoreIterator (int mask, ContainerStore *container);
///< Begin-iterator
void incType();
void nextType();
bool resetIterator();
///< Reset iterator for selected type.
///
/// \return Type not empty?
bool incIterator();
///< Increment iterator for selected type.
///
/// \return reached the end?
public:
Ptr *operator->() const;
Ptr operator*() const;
ContainerStoreIterator& operator++();
ContainerStoreIterator operator++ (int);
bool isEqual (const ContainerStoreIterator& iter) const;
int getType() const;
friend class ContainerStore;
};
bool operator== (const ContainerStoreIterator& left, const ContainerStoreIterator& right);
bool operator!= (const ContainerStoreIterator& left, const ContainerStoreIterator& right);
}
#endif

View file

@ -1,43 +0,0 @@
#include "containerutil.hpp"
namespace
{
template<typename T>
void listItemsInContainerImp (const std::string& id,
ESMS::CellRefList<T, MWWorld::RefData>& containerStore,
const ESMS::RecListT<T>& store, std::vector<MWWorld::Ptr>& list)
{
if (const T *record = store.search (id))
{
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter
(containerStore.list.begin());
iter!=containerStore.list.end(); ++iter)
{
if (iter->base==record)
list.push_back (MWWorld::Ptr (&*iter, 0));
}
}
}
}
namespace MWWorld
{
void listItemsInContainer (const std::string& id,
ContainerStore<MWWorld::RefData>& containerStore,
const ESMS::ESMStore& store, std::vector<Ptr>& list)
{
listItemsInContainerImp (id, containerStore.potions, store.potions, list);
listItemsInContainerImp (id, containerStore.appas, store.appas, list);
listItemsInContainerImp (id, containerStore.armors, store.armors, list);
listItemsInContainerImp (id, containerStore.books, store.books, list);
listItemsInContainerImp (id, containerStore.clothes, store.clothes, list);
listItemsInContainerImp (id, containerStore.ingreds, store.ingreds, list);
listItemsInContainerImp (id, containerStore.lights, store.lights, list);
listItemsInContainerImp (id, containerStore.lockpicks, store.lockpicks, list);
listItemsInContainerImp (id, containerStore.miscItems, store.miscItems, list);
listItemsInContainerImp (id, containerStore.probes, store.probes, list);
listItemsInContainerImp (id, containerStore.repairs, store.repairs, list);
listItemsInContainerImp (id, containerStore.weapons, store.weapons, list);
}
}

View file

@ -1,20 +0,0 @@
#ifndef GAME_MWWORLD_CONTAINERUTIL_H
#define GAME_MWWORLD_CONTAINERUTIL_H
#include <string>
#include <vector>
#include <components/esm_store/store.hpp>
#include "containerstore.hpp"
#include "ptr.hpp"
#include "refdata.hpp"
namespace MWWorld
{
void listItemsInContainer (const std::string& id, ContainerStore<MWWorld::RefData>& containerStore,
const ESMS::ESMStore& store, std::vector<Ptr>& list);
///< append all references with the given id to list.
}
#endif

View file

@ -82,6 +82,7 @@ namespace MWWorld
// initialise
ESM::CellRef& cellRef = mPtr.getCellRef();
cellRef.refID = name;
cellRef.refnum = -1;
cellRef.scale = 1;
cellRef.factIndex = 0;