diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 586e8b766d..9032209aba 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -99,7 +99,7 @@ namespace MWGui mPlayerAttributes.emplace(attribute.mId, MWMechanics::AttributeValue()); for (const auto& skill : store.get()) - mPlayerSkillValues.emplace(skill.second.mIndex, MWMechanics::SkillValue()); + mPlayerSkillValues.emplace(skill.mIndex, MWMechanics::SkillValue()); } void CharacterCreation::setValue(std::string_view id, const MWMechanics::AttributeValue& value) diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index acea128f07..2a04cca6c8 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -236,10 +236,10 @@ namespace MWGui std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin())); mMiscSkills.clear(); const auto& store = MWBase::Environment::get().getWorld()->getStore().get(); - for (const auto& skill : store) + for (const ESM::Skill& skill : store) { - if (!skillSet.contains(skill.second.mIndex)) - mMiscSkills.push_back(skill.second.mIndex); + if (!skillSet.contains(skill.mIndex)) + mMiscSkills.push_back(skill.mIndex); } mUpdateSkillArea = true; @@ -339,12 +339,13 @@ namespace MWGui addGroup( MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); - for (const int& skillId : skills) + for (const int& skillIndex : skills) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search(skillId); - if (!skill) // Skip unknown skill indexes + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search( + ESM::Skill::indexToRefId(skillIndex)); + if (!skill) // Skip unknown skills continue; - const MWMechanics::SkillValue& stat = mSkillValues.find(skillId)->second; + const MWMechanics::SkillValue& stat = mSkillValues.find(skill->mIndex)->second; int base = stat.getBase(); int modified = stat.getModified(); @@ -358,10 +359,10 @@ namespace MWGui for (int i = 0; i < 2; ++i) { - ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skillId); + ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skill->mIndex); } - mSkillWidgetMap[skillId] = widget; + mSkillWidgetMap[skill->mIndex] = widget; } } diff --git a/apps/openmw/mwgui/spellmodel.cpp b/apps/openmw/mwgui/spellmodel.cpp index 473324e685..dafa009eef 100644 --- a/apps/openmw/mwgui/spellmodel.cpp +++ b/apps/openmw/mwgui/spellmodel.cpp @@ -55,7 +55,7 @@ namespace MWGui { const ESM::MagicEffect* magicEffect = store.get().find(effectId); const ESM::Attribute* attribute = store.get().search(effect.mAttribute); - const ESM::Skill* skill = store.get().search(effect.mSkill); + const ESM::Skill* skill = store.get().search(ESM::Skill::indexToRefId(effect.mSkill)); std::string fullEffectName = MWMechanics::getMagicEffectString(*magicEffect, attribute, skill); std::string convert = Utf8Stream::lowerCaseUtf8(fullEffectName); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index ee93c5720e..ec6fd49f15 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -327,8 +327,8 @@ namespace MWGui const auto& store = MWBase::Environment::get().getWorld()->getStore().get(); for (const auto& skill : store) { - if (!skillSet.contains(skill.second.mIndex)) - mMiscSkills.push_back(skill.second.mIndex); + if (!skillSet.contains(skill.mIndex)) + mMiscSkills.push_back(skill.mIndex); } updateSkillArea(); @@ -504,13 +504,12 @@ namespace MWGui addGroup( MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); + const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); for (const int skillId : skills) { - if (skillId < 0 || skillId >= ESM::Skill::Length) // Skip unknown skill indexes + const ESM::Skill* skill = esmStore.get().search(ESM::Skill::indexToRefId(skillId)); + if (!skill) // Skip unknown skills continue; - const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); - - const ESM::Skill* skill = esmStore.get().find(skillId); const ESM::Attribute* attr = esmStore.get().find(skill->mData.mAttribute); @@ -640,13 +639,13 @@ namespace MWGui bool firstSkill = true; for (int id : faction->mData.mSkills) { - if (id != -1) + const ESM::Skill* skill = store.get().search(ESM::Skill::indexToRefId(id)); + if (skill) { if (!firstSkill) text += ", "; firstSkill = false; - const ESM::Skill* skill = store.get().find(id); text += MyGUI::TextIterator::toTagsString(skill->mName); } } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 7ad3206055..6ca89add80 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -846,7 +846,7 @@ namespace MWGui const MWWorld::Store& skills = MWBase::Environment::get().getESMStore()->get(); bool isFirst = true; - for (const auto& [_, skill] : skills) + for (const auto& skill : skills) { if (skill.mData.mSpecialization == specId) { diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 8523a85550..d63e1b290d 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -60,7 +60,8 @@ namespace MWGui::Widgets { if (mSkillNameWidget) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search(mSkillId); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search( + ESM::Skill::indexToRefId(mSkillId)); if (skill == nullptr) mSkillNameWidget->setCaption({}); else @@ -374,7 +375,7 @@ namespace MWGui::Widgets const ESM::MagicEffect* magicEffect = store.get().search(mEffectParams.mEffectID); const ESM::Attribute* attribute = store.get().search(mEffectParams.mAttribute); - const ESM::Skill* skill = store.get().search(mEffectParams.mSkill); + const ESM::Skill* skill = store.get().search(ESM::Skill::indexToRefId(mEffectParams.mSkill)); assert(magicEffect); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index acab0edefa..3d5823ddf2 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -576,7 +576,7 @@ std::vector MWMechanics::Alchemy::effectsDescription(const MWWorld: if (effectID != -1) { const ESM::Attribute* attribute = store->get().search(data.mAttributes[i]); - const ESM::Skill* skill = store->get().search(data.mAttributes[i]); + const ESM::Skill* skill = store->get().search(ESM::Skill::indexToRefId(data.mSkills[i])); std::string effect = getMagicEffectString(*mgef.find(effectID), attribute, skill); effects.push_back(effect); diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index b9918a398e..e75a1184a4 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -53,8 +53,8 @@ namespace MWMechanics { const auto& store = MWBase::Environment::get().getESMStore(); const ESM::MagicEffect* magicEffect = store->get().search(mId); - return getMagicEffectString( - *magicEffect, store->get().search(mArg), store->get().search(mArg)); + return getMagicEffectString(*magicEffect, store->get().search(mArg), + store->get().search(ESM::Skill::indexToRefId(mArg))); } bool operator<(const EffectKey& left, const EffectKey& right) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 62d7f47873..487764cfbe 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -214,14 +214,11 @@ namespace MWMechanics } } - const MWWorld::Store& skills = esmStore.get(); - - MWWorld::Store::iterator iter = skills.begin(); - for (; iter != skills.end(); ++iter) + for (const ESM::Skill& skill : esmStore.get()) { - if (iter->second.mData.mSpecialization == class_->mData.mSpecialization) + if (skill.mData.mSpecialization == class_->mData.mSpecialization) { - int index = iter->first; + int index = skill.mIndex; if (index >= 0 && index < 27) { diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5e3029af1e..2d7617adfa 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -103,7 +103,7 @@ namespace MWWorld npcStats.setAttribute(attribute.mId, value); } - for (const auto& [_, skill] : store->get()) + for (const auto& skill : store->get()) { // Acrobatics is set separately for some reason. if (skill.mIndex == ESM::Skill::Acrobatics) diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index e19e099580..5b717c81fc 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -113,7 +113,6 @@ namespace MWWorld // Need to instantiate these before they're used template class IndexedStore; - template class IndexedStore; template TypedDynamicStore::TypedDynamicStore() @@ -915,8 +914,6 @@ namespace MWWorld // Skill //========================================================================= - Store::Store() {} - void Store::setUp(const MWWorld::Store& settings) { constexpr std::string_view skillValues[ESM::Skill::Length][3] = { @@ -949,15 +946,13 @@ namespace MWWorld { "sSkillSpeechcraft", "icons\\k\\stealth_speechcraft.dds", "fWerewolfSpeechcraft" }, { "sSkillHandtohand", "icons\\k\\stealth_handtohand.dds", "fWerewolfHandtohand" }, }; - for (int i = 0; i < ESM::Skill::Length; ++i) + for (ESM::Skill* skill : mShared) { - auto found = mStatic.find(i); - if (found != mStatic.end()) + if (skill->mIndex >= 0) { - ESM::Skill& skill = found->second; - skill.mName = getGMSTString(settings, skillValues[i][0]); - skill.mIcon = skillValues[i][1]; - skill.mWerewolfValue = getGMSTFloat(settings, skillValues[i][2]); + skill->mName = getGMSTString(settings, skillValues[skill->mIndex][0]); + skill->mIcon = skillValues[skill->mIndex][1]; + skill->mWerewolfValue = getGMSTFloat(settings, skillValues[skill->mIndex][2]); } } } @@ -1344,7 +1339,7 @@ template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; -// template class MWWorld::Store; +template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index b6e9044184..97cc733147 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,7 +31,6 @@ namespace ESM struct Attribute; struct LandTexture; struct MagicEffect; - struct Skill; struct WeaponType; class ESMReader; class ESMWriter; @@ -476,10 +476,14 @@ namespace MWWorld }; template <> - class Store : public IndexedStore + class Store : public TypedDynamicStore { public: - Store(); + Store() = default; + + using TypedDynamicStore::find; + // TODO delete + const ESM::Skill* find(int index) const { return find(ESM::Skill::indexToRefId(index)); } void setUp(const MWWorld::Store& settings); }; diff --git a/components/esm3/loadskil.cpp b/components/esm3/loadskil.cpp index 9fbbbdae2b..24faa0c7f1 100644 --- a/components/esm3/loadskil.cpp +++ b/components/esm3/loadskil.cpp @@ -75,6 +75,8 @@ namespace ESM } if (!hasIndex) esm.fail("Missing INDX"); + else if (mIndex < 0 || mIndex >= Length) + esm.fail("Invalid INDX"); if (!hasData) esm.fail("Missing SKDT"); @@ -101,7 +103,7 @@ namespace ESM RefId Skill::indexToRefId(int index) { - if (index == -1) + if (index < 0 || index >= Length) return RefId(); return RefId::index(sRecordId, static_cast(index)); } diff --git a/components/esm3/loadskil.hpp b/components/esm3/loadskil.hpp index a0dc56f1d4..f4ccd54f66 100644 --- a/components/esm3/loadskil.hpp +++ b/components/esm3/loadskil.hpp @@ -41,7 +41,7 @@ namespace ESM // 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; + int mIndex{ -1 }; std::string mDescription; std::string mName;