Optimize characters data in savegame

pull/2845/head
Andrei Kortunov 5 years ago
parent 019c843589
commit e6ca95174a

@ -17,53 +17,60 @@ void ESM::CreatureStats::load (ESMReader &esm)
mTradeTime.mHour = 0;
esm.getHNOT (mTradeTime, "TIME");
int flags = 0;
mDead = false;
esm.getHNOT (mDead, "DEAD");
mDeathAnimationFinished = false;
esm.getHNOT (mDeathAnimationFinished, "DFNT");
if (esm.getFormat() < 3 && mDead)
mDeathAnimationFinished = true;
mDied = false;
esm.getHNOT (mDied, "DIED");
mMurdered = false;
esm.getHNOT (mMurdered, "MURD");
if (esm.isNextSub("FRHT"))
esm.skipHSub(); // Friendly hits, no longer used
mTalkedTo = false;
esm.getHNOT (mTalkedTo, "TALK");
mAlarmed = false;
esm.getHNOT (mAlarmed, "ALRM");
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;
esm.getHNOT (mKnockdown, "KNCK");
mKnockdownOneFrame = false;
esm.getHNOT (mKnockdownOneFrame, "KNC1");
mKnockdownOverOneFrame = false;
esm.getHNOT (mKnockdownOverOneFrame, "KNCO");
mHitRecovery = false;
esm.getHNOT (mHitRecovery, "HITR");
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;
esm.getHNOT (mMovementFlags, "MOVE");
@ -78,8 +85,8 @@ void ESM::CreatureStats::load (ESMReader &esm)
mLastHitAttemptObject = esm.getHNOString ("LHAT");
mRecalcDynamicStats = false;
esm.getHNOT (mRecalcDynamicStats, "CALC");
if (esm.getFormat() < 8)
esm.getHNOT (mRecalcDynamicStats, "CALC");
mDrawState = 0;
esm.getHNOT (mDrawState, "DRAW");
@ -90,9 +97,6 @@ void ESM::CreatureStats::load (ESMReader &esm)
mActorId = -1;
esm.getHNOT (mActorId, "ACID");
//mHitAttemptActorId = -1;
//esm.getHNOT(mHitAttemptActorId, "HAID");
mDeathAnimation = -1;
esm.getHNOT (mDeathAnimation, "DANM");
@ -134,7 +138,6 @@ void ESM::CreatureStats::load (ESMReader &esm)
void ESM::CreatureStats::save (ESMWriter &esm) const
{
for (int i=0; i<8; ++i)
mAttributes[i].save (esm);
@ -147,41 +150,23 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
if (mTradeTime.mDay != 0 || mTradeTime.mHour != 0)
esm.writeHNT ("TIME", mTradeTime);
if (mDead)
esm.writeHNT ("DEAD", mDead);
if (mDeathAnimationFinished)
esm.writeHNT ("DFNT", mDeathAnimationFinished);
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);
int flags = 0;
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 (flags)
esm.writeHNT ("AFLG", flags);
if (mMovementFlags)
esm.writeHNT ("MOVE", mMovementFlags);
@ -195,9 +180,6 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
if (!mLastHitAttemptObject.empty())
esm.writeHNString ("LHAT", mLastHitAttemptObject);
if (mRecalcDynamicStats)
esm.writeHNT ("CALC", mRecalcDynamicStats);
if (mDrawState)
esm.writeHNT ("DRAW", mDrawState);
@ -207,13 +189,10 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
if (mActorId != -1)
esm.writeHNT ("ACID", mActorId);
//if (mHitAttemptActorId != -1)
// esm.writeHNT("HAID", mHitAttemptActorId);
if (mDeathAnimation != -1)
esm.writeHNT ("DANM", mDeathAnimation);
if (mTimeOfDeath.mHour != 0 && mTimeOfDeath.mDay != 0)
if (mTimeOfDeath.mHour != 0 || mTimeOfDeath.mDay != 0)
esm.writeHNT ("DTIM", mTimeOfDeath);
mSpells.save(esm);
@ -247,7 +226,6 @@ void ESM::CreatureStats::blank()
mTradeTime.mDay = 0;
mGoldPool = 0;
mActorId = -1;
//mHitAttemptActorId = -1;
mHasAiSettings = false;
mDead = false;
mDeathAnimationFinished = false;

@ -40,6 +40,22 @@ namespace ESM
int mActorId;
//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 mDeathAnimationFinished;
bool mDied;

@ -5,6 +5,7 @@
void ESM::InventoryState::load (ESMReader &esm)
{
// obsolete
int index = 0;
while (esm.isNextSub ("IOBJ"))
{
@ -31,6 +32,22 @@ void ESM::InventoryState::load (ESMReader &esm)
++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
while (esm.isNextSub("LEVM"))
{
@ -72,18 +89,35 @@ void ESM::InventoryState::load (ESMReader &esm)
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;
esm.getHNOT(mSelectedEnchantItem, "SELE");
}
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 ("IOBJ", unused);
iter->save (esm, true);
esm.writeHNT ("ICNT", itemsCount);
for (const ObjectState& state : mItems)
{
state.save (esm, true);
}
}
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.writeT(it->first);
esm.writeT(it->second);
esm.endRecord("EQUI");
esm.startSubRecord("EQIP");
esm.writeT(slotsCount);
for (std::map<int, int>::const_iterator it = mEquipmentSlots.begin(); it != mEquipmentSlots.end(); ++it)
{
esm.writeT(it->first);
esm.writeT(it->second);
}
esm.endRecord("EQIP");
}
if (mSelectedEnchantItem != -1)

@ -35,7 +35,7 @@ void ESM::NpcStats::load (ESMReader &esm)
mSkills[i].load (esm);
mWerewolfDeprecatedData = false;
if (esm.peekNextSub("STBA"))
if (esm.getFormat() < 8 && esm.peekNextSub("STBA"))
{
// we have deprecated werewolf skills, stored interleaved
// Load into one big vector, then remove every 2nd value
@ -95,7 +95,9 @@ void ESM::NpcStats::load (ESMReader &esm)
mLevelProgress = 0;
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)
mSpecIncreases[i] = 0;
@ -160,8 +162,21 @@ void ESM::NpcStats::save (ESMWriter &esm) const
if (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);
for (std::vector<std::string>::const_iterator iter (mUsedIds.begin()); iter!=mUsedIds.end();

@ -5,7 +5,7 @@
#include "defs.hpp"
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
int ESM::SavedGame::sCurrentFormat = 7;
int ESM::SavedGame::sCurrentFormat = 8;
void ESM::SavedGame::load (ESMReader &esm)
{

Loading…
Cancel
Save