mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 19:53:53 +00:00
Merge pull request #2845 from akortunov/save_cleanup
Optimize characters data in savegame
This commit is contained in:
commit
7da5558808
5 changed files with 145 additions and 97 deletions
|
@ -17,53 +17,60 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
||||||
mTradeTime.mHour = 0;
|
mTradeTime.mHour = 0;
|
||||||
esm.getHNOT (mTradeTime, "TIME");
|
esm.getHNOT (mTradeTime, "TIME");
|
||||||
|
|
||||||
|
int flags = 0;
|
||||||
mDead = false;
|
mDead = false;
|
||||||
esm.getHNOT (mDead, "DEAD");
|
|
||||||
|
|
||||||
mDeathAnimationFinished = false;
|
mDeathAnimationFinished = false;
|
||||||
esm.getHNOT (mDeathAnimationFinished, "DFNT");
|
|
||||||
|
|
||||||
if (esm.getFormat() < 3 && mDead)
|
|
||||||
mDeathAnimationFinished = true;
|
|
||||||
|
|
||||||
mDied = false;
|
mDied = false;
|
||||||
esm.getHNOT (mDied, "DIED");
|
|
||||||
|
|
||||||
mMurdered = false;
|
mMurdered = false;
|
||||||
esm.getHNOT (mMurdered, "MURD");
|
|
||||||
|
|
||||||
if (esm.isNextSub("FRHT"))
|
|
||||||
esm.skipHSub(); // Friendly hits, no longer used
|
|
||||||
|
|
||||||
mTalkedTo = false;
|
mTalkedTo = false;
|
||||||
esm.getHNOT (mTalkedTo, "TALK");
|
|
||||||
|
|
||||||
mAlarmed = false;
|
mAlarmed = false;
|
||||||
esm.getHNOT (mAlarmed, "ALRM");
|
|
||||||
|
|
||||||
mAttacked = false;
|
mAttacked = false;
|
||||||
esm.getHNOT (mAttacked, "ATKD");
|
|
||||||
|
|
||||||
if (esm.isNextSub("HOST"))
|
|
||||||
esm.skipHSub(); // Hostile, no longer used
|
|
||||||
|
|
||||||
if (esm.isNextSub("ATCK"))
|
|
||||||
esm.skipHSub(); // attackingOrSpell, no longer used
|
|
||||||
|
|
||||||
mKnockdown = false;
|
mKnockdown = false;
|
||||||
esm.getHNOT (mKnockdown, "KNCK");
|
|
||||||
|
|
||||||
mKnockdownOneFrame = false;
|
mKnockdownOneFrame = false;
|
||||||
esm.getHNOT (mKnockdownOneFrame, "KNC1");
|
|
||||||
|
|
||||||
mKnockdownOverOneFrame = false;
|
mKnockdownOverOneFrame = false;
|
||||||
esm.getHNOT (mKnockdownOverOneFrame, "KNCO");
|
|
||||||
|
|
||||||
mHitRecovery = false;
|
mHitRecovery = false;
|
||||||
esm.getHNOT (mHitRecovery, "HITR");
|
|
||||||
|
|
||||||
mBlock = false;
|
mBlock = false;
|
||||||
esm.getHNOT (mBlock, "BLCK");
|
mRecalcDynamicStats = false;
|
||||||
|
if (esm.getFormat() < 8)
|
||||||
|
{
|
||||||
|
esm.getHNOT (mDead, "DEAD");
|
||||||
|
esm.getHNOT (mDeathAnimationFinished, "DFNT");
|
||||||
|
if (esm.getFormat() < 3 && mDead)
|
||||||
|
mDeathAnimationFinished = true;
|
||||||
|
esm.getHNOT (mDied, "DIED");
|
||||||
|
esm.getHNOT (mMurdered, "MURD");
|
||||||
|
if (esm.isNextSub("FRHT"))
|
||||||
|
esm.skipHSub(); // Friendly hits, no longer used
|
||||||
|
esm.getHNOT (mTalkedTo, "TALK");
|
||||||
|
esm.getHNOT (mAlarmed, "ALRM");
|
||||||
|
esm.getHNOT (mAttacked, "ATKD");
|
||||||
|
if (esm.isNextSub("HOST"))
|
||||||
|
esm.skipHSub(); // Hostile, no longer used
|
||||||
|
if (esm.isNextSub("ATCK"))
|
||||||
|
esm.skipHSub(); // attackingOrSpell, no longer used
|
||||||
|
esm.getHNOT (mKnockdown, "KNCK");
|
||||||
|
esm.getHNOT (mKnockdownOneFrame, "KNC1");
|
||||||
|
esm.getHNOT (mKnockdownOverOneFrame, "KNCO");
|
||||||
|
esm.getHNOT (mHitRecovery, "HITR");
|
||||||
|
esm.getHNOT (mBlock, "BLCK");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
esm.getHNOT(flags, "AFLG");
|
||||||
|
mDead = flags & Dead;
|
||||||
|
mDeathAnimationFinished = flags & DeathAnimationFinished;
|
||||||
|
mDied = flags & Died;
|
||||||
|
mMurdered = flags & Murdered;
|
||||||
|
mTalkedTo = flags & TalkedTo;
|
||||||
|
mAlarmed = flags & Alarmed;
|
||||||
|
mAttacked = flags & Attacked;
|
||||||
|
mKnockdown = flags & Knockdown;
|
||||||
|
mKnockdownOneFrame = flags & KnockdownOneFrame;
|
||||||
|
mKnockdownOverOneFrame = flags & KnockdownOverOneFrame;
|
||||||
|
mHitRecovery = flags & HitRecovery;
|
||||||
|
mBlock = flags & Block;
|
||||||
|
mRecalcDynamicStats = flags & RecalcDynamicStats;
|
||||||
|
}
|
||||||
|
|
||||||
mMovementFlags = 0;
|
mMovementFlags = 0;
|
||||||
esm.getHNOT (mMovementFlags, "MOVE");
|
esm.getHNOT (mMovementFlags, "MOVE");
|
||||||
|
@ -78,8 +85,8 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
||||||
|
|
||||||
mLastHitAttemptObject = esm.getHNOString ("LHAT");
|
mLastHitAttemptObject = esm.getHNOString ("LHAT");
|
||||||
|
|
||||||
mRecalcDynamicStats = false;
|
if (esm.getFormat() < 8)
|
||||||
esm.getHNOT (mRecalcDynamicStats, "CALC");
|
esm.getHNOT (mRecalcDynamicStats, "CALC");
|
||||||
|
|
||||||
mDrawState = 0;
|
mDrawState = 0;
|
||||||
esm.getHNOT (mDrawState, "DRAW");
|
esm.getHNOT (mDrawState, "DRAW");
|
||||||
|
@ -90,9 +97,6 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
||||||
mActorId = -1;
|
mActorId = -1;
|
||||||
esm.getHNOT (mActorId, "ACID");
|
esm.getHNOT (mActorId, "ACID");
|
||||||
|
|
||||||
//mHitAttemptActorId = -1;
|
|
||||||
//esm.getHNOT(mHitAttemptActorId, "HAID");
|
|
||||||
|
|
||||||
mDeathAnimation = -1;
|
mDeathAnimation = -1;
|
||||||
esm.getHNOT (mDeathAnimation, "DANM");
|
esm.getHNOT (mDeathAnimation, "DANM");
|
||||||
|
|
||||||
|
@ -134,7 +138,6 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
||||||
|
|
||||||
void ESM::CreatureStats::save (ESMWriter &esm) const
|
void ESM::CreatureStats::save (ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i=0; i<8; ++i)
|
for (int i=0; i<8; ++i)
|
||||||
mAttributes[i].save (esm);
|
mAttributes[i].save (esm);
|
||||||
|
|
||||||
|
@ -147,41 +150,23 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
||||||
if (mTradeTime.mDay != 0 || mTradeTime.mHour != 0)
|
if (mTradeTime.mDay != 0 || mTradeTime.mHour != 0)
|
||||||
esm.writeHNT ("TIME", mTradeTime);
|
esm.writeHNT ("TIME", mTradeTime);
|
||||||
|
|
||||||
if (mDead)
|
int flags = 0;
|
||||||
esm.writeHNT ("DEAD", mDead);
|
if (mDead) flags |= Dead;
|
||||||
|
if (mDeathAnimationFinished) flags |= DeathAnimationFinished;
|
||||||
|
if (mDied) flags |= Died;
|
||||||
|
if (mMurdered) flags |= Murdered;
|
||||||
|
if (mTalkedTo) flags |= TalkedTo;
|
||||||
|
if (mAlarmed) flags |= Alarmed;
|
||||||
|
if (mAttacked) flags |= Attacked;
|
||||||
|
if (mKnockdown) flags |= Knockdown;
|
||||||
|
if (mKnockdownOneFrame) flags |= KnockdownOneFrame;
|
||||||
|
if (mKnockdownOverOneFrame) flags |= KnockdownOverOneFrame;
|
||||||
|
if (mHitRecovery) flags |= HitRecovery;
|
||||||
|
if (mBlock) flags |= Block;
|
||||||
|
if (mRecalcDynamicStats) flags |= RecalcDynamicStats;
|
||||||
|
|
||||||
if (mDeathAnimationFinished)
|
if (flags)
|
||||||
esm.writeHNT ("DFNT", mDeathAnimationFinished);
|
esm.writeHNT ("AFLG", flags);
|
||||||
|
|
||||||
if (mDied)
|
|
||||||
esm.writeHNT ("DIED", mDied);
|
|
||||||
|
|
||||||
if (mMurdered)
|
|
||||||
esm.writeHNT ("MURD", mMurdered);
|
|
||||||
|
|
||||||
if (mTalkedTo)
|
|
||||||
esm.writeHNT ("TALK", mTalkedTo);
|
|
||||||
|
|
||||||
if (mAlarmed)
|
|
||||||
esm.writeHNT ("ALRM", mAlarmed);
|
|
||||||
|
|
||||||
if (mAttacked)
|
|
||||||
esm.writeHNT ("ATKD", mAttacked);
|
|
||||||
|
|
||||||
if (mKnockdown)
|
|
||||||
esm.writeHNT ("KNCK", mKnockdown);
|
|
||||||
|
|
||||||
if (mKnockdownOneFrame)
|
|
||||||
esm.writeHNT ("KNC1", mKnockdownOneFrame);
|
|
||||||
|
|
||||||
if (mKnockdownOverOneFrame)
|
|
||||||
esm.writeHNT ("KNCO", mKnockdownOverOneFrame);
|
|
||||||
|
|
||||||
if (mHitRecovery)
|
|
||||||
esm.writeHNT ("HITR", mHitRecovery);
|
|
||||||
|
|
||||||
if (mBlock)
|
|
||||||
esm.writeHNT ("BLCK", mBlock);
|
|
||||||
|
|
||||||
if (mMovementFlags)
|
if (mMovementFlags)
|
||||||
esm.writeHNT ("MOVE", mMovementFlags);
|
esm.writeHNT ("MOVE", mMovementFlags);
|
||||||
|
@ -195,9 +180,6 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
||||||
if (!mLastHitAttemptObject.empty())
|
if (!mLastHitAttemptObject.empty())
|
||||||
esm.writeHNString ("LHAT", mLastHitAttemptObject);
|
esm.writeHNString ("LHAT", mLastHitAttemptObject);
|
||||||
|
|
||||||
if (mRecalcDynamicStats)
|
|
||||||
esm.writeHNT ("CALC", mRecalcDynamicStats);
|
|
||||||
|
|
||||||
if (mDrawState)
|
if (mDrawState)
|
||||||
esm.writeHNT ("DRAW", mDrawState);
|
esm.writeHNT ("DRAW", mDrawState);
|
||||||
|
|
||||||
|
@ -207,13 +189,10 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
||||||
if (mActorId != -1)
|
if (mActorId != -1)
|
||||||
esm.writeHNT ("ACID", mActorId);
|
esm.writeHNT ("ACID", mActorId);
|
||||||
|
|
||||||
//if (mHitAttemptActorId != -1)
|
|
||||||
// esm.writeHNT("HAID", mHitAttemptActorId);
|
|
||||||
|
|
||||||
if (mDeathAnimation != -1)
|
if (mDeathAnimation != -1)
|
||||||
esm.writeHNT ("DANM", mDeathAnimation);
|
esm.writeHNT ("DANM", mDeathAnimation);
|
||||||
|
|
||||||
if (mTimeOfDeath.mHour != 0 && mTimeOfDeath.mDay != 0)
|
if (mTimeOfDeath.mHour != 0 || mTimeOfDeath.mDay != 0)
|
||||||
esm.writeHNT ("DTIM", mTimeOfDeath);
|
esm.writeHNT ("DTIM", mTimeOfDeath);
|
||||||
|
|
||||||
mSpells.save(esm);
|
mSpells.save(esm);
|
||||||
|
@ -247,7 +226,6 @@ void ESM::CreatureStats::blank()
|
||||||
mTradeTime.mDay = 0;
|
mTradeTime.mDay = 0;
|
||||||
mGoldPool = 0;
|
mGoldPool = 0;
|
||||||
mActorId = -1;
|
mActorId = -1;
|
||||||
//mHitAttemptActorId = -1;
|
|
||||||
mHasAiSettings = false;
|
mHasAiSettings = false;
|
||||||
mDead = false;
|
mDead = false;
|
||||||
mDeathAnimationFinished = false;
|
mDeathAnimationFinished = false;
|
||||||
|
|
|
@ -40,6 +40,22 @@ namespace ESM
|
||||||
int mActorId;
|
int mActorId;
|
||||||
//int mHitAttemptActorId;
|
//int mHitAttemptActorId;
|
||||||
|
|
||||||
|
enum Flags
|
||||||
|
{
|
||||||
|
Dead = 0x0001,
|
||||||
|
DeathAnimationFinished = 0x0002,
|
||||||
|
Died = 0x0004,
|
||||||
|
Murdered = 0x0008,
|
||||||
|
TalkedTo = 0x0010,
|
||||||
|
Alarmed = 0x0020,
|
||||||
|
Attacked = 0x0040,
|
||||||
|
Knockdown = 0x0080,
|
||||||
|
KnockdownOneFrame = 0x0100,
|
||||||
|
KnockdownOverOneFrame = 0x0200,
|
||||||
|
HitRecovery = 0x0400,
|
||||||
|
Block = 0x0800,
|
||||||
|
RecalcDynamicStats = 0x1000
|
||||||
|
};
|
||||||
bool mDead;
|
bool mDead;
|
||||||
bool mDeathAnimationFinished;
|
bool mDeathAnimationFinished;
|
||||||
bool mDied;
|
bool mDied;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
void ESM::InventoryState::load (ESMReader &esm)
|
void ESM::InventoryState::load (ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
// obsolete
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (esm.isNextSub ("IOBJ"))
|
while (esm.isNextSub ("IOBJ"))
|
||||||
{
|
{
|
||||||
|
@ -31,6 +32,22 @@ void ESM::InventoryState::load (ESMReader &esm)
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int itemsCount = 0;
|
||||||
|
esm.getHNOT(itemsCount, "ICNT");
|
||||||
|
for (int i = 0; i < itemsCount; i++)
|
||||||
|
{
|
||||||
|
ObjectState state;
|
||||||
|
|
||||||
|
state.mRef.loadId(esm, true);
|
||||||
|
state.load (esm);
|
||||||
|
|
||||||
|
if (state.mCount == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mItems.push_back (state);
|
||||||
|
}
|
||||||
|
|
||||||
//Next item is Levelled item
|
//Next item is Levelled item
|
||||||
while (esm.isNextSub("LEVM"))
|
while (esm.isNextSub("LEVM"))
|
||||||
{
|
{
|
||||||
|
@ -72,18 +89,35 @@ void ESM::InventoryState::load (ESMReader &esm)
|
||||||
mEquipmentSlots[equipIndex] = slot;
|
mEquipmentSlots[equipIndex] = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esm.isNextSub("EQIP"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
int slotsCount = 0;
|
||||||
|
esm.getT(slotsCount);
|
||||||
|
for (int i = 0; i < slotsCount; i++)
|
||||||
|
{
|
||||||
|
int equipIndex;
|
||||||
|
esm.getT(equipIndex);
|
||||||
|
int slot;
|
||||||
|
esm.getT(slot);
|
||||||
|
mEquipmentSlots[equipIndex] = slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mSelectedEnchantItem = -1;
|
mSelectedEnchantItem = -1;
|
||||||
esm.getHNOT(mSelectedEnchantItem, "SELE");
|
esm.getHNOT(mSelectedEnchantItem, "SELE");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::InventoryState::save (ESMWriter &esm) const
|
void ESM::InventoryState::save (ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
for (std::vector<ObjectState>::const_iterator iter (mItems.begin()); iter!=mItems.end(); ++iter)
|
int itemsCount = static_cast<int>(mItems.size());
|
||||||
|
if (itemsCount > 0)
|
||||||
{
|
{
|
||||||
int unused = 0;
|
esm.writeHNT ("ICNT", itemsCount);
|
||||||
esm.writeHNT ("IOBJ", unused);
|
for (const ObjectState& state : mItems)
|
||||||
|
{
|
||||||
iter->save (esm, true);
|
state.save (esm, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<std::pair<std::string, std::string>, int>::const_iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end(); ++it)
|
for (std::map<std::pair<std::string, std::string>, int>::const_iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end(); ++it)
|
||||||
|
@ -105,12 +139,17 @@ void ESM::InventoryState::save (ESMWriter &esm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<int, int>::const_iterator it = mEquipmentSlots.begin(); it != mEquipmentSlots.end(); ++it)
|
int slotsCount = static_cast<int>(mEquipmentSlots.size());
|
||||||
|
if (slotsCount > 0)
|
||||||
{
|
{
|
||||||
esm.startSubRecord("EQUI");
|
esm.startSubRecord("EQIP");
|
||||||
esm.writeT(it->first);
|
esm.writeT(slotsCount);
|
||||||
esm.writeT(it->second);
|
for (std::map<int, int>::const_iterator it = mEquipmentSlots.begin(); it != mEquipmentSlots.end(); ++it)
|
||||||
esm.endRecord("EQUI");
|
{
|
||||||
|
esm.writeT(it->first);
|
||||||
|
esm.writeT(it->second);
|
||||||
|
}
|
||||||
|
esm.endRecord("EQIP");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSelectedEnchantItem != -1)
|
if (mSelectedEnchantItem != -1)
|
||||||
|
|
|
@ -35,7 +35,7 @@ void ESM::NpcStats::load (ESMReader &esm)
|
||||||
mSkills[i].load (esm);
|
mSkills[i].load (esm);
|
||||||
|
|
||||||
mWerewolfDeprecatedData = false;
|
mWerewolfDeprecatedData = false;
|
||||||
if (esm.peekNextSub("STBA"))
|
if (esm.getFormat() < 8 && esm.peekNextSub("STBA"))
|
||||||
{
|
{
|
||||||
// we have deprecated werewolf skills, stored interleaved
|
// we have deprecated werewolf skills, stored interleaved
|
||||||
// Load into one big vector, then remove every 2nd value
|
// Load into one big vector, then remove every 2nd value
|
||||||
|
@ -95,7 +95,9 @@ void ESM::NpcStats::load (ESMReader &esm)
|
||||||
mLevelProgress = 0;
|
mLevelProgress = 0;
|
||||||
esm.getHNOT (mLevelProgress, "LPRO");
|
esm.getHNOT (mLevelProgress, "LPRO");
|
||||||
|
|
||||||
esm.getHNT (mSkillIncrease, "INCR");
|
for (int i = 0; i < 8; ++i)
|
||||||
|
mSkillIncrease[i] = 0;
|
||||||
|
esm.getHNOT (mSkillIncrease, "INCR");
|
||||||
|
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
mSpecIncreases[i] = 0;
|
mSpecIncreases[i] = 0;
|
||||||
|
@ -160,8 +162,21 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
||||||
if (mLevelProgress)
|
if (mLevelProgress)
|
||||||
esm.writeHNT ("LPRO", mLevelProgress);
|
esm.writeHNT ("LPRO", mLevelProgress);
|
||||||
|
|
||||||
esm.writeHNT ("INCR", mSkillIncrease);
|
bool saveSkillIncreases = false;
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
if (mSkillIncrease[i] != 0)
|
||||||
|
{
|
||||||
|
saveSkillIncreases = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (saveSkillIncreases)
|
||||||
|
esm.writeHNT ("INCR", mSkillIncrease);
|
||||||
|
|
||||||
|
if (mSpecIncreases[0] != 0 ||
|
||||||
|
mSpecIncreases[1] != 0 ||
|
||||||
|
mSpecIncreases[2] != 0)
|
||||||
esm.writeHNT ("SPEC", mSpecIncreases);
|
esm.writeHNT ("SPEC", mSpecIncreases);
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator iter (mUsedIds.begin()); iter!=mUsedIds.end();
|
for (std::vector<std::string>::const_iterator iter (mUsedIds.begin()); iter!=mUsedIds.end();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "defs.hpp"
|
#include "defs.hpp"
|
||||||
|
|
||||||
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
|
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
|
||||||
int ESM::SavedGame::sCurrentFormat = 7;
|
int ESM::SavedGame::sCurrentFormat = 8;
|
||||||
|
|
||||||
void ESM::SavedGame::load (ESMReader &esm)
|
void ESM::SavedGame::load (ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue