Skip to content

Commit

Permalink
Optimize characters data in savegame
Browse files Browse the repository at this point in the history
  • Loading branch information
akortunov committed May 14, 2020
1 parent 019c843 commit 1f41206
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 112 deletions.
1 change: 0 additions & 1 deletion apps/essimporter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ namespace
if (cellref.mDeleted)
objstate.mCount = 0;
convertSCRI(cellref.mSCRI, objstate.mLocals);
objstate.mHasLocals = !objstate.mLocals.mVariables.empty();

if (cellref.mHasANIS)
convertANIS(cellref.mANIS, objstate.mAnimationState);
Expand Down
2 changes: 1 addition & 1 deletion apps/openmw/mwworld/livecellref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state)

Ptr ptr (this);

if (state.mHasLocals)
if (state.mLocals.mVariables.size() > 0)
{
std::string scriptId = mClass->getScript (ptr);
// Make sure we still have a script. It could have been coming from a content file that is no longer active.
Expand Down
2 changes: 1 addition & 1 deletion apps/openmw/mwworld/refdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace MWWorld

void RefData::write (ESM::ObjectState& objectState, const std::string& scriptId) const
{
objectState.mHasLocals = mLocals.write (objectState.mLocals, scriptId);
mLocals.write (objectState.mLocals, scriptId);

objectState.mEnabled = mEnabled;
objectState.mCount = mCount;
Expand Down
146 changes: 62 additions & 84 deletions components/esm/creaturestats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand All @@ -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");

Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -247,7 +226,6 @@ void ESM::CreatureStats::blank()
mTradeTime.mDay = 0;
mGoldPool = 0;
mActorId = -1;
//mHitAttemptActorId = -1;
mHasAiSettings = false;
mDead = false;
mDeathAnimationFinished = false;
Expand Down
16 changes: 16 additions & 0 deletions components/esm/creaturestats.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
59 changes: 49 additions & 10 deletions components/esm/inventorystate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

void ESM::InventoryState::load (ESMReader &esm)
{
// obsolete
int index = 0;
while (esm.isNextSub ("IOBJ"))
{
Expand All @@ -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"))
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Loading

0 comments on commit 1f41206

Please sign in to comment.