Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
6.6 kB · 236 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237#include "npcstats.hpp"
#include "esmreader.hpp"#include "esmwriter.hpp"
namespace ESM{
NpcStats::Faction::Faction() : mExpelled(false) , mRank(-1) , mReputation(0) { }
void NpcStats::load(ESMReader& esm) { while (esm.isNextSub("FACT")) { ESM::RefId id = esm.getRefId();
Faction faction;
int32_t expelled = 0; esm.getHNOT(expelled, "FAEX");
if (expelled) faction.mExpelled = true;
esm.getHNOT(faction.mRank, "FARA");
esm.getHNOT(faction.mReputation, "FARE");
mFactions.emplace(id, faction); }
mDisposition = 0; esm.getHNOT(mDisposition, "DISP");
mCrimeDispositionModifier = 0; esm.getHNOT(mCrimeDispositionModifier, "DISM");
if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { const bool intFallback = esm.getFormatVersion() <= MaxIntFallbackFormatVersion; for (int i = 0; i < ESM::Skill::Length; ++i) mSkills[ESM::Skill::indexToRefId(i)].load(esm, intFallback); } else { while (esm.isNextSub("SKIL")) { ESM::RefId skill = esm.getRefId(); mSkills[skill].load(esm); } }
mIsWerewolf = false; esm.getHNOT(mIsWerewolf, "WOLF");
mBounty = 0; esm.getHNOT(mBounty, "BOUN");
mReputation = 0; esm.getHNOT(mReputation, "REPU");
mWerewolfKills = 0; esm.getHNOT(mWerewolfKills, "WKIL");
mLevelProgress = 0; esm.getHNOT(mLevelProgress, "LPRO");
mSkillIncrease.clear(); if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { std::array<int32_t, ESM::Attribute::Length> increases; if (esm.getHNOT("INCR", increases)) { for (int i = 0; i < ESM::Attribute::Length; ++i) mSkillIncrease[ESM::Attribute::indexToRefId(i)] = increases[i]; } } else { while (esm.isNextSub("INCR")) { esm.getSubHeader(); int32_t value; esm.getT(value); ESM::RefId attribute = esm.getRefId(esm.getSubSize() - sizeof(value)); mSkillIncrease[attribute] = value; } }
mSpecIncreases.fill(0); esm.getHNOT(mSpecIncreases, "SPEC");
while (esm.isNextSub("USED")) mUsedIds.push_back(esm.getRefId());
mTimeToStartDrowning = 0; esm.getHNOT(mTimeToStartDrowning, "DRTI");
mCrimeId = -1; esm.getHNOT(mCrimeId, "CRID"); }
void NpcStats::save(ESMWriter& esm) const { for (const auto& [id, faction] : mFactions) { esm.writeHNRefId("FACT", id);
if (faction.mExpelled) { int32_t expelled = 1; esm.writeHNT("FAEX", expelled); }
if (faction.mRank >= 0) esm.writeHNT("FARA", faction.mRank);
if (faction.mReputation) esm.writeHNT("FARE", faction.mReputation); }
if (mDisposition) esm.writeHNT("DISP", mDisposition);
if (mCrimeDispositionModifier) esm.writeHNT("DISM", mCrimeDispositionModifier);
if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { // This branch is only used in tests. It probably shouldn't exist. for (int i = 0; i < ESM::Skill::Length; ++i) { const auto it = mSkills.find(ESM::Skill::indexToRefId(i)); if (it != mSkills.end()) it->second.save(esm); else StatState<float>{}.save(esm); } } else { for (const auto& [skill, value] : mSkills) { esm.writeHNRefId("SKIL", skill); value.save(esm); } }
if (mIsWerewolf) esm.writeHNT("WOLF", mIsWerewolf);
if (mBounty) esm.writeHNT("BOUN", mBounty);
if (mReputation) esm.writeHNT("REPU", mReputation);
if (mWerewolfKills) esm.writeHNT("WKIL", mWerewolfKills);
if (mLevelProgress) esm.writeHNT("LPRO", mLevelProgress);
if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { // This branch is only used in tests. It probably shouldn't exist. bool saveSkillIncreases = false; for (const auto& [id, increase] : mSkillIncrease) { if (increase != 0) { saveSkillIncreases = true; break; } } if (saveSkillIncreases) { esm.startSubRecord("INCR"); for (int i = 0; i < ESM::Attribute::Length; ++i) { int32_t increase = 0; const auto it = mSkillIncrease.find(ESM::Attribute::indexToRefId(i)); if (it != mSkillIncrease.end()) increase = it->second; esm.writeT(increase); } esm.endRecord("INCR"); } } else { for (const auto& [id, increase] : mSkillIncrease) { if (id.empty() || increase == 0) continue; esm.startSubRecord("INCR"); esm.writeT(increase); esm.writeHRefId(id); esm.endRecord("INCR"); } }
if (mSpecIncreases[0] != 0 || mSpecIncreases[1] != 0 || mSpecIncreases[2] != 0) esm.writeHNT("SPEC", mSpecIncreases);
for (const RefId& id : mUsedIds) esm.writeHNRefId("USED", id);
if (mTimeToStartDrowning) esm.writeHNT("DRTI", mTimeToStartDrowning);
if (mCrimeId != -1) esm.writeHNT("CRID", mCrimeId); }
void NpcStats::blank() { mIsWerewolf = false; mDisposition = 0; mCrimeDispositionModifier = 0; mBounty = 0; mReputation = 0; mWerewolfKills = 0; mLevelProgress = 0; mSkillIncrease.clear(); mSpecIncreases.fill(0); mTimeToStartDrowning = 20; mCrimeId = -1; }
}