1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-10 12:39:53 +00:00
OpenMW/components/esm3/npcstats.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

216 lines
5.7 KiB
C++
Raw Normal View History

#include <cassert>
2014-02-16 15:06:34 +01:00
#include "npcstats.hpp"
#include "esmreader.hpp"
#include "esmwriter.hpp"
namespace ESM
{
NpcStats::Faction::Faction()
: mExpelled(false)
, mRank(-1)
, mReputation(0)
2014-02-16 15:06:34 +01:00
{
2022-09-22 21:26:05 +03:00
}
2014-02-16 15:06:34 +01:00
void NpcStats::load(ESMReader& esm)
2022-09-22 21:26:05 +03:00
{
2014-02-16 15:06:34 +01:00
while (esm.isNextSub("FACT"))
2022-09-22 21:26:05 +03:00
{
2014-02-16 15:06:34 +01:00
std::string id = esm.getHString();
Faction faction;
int expelled = 0;
esm.getHNOT(expelled, "FAEX");
if (expelled)
faction.mExpelled = true;
esm.getHNOT(faction.mRank, "FARA");
esm.getHNOT(faction.mReputation, "FARE");
mFactions.insert(std::make_pair(id, faction));
2022-09-22 21:26:05 +03:00
}
2014-02-16 15:06:34 +01:00
mDisposition = 0;
esm.getHNOT(mDisposition, "DISP");
2020-05-14 19:45:35 +04:00
bool intFallback = esm.getFormat() < 11;
for (int i = 0; i < 27; ++i)
mSkills[i].load(esm, intFallback);
mWerewolfDeprecatedData = false;
if (esm.getFormat() < 8 && esm.peekNextSub("STBA"))
{
// we have deprecated werewolf skills, stored interleaved
// Load into one big vector, then remove every 2nd value
mWerewolfDeprecatedData = true;
std::vector<StatState<float>> skills(mSkills, mSkills + sizeof(mSkills) / sizeof(mSkills[0]));
2022-09-22 21:26:05 +03:00
2020-05-14 19:45:35 +04:00
for (int i = 0; i < 27; ++i)
2022-09-22 21:26:05 +03:00
{
StatState<float> skill;
skill.load(esm, intFallback);
skills.push_back(skill);
2022-09-22 21:26:05 +03:00
}
2020-05-14 19:45:35 +04:00
int i = 0;
for (std::vector<StatState<float>>::iterator it = skills.begin(); it != skills.end(); ++i)
2022-09-22 21:26:05 +03:00
{
if (i % 2 == 1)
it = skills.erase(it);
2022-09-22 21:26:05 +03:00
else
++it;
}
assert(skills.size() == 27);
std::copy(skills.begin(), skills.end(), mSkills);
}
// No longer used
bool hasWerewolfAttributes = false;
esm.getHNOT(hasWerewolfAttributes, "HWAT");
if (hasWerewolfAttributes)
{
StatState<int> dummy;
for (int i = 0; i < 8; ++i)
dummy.load(esm, intFallback);
mWerewolfDeprecatedData = true;
}
2014-02-16 15:06:34 +01:00
2014-05-12 21:04:02 +02:00
mIsWerewolf = false;
esm.getHNOT(mIsWerewolf, "WOLF");
mBounty = 0;
esm.getHNOT(mBounty, "BOUN");
2014-02-16 15:06:34 +01:00
mReputation = 0;
esm.getHNOT(mReputation, "REPU");
mWerewolfKills = 0;
esm.getHNOT(mWerewolfKills, "WKIL");
// No longer used
if (esm.isNextSub("PROF"))
esm.skipHSub(); // int profit
// No longer used
if (esm.isNextSub("ASTR"))
esm.skipHSub(); // attackStrength
2014-02-16 15:06:34 +01:00
mLevelProgress = 0;
esm.getHNOT(mLevelProgress, "LPRO");
2014-02-16 15:06:34 +01:00
2020-05-14 19:45:35 +04:00
for (int i = 0; i < 8; ++i)
2014-02-16 15:06:34 +01:00
mSkillIncrease[i] = 0;
esm.getHNOT(mSkillIncrease, "INCR");
2020-05-14 19:45:35 +04:00
for (int i = 0; i < 3; ++i)
mSpecIncreases[i] = 0;
esm.getHNOT(mSpecIncreases, "SPEC");
2014-02-16 15:06:34 +01:00
while (esm.isNextSub("USED"))
mUsedIds.push_back(esm.getHString());
2014-02-16 15:06:34 +01:00
mTimeToStartDrowning = 0;
esm.getHNOT(mTimeToStartDrowning, "DRTI");
// No longer used
2014-02-16 15:06:34 +01:00
float lastDrowningHit = 0;
esm.getHNOT(lastDrowningHit, "DRLH");
2015-01-16 04:55:42 +01:00
// No longer used
float levelHealthBonus = 0;
esm.getHNOT(levelHealthBonus, "LVLH");
2014-02-16 15:06:34 +01:00
mCrimeId = -1;
esm.getHNOT(mCrimeId, "CRID");
2014-02-16 15:06:34 +01:00
}
void NpcStats::save(ESMWriter& esm) const
2014-02-16 15:06:34 +01:00
{
for (std::map<std::string, Faction>::const_iterator iter(mFactions.begin()); iter != mFactions.end(); ++iter)
{
esm.writeHNString("FACT", iter->first);
if (iter->second.mExpelled)
2022-09-22 21:26:05 +03:00
{
2014-02-16 15:06:34 +01:00
int expelled = 1;
esm.writeHNT("FAEX", expelled);
2022-09-22 21:26:05 +03:00
}
2014-02-16 15:06:34 +01:00
if (iter->second.mRank >= 0)
esm.writeHNT("FARA", iter->second.mRank);
if (iter->second.mReputation)
esm.writeHNT("FARE", iter->second.mReputation);
2022-09-22 21:26:05 +03:00
}
2014-02-16 15:06:34 +01:00
if (mDisposition)
esm.writeHNT("DISP", mDisposition);
2014-02-16 15:06:34 +01:00
2014-05-12 21:04:02 +02:00
for (int i = 0; i < 27; ++i)
mSkills[i].save(esm);
2014-02-16 15:06:34 +01:00
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);
2022-09-22 21:26:05 +03:00
2020-05-14 19:45:35 +04:00
bool saveSkillIncreases = false;
for (int i = 0; i < 8; ++i)
{
if (mSkillIncrease[i] != 0)
2022-09-22 21:26:05 +03:00
{
2020-05-14 19:45:35 +04:00
saveSkillIncreases = true;
break;
2022-09-22 21:26:05 +03:00
}
2020-05-14 19:45:35 +04:00
}
if (saveSkillIncreases)
esm.writeHNT("INCR", mSkillIncrease);
2014-02-16 15:06:34 +01:00
2020-05-14 19:45:35 +04:00
if (mSpecIncreases[0] != 0 || mSpecIncreases[1] != 0 || mSpecIncreases[2] != 0)
esm.writeHNT("SPEC", mSpecIncreases);
2014-02-16 15:06:34 +01:00
for (std::vector<std::string>::const_iterator iter(mUsedIds.begin()); iter != mUsedIds.end(); ++iter)
esm.writeHNString("USED", *iter);
2014-02-16 15:06:34 +01:00
if (mTimeToStartDrowning)
esm.writeHNT("DRTI", mTimeToStartDrowning);
if (mCrimeId != -1)
esm.writeHNT("CRID", mCrimeId);
2014-05-12 21:04:02 +02:00
}
void NpcStats::blank()
{
mWerewolfDeprecatedData = false;
mIsWerewolf = false;
mDisposition = 0;
mBounty = 0;
mReputation = 0;
mWerewolfKills = 0;
mLevelProgress = 0;
for (int i = 0; i < 8; ++i)
mSkillIncrease[i] = 0;
for (int i = 0; i < 3; ++i)
mSpecIncreases[i] = 0;
mTimeToStartDrowning = 20;
mCrimeId = -1;
}
}