Merge branch 'master' into dialogue

Conflicts:
	apps/openmw/CMakeLists.txt
	apps/openmw/mwclass/creature.cpp
	apps/openmw/mwclass/creature.hpp
	apps/openmw/mwclass/npc.cpp
	apps/openmw/mwclass/npc.hpp
pull/7/head
Marc Zinnschlag 15 years ago
commit 8086933282

@ -180,7 +180,7 @@ int main(int argc, char**argv)
case REC_CREA:
{
Creature b;
b.load(esm);
b.load(esm, id);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;

@ -59,6 +59,7 @@ set(GAMESCRIPT
mwscript/soundextensions.cpp
mwscript/skyextensions.cpp
mwscript/statsextensions.cpp
mwscript/containerextensions.cpp
mwscript/extensions.cpp
mwscript/globalscripts.cpp
)
@ -73,6 +74,7 @@ set(GAMESCRIPT_HEADER
mwscript/soundextensions.hpp
mwscript/skyextensions.hpp
mwscript/statsextensions.hpp
mwscript/containerextensions.hpp
mwscript/extensions.hpp
mwscript/globalscripts.hpp
)
@ -90,6 +92,8 @@ set(GAMEWORLD
mwworld/class.cpp
mwworld/actionteleport.cpp
mwworld/actiontalk.cpp
mwworld/actiontake.cpp
mwworld/containerutil.cpp
)
set(GAMEWORLD_HEADER
mwworld/refdata.hpp
@ -103,6 +107,10 @@ set(GAMEWORLD_HEADER
mwworld/actionteleport.hpp
mwworld/containerstore.hpp
mwworld/actiontalk.hpp
mwworld/actiontake.hpp
mwworld/containerstore.hpp
mwworld/manualref.hpp
mwworld/containerutil.hpp
)
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
@ -151,6 +159,7 @@ set(GAMECLASS_HEADER
mwclass/probe.hpp
mwclass/repair.hpp
mwclass/static.hpp
mwclass/containerutil.hpp
)
source_group(apps\\openmw\\mwclass FILES ${GAMECLASS} ${GAMECLASS_HEADER})

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,13 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
}
bool Armor::hasItemHealth (const MWWorld::Ptr& ptr) const
{
return true;
@ -30,6 +40,12 @@ 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 =

@ -13,12 +13,20 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
///< \return Item health data available?
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,21 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
// TODO implement reading
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -0,0 +1,31 @@
#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;
cellRef.base = ptr.get<T>()->base;
cellRef.ref = ptr.getCellRef();
cellRef.mData = ptr.getRefData();
containerStore.list.push_back (cellRef);
}
}
}
#endif

@ -45,6 +45,12 @@ namespace MWClass
return *ptr.getRefData().getCreatureStats();
}
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
MWWorld::ContainerStore<MWWorld::RefData>& Creature::getContainerStore (const MWWorld::Ptr& ptr)
const
{
@ -61,12 +67,6 @@ namespace MWClass
return *ptr.getRefData().getContainerStore();
}
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =

@ -16,14 +16,14 @@ namespace MWClass
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
///< Return creature stats
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
const MWWorld::Ptr& ptr) const;
///< Return container store
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
const MWWorld::Ptr& ptr) const;
///< Return container store
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,10 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "../mwworld/nullaction.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -20,6 +24,25 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
if (!(ref->base->data.flags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Misc::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
}
void Misc::insertIntoContainer (const MWWorld::Ptr& ptr,
MWWorld::ContainerStore<MWWorld::RefData>& containerStore) const
{
insertIntoContainerStore (ptr, containerStore.miscItems);
}
std::string Misc::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Misc, MWWorld::RefData> *ref =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,19 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
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 =

@ -13,6 +13,14 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
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

@ -6,6 +6,9 @@
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp"
#include "containerutil.hpp"
namespace MWClass
{
@ -17,6 +20,13 @@ namespace MWClass
return ref->base->name;
}
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const
{
return boost::shared_ptr<MWWorld::Action> (
new MWWorld::ActionTake (ptr));
}
bool Weapon::hasItemHealth (const MWWorld::Ptr& ptr) const
{
return true;
@ -30,6 +40,12 @@ 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 =

@ -13,12 +13,20 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
///< \return Item health data available?
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

@ -3,31 +3,33 @@
#include <string>
namespace MWRender
namespace MWRender
{
class CellRender
{
public:
public:
virtual ~CellRender() {};
/// Make the cell visible. Load the cell if necessary.
virtual void show() = 0;
/// Remove the cell from rendering, but don't remove it from
/// memory.
virtual void hide() = 0;
virtual void hide() = 0;
/// Destroy all rendering objects connected with this cell.
virtual void destroy() = 0;
/// Make the reference with the given handle visible.
virtual void enable (const std::string& handle) = 0;
/// Make the reference with the given handle invisible.
virtual void disable (const std::string& handle) = 0;
/// Remove the reference with the given handle permanently from the scene.
virtual void deleteObject (const std::string& handle) = 0;
};
}
#endif

@ -237,6 +237,16 @@ void InteriorCellRender::disable (const std::string& handle)
scene.getMgr()->getSceneNode (handle)->setVisible (false);
}
void InteriorCellRender::deleteObject (const std::string& handle)
{
if (!handle.empty())
{
Ogre::SceneNode *node = scene.getMgr()->getSceneNode (handle);
node->removeAndDestroyAllChildren();
scene.getMgr()->destroySceneNode (node);
}
}
// Magic function from the internets. Might need this later.
/*
void Scene::DestroyAllAttachedMovableObjects( SceneNode* i_pSceneNode )

@ -99,11 +99,13 @@ namespace MWRender
/// Make the reference with the given handle visible.
virtual void enable (const std::string& handle);
/// Make the reference with the given handle invisible.
virtual void disable (const std::string& handle);
virtual void disable (const std::string& handle);
/// Remove the reference with the given handle permanently from the scene.
virtual void deleteObject (const std::string& handle);
};
}
#endif

@ -0,0 +1,273 @@
#include "containerextensions.hpp"
#include <stdexcept>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerutil.hpp"
#include "interpretercontext.hpp"
namespace MWScript
{
namespace Container
{
class OpAddItem : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer count = runtime[0].mInteger;
runtime.pop();
if (count<0)
throw std::runtime_error ("second argument for AddItem must be non-negative");
MWWorld::Ptr ptr = context.getReference();
MWWorld::ManualRef ref (context.getWorld().getStore(), item);
ref.getPtr().getRefData().setCount (count);
MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(),
MWWorld::Class::get (ptr).getContainerStore (ptr));
}
};
class OpAddItemExplicit : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer count = runtime[0].mInteger;
runtime.pop();
if (count<0)
throw std::runtime_error ("second argument for AddItem must be non-negative");
MWWorld::Ptr ptr = context.getWorld().getPtr (id, false);
MWWorld::ManualRef ref (context.getWorld().getStore(), item);
ref.getPtr().getRefData().setCount (count);
MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(),
MWWorld::Class::get (ptr).getContainerStore (ptr));
}
};
class OpGetItemCount : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::Ptr ptr = context.getReference();
std::vector<MWWorld::Ptr> list;
MWWorld::listItemsInContainer (item,
MWWorld::Class::get (ptr).getContainerStore (ptr),
context.getWorld().getStore(), list);
Interpreter::Type_Integer sum = 0;
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin()); iter!=list.end();
++iter)
{
sum += iter->getRefData().getCount();
}
runtime.push (sum);
}
};
class OpGetItemCountExplicit : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWWorld::Ptr ptr = context.getWorld().getPtr (id, false);
std::vector<MWWorld::Ptr> list;
MWWorld::listItemsInContainer (item,
MWWorld::Class::get (ptr).getContainerStore (ptr),
context.getWorld().getStore(), list);
Interpreter::Type_Integer sum = 0;
for (std::vector<MWWorld::Ptr>::iterator iter (list.begin()); iter!=list.end();
++iter)
{
sum += iter->getRefData().getCount();
}
runtime.push (sum);
}
};
class OpRemoveItem : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer count = runtime[0].mInteger;
runtime.pop();
if (count<0)
throw std::runtime_error ("second argument for RemoveItem must be non-negative");
MWWorld::Ptr ptr = context.getReference();
std::vector<MWWorld::Ptr> list;
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;
++iter)
{
if (iter->getRefData().getCount()<=count)
{
count -= iter->getRefData().getCount();
iter->getRefData().setCount (0);
}
else
{
iter->getRefData().setCount (iter->getRefData().getCount()-count);
count = 0;
}
}
// To be fully compatible with original Morrowind, we would need to check if
// count is >= 0 here and throw an exception. But let's be tollerant instead.
}
};
class OpRemoveItemExplicit : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
std::string item = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer count = runtime[0].mInteger;
runtime.pop();
if (count<0)
throw std::runtime_error ("second argument for RemoveItem must be non-negative");
MWWorld::Ptr ptr = context.getWorld().getPtr (id, false);
std::vector<MWWorld::Ptr> list;
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;
++iter)
{
if (iter->getRefData().getCount()<=count)
{
count -= iter->getRefData().getCount();
iter->getRefData().setCount (0);
}
else
{
iter->getRefData().setCount (iter->getRefData().getCount()-count);
count = 0;
}
}
// To be fully compatible with original Morrowind, we would need to check if
// count is >= 0 here and throw an exception. But let's be tollerant instead.
}
};
const int opcodeAddItem = 0x2000076;
const int opcodeAddItemExplicit = 0x2000077;
const int opcodeGetItemCount = 0x2000078;
const int opcodeGetItemCountExplicit = 0x2000079;
const int opcodeRemoveItem = 0x200007a;
const int opcodeRemoveItemExplicit = 0x200007b;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit);
extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount,
opcodeGetItemCountExplicit);
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
opcodeRemoveItemExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeAddItem, new OpAddItem);
interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItemExplicit);
interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount);
interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCountExplicit);
interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem);
interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItemExplicit);
}
}
}

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_CONTAINEREXTENSIONS_H
#define GAME_SCRIPT_CONTAINEREXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief stats-related script functionality (creatures and NPCs)
namespace Container
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

@ -77,4 +77,10 @@ op 0x200006c-0x200006e: ModDynamic (health, magicka, fatigue), explicit referenc
op 0x200006f-0x2000071: GetDynamic (health, magicka, fatigue)
op 0x2000072-0x2000074: GetDynamic (health, magicka, fatigue), explicit reference
op 0x2000075: Activate
opcodes 0x2000076-0x3ffffff unused
op 0x2000076: AddItem
op 0x2000077: AddItem, explicit reference
op 0x2000078: GetItemCount
op 0x2000079: GetItemCount, explicit reference
op 0x200007a: RemoveItem
op 0x200007b: RemoveItem, explicit reference
opcodes 0x200007c-0x3ffffff unused

@ -10,6 +10,7 @@
#include "guiextensions.hpp"
#include "skyextensions.hpp"
#include "statsextensions.hpp"
#include "containerextensions.hpp"
namespace MWScript
{
@ -21,8 +22,9 @@ namespace MWScript
Sound::registerExtensions (extensions);
Sky::registerExtensions (extensions);
Stats::registerExtensions (extensions);
Container::registerExtensions (extensions);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
Interpreter::installOpcodes (interpreter);
@ -32,6 +34,6 @@ namespace MWScript
Sound::installOpcodes (interpreter);
Sky::installOpcodes (interpreter);
Stats::installOpcodes (interpreter);
}
Container::installOpcodes (interpreter);
}
}

@ -0,0 +1,23 @@
#include "actiontake.hpp"
#include "class.hpp"
#include "environment.hpp"
#include "world.hpp"
namespace MWWorld
{
ActionTake::ActionTake (const MWWorld::Ptr& object) : mObject (object) {}
void ActionTake::execute (Environment& environment)
{
// 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));
// remove from world
environment.mWorld->deleteObject (mObject);
}
}

@ -0,0 +1,21 @@
#ifndef GAME_MWWORLD_ACTIONTAKE_H
#define GAME_MWWORLD_ACTIONTAKE_H
#include "action.hpp"
#include "ptr.hpp"
namespace MWWorld
{
class ActionTake : public Action
{
MWWorld::Ptr mObject;
public:
ActionTake (const MWWorld::Ptr& object);
virtual void execute (Environment& environment);
};
}
#endif

@ -44,7 +44,12 @@ namespace MWWorld
ContainerStore<RefData>& 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");
}
std::string Class::getScript (const Ptr& ptr) const
{

@ -64,6 +64,11 @@ namespace MWWorld
///< 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 std::string getScript (const Ptr& ptr) const;
///< Return name of the script attached to ptr (default implementation: return an empty
/// string).

@ -0,0 +1,43 @@
#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);
}
}

@ -0,0 +1,20 @@
#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

@ -0,0 +1,103 @@
#ifndef GAME_MWWORLD_MANUALREF_H
#define GAME_MWWORLD_MANUALREF_H
#include <boost/any.hpp>
#include <components/esm_store/cell_store.hpp>
#include <components/esm_store/store.hpp>
#include "ptr.hpp"
namespace MWWorld
{
/// \brief Manually constructed live cell ref
class ManualRef
{
boost::any mRef;
Ptr mPtr;
ManualRef (const ManualRef&);
ManualRef& operator= (const ManualRef&);
template<typename T>
bool create (const ESMS::RecListT<T>& list, const std::string& name)
{
if (const T *instance = list.search (name))
{
ESMS::LiveCellRef<T, RefData> ref;
ref.base = instance;
mRef = ref;
mPtr = Ptr (&boost::any_cast<ESMS::LiveCellRef<T, RefData>&> (mRef), 0);
return true;
}
return false;
}
template<typename T>
bool create (const ESMS::RecListWithIDT<T>& list, const std::string& name)
{
if (const T *instance = list.search (name))
{
ESMS::LiveCellRef<T, RefData> ref;
ref.base = instance;
mRef = ref;
mPtr = Ptr (&boost::any_cast<ESMS::LiveCellRef<T, RefData>&> (mRef), 0);
return true;
}
return false;
}
public:
ManualRef (const ESMS::ESMStore& store, const std::string& name)
{
// create
if (!create (store.activators, name) &&
!create (store.potions, name) &&
!create (store.appas, name) &&
!create (store.armors, name) &&
!create (store.books, name) &&
!create (store.clothes, name) &&
!create (store.containers, name) &&
!create (store.creatures, name) &&
!create (store.doors, name) &&
!create (store.ingreds, name) &&
!create (store.creatureLists, name) &&
!create (store.itemLists, name) &&
!create (store.lights, name) &&
!create (store.lockpicks, name) &&
!create (store.miscItems, name) &&
!create (store.npcs, name) &&
!create (store.probes, name) &&
!create (store.repairs, name) &&
!create (store.statics, name) &&
!create (store.weapons, name))
throw std::logic_error ("failed to create manual cell ref for " + name);
// initialise
ESM::CellRef& cellRef = mPtr.getCellRef();
cellRef.refnum = -1;
cellRef.scale = 1;
cellRef.factIndex = 0;
cellRef.charge = 0;
cellRef.intv = 0;
cellRef.nam9 = 0;
cellRef.teleport = false;
cellRef.lockLevel = 0;
cellRef.unam = 0;
}
const Ptr& getPtr() const
{
return mPtr;
}
};
}
#endif

@ -384,9 +384,9 @@ namespace MWWorld
void World::disable (Ptr reference)
{
if (!reference.getRefData().isEnabled())
if (reference.getRefData().isEnabled())
{
reference.getRefData().enable();
reference.getRefData().disable();
if (MWRender::CellRender *render = searchRender (reference.getCell()))
{
@ -611,4 +611,25 @@ namespace MWWorld
return result.first;
}
void World::deleteObject (Ptr ptr)
{
if (ptr.getRefData().getCount()>0)
{
ptr.getRefData().setCount (0);
if (MWRender::CellRender *render = searchRender (ptr.getCell()))
{
render->deleteObject (ptr.getRefData().getHandle());
ptr.getRefData().setHandle ("");
if (mActiveCells.find (ptr.getCell())!=mActiveCells.end() &&
(ptr.getType()==typeid (ESMS::LiveCellRef<ESM::NPC, RefData>) ||
ptr.getType()==typeid (ESMS::LiveCellRef<ESM::Creature, RefData>)))
{
mEnvironment.mMechanicsManager->removeActor (ptr);
}
}
}
}
}

@ -134,6 +134,8 @@ namespace MWWorld
std::string getFacedHandle();
///< Return handle of the object the player is looking at
void deleteObject (Ptr ptr);
};
}

@ -62,8 +62,12 @@ struct Creature
// Defined in loadcont.hpp
InventoryList inventory;
void load(ESMReader &esm)
std::string mId;
void load(ESMReader &esm, const std::string& id)
{
mId = id;
model = esm.getHNString("MODL");
original = esm.getHNOString("CNAM");
name = esm.getHNOString("FNAM");
@ -93,7 +97,7 @@ struct Creature
// AI_A - activate?
esm.skipRecord();
}
}
};
}
#endif

@ -97,8 +97,12 @@ struct NPC
std::string name, model, race, cls, faction, script,
hair, head; // body parts
void load(ESMReader &esm)
std::string mId;
void load(ESMReader &esm, const std::string& id)
{
mId = id;
npdt52.gold = -10;
model = esm.getHNOString("MODL");

@ -17,16 +17,16 @@ namespace ESMS
{
virtual void load(ESMReader &esm, const std::string &id) = 0;
virtual int getSize() = 0;
static std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
};
typedef std::map<int,RecList*> RecListList;
@ -53,15 +53,53 @@ namespace ESMS
return NULL;
return &list.find(id2)->second;
}
// Find the given object ID (throws an exception if not found)
const X* find(const std::string &id) const
{
const X *object = search (id);
if (!object)
throw std::runtime_error ("object " + id + " not found");
return object;
}
int getSize() { return list.size(); }
};
/// Modified version of RecListT for records, that need to store their own ID
template <typename X>
struct RecListWithIDT : RecList
{
typedef std::map<std::string,X> MapType;
MapType list;
// Load one object of this type
void load(ESMReader &esm, const std::string &id)
{
std::string id2 = toLower (id);
list[id2].load(esm, id2);
}
// Find the given object ID, or return NULL if not found.
const X* search(const std::string &id) const
{
std::string id2 = toLower (id);
if(list.find(id2) == list.end())
return NULL;
return &list.find(id2)->second;
}
// Find the given object ID (throws an exception if not found)
const X* find(const std::string &id) const
{
const X *object = search (id);
if (!object)
throw std::runtime_error ("object " + id + " not found");
return object;
}
@ -80,7 +118,7 @@ namespace ESMS
void load(ESMReader &esm, const std::string &id)
{
std::string id2 = toLower (id);
std::string id2 = toLower (id);
X& ref = list[id2];
ref.id = id;
@ -95,18 +133,18 @@ namespace ESMS
return NULL;
return &list.find(id2)->second;
}
// Find the given object ID (throws an exception if not found)
const X* find(const std::string &id) const
{
const X *object = search (id);
if (!object)
throw std::runtime_error ("object " + id + " not found");
return object;
}
int getSize() { return list.size(); }
};
@ -180,7 +218,7 @@ namespace ESMS
}
}
};
template <typename X>
struct ScriptListT : RecList
{
@ -193,16 +231,16 @@ namespace ESMS
{
X ref;
ref.load (esm);
std::string realId = toLower (ref.data.name.toString());
std::swap (list[realId], ref);
}
// Find the given object ID, or return NULL if not found.
const X* search(const std::string &id) const
{
std::string id2 = toLower (id);
std::string id2 = toLower (id);
if(list.find(id2) == list.end())
return NULL;
return &list.find(id2)->second;
@ -212,15 +250,15 @@ namespace ESMS
const X* find(const std::string &id) const
{
const X *object = search (id);
if (!object)
throw std::runtime_error ("object " + id + " not found");
return object;
}
int getSize() { return list.size(); }
};
};
/* We need special lists for:

@ -40,7 +40,7 @@ namespace ESMS
RecListT<Clothing> clothes;
RecListT<LoadCNTC> contChange;
RecListT<Container> containers;
RecListT<Creature> creatures;
RecListWithIDT<Creature> creatures;
RecListT<LoadCREC> creaChange;
RecListT<Dialogue> dialogs;
RecListT<Door> doors;
@ -53,7 +53,7 @@ namespace ESMS
RecListT<Light> lights;
RecListT<Tool> lockpicks;
RecListT<Misc> miscItems;
RecListT<NPC> npcs;
RecListWithIDT<NPC> npcs;
RecListT<LoadNPCC> npcChange;
RecListT<Probe> probes;
RecListT<Race> races;

Loading…
Cancel
Save