diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2dc4473ba..7f384a794 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -82,6 +82,8 @@ set(GAMEWORLD mwworld/class.cpp mwworld/classes.cpp mwworld/activator.cpp + mwworld/creature.cpp + mwworld/npc.cpp ) set(GAMEWORLD_HEADER mwworld/refdata.hpp @@ -92,6 +94,8 @@ set(GAMEWORLD_HEADER mwworld/class.hpp mwworld/classes.hpp mwworld/activator.hpp + mwworld/creature.hpp + mwworld/npc.hpp ) source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 310695959..229a351ac 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -5,6 +5,8 @@ #include "../mwgui/window_manager.hpp" +#include "../mwworld/class.hpp" + namespace MWMechanics { MechanicsManager::MechanicsManager (const ESMS::ESMStore& store, @@ -46,7 +48,8 @@ namespace MWMechanics { if (!mWatched.isEmpty()) { - MWMechanics::CreatureStats& stats = mWatched.getCreatureStats(); + MWMechanics::CreatureStats& stats = + MWWorld::Class::get (mWatched).getCreatureStats (mWatched); static const char *attributeNames[8] = { diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 997e2473a..2abf1f284 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -7,6 +7,8 @@ #include #include +#include "../mwworld/class.hpp" + #include "interpretercontext.hpp" namespace MWScript @@ -26,8 +28,10 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = context.getReference(); + Interpreter::Type_Integer value = - context.getReference().getCreatureStats().mAttributes[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. getModified(); runtime.push (value); @@ -50,8 +54,10 @@ namespace MWScript std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + Interpreter::Type_Integer value = - context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. getModified(); runtime.push (value); @@ -74,7 +80,9 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - context.getReference().getCreatureStats().mAttributes[mIndex]. + MWWorld::Ptr ptr = context.getReference(); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. setModified (value, 0); } }; @@ -98,7 +106,9 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. setModified (value, 0); } }; @@ -119,10 +129,12 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - value += context.getReference().getCreatureStats().mAttributes[mIndex]. + MWWorld::Ptr ptr = context.getReference(); + + value += MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. getModified(); - context.getReference().getCreatureStats().mAttributes[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. setModified (value, 0, 100); } }; @@ -146,11 +158,13 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + value += - context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. getModified(); - context.getWorld().getPtr (id, false).getCreatureStats().mAttributes[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mAttributes[mIndex]. setModified (value, 0, 100); } }; @@ -168,6 +182,8 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); + MWWorld::Ptr ptr = context.getReference(); + if (mIndex==0) { // health is a special case @@ -196,7 +212,7 @@ namespace MWScript } Interpreter::Type_Integer value = - context.getReference().getCreatureStats().mDynamic[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mDynamic[mIndex]. getCurrent(); runtime.push (value); @@ -219,6 +235,8 @@ namespace MWScript std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + if (mIndex==0) { // health is a special case @@ -247,7 +265,7 @@ namespace MWScript } Interpreter::Type_Integer value = - context.getWorld().getPtr (id, false).getCreatureStats().mDynamic[mIndex]. + MWWorld::Class::get (ptr).getCreatureStats (ptr).mDynamic[mIndex]. getCurrent(); runtime.push (value); @@ -270,7 +288,9 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - context.getReference().getCreatureStats().mDynamic[mIndex]. + MWWorld::Ptr ptr = context.getReference(); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mDynamic[mIndex]. setModified (value, 0); } }; @@ -294,7 +314,9 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - context.getWorld().getPtr (id, false).getCreatureStats().mDynamic[mIndex]. + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mDynamic[mIndex]. setModified (value, 0); } }; @@ -315,7 +337,9 @@ namespace MWScript Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); - MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + MWWorld::Ptr ptr = context.getReference(); + + MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -345,8 +369,10 @@ namespace MWScript Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWMechanics::CreatureStats& stats = - context.getWorld().getPtr (id, false).getCreatureStats(); + MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -374,7 +400,9 @@ namespace MWScript Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); - MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + MWWorld::Ptr ptr = context.getReference(); + + MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -401,8 +429,10 @@ namespace MWScript Interpreter::Type_Integer diff = runtime[0].mInteger; runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWMechanics::CreatureStats& stats = - context.getWorld().getPtr (id, false).getCreatureStats(); + MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Integer current = stats.mDynamic[mIndex].getCurrent(); @@ -423,7 +453,9 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - MWMechanics::CreatureStats& stats = context.getReference().getCreatureStats(); + MWWorld::Ptr ptr = context.getReference(); + + MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Float value = 0; @@ -452,8 +484,10 @@ namespace MWScript std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + MWMechanics::CreatureStats& stats = - context.getWorld().getPtr (id, false).getCreatureStats(); + MWWorld::Class::get (ptr).getCreatureStats (ptr); Interpreter::Type_Float value = 0; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 1520916be..9a2020337 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -3,6 +3,8 @@ #include +#include "ptr.hpp" + namespace MWWorld { std::map > Class::sClasses; @@ -11,6 +13,11 @@ namespace MWWorld Class::~Class() {} + MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const + { + throw std::runtime_error ("class does not have creature stats"); + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); @@ -21,6 +28,11 @@ namespace MWWorld return *iter->second; } + const Class& Class::get (const Ptr& ptr) + { + return get (ptr.getTypeName()); + } + void Class::registerClass (const std::string& key, boost::shared_ptr instance) { sClasses.insert (std::make_pair (key, instance)); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index c7c6a26f9..3144a7108 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -6,8 +6,15 @@ #include +namespace MWMechanics +{ + struct CreatureStats; +} + namespace MWWorld { + class Ptr; + /// \brief Base class for referenceable esm records class Class { @@ -25,11 +32,17 @@ namespace MWWorld virtual ~Class(); + virtual MWMechanics::CreatureStats& getCreatureStats (const Ptr& ptr) const; + ///< Return creature stats or throw an exception, if class does not have creature stats + /// (default implementation: throw an exceoption) static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. + static const Class& get (const Ptr& ptr); + ///< If there is no class for this pointer, an exception is thrown. + static void registerClass (const std::string& key, boost::shared_ptr instance); }; } diff --git a/apps/openmw/mwworld/classes.cpp b/apps/openmw/mwworld/classes.cpp index 79f9b52d7..4ae2076d9 100644 --- a/apps/openmw/mwworld/classes.cpp +++ b/apps/openmw/mwworld/classes.cpp @@ -2,11 +2,15 @@ #include "classes.hpp" #include "activator.hpp" +#include "creature.hpp" +#include "npc.hpp" namespace MWWorld { void registerClasses() { Activator::registerSelf(); + Creature::registerSelf(); + Npc::registerSelf(); } } diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 92eed194c..bf119b8f4 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -82,63 +82,6 @@ namespace MWWorld assert (mCell); return mCell; } - - /// Throws an exception, if the ID type does not support creature stats. - MWMechanics::CreatureStats& getCreatureStats() const - { - RefData& data = getRefData(); - - if (!data.getCreatureStats().get()) - { - if (mPtr.type()==typeid (ESMS::LiveCellRef *)) - { - boost::shared_ptr stats ( - new MWMechanics::CreatureStats); - - ESMS::LiveCellRef *ref = get(); - - stats->mAttributes[0].set (ref->base->data.strength); - stats->mAttributes[1].set (ref->base->data.intelligence); - stats->mAttributes[2].set (ref->base->data.willpower); - stats->mAttributes[3].set (ref->base->data.agility); - stats->mAttributes[4].set (ref->base->data.speed); - stats->mAttributes[5].set (ref->base->data.endurance); - stats->mAttributes[6].set (ref->base->data.personality); - stats->mAttributes[7].set (ref->base->data.luck); - stats->mDynamic[0].set (ref->base->data.health); - stats->mDynamic[1].set (ref->base->data.mana); - stats->mDynamic[2].set (ref->base->data.fatigue); - - data.getCreatureStats() = stats; - } - else if (mPtr.type()==typeid (ESMS::LiveCellRef *)) - { - boost::shared_ptr stats ( - new MWMechanics::CreatureStats); - - ESMS::LiveCellRef *ref = get(); - - stats->mAttributes[0].set (ref->base->npdt52.strength); - stats->mAttributes[1].set (ref->base->npdt52.intelligence); - stats->mAttributes[2].set (ref->base->npdt52.willpower); - stats->mAttributes[3].set (ref->base->npdt52.agility); - stats->mAttributes[4].set (ref->base->npdt52.speed); - stats->mAttributes[5].set (ref->base->npdt52.endurance); - stats->mAttributes[6].set (ref->base->npdt52.personality); - stats->mAttributes[7].set (ref->base->npdt52.luck); - stats->mDynamic[0].set (ref->base->npdt52.health); - stats->mDynamic[1].set (ref->base->npdt52.mana); - stats->mDynamic[2].set (ref->base->npdt52.fatigue); - - data.getCreatureStats() = stats; - } - else - throw std::runtime_error ( - "CreatureStats not available for this ID type"); - } - - return *data.getCreatureStats(); - } }; inline bool operator== (const Ptr& left, const Ptr& right)