1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 21:53:51 +00:00

Merge remote branch 'upstream/master'

This commit is contained in:
Armin Preiml 2010-08-08 10:09:10 +02:00
commit fa077ccdc4
65 changed files with 1548 additions and 148 deletions

View file

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

View file

@ -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();
}
}

View file

@ -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&);
@ -117,6 +120,9 @@ namespace OMW
/// Initialise and enter main loop.
void go();
/// Activate the focussed object.
void activate();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -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();
};
}

View file

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

View file

@ -26,8 +26,10 @@ namespace MWRender
/// 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

View file

@ -61,11 +61,12 @@ void insertObj(CellRenderImp& cellRender, ESMS::LiveCellRef<ESM::NPC, MWWorld::R
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);
}

View file

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

View file

@ -102,8 +102,10 @@ namespace MWRender
/// Make the reference with the given handle invisible.
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

View file

@ -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);
}
}
}

View file

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

View file

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

View file

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

View file

@ -50,7 +50,8 @@ namespace MWScript
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
@ -197,11 +198,46 @@ namespace MWScript
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;
@ -245,4 +281,3 @@ namespace MWScript
return getReference ("", true);
}
}

View file

@ -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
{
@ -22,6 +25,9 @@ namespace MWScript
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);
@ -70,7 +76,21 @@ namespace MWScript
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;
@ -92,5 +112,3 @@ namespace MWScript
}
#endif

View file

@ -29,24 +29,46 @@ namespace MWScript
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();
runtime.push (context.hasBeenActivated (ptr));
}
};
class OpActivate : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWWorld::Ptr ptr = context.getReference();
context.executeActivation();
}
};
const int opcodeXBox = 0x200000c;
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);
}
}
}

View file

@ -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);
}
}

View file

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

View file

@ -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);
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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);
}
}

View file

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

View file

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

View file

@ -7,6 +7,8 @@
#include "../mwscript/locals.hpp"
#include "containerstore.hpp"
namespace ESM
{
class Script;
@ -28,6 +30,7 @@ namespace MWWorld
// 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
@ -35,15 +38,22 @@ namespace MWWorld
// 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)
@ -58,6 +68,11 @@ namespace MWWorld
mHandle = handle;
}
void setCount (int count)
{
mCount = count;
}
MWScript::Locals& getLocals()
{
return mLocals;
@ -82,6 +97,11 @@ namespace MWWorld
{
return mCreatureStats;
}
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
{
return mContainerStore;
}
};
}

View file

@ -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);
}
}
}
}
}

View file

@ -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);
};
}