forked from teamnwah/openmw-tes3coop
save and load dynamic records
This commit is contained in:
parent
030c733e2d
commit
1c13a9037a
10 changed files with 189 additions and 29 deletions
|
@ -101,28 +101,30 @@ namespace MWBase
|
|||
float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
|
||||
///< Perform a persuasion action on NPC
|
||||
|
||||
virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0;
|
||||
///< Forces an object to refresh its animation state.
|
||||
virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0;
|
||||
///< Forces an object to refresh its animation state.
|
||||
|
||||
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0;
|
||||
///< Run animation for a MW-reference. Calls to this function for references that are currently not
|
||||
/// in the scene should be ignored.
|
||||
///
|
||||
/// \param mode 0 normal, 1 immediate start, 2 immediate loop
|
||||
/// \param count How many times the animation should be run
|
||||
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0;
|
||||
///< Run animation for a MW-reference. Calls to this function for references that are currently not
|
||||
/// in the scene should be ignored.
|
||||
///
|
||||
/// \param mode 0 normal, 1 immediate start, 2 immediate loop
|
||||
/// \param count How many times the animation should be run
|
||||
|
||||
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
|
||||
/// references that are currently not in the scene should be ignored.
|
||||
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
|
||||
/// references that are currently not in the scene should be ignored.
|
||||
|
||||
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0;
|
||||
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0;
|
||||
|
||||
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
|
||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0;
|
||||
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
|
||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0;
|
||||
|
||||
virtual void toggleAI() = 0;
|
||||
virtual bool isAIActive() = 0;
|
||||
virtual void toggleAI() = 0;
|
||||
virtual bool isAIActive() = 0;
|
||||
|
||||
virtual void playerLoaded() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace OEngine
|
|||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
struct Position;
|
||||
struct Cell;
|
||||
struct Class;
|
||||
|
@ -98,6 +99,12 @@ namespace MWBase
|
|||
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual int countSavedGameRecords() const = 0;
|
||||
|
||||
virtual void write (ESM::ESMWriter& writer) const = 0;
|
||||
|
||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
||||
|
||||
virtual OEngine::Render::Fader* getFader() = 0;
|
||||
///< \ŧodo remove this function. Rendering details should not be exposed.
|
||||
|
||||
|
|
|
@ -701,4 +701,12 @@ namespace MWMechanics
|
|||
{
|
||||
return mAI;
|
||||
}
|
||||
|
||||
void MechanicsManager::playerLoaded()
|
||||
{
|
||||
mUpdatePlayer = true;
|
||||
mClassSelected = true;
|
||||
mRaceSelected = true;
|
||||
mAI = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,18 +98,20 @@ namespace MWMechanics
|
|||
void toLower(std::string npcFaction);
|
||||
///< Perform a persuasion action on NPC
|
||||
|
||||
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
|
||||
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
|
||||
|
||||
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||
virtual void skipAnimation(const MWWorld::Ptr& ptr);
|
||||
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName);
|
||||
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||
virtual void skipAnimation(const MWWorld::Ptr& ptr);
|
||||
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName);
|
||||
|
||||
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
|
||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr);
|
||||
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
|
||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr);
|
||||
|
||||
virtual void toggleAI();
|
||||
virtual bool isAIActive();
|
||||
virtual void toggleAI();
|
||||
virtual bool isAIActive();
|
||||
|
||||
virtual void playerLoaded();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../mwbase/journal.hpp"
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
@ -103,8 +104,10 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
|||
ESM::ESMWriter writer;
|
||||
writer.setFormat (ESM::Header::CurrentFormat);
|
||||
writer.setRecordCount (
|
||||
1+ // saved game header
|
||||
MWBase::Environment::get().getJournal()->countSavedGameRecords());
|
||||
1 // saved game header
|
||||
+MWBase::Environment::get().getJournal()->countSavedGameRecords()
|
||||
+MWBase::Environment::get().getWorld()->countSavedGameRecords()
|
||||
);
|
||||
|
||||
writer.save (stream);
|
||||
|
||||
|
@ -113,7 +116,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
|||
writer.endRecord (ESM::REC_SAVE);
|
||||
|
||||
MWBase::Environment::get().getJournal()->write (writer);
|
||||
/// \todo write saved game data
|
||||
MWBase::Environment::get().getWorld()->write (writer);
|
||||
|
||||
writer.close();
|
||||
|
||||
|
@ -149,6 +152,19 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
|
|||
MWBase::Environment::get().getJournal()->readRecord (reader, n.val);
|
||||
break;
|
||||
|
||||
case ESM::REC_ALCH:
|
||||
case ESM::REC_ARMO:
|
||||
case ESM::REC_BOOK:
|
||||
case ESM::REC_CLAS:
|
||||
case ESM::REC_CLOT:
|
||||
case ESM::REC_ENCH:
|
||||
case ESM::REC_NPC_:
|
||||
case ESM::REC_SPEL:
|
||||
case ESM::REC_WEAP:
|
||||
|
||||
MWBase::Environment::get().getWorld()->readRecord (reader, n.val);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// ignore invalid records
|
||||
|
@ -167,6 +183,13 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
|
|||
MWBase::Environment::get().getWorld()->setupPlayer();
|
||||
MWBase::Environment::get().getWorld()->renderPlayer();
|
||||
MWBase::Environment::get().getWindowManager()->updatePlayer();
|
||||
MWBase::Environment::get().getMechanicsManager()->playerLoaded();
|
||||
|
||||
// for testing purpose only
|
||||
ESM::Position pos;
|
||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||
MWBase::Environment::get().getWorld()->changeToExteriorCell (pos);
|
||||
}
|
||||
|
||||
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
|
||||
|
|
|
@ -139,4 +139,54 @@ void ESMStore::setUp()
|
|||
mAttributes.setUp();
|
||||
}
|
||||
|
||||
int ESMStore::countSavedGameRecords() const
|
||||
{
|
||||
return
|
||||
mPotions.getDynamicSize()
|
||||
+mArmors.getDynamicSize()
|
||||
+mBooks.getDynamicSize()
|
||||
+mClasses.getDynamicSize()
|
||||
+mClothes.getDynamicSize()
|
||||
+mEnchants.getDynamicSize()
|
||||
+mNpcs.getDynamicSize()
|
||||
+mSpells.getDynamicSize()
|
||||
+mWeapons.getDynamicSize();
|
||||
}
|
||||
|
||||
void ESMStore::write (ESM::ESMWriter& writer) const
|
||||
{
|
||||
mPotions.write (writer);
|
||||
mArmors.write (writer);
|
||||
mBooks.write (writer);
|
||||
mClasses.write (writer);
|
||||
mClothes.write (writer);
|
||||
mEnchants.write (writer);
|
||||
mNpcs.write (writer);
|
||||
mSpells.write (writer);
|
||||
mWeapons.write (writer);
|
||||
}
|
||||
|
||||
bool ESMStore::readRecord (ESM::ESMReader& reader, int32_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ESM::REC_ALCH:
|
||||
case ESM::REC_ARMO:
|
||||
case ESM::REC_BOOK:
|
||||
case ESM::REC_CLAS:
|
||||
case ESM::REC_CLOT:
|
||||
case ESM::REC_ENCH:
|
||||
case ESM::REC_NPC_:
|
||||
case ESM::REC_SPEL:
|
||||
case ESM::REC_WEAP:
|
||||
|
||||
mStores[type]->read (reader);
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
|
|
@ -209,6 +209,13 @@ namespace MWWorld
|
|||
// This method must be called once, after loading all master/plugin files. This can only be done
|
||||
// from the outside, so it must be public.
|
||||
void setUp();
|
||||
|
||||
int countSavedGameRecords() const;
|
||||
|
||||
void write (ESM::ESMWriter& writer) const;
|
||||
|
||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
||||
///< \return Known type?
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/esm/esmwriter.hpp>
|
||||
|
||||
#include "recordcmp.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
|
@ -18,10 +20,16 @@ namespace MWWorld
|
|||
virtual void listIdentifier(std::vector<std::string> &list) const {}
|
||||
|
||||
virtual size_t getSize() const = 0;
|
||||
virtual int getDynamicSize() const { return 0; }
|
||||
virtual void load(ESM::ESMReader &esm, const std::string &id) = 0;
|
||||
|
||||
virtual bool eraseStatic(const std::string &id) {return false;}
|
||||
virtual void clearDynamic() {}
|
||||
|
||||
virtual void write (ESM::ESMWriter& writer) const {}
|
||||
|
||||
virtual void read (ESM::ESMReader& reader) {}
|
||||
///< Read into dynamic storage
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -212,6 +220,11 @@ namespace MWWorld
|
|||
return mShared.size();
|
||||
}
|
||||
|
||||
int getDynamicSize() const
|
||||
{
|
||||
return mDynamic.size();
|
||||
}
|
||||
|
||||
void listIdentifier(std::vector<std::string> &list) const {
|
||||
list.reserve(list.size() + getSize());
|
||||
typename std::vector<T *>::const_iterator it = mShared.begin();
|
||||
|
@ -290,6 +303,26 @@ namespace MWWorld
|
|||
bool erase(const T &item) {
|
||||
return erase(item.mId);
|
||||
}
|
||||
|
||||
void write (ESM::ESMWriter& writer) const
|
||||
{
|
||||
for (typename Dynamic::const_iterator iter (mDynamic.begin()); iter!=mDynamic.end();
|
||||
++iter)
|
||||
{
|
||||
writer.startRecord (T::sRecordId);
|
||||
writer.writeHNString ("NAME", iter->second.mId);
|
||||
iter->second.save (writer);
|
||||
writer.endRecord (T::sRecordId);
|
||||
}
|
||||
}
|
||||
|
||||
void read (ESM::ESMReader& reader)
|
||||
{
|
||||
T record;
|
||||
record.mId = reader.getHNString ("NAME");
|
||||
record.load (reader);
|
||||
insert (record);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -282,7 +282,10 @@ namespace MWWorld
|
|||
mWorldScene->changeToVoid();
|
||||
|
||||
if (mPlayer)
|
||||
{
|
||||
mPlayer->setCell (0);
|
||||
mPlayer->getPlayer().getRefData() = RefData();
|
||||
}
|
||||
|
||||
mStore.clearDynamic();
|
||||
mStore.setUp();
|
||||
|
@ -299,6 +302,25 @@ namespace MWWorld
|
|||
mFacedDistance = FLT_MAX;
|
||||
}
|
||||
|
||||
int World::countSavedGameRecords() const
|
||||
{
|
||||
return mStore.countSavedGameRecords();
|
||||
}
|
||||
|
||||
void World::write (ESM::ESMWriter& writer) const
|
||||
{
|
||||
mStore.write (writer);
|
||||
}
|
||||
|
||||
void World::readRecord (ESM::ESMReader& reader, int32_t type)
|
||||
{
|
||||
if (!mStore.readRecord (reader, type))
|
||||
{
|
||||
/// \todo handle other world state records
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void World::ensureNeededRecords()
|
||||
{
|
||||
if (!mStore.get<ESM::GameSetting>().search("sCompanionShare"))
|
||||
|
|
|
@ -171,6 +171,12 @@ namespace MWWorld
|
|||
|
||||
virtual void clear();
|
||||
|
||||
virtual int countSavedGameRecords() const;
|
||||
|
||||
virtual void write (ESM::ESMWriter& writer) const;
|
||||
|
||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
||||
|
||||
virtual OEngine::Render::Fader* getFader();
|
||||
///< \ŧodo remove this function. Rendering details should not be exposed.
|
||||
|
||||
|
|
Loading…
Reference in a new issue