From ac9378fa0803ea5b724af7798c35957cb941744e Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 15 Jun 2023 20:49:14 +0200 Subject: [PATCH] Replace Skill::mIndex with Skill::refIdToIndex --- apps/esmtool/record.cpp | 3 ++- apps/opencs/model/doc/document.cpp | 5 ++--- apps/openmw/mwclass/npc.cpp | 10 ++++++---- apps/openmw/mwgui/charactercreation.cpp | 4 ++-- apps/openmw/mwgui/spellcreationdialog.cpp | 2 +- apps/openmw/mwlua/stats.cpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 4 ++-- apps/openmw/mwmechanics/npcstats.cpp | 13 +++++++------ apps/openmw/mwworld/store.cpp | 12 +++++++----- apps/openmw_test_suite/mwworld/test_store.cpp | 4 +++- components/esm3/loadskil.cpp | 19 +++++++++++++++---- components/esm3/loadskil.hpp | 6 +----- 12 files changed, 49 insertions(+), 35 deletions(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 8227fcfcf0..d20bb4619c 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1264,7 +1264,8 @@ namespace EsmTool template <> void Record::print() { - std::cout << " ID: " << skillLabel(mData.mIndex) << " (" << mData.mIndex << ")" << std::endl; + int index = ESM::Skill::refIdToIndex(mData.mId); + std::cout << " ID: " << skillLabel(index) << " (" << index << ")" << std::endl; std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) << " (" << mData.mData.mAttribute << ")" << std::endl; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 9ee2a8bc48..84adfb2b87 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -201,11 +201,10 @@ void CSMDoc::Document::createBase() addGmsts(); - for (int i = 0; i < 27; ++i) + for (int i = 0; i < ESM::Skill::Length; ++i) { ESM::Skill record; - record.mIndex = i; - record.mId = ESM::Skill::indexToRefId(record.mIndex); + record.mId = ESM::Skill::indexToRefId(i); record.blank(); getData().getSkills().add(record); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 59aefc715f..bdba113038 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -121,11 +121,12 @@ namespace // is this a minor or major skill? float add = 0.2f; + int index = ESM::Skill::refIdToIndex(skill.mId); for (const auto& skills : class_->mData.mSkills) { - if (skills[0] == skill.mIndex) + if (skills[0] == index) add = 0.5; - if (skills[1] == skill.mIndex) + if (skills[1] == index) add = 1.0; } modifierSum += add; @@ -199,15 +200,16 @@ namespace int raceBonus = 0; int specBonus = 0; + int index = ESM::Skill::refIdToIndex(skill.mId); auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(), - [&](const auto& bonus) { return bonus.mSkill == skill.mIndex; }); + [&](const auto& bonus) { return bonus.mSkill == index; }); if (bonusIt != race->mData.mBonus.end()) raceBonus = bonusIt->mBonus; for (const auto& skills : class_->mData.mSkills) { // is this a minor or major skill? - if (std::find(skills.begin(), skills.end(), skill.mIndex) != skills.end()) + if (std::find(skills.begin(), skills.end(), index) != skills.end()) { majorMultiplier = 1.0f; break; diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 114238482d..3987264fc6 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -471,8 +471,8 @@ namespace MWGui assert(minorSkills.size() >= klass.mData.mSkills.size()); for (size_t i = 0; i < klass.mData.mSkills.size(); ++i) { - klass.mData.mSkills[i][1] = majorSkills[i].getIf()->getValue(); - klass.mData.mSkills[i][0] = minorSkills[i].getIf()->getValue(); + klass.mData.mSkills[i][1] = ESM::Skill::refIdToIndex(majorSkills[i]); + klass.mData.mSkills[i][0] = ESM::Skill::refIdToIndex(minorSkills[i]); } MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 0c326049e8..7105112cca 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -287,7 +287,7 @@ namespace MWGui void EditEffectDialog::setSkill(ESM::RefId skill) { - mEffect.mSkill = skill.getIf()->getValue(); + mEffect.mSkill = ESM::Skill::refIdToIndex(skill); eventEffectModified(mEffect); } diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index da4d2a4614..552129c3fd 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -392,7 +392,7 @@ namespace MWLua sol::table skills(context.mLua->sol(), sol::create); npcStats["skills"] = LuaUtil::makeReadOnly(skills); for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) - skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[skill.mIndex])] + skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[ESM::Skill::refIdToIndex(skill.mId)])] = addIndexedAccessor(skill.mId); } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 135c8e4660..8d89e81f12 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -158,9 +158,9 @@ namespace MWMechanics for (const ESM::Skill& skill : esmStore.get()) { int bonus = 0; - + int index = ESM::Skill::refIdToIndex(skill.mId); auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(), - [&](const auto& bonus) { return bonus.mSkill == skill.mIndex; }); + [&](const auto& bonus) { return bonus.mSkill == index; }); if (bonusIt != race->mData.mBonus.end()) bonus = bonusIt->mBonus; diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index ce779418af..f182a09944 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -155,15 +155,15 @@ float MWMechanics::NpcStats::getSkillProgressRequirement(ESM::RefId id, const ES const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(id); float typeFactor = gmst.find("fMiscSkillBonus")->mValue.getFloat(); - + int index = ESM::Skill::refIdToIndex(skill->mId); for (const auto& skills : class_.mData.mSkills) { - if (skills[0] == skill->mIndex) + if (skills[0] == index) { typeFactor = gmst.find("fMinorSkillBonus")->mValue.getFloat(); break; } - else if (skills[1] == skill->mIndex) + else if (skills[1] == index) { typeFactor = gmst.find("fMajorSkillBonus")->mValue.getFloat(); break; @@ -228,15 +228,16 @@ void MWMechanics::NpcStats::increaseSkill(ESM::RefId id, const ESM::Class& class // is this a minor or major skill? int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo + int index = ESM::Skill::refIdToIndex(skill->mId); for (const auto& skills : class_.mData.mSkills) { - if (skills[0] == skill->mIndex) + if (skills[0] == index) { mLevelProgress += gmst.find("iLevelUpMinorMult")->mValue.getInteger(); increase = gmst.find("iLevelUpMinorMultAttribute")->mValue.getInteger(); break; } - else if (skills[1] == skill->mIndex) + else if (skills[1] == index) { mLevelProgress += gmst.find("iLevelUpMajorMult")->mValue.getInteger(); increase = gmst.find("iLevelUpMajorMultAttribute")->mValue.getInteger(); @@ -463,7 +464,7 @@ void MWMechanics::NpcStats::writeState(ESM::NpcStats& state) const for (const auto& [id, value] : mSkills) { // TODO extend format - auto index = id.getIf()->getValue(); + auto index = ESM::Skill::refIdToIndex(id); value.writeState(state.mSkills[index]); } diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 2b69ec82c4..a2114648a0 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -962,12 +962,14 @@ namespace MWWorld }; for (ESM::Skill* skill : mShared) { - if (skill->mIndex >= 0) + int index = ESM::Skill::refIdToIndex(skill->mId); + if (index >= 0) { - skill->mName = getGMSTString(settings, skillValues[skill->mIndex][0]); - skill->mIcon = skillValues[skill->mIndex][1]; - skill->mWerewolfValue = getGMSTFloat(settings, skillValues[skill->mIndex][2]); - const auto& school = skillValues[skill->mIndex][3]; + const auto& values = skillValues[index]; + skill->mName = getGMSTString(settings, values[0]); + skill->mIcon = values[1]; + skill->mWerewolfValue = getGMSTFloat(settings, values[2]); + const auto& school = values[3]; if (!school.empty()) { if (!skill->mSchool) diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index 2b5e460627..e325dcd08e 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -462,6 +462,8 @@ namespace { refId = ESM::RefId::esm3ExteriorCell(0, 0); } + else if constexpr (std::is_same_v) + refId = ESM::Skill::Block; else refId = ESM::StringRefId(stringId); @@ -496,7 +498,7 @@ namespace const RecordType* result = nullptr; if constexpr (std::is_same_v) result = esmStore.get().search(index, 0); - else if constexpr (ESM::hasIndex && !std::is_same_v) + else if constexpr (ESM::hasIndex) result = esmStore.get().search(index); else result = esmStore.get().search(refId); diff --git a/components/esm3/loadskil.cpp b/components/esm3/loadskil.cpp index d435501e05..73fb7f34e3 100644 --- a/components/esm3/loadskil.cpp +++ b/components/esm3/loadskil.cpp @@ -53,13 +53,14 @@ namespace ESM bool hasIndex = false; bool hasData = false; + int index = -1; while (esm.hasMoreSubs()) { esm.getSubName(); switch (esm.retSubName().toInt()) { case fourCC("INDX"): - esm.getHT(mIndex); + esm.getHT(index); hasIndex = true; break; case fourCC("SKDT"): @@ -75,19 +76,19 @@ namespace ESM } if (!hasIndex) esm.fail("Missing INDX"); - else if (mIndex < 0 || mIndex >= Length) + else if (index < 0 || index >= Length) esm.fail("Invalid INDX"); if (!hasData) esm.fail("Missing SKDT"); // create an ID from the index and the name (only used in the editor and likely to change in the // future) - mId = indexToRefId(mIndex); + mId = indexToRefId(index); } void Skill::save(ESMWriter& esm, bool /*isDeleted*/) const { - esm.writeHNT("INDX", mIndex); + esm.writeHNT("INDX", refIdToIndex(mId)); esm.writeHNT("SKDT", mData, 24); esm.writeHNOString("DESC", mDescription); } @@ -108,6 +109,16 @@ namespace ESM return RefId::index(sRecordId, static_cast(index)); } + int Skill::refIdToIndex(RefId id) + { + if (const IndexRefId* index = id.getIf()) + { + if (index->getRecordType() == sRecordId) + return index->getValue(); + } + return -1; + } + const std::array sMagicSchools = { Skill::Alteration, Skill::Conjuration, diff --git a/components/esm3/loadskil.hpp b/components/esm3/loadskil.hpp index 637c44d0f8..f8e3390fa1 100644 --- a/components/esm3/loadskil.hpp +++ b/components/esm3/loadskil.hpp @@ -55,11 +55,6 @@ namespace ESM }; // Total size: 24 bytes SKDTstruct mData; - // Skill index. Skils don't have an id ("NAME") like most records, - // they only have a numerical index that matches one of the - // hard-coded skills in the game. - int mIndex{ -1 }; - std::string mDescription; std::string mName; std::string mIcon; @@ -105,6 +100,7 @@ namespace ESM ///< Set record to default state (does not touch the ID/index). static RefId indexToRefId(int index); + static int refIdToIndex(RefId id); }; } #endif