From 04b86f7e1e2bb0ccacd5d7b661a5e9411a51af37 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag <marc@zpages.de> Date: Mon, 26 Jul 2010 12:52:32 +0200 Subject: [PATCH] added first set of character and creature stats (attributes) --- apps/openmw/CMakeLists.txt | 5 ++- apps/openmw/mwmechanics/creaturestats.hpp | 15 +++++++ apps/openmw/mwmechanics/stat.hpp | 49 +++++++++++++++++++++ apps/openmw/mwworld/ptr.hpp | 53 ++++++++++++++++++++++- apps/openmw/mwworld/refdata.hpp | 18 ++++++++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 apps/openmw/mwmechanics/creaturestats.hpp create mode 100644 apps/openmw/mwmechanics/stat.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 7d19390b66..bac5146692 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 0000000000..f8aaa3caff --- /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<int> mAttributes[8]; + }; +} + +#endif + diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp new file mode 100644 index 0000000000..eb0e35bd96 --- /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<typename T> + 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 a65fcb7cca..5f8c938a33 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -5,8 +5,12 @@ #include <boost/any.hpp> +#include <components/esm/loadcrea.hpp> +#include <components/esm/loadnpc.hpp> #include <components/esm_store/cell_store.hpp> +#include "../mwmechanics/creaturestats.hpp" + #include "refdata.hpp" namespace MWWorld @@ -45,7 +49,7 @@ namespace MWWorld template<typename T> ESMS::LiveCellRef<T, RefData> *get() const { - return boost::any_cast<const ESMS::LiveCellRef<T, RefData>*> (mPtr); + return boost::any_cast<ESMS::LiveCellRef<T, RefData>*> (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<ESM::Creature, RefData> *)) + { + boost::shared_ptr<MWMechanics::CreatureStats> stats; + data.getCreatureStats() = stats; + + ESMS::LiveCellRef<ESM::Creature, RefData> *ref = get<ESM::Creature>(); + + 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<ESM::NPC, RefData> *)) + { + boost::shared_ptr<MWMechanics::CreatureStats> stats; + data.getCreatureStats() = stats; + + ESMS::LiveCellRef<ESM::NPC, RefData> *ref = get<ESM::NPC>(); + + 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 58c169c0e5..919f4f8a02 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -3,6 +3,8 @@ #include <string> +#include <boost/shared_ptr.hpp> + #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<MWMechanics::CreatureStats> mCreatureStats; public: @@ -64,6 +77,11 @@ namespace MWWorld { mEnabled = true; } + + boost::shared_ptr<MWMechanics::CreatureStats>& getCreatureStats() + { + return mCreatureStats; + } }; }