From e458cf1df2a2e6adbbfeff565d05b31fc869facf Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Jun 2014 01:24:58 +0200 Subject: [PATCH] Savegame: Store death counter (Fixes #1477) --- apps/openmw/mwbase/mechanicsmanager.hpp | 17 ++++++++++ apps/openmw/mwmechanics/actors.cpp | 32 +++++++++++++++++++ apps/openmw/mwmechanics/actors.hpp | 6 ++++ .../mwmechanics/mechanicsmanagerimp.cpp | 20 ++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 8 +++++ apps/openmw/mwstate/statemanagerimp.cpp | 10 +++++- components/esm/defs.hpp | 1 + 7 files changed, 93 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index f31241bdb..30a576a15 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace Ogre { @@ -13,6 +14,9 @@ namespace Ogre namespace ESM { struct Class; + + class ESMReader; + class ESMWriter; } namespace MWWorld @@ -21,6 +25,11 @@ namespace MWWorld class CellStore; } +namespace Loading +{ + class Listener; +} + namespace MWBase { /// \brief Interface for game mechanics manager (implemented in MWMechanics) @@ -174,6 +183,14 @@ namespace MWBase virtual std::list getActorsFighting(const MWWorld::Ptr& actor) = 0; virtual void playerLoaded() = 0; + + virtual int countSavedGameRecords() const = 0; + + virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; + + virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; + + virtual void clear() = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 5727996d9..f3c42682b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1181,4 +1181,36 @@ namespace MWMechanics } return list; } + + void Actors::write (ESM::ESMWriter& writer, Loading::Listener& listener) const + { + writer.startRecord(ESM::REC_DCOU); + for (std::map::const_iterator it = mDeathCount.begin(); it != mDeathCount.end(); ++it) + { + writer.writeHNString("ID__", it->first); + writer.writeHNT ("COUN", it->second); + } + writer.endRecord(ESM::REC_DCOU); + + listener.increaseProgress(1); + } + + void Actors::readRecord (ESM::ESMReader& reader, int32_t type) + { + if (type == ESM::REC_DCOU) + { + while (reader.isNextSub("ID__")) + { + std::string id = reader.getHString(); + int count; + reader.getHNT (count, "COUN"); + mDeathCount[id] = count; + } + } + } + + void Actors::clear() + { + mDeathCount.clear(); + } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index cc95660dc..4784162f4 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -112,6 +112,12 @@ namespace MWMechanics /**ie AiCombat is active and the target is the actor **/ std::list getActorsFighting(const MWWorld::Ptr& actor); + void write (ESM::ESMWriter& writer, Loading::Listener& listener) const; + + void readRecord (ESM::ESMReader& reader, int32_t type); + + void clear(); // Clear death counter + private: PtrControllerMap mActors; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index f39a4b961..5737c380a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1050,4 +1050,24 @@ namespace MWMechanics std::list MechanicsManager::getActorsFighting(const MWWorld::Ptr& actor) { return mActors.getActorsFighting(actor); } + + int MechanicsManager::countSavedGameRecords() const + { + return 1; // Death counter + } + + void MechanicsManager::write(ESM::ESMWriter &writer, Loading::Listener &listener) const + { + mActors.write(writer, listener); + } + + void MechanicsManager::readRecord(ESM::ESMReader &reader, int32_t type) + { + mActors.readRecord(reader, type); + } + + void MechanicsManager::clear() + { + mActors.clear(); + } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index dcd12ee14..2511d5785 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -147,6 +147,14 @@ namespace MWMechanics virtual bool isAIActive(); virtual void playerLoaded(); + + virtual int countSavedGameRecords() const; + + virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const; + + virtual void readRecord (ESM::ESMReader& reader, int32_t type); + + virtual void clear(); }; } diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 68cb91eb9..a459c87bb 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -45,6 +45,7 @@ void MWState::StateManager::cleanup (bool force) MWBase::Environment::get().getWorld()->clear(); MWBase::Environment::get().getWindowManager()->clear(); MWBase::Environment::get().getInputManager()->clear(); + MWBase::Environment::get().getMechanicsManager()->clear(); mState = State_NoGame; mCharacterManager.clearCurrentCharacter(); @@ -205,7 +206,8 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot +MWBase::Environment::get().getWorld()->countSavedGameRecords() +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() - +MWBase::Environment::get().getWindowManager()->countSavedGameRecords(); + +MWBase::Environment::get().getWindowManager()->countSavedGameRecords() + +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords(); writer.setRecordCount (recordCount); writer.save (stream); @@ -226,6 +228,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot MWBase::Environment::get().getWorld()->write (writer, listener); MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer, listener); MWBase::Environment::get().getWindowManager()->write(writer, listener); + MWBase::Environment::get().getMechanicsManager()->write(writer, listener); // Ensure we have written the number of records that was estimated if (writer.getRecordCount() != recordCount+1) // 1 extra for TES3 record @@ -357,6 +360,11 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val); break; + case ESM::REC_DCOU: + + MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.val); + break; + default: // ignore invalid records diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index bdeb95291..f967af274 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -111,6 +111,7 @@ enum RecNameInts REC_ACTC = FourCC<'A','C','T','C'>::value, REC_MPRJ = FourCC<'M','P','R','J'>::value, REC_PROJ = FourCC<'P','R','O','J'>::value, + REC_DCOU = FourCC<'D','C','O','U'>::value, // format 1 REC_FILT = 0x544C4946