Merge remote branch 'upstream/master'

actorid
Armin Preiml 15 years ago
commit fa077ccdc4

@ -51,6 +51,7 @@ set(GAMESCRIPT
mwscript/soundextensions.cpp
mwscript/skyextensions.cpp
mwscript/statsextensions.cpp
mwscript/containerextensions.cpp
mwscript/extensions.cpp
mwscript/globalscripts.cpp
)
@ -65,6 +66,7 @@ set(GAMESCRIPT_HEADER
mwscript/soundextensions.hpp
mwscript/skyextensions.hpp
mwscript/statsextensions.hpp
mwscript/containerextensions.hpp
mwscript/extensions.hpp
mwscript/globalscripts.hpp
)
@ -81,6 +83,9 @@ set(GAMEWORLD
mwworld/globals.cpp
mwworld/class.cpp
mwworld/actionteleport.cpp
mwworld/actiontalk.cpp
mwworld/actiontake.cpp
mwworld/containerutil.cpp
)
set(GAMEWORLD_HEADER
mwworld/refdata.hpp
@ -92,6 +97,11 @@ set(GAMEWORLD_HEADER
mwworld/action.hpp
mwworld/nullaction.hpp
mwworld/actionteleport.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})
@ -140,6 +150,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})

@ -38,13 +38,18 @@ void OMW::Engine::executeLocalScripts()
mEnvironment.mWorld->getLocalScripts().begin());
iter!=mEnvironment.mWorld->getLocalScripts().end(); ++iter)
{
MWScript::InterpreterContext interpreterContext (mEnvironment,
&iter->second.getRefData().getLocals(), MWWorld::Ptr (iter->second));
mScriptManager->run (iter->first, interpreterContext);
if (!mIgnoreLocalPtr.isEmpty() && mIgnoreLocalPtr!=iter->second)
{
MWScript::InterpreterContext interpreterContext (mEnvironment,
&iter->second.getRefData().getLocals(), MWWorld::Ptr (iter->second));
mScriptManager->run (iter->first, interpreterContext);
if (mEnvironment.mWorld->hasCellChanged())
break;
if (mEnvironment.mWorld->hasCellChanged())
break;
}
}
mIgnoreLocalPtr = MWWorld::Ptr();
}
bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
@ -74,22 +79,20 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
if (focusFrameCounter++ == focusUpdateFrame)
{
std::pair<std::string, float> handle = mEnvironment.mWorld->getMWScene()->getFacedHandle();
std::string handle = mEnvironment.mWorld->getFacedHandle();
std::string name;
if (!handle.first.empty())
if (!handle.empty())
{
// TODO compare handle.second with max activation range (from a GMST)
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle.first);
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
if (!ptr.isEmpty())
name = MWWorld::Class::get (ptr).getName (ptr);
}
if (!name.empty())
std::cout << "Object: " << name << ", distance: " << handle.second << std::endl;
std::cout << "Object: " << name << std::endl;
focusFrameCounter = 0;
}
@ -255,7 +258,7 @@ void OMW::Engine::go()
// Sets up the input system
MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(),
*mEnvironment.mWindowManager, mDebug);
*mEnvironment.mWindowManager, mDebug, *this);
focusFrameCounter = 0;
@ -268,3 +271,38 @@ void OMW::Engine::go()
std::cout << "Quitting peacefully.\n";
}
void OMW::Engine::activate()
{
std::string handle = mEnvironment.mWorld->getFacedHandle();
if (handle.empty())
return;
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
if (ptr.isEmpty())
return;
MWScript::InterpreterContext interpreterContext (mEnvironment,
&ptr.getRefData().getLocals(), ptr);
boost::shared_ptr<MWWorld::Action> action =
MWWorld::Class::get (ptr).activate (ptr, mEnvironment.mWorld->getPlayerPos().getPlayer(),
mEnvironment);
interpreterContext.activate (ptr, action);
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
if (!script.empty())
{
mIgnoreLocalPtr = ptr;
mScriptManager->run (script, interpreterContext);
}
if (!interpreterContext.hasActivationBeenHandled())
{
interpreterContext.executeActivation();
}
}

@ -11,6 +11,7 @@
#include <components/compiler/extensions.hpp>
#include "mwworld/environment.hpp"
#include "mwworld/ptr.hpp"
namespace Compiler
{
@ -68,6 +69,8 @@ namespace OMW
int focusFrameCounter;
static const int focusUpdateFrame = 10;
MWWorld::Ptr mIgnoreLocalPtr;
// not implemented
Engine (const Engine&);
Engine& operator= (const Engine&);
@ -111,12 +114,15 @@ namespace OMW
/// Enable verbose script output
void enableVerboseScripts();
/// Start as a new game.
void setNewGame();
/// Initialise and enter main loop.
void go();
/// Activate the focussed object.
void activate();
};
}

@ -17,6 +17,14 @@ namespace MWClass
return ref->base->name;
}
std::string Activator::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Activator, MWWorld::RefData> *ref =
ptr.get<ESM::Activator>();
return ref->base->script;
}
void Activator::registerSelf()
{
boost::shared_ptr<Class> instance (new Activator);

@ -13,6 +13,9 @@ namespace MWClass
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Apparatus>();
return ref->base->script;
}
void Apparatus::registerSelf()
{
boost::shared_ptr<Class> instance (new Apparatus);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,20 @@ 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 =
ptr.get<ESM::Armor>();
return ref->base->script;
}
void Armor::registerSelf()
{
boost::shared_ptr<Class> instance (new Armor);

@ -13,12 +13,23 @@ 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
static void registerSelf();
};
}

@ -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,29 @@ 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 =
ptr.get<ESM::Book>();
return ref->base->script;
}
void Book::registerSelf()
{
boost::shared_ptr<Class> instance (new Book);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Clothing>();
return ref->base->script;
}
void Clothing::registerSelf()
{
boost::shared_ptr<Class> instance (new Clothing);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -17,6 +17,30 @@ namespace MWClass
return ref->base->name;
}
MWWorld::ContainerStore<MWWorld::RefData>& Container::getContainerStore (const MWWorld::Ptr& ptr)
const
{
if (!ptr.getRefData().getContainerStore().get())
{
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
new MWWorld::ContainerStore<MWWorld::RefData>);
// TODO add initial content
ptr.getRefData().getContainerStore() = store;
}
return *ptr.getRefData().getContainerStore();
}
std::string Container::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
ptr.get<ESM::Container>();
return ref->base->script;
}
void Container::registerSelf()
{
boost::shared_ptr<Class> instance (new Container);

@ -13,6 +13,13 @@ 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;
///< Return container store
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
static void registerSelf();
};
}

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

@ -6,6 +6,7 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
namespace MWClass
{
@ -44,6 +45,36 @@ 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
{
if (!ptr.getRefData().getContainerStore().get())
{
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
new MWWorld::ContainerStore<MWWorld::RefData>);
// TODO add initial content
ptr.getRefData().getContainerStore() = store;
}
return *ptr.getRefData().getContainerStore();
}
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>();
return ref->base->script;
}
void Creature::registerSelf()
{
boost::shared_ptr<Class> instance (new Creature);

@ -16,6 +16,17 @@ namespace MWClass
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
///< Return creature stats
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
static void registerSelf();
};
}

@ -53,6 +53,14 @@ namespace MWClass
}
}
std::string Door::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
ptr.get<ESM::Door>();
return ref->base->script;
}
void Door::registerSelf()
{
boost::shared_ptr<Class> instance (new Door);

@ -17,6 +17,9 @@ namespace MWClass
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Ingredient>();
return ref->base->script;
}
void Ingredient::registerSelf()
{
boost::shared_ptr<Class> instance (new Ingredient);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,33 @@ 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 =
ptr.get<ESM::Light>();
return ref->base->script;
}
void Light::registerSelf()
{
boost::shared_ptr<Class> instance (new Light);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Tool>();
return ref->base->script;
}
void Lockpick::registerSelf()
{
boost::shared_ptr<Class> instance (new Lockpick);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Misc>();
return ref->base->script;
}
void Misc::registerSelf()
{
boost::shared_ptr<Class> instance (new Misc);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -6,6 +6,7 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
namespace MWClass
{
@ -44,6 +45,36 @@ namespace MWClass
return *ptr.getRefData().getCreatureStats();
}
boost::shared_ptr<MWWorld::Action> Npc::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>& Npc::getContainerStore (const MWWorld::Ptr& ptr)
const
{
if (!ptr.getRefData().getContainerStore().get())
{
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
new MWWorld::ContainerStore<MWWorld::RefData>);
// TODO add initial content
ptr.getRefData().getContainerStore() = store;
}
return *ptr.getRefData().getContainerStore();
}
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>();
return ref->base->script;
}
void Npc::registerSelf()
{
boost::shared_ptr<Class> instance (new Npc);

@ -16,6 +16,17 @@ namespace MWClass
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
///< Return creature stats
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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Potion>();
return ref->base->script;
}
void Potion::registerSelf()
{
boost::shared_ptr<Class> instance (new Potion);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Probe>();
return ref->base->script;
}
void Probe::registerSelf()
{
boost::shared_ptr<Class> instance (new Probe);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,27 @@ 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 =
ptr.get<ESM::Repair>();
return ref->base->script;
}
void Repair::registerSelf()
{
boost::shared_ptr<Class> instance (new Repair);

@ -13,6 +13,17 @@ 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
static void registerSelf();
};
}

@ -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,20 @@ 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 =
ptr.get<ESM::Weapon>();
return ref->base->script;
}
void Weapon::registerSelf()
{
boost::shared_ptr<Class> instance (new Weapon);

@ -13,12 +13,23 @@ 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
static void registerSelf();
};
}

@ -17,6 +17,8 @@
#include <libs/platform/strings.h>
#include "../mwrender/playerpos.hpp"
#include "../engine.hpp"
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <OgreRoot.h>
@ -58,6 +60,7 @@ namespace MWInput
OEngine::GUI::EventInjectorPtr guiEvents;
MWRender::PlayerPos &player;
MWGui::WindowManager &windows;
OMW::Engine& mEngine;
// Count screenshots.
int shotCount;
@ -137,7 +140,7 @@ namespace MWInput
void activate()
{
mEngine.activate();
}
// Exit program now button (which is disabled in GUI mode)
@ -151,13 +154,15 @@ namespace MWInput
InputImpl(OEngine::Render::OgreRenderer &_ogre,
MWRender::PlayerPos &_player,
MWGui::WindowManager &_windows,
bool debug)
bool debug,
OMW::Engine& engine)
: ogre(_ogre),
exit(ogre.getWindow()),
input(ogre.getWindow(), !debug),
poller(input),
player(_player),
windows(_windows),
mEngine (engine),
shotCount(0)
{
using namespace OEngine::Input;
@ -275,9 +280,10 @@ namespace MWInput
MWInputManager::MWInputManager(OEngine::Render::OgreRenderer &ogre,
MWRender::PlayerPos &player,
MWGui::WindowManager &windows,
bool debug)
bool debug,
OMW::Engine& engine)
{
impl = new InputImpl(ogre,player,windows,debug);
impl = new InputImpl(ogre,player,windows,debug, engine);
}
MWInputManager::~MWInputManager()

@ -19,6 +19,11 @@ namespace MWGui
class WindowManager;
}
namespace OMW
{
class Engine;
}
namespace MWInput
{
// Forward declaration of the real implementation.
@ -37,7 +42,8 @@ namespace MWInput
MWInputManager(OEngine::Render::OgreRenderer &_ogre,
MWRender::PlayerPos &_player,
MWGui::WindowManager &_windows,
bool debug);
bool debug,
OMW::Engine& engine);
~MWInputManager();
};
}

@ -49,7 +49,7 @@ namespace MWMechanics
value = min + (mModified - mBase);
diff = value - mModified;
}
else if (mBase>max-diff)
else if (mBase+diff>max)
{
value = max + (mModified - mBase);
diff = value - mModified;

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

@ -48,24 +48,25 @@ void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef<ESM::NPC, MWWorld::R
//get the part of the bodypart id which describes the race and the gender
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
std::string headModel = "meshes\\" + store.bodyParts.find(headID)->model;
cellRender.insertBegin(liveRef.ref);
cellRender.insertMesh(headModel);
//TODO: define consts for each bodypart e.g. chest, foot, wrist... and put the parts in the right place
cellRender.insertMesh("meshes\\" + store.bodyParts.find(bodyRaceID + "chest")->model);
liveRef.mData.setHandle (cellRender.insertEnd (liveRef.mData.isEnabled()));
}
template<typename T>
void insertCellRefList (CellRenderImp& cellRender, const ESMS::ESMStore& store, T& cellRefList)
{
for(typename T::List::iterator it = cellRefList.list.begin();
it != cellRefList.list.end(); it++)
{
insertObj (cellRender, *it, store);
}
for(typename T::List::iterator it = cellRefList.list.begin();
it != cellRefList.list.end(); it++)
{
if (it->mData.getCount())
insertObj (cellRender, *it, store);
}
}
void CellRenderImp::insertCell(ESMS::CellStore<MWWorld::RefData> &cell, const ESMS::ESMStore& store)
@ -92,5 +93,3 @@ void CellRenderImp::insertCell(ESMS::CellStore<MWWorld::RefData> &cell, const ES
insertCellRefList (*this, store, cell.statics);
insertCellRefList (*this, store, cell.weapons);
}

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

@ -76,4 +76,11 @@ op 0x2000069-0x200006b: ModDynamic (health, magicka, fatigue)
op 0x200006c-0x200006e: ModDynamic (health, magicka, fatigue), explicit reference
op 0x200006f-0x2000071: GetDynamic (health, magicka, fatigue)
op 0x2000072-0x2000074: GetDynamic (health, magicka, fatigue), explicit reference
opcodes 0x2000075-0x3ffffff unused
op 0x2000075: Activate
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);
}
}

@ -27,9 +27,9 @@ namespace MWScript
{
if (mReference.isEmpty())
throw std::runtime_error ("no implicit reference");
return mReference;
}
}
}
const MWWorld::Ptr InterpreterContext::getReference (
@ -43,21 +43,22 @@ namespace MWScript
{
if (mReference.isEmpty())
throw std::runtime_error ("no implicit reference");
return mReference;
}
}
}
InterpreterContext::InterpreterContext (MWWorld::Environment& environment,
MWScript::Locals *locals, MWWorld::Ptr reference)
: mEnvironment (environment), mLocals (locals), mReference (reference)
: mEnvironment (environment), mLocals (locals), mReference (reference),
mActivationHandled (false)
{}
int InterpreterContext::getLocalShort (int index) const
{
if (!mLocals)
throw std::runtime_error ("local variables not available in this context");
return mLocals->mShorts.at (index);
}
@ -65,7 +66,7 @@ namespace MWScript
{
if (!mLocals)
throw std::runtime_error ("local variables not available in this context");
return mLocals->mLongs.at (index);
}
@ -73,7 +74,7 @@ namespace MWScript
{
if (!mLocals)
throw std::runtime_error ("local variables not available in this context");
return mLocals->mFloats.at (index);
}
@ -90,45 +91,45 @@ namespace MWScript
if (!mLocals)
throw std::runtime_error ("local variables not available in this context");
mLocals->mLongs.at (index) = value;
mLocals->mLongs.at (index) = value;
}
void InterpreterContext::setLocalFloat (int index, float value)
{
if (!mLocals)
throw std::runtime_error ("local variables not available in this context");
mLocals->mFloats.at (index) = value;
mLocals->mFloats.at (index) = value;
}
void InterpreterContext::messageBox (const std::string& message,
const std::vector<std::string>& buttons)
{
std::cout << "message box: " << message << std::endl;
if (!buttons.empty())
if (!buttons.empty())
std::cerr << "error: message box buttons not supported" << std::endl;
}
bool InterpreterContext::menuMode()
{
return mEnvironment.mWindowManager->isGuiMode();
}
int InterpreterContext::getGlobalShort (const std::string& name) const
{
return mEnvironment.mWorld->getGlobalVariable (name).mShort;
return mEnvironment.mWorld->getGlobalVariable (name).mShort;
}
int InterpreterContext::getGlobalLong (const std::string& name) const
{
// a global long is internally a float.
return mEnvironment.mWorld->getGlobalVariable (name).mLong;
return mEnvironment.mWorld->getGlobalVariable (name).mLong;
}
float InterpreterContext::getGlobalFloat (const std::string& name) const
{
return mEnvironment.mWorld->getGlobalVariable (name).mFloat;
return mEnvironment.mWorld->getGlobalVariable (name).mFloat;
}
void InterpreterContext::setGlobalShort (const std::string& name, int value)
@ -166,83 +167,117 @@ namespace MWScript
else
mEnvironment.mWorld->getGlobalVariable (name).mFloat = value;
}
bool InterpreterContext::isScriptRunning (const std::string& name) const
{
return mEnvironment.mGlobalScripts->isRunning (name);
}
void InterpreterContext::startScript (const std::string& name)
{
mEnvironment.mGlobalScripts->addScript (name);
}
void InterpreterContext::stopScript (const std::string& name)
{
mEnvironment.mGlobalScripts->removeScript (name);
}
float InterpreterContext::getDistance (const std::string& name, const std::string& id) const
{
// TODO handle exterior cells (when ref and ref2 are located in different cells)
const MWWorld::Ptr ref2 = getReference (id, false);
const MWWorld::Ptr ref = mEnvironment.mWorld->getPtr (name, true);
double diff[3];
for (int i=0; i<3; ++i)
for (int i=0; i<3; ++i)
diff[i] = ref.getCellRef().pos.pos[i] - ref2.getCellRef().pos.pos[i];
return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]);
}
bool InterpreterContext::hasBeenActivated() const
bool InterpreterContext::hasBeenActivated (const MWWorld::Ptr& ptr)
{
if (!mActivated.isEmpty() && mActivated==ptr)
{
mActivationHandled = true;
return true;
}
return false;
}
bool InterpreterContext::hasActivationBeenHandled() const
{
return mActivationHandled;
}
void InterpreterContext::activate (const MWWorld::Ptr& ptr,
boost::shared_ptr<MWWorld::Action> action)
{
mActivated = ptr;
mActivationHandled = false;
mAction = action;
}
void InterpreterContext::executeActivation()
{
if (!mAction.get())
throw std::runtime_error ("activation failed, because no action to perform");
mAction->execute (mEnvironment);
mActivationHandled = true;
}
void InterpreterContext::clearActivation()
{
mActivated = MWWorld::Ptr();
mActivationHandled = false;
mAction.reset();
}
float InterpreterContext::getSecondsPassed() const
{
return mEnvironment.mFrameDuration;
}
bool InterpreterContext::isDisabled (const std::string& id) const
{
const MWWorld::Ptr ref = getReference (id, false);
return !ref.getRefData().isEnabled();
}
void InterpreterContext::enable (const std::string& id)
{
MWWorld::Ptr ref = getReference (id, false);
mEnvironment.mWorld->enable (ref);
}
void InterpreterContext::disable (const std::string& id)
{
MWWorld::Ptr ref = getReference (id, false);
MWWorld::Ptr ref = getReference (id, false);
mEnvironment.mWorld->disable (ref);
}
MWGui::WindowManager& InterpreterContext::getWindowManager()
{
return *mEnvironment.mWindowManager;
}
MWWorld::World& InterpreterContext::getWorld()
{
return *mEnvironment.mWorld;
}
MWSound::SoundManager& InterpreterContext::getSoundManager()
{
return *mEnvironment.mSoundManager;
}
MWWorld::Ptr InterpreterContext::getReference()
{
return getReference ("", true);
}
}

@ -1,11 +1,14 @@
#ifndef GAME_SCRIPT_INTERPRETERCONTEXT_H
#define GAME_SCRIPT_INTERPRETERCONTEXT_H
#include <boost/shared_ptr.hpp>
#include <components/interpreter/context.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/action.hpp"
namespace MWSound
{
@ -17,80 +20,95 @@ namespace MWScript
struct Locals;
class InterpreterContext : public Interpreter::Context
{
{
MWWorld::Environment& mEnvironment;
Locals *mLocals;
MWWorld::Ptr mReference;
MWWorld::Ptr mActivated;
bool mActivationHandled;
boost::shared_ptr<MWWorld::Action> mAction;
MWWorld::Ptr getReference (const std::string& id, bool activeOnly);
const MWWorld::Ptr getReference (const std::string& id, bool activeOnly) const;
public:
InterpreterContext (MWWorld::Environment& environment,
InterpreterContext (MWWorld::Environment& environment,
MWScript::Locals *locals, MWWorld::Ptr reference);
///< The ownership of \a locals is not transferred. 0-pointer allowed.
virtual int getLocalShort (int index) const;
virtual int getLocalLong (int index) const;
virtual float getLocalFloat (int index) const;
virtual void setLocalShort (int index, int value);
virtual void setLocalShort (int index, int value);
virtual void setLocalLong (int index, int value);
virtual void setLocalFloat (int index, float value);
virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons);
const std::vector<std::string>& buttons);
virtual bool menuMode();
virtual int getGlobalShort (const std::string& name) const;
virtual int getGlobalLong (const std::string& name) const;
virtual float getGlobalFloat (const std::string& name) const;
virtual void setGlobalShort (const std::string& name, int value);
virtual void setGlobalShort (const std::string& name, int value);
virtual void setGlobalLong (const std::string& name, int value);
virtual void setGlobalLong (const std::string& name, int value);
virtual void setGlobalFloat (const std::string& name, float value);
virtual bool isScriptRunning (const std::string& name) const;
virtual void startScript (const std::string& name);
virtual void stopScript (const std::string& name);
virtual float getDistance (const std::string& name, const std::string& id = "") const;
virtual bool hasBeenActivated() const;
bool hasBeenActivated (const MWWorld::Ptr& ptr);
///< \attention Calling this function for the right reference will mark the action as
/// been handled.
bool hasActivationBeenHandled() const;
void activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> action);
///< Store reference acted upon and action. The actual execution of the action does not
/// take place here.
void executeActivation();
///< Execute the action defined by the last activate call.
void clearActivation();
///< Discard the action defined by the last activate call.
virtual float getSecondsPassed() const;
virtual bool isDisabled (const std::string& id = "") const;
virtual void enable (const std::string& id = "");
virtual void disable (const std::string& id = "");
MWWorld::World& getWorld();
MWSound::SoundManager& getSoundManager();
MWGui::WindowManager& getWindowManager();
MWWorld::Ptr getReference();
///< Reference, that the script is running from (can be empty)
};
}
#endif

@ -16,37 +16,59 @@ namespace MWScript
class OpXBox : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push (0);
}
}
};
class OpOnActivate : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
runtime.push (context.hasBeenActivated (ptr));
}
};
class OpActivate : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push (static_cast<InterpreterContext&> (
runtime.getContext()).hasBeenActivated());
}
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
context.executeActivation();
}
};
const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d;
const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerFunction ("xbox", 'l', "", opcodeXBox);
extensions.registerFunction ("onactivate", 'l', "", opcodeOnActivate);
extensions.registerInstruction ("activate", "", opcodeActivate);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeXBox, new OpXBox);
interpreter.installSegment5 (opcodeOnActivate, new OpOnActivate);
}
}
interpreter.installSegment5 (opcodeActivate, new OpActivate);
}
}
}

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

@ -0,0 +1,16 @@
#include "actiontalk.hpp"
#include "environment.hpp"
#include "../mwgui/window_manager.hpp"
namespace MWWorld
{
ActionTalk::ActionTalk (const Ptr& actor) : mActor (actor) {}
void ActionTalk::execute (Environment& environment)
{
environment.mWindowManager->setMode (MWGui::GM_Dialogue);
}
}

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

@ -41,6 +41,21 @@ namespace MWWorld
return boost::shared_ptr<Action> (new NullAction);
}
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
{
return "";
}
const Class& Class::get (const std::string& key)
{
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);

@ -7,6 +7,8 @@
#include <boost/shared_ptr.hpp>
#include "action.hpp"
#include "containerstore.hpp"
#include "refdata.hpp"
namespace MWMechanics
{
@ -58,6 +60,19 @@ namespace MWWorld
///< Generate action for using via inventory menu (default implementation: return a
/// null action).
virtual ContainerStore<RefData>& 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 std::string getScript (const Ptr& ptr) const;
///< Return name of the script attached to ptr (default implementation: return an empty
/// string).
static const Class& get (const std::string& key);
///< If there is no class for this \a key, an exception is thrown.

@ -0,0 +1,26 @@
#ifndef GAME_MWWORLD_CONTAINERSTORE_H
#define GAME_MWWORLD_CONTAINERSTORE_H
#include <components/esm_store/cell_store.hpp>
namespace MWWorld
{
template<typename D>
struct 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::Misc, D> miscItems;
ESMS::CellRefList<ESM::Probe, D> probes;
ESMS::CellRefList<ESM::Repair, D> repairs;
ESMS::CellRefList<ESM::Weapon, D> weapons;
};
}
#endif

@ -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,86 @@
#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;
}
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

@ -7,6 +7,8 @@
#include "../mwscript/locals.hpp"
#include "containerstore.hpp"
namespace ESM
{
class Script;
@ -22,28 +24,36 @@ namespace MWWorld
class RefData
{
std::string mHandle;
MWScript::Locals mLocals; // if we find the overhead of heaving a locals
// object in the refdata of refs without a script,
// we can make this a pointer later.
bool mHasLocals;
bool mEnabled;
int mCount; // 0: deleted
// we are using shared pointer here to avoid having to create custom copy-constructor,
// assignment operator and destructor. As a consequence though copying a RefData object
// manually will probably give unexcepted results. This is not a problem since RefData
// are never copied outside of container operations.
boost::shared_ptr<MWMechanics::CreatureStats> mCreatureStats;
boost::shared_ptr<ContainerStore<RefData> > mContainerStore;
public:
RefData() : mHasLocals (false), mEnabled (true) {}
RefData() : mHasLocals (false), mEnabled (true), mCount (1) {}
std::string getHandle()
{
return mHandle;
}
int getCount() const
{
return mCount;
}
void setLocals (const ESM::Script& script)
{
if (!mHasLocals)
@ -52,37 +62,47 @@ namespace MWWorld
mHasLocals = true;
}
}
void setHandle (const std::string& handle)
{
mHandle = handle;
}
void setCount (int count)
{
mCount = count;
}
MWScript::Locals& getLocals()
{
return mLocals;
}
bool isEnabled() const
{
return mEnabled;
}
void enable()
{
mEnabled = true;
}
void disable()
{
mEnabled = true;
}
boost::shared_ptr<MWMechanics::CreatureStats>& getCreatureStats()
{
return mCreatureStats;
return mCreatureStats;
}
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
{
return mContainerStore;
}
};
};
}
#endif

@ -25,7 +25,7 @@ namespace
cellRefList.list.begin());
iter!=cellRefList.list.end(); ++iter)
{
if (!iter->base->script.empty())
if (!iter->base->script.empty() && iter->mData.getCount())
{
if (const ESM::Script *script = store.scripts.find (iter->base->script))
{
@ -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()))
{
@ -544,7 +544,7 @@ namespace MWWorld
insertInteriorScripts (*cell);
// adjust player
mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2]);
mPlayerPos->setPos (position.pos[0], position.pos[1], position.pos[2], true);
mPlayerPos->setCell (cell);
// TODO orientation
@ -600,4 +600,36 @@ namespace MWWorld
{
mCellChanged = false;
}
std::string World::getFacedHandle()
{
std::pair<std::string, float> result = mScene.getFacedHandle();
if (result.first.empty() ||
result.second>getStore().gameSettings.find ("iMaxActivateDist")->i)
return "";
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);
}
}
}
}
}

@ -83,8 +83,6 @@ namespace MWWorld
~World();
MWRender::MWScene* getMWScene() { return &mScene; }
MWRender::PlayerPos& getPlayerPos();
ESMS::ESMStore& getStore();
@ -133,6 +131,11 @@ namespace MWWorld
///< works only for interior cells currently.
void markCellAsUnchanged();
std::string getFacedHandle();
///< Return handle of the object the player is looking at
void deleteObject (Ptr ptr);
};
}

Loading…
Cancel
Save