diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 900c28164f..519d3b8f06 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -775,14 +775,13 @@ namespace EsmTool { std::cout << " Name: " << mData.mName << std::endl; std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; - std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) << " (" << mData.mData.mAttribute[0] - << ")" << std::endl; - std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) << " (" << mData.mData.mAttribute[1] - << ")" << std::endl; + for (size_t i = 0; i < mData.mData.mAttribute.size(); ++i) + std::cout << " Attribute" << (i + 1) << ": " << attributeLabel(mData.mData.mAttribute[i]) << " (" + << mData.mData.mAttribute[i] << ")" << std::endl; for (int skill : mData.mData.mSkills) if (skill != -1) std::cout << " Skill: " << skillLabel(skill) << " (" << skill << ")" << std::endl; - for (int i = 0; i != 10; i++) + for (int i = 0; i != mData.mData.mRankData.size(); i++) if (!mData.mRanks[i].empty()) { std::cout << " Rank: " << mData.mRanks[i] << std::endl; diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index fb4c057879..69b790e659 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -46,17 +46,30 @@ void CSMTools::FactionCheckStage::perform(int stage, CSMDoc::Messages& messages) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // test for invalid attributes - if (faction.mData.mAttribute[0] == faction.mData.mAttribute[1] && faction.mData.mAttribute[0] != -1) + std::map attributeCount; + for (size_t i = 0; i < faction.mData.mAttribute.size(); ++i) { - messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Error); + int attribute = faction.mData.mAttribute[i]; + if (attribute != -1) + { + auto it = attributeCount.find(attribute); + if (it == attributeCount.end()) + attributeCount.emplace(attribute, 1); + else + { + if (it->second == 1) + messages.add(id, "Same attribute is listed twice", {}, CSMDoc::Message::Severity_Error); + ++it->second; + } + } } // test for non-unique skill std::map skills; // ID, number of occurrences - for (int i = 0; i < 7; ++i) - if (faction.mData.mSkills[i] != -1) - ++skills[faction.mData.mSkills[i]]; + for (int skill : faction.mData.mSkills) + if (skill != -1) + ++skills[skill]; for (auto& skill : skills) if (skill.second > 1) diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index bdfb68c64a..9572d8de39 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -1186,13 +1186,9 @@ namespace CSMWorld QVariant FactionRanksAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { - ESM::Faction faction = record.get(); + const ESM::Faction& faction = record.get(); - if (subRowIndex < 0 - || subRowIndex >= static_cast(sizeof(faction.mData.mRankData) / sizeof(faction.mData.mRankData[0]))) - throw std::runtime_error("index out of range"); - - auto& rankData = faction.mData.mRankData[subRowIndex]; + const auto& rankData = faction.mData.mRankData.at(subRowIndex); switch (subColIndex) { @@ -1218,11 +1214,7 @@ namespace CSMWorld { ESM::Faction faction = record.get(); - if (subRowIndex < 0 - || subRowIndex >= static_cast(sizeof(faction.mData.mRankData) / sizeof(faction.mData.mRankData[0]))) - throw std::runtime_error("index out of range"); - - auto& rankData = faction.mData.mRankData[subRowIndex]; + auto& rankData = faction.mData.mRankData.at(subRowIndex); switch (subColIndex) { diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index c5ec812a8f..31a76e949c 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -644,9 +644,6 @@ int MWDialogue::Filter::getFactionRank(const MWWorld::Ptr& actor, const ESM::Ref bool MWDialogue::Filter::hasFactionRankSkillRequirements( const MWWorld::Ptr& actor, const ESM::RefId& factionId, int rank) const { - if (rank < 0 || rank >= 10) - throw std::runtime_error("rank index out of range"); - if (!actor.getClass().getNpcStats(actor).hasSkillsForRank(factionId, rank)) return false; @@ -661,14 +658,11 @@ bool MWDialogue::Filter::hasFactionRankSkillRequirements( bool MWDialogue::Filter::hasFactionRankReputationRequirements( const MWWorld::Ptr& actor, const ESM::RefId& factionId, int rank) const { - if (rank < 0 || rank >= 10) - throw std::runtime_error("rank index out of range"); - MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); const ESM::Faction& faction = *MWBase::Environment::get().getESMStore()->get().find(factionId); - return stats.getFactionReputation(factionId) >= faction.mData.mRankData[rank].mFactReaction; + return stats.getFactionReputation(factionId) >= faction.mData.mRankData.at(rank).mFactReaction; } MWDialogue::Filter::Filter(const MWWorld::Ptr& actor, int choice, bool talkedToPlayer) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 93062ef6ab..ee93c5720e 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -626,7 +626,7 @@ namespace MWGui // player doesn't have max rank yet text += std::string("\n\n#{fontcolourhtml=header}#{sNextRank} ") + faction->mRanks[rank + 1]; - ESM::RankData rankData = faction->mData.mRankData[rank + 1]; + const ESM::RankData& rankData = faction->mData.mRankData[rank + 1]; const ESM::Attribute* attr1 = store.get().find(faction->mData.mAttribute[0]); const ESM::Attribute* attr2 = store.get().find(faction->mData.mAttribute[1]); @@ -638,15 +638,15 @@ namespace MWGui text += "\n\n#{fontcolourhtml=header}#{sFavoriteSkills}"; text += "\n#{fontcolourhtml=normal}"; bool firstSkill = true; - for (int i = 0; i < 7; ++i) + for (int id : faction->mData.mSkills) { - if (faction->mData.mSkills[i] != -1) + if (id != -1) { if (!firstSkill) text += ", "; firstSkill = false; - const ESM::Skill* skill = store.get().find(faction->mData.mSkills[i]); + const ESM::Skill* skill = store.get().find(id); text += MyGUI::TextIterator::toTagsString(skill->mName); } } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 9f1010194c..242f87591c 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -382,17 +382,16 @@ void MWMechanics::NpcStats::setCrimeId(int id) bool MWMechanics::NpcStats::hasSkillsForRank(const ESM::RefId& factionId, int rank) const { - if (rank < 0 || rank >= 10) - throw std::runtime_error("rank index out of range"); - const ESM::Faction& faction = *MWBase::Environment::get().getESMStore()->get().find(factionId); + const ESM::RankData& rankData = faction.mData.mRankData.at(rank); + std::vector skills; - for (int i = 0; i < 7; ++i) + for (int id : faction.mData.mSkills) { - if (faction.mData.mSkills[i] != -1) - skills.push_back(static_cast(getSkill(faction.mData.mSkills[i]).getBase())); + if (id != -1) + skills.push_back(static_cast(getSkill(id).getBase())); } if (skills.empty()) @@ -402,8 +401,6 @@ bool MWMechanics::NpcStats::hasSkillsForRank(const ESM::RefId& factionId, int ra std::vector::const_reverse_iterator iter = skills.rbegin(); - const ESM::RankData& rankData = faction.mData.mRankData[rank]; - if (*iter < rankData.mPrimarySkill) return false; diff --git a/components/esm3/loadfact.cpp b/components/esm3/loadfact.cpp index bd1c998556..410ea1d40e 100644 --- a/components/esm3/loadfact.cpp +++ b/components/esm3/loadfact.cpp @@ -7,20 +7,14 @@ namespace ESM { - int& Faction::FADTstruct::getSkill(int index, bool ignored) + int& Faction::FADTstruct::getSkill(int index, bool) { - if (index < 0 || index >= 7) - throw std::logic_error("skill index out of range"); - - return mSkills[index]; + return mSkills.at(index); } - int Faction::FADTstruct::getSkill(int index, bool ignored) const + int Faction::FADTstruct::getSkill(int index, bool) const { - if (index < 0 || index >= 7) - throw std::logic_error("skill index out of range"); - - return mSkills[index]; + return mSkills.at(index); } void Faction::load(ESMReader& esm, bool& isDeleted) @@ -115,10 +109,10 @@ namespace ESM { mRecordFlags = 0; mName.clear(); - mData.mAttribute[0] = mData.mAttribute[1] = 0; + mData.mAttribute.fill(0); mData.mIsHidden = 0; - for (int i = 0; i < 10; ++i) + for (size_t i = 0; i < mData.mRankData.size(); ++i) { mData.mRankData[i].mAttribute1 = mData.mRankData[i].mAttribute2 = 0; mData.mRankData[i].mPrimarySkill = mData.mRankData[i].mFavouredSkill = 0; @@ -127,8 +121,7 @@ namespace ESM mRanks[i].clear(); } - for (int i = 0; i < 7; ++i) - mData.mSkills[i] = 0; + mData.mSkills.fill(0); mReactions.clear(); } diff --git a/components/esm3/loadfact.hpp b/components/esm3/loadfact.hpp index 5383b7a57f..0ba71dc06f 100644 --- a/components/esm3/loadfact.hpp +++ b/components/esm3/loadfact.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_ESM_FACT_H #define OPENMW_ESM_FACT_H +#include #include #include @@ -45,12 +46,12 @@ namespace ESM struct FADTstruct { // Which attributes we like - int mAttribute[2]; + std::array mAttribute; - RankData mRankData[10]; + std::array mRankData; - int mSkills[7]; // IDs of skills this faction require - // Each element will either contain an Skill index, or -1. + std::array mSkills; // IDs of skills this faction require + // Each element will either contain an Skill index, or -1. int mIsHidden; // 1 - hidden from player