Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
6.3 kB · 218 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219#include "loadfact.hpp"
#include <stdexcept>
#include "esmreader.hpp"#include "esmwriter.hpp"
#include <components/esm/attr.hpp>#include <components/esm3/loadskil.hpp>
namespace ESM{ ESM::RefId& Faction::FADTstruct::getSkill(size_t index, bool) { return mSkills.at(index); }
ESM::RefId Faction::FADTstruct::getSkill(size_t index, bool) const { return mSkills.at(index); }
void RankData::load(ESMReader& esm) { esm.getT(mAttribute1); esm.getT(mAttribute2); esm.getT(mPrimarySkill); esm.getT(mFavouredSkill); esm.getT(mFactReputation); }
void RankData::save(ESMWriter& esm) const { esm.writeT(mAttribute1); esm.writeT(mAttribute2); esm.writeT(mPrimarySkill); esm.writeT(mFavouredSkill); esm.writeT(mFactReputation); }
void Faction::FADTstruct::load(ESMReader& esm) { esm.getSubHeader(); if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { int32_t attributes[2]; esm.getT(attributes); mAttribute[0] = ESM::Attribute::indexToRefId(attributes[0]); mAttribute[1] = ESM::Attribute::indexToRefId(attributes[1]); for (auto& rank : mRankData) rank.load(esm); int32_t skills[7]; esm.getT(skills); for (std::size_t i = 0; i < std::size(skills); ++i) mSkills[i] = ESM::Skill::indexToRefId(skills[i]); esm.getT(mFlags); } else { for (auto& rank : mRankData) rank.load(esm); esm.getT(mFlags); for (size_t i = 0; i < mAttribute.size() && esm.isNextSub("ATTR"); ++i) mAttribute[i] = esm.getRefId(); for (size_t i = 0; i < mSkills.size() && esm.isNextSub("SKIL"); ++i) mSkills[i] = esm.getRefId(); } }
void Faction::FADTstruct::save(ESMWriter& esm) const { if (esm.getFormatVersion() <= MaxFixedStatsFormatVersion) { esm.startSubRecord("FADT"); esm.writeT(ESM::Attribute::refIdToIndex(mAttribute[0])); esm.writeT(ESM::Attribute::refIdToIndex(mAttribute[1])); for (const auto& rank : mRankData) rank.save(esm); for (const ESM::RefId& id : mSkills) { int32_t skill = ESM::Skill::refIdToIndex(id); esm.writeT(skill); } esm.writeT(mFlags); esm.endRecord("FADT"); } else { esm.startSubRecord("FADT"); for (const auto& rank : mRankData) rank.save(esm); esm.writeT(mFlags); esm.endRecord("FADT"); for (const ESM::RefId& id : mAttribute) esm.writeHNOCRefId("ATTR", id); for (const ESM::RefId& id : mSkills) esm.writeHNOCRefId("SKIL", id); } }
void Faction::load(ESMReader& esm, bool& isDeleted) { isDeleted = false; mRecordFlags = esm.getRecordFlags();
mReactions.clear(); for (auto& rank : mRanks) rank.clear();
size_t rankCounter = 0; bool hasName = false; bool hasData = false; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().toInt()) { case SREC_NAME: mId = esm.getRefId(); hasName = true; break; case fourCC("FNAM"): mName = esm.getHString(); break; case fourCC("RNAM"): if (rankCounter >= mRanks.size()) esm.fail("Rank out of range"); mRanks[rankCounter++] = esm.getHString(); break; case fourCC("FADT"): mData.load(esm); hasData = true; break; case fourCC("ANAM"): { ESM::RefId faction = esm.getRefId(); int32_t reaction; esm.getHNT(reaction, "INTV"); // Prefer the lowest reaction in case a faction is listed multiple times auto it = mReactions.find(faction); if (it == mReactions.end()) mReactions.emplace(faction, reaction); else if (it->second > reaction) it->second = reaction; break; } case SREC_DELE: esm.skipHSub(); isDeleted = true; break; default: esm.fail("Unknown subrecord"); break; } }
if (!hasName) esm.fail("Missing NAME subrecord"); if (!hasData && !isDeleted) esm.fail("Missing FADT subrecord"); }
void Faction::save(ESMWriter& esm, bool isDeleted) const { esm.writeHNCRefId("NAME", mId);
if (isDeleted) { esm.writeHNString("DELE", "", 3); return; }
esm.writeHNOCString("FNAM", mName);
for (const auto& rank : mRanks) { if (rank.empty()) break;
esm.writeHNString("RNAM", rank, 32); }
mData.save(esm);
for (auto it = mReactions.begin(); it != mReactions.end(); ++it) { esm.writeHNRefId("ANAM", it->first); esm.writeHNT("INTV", it->second); } }
void Faction::blank() { mRecordFlags = 0; mName.clear(); mData.mAttribute.fill({}); mData.mFlags = 0;
for (size_t i = 0; i < mData.mRankData.size(); ++i) { mData.mRankData[i].blank(); mRanks[i].clear(); }
mData.mSkills.fill({});
mReactions.clear(); }
void RankData::blank() { mAttribute1 = 0; mAttribute2 = 0; mPrimarySkill = 0; mFavouredSkill = 0; mFactReputation = 0; }}