diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 83960d64a..3464a2c33 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -90,7 +90,10 @@ source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) set(GAMEMECHANICS mwmechanics/mechanicsmanager.cpp) set(GAMEMECHANICS_HEADER - mwmechanics/mechanicsmanager.hpp) + mwmechanics/mechanicsmanager.hpp + mwmechanics/stat.hpp + mwmechanics/creaturestats.hpp + ) source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER}) set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD} diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp new file mode 100644 index 000000000..f8aaa3caf --- /dev/null +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -0,0 +1,15 @@ +#ifndef GAME_MWMECHANICS_CREATURESTATS_H +#define GAME_MWMECHANICS_CREATURESTATS_H + +#include "stat.hpp" + +namespace MWMechanics +{ + struct CreatureStats + { + Stat mAttributes[8]; + }; +} + +#endif + diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp new file mode 100644 index 000000000..eb0e35bd9 --- /dev/null +++ b/apps/openmw/mwmechanics/stat.hpp @@ -0,0 +1,49 @@ +#ifndef GAME_MWMECHANICS_STAT_H +#define GAME_MWMECHANICS_STAT_H + +namespace MWMechanics +{ + template + class Stat + { + T mBase; + T mModified; + + public: + + Stat() : mBase (0), mModified (0) {} + + const T& getBase() const + { + return mBase; + } + + const T& getModified() const + { + return mModified; + } + + /// Set base and modified to \a value. + void set (const T& value) + { + mBase = mModified = value; + } + + /// Set base and adjust modified accordingly. + void setBase (const T& value) + { + T diff = value - mBase; + mBase = value; + mModified += diff; + } + + /// Change modified relatively. + void modify (const T& diff) + { + mModified += diff; + } + }; +} + +#endif + diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index a65fcb7cc..5f8c938a3 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -5,8 +5,12 @@ #include +#include +#include #include +#include "../mwmechanics/creaturestats.hpp" + #include "refdata.hpp" namespace MWWorld @@ -45,7 +49,7 @@ namespace MWWorld template ESMS::LiveCellRef *get() const { - return boost::any_cast*> (mPtr); + return boost::any_cast*> (mPtr); } ESM::CellRef& getCellRef() const @@ -65,6 +69,53 @@ 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; + data.getCreatureStats() = stats; + + 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); + } + else if (mPtr.type()==typeid (ESMS::LiveCellRef *)) + { + boost::shared_ptr stats; + data.getCreatureStats() = stats; + + 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); + } + else + throw std::runtime_error ( + "CreatureStats not available for this ID type"); + } + + return *data.getCreatureStats(); + } }; } diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 58c169c0e..919f4f8a0 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -3,6 +3,8 @@ #include +#include + #include "../mwscript/locals.hpp" namespace ESM @@ -10,6 +12,11 @@ namespace ESM class Script; } +namespace MWMechanics +{ + struct CreatureStats; +} + namespace MWWorld { class RefData @@ -21,6 +28,12 @@ namespace MWWorld // we can make this a pointer later. bool mHasLocals; bool mEnabled; + + // 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 mCreatureStats; public: @@ -64,6 +77,11 @@ namespace MWWorld { mEnabled = true; } + + boost::shared_ptr& getCreatureStats() + { + return mCreatureStats; + } }; }