From 9788bbcab962b8d72f91c3b762ed6d90035e2bec Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Feb 2014 15:56:36 +0100 Subject: [PATCH] partially store creature state in saved game files (only attributes and dynamics for now) --- apps/openmw/mwclass/creature.cpp | 13 +++++++---- apps/openmw/mwclass/npc.cpp | 2 ++ apps/openmw/mwmechanics/creaturestats.cpp | 19 ++++++++++++++++ apps/openmw/mwmechanics/creaturestats.hpp | 9 ++++++++ apps/openmw/mwmechanics/npcstats.cpp | 8 +++++-- apps/openmw/mwmechanics/stat.hpp | 24 ++++++++++++++++++++ components/CMakeLists.txt | 2 +- components/esm/creaturestate.cpp | 4 ++++ components/esm/creaturestate.hpp | 2 ++ components/esm/creaturestats.cpp | 20 +++++++++++++++++ components/esm/creaturestats.hpp | 27 +++++++++++++++++++++++ components/esm/statstate.hpp | 8 ++++++- 12 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 components/esm/creaturestats.cpp create mode 100644 components/esm/creaturestats.hpp diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 6af8373c55..81ca0ce2bf 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -766,8 +766,11 @@ namespace MWClass ensureCustomData (ptr); - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore-> - readState (state2.mInventory); + CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + + customData.mContainerStore->readState (state2.mInventory); + customData.mCreatureStats.readState (state2.mCreatureStats); + } void Creature::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) @@ -777,8 +780,10 @@ namespace MWClass ensureCustomData (ptr); - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore-> - writeState (state2.mInventory); + CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + + customData.mContainerStore->writeState (state2.mInventory); + customData.mCreatureStats.writeState (state2.mCreatureStats); } const ESM::GameSetting* Creature::fMinWalkSpeedCreature; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 7e67738d44..3a95f3c294 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1282,6 +1282,7 @@ namespace MWClass customData.mInventoryStore.readState (state2.mInventory); customData.mNpcStats.readState (state2.mNpcStats); + static_cast (customData.mNpcStats).readState (state2.mCreatureStats); } void Npc::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) @@ -1295,6 +1296,7 @@ namespace MWClass customData.mInventoryStore.writeState (state2.mInventory); customData.mNpcStats.writeState (state2.mNpcStats); + static_cast (customData.mNpcStats).writeState (state2.mCreatureStats); } const ESM::GameSetting *Npc::fMinWalkSpeed; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 8f890befba..d61b967390 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" @@ -457,4 +459,21 @@ namespace MWMechanics mAttackStrength = value; } + void CreatureStats::writeState (ESM::CreatureStats& state) const + { + for (int i=0; i<8; ++i) + mAttributes[i].writeState (state.mAttributes[i]); + + for (int i=0; i<3; ++i) + mDynamic[i].writeState (state.mDynamic[i]); + } + + void CreatureStats::readState (const ESM::CreatureStats& state) + { + for (int i=0; i<8; ++i) + mAttributes[i].readState (state.mAttributes[i]); + + for (int i=0; i<3; ++i) + mDynamic[i].readState (state.mDynamic[i]); + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index bb95833015..94e506fc4f 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -12,6 +12,11 @@ #include "aisequence.hpp" #include "drawstate.hpp" +namespace ESM +{ + struct CreatureStats; +} + namespace MWMechanics { /// \brief Common creature stats @@ -212,6 +217,10 @@ namespace MWMechanics std::set mBoundItems; // Same as above std::map mSummonedCreatures; + + void writeState (ESM::CreatureStats& state) const; + + void readState (const ESM::CreatureStats& state); }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 786d35b9cb..eee27272aa 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -437,7 +437,6 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const { mSkill[i].writeState (state.mSkills[i].mRegular); mWerewolfSkill[i].writeState (state.mSkills[i].mWerewolf); - state.mSkills[i].mIncrease = mSkillIncreases[i]; } state.mBounty = mBounty; @@ -456,6 +455,9 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const state.mAttackStrength = mAttackStrength; state.mLevelProgress = mLevelProgress; + for (int i=0; i<8; ++i) + state.mSkillIncrease[i] = mSkillIncreases[i]; + std::copy (mUsedIds.begin(), mUsedIds.end(), std::back_inserter (state.mUsedIds)); state.mTimeToStartDrowning = mTimeToStartDrowning; @@ -484,7 +486,6 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state) { mSkill[i].readState (state.mSkills[i].mRegular); mWerewolfSkill[i].readState (state.mSkills[i].mWerewolf); - mSkillIncreases[i] = state.mSkills[i].mIncrease; } mBounty = state.mBounty; @@ -494,6 +495,9 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state) mAttackStrength = state.mAttackStrength; mLevelProgress = state.mLevelProgress; + for (int i=0; i<8; ++i) + mSkillIncreases[i] = state.mSkillIncrease[i]; + std::copy (state.mUsedIds.begin(), state.mUsedIds.end(), std::inserter (mUsedIds, mUsedIds.begin())); mTimeToStartDrowning = state.mTimeToStartDrowning; diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 28005966a0..0fb4c57328 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -88,6 +88,18 @@ namespace MWMechanics { mModified = mBase + modifier; } + + void writeState (ESM::StatState& state) const + { + state.mBase = mBase; + state.mMod = mModified; + } + + void readState (const ESM::StatState& state) + { + mBase = state.mBase; + mModified = state.mMod; + } }; template @@ -192,6 +204,18 @@ namespace MWMechanics mStatic.setModifier (modifier); setCurrent (getCurrent()+diff); } + + void writeState (ESM::StatState& state) const + { + mStatic.writeState (state); + state.mCurrent = mCurrent; + } + + void readState (const ESM::StatState& state) + { + mStatic.readState (state); + mCurrent = state.mCurrent; + } }; template diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 8665938630..831b140575 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -45,7 +45,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats + npcstats creaturestats ) add_component_dir (misc diff --git a/components/esm/creaturestate.cpp b/components/esm/creaturestate.cpp index 43cde30251..9e9b561026 100644 --- a/components/esm/creaturestate.cpp +++ b/components/esm/creaturestate.cpp @@ -6,6 +6,8 @@ void ESM::CreatureState::load (ESMReader &esm) ObjectState::load (esm); mInventory.load (esm); + + mCreatureStats.load (esm); } void ESM::CreatureState::save (ESMWriter &esm, bool inInventory) const @@ -13,4 +15,6 @@ void ESM::CreatureState::save (ESMWriter &esm, bool inInventory) const ObjectState::save (esm, inInventory); mInventory.save (esm); + + mCreatureStats.save (esm); } \ No newline at end of file diff --git a/components/esm/creaturestate.hpp b/components/esm/creaturestate.hpp index f7f9b80380..604c2f3a70 100644 --- a/components/esm/creaturestate.hpp +++ b/components/esm/creaturestate.hpp @@ -3,6 +3,7 @@ #include "objectstate.hpp" #include "inventorystate.hpp" +#include "creaturestats.hpp" namespace ESM { @@ -11,6 +12,7 @@ namespace ESM struct CreatureState : public ObjectState { InventoryState mInventory; + CreatureStats mCreatureStats; virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp new file mode 100644 index 0000000000..fe250089aa --- /dev/null +++ b/components/esm/creaturestats.cpp @@ -0,0 +1,20 @@ + +#include "creaturestats.hpp" + +void ESM::CreatureStats::load (ESMReader &esm) +{ + for (int i=0; i<8; ++i) + mAttributes[i].load (esm); + + for (int i=0; i<3; ++i) + mDynamic[i].load (esm); +} + +void ESM::CreatureStats::save (ESMWriter &esm) const +{ + for (int i=0; i<8; ++i) + mAttributes[i].save (esm); + + for (int i=0; i<3; ++i) + mDynamic[i].save (esm); +} \ No newline at end of file diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp new file mode 100644 index 0000000000..540044f389 --- /dev/null +++ b/components/esm/creaturestats.hpp @@ -0,0 +1,27 @@ +#ifndef OPENMW_ESM_CREATURESTATS_H +#define OPENMW_ESM_CREATURESTATS_H + +#include +#include +#include + +#include "statstate.hpp" + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + // format 0, saved games only + + struct CreatureStats + { + StatState mAttributes[8]; + StatState mDynamic[3]; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; +} + +#endif \ No newline at end of file diff --git a/components/esm/statstate.hpp b/components/esm/statstate.hpp index c8b0d6a4d9..4b4023bc22 100644 --- a/components/esm/statstate.hpp +++ b/components/esm/statstate.hpp @@ -13,6 +13,7 @@ namespace ESM { T mBase; T mMod; + T mCurrent; T mDamage; float mProgress; @@ -23,13 +24,15 @@ namespace ESM }; template - StatState::StatState() : mBase (0), mMod (0), mDamage (0), mProgress (0) {} + StatState::StatState() : mBase (0), mMod (0), mCurrent (0), mDamage (0), mProgress (0) {} template void StatState::load (ESMReader &esm) { esm.getHNT (mBase, "STBA"); esm.getHNT (mMod, "STMO"); + mCurrent = 0; + esm.getHNOT (mCurrent, "STCU"); mDamage = 0; esm.getHNOT (mDamage, "STDA"); mProgress = 0; @@ -42,6 +45,9 @@ namespace ESM esm.writeHNT ("STBA", mBase); esm.writeHNT ("STMO", mMod); + if (mCurrent) + esm.writeHNT ("STCU", mCurrent); + if (mDamage) esm.writeHNT ("STDA", mDamage);