From 16c0f0d5cce554e413d6295566050c20376a1cb8 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 5 Jun 2023 12:41:01 +0200 Subject: [PATCH 01/15] Use a regular TypedDynamicStore for ESM:Skill --- apps/openmw/mwgui/charactercreation.cpp | 2 +- apps/openmw/mwgui/review.cpp | 19 ++++++++++--------- apps/openmw/mwgui/spellmodel.cpp | 2 +- apps/openmw/mwgui/statswindow.cpp | 15 +++++++-------- apps/openmw/mwgui/tooltips.cpp | 2 +- apps/openmw/mwgui/widgets.cpp | 5 +++-- apps/openmw/mwmechanics/alchemy.cpp | 2 +- apps/openmw/mwmechanics/magiceffects.cpp | 4 ++-- .../mwmechanics/mechanicsmanagerimp.cpp | 9 +++------ apps/openmw/mwworld/player.cpp | 2 +- apps/openmw/mwworld/store.cpp | 17 ++++++----------- apps/openmw/mwworld/store.hpp | 10 +++++++--- components/esm3/loadskil.cpp | 4 +++- components/esm3/loadskil.hpp | 2 +- 14 files changed, 47 insertions(+), 48 deletions(-) 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; From 1b956521fcce9df11fa22e3de75948fda3248eeb Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 5 Jun 2023 16:45:45 +0200 Subject: [PATCH 02/15] Reduce skill lookups by index --- apps/openmw/mwgui/jailscreen.cpp | 2 +- apps/openmw/mwgui/trainingwindow.cpp | 56 +++++++------------ .../mwmechanics/mechanicsmanagerimp.cpp | 15 ++--- apps/openmw/mwworld/store.cpp | 18 ++++-- 4 files changed, 38 insertions(+), 53 deletions(-) diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index ec0614a664..b73aafb79c 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -93,7 +93,7 @@ namespace MWGui for (int day = 0; day < mDays; ++day) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Skill* skill = skillStore.find(Misc::Rng::rollDice(ESM::Skill::Length, prng)); + const ESM::Skill* skill = skillStore.searchRandom({}, prng); skills.insert(skill); MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mIndex); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 7b0e93edd0..e9184978fa 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -21,24 +21,6 @@ #include "tooltips.hpp" -namespace -{ - // Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID. - // pair - bool sortSkills(const std::pair& left, const std::pair& right) - { - if (left == right) - return false; - - if (left.second > right.second) - return true; - else if (left.second < right.second) - return false; - - return left.first < right.first; - } -} - namespace MWGui { @@ -80,34 +62,37 @@ namespace MWGui mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); + const auto& store = MWBase::Environment::get().getESMStore(); + const MWWorld::Store& gmst = store->get(); + const MWWorld::Store& skillStore = store->get(); + // NPC can train you in his best 3 skills - std::vector> skills; + std::vector> skills; MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor)); - for (int i = 0; i < ESM::Skill::Length; ++i) + for (const ESM::Skill& skill : skillStore) { - float value = getSkillForTraining(actorStats, i); + float value = getSkillForTraining(actorStats, skill.mIndex); - skills.emplace_back(i, value); + skills.emplace_back(&skill, value); } - std::sort(skills.begin(), skills.end(), sortSkills); + std::sort(skills.begin(), skills.end(), [](const auto& left, const auto& right) { + return std::tie(right.second, left.first->mId) < std::tie(left.second, right.first->mId); + }); MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator(); MyGUI::Gui::getInstance().destroyWidgets(widgets); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); - const auto& store = MWBase::Environment::get().getESMStore(); - const MWWorld::Store& gmst = store->get(); - const MWWorld::Store& skillStore = store->get(); - const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; for (int i = 0; i < 3; ++i) { + const ESM::Skill* skill = skills[i].first; int price = static_cast( - pcStats.getSkill(skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); + pcStats.getSkill(skill->mIndex).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); price = std::max(1, price); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); @@ -120,13 +105,12 @@ namespace MWGui button->setUserData(skills[i].first); button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); - const ESM::Skill* skill = skillStore.find(skills[i].first); button->setCaptionWithReplacing( MyGUI::TextIterator::toTagsString(skill->mName) + " - " + MyGUI::utility::toString(price)); button->setSize(button->getTextSize().width + 12, button->getSize().height); - ToolTips::createSkillToolTip(button, skills[i].first); + ToolTips::createSkillToolTip(button, skill->mIndex); } center(); @@ -144,29 +128,29 @@ namespace MWGui void TrainingWindow::onTrainingSelected(MyGUI::Widget* sender) { - int skillId = *sender->getUserData(); + const ESM::Skill* skill = *sender->getUserData(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore(); - int price = pcStats.getSkill(skillId).getBase() + int price = pcStats.getSkill(skill->mIndex).getBase() * store.get().find("iTrainingMod")->mValue.getInteger(); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) return; - if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skillId) <= pcStats.getSkill(skillId).getBase()) + if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skill->mIndex) + <= pcStats.getSkill(skill->mIndex).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sServiceTrainingWords}"); return; } // You can not train a skill above its governing attribute - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillId); - if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) + if (pcStats.getSkill(skill->mIndex).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage17}"); return; @@ -176,7 +160,7 @@ namespace MWGui MWWorld::LiveCellRef* playerRef = player.get(); const ESM::Class* class_ = store.get().find(playerRef->mBase->mClass); - pcStats.increaseSkill(skillId, *class_, true); + pcStats.increaseSkill(skill->mIndex, *class_, true); // remove gold player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 487764cfbe..0fa85b9b97 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -155,16 +155,16 @@ namespace MWMechanics creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale); } - for (int i = 0; i < 27; ++i) + for (const ESM::Skill& skill : esmStore.get()) { int bonus = 0; auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(), - [i](const auto& bonus) { return bonus.mSkill == i; }); + [&](const auto& bonus) { return bonus.mSkill == skill.mIndex; }); if (bonusIt != race->mData.mBonus.end()) bonus = bonusIt->mBonus; - npcStats.getSkill(i).setBase(5 + bonus); + npcStats.getSkill(skill.mIndex).setBase(5 + bonus); } for (const ESM::RefId& power : race->mPowers.mList) @@ -217,14 +217,7 @@ namespace MWMechanics for (const ESM::Skill& skill : esmStore.get()) { if (skill.mData.mSpecialization == class_->mData.mSpecialization) - { - int index = skill.mIndex; - - if (index >= 0 && index < 27) - { - npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + 5); - } - } + npcStats.getSkill(skill.mIndex).setBase(npcStats.getSkill(skill.mIndex).getBase() + 5); } } diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 5b717c81fc..5d17a86c3a 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -168,11 +168,19 @@ namespace MWWorld { if constexpr (std::is_same_v) { - std::vector results; - std::copy_if(mShared.begin(), mShared.end(), std::back_inserter(results), - [prefix](const T* item) { return item->mId.startsWith(prefix); }); - if (!results.empty()) - return results[Misc::Rng::rollDice(results.size(), prng)]; + if (prefix.empty()) + { + if (!mShared.empty()) + return mShared[Misc::Rng::rollDice(mShared.size(), prng)]; + } + else + { + std::vector results; + std::copy_if(mShared.begin(), mShared.end(), std::back_inserter(results), + [prefix](const T* item) { return item->mId.startsWith(prefix); }); + if (!results.empty()) + return results[Misc::Rng::rollDice(results.size(), prng)]; + } return nullptr; } else From 47c15699616015b0dd304e4472df8d5d58b02809 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 5 Jun 2023 21:21:30 +0200 Subject: [PATCH 03/15] Use RefId key for NPC skills --- apps/openmw/mwclass/armor.cpp | 2 +- apps/openmw/mwclass/creature.cpp | 4 +- apps/openmw/mwclass/creature.hpp | 2 +- apps/openmw/mwclass/npc.cpp | 30 ++++---- apps/openmw/mwclass/npc.hpp | 2 +- apps/openmw/mwdialogue/filter.cpp | 8 +- apps/openmw/mwgui/jailscreen.cpp | 4 +- apps/openmw/mwgui/review.cpp | 19 ++--- apps/openmw/mwgui/review.hpp | 2 +- apps/openmw/mwgui/statswatcher.cpp | 10 +-- apps/openmw/mwgui/statswindow.cpp | 7 +- apps/openmw/mwgui/trainingwindow.cpp | 18 ++--- apps/openmw/mwgui/trainingwindow.hpp | 2 +- apps/openmw/mwlua/stats.cpp | 51 +++++++------ apps/openmw/mwmechanics/autocalcspell.cpp | 32 +++++--- apps/openmw/mwmechanics/autocalcspell.hpp | 17 +++-- apps/openmw/mwmechanics/combat.cpp | 5 +- .../mwmechanics/mechanicsmanagerimp.cpp | 23 ++---- apps/openmw/mwmechanics/npcstats.cpp | 73 +++++++++++-------- apps/openmw/mwmechanics/npcstats.hpp | 17 +++-- apps/openmw/mwmechanics/spelleffects.cpp | 12 +-- apps/openmw/mwmechanics/spellpriority.cpp | 2 +- apps/openmw/mwmechanics/weaponpriority.cpp | 8 +- apps/openmw/mwscript/statsextensions.cpp | 37 +++++----- apps/openmw/mwworld/class.cpp | 2 +- apps/openmw/mwworld/class.hpp | 7 +- apps/openmw/mwworld/inventorystore.cpp | 2 +- apps/openmw/mwworld/player.cpp | 23 +++--- apps/openmw/mwworld/player.hpp | 3 +- 29 files changed, 228 insertions(+), 196 deletions(-) diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 416a55336a..bdaa82e873 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -298,7 +298,7 @@ namespace MWClass const MWWorld::LiveCellRef* ref = ptr.get(); int armorSkillType = getEquipmentSkill(ptr); - float armorSkill = actor.getClass().getSkill(actor, armorSkillType); + float armorSkill = actor.getClass().getSkill(actor, ESM::Skill::indexToRefId(armorSkillType)); int iBaseArmorSkill = MWBase::Environment::get() .getESMStore() diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 39de4a5b1d..1ff9c6375a 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -762,11 +762,11 @@ namespace MWClass throw std::runtime_error("Unexpected soundgen type: " + std::string(name)); } - float Creature::getSkill(const MWWorld::Ptr& ptr, int skill) const + float Creature::getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const { MWWorld::LiveCellRef* ref = ptr.get(); - const ESM::Skill* skillRecord = MWBase::Environment::get().getESMStore()->get().find(skill); + const ESM::Skill* skillRecord = MWBase::Environment::get().getESMStore()->get().find(id); switch (skillRecord->mData.mSpecialization) { diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 465c28aaaf..bd7101e93d 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -115,7 +115,7 @@ namespace MWClass bool canSwim(const MWWorld::ConstPtr& ptr) const override; bool canWalk(const MWWorld::ConstPtr& ptr) const override; - float getSkill(const MWWorld::Ptr& ptr, int skill) const override; + float getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const override; /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) int getBloodTexture(const MWWorld::ConstPtr& ptr) const override; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 9e3ca67759..ebab5bfb9c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -181,10 +181,10 @@ namespace for (const auto& skills : class_->mData.mSkills) { - int index = skills[i]; - if (index >= 0 && index < ESM::Skill::Length) + ESM::RefId id = ESM::Skill::indexToRefId(skills[i]); + if (!id.empty()) { - npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + bonus); + npcStats.getSkill(id).setBase(npcStats.getSkill(id).getBase() + bonus); } } } @@ -220,23 +220,19 @@ namespace specBonus = 5; } - npcStats.getSkill(skillIndex) - .setBase(std::min(round_ieee_754(npcStats.getSkill(skillIndex).getBase() + 5 + raceBonus + specBonus + npcStats.getSkill(skill->mId) + .setBase(std::min(round_ieee_754(npcStats.getSkill(skill->mId).getBase() + 5 + raceBonus + specBonus + (int(level) - 1) * (majorMultiplier + specMultiplier)), 100)); // Must gracefully handle level 0 } - int skills[ESM::Skill::Length]; - for (int i = 0; i < ESM::Skill::Length; ++i) - skills[i] = npcStats.getSkill(i).getBase(); - int attributes[ESM::Attribute::Length]; for (int i = 0; i < ESM::Attribute::Length; ++i) attributes[i] = npcStats.getAttribute(i).getBase(); if (!spellsInitialised) { - std::vector spells = MWMechanics::autoCalcNpcSpells(skills, attributes, race); + std::vector spells = MWMechanics::autoCalcNpcSpells(npcStats.getSkills(), attributes, race); npcStats.getSpells().addAllToInstance(spells); } } @@ -315,7 +311,7 @@ namespace MWClass gold = ref->mBase->mNpdt.mGold; for (size_t i = 0; i < ref->mBase->mNpdt.mSkills.size(); ++i) - data->mNpcStats.getSkill(i).setBase(ref->mBase->mNpdt.mSkills[i]); + data->mNpcStats.getSkill(ESM::Skill::indexToRefId(i)).setBase(ref->mBase->mNpdt.mSkills[i]); data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt.mStrength); data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt.mIntelligence); @@ -593,7 +589,7 @@ namespace MWClass if (!weapon.isEmpty()) weapskill = weapon.getClass().getEquipmentSkill(weapon); - float hitchance = MWMechanics::getHitChance(ptr, victim, getSkill(ptr, weapskill)); + float hitchance = MWMechanics::getHitChance(ptr, victim, getSkill(ptr, ESM::Skill::indexToRefId(weapskill))); return Misc::Rng::roll0to99(world->getPrng()) < hitchance; } @@ -1052,7 +1048,7 @@ namespace MWClass const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() + gmst.fJumpEncumbranceMultiplier->mValue.getFloat() * (1.0f - Npc::getNormalizedEncumbrance(ptr)); - float a = getSkill(ptr, ESM::Skill::Acrobatics); + float a = Class::getSkill(ptr, ESM::Skill::Acrobatics); float b = 0.0f; if (a > 50.0f) { @@ -1185,7 +1181,7 @@ namespace MWClass float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); - float unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored); + float unarmoredSkill = Class::getSkill(ptr, ESM::Skill::Unarmored); float ratings[MWWorld::InventoryStore::Slots]; for (int i = 0; i < MWWorld::InventoryStore::Slots; i++) @@ -1355,9 +1351,9 @@ namespace MWClass return MWWorld::Ptr(cell.insert(ref), &cell); } - float Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const + float Npc::getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const { - return getNpcStats(ptr).getSkill(skill).getModified(); + return getNpcStats(ptr).getSkill(id).getModified(); } int Npc::getBloodTexture(const MWWorld::ConstPtr& ptr) const @@ -1550,7 +1546,7 @@ namespace MWClass { const GMST& gmst = getGmst(); return getWalkSpeed(ptr) - * (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + * (0.01f * Class::getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat()); } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 9b8e229890..242548ab20 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -134,7 +134,7 @@ namespace MWClass std::string getModel(const MWWorld::ConstPtr& ptr) const override; - float getSkill(const MWWorld::Ptr& ptr, int skill) const override; + float getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const override; /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) int getBloodTexture(const MWWorld::ConstPtr& ptr) const override; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 31a76e949c..6858c76cfe 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" @@ -385,9 +386,10 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons return player.getClass().getCreatureStats(player).getAttribute(select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: - - return static_cast(player.getClass().getNpcStats(player).getSkill(select.getArgument()).getModified()); - + { + ESM::RefId skill = ESM::Skill::indexToRefId(select.getArgument()); + return static_cast(player.getClass().getNpcStats(player).getSkill(skill).getModified()); + } case SelectWrapper::Function_FriendlyHit: { int hits = mActor.getClass().getCreatureStats(mActor).getFriendlyHits(); diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index b73aafb79c..484e9370cc 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -96,7 +96,7 @@ namespace MWGui const ESM::Skill* skill = skillStore.searchRandom({}, prng); skills.insert(skill); - MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mIndex); + MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mId); if (skill->mIndex == ESM::Skill::Security || skill->mIndex == ESM::Skill::Sneak) value.setBase(std::min(100.f, value.getBase() + 1)); else @@ -116,7 +116,7 @@ namespace MWGui for (const ESM::Skill* skill : skills) { - int skillValue = player.getClass().getNpcStats(player).getSkill(skill->mIndex).getBase(); + int skillValue = player.getClass().getNpcStats(player).getSkill(skill->mId).getBase(); std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString(); if (skill->mIndex == ESM::Skill::Sneak || skill->mIndex == ESM::Skill::Security) skillMsg = gmst.find("sNotifyMessage39")->mValue.getString(); diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 2a04cca6c8..02555a4cfe 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -90,10 +90,10 @@ namespace MWGui getWidget(mSkillView, "SkillView"); mSkillView->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); - for (int i = 0; i < ESM::Skill::Length; ++i) + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { - mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert(std::make_pair(i, static_cast(nullptr))); + mSkillValues.emplace(skill.mId, MWMechanics::SkillValue()); + mSkillWidgetMap.emplace(skill.mIndex, static_cast(nullptr)); } MyGUI::Button* backButton; @@ -206,11 +206,12 @@ namespace MWGui void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value) { - mSkillValues[skillId] = value; + mSkillValues[ESM::Skill::indexToRefId(skillId)] = value; MyGUI::TextBox* widget = mSkillWidgetMap[skillId]; if (widget) { - float modified = static_cast(value.getModified()), base = static_cast(value.getBase()); + float modified = value.getModified(); + float base = value.getBase(); std::string text = MyGUI::utility::toString(std::floor(modified)); std::string state = "normal"; if (modified > base) @@ -345,7 +346,7 @@ namespace MWGui ESM::Skill::indexToRefId(skillIndex)); if (!skill) // Skip unknown skills continue; - const MWMechanics::SkillValue& stat = mSkillValues.find(skill->mIndex)->second; + const MWMechanics::SkillValue& stat = mSkillValues.find(skill->mId)->second; int base = stat.getBase(); int modified = stat.getModified(); @@ -394,15 +395,11 @@ namespace MWGui if (!mRaceId.empty()) race = MWBase::Environment::get().getESMStore()->get().find(mRaceId); - int skills[ESM::Skill::Length]; - for (int i = 0; i < ESM::Skill::Length; ++i) - skills[i] = mSkillValues.find(i)->second.getBase(); - int attributes[ESM::Attribute::Length]; for (int i = 0; i < ESM::Attribute::Length; ++i) attributes[i] = mAttributeWidgets[i]->getAttributeValue().getBase(); - std::vector selectedSpells = MWMechanics::autoCalcPlayerSpells(skills, attributes, race); + std::vector selectedSpells = MWMechanics::autoCalcPlayerSpells(mSkillValues, attributes, race); for (ESM::RefId& spellId : selectedSpells) { if (std::find(spells.begin(), spells.end(), spellId) == spells.end()) diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 54044a762a..f0eefb35a7 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -94,7 +94,7 @@ namespace MWGui std::map mAttributeWidgets; SkillList mMajorSkills, mMinorSkills, mMiscSkills; - std::map mSkillValues; + std::map mSkillValues; std::map mSkillWidgetMap; ESM::RefId mRaceId, mBirthSignId; std::string mName; diff --git a/apps/openmw/mwgui/statswatcher.cpp b/apps/openmw/mwgui/statswatcher.cpp index 6ad574a5a2..cd630043d3 100644 --- a/apps/openmw/mwgui/statswatcher.cpp +++ b/apps/openmw/mwgui/statswatcher.cpp @@ -83,13 +83,13 @@ namespace MWGui } } - // Loop over ESM::Skill::SkillEnum - for (int i = 0; i < ESM::Skill::Length; ++i) + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { - if (stats.getSkill(i) != mWatchedSkills[i] || mWatchedStatsEmpty) + const auto& value = stats.getSkill(skill.mId); + if (value != mWatchedSkills[skill.mIndex] || mWatchedStatsEmpty) { - mWatchedSkills[i] = stats.getSkill(i); - setValue((ESM::Skill::SkillEnum)i, stats.getSkill(i)); + mWatchedSkills[skill.mIndex] = value; + setValue(ESM::Skill::SkillEnum(skill.mIndex), value); } } diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index ec6fd49f15..00e330c54c 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -237,7 +237,7 @@ namespace MWGui } } - void setSkillProgress(MyGUI::Widget* w, float progress, int skillId) + void setSkillProgress(MyGUI::Widget* w, float progress, ESM::RefId skillId) { MWWorld::Ptr player = MWMechanics::getPlayer(); const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); @@ -296,8 +296,9 @@ namespace MWGui valueWidget->setUserString("Visible_SkillProgressVBox", "true"); valueWidget->setUserString("UserData^Hidden_SkillProgressVBox", "false"); - setSkillProgress(nameWidget, value.getProgress(), parSkill); - setSkillProgress(valueWidget, value.getProgress(), parSkill); + ESM::RefId id = ESM::Skill::indexToRefId(parSkill); + setSkillProgress(nameWidget, value.getProgress(), id); + setSkillProgress(valueWidget, value.getProgress(), id); } else { diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index e9184978fa..daa8303a69 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -72,7 +72,7 @@ namespace MWGui MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor)); for (const ESM::Skill& skill : skillStore) { - float value = getSkillForTraining(actorStats, skill.mIndex); + float value = getSkillForTraining(actorStats, skill.mId); skills.emplace_back(&skill, value); } @@ -92,7 +92,7 @@ namespace MWGui { const ESM::Skill* skill = skills[i].first; int price = static_cast( - pcStats.getSkill(skill->mIndex).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); + pcStats.getSkill(skill->mId).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); price = std::max(1, price); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); @@ -135,22 +135,22 @@ namespace MWGui const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore(); - int price = pcStats.getSkill(skill->mIndex).getBase() + int price = pcStats.getSkill(skill->mId).getBase() * store.get().find("iTrainingMod")->mValue.getInteger(); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) return; - if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skill->mIndex) - <= pcStats.getSkill(skill->mIndex).getBase()) + if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skill->mId) + <= pcStats.getSkill(skill->mId).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sServiceTrainingWords}"); return; } // You can not train a skill above its governing attribute - if (pcStats.getSkill(skill->mIndex).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) + if (pcStats.getSkill(skill->mId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage17}"); return; @@ -196,11 +196,11 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } - float TrainingWindow::getSkillForTraining(const MWMechanics::NpcStats& stats, int skillId) const + float TrainingWindow::getSkillForTraining(const MWMechanics::NpcStats& stats, ESM::RefId id) const { if (mTrainingSkillBasedOnBaseSkill) - return stats.getSkill(skillId).getBase(); - return stats.getSkill(skillId).getModified(); + return stats.getSkill(id).getBase(); + return stats.getSkill(id).getModified(); } void TrainingWindow::onFrame(float dt) diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp index 145c326150..c169022b25 100644 --- a/apps/openmw/mwgui/trainingwindow.hpp +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -42,7 +42,7 @@ namespace MWGui // Retrieve the base skill value if the setting 'training skills based on base skill' is set; // otherwise returns the modified skill - float getSkillForTraining(const MWMechanics::NpcStats& stats, int skillId) const; + float getSkillForTraining(const MWMechanics::NpcStats& stats, ESM::RefId id) const; MyGUI::Widget* mTrainingOptions; MyGUI::Button* mCancelButton; diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index eddd366fd0..817703728e 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -25,8 +25,8 @@ namespace using SelfObject = MWLua::SelfObject; using ObjectVariant = MWLua::ObjectVariant; - template - auto addIndexedAccessor(int index) + template + auto addIndexedAccessor(I index) { return [index](const sol::object& o) { return T::create(ObjectVariant(o), index); }; } @@ -228,37 +228,36 @@ namespace MWLua class SkillStat { ObjectVariant mObject; - int mIndex; + ESM::RefId mId; - SkillStat(ObjectVariant object, int index) + SkillStat(ObjectVariant object, ESM::RefId id) : mObject(std::move(object)) - , mIndex(index) + , mId(id) { } - static float getProgress(const MWWorld::Ptr& ptr, int index, const MWMechanics::SkillValue& stat) + static float getProgress(const MWWorld::Ptr& ptr, ESM::RefId id, const MWMechanics::SkillValue& stat) { float progress = stat.getProgress(); if (progress != 0.f) - progress /= getMaxProgress(ptr, index, stat); + progress /= getMaxProgress(ptr, id, stat); return progress; } - static float getMaxProgress(const MWWorld::Ptr& ptr, int index, const MWMechanics::SkillValue& stat) + static float getMaxProgress(const MWWorld::Ptr& ptr, ESM::RefId id, const MWMechanics::SkillValue& stat) { const auto& store = *MWBase::Environment::get().getESMStore(); const auto cl = store.get().find(ptr.get()->mBase->mClass); - return ptr.getClass().getNpcStats(ptr).getSkillProgressRequirement(index, *cl); + return ptr.getClass().getNpcStats(ptr).getSkillProgressRequirement(id, *cl); } public: template sol::object get(const Context& context, std::string_view prop, G getter) const { - return getValue( - context, mObject, &SkillStat::setValue, mIndex, prop, [this, getter](const MWWorld::Ptr& ptr) { - return (ptr.getClass().getNpcStats(ptr).getSkill(mIndex).*getter)(); - }); + return getValue(context, mObject, &SkillStat::setValue, mId.getIf()->getValue(), prop, + [this, getter]( + const MWWorld::Ptr& ptr) { return (ptr.getClass().getNpcStats(ptr).getSkill(mId).*getter)(); }); } float getModified(const Context& context) const @@ -271,30 +270,33 @@ namespace MWLua sol::object getProgress(const Context& context) const { - return getValue( - context, mObject, &SkillStat::setValue, mIndex, "progress", [this](const MWWorld::Ptr& ptr) { - return getProgress(ptr, mIndex, ptr.getClass().getNpcStats(ptr).getSkill(mIndex)); + return getValue(context, mObject, &SkillStat::setValue, mId.getIf()->getValue(), + "progress", [this](const MWWorld::Ptr& ptr) { + return getProgress(ptr, mId, ptr.getClass().getNpcStats(ptr).getSkill(mId)); }); } - static std::optional create(ObjectVariant object, int index) + static std::optional create(ObjectVariant object, ESM::RefId id) { if (!object.ptr().getClass().isNpc()) return {}; - return SkillStat{ std::move(object), index }; + return SkillStat{ std::move(object), id }; } void cache(const Context& context, std::string_view prop, const sol::object& value) const { SelfObject* obj = mObject.asSelfObject(); addStatUpdateAction(context.mLuaManager, *obj); - obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mIndex, prop }] = value; + obj->mStatsCache[SelfObject::CachedStat{ + &SkillStat::setValue, int(mId.getIf()->getValue()), prop }] + = value; } static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { + ESM::RefId id = ESM::Skill::indexToRefId(index); auto& stats = ptr.getClass().getNpcStats(ptr); - auto stat = stats.getSkill(index); + auto stat = stats.getSkill(id); float floatValue = LuaUtil::cast(value); if (prop == "base") stat.setBase(floatValue); @@ -306,8 +308,8 @@ namespace MWLua else if (prop == "modifier") stat.setModifier(floatValue); else if (prop == "progress") - stat.setProgress(floatValue * getMaxProgress(ptr, index, stat)); - stats.setSkill(index, stat); + stat.setProgress(floatValue * getMaxProgress(ptr, id, stat)); + stats.setSkill(id, stat); } }; } @@ -385,7 +387,8 @@ namespace MWLua [context](const SkillStat& stat, const sol::object& value) { stat.cache(context, "progress", value); }); sol::table skills(context.mLua->sol(), sol::create); npcStats["skills"] = LuaUtil::makeReadOnly(skills); - for (int id = ESM::Skill::Block; id < ESM::Skill::Length; ++id) - skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[id])] = addIndexedAccessor(id); + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) + skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[skill.mIndex])] + = addIndexedAccessor(skill.mId); } } diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index e2ad06854d..c0be97c9a9 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -27,7 +27,8 @@ namespace MWMechanics ESM::RefId mWeakestSpell; }; - std::vector autoCalcNpcSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race) + std::vector autoCalcNpcSpells( + const std::map& actorSkills, const int* actorAttributes, const ESM::Race* race) { const MWWorld::Store& gmst = MWBase::Environment::get().getESMStore()->get(); @@ -148,7 +149,7 @@ namespace MWMechanics } std::vector autoCalcPlayerSpells( - const int* actorSkills, const int* actorAttributes, const ESM::Race* race) + const std::map& actorSkills, const int* actorAttributes, const ESM::Race* race) { const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); @@ -226,7 +227,8 @@ namespace MWMechanics return selectedSpells; } - bool attrSkillCheck(const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes) + bool attrSkillCheck( + const ESM::Spell* spell, const std::map& actorSkills, const int* actorAttributes) { for (const auto& spellEffect : spell->mEffects.mList) { @@ -240,8 +242,9 @@ namespace MWMechanics if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)) { - assert(spellEffect.mSkill >= 0 && spellEffect.mSkill < ESM::Skill::Length); - if (actorSkills[spellEffect.mSkill] < iAutoSpellAttSkillMin) + ESM::RefId skill = ESM::Skill::indexToRefId(spellEffect.mSkill); + auto found = actorSkills.find(skill); + if (found == actorSkills.end() || found->second.getBase() < iAutoSpellAttSkillMin) return false; } @@ -256,7 +259,8 @@ namespace MWMechanics return true; } - void calcWeakestSchool(const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm) + void calcWeakestSchool(const ESM::Spell* spell, const std::map& actorSkills, + int& effectiveSchool, float& skillTerm) { // Morrowind for some reason uses a formula slightly different from magicka cost calculation float minChance = std::numeric_limits::max(); @@ -294,7 +298,11 @@ namespace MWMechanics if (effect.mRange == ESM::RT_Target) x *= 1.5f; - float s = 2.f * actorSkills[spellSchoolToSkill(magicEffect->mData.mSchool)]; + float s = 0.f; + ESM::RefId skill = ESM::Skill::indexToRefId(spellSchoolToSkill(magicEffect->mData.mSchool)); + auto found = actorSkills.find(skill); + if (found != actorSkills.end()) + s = 2.f * found->second.getBase(); if (s - x < minChance) { minChance = s - x; @@ -304,8 +312,8 @@ namespace MWMechanics } } - float calcAutoCastChance( - const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, int effectiveSchool) + float calcAutoCastChance(const ESM::Spell* spell, const std::map& actorSkills, + const int* actorAttributes, int effectiveSchool) { if (spell->mData.mType != ESM::Spell::ST_Spell) return 100.f; @@ -314,8 +322,10 @@ namespace MWMechanics return 100.f; float skillTerm = 0; - if (effectiveSchool != -1) - skillTerm = 2.f * actorSkills[spellSchoolToSkill(effectiveSchool)]; + ESM::RefId skill = ESM::Skill::indexToRefId(spellSchoolToSkill(effectiveSchool)); + auto found = actorSkills.find(skill); + if (found != actorSkills.end()) + skillTerm = 2.f * found->second.getBase(); else calcWeakestSchool( spell, actorSkills, effectiveSchool, skillTerm); // Note effectiveSchool is unused after this diff --git a/apps/openmw/mwmechanics/autocalcspell.hpp b/apps/openmw/mwmechanics/autocalcspell.hpp index c445321623..4c445b01ab 100644 --- a/apps/openmw/mwmechanics/autocalcspell.hpp +++ b/apps/openmw/mwmechanics/autocalcspell.hpp @@ -1,9 +1,12 @@ #ifndef OPENMW_AUTOCALCSPELL_H #define OPENMW_AUTOCALCSPELL_H +#include "creaturestats.hpp" #include +#include #include #include + namespace ESM { struct Spell; @@ -17,19 +20,21 @@ namespace MWMechanics /// @note We might want to move this code to a component later, so the editor can use it for preview purposes std::vector autoCalcNpcSpells( - const int* actorSkills, const int* actorAttributes, const ESM::Race* race); + const std::map& actorSkills, const int* actorAttributes, const ESM::Race* race); std::vector autoCalcPlayerSpells( - const int* actorSkills, const int* actorAttributes, const ESM::Race* race); + const std::map& actorSkills, const int* actorAttributes, const ESM::Race* race); // Helpers - bool attrSkillCheck(const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes); + bool attrSkillCheck( + const ESM::Spell* spell, const std::map& actorSkills, const int* actorAttributes); - void calcWeakestSchool(const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm); + void calcWeakestSchool(const ESM::Spell* spell, const std::map& actorSkills, + int& effectiveSchool, float& skillTerm); - float calcAutoCastChance( - const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, int effectiveSchool); + float calcAutoCastChance(const ESM::Spell* spell, const std::map& actorSkills, + const int* actorAttributes, int effectiveSchool); } diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 917d06bea6..06c3cb603b 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -122,7 +122,8 @@ namespace MWMechanics if (weapon.isEmpty()) attackerSkill = attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand); else - attackerSkill = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon)); + attackerSkill = attacker.getClass().getSkill( + attacker, ESM::Skill::indexToRefId(weapon.getClass().getEquipmentSkill(weapon))); float attackerTerm = attackerSkill + 0.2f * attackerStats.getAttribute(ESM::Attribute::Agility).getModified() + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); attackerTerm *= attackerStats.getFatigueTerm(); @@ -227,7 +228,7 @@ namespace MWMechanics if (attacker == getPlayer()) MWBase::Environment::get().getWindowManager()->setEnemy(victim); - int skillValue = attacker.getClass().getSkill(attacker, weaponSkill); + int skillValue = attacker.getClass().getSkill(attacker, ESM::Skill::indexToRefId(weaponSkill)); if (Misc::Rng::roll0to99(world->getPrng()) >= getHitChance(attacker, victim, skillValue)) { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 0fa85b9b97..4e2fe047f6 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -129,7 +129,7 @@ namespace MWMechanics creatureStats.getActiveSpells().clear(ptr); for (size_t i = 0; i < player->mNpdt.mSkills.size(); ++i) - npcStats.getSkill(i).setBase(player->mNpdt.mSkills[i]); + npcStats.getSkill(ESM::Skill::indexToRefId(i)).setBase(player->mNpdt.mSkills[i]); creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt.mStrength); creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt.mIntelligence); @@ -164,7 +164,7 @@ namespace MWMechanics if (bonusIt != race->mData.mBonus.end()) bonus = bonusIt->mBonus; - npcStats.getSkill(skill.mIndex).setBase(5 + bonus); + npcStats.getSkill(skill.mId).setBase(5 + bonus); } for (const ESM::RefId& power : race->mPowers.mList) @@ -205,19 +205,16 @@ namespace MWMechanics for (const auto& skills : class_->mData.mSkills) { - int index = skills[i]; - - if (index >= 0 && index < ESM::Skill::Length) - { - npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + bonus); - } + ESM::RefId id = ESM::Skill::indexToRefId(skills[i]); + if (!id.empty()) + npcStats.getSkill(id).setBase(npcStats.getSkill(id).getBase() + bonus); } } for (const ESM::Skill& skill : esmStore.get()) { if (skill.mData.mSpecialization == class_->mData.mSpecialization) - npcStats.getSkill(skill.mIndex).setBase(npcStats.getSkill(skill.mIndex).getBase() + 5); + npcStats.getSkill(skill.mId).setBase(npcStats.getSkill(skill.mId).getBase() + 5); } } @@ -226,16 +223,12 @@ namespace MWMechanics if (mRaceSelected) race = esmStore.get().find(player->mRace); - int skills[ESM::Skill::Length]; - for (int i = 0; i < ESM::Skill::Length; ++i) - skills[i] = npcStats.getSkill(i).getBase(); - int attributes[ESM::Attribute::Length]; for (int i = 0; i < ESM::Attribute::Length; ++i) attributes[i] = npcStats.getAttribute(i).getBase(); npcStats.updateHealth(); - std::vector selectedSpells = autoCalcPlayerSpells(skills, attributes, race); + std::vector selectedSpells = autoCalcPlayerSpells(npcStats.getSkills(), attributes, race); for (const ESM::RefId& spell : selectedSpells) creatureStats.getSpells().add(spell); @@ -1914,7 +1907,7 @@ namespace MWMechanics const ESM::Skill* acrobatics = MWBase::Environment::get().getESMStore()->get().find(ESM::Skill::Acrobatics); MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); - auto& skill = stats.getSkill(acrobatics->mIndex); + auto& skill = stats.getSkill(acrobatics->mId); skill.setModifier(acrobatics->mWerewolfValue - skill.getModified()); } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index e9812e7931..e52f8232c3 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -30,6 +30,8 @@ MWMechanics::NpcStats::NpcStats() { mSkillIncreases.resize(ESM::Attribute::Length, 0); mSpecIncreases.resize(3, 0); + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) + mSkills.emplace(skill.mId, SkillValue{}); } int MWMechanics::NpcStats::getBaseDisposition() const @@ -42,28 +44,28 @@ void MWMechanics::NpcStats::setBaseDisposition(int disposition) mDisposition = disposition; } -const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(int index) const +const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(ESM::RefId id) const { - if (index < 0 || index >= ESM::Skill::Length) - throw std::runtime_error("skill index out of range"); - - return mSkill[index]; + auto it = mSkills.find(id); + if (it == mSkills.end()) + throw std::runtime_error("skill not found"); + return it->second; } -MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(int index) +MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(ESM::RefId id) { - if (index < 0 || index >= ESM::Skill::Length) - throw std::runtime_error("skill index out of range"); - - return mSkill[index]; + auto it = mSkills.find(id); + if (it == mSkills.end()) + throw std::runtime_error("skill not found"); + return it->second; } -void MWMechanics::NpcStats::setSkill(int index, const MWMechanics::SkillValue& value) +void MWMechanics::NpcStats::setSkill(ESM::RefId id, const MWMechanics::SkillValue& value) { - if (index < 0 || index >= ESM::Skill::Length) - throw std::runtime_error("skill index out of range"); - - mSkill[index] = value; + auto it = mSkills.find(id); + if (it == mSkills.end()) + throw std::runtime_error("skill not found"); + it->second = value; } const std::map& MWMechanics::NpcStats::getFactionRanks() const @@ -154,22 +156,23 @@ void MWMechanics::NpcStats::setFactionReputation(const ESM::RefId& faction, int mFactionReputation[faction] = value; } -float MWMechanics::NpcStats::getSkillProgressRequirement(int skillIndex, const ESM::Class& class_) const +float MWMechanics::NpcStats::getSkillProgressRequirement(ESM::RefId id, const ESM::Class& class_) const { - float progressRequirement = static_cast(1 + getSkill(skillIndex).getBase()); + float progressRequirement = 1.f + getSkill(id).getBase(); const MWWorld::Store& gmst = MWBase::Environment::get().getESMStore()->get(); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(id); float typeFactor = gmst.find("fMiscSkillBonus")->mValue.getFloat(); for (const auto& skills : class_.mData.mSkills) { - if (skills[0] == skillIndex) + if (skills[0] == skill->mIndex) { typeFactor = gmst.find("fMinorSkillBonus")->mValue.getFloat(); break; } - else if (skills[1] == skillIndex) + else if (skills[1] == skill->mIndex) { typeFactor = gmst.find("fMajorSkillBonus")->mValue.getFloat(); break; @@ -183,7 +186,6 @@ float MWMechanics::NpcStats::getSkillProgressRequirement(int skillIndex, const E float specialisationFactor = 1; - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); if (skill->mData.mSpecialization == class_.mData.mSpecialization) { specialisationFactor = gmst.find("fSpecialSkillBonus")->mValue.getFloat(); @@ -210,11 +212,11 @@ void MWMechanics::NpcStats::useSkill(int skillIndex, const ESM::Class& class_, i } skillGain *= extraFactor; - MWMechanics::SkillValue& value = getSkill(skillIndex); + MWMechanics::SkillValue& value = getSkill(skill->mId); value.setProgress(value.getProgress() + skillGain); - if (int(value.getProgress()) >= int(getSkillProgressRequirement(skillIndex, class_))) + if (int(value.getProgress()) >= int(getSkillProgressRequirement(skill->mId, class_))) { // skill levelled up increaseSkill(skillIndex, class_, false); @@ -224,7 +226,8 @@ void MWMechanics::NpcStats::useSkill(int skillIndex, const ESM::Class& class_, i void MWMechanics::NpcStats::increaseSkill( int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook) { - float base = getSkill(skillIndex).getBase(); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); + float base = getSkill(skill->mId).getBase(); if (base >= 100.f) return; @@ -251,7 +254,6 @@ void MWMechanics::NpcStats::increaseSkill( } } - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); mSkillIncreases[skill->mData.mAttribute] += increase; mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->mValue.getInteger(); @@ -275,9 +277,9 @@ void MWMechanics::NpcStats::increaseSkill( MWBase::Environment::get().getWindowManager()->messageBox("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never); } - getSkill(skillIndex).setBase(base); + getSkill(skill->mId).setBase(base); if (!preserveProgress) - getSkill(skillIndex).setProgress(0); + getSkill(skill->mId).setProgress(0); } int MWMechanics::NpcStats::getLevelProgress() const @@ -388,9 +390,10 @@ bool MWMechanics::NpcStats::hasSkillsForRank(const ESM::RefId& factionId, int ra std::vector skills; - for (int id : faction.mData.mSkills) + for (int index : faction.mData.mSkills) { - if (id != -1) + ESM::RefId id = ESM::Skill::indexToRefId(index); + if (!id.empty()) skills.push_back(static_cast(getSkill(id).getBase())); } @@ -470,8 +473,12 @@ void MWMechanics::NpcStats::writeState(ESM::NpcStats& state) const state.mDisposition = mDisposition; - for (size_t i = 0; i < state.mSkills.size(); ++i) - mSkill[i].writeState(state.mSkills[i]); + for (const auto& [id, value] : mSkills) + { + // TODO extend format + auto index = id.getIf()->getValue(); + value.writeState(state.mSkills[index]); + } state.mIsWerewolf = mIsWerewolf; @@ -524,7 +531,11 @@ void MWMechanics::NpcStats::readState(const ESM::NpcStats& state) mDisposition = state.mDisposition; for (size_t i = 0; i < state.mSkills.size(); ++i) - mSkill[i].readState(state.mSkills[i]); + { + // TODO extend format + ESM::RefId id = ESM::Skill::indexToRefId(i); + mSkills[id].readState(state.mSkills[i]); + } mIsWerewolf = state.mIsWerewolf; diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 57f4bbd1e4..ddf677c665 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -3,6 +3,7 @@ #include "creaturestats.hpp" #include +#include #include #include #include @@ -21,7 +22,7 @@ namespace MWMechanics class NpcStats : public CreatureStats { int mDisposition; - SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only + std::map mSkills; // SkillValue.mProgress used by the player only int mReputation; int mCrimeId; @@ -58,9 +59,13 @@ namespace MWMechanics int getCrimeId() const; void setCrimeId(int id); - const SkillValue& getSkill(int index) const; - SkillValue& getSkill(int index); - void setSkill(int index, const SkillValue& value); + const SkillValue& getSkill(ESM::RefId id) const; + const SkillValue& getSkill(ESM::Skill::SkillEnum index) const + { + return getSkill(ESM::Skill::indexToRefId(index)); + } + SkillValue& getSkill(ESM::RefId id); + void setSkill(ESM::RefId id, const SkillValue& value); int getFactionRank(const ESM::RefId& faction) const; const std::map& getFactionRanks() const; @@ -79,7 +84,7 @@ namespace MWMechanics bool isInFaction(const ESM::RefId& faction) const; - float getSkillProgressRequirement(int skillIndex, const ESM::Class& class_) const; + float getSkillProgressRequirement(ESM::RefId id, const ESM::Class& class_) const; void useSkill(int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor = 1.f); ///< Increase skill by usage. @@ -133,6 +138,8 @@ namespace MWMechanics void readState(const ESM::CreatureStats& state); void readState(const ESM::NpcStats& state); + + const std::map& getSkills() const { return mSkills; } }; } diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index 3afe220a24..fe1e073aac 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -105,7 +105,7 @@ namespace void damageSkill(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect, float magnitude) { auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); if (effect.mEffectId == ESM::MagicEffect::DamageSkill) magnitude = std::min(skill.getModified(), magnitude); skill.damage(magnitude); @@ -114,14 +114,14 @@ namespace void restoreSkill(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect, float magnitude) { auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); skill.restore(magnitude); } void fortifySkill(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect, float magnitude) { auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); skill.setModifier(skill.getModifier() + magnitude); } @@ -668,7 +668,7 @@ namespace MWMechanics if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) { auto& npcStats = target.getClass().getNpcStats(target); - SkillValue& skill = npcStats.getSkill(effect.mArg); + SkillValue& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); // Damage Skill abilities reduce base skill :todd: skill.setBase(std::max(skill.getBase() - effect.mMagnitude, 0.f)); } @@ -760,7 +760,7 @@ namespace MWMechanics { // Abilities affect base stats, but not for drain auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); skill.setBase(skill.getBase() + effect.mMagnitude); } else @@ -1218,7 +1218,7 @@ namespace MWMechanics if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) { auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(effect.mArg)); skill.setBase(skill.getBase() - effect.mMagnitude); } else diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 4e813ec37c..79f8d315ab 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -565,7 +565,7 @@ namespace MWMechanics case ESM::MagicEffect::DrainSkill: if (enemy.isEmpty() || !enemy.getClass().isNpc()) return 0.f; - if (enemy.getClass().getSkill(enemy, effect.mSkill) <= 0) + if (enemy.getClass().getSkill(enemy, ESM::Skill::indexToRefId(effect.mSkill)) <= 0) return 0.f; break; diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 14ee1d7c02..3fa4d454fa 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -120,8 +120,8 @@ namespace MWMechanics int value = 50.f; if (actor.getClass().isNpc()) { - int skill = item.getClass().getEquipmentSkill(item); - if (skill != -1) + ESM::RefId skill = ESM::Skill::indexToRefId(item.getClass().getEquipmentSkill(item)); + if (!skill.empty()) value = actor.getClass().getSkill(actor, skill); } else @@ -179,7 +179,9 @@ namespace MWMechanics if (weapon.isEmpty()) return 0.f; - float skillMult = actor.getClass().getSkill(actor, weapon.getClass().getEquipmentSkill(weapon)) * 0.01f; + float skillMult + = actor.getClass().getSkill(actor, ESM::Skill::indexToRefId(weapon.getClass().getEquipmentSkill(weapon))) + * 0.01f; float chopMult = fAIMeleeWeaponMult; float bonusDamage = 0.f; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 877fa79099..a3d2d89220 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -345,11 +345,11 @@ namespace MWScript template class OpGetSkill : public Interpreter::Opcode0 { - int mIndex; + ESM::RefId mId; public: - OpGetSkill(int index) - : mIndex(index) + OpGetSkill(ESM::RefId id) + : mId(id) { } @@ -357,7 +357,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mIndex); + Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mId); runtime.push(value); } @@ -366,11 +366,11 @@ namespace MWScript template class OpSetSkill : public Interpreter::Opcode0 { - int mIndex; + ESM::RefId mId; public: - OpSetSkill(int index) - : mIndex(index) + OpSetSkill(ESM::RefId id) + : mId(id) { } @@ -383,18 +383,18 @@ namespace MWScript MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats(ptr); - stats.getSkill(mIndex).setBase(value, true); + stats.getSkill(mId).setBase(value, true); } }; template class OpModSkill : public Interpreter::Opcode0 { - int mIndex; + ESM::RefId mId; public: - OpModSkill(int index) - : mIndex(index) + OpModSkill(ESM::RefId id) + : mId(id) { } @@ -405,7 +405,7 @@ namespace MWScript Interpreter::Type_Float value = runtime[0].mFloat; runtime.pop(); - MWMechanics::SkillValue& skill = ptr.getClass().getNpcStats(ptr).getSkill(mIndex); + MWMechanics::SkillValue& skill = ptr.getClass().getNpcStats(ptr).getSkill(mId); modStat(skill, value); } }; @@ -1364,14 +1364,15 @@ namespace MWScript for (int i = 0; i < Compiler::Stats::numberOfSkills; ++i) { - interpreter.installSegment5>(Compiler::Stats::opcodeGetSkill + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeGetSkillExplicit + i, i); + ESM::RefId id = ESM::Skill::indexToRefId(i); + interpreter.installSegment5>(Compiler::Stats::opcodeGetSkill + i, id); + interpreter.installSegment5>(Compiler::Stats::opcodeGetSkillExplicit + i, id); - interpreter.installSegment5>(Compiler::Stats::opcodeSetSkill + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeSetSkillExplicit + i, i); + interpreter.installSegment5>(Compiler::Stats::opcodeSetSkill + i, id); + interpreter.installSegment5>(Compiler::Stats::opcodeSetSkillExplicit + i, id); - interpreter.installSegment5>(Compiler::Stats::opcodeModSkill + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeModSkillExplicit + i, i); + interpreter.installSegment5>(Compiler::Stats::opcodeModSkill + i, id); + interpreter.installSegment5>(Compiler::Stats::opcodeModSkillExplicit + i, id); } interpreter.installSegment5(Compiler::Stats::opcodeGetPCCrimeLevel); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 28777656c8..bb91e66b86 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -438,7 +438,7 @@ namespace MWWorld return canSwim(ptr) || canWalk(ptr) || canFly(ptr); } - float Class::getSkill(const MWWorld::Ptr& ptr, int skill) const + float Class::getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const { throw std::runtime_error("class does not support skills"); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 59f228a4d4..eaaf19d135 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -14,6 +14,7 @@ #include "../mwmechanics/aisetting.hpp" #include +#include namespace ESM { @@ -340,7 +341,11 @@ namespace MWWorld bool isPureLandCreature(const MWWorld::Ptr& ptr) const; bool isMobile(const MWWorld::Ptr& ptr) const; - virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const; + virtual float getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const; + float getSkill(const MWWorld::Ptr& ptr, ESM::Skill::SkillEnum index) const + { + return getSkill(ptr, ESM::Skill::indexToRefId(index)); + }; virtual void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const; ///< Read additional state from \a state into \a ptr. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 34a298ae0d..5ec18557ac 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -285,7 +285,7 @@ void MWWorld::InventoryStore::autoEquipWeapon(TSlots& slots_) for (int j = 0; j < static_cast(weaponSkillsLength); ++j) { - float skillValue = mActor.getClass().getSkill(mActor, static_cast(weaponSkills[j])); + float skillValue = mActor.getClass().getSkill(mActor, weaponSkills[j]); if (skillValue > max && !weaponSkillVisited[j]) { max = skillValue; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 2d7617adfa..ea1ada7689 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -59,23 +59,23 @@ namespace MWWorld { MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer()); - for (int i = 0; i < ESM::Skill::Length; ++i) - mSaveSkills[i] = stats.getSkill(i).getModified(); + for (size_t i = 0; i < mSaveSkills.size(); ++i) + mSaveSkills[i] = stats.getSkill(ESM::Skill::indexToRefId(i)).getModified(); for (int i = 0; i < ESM::Attribute::Length; ++i) mSaveAttributes[i] = stats.getAttribute(i).getModified(); } void Player::restoreStats() { - const MWWorld::Store& gmst - = MWBase::Environment::get().getESMStore()->get(); + const auto& store = MWBase::Environment::get().getESMStore(); + const MWWorld::Store& gmst = store->get(); MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat health = creatureStats.getDynamic(0); creatureStats.setHealth(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat()); - for (int i = 0; i < ESM::Skill::Length; ++i) + for (size_t i = 0; i < mSaveSkills.size(); ++i) { - auto& skill = npcStats.getSkill(i); + auto& skill = npcStats.getSkill(ESM::Skill::indexToRefId(i)); skill.restore(skill.getDamage()); skill.setModifier(mSaveSkills[i] - skill.getBase()); } @@ -109,7 +109,7 @@ namespace MWWorld if (skill.mIndex == ESM::Skill::Acrobatics) continue; - MWMechanics::SkillValue& value = npcStats.getSkill(skill.mIndex); + MWMechanics::SkillValue& value = npcStats.getSkill(skill.mId); value.setModifier(skill.mWerewolfValue - value.getModified()); } } @@ -251,10 +251,7 @@ namespace MWWorld mPreviousItems.clear(); mLastKnownExteriorPosition = osg::Vec3f(0, 0, 0); - for (int i = 0; i < ESM::Skill::Length; ++i) - { - mSaveSkills[i] = 0.f; - } + mSaveSkills.fill(0.f); for (int i = 0; i < ESM::Attribute::Length; ++i) { @@ -296,7 +293,7 @@ namespace MWWorld for (int i = 0; i < ESM::Attribute::Length; ++i) player.mSaveAttributes[i] = mSaveAttributes[i]; - for (int i = 0; i < ESM::Skill::Length; ++i) + for (size_t i = 0; i < mSaveSkills.size(); ++i) player.mSaveSkills[i] = mSaveSkills[i]; player.mPreviousItems = mPreviousItems; @@ -334,7 +331,7 @@ namespace MWWorld for (int i = 0; i < ESM::Attribute::Length; ++i) mSaveAttributes[i] = player.mSaveAttributes[i]; - for (int i = 0; i < ESM::Skill::Length; ++i) + for (size_t i = 0; i < mSaveSkills.size(); ++i) mSaveSkills[i] = player.mSaveSkills[i]; if (player.mObject.mNpcStats.mIsWerewolf) diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 913ff00b02..12eadab10f 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -1,6 +1,7 @@ #ifndef GAME_MWWORLD_PLAYER_H #define GAME_MWWORLD_PLAYER_H +#include #include #include "../mwworld/livecellref.hpp" @@ -50,7 +51,7 @@ namespace MWWorld PreviousItems mPreviousItems; // Saved stats prior to becoming a werewolf - float mSaveSkills[ESM::Skill::Length]; + std::array mSaveSkills; float mSaveAttributes[ESM::Attribute::Length]; bool mJumping; From 28025e84f764a26d31796bd8c602aa2caef02471 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 5 Jun 2023 22:29:12 +0200 Subject: [PATCH 04/15] Replace more instances of ESM::Skill::Length --- apps/openmw/mwclass/npc.cpp | 25 +++++++++++-------------- apps/openmw/mwworld/magiceffects.cpp | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ebab5bfb9c..18d616de27 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -111,20 +111,18 @@ namespace { float modifierSum = 0; - for (int j = 0; j < ESM::Skill::Length; ++j) + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(j); - - if (skill->mData.mAttribute != attribute) + if (skill.mData.mAttribute != attribute) continue; // is this a minor or major skill? float add = 0.2f; for (const auto& skills : class_->mData.mSkills) { - if (skills[0] == j) + if (skills[0] == skill.mIndex) add = 0.5; - if (skills[1] == j) + if (skills[1] == skill.mIndex) add = 1.0; } modifierSum += add; @@ -189,7 +187,7 @@ namespace } } - for (int skillIndex = 0; skillIndex < ESM::Skill::Length; ++skillIndex) + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { float majorMultiplier = 0.1f; float specMultiplier = 0.0f; @@ -198,14 +196,14 @@ namespace int specBonus = 0; auto bonusIt = std::find_if(race->mData.mBonus.begin(), race->mData.mBonus.end(), - [skillIndex](const auto& bonus) { return bonus.mSkill == skillIndex; }); + [&](const auto& bonus) { return bonus.mSkill == skill.mIndex; }); 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(), skillIndex) != skills.end()) + if (std::find(skills.begin(), skills.end(), skill.mIndex) != skills.end()) { majorMultiplier = 1.0f; break; @@ -213,16 +211,15 @@ namespace } // is this skill in the same Specialization as the class? - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); - if (skill->mData.mSpecialization == class_->mData.mSpecialization) + if (skill.mData.mSpecialization == class_->mData.mSpecialization) { specMultiplier = 0.5f; specBonus = 5; } - npcStats.getSkill(skill->mId) - .setBase(std::min(round_ieee_754(npcStats.getSkill(skill->mId).getBase() + 5 + raceBonus + specBonus - + (int(level) - 1) * (majorMultiplier + specMultiplier)), + npcStats.getSkill(skill.mId).setBase( + std::min(round_ieee_754(npcStats.getSkill(skill.mId).getBase() + 5 + raceBonus + specBonus + + (int(level) - 1) * (majorMultiplier + specMultiplier)), 100)); // Must gracefully handle level 0 } diff --git a/apps/openmw/mwworld/magiceffects.cpp b/apps/openmw/mwworld/magiceffects.cpp index 77525ad3df..d3e6db10a7 100644 --- a/apps/openmw/mwworld/magiceffects.cpp +++ b/apps/openmw/mwworld/magiceffects.cpp @@ -221,7 +221,7 @@ namespace MWWorld creatureStats.mAiSettings[i].mMod = 0.f; if (npcStats) { - for (std::size_t i = 0; i < ESM::Skill::Length; ++i) + for (std::size_t i = 0; i < npcStats->mSkills.size(); ++i) npcStats->mSkills[i].mMod = 0.f; } } From 1e0ed42294504969ce74bd9fbce7636fd098150c Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 12:35:01 +0200 Subject: [PATCH 05/15] Use RefId for skills in StatsListener --- apps/openmw/mwgui/charactercreation.cpp | 13 ++++++------ apps/openmw/mwgui/charactercreation.hpp | 4 ++-- apps/openmw/mwgui/review.cpp | 10 ++++----- apps/openmw/mwgui/review.hpp | 4 ++-- apps/openmw/mwgui/statswatcher.cpp | 12 +++++------ apps/openmw/mwgui/statswatcher.hpp | 7 ++++--- apps/openmw/mwgui/statswindow.cpp | 27 ++++++++----------------- apps/openmw/mwgui/statswindow.hpp | 6 +++--- 8 files changed, 35 insertions(+), 48 deletions(-) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 9032209aba..fa9b019ca3 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.mIndex, MWMechanics::SkillValue()); + mPlayerSkillValues.emplace(skill.mId, MWMechanics::SkillValue()); } void CharacterCreation::setValue(std::string_view id, const MWMechanics::AttributeValue& value) @@ -138,11 +138,11 @@ namespace MWGui } } - void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) + void CharacterCreation::setValue(ESM::RefId id, const MWMechanics::SkillValue& value) { - mPlayerSkillValues[parSkill] = value; + mPlayerSkillValues[id] = value; if (mReviewDialog) - mReviewDialog->setSkillValue(parSkill, value); + mReviewDialog->setSkillValue(id, value); } void CharacterCreation::configureSkills(const SkillList& major, const SkillList& minor) @@ -275,10 +275,9 @@ namespace MWGui mReviewDialog->setAttribute( static_cast(attributePair.first), attributePair.second); } - for (auto& skillPair : mPlayerSkillValues) + for (const auto& [skill, value] : mPlayerSkillValues) { - mReviewDialog->setSkillValue( - static_cast(skillPair.first), skillPair.second); + mReviewDialog->setSkillValue(skill, value); } mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills); diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index e2e6c3ca26..79cf5a35a7 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -48,7 +48,7 @@ namespace MWGui void setValue(std::string_view id, const MWMechanics::AttributeValue& value) override; void setValue(std::string_view id, const MWMechanics::DynamicStat& value) override; - void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; + void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) override; void configureSkills(const SkillList& major, const SkillList& minor) override; void onFrame(float duration); @@ -59,7 +59,7 @@ namespace MWGui SkillList mPlayerMajorSkills, mPlayerMinorSkills; std::map mPlayerAttributes; - std::map mPlayerSkillValues; + std::map mPlayerSkillValues; // Dialogs std::unique_ptr mNameDialog; diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 02555a4cfe..840ba564be 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -93,7 +93,7 @@ namespace MWGui for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { mSkillValues.emplace(skill.mId, MWMechanics::SkillValue()); - mSkillWidgetMap.emplace(skill.mIndex, static_cast(nullptr)); + mSkillWidgetMap.emplace(skill.mId, static_cast(nullptr)); } MyGUI::Button* backButton; @@ -204,10 +204,10 @@ namespace MWGui } } - void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value) + void ReviewDialog::setSkillValue(ESM::RefId id, const MWMechanics::SkillValue& value) { - mSkillValues[ESM::Skill::indexToRefId(skillId)] = value; - MyGUI::TextBox* widget = mSkillWidgetMap[skillId]; + mSkillValues[id] = value; + MyGUI::TextBox* widget = mSkillWidgetMap[id]; if (widget) { float modified = value.getModified(); @@ -363,7 +363,7 @@ namespace MWGui ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skill->mIndex); } - mSkillWidgetMap[skill->mIndex] = widget; + mSkillWidgetMap[skill->mId] = widget; } } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index f0eefb35a7..44a60bd833 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -42,7 +42,7 @@ namespace MWGui void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::AttributeValue& value); void configureSkills(const SkillList& major, const SkillList& minor); - void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value); + void setSkillValue(ESM::RefId id, const MWMechanics::SkillValue& value); void onOpen() override; @@ -95,7 +95,7 @@ namespace MWGui SkillList mMajorSkills, mMinorSkills, mMiscSkills; std::map mSkillValues; - std::map mSkillWidgetMap; + std::map mSkillWidgetMap; ESM::RefId mRaceId, mBirthSignId; std::string mName; ESM::Class mKlass; diff --git a/apps/openmw/mwgui/statswatcher.cpp b/apps/openmw/mwgui/statswatcher.cpp index cd630043d3..05e170a2ad 100644 --- a/apps/openmw/mwgui/statswatcher.cpp +++ b/apps/openmw/mwgui/statswatcher.cpp @@ -86,10 +86,10 @@ namespace MWGui for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { const auto& value = stats.getSkill(skill.mId); - if (value != mWatchedSkills[skill.mIndex] || mWatchedStatsEmpty) + if (value != mWatchedSkills[skill.mId] || mWatchedStatsEmpty) { - mWatchedSkills[skill.mIndex] = value; - setValue(ESM::Skill::SkillEnum(skill.mIndex), value); + mWatchedSkills[skill.mId] = value; + setValue(skill.mId, value); } } @@ -157,12 +157,10 @@ namespace MWGui listener->setValue(id, value); } - void StatsWatcher::setValue(ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) + void StatsWatcher::setValue(ESM::RefId id, const MWMechanics::SkillValue& value) { - /// \todo Don't use the skill enum as a parameter type (we will have to drop it anyway, once we - /// allow custom skills. for (StatsListener* listener : mListeners) - listener->setValue(parSkill, value); + listener->setValue(id, value); } void StatsWatcher::setValue(std::string_view id, const MWMechanics::DynamicStat& value) diff --git a/apps/openmw/mwgui/statswatcher.hpp b/apps/openmw/mwgui/statswatcher.hpp index da49eed10b..5a7c007020 100644 --- a/apps/openmw/mwgui/statswatcher.hpp +++ b/apps/openmw/mwgui/statswatcher.hpp @@ -1,6 +1,7 @@ #ifndef MWGUI_STATSWATCHER_H #define MWGUI_STATSWATCHER_H +#include #include #include @@ -22,7 +23,7 @@ namespace MWGui virtual void setValue(std::string_view id, const MWMechanics::DynamicStat& value) {} virtual void setValue(std::string_view, const std::string& value) {} virtual void setValue(std::string_view, int value) {} - virtual void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) {} + virtual void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) {} virtual void configureSkills(const std::vector& major, const std::vector& minor) {} }; @@ -31,7 +32,7 @@ namespace MWGui MWWorld::Ptr mWatched; MWMechanics::AttributeValue mWatchedAttributes[ESM::Attribute::Length]; - MWMechanics::SkillValue mWatchedSkills[ESM::Skill::Length]; + std::map mWatchedSkills; MWMechanics::DynamicStat mWatchedHealth; MWMechanics::DynamicStat mWatchedMagicka; @@ -53,7 +54,7 @@ namespace MWGui void setValue(std::string_view id, const MWMechanics::DynamicStat& value); void setValue(std::string_view id, const std::string& value); void setValue(std::string_view id, int value); - void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value); + void setValue(ESM::RefId id, const MWMechanics::SkillValue& value); void configureSkills(const std::vector& major, const std::vector& minor); public: diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 00e330c54c..ac04977177 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -37,17 +37,8 @@ namespace MWGui : WindowPinnableBase("openmw_stats_window.layout") , NoDrop(drag, mMainWidget) , mSkillView(nullptr) - , mMajorSkills() - , mMinorSkills() - , mMiscSkills() - , mSkillValues() - , mSkillWidgetMap() - , mFactionWidgetMap() - , mFactions() - , mBirthSignId() , mReputation(0) , mBounty(0) - , mSkillWidgets() , mChanged(true) , mMinFullWidth(mMainWidget->getSize().width) { @@ -67,11 +58,10 @@ namespace MWGui getWidget(mLeftPane, "LeftPane"); getWidget(mRightPane, "RightPane"); - for (int i = 0; i < ESM::Skill::Length; ++i) + for (const ESM::Skill& skill : store.get()) { - mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert( - std::make_pair(i, std::make_pair((MyGUI::TextBox*)nullptr, (MyGUI::TextBox*)nullptr))); + mSkillValues.emplace(skill.mId, MWMechanics::SkillValue()); + mSkillWidgetMap.emplace(skill.mId, std::make_pair(nullptr, nullptr)); } MyGUI::Window* t = mMainWidget->castType(); @@ -255,10 +245,10 @@ namespace MWGui w->setUserString("RangePosition_SkillProgress", MyGUI::utility::toString(progressPercent)); } - void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) + void StatsWindow::setValue(ESM::RefId id, const MWMechanics::SkillValue& value) { - mSkillValues[parSkill] = value; - std::pair widgets = mSkillWidgetMap[(int)parSkill]; + mSkillValues[id] = value; + std::pair widgets = mSkillWidgetMap[id]; MyGUI::TextBox* valueWidget = widgets.second; MyGUI::TextBox* nameWidget = widgets.first; if (valueWidget && nameWidget) @@ -296,7 +286,6 @@ namespace MWGui valueWidget->setUserString("Visible_SkillProgressVBox", "true"); valueWidget->setUserString("UserData^Hidden_SkillProgressVBox", "false"); - ESM::RefId id = ESM::Skill::indexToRefId(parSkill); setSkillProgress(nameWidget, value.getProgress(), id); setSkillProgress(valueWidget, value.getProgress(), id); } @@ -516,7 +505,7 @@ namespace MWGui std::pair widgets = addValueItem(skill->mName, {}, "normal", coord1, coord2); - mSkillWidgetMap[skillId] = widgets; + mSkillWidgetMap[skill->mId] = widgets; for (int i = 0; i < 2; ++i) { @@ -532,7 +521,7 @@ namespace MWGui mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("Range_SkillProgress", "100"); } - setValue(static_cast(skillId), mSkillValues.find(skillId)->second); + setValue(skill->mId, mSkillValues.find(skill->mId)->second); } } diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index 6a781cd5cc..c497353d9a 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -27,7 +27,7 @@ namespace MWGui void setValue(std::string_view id, const MWMechanics::DynamicStat& value) override; void setValue(std::string_view id, const std::string& value) override; void setValue(std::string_view id, int value) override; - void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; + void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) override; void configureSkills(const SkillList& major, const SkillList& minor) override; void setReputation(int reputation) @@ -68,8 +68,8 @@ namespace MWGui MyGUI::ScrollView* mSkillView; SkillList mMajorSkills, mMinorSkills, mMiscSkills; - std::map mSkillValues; - std::map> mSkillWidgetMap; + std::map mSkillValues; + std::map> mSkillWidgetMap; std::map mFactionWidgetMap; FactionList mFactions; ///< Stores a list of factions and the current rank ESM::RefId mBirthSignId; From 72f8f9d1ad11c9120f534bbf773a898ab1991da1 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 17:02:10 +0200 Subject: [PATCH 06/15] Replace remaining skill indices in NpcStats --- apps/openmw/mwclass/npc.cpp | 9 +++++---- apps/openmw/mwclass/npc.hpp | 2 +- apps/openmw/mwgui/trainingwindow.cpp | 2 +- apps/openmw/mwmechanics/combat.cpp | 2 +- apps/openmw/mwmechanics/npcstats.cpp | 15 +++++++-------- apps/openmw/mwmechanics/npcstats.hpp | 4 ++-- apps/openmw/mwworld/actionapply.cpp | 15 --------------- apps/openmw/mwworld/actionapply.hpp | 12 ------------ apps/openmw/mwworld/actionread.cpp | 7 ++++--- apps/openmw/mwworld/class.cpp | 2 +- apps/openmw/mwworld/class.hpp | 7 ++++++- 11 files changed, 28 insertions(+), 49 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 18d616de27..6b10180add 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -654,7 +654,7 @@ namespace MWClass int weapskill = ESM::Skill::HandToHand; if (!weapon.isEmpty()) weapskill = weapon.getClass().getEquipmentSkill(weapon); - skillUsageSucceeded(ptr, weapskill, 0); + skillUsageSucceeded(ptr, ESM::Skill::indexToRefId(weapskill), 0); const MWMechanics::AiSequence& seq = victim.getClass().getCreatureStats(victim).getAiSequence(); @@ -843,7 +843,8 @@ namespace MWClass } if (ptr == MWMechanics::getPlayer()) - skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0); + skillUsageSucceeded( + ptr, ESM::Skill::indexToRefId(armor.getClass().getEquipmentSkill(armor)), 0); switch (armor.getClass().getEquipmentSkill(armor)) { @@ -859,7 +860,7 @@ namespace MWClass } } else if (ptr == MWMechanics::getPlayer()) - skillUsageSucceeded(ptr, ESM::Skill::Unarmored, 0); + Class::skillUsageSucceeded(ptr, ESM::Skill::Unarmored, 0); } } @@ -1154,7 +1155,7 @@ namespace MWClass return cast.cast(recordId); } - void Npc::skillUsageSucceeded(const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const + void Npc::skillUsageSucceeded(const MWWorld::Ptr& ptr, ESM::RefId skill, int usageType, float extraFactor) const { MWMechanics::NpcStats& stats = getNpcStats(ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 242548ab20..9b53143c4d 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -120,7 +120,7 @@ namespace MWClass /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh void skillUsageSucceeded( - const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor = 1.f) const override; + const MWWorld::Ptr& ptr, ESM::RefId skill, int usageType, float extraFactor = 1.f) const override; ///< Inform actor \a ptr that a skill use has succeeded. bool isEssential(const MWWorld::ConstPtr& ptr) const override; diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index daa8303a69..38ae900841 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -160,7 +160,7 @@ namespace MWGui MWWorld::LiveCellRef* playerRef = player.get(); const ESM::Class* class_ = store.get().find(playerRef->mBase->mClass); - pcStats.increaseSkill(skill->mIndex, *class_, true); + pcStats.increaseSkill(skill->mId, *class_, true); // remove gold player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 06c3cb603b..8556a9380b 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -259,7 +259,7 @@ namespace MWMechanics applyWerewolfDamageMult(victim, projectile, damage); if (attacker == getPlayer()) - attacker.getClass().skillUsageSucceeded(attacker, weaponSkill, 0); + attacker.getClass().skillUsageSucceeded(attacker, ESM::Skill::indexToRefId(weaponSkill), 0); const MWMechanics::AiSequence& sequence = victim.getClass().getCreatureStats(victim).getAiSequence(); bool unaware = attacker == getPlayer() && !sequence.isInCombat() diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index e52f8232c3..b18c7cf616 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -198,9 +198,9 @@ float MWMechanics::NpcStats::getSkillProgressRequirement(ESM::RefId id, const ES return progressRequirement; } -void MWMechanics::NpcStats::useSkill(int skillIndex, const ESM::Class& class_, int usageType, float extraFactor) +void MWMechanics::NpcStats::useSkill(ESM::RefId id, const ESM::Class& class_, int usageType, float extraFactor) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(id); float skillGain = 1; if (usageType >= 4) throw std::runtime_error("skill usage type out of range"); @@ -219,14 +219,13 @@ void MWMechanics::NpcStats::useSkill(int skillIndex, const ESM::Class& class_, i if (int(value.getProgress()) >= int(getSkillProgressRequirement(skill->mId, class_))) { // skill levelled up - increaseSkill(skillIndex, class_, false); + increaseSkill(skill->mId, class_, false); } } -void MWMechanics::NpcStats::increaseSkill( - int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook) +void MWMechanics::NpcStats::increaseSkill(ESM::RefId id, const ESM::Class& class_, bool preserveProgress, bool readBook) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(skillIndex); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().find(id); float base = getSkill(skill->mId).getBase(); if (base >= 100.f) @@ -240,13 +239,13 @@ void MWMechanics::NpcStats::increaseSkill( int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo for (const auto& skills : class_.mData.mSkills) { - if (skills[0] == skillIndex) + if (skills[0] == skill->mIndex) { mLevelProgress += gmst.find("iLevelUpMinorMult")->mValue.getInteger(); increase = gmst.find("iLevelUpMinorMultAttribute")->mValue.getInteger(); break; } - else if (skills[1] == skillIndex) + else if (skills[1] == skill->mIndex) { mLevelProgress += gmst.find("iLevelUpMajorMult")->mValue.getInteger(); increase = gmst.find("iLevelUpMajorMultAttribute")->mValue.getInteger(); diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index ddf677c665..1da46efc87 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -86,10 +86,10 @@ namespace MWMechanics float getSkillProgressRequirement(ESM::RefId id, const ESM::Class& class_) const; - void useSkill(int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor = 1.f); + void useSkill(ESM::RefId id, const ESM::Class& class_, int usageType = -1, float extraFactor = 1.f); ///< Increase skill by usage. - void increaseSkill(int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook = false); + void increaseSkill(ESM::RefId id, const ESM::Class& class_, bool preserveProgress, bool readBook = false); int getLevelProgress() const; diff --git a/apps/openmw/mwworld/actionapply.cpp b/apps/openmw/mwworld/actionapply.cpp index 17c4474727..bf4fce38ce 100644 --- a/apps/openmw/mwworld/actionapply.cpp +++ b/apps/openmw/mwworld/actionapply.cpp @@ -16,19 +16,4 @@ namespace MWWorld { actor.getClass().consume(getTarget(), actor); } - - ActionApplyWithSkill::ActionApplyWithSkill(const Ptr& object, const ESM::RefId& id, int skillIndex, int usageType) - : Action(false, object) - , mId(id) - , mSkillIndex(skillIndex) - , mUsageType(usageType) - { - } - - void ActionApplyWithSkill::executeImp(const Ptr& actor) - { - bool consumed = actor.getClass().consume(getTarget(), actor); - if (consumed && mUsageType != -1 && actor == MWMechanics::getPlayer()) - actor.getClass().skillUsageSucceeded(actor, mSkillIndex, mUsageType); - } } diff --git a/apps/openmw/mwworld/actionapply.hpp b/apps/openmw/mwworld/actionapply.hpp index f585179e6f..645b301915 100644 --- a/apps/openmw/mwworld/actionapply.hpp +++ b/apps/openmw/mwworld/actionapply.hpp @@ -16,18 +16,6 @@ namespace MWWorld public: ActionApply(const Ptr& object, const ESM::RefId& id); }; - - class ActionApplyWithSkill : public Action - { - ESM::RefId mId; - int mSkillIndex; - int mUsageType; - - void executeImp(const Ptr& actor) override; - - public: - ActionApplyWithSkill(const Ptr& object, const ESM::RefId& id, int skillIndex, int usageType); - }; } #endif diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 10614f48da..e621eb3836 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -46,15 +47,15 @@ namespace MWWorld MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor); // Skill gain from books - if (ref->mBase->mData.mSkillId >= 0 && ref->mBase->mData.mSkillId < ESM::Skill::Length - && !npcStats.hasBeenUsed(ref->mBase->mId)) + ESM::RefId skill = ESM::Skill::indexToRefId(ref->mBase->mData.mSkillId); + if (!skill.empty() && !npcStats.hasBeenUsed(ref->mBase->mId)) { MWWorld::LiveCellRef* playerRef = actor.get(); const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get().find(playerRef->mBase->mClass); - npcStats.increaseSkill(ref->mBase->mData.mSkillId, *class_, true, true); + npcStats.increaseSkill(skill, *class_, true, true); npcStats.flagAsUsed(ref->mBase->mId); } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index bb91e66b86..8279d01582 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -52,7 +52,7 @@ namespace MWWorld return false; } - void Class::skillUsageSucceeded(const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const + void Class::skillUsageSucceeded(const MWWorld::Ptr& ptr, ESM::RefId skill, int usageType, float extraFactor) const { throw std::runtime_error("class does not represent an actor"); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index eaaf19d135..d46e7d9578 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -235,10 +235,15 @@ namespace MWWorld ///< Consume an item, e. g. a potion. virtual void skillUsageSucceeded( - const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor = 1.f) const; + const MWWorld::Ptr& ptr, ESM::RefId skill, int usageType, float extraFactor = 1.f) const; ///< Inform actor \a ptr that a skill use has succeeded. /// /// (default implementations: throws an exception) + void skillUsageSucceeded( + const MWWorld::Ptr& ptr, ESM::Skill::SkillEnum index, int usageType, float extraFactor = 1.f) const + { + return skillUsageSucceeded(ptr, ESM::Skill::indexToRefId(index), usageType, extraFactor); + }; virtual bool isEssential(const MWWorld::ConstPtr& ptr) const; ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) From 65b22975c9dfe193c27362c6f5927109815155d5 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 17:24:22 +0200 Subject: [PATCH 07/15] Remove SkillEnum --- apps/openmw/mwclass/actor.cpp | 21 +++---- apps/openmw/mwclass/armor.cpp | 14 ++--- apps/openmw/mwclass/armor.hpp | 4 +- apps/openmw/mwclass/clothing.cpp | 4 +- apps/openmw/mwclass/clothing.hpp | 4 +- apps/openmw/mwclass/npc.cpp | 57 +++++++---------- apps/openmw/mwclass/weapon.cpp | 2 +- apps/openmw/mwclass/weapon.hpp | 4 +- apps/openmw/mwgui/charactercreation.cpp | 8 +-- apps/openmw/mwgui/class.cpp | 34 ++++++----- apps/openmw/mwgui/class.hpp | 13 ++-- apps/openmw/mwgui/jailscreen.cpp | 4 +- apps/openmw/mwgui/race.cpp | 7 ++- apps/openmw/mwgui/review.cpp | 2 +- apps/openmw/mwgui/spellcreationdialog.cpp | 4 +- apps/openmw/mwgui/spellcreationdialog.hpp | 2 +- apps/openmw/mwgui/spellicons.cpp | 3 +- apps/openmw/mwgui/tooltips.cpp | 4 +- apps/openmw/mwgui/tooltips.hpp | 2 +- apps/openmw/mwgui/trainingwindow.cpp | 2 +- apps/openmw/mwgui/widgets.cpp | 18 +----- apps/openmw/mwgui/widgets.hpp | 7 +-- apps/openmw/mwlua/types/book.cpp | 2 +- apps/openmw/mwmechanics/autocalcspell.cpp | 13 ++-- apps/openmw/mwmechanics/combat.cpp | 9 ++- apps/openmw/mwmechanics/npcstats.hpp | 4 -- apps/openmw/mwmechanics/spellpriority.cpp | 2 +- apps/openmw/mwmechanics/spellutil.cpp | 4 +- apps/openmw/mwmechanics/spellutil.hpp | 2 +- apps/openmw/mwmechanics/weaponpriority.cpp | 6 +- apps/openmw/mwscript/containerextensions.cpp | 2 +- apps/openmw/mwworld/class.cpp | 4 +- apps/openmw/mwworld/class.hpp | 16 +---- apps/openmw/mwworld/inventorystore.cpp | 2 +- apps/openmw/mwworld/player.cpp | 2 +- apps/openmw/mwworld/store.hpp | 4 -- apps/openmw_test_suite/mwworld/test_store.cpp | 2 +- components/esm3/loadskil.cpp | 32 +++++++++- components/esm3/loadskil.hpp | 61 +++++++++---------- components/esm3/loadweap.hpp | 4 +- components/esm3/player.cpp | 3 +- 41 files changed, 185 insertions(+), 209 deletions(-) diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 4157a03bc0..6729a22f39 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -43,20 +43,13 @@ namespace MWClass return; MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); - switch (shield->getClass().getEquipmentSkill(*shield)) - { - case ESM::Skill::LightArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Light Armor Hit"), 1.0f, 1.0f); - break; - case ESM::Skill::MediumArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Medium Armor Hit"), 1.0f, 1.0f); - break; - case ESM::Skill::HeavyArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Heavy Armor Hit"), 1.0f, 1.0f); - break; - default: - return; - } + ESM::RefId skill = shield->getClass().getEquipmentSkill(*shield); + if (skill == ESM::Skill::LightArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Light Armor Hit"), 1.0f, 1.0f); + else if (skill == ESM::Skill::MediumArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Medium Armor Hit"), 1.0f, 1.0f); + else if (skill == ESM::Skill::HeavyArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Heavy Armor Hit"), 1.0f, 1.0f); } osg::Vec3f Actor::getRotationVector(const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index bdaa82e873..f1c22c1d43 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -112,7 +112,7 @@ namespace MWClass return std::make_pair(slots_, false); } - int Armor::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const + ESM::RefId Armor::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { const MWWorld::LiveCellRef* ref = ptr.get(); @@ -150,7 +150,7 @@ namespace MWClass } if (typeGmst.empty()) - return -1; + return {}; const MWWorld::Store& gmst = MWBase::Environment::get().getESMStore()->get(); @@ -178,7 +178,7 @@ namespace MWClass const ESM::RefId& Armor::getUpSoundId(const MWWorld::ConstPtr& ptr) const { - int es = getEquipmentSkill(ptr); + ESM::RefId es = getEquipmentSkill(ptr); static const ESM::RefId lightUp = ESM::RefId::stringRefId("Item Armor Light Up"); static const ESM::RefId mediumUp = ESM::RefId::stringRefId("Item Armor Medium Up"); static const ESM::RefId heavyUp = ESM::RefId::stringRefId("Item Armor Heavy Up"); @@ -193,7 +193,7 @@ namespace MWClass const ESM::RefId& Armor::getDownSoundId(const MWWorld::ConstPtr& ptr) const { - int es = getEquipmentSkill(ptr); + ESM::RefId es = getEquipmentSkill(ptr); static const ESM::RefId lightDown = ESM::RefId::stringRefId("Item Armor Light Down"); static const ESM::RefId mediumDown = ESM::RefId::stringRefId("Item Armor Medium Down"); static const ESM::RefId heavyDown = ESM::RefId::stringRefId("Item Armor Heavy Down"); @@ -232,7 +232,7 @@ namespace MWClass } else { - int armorType = getEquipmentSkill(ptr); + ESM::RefId armorType = getEquipmentSkill(ptr); if (armorType == ESM::Skill::LightArmor) typeText = "#{sLight}"; else if (armorType == ESM::Skill::MediumArmor) @@ -297,8 +297,8 @@ namespace MWClass { const MWWorld::LiveCellRef* ref = ptr.get(); - int armorSkillType = getEquipmentSkill(ptr); - float armorSkill = actor.getClass().getSkill(actor, ESM::Skill::indexToRefId(armorSkillType)); + ESM::RefId armorSkillType = getEquipmentSkill(ptr); + float armorSkill = actor.getClass().getSkill(actor, armorSkillType); int iBaseArmorSkill = MWBase::Environment::get() .getESMStore() diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 0b01b643ba..d464360623 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -41,9 +41,7 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + ESM::RefId getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 06935ad2bd..fec0b4260f 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -101,14 +101,14 @@ namespace MWClass return std::make_pair(slots_, false); } - int Clothing::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const + ESM::RefId Clothing::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { const MWWorld::LiveCellRef* ref = ptr.get(); if (ref->mBase->mData.mType == ESM::Clothing::Shoes) return ESM::Skill::Unarmored; - return -1; + return {}; } int Clothing::getValue(const MWWorld::ConstPtr& ptr) const diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 1c758ac68b..a1e8348713 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -33,9 +33,7 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + ESM::RefId getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 6b10180add..5f475ec61d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -582,11 +582,11 @@ namespace MWClass victim = result.first; hitPosition = result.second; - int weapskill = ESM::Skill::HandToHand; + ESM::RefId weapskill = ESM::Skill::HandToHand; if (!weapon.isEmpty()) weapskill = weapon.getClass().getEquipmentSkill(weapon); - float hitchance = MWMechanics::getHitChance(ptr, victim, getSkill(ptr, ESM::Skill::indexToRefId(weapskill))); + float hitchance = MWMechanics::getHitChance(ptr, victim, getSkill(ptr, weapskill)); return Misc::Rng::roll0to99(world->getPrng()) < hitchance; } @@ -651,10 +651,10 @@ namespace MWClass if (ptr == MWMechanics::getPlayer()) { - int weapskill = ESM::Skill::HandToHand; + ESM::RefId weapskill = ESM::Skill::HandToHand; if (!weapon.isEmpty()) weapskill = weapon.getClass().getEquipmentSkill(weapon); - skillUsageSucceeded(ptr, ESM::Skill::indexToRefId(weapskill), 0); + skillUsageSucceeded(ptr, weapskill, 0); const MWMechanics::AiSequence& seq = victim.getClass().getCreatureStats(victim).getAiSequence(); @@ -842,25 +842,19 @@ namespace MWClass armor = *inv.unequipItem(armor); } + ESM::RefId skill = armor.getClass().getEquipmentSkill(armor); if (ptr == MWMechanics::getPlayer()) - skillUsageSucceeded( - ptr, ESM::Skill::indexToRefId(armor.getClass().getEquipmentSkill(armor)), 0); + skillUsageSucceeded(ptr, skill, 0); - switch (armor.getClass().getEquipmentSkill(armor)) - { - case ESM::Skill::LightArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Light Armor Hit"), 1.0f, 1.0f); - break; - case ESM::Skill::MediumArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Medium Armor Hit"), 1.0f, 1.0f); - break; - case ESM::Skill::HeavyArmor: - sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Heavy Armor Hit"), 1.0f, 1.0f); - break; - } + if (skill == ESM::Skill::LightArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Light Armor Hit"), 1.0f, 1.0f); + else if (skill == ESM::Skill::MediumArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Medium Armor Hit"), 1.0f, 1.0f); + else if (skill == ESM::Skill::HeavyArmor) + sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Heavy Armor Hit"), 1.0f, 1.0f); } else if (ptr == MWMechanics::getPlayer()) - Class::skillUsageSucceeded(ptr, ESM::Skill::Unarmored, 0); + skillUsageSucceeded(ptr, ESM::Skill::Unarmored, 0); } } @@ -1046,7 +1040,7 @@ namespace MWClass const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() + gmst.fJumpEncumbranceMultiplier->mValue.getFloat() * (1.0f - Npc::getNormalizedEncumbrance(ptr)); - float a = Class::getSkill(ptr, ESM::Skill::Acrobatics); + float a = getSkill(ptr, ESM::Skill::Acrobatics); float b = 0.0f; if (a > 50.0f) { @@ -1179,7 +1173,7 @@ namespace MWClass float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); - float unarmoredSkill = Class::getSkill(ptr, ESM::Skill::Unarmored); + float unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored); float ratings[MWWorld::InventoryStore::Slots]; for (int i = 0; i < MWWorld::InventoryStore::Slots; i++) @@ -1305,18 +1299,13 @@ namespace MWClass if (boots == inv.end() || boots->getType() != ESM::Armor::sRecordId) return (name == "left") ? footBareLeft : footBareRight; - switch (boots->getClass().getEquipmentSkill(*boots)) - { - case ESM::Skill::LightArmor: - return (name == "left") ? footLightLeft : footLightRight; - break; - case ESM::Skill::MediumArmor: - return (name == "left") ? footMediumLeft : footMediumRight; - break; - case ESM::Skill::HeavyArmor: - return (name == "left") ? footHeavyLeft : footHeavyRight; - break; - } + ESM::RefId skill = boots->getClass().getEquipmentSkill(*boots); + if (skill == ESM::Skill::LightArmor) + return (name == "left") ? footLightLeft : footLightRight; + else if (skill == ESM::Skill::MediumArmor) + return (name == "left") ? footMediumLeft : footMediumRight; + else if (skill == ESM::Skill::HeavyArmor) + return (name == "left") ? footHeavyLeft : footHeavyRight; } return ESM::RefId(); } @@ -1544,7 +1533,7 @@ namespace MWClass { const GMST& gmst = getGmst(); return getWalkSpeed(ptr) - * (0.01f * Class::getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + * (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat()); } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 4eddc37f73..74e26a3b83 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -108,7 +108,7 @@ namespace MWClass return std::make_pair(slots_, stack); } - int Weapon::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const + ESM::RefId Weapon::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { const MWWorld::LiveCellRef* ref = ptr.get(); int type = ref->mBase->mData.mType; diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 336c1a89eb..110069341d 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -42,9 +42,7 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + ESM::RefId getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; int getValue(const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index fa9b019ca3..0229fccb16 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -475,14 +475,14 @@ namespace MWGui assert(attributes.size() == klass.mData.mAttribute.size()); std::copy(attributes.begin(), attributes.end(), klass.mData.mAttribute.begin()); - std::vector majorSkills = mCreateClassDialog->getMajorSkills(); - std::vector minorSkills = mCreateClassDialog->getMinorSkills(); + std::vector majorSkills = mCreateClassDialog->getMajorSkills(); + std::vector minorSkills = mCreateClassDialog->getMinorSkills(); assert(majorSkills.size() >= klass.mData.mSkills.size()); 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]; - klass.mData.mSkills[i][0] = minorSkills[i]; + klass.mData.mSkills[i][1] = majorSkills[i].getIf()->getValue(); + klass.mData.mSkills[i][0] = minorSkills[i].getIf()->getValue(); } MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 300683472f..55f9f277a4 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -266,10 +266,12 @@ namespace MWGui for (size_t i = 0; i < klass->mData.mSkills.size(); ++i) { - mMinorSkill[i]->setSkillNumber(klass->mData.mSkills[i][0]); - mMajorSkill[i]->setSkillNumber(klass->mData.mSkills[i][1]); - ToolTips::createSkillToolTip(mMinorSkill[i], klass->mData.mSkills[i][0]); - ToolTips::createSkillToolTip(mMajorSkill[i], klass->mData.mSkills[i][1]); + ESM::RefId minor = ESM::Skill::indexToRefId(klass->mData.mSkills[i][0]); + ESM::RefId major = ESM::Skill::indexToRefId(klass->mData.mSkills[i][1]); + mMinorSkill[i]->setSkillId(minor); + mMajorSkill[i]->setSkillId(major); + ToolTips::createSkillToolTip(mMinorSkill[i], minor); + ToolTips::createSkillToolTip(mMajorSkill[i], major); } setClassImage(mClassImage, mCurrentClassId); @@ -514,24 +516,24 @@ namespace MWGui return v; } - std::vector CreateClassDialog::getMajorSkills() const + std::vector CreateClassDialog::getMajorSkills() const { - std::vector v; - v.reserve(5); - for (int i = 0; i < 5; i++) + std::vector v; + v.reserve(mMajorSkill.size()); + for (const auto& widget : mMajorSkill) { - v.push_back(mMajorSkill[i]->getSkillId()); + v.push_back(widget->getSkillId()); } return v; } - std::vector CreateClassDialog::getMinorSkills() const + std::vector CreateClassDialog::getMinorSkills() const { - std::vector v; - v.reserve(5); - for (int i = 0; i < 5; i++) + std::vector v; + v.reserve(mMinorSkill.size()); + for (const auto& widget : mMinorSkill) { - v.push_back(mMinorSkill[i]->getSkillId()); + v.push_back(widget->getSkillId()); } return v; } @@ -624,7 +626,7 @@ namespace MWGui void CreateClassDialog::onSkillSelected() { - ESM::Skill::SkillEnum id = mSkillDialog->getSkillId(); + ESM::RefId id = mSkillDialog->getSkillId(); // Avoid duplicate skills by swapping any skill field that matches the selected one for (Widgets::MWSkillPtr& skill : mSkills) @@ -804,7 +806,7 @@ namespace MWGui struct { Widgets::MWSkillPtr widget; - ESM::Skill::SkillEnum skillId; + ESM::RefId skillId; } mSkills[3][9] = { { { mCombatSkill[0], ESM::Skill::Block }, { mCombatSkill[1], ESM::Skill::Armorer }, { mCombatSkill[2], ESM::Skill::MediumArmor }, { mCombatSkill[3], ESM::Skill::HeavyArmor }, diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index dd66632784..e00d9b98dd 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -1,6 +1,7 @@ #ifndef MWGUI_CLASS_H #define MWGUI_CLASS_H +#include #include #include @@ -218,7 +219,7 @@ namespace MWGui bool exit() override; - ESM::Skill::SkillEnum getSkillId() const { return mSkillId; } + ESM::RefId getSkillId() const { return mSkillId; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -242,7 +243,7 @@ namespace MWGui Widgets::MWSkillPtr mMagicSkill[9]; Widgets::MWSkillPtr mStealthSkill[9]; - ESM::Skill::SkillEnum mSkillId; + ESM::RefId mSkillId; }; class DescriptionDialog : public WindowModal @@ -278,8 +279,8 @@ namespace MWGui std::string getDescription() const; ESM::Class::Specialization getSpecializationId() const; std::vector getFavoriteAttributes() const; - std::vector getMajorSkills() const; - std::vector getMinorSkills() const; + std::vector getMajorSkills() const; + std::vector getMinorSkills() const; void setNextButtonShow(bool shown); @@ -318,8 +319,8 @@ namespace MWGui MyGUI::EditBox* mEditName; MyGUI::TextBox* mSpecializationName; Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1; - Widgets::MWSkillPtr mMajorSkill[5]; - Widgets::MWSkillPtr mMinorSkill[5]; + std::array mMajorSkill; + std::array mMinorSkill; std::vector mSkills; std::string mDescription; diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index 484e9370cc..c6aefdd177 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -97,7 +97,7 @@ namespace MWGui skills.insert(skill); MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill->mId); - if (skill->mIndex == ESM::Skill::Security || skill->mIndex == ESM::Skill::Sneak) + if (skill->mId == ESM::Skill::Security || skill->mId == ESM::Skill::Sneak) value.setBase(std::min(100.f, value.getBase() + 1)); else value.setBase(std::max(0.f, value.getBase() - 1)); @@ -118,7 +118,7 @@ namespace MWGui { int skillValue = player.getClass().getNpcStats(player).getSkill(skill->mId).getBase(); std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString(); - if (skill->mIndex == ESM::Skill::Sneak || skill->mIndex == ESM::Skill::Security) + if (skill->mId == ESM::Skill::Sneak || skill->mId == ESM::Skill::Security) skillMsg = gmst.find("sNotifyMessage39")->mValue.getString(); skillMsg = Misc::StringUtils::format(skillMsg, skill->mName, skillValue); diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index e239e641c7..6f1a615dd9 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -414,13 +414,14 @@ namespace MWGui const ESM::Race* race = store.get().find(mCurrentRaceId); for (const auto& bonus : race->mData.mBonus) { - if (bonus.mSkill < 0 || bonus.mSkill >= ESM::Skill::Length) // Skip unknown skill indexes + ESM::RefId skill = ESM::Skill::indexToRefId(bonus.mSkill); + if (skill.empty()) // Skip unknown skill indexes continue; skillWidget = mSkillList->createWidget("MW_StatNameValue", coord1, MyGUI::Align::Default); - skillWidget->setSkillId(ESM::Skill::SkillEnum(bonus.mSkill)); + skillWidget->setSkillId(skill); skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(static_cast(bonus.mBonus), 0.f)); - ToolTips::createSkillToolTip(skillWidget, bonus.mSkill); + ToolTips::createSkillToolTip(skillWidget, skill); mSkillItems.push_back(skillWidget); diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 840ba564be..161e43203e 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -360,7 +360,7 @@ namespace MWGui for (int i = 0; i < 2; ++i) { - ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skill->mIndex); + ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skill->mId); } mSkillWidgetMap[skill->mId] = widget; diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index a1d3ea6f9f..d515724e5b 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -286,9 +286,9 @@ namespace MWGui exit(); } - void EditEffectDialog::setSkill(int skill) + void EditEffectDialog::setSkill(ESM::RefId skill) { - mEffect.mSkill = skill; + mEffect.mSkill = skill.getIf()->getValue(); eventEffectModified(mEffect); } diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index d79494dae2..cde0fcacd0 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -30,7 +30,7 @@ namespace MWGui void setConstantEffect(bool constant); - void setSkill(int skill); + void setSkill(ESM::RefId skill); void setAttribute(int attribute); void newEffect(const ESM::MagicEffect* effect); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 8e90166e51..e5eff6e178 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -83,7 +83,8 @@ namespace MWGui if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) { - const ESM::Skill* skill = store->get().find(effectInfo.mKey.mArg); + const ESM::Skill* skill + = store->get().find(ESM::Skill::indexToRefId(effectInfo.mKey.mArg)); sourcesDescription += " (" + skill->mName + ')'; } if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 6ca89add80..265ccd8ec7 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -805,9 +805,9 @@ namespace MWGui mFocusToolTipY = min_y; } - void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId) + void ToolTips::createSkillToolTip(MyGUI::Widget* widget, ESM::RefId skillId) { - if (skillId == -1) + if (skillId.empty()) return; const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore(); diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 9ed62d4e35..8246b0ca3b 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -93,7 +93,7 @@ namespace MWGui // these do not create an actual tooltip, but they fill in the data that is required so the tooltip // system knows what to show in case this widget is hovered - static void createSkillToolTip(MyGUI::Widget* widget, int skillId); + static void createSkillToolTip(MyGUI::Widget* widget, ESM::RefId skillId); static void createAttributeToolTip(MyGUI::Widget* widget, int attributeId); static void createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId); static void createBirthsignToolTip(MyGUI::Widget* widget, const ESM::RefId& birthsignId); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 38ae900841..785a6b48c2 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -110,7 +110,7 @@ namespace MWGui button->setSize(button->getTextSize().width + 12, button->getSize().height); - ToolTips::createSkillToolTip(button, skill->mIndex); + ToolTips::createSkillToolTip(button, skill->mId); } center(); diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index d63e1b290d..194fa972af 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -28,28 +28,17 @@ namespace MWGui::Widgets /* MWSkill */ MWSkill::MWSkill() - : mSkillId(ESM::Skill::Length) - , mSkillNameWidget(nullptr) + : mSkillNameWidget(nullptr) , mSkillValueWidget(nullptr) { } - void MWSkill::setSkillId(ESM::Skill::SkillEnum skill) + void MWSkill::setSkillId(ESM::RefId skill) { mSkillId = skill; updateWidgets(); } - void MWSkill::setSkillNumber(int skill) - { - if (skill < 0) - setSkillId(ESM::Skill::Length); - else if (skill < ESM::Skill::Length) - setSkillId(static_cast(skill)); - else - throw std::runtime_error("Skill number out of range"); - } - void MWSkill::setSkillValue(const SkillValue& value) { mValue = value; @@ -60,8 +49,7 @@ namespace MWGui::Widgets { if (mSkillNameWidget) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search( - ESM::Skill::indexToRefId(mSkillId)); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search(mSkillId); if (skill == nullptr) mSkillNameWidget->setCaption({}); else diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 63a6fd0db9..90e9680a90 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -100,11 +100,10 @@ namespace MWGui typedef MWMechanics::Stat SkillValue; - void setSkillId(ESM::Skill::SkillEnum skillId); - void setSkillNumber(int skillId); + void setSkillId(ESM::RefId skillId); void setSkillValue(const SkillValue& value); - ESM::Skill::SkillEnum getSkillId() const { return mSkillId; } + ESM::RefId getSkillId() const { return mSkillId; } const SkillValue& getSkillValue() const { return mValue; } // Events @@ -125,7 +124,7 @@ namespace MWGui private: void updateWidgets(); - ESM::Skill::SkillEnum mSkillId; + ESM::RefId mSkillId; SkillValue mValue; MyGUI::TextBox* mSkillNameWidget; MyGUI::TextBox* mSkillValueWidget; diff --git a/apps/openmw/mwlua/types/book.cpp b/apps/openmw/mwlua/types/book.cpp index 2a4068f2fa..12daf52fd9 100644 --- a/apps/openmw/mwlua/types/book.cpp +++ b/apps/openmw/mwlua/types/book.cpp @@ -67,7 +67,7 @@ namespace MWLua sol::table skill(context.mLua->sol(), sol::create); book["SKILL"] = LuaUtil::makeStrictReadOnly(skill); book["createRecordDraft"] = tableToBook; - for (int id = ESM::Skill::Block; id < ESM::Skill::Length; ++id) + for (int id = 0; id < ESM::Skill::Length; ++id) { std::string skillName = Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[id]); skill[skillName] = skillName; diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index c0be97c9a9..66ed8c7bab 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -299,7 +299,7 @@ namespace MWMechanics x *= 1.5f; float s = 0.f; - ESM::RefId skill = ESM::Skill::indexToRefId(spellSchoolToSkill(magicEffect->mData.mSchool)); + ESM::RefId skill = spellSchoolToSkill(magicEffect->mData.mSchool); auto found = actorSkills.find(skill); if (found != actorSkills.end()) s = 2.f * found->second.getBase(); @@ -322,10 +322,13 @@ namespace MWMechanics return 100.f; float skillTerm = 0; - ESM::RefId skill = ESM::Skill::indexToRefId(spellSchoolToSkill(effectiveSchool)); - auto found = actorSkills.find(skill); - if (found != actorSkills.end()) - skillTerm = 2.f * found->second.getBase(); + if (effectiveSchool != -1) + { + ESM::RefId skill = spellSchoolToSkill(effectiveSchool); + auto found = actorSkills.find(skill); + if (found != actorSkills.end()) + skillTerm = 2.f * found->second.getBase(); + } else calcWeakestSchool( spell, actorSkills, effectiveSchool, skillTerm); // Note effectiveSchool is unused after this diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 8556a9380b..b83eb1f10c 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -122,8 +122,7 @@ namespace MWMechanics if (weapon.isEmpty()) attackerSkill = attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand); else - attackerSkill = attacker.getClass().getSkill( - attacker, ESM::Skill::indexToRefId(weapon.getClass().getEquipmentSkill(weapon))); + attackerSkill = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon)); float attackerTerm = attackerSkill + 0.2f * attackerStats.getAttribute(ESM::Attribute::Agility).getModified() + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); attackerTerm *= attackerStats.getFatigueTerm(); @@ -218,7 +217,7 @@ namespace MWMechanics bool validVictim = !victim.isEmpty() && victim.getClass().isActor(); - int weaponSkill = ESM::Skill::Marksman; + ESM::RefId weaponSkill = ESM::Skill::Marksman; if (!weapon.isEmpty()) weaponSkill = weapon.getClass().getEquipmentSkill(weapon); @@ -228,7 +227,7 @@ namespace MWMechanics if (attacker == getPlayer()) MWBase::Environment::get().getWindowManager()->setEnemy(victim); - int skillValue = attacker.getClass().getSkill(attacker, ESM::Skill::indexToRefId(weaponSkill)); + int skillValue = attacker.getClass().getSkill(attacker, weaponSkill); if (Misc::Rng::roll0to99(world->getPrng()) >= getHitChance(attacker, victim, skillValue)) { @@ -259,7 +258,7 @@ namespace MWMechanics applyWerewolfDamageMult(victim, projectile, damage); if (attacker == getPlayer()) - attacker.getClass().skillUsageSucceeded(attacker, ESM::Skill::indexToRefId(weaponSkill), 0); + attacker.getClass().skillUsageSucceeded(attacker, weaponSkill, 0); const MWMechanics::AiSequence& sequence = victim.getClass().getCreatureStats(victim).getAiSequence(); bool unaware = attacker == getPlayer() && !sequence.isInCombat() diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 1da46efc87..b463d25c30 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -60,10 +60,6 @@ namespace MWMechanics void setCrimeId(int id); const SkillValue& getSkill(ESM::RefId id) const; - const SkillValue& getSkill(ESM::Skill::SkillEnum index) const - { - return getSkill(ESM::Skill::indexToRefId(index)); - } SkillValue& getSkill(ESM::RefId id); void setSkill(ESM::RefId id, const SkillValue& value); diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 79f8d315ab..fbcfa9a9c1 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -600,7 +600,7 @@ namespace MWMechanics && (e != ESM::MagicEffect::BoundLongbow || effect.mEffectID == e || rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f)) return 0.f; - ESM::Skill::SkillEnum skill = ESM::Skill::ShortBlade; + ESM::RefId skill = ESM::Skill::ShortBlade; if (effect.mEffectID == ESM::MagicEffect::BoundLongsword) skill = ESM::Skill::LongBlade; else if (effect.mEffectID == ESM::MagicEffect::BoundMace) diff --git a/apps/openmw/mwmechanics/spellutil.cpp b/apps/openmw/mwmechanics/spellutil.cpp index 60574880a1..a03b7577d3 100644 --- a/apps/openmw/mwmechanics/spellutil.cpp +++ b/apps/openmw/mwmechanics/spellutil.cpp @@ -15,9 +15,9 @@ namespace MWMechanics { - ESM::Skill::SkillEnum spellSchoolToSkill(int school) + ESM::RefId spellSchoolToSkill(int school) { - static const std::array schoolSkillArray{ + static const std::array schoolSkillArray{ ESM::Skill::Alteration, ESM::Skill::Conjuration, ESM::Skill::Destruction, diff --git a/apps/openmw/mwmechanics/spellutil.hpp b/apps/openmw/mwmechanics/spellutil.hpp index 40b1ea0ff0..8db37b9adf 100644 --- a/apps/openmw/mwmechanics/spellutil.hpp +++ b/apps/openmw/mwmechanics/spellutil.hpp @@ -17,7 +17,7 @@ namespace MWWorld namespace MWMechanics { - ESM::Skill::SkillEnum spellSchoolToSkill(int school); + ESM::RefId spellSchoolToSkill(int school); enum class EffectCostMethod { diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 3fa4d454fa..c123a94056 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -120,7 +120,7 @@ namespace MWMechanics int value = 50.f; if (actor.getClass().isNpc()) { - ESM::RefId skill = ESM::Skill::indexToRefId(item.getClass().getEquipmentSkill(item)); + ESM::RefId skill = item.getClass().getEquipmentSkill(item); if (!skill.empty()) value = actor.getClass().getSkill(actor, skill); } @@ -179,9 +179,7 @@ namespace MWMechanics if (weapon.isEmpty()) return 0.f; - float skillMult - = actor.getClass().getSkill(actor, ESM::Skill::indexToRefId(weapon.getClass().getEquipmentSkill(weapon))) - * 0.01f; + float skillMult = actor.getClass().getSkill(actor, weapon.getClass().getEquipmentSkill(weapon)) * 0.01f; float chopMult = fAIMeleeWeaponMult; float bonusDamage = 0.f; diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index e664dfbd45..edee3963e7 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -392,7 +392,7 @@ namespace MWScript return; } - int skill = it->getClass().getEquipmentSkill(*it); + ESM::RefId skill = it->getClass().getEquipmentSkill(*it); if (skill == ESM::Skill::HeavyArmor) runtime.push(2); else if (skill == ESM::Skill::MediumArmor) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 8279d01582..03e624a608 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -209,9 +209,9 @@ namespace MWWorld return std::make_pair(std::vector(), false); } - int Class::getEquipmentSkill(const ConstPtr& ptr) const + ESM::RefId Class::getEquipmentSkill(const ConstPtr& ptr) const { - return -1; + return {}; } int Class::getValue(const ConstPtr& ptr) const diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index d46e7d9578..fbd2b98a74 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -209,10 +209,9 @@ namespace MWWorld /// /// Default implementation: return (empty vector, false). - virtual int getEquipmentSkill(const ConstPtr& ptr) const; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. - /// (default implementation: return -1) + virtual ESM::RefId getEquipmentSkill(const ConstPtr& ptr) const; + /// Return the index of the skill this item corresponds to when equipped. + /// (default implementation: return empty ref id) virtual int getValue(const ConstPtr& ptr) const; ///< Return trade value of the object. Throws an exception, if the object can't be traded. @@ -239,11 +238,6 @@ namespace MWWorld ///< Inform actor \a ptr that a skill use has succeeded. /// /// (default implementations: throws an exception) - void skillUsageSucceeded( - const MWWorld::Ptr& ptr, ESM::Skill::SkillEnum index, int usageType, float extraFactor = 1.f) const - { - return skillUsageSucceeded(ptr, ESM::Skill::indexToRefId(index), usageType, extraFactor); - }; virtual bool isEssential(const MWWorld::ConstPtr& ptr) const; ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) @@ -347,10 +341,6 @@ namespace MWWorld bool isMobile(const MWWorld::Ptr& ptr) const; virtual float getSkill(const MWWorld::Ptr& ptr, ESM::RefId id) const; - float getSkill(const MWWorld::Ptr& ptr, ESM::Skill::SkillEnum index) const - { - return getSkill(ptr, ESM::Skill::indexToRefId(index)); - }; virtual void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const; ///< Read additional state from \a state into \a ptr. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 5ec18557ac..e8204223aa 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -236,7 +236,7 @@ void MWWorld::InventoryStore::autoEquipWeapon(TSlots& slots_) return; } - static const ESM::Skill::SkillEnum weaponSkills[] = { + static const ESM::RefId weaponSkills[] = { ESM::Skill::LongBlade, ESM::Skill::Axe, ESM::Skill::Spear, diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index ea1ada7689..bb70c46aa0 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -106,7 +106,7 @@ namespace MWWorld for (const auto& skill : store->get()) { // Acrobatics is set separately for some reason. - if (skill.mIndex == ESM::Skill::Acrobatics) + if (skill.mId == ESM::Skill::Acrobatics) continue; MWMechanics::SkillValue& value = npcStats.getSkill(skill.mId); diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 97cc733147..07d6fd0865 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -481,10 +481,6 @@ namespace MWWorld public: 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/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index ba54e4a5e0..eddc4137d0 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -496,7 +496,7 @@ namespace const RecordType* result = nullptr; if constexpr (std::is_same_v) result = esmStore.get().search(index, 0); - else if constexpr (ESM::hasIndex) + else if constexpr (ESM::hasIndex && !std::is_same_v) result = esmStore.get().search(index); else result = esmStore.get().search(refId); diff --git a/components/esm3/loadskil.cpp b/components/esm3/loadskil.cpp index 24faa0c7f1..14dd9acac2 100644 --- a/components/esm3/loadskil.cpp +++ b/components/esm3/loadskil.cpp @@ -7,6 +7,34 @@ namespace ESM { + const RefId Skill::Block = Skill::indexToRefId(0); + const RefId Skill::Armorer = Skill::indexToRefId(1); + const RefId Skill::MediumArmor = Skill::indexToRefId(2); + const RefId Skill::HeavyArmor = Skill::indexToRefId(3); + const RefId Skill::BluntWeapon = Skill::indexToRefId(4); + const RefId Skill::LongBlade = Skill::indexToRefId(5); + const RefId Skill::Axe = Skill::indexToRefId(6); + const RefId Skill::Spear = Skill::indexToRefId(7); + const RefId Skill::Athletics = Skill::indexToRefId(8); + const RefId Skill::Enchant = Skill::indexToRefId(9); + const RefId Skill::Destruction = Skill::indexToRefId(10); + const RefId Skill::Alteration = Skill::indexToRefId(11); + const RefId Skill::Illusion = Skill::indexToRefId(12); + const RefId Skill::Conjuration = Skill::indexToRefId(13); + const RefId Skill::Mysticism = Skill::indexToRefId(14); + const RefId Skill::Restoration = Skill::indexToRefId(15); + const RefId Skill::Alchemy = Skill::indexToRefId(16); + const RefId Skill::Unarmored = Skill::indexToRefId(17); + const RefId Skill::Security = Skill::indexToRefId(18); + const RefId Skill::Sneak = Skill::indexToRefId(19); + const RefId Skill::Acrobatics = Skill::indexToRefId(20); + const RefId Skill::LightArmor = Skill::indexToRefId(21); + const RefId Skill::ShortBlade = Skill::indexToRefId(22); + const RefId Skill::Marksman = Skill::indexToRefId(23); + const RefId Skill::Mercantile = Skill::indexToRefId(24); + const RefId Skill::Speechcraft = Skill::indexToRefId(25); + const RefId Skill::HandToHand = Skill::indexToRefId(26); + const std::string Skill::sSkillNames[Length] = { "Block", "Armorer", @@ -37,11 +65,11 @@ namespace ESM "Handtohand", }; - Skill::SkillEnum Skill::stringToSkillId(std::string_view skill) + int Skill::stringToSkillId(std::string_view skill) { for (int id = 0; id < Skill::Length; ++id) if (Misc::StringUtils::ciEqual(sSkillNames[id], skill)) - return Skill::SkillEnum(id); + return id; throw std::logic_error("No such skill: " + std::string(skill)); } diff --git a/components/esm3/loadskil.hpp b/components/esm3/loadskil.hpp index f4ccd54f66..bd956475bf 100644 --- a/components/esm3/loadskil.hpp +++ b/components/esm3/loadskil.hpp @@ -48,40 +48,37 @@ namespace ESM std::string mIcon; float mWerewolfValue{}; - enum SkillEnum - { - Block = 0, - Armorer = 1, - MediumArmor = 2, - HeavyArmor = 3, - BluntWeapon = 4, - LongBlade = 5, - Axe = 6, - Spear = 7, - Athletics = 8, - Enchant = 9, - Destruction = 10, - Alteration = 11, - Illusion = 12, - Conjuration = 13, - Mysticism = 14, - Restoration = 15, - Alchemy = 16, - Unarmored = 17, - Security = 18, - Sneak = 19, - Acrobatics = 20, - LightArmor = 21, - ShortBlade = 22, - Marksman = 23, - Mercantile = 24, - Speechcraft = 25, - HandToHand = 26, - Length - }; + static const RefId Block; + static const RefId Armorer; + static const RefId MediumArmor; + static const RefId HeavyArmor; + static const RefId BluntWeapon; + static const RefId LongBlade; + static const RefId Axe; + static const RefId Spear; + static const RefId Athletics; + static const RefId Enchant; + static const RefId Destruction; + static const RefId Alteration; + static const RefId Illusion; + static const RefId Conjuration; + static const RefId Mysticism; + static const RefId Restoration; + static const RefId Alchemy; + static const RefId Unarmored; + static const RefId Security; + static const RefId Sneak; + static const RefId Acrobatics; + static const RefId LightArmor; + static const RefId ShortBlade; + static const RefId Marksman; + static const RefId Mercantile; + static const RefId Speechcraft; + static const RefId HandToHand; + static constexpr int Length = 27; static const std::string sSkillNames[Length]; - static SkillEnum stringToSkillId(std::string_view skill); + static int stringToSkillId(std::string_view skill); void load(ESMReader& esm, bool& isDeleted); void save(ESMWriter& esm, bool isDeleted = false) const; diff --git a/components/esm3/loadweap.hpp b/components/esm3/loadweap.hpp index d3a2a1f053..bc2af28edd 100644 --- a/components/esm3/loadweap.hpp +++ b/components/esm3/loadweap.hpp @@ -109,13 +109,13 @@ namespace ESM ESM::RefId mSoundIdUp; std::string mAttachBone; std::string mSheathingBone; - Skill::SkillEnum mSkill; + ESM::RefId mSkill; Class mWeaponClass; int mAmmoType; int mFlags; WeaponType(std::string shortGroup, std::string longGroup, const std::string& soundId, std::string attachBone, - std::string sheathingBone, Skill::SkillEnum skill, Class weaponClass, int ammoType, int flags) + std::string sheathingBone, ESM::RefId skill, Class weaponClass, int ammoType, int flags) : mShortGroup(std::move(shortGroup)) , mLongGroup(std::move(longGroup)) , mSoundIdDown(ESM::RefId::stringRefId(soundId + " Down")) diff --git a/components/esm3/player.cpp b/components/esm3/player.cpp index 4c56c7488b..9c2cad86d1 100644 --- a/components/esm3/player.cpp +++ b/components/esm3/player.cpp @@ -73,7 +73,8 @@ namespace ESM mSaveSkills[i] = skill.mBase + skill.mMod - skill.mDamage; if (mObject.mNpcStats.mIsWerewolf) { - if (i == Skill::Acrobatics) + constexpr int Acrobatics = 20; + if (i == Acrobatics) mSetWerewolfAcrobatics = mObject.mNpcStats.mSkills[i].mBase != skill.mBase; mObject.mNpcStats.mSkills[i] = skill; } From 15a5fa84f6747693f78537eac31203827267d275 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 18:34:25 +0200 Subject: [PATCH 08/15] Use std::variant in CachedStat --- apps/openmw/mwlua/localscripts.hpp | 10 ++++--- apps/openmw/mwlua/stats.cpp | 47 ++++++++++++++++-------------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index aa22ec0424..95caf3d1fc 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -21,11 +22,12 @@ namespace MWLua class CachedStat { public: - using Setter = void (*)(int, std::string_view, const MWWorld::Ptr&, const sol::object&); + using Index = std::variant; + using Setter = void (*)(const Index&, std::string_view, const MWWorld::Ptr&, const sol::object&); - CachedStat(Setter setter, int index, std::string_view prop) + CachedStat(Setter setter, Index index, std::string_view prop) : mSetter(setter) - , mIndex(index) + , mIndex(std::move(index)) , mProp(std::move(prop)) { } @@ -42,7 +44,7 @@ namespace MWLua private: Setter mSetter; // Function that updates a stat's property - int mIndex; // Optional index to disambiguate the stat + Index mIndex; // Optional index to disambiguate the stat std::string_view mProp; // Name of the stat's property }; diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index 817703728e..1687b202d7 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -24,9 +24,10 @@ namespace { using SelfObject = MWLua::SelfObject; using ObjectVariant = MWLua::ObjectVariant; + using Index = const SelfObject::CachedStat::Index&; - template - auto addIndexedAccessor(I index) + template + auto addIndexedAccessor(Index index) { return [index](const sol::object& o) { return T::create(ObjectVariant(o), index); }; } @@ -40,7 +41,7 @@ namespace template sol::object getValue(const MWLua::Context& context, const ObjectVariant& obj, SelfObject::CachedStat::Setter setter, - int index, std::string_view prop, G getter) + Index index, std::string_view prop, G getter) { if (obj.isSelfObject()) { @@ -99,14 +100,14 @@ namespace MWLua return sol::make_object(context.mLua->sol(), ptr.getClass().getNpcStats(ptr).getLevelProgress()); } - static std::optional create(ObjectVariant object, int index) + static std::optional create(ObjectVariant object, Index) { if (!object.ptr().getClass().isActor()) return {}; return LevelStat{ std::move(object) }; } - static void setValue(int, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) + static void setValue(Index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { auto& stats = ptr.getClass().getCreatureStats(ptr); if (prop == "current") @@ -135,10 +136,11 @@ namespace MWLua }); } - static std::optional create(ObjectVariant object, int index) + static std::optional create(ObjectVariant object, Index i) { if (!object.ptr().getClass().isActor()) return {}; + int index = std::get(i); return DynamicStat{ std::move(object), index }; } @@ -149,8 +151,9 @@ namespace MWLua obj->mStatsCache[SelfObject::CachedStat{ &DynamicStat::setValue, mIndex, prop }] = value; } - static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) + static void setValue(Index i, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { + int index = std::get(i); auto& stats = ptr.getClass().getCreatureStats(ptr); auto stat = stats.getDynamic(index); float floatValue = LuaUtil::cast(value); @@ -193,10 +196,11 @@ namespace MWLua return std::max(0.f, base - damage + modifier); // Should match AttributeValue::getModified } - static std::optional create(ObjectVariant object, int index) + static std::optional create(ObjectVariant object, Index i) { if (!object.ptr().getClass().isActor()) return {}; + int index = std::get(i); return AttributeStat{ std::move(object), index }; } @@ -207,8 +211,9 @@ namespace MWLua obj->mStatsCache[SelfObject::CachedStat{ &AttributeStat::setValue, mIndex, prop }] = value; } - static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) + static void setValue(Index i, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { + int index = std::get(i); auto& stats = ptr.getClass().getCreatureStats(ptr); auto stat = stats.getAttribute(index); float floatValue = LuaUtil::cast(value); @@ -255,9 +260,9 @@ namespace MWLua template sol::object get(const Context& context, std::string_view prop, G getter) const { - return getValue(context, mObject, &SkillStat::setValue, mId.getIf()->getValue(), prop, - [this, getter]( - const MWWorld::Ptr& ptr) { return (ptr.getClass().getNpcStats(ptr).getSkill(mId).*getter)(); }); + return getValue(context, mObject, &SkillStat::setValue, mId, prop, [this, getter](const MWWorld::Ptr& ptr) { + return (ptr.getClass().getNpcStats(ptr).getSkill(mId).*getter)(); + }); } float getModified(const Context& context) const @@ -270,16 +275,16 @@ namespace MWLua sol::object getProgress(const Context& context) const { - return getValue(context, mObject, &SkillStat::setValue, mId.getIf()->getValue(), - "progress", [this](const MWWorld::Ptr& ptr) { - return getProgress(ptr, mId, ptr.getClass().getNpcStats(ptr).getSkill(mId)); - }); + return getValue(context, mObject, &SkillStat::setValue, mId, "progress", [this](const MWWorld::Ptr& ptr) { + return getProgress(ptr, mId, ptr.getClass().getNpcStats(ptr).getSkill(mId)); + }); } - static std::optional create(ObjectVariant object, ESM::RefId id) + static std::optional create(ObjectVariant object, Index index) { if (!object.ptr().getClass().isNpc()) return {}; + ESM::RefId id = std::get(index); return SkillStat{ std::move(object), id }; } @@ -287,14 +292,12 @@ namespace MWLua { SelfObject* obj = mObject.asSelfObject(); addStatUpdateAction(context.mLuaManager, *obj); - obj->mStatsCache[SelfObject::CachedStat{ - &SkillStat::setValue, int(mId.getIf()->getValue()), prop }] - = value; + obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mId, prop }] = value; } - static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) + static void setValue(Index index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { - ESM::RefId id = ESM::Skill::indexToRefId(index); + ESM::RefId id = std::get(index); auto& stats = ptr.getClass().getNpcStats(ptr); auto stat = stats.getSkill(id); float floatValue = LuaUtil::cast(value); From 9a93dcc39e22d84b8c6b41b5b9df6e3ba71e5bb5 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 19:17:03 +0200 Subject: [PATCH 09/15] Dehardcode the list of skills in the stats window --- apps/openmw/mwgui/charactercreation.cpp | 2 +- apps/openmw/mwgui/charactercreation.hpp | 6 ++---- apps/openmw/mwgui/review.cpp | 17 ++++++++--------- apps/openmw/mwgui/review.hpp | 9 ++++----- apps/openmw/mwgui/statswatcher.cpp | 10 +++++----- apps/openmw/mwgui/statswatcher.hpp | 4 ++-- apps/openmw/mwgui/statswindow.cpp | 14 +++++++------- apps/openmw/mwgui/statswindow.hpp | 10 ++++------ 8 files changed, 33 insertions(+), 39 deletions(-) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 0229fccb16..dc1608b9c7 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -145,7 +145,7 @@ namespace MWGui mReviewDialog->setSkillValue(id, value); } - void CharacterCreation::configureSkills(const SkillList& major, const SkillList& minor) + void CharacterCreation::configureSkills(const std::vector& major, const std::vector& minor) { if (mReviewDialog) mReviewDialog->configureSkills(major, minor); diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index 79cf5a35a7..f9e76d1fc6 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -38,8 +38,6 @@ namespace MWGui class CharacterCreation : public StatsListener { public: - typedef std::vector SkillList; - CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem); virtual ~CharacterCreation(); @@ -49,7 +47,7 @@ namespace MWGui void setValue(std::string_view id, const MWMechanics::AttributeValue& value) override; void setValue(std::string_view id, const MWMechanics::DynamicStat& value) override; void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) override; - void configureSkills(const SkillList& major, const SkillList& minor) override; + void configureSkills(const std::vector& major, const std::vector& minor) override; void onFrame(float duration); @@ -57,7 +55,7 @@ namespace MWGui osg::Group* mParent; Resource::ResourceSystem* mResourceSystem; - SkillList mPlayerMajorSkills, mPlayerMinorSkills; + std::vector mPlayerMajorSkills, mPlayerMinorSkills; std::map mPlayerAttributes; std::map mPlayerSkillValues; diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 161e43203e..8887b9eb4f 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -226,21 +226,21 @@ namespace MWGui mUpdateSkillArea = true; } - void ReviewDialog::configureSkills(const std::vector& major, const std::vector& minor) + void ReviewDialog::configureSkills(const std::vector& major, const std::vector& minor) { mMajorSkills = major; mMinorSkills = minor; // Update misc skills with the remaining skills not in major or minor - std::set skillSet; + std::set skillSet; std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin())); mMiscSkills.clear(); const auto& store = MWBase::Environment::get().getWorld()->getStore().get(); for (const ESM::Skill& skill : store) { - if (!skillSet.contains(skill.mIndex)) - mMiscSkills.push_back(skill.mIndex); + if (!skillSet.contains(skill.mId)) + mMiscSkills.push_back(skill.mId); } mUpdateSkillArea = true; @@ -328,8 +328,8 @@ namespace MWGui coord2.top += lineHeight; } - void ReviewDialog::addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, - MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) + void ReviewDialog::addSkills(const std::vector& skills, const std::string& titleId, + const std::string& titleDefault, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { // Add a line separator if there are items above if (!mSkillWidgets.empty()) @@ -340,10 +340,9 @@ namespace MWGui addGroup( MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); - for (const int& skillIndex : skills) + for (const ESM::RefId& skillId : skills) { - const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search( - ESM::Skill::indexToRefId(skillIndex)); + const ESM::Skill* skill = MWBase::Environment::get().getESMStore()->get().search(skillId); if (!skill) // Skip unknown skills continue; const MWMechanics::SkillValue& stat = mSkillValues.find(skill->mId)->second; diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 44a60bd833..dcb63d4d05 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -24,7 +24,6 @@ namespace MWGui CLASS_DIALOG, BIRTHSIGN_DIALOG }; - typedef std::vector SkillList; ReviewDialog(); @@ -41,7 +40,7 @@ namespace MWGui void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::AttributeValue& value); - void configureSkills(const SkillList& major, const SkillList& minor); + void configureSkills(const std::vector& major, const std::vector& minor); void setSkillValue(ESM::RefId id, const MWMechanics::SkillValue& value); void onOpen() override; @@ -76,8 +75,8 @@ namespace MWGui void onMouseWheel(MyGUI::Widget* _sender, int _rel); private: - void addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, - MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addSkills(const std::vector& skills, const std::string& titleId, + const std::string& titleDefault, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); MyGUI::TextBox* addValueItem(std::string_view text, const std::string& value, const std::string& state, @@ -93,7 +92,7 @@ namespace MWGui std::map mAttributeWidgets; - SkillList mMajorSkills, mMinorSkills, mMiscSkills; + std::vector mMajorSkills, mMinorSkills, mMiscSkills; std::map mSkillValues; std::map mSkillWidgetMap; ESM::RefId mRaceId, mBirthSignId; diff --git a/apps/openmw/mwgui/statswatcher.cpp b/apps/openmw/mwgui/statswatcher.cpp index 05e170a2ad..dab6b9bf82 100644 --- a/apps/openmw/mwgui/statswatcher.cpp +++ b/apps/openmw/mwgui/statswatcher.cpp @@ -125,13 +125,13 @@ namespace MWGui setValue("class", cls->mName); size_t size = cls->mData.mSkills.size(); - MWBase::WindowManager::SkillList majorSkills(size); - MWBase::WindowManager::SkillList minorSkills(size); + std::vector majorSkills(size); + std::vector minorSkills(size); for (size_t i = 0; i < size; ++i) { - minorSkills[i] = cls->mData.mSkills[i][0]; - majorSkills[i] = cls->mData.mSkills[i][1]; + minorSkills[i] = ESM::Skill::indexToRefId(cls->mData.mSkills[i][0]); + majorSkills[i] = ESM::Skill::indexToRefId(cls->mData.mSkills[i][1]); } configureSkills(majorSkills, minorSkills); @@ -181,7 +181,7 @@ namespace MWGui listener->setValue(id, value); } - void StatsWatcher::configureSkills(const std::vector& major, const std::vector& minor) + void StatsWatcher::configureSkills(const std::vector& major, const std::vector& minor) { for (StatsListener* listener : mListeners) listener->configureSkills(major, minor); diff --git a/apps/openmw/mwgui/statswatcher.hpp b/apps/openmw/mwgui/statswatcher.hpp index 5a7c007020..e7339294da 100644 --- a/apps/openmw/mwgui/statswatcher.hpp +++ b/apps/openmw/mwgui/statswatcher.hpp @@ -24,7 +24,7 @@ namespace MWGui virtual void setValue(std::string_view, const std::string& value) {} virtual void setValue(std::string_view, int value) {} virtual void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) {} - virtual void configureSkills(const std::vector& major, const std::vector& minor) {} + virtual void configureSkills(const std::vector& major, const std::vector& minor) {} }; class StatsWatcher @@ -55,7 +55,7 @@ namespace MWGui void setValue(std::string_view id, const std::string& value); void setValue(std::string_view id, int value); void setValue(ESM::RefId id, const MWMechanics::SkillValue& value); - void configureSkills(const std::vector& major, const std::vector& minor); + void configureSkills(const std::vector& major, const std::vector& minor); public: StatsWatcher(); diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index ac04977177..25bc3aee90 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -304,21 +304,21 @@ namespace MWGui } } - void StatsWindow::configureSkills(const std::vector& major, const std::vector& minor) + void StatsWindow::configureSkills(const std::vector& major, const std::vector& minor) { mMajorSkills = major; mMinorSkills = minor; // Update misc skills with the remaining skills not in major or minor - std::set skillSet; + std::set skillSet; std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); 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) { - if (!skillSet.contains(skill.mIndex)) - mMiscSkills.push_back(skill.mIndex); + if (!skillSet.contains(skill.mId)) + mMiscSkills.push_back(skill.mId); } updateSkillArea(); @@ -482,7 +482,7 @@ namespace MWGui return skillNameWidget; } - void StatsWindow::addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, + void StatsWindow::addSkills(const std::vector& skills, const std::string& titleId, const std::string& titleDefault, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { // Add a line separator if there are items above @@ -495,9 +495,9 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); - for (const int skillId : skills) + for (const ESM::RefId& skillId : skills) { - const ESM::Skill* skill = esmStore.get().search(ESM::Skill::indexToRefId(skillId)); + const ESM::Skill* skill = esmStore.get().search(skillId); if (!skill) // Skip unknown skills continue; diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index c497353d9a..ca7a5a7e07 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -12,8 +12,6 @@ namespace MWGui public: typedef std::map FactionList; - typedef std::vector SkillList; - StatsWindow(DragAndDrop* drag); /// automatically updates all the data in the stats window, but only if it has changed. @@ -28,7 +26,7 @@ namespace MWGui void setValue(std::string_view id, const std::string& value) override; void setValue(std::string_view id, int value) override; void setValue(ESM::RefId id, const MWMechanics::SkillValue& value) override; - void configureSkills(const SkillList& major, const SkillList& minor) override; + void configureSkills(const std::vector& major, const std::vector& minor) override; void setReputation(int reputation) { @@ -47,8 +45,8 @@ namespace MWGui void onOpen() override { onWindowResize(mMainWidget->castType()); } private: - void addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, - MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addSkills(const std::vector& skills, const std::string& titleId, + const std::string& titleDefault, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); std::pair addValueItem(std::string_view text, const std::string& value, @@ -67,7 +65,7 @@ namespace MWGui MyGUI::ScrollView* mSkillView; - SkillList mMajorSkills, mMinorSkills, mMiscSkills; + std::vector mMajorSkills, mMinorSkills, mMiscSkills; std::map mSkillValues; std::map> mSkillWidgetMap; std::map mFactionWidgetMap; From 2cb77ed48f862a20be216102eb4a673725718090 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 20:54:55 +0200 Subject: [PATCH 10/15] Dehardcode skill selection --- apps/openmw/mwgui/class.cpp | 57 ++++++++----------- apps/openmw/mwgui/class.hpp | 4 -- .../mygui/openmw_chargen_select_skill.layout | 36 +++--------- 3 files changed, 33 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 55f9f277a4..b26d750191 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -795,43 +796,33 @@ namespace MWGui // Centre dialog center(); - for (int i = 0; i < 9; i++) + std::array, 3> specializations; + getWidget(specializations[ESM::Class::Combat].first, "CombatSkills"); + getWidget(specializations[ESM::Class::Magic].first, "MagicSkills"); + getWidget(specializations[ESM::Class::Stealth].first, "StealthSkills"); + for (auto& [widget, coord] : specializations) { - char theIndex = '0' + i; - getWidget(mCombatSkill[i], std::string("CombatSkill").append(1, theIndex)); - getWidget(mMagicSkill[i], std::string("MagicSkill").append(1, theIndex)); - getWidget(mStealthSkill[i], std::string("StealthSkill").append(1, theIndex)); + coord.width = widget->getCoord().width; + coord.height = 18; + while (widget->getChildCount() > 0) + MyGUI::Gui::getInstance().destroyWidget(widget->getChildAt(0)); } - - struct + for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get()) { - Widgets::MWSkillPtr widget; - ESM::RefId skillId; - } mSkills[3][9] - = { { { mCombatSkill[0], ESM::Skill::Block }, { mCombatSkill[1], ESM::Skill::Armorer }, - { mCombatSkill[2], ESM::Skill::MediumArmor }, { mCombatSkill[3], ESM::Skill::HeavyArmor }, - { mCombatSkill[4], ESM::Skill::BluntWeapon }, { mCombatSkill[5], ESM::Skill::LongBlade }, - { mCombatSkill[6], ESM::Skill::Axe }, { mCombatSkill[7], ESM::Skill::Spear }, - { mCombatSkill[8], ESM::Skill::Athletics } }, - { { mMagicSkill[0], ESM::Skill::Enchant }, { mMagicSkill[1], ESM::Skill::Destruction }, - { mMagicSkill[2], ESM::Skill::Alteration }, { mMagicSkill[3], ESM::Skill::Illusion }, - { mMagicSkill[4], ESM::Skill::Conjuration }, { mMagicSkill[5], ESM::Skill::Mysticism }, - { mMagicSkill[6], ESM::Skill::Restoration }, { mMagicSkill[7], ESM::Skill::Alchemy }, - { mMagicSkill[8], ESM::Skill::Unarmored } }, - { { mStealthSkill[0], ESM::Skill::Security }, { mStealthSkill[1], ESM::Skill::Sneak }, - { mStealthSkill[2], ESM::Skill::Acrobatics }, { mStealthSkill[3], ESM::Skill::LightArmor }, - { mStealthSkill[4], ESM::Skill::ShortBlade }, { mStealthSkill[5], ESM::Skill::Marksman }, - { mStealthSkill[6], ESM::Skill::Mercantile }, { mStealthSkill[7], ESM::Skill::Speechcraft }, - { mStealthSkill[8], ESM::Skill::HandToHand } } }; - - for (int spec = 0; spec < 3; ++spec) + auto& [widget, coord] = specializations[skill.mData.mSpecialization]; + auto* skillWidget + = widget->createWidget("MW_StatNameButton", coord, MyGUI::Align::Default); + coord.top += coord.height; + skillWidget->setSkillId(skill.mId); + skillWidget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); + ToolTips::createSkillToolTip(skillWidget, skill.mId); + } + for (const auto& [widget, coord] : specializations) { - for (int i = 0; i < 9; ++i) - { - mSkills[spec][i].widget->setSkillId(mSkills[spec][i].skillId); - mSkills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); - ToolTips::createSkillToolTip(mSkills[spec][i].widget, mSkills[spec][i].widget->getSkillId()); - } + widget->setVisibleVScroll(false); + widget->setCanvasSize(MyGUI::IntSize(widget->getWidth(), std::max(widget->getHeight(), coord.top))); + widget->setVisibleVScroll(true); + widget->setViewOffset(MyGUI::IntPoint()); } MyGUI::Button* cancelButton; diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index e00d9b98dd..1052dab581 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -239,10 +239,6 @@ namespace MWGui void onCancelClicked(MyGUI::Widget* _sender); private: - Widgets::MWSkillPtr mCombatSkill[9]; - Widgets::MWSkillPtr mMagicSkill[9]; - Widgets::MWSkillPtr mStealthSkill[9]; - ESM::RefId mSkillId; }; diff --git a/files/data/mygui/openmw_chargen_select_skill.layout b/files/data/mygui/openmw_chargen_select_skill.layout index c047d7158d..c449c7d0af 100644 --- a/files/data/mygui/openmw_chargen_select_skill.layout +++ b/files/data/mygui/openmw_chargen_select_skill.layout @@ -14,45 +14,27 @@ - - - - - - - - - + + + - - - - - - - - - + + + - - - - - - - - - + + + From f62ba346e17aa4a9b6b469010032d91c989f4dc0 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 6 Jun 2023 21:02:46 +0200 Subject: [PATCH 11/15] Appease the formatting gods --- apps/openmw/mwgui/statswindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 25bc3aee90..4bd82faa70 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -482,8 +482,8 @@ namespace MWGui return skillNameWidget; } - void StatsWindow::addSkills(const std::vector& skills, const std::string& titleId, const std::string& titleDefault, - MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) + void StatsWindow::addSkills(const std::vector& skills, const std::string& titleId, + const std::string& titleDefault, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { // Add a line separator if there are items above if (!mSkillWidgets.empty()) From 627bfa115502dd44b0f93380293fd9b358e87d31 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 7 Jun 2023 19:13:09 +0200 Subject: [PATCH 12/15] Silence a clang warning --- apps/openmw/mwworld/store.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 07d6fd0865..a839f317f2 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -478,6 +478,8 @@ namespace MWWorld template <> class Store : public TypedDynamicStore { + using TypedDynamicStore::setUp; + public: Store() = default; From 3a888ef543cf2c2a2cc0fce5bff6449a76d57047 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 7 Jun 2023 20:08:08 +0200 Subject: [PATCH 13/15] Prevent a static initialization order fiasco --- apps/openmw/mwmechanics/weapontype.cpp | 434 ++++++++++++++----------- 1 file changed, 253 insertions(+), 181 deletions(-) diff --git a/apps/openmw/mwmechanics/weapontype.cpp b/apps/openmw/mwmechanics/weapontype.cpp index 0612ca1a2e..9dd5842f58 100644 --- a/apps/openmw/mwmechanics/weapontype.cpp +++ b/apps/openmw/mwmechanics/weapontype.cpp @@ -18,253 +18,325 @@ namespace MWMechanics template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1h", - /* long group */ "pickprobe", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Security, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1h", + /* long group */ "pickprobe", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Security, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "spell", - /* long group */ "spellcast", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "spell", + /* long group */ "spellcast", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "hh", - /* long group */ "handtohand", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "hh", + /* long group */ "handtohand", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1s", - /* long group */ "shortbladeonehand", - /* sound ID */ "Item Weapon Shortblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 ShortBladeOneHand", - /* usage skill */ ESM::Skill::ShortBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1s", + /* long group */ "shortbladeonehand", + /* sound ID */ "Item Weapon Shortblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 ShortBladeOneHand", + /* usage skill */ ESM::Skill::ShortBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1h", - /* long group */ "weapononehand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1h", + /* long group */ "weapononehand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntOneHand", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntOneHand", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2c", - /* long group */ "weapontwohand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeTwoClose", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2c", + /* long group */ "weapontwohand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeTwoClose", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 AxeTwoClose", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 AxeTwoClose", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoClose", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoClose", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoWide", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoWide", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Spear", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 SpearTwoWide", - /* usage skill */ ESM::Skill::Spear, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Spear", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 SpearTwoWide", + /* usage skill */ ESM::Skill::Spear, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "bow", - /* long group */ "bowandarrow", - /* sound ID */ "Item Weapon Bow", - /* attach bone */ "Weapon Bone Left", - /* sheath bone */ "Bip01 MarksmanBow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Arrow, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "bow", + /* long group */ "bowandarrow", + /* sound ID */ "Item Weapon Bow", + /* attach bone */ "Weapon Bone Left", + /* sheath bone */ "Bip01 MarksmanBow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Arrow, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "crossbow", - /* long group */ "crossbow", - /* sound ID */ "Item Weapon Crossbow", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanCrossbow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Bolt, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "crossbow", + /* long group */ "crossbow", + /* sound ID */ "Item Weapon Crossbow", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanCrossbow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Bolt, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "1t", - /* long group */ "throwweapon", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanThrown", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Thrown, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "1t", + /* long group */ "throwweapon", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanThrown", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Thrown, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "Bip01 Arrow", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "Bip01 Arrow", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; template <> struct Weapon { - inline static const ESM::WeaponType sValue{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "ArrowBone", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; + inline static const ESM::WeaponType& getValue() + { + static const ESM::WeaponType value{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "ArrowBone", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; + return value; + } }; MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int* weaptype) @@ -305,43 +377,43 @@ namespace MWMechanics switch (static_cast(weaponType)) { case ESM::Weapon::PickProbe: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::HandToHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Spell: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::None: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::ShortBladeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::LongBladeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::LongBladeTwoHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntTwoClose: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::BluntTwoWide: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::SpearTwoWide: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::AxeOneHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::AxeTwoHand: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanBow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanCrossbow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::MarksmanThrown: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Arrow: - return &Weapon::sValue; + return &Weapon::getValue(); case ESM::Weapon::Bolt: - return &Weapon::sValue; + return &Weapon::getValue(); } - return &Weapon::sValue; + return &Weapon::getValue(); } } From 583a0b4d0478af4ad316b4ca196c56200dc6100f Mon Sep 17 00:00:00 2001 From: jvoisin Date: Thu, 8 Jun 2023 16:34:45 +0000 Subject: [PATCH 14/15] Apply jvoisin's suggestions --- apps/openmw/mwclass/actor.cpp | 2 +- apps/openmw/mwclass/armor.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 6729a22f39..152a4bbba9 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -43,7 +43,7 @@ namespace MWClass return; MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); - ESM::RefId skill = shield->getClass().getEquipmentSkill(*shield); + const ESM::RefId skill = shield->getClass().getEquipmentSkill(*shield); if (skill == ESM::Skill::LightArmor) sndMgr->playSound3D(ptr, ESM::RefId::stringRefId("Light Armor Hit"), 1.0f, 1.0f); else if (skill == ESM::Skill::MediumArmor) diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index f1c22c1d43..8b23349f09 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -178,7 +178,7 @@ namespace MWClass const ESM::RefId& Armor::getUpSoundId(const MWWorld::ConstPtr& ptr) const { - ESM::RefId es = getEquipmentSkill(ptr); + const ESM::RefId es = getEquipmentSkill(ptr); static const ESM::RefId lightUp = ESM::RefId::stringRefId("Item Armor Light Up"); static const ESM::RefId mediumUp = ESM::RefId::stringRefId("Item Armor Medium Up"); static const ESM::RefId heavyUp = ESM::RefId::stringRefId("Item Armor Heavy Up"); @@ -193,7 +193,7 @@ namespace MWClass const ESM::RefId& Armor::getDownSoundId(const MWWorld::ConstPtr& ptr) const { - ESM::RefId es = getEquipmentSkill(ptr); + const ESM::RefId es = getEquipmentSkill(ptr); static const ESM::RefId lightDown = ESM::RefId::stringRefId("Item Armor Light Down"); static const ESM::RefId mediumDown = ESM::RefId::stringRefId("Item Armor Medium Down"); static const ESM::RefId heavyDown = ESM::RefId::stringRefId("Item Armor Heavy Down"); @@ -232,7 +232,7 @@ namespace MWClass } else { - ESM::RefId armorType = getEquipmentSkill(ptr); + const ESM::RefId armorType = getEquipmentSkill(ptr); if (armorType == ESM::Skill::LightArmor) typeText = "#{sLight}"; else if (armorType == ESM::Skill::MediumArmor) @@ -297,7 +297,7 @@ namespace MWClass { const MWWorld::LiveCellRef* ref = ptr.get(); - ESM::RefId armorSkillType = getEquipmentSkill(ptr); + const ESM::RefId armorSkillType = getEquipmentSkill(ptr); float armorSkill = actor.getClass().getSkill(actor, armorSkillType); int iBaseArmorSkill = MWBase::Environment::get() From 3c588900dd4afef5320e765dc72850cf2ef25ce5 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sat, 10 Jun 2023 22:04:14 +0200 Subject: [PATCH 15/15] Apply elsid's suggestion and revert 3a888ef543cf2c2a2cc0fce5bff6449a76d57047 --- apps/openmw/mwmechanics/weapontype.cpp | 434 +++++++++++-------------- components/esm3/loadskil.cpp | 28 -- components/esm3/loadskil.hpp | 54 +-- 3 files changed, 208 insertions(+), 308 deletions(-) diff --git a/apps/openmw/mwmechanics/weapontype.cpp b/apps/openmw/mwmechanics/weapontype.cpp index 9dd5842f58..0612ca1a2e 100644 --- a/apps/openmw/mwmechanics/weapontype.cpp +++ b/apps/openmw/mwmechanics/weapontype.cpp @@ -18,325 +18,253 @@ namespace MWMechanics template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "", - /* long group */ "", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "", + /* long group */ "", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1h", - /* long group */ "pickprobe", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Security, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1h", + /* long group */ "pickprobe", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Security, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "spell", - /* long group */ "spellcast", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "spell", + /* long group */ "spellcast", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "hh", - /* long group */ "handtohand", - /* sound ID */ "", - /* attach bone */ "", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::HandToHand, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "hh", + /* long group */ "handtohand", + /* sound ID */ "", + /* attach bone */ "", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::HandToHand, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1s", - /* long group */ "shortbladeonehand", - /* sound ID */ "Item Weapon Shortblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 ShortBladeOneHand", - /* usage skill */ ESM::Skill::ShortBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1s", + /* long group */ "shortbladeonehand", + /* sound ID */ "Item Weapon Shortblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 ShortBladeOneHand", + /* usage skill */ ESM::Skill::ShortBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1h", - /* long group */ "weapononehand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1h", + /* long group */ "weapononehand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntOneHand", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntOneHand", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1b", - /* long group */ "bluntonehand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeOneHand", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1b", + /* long group */ "bluntonehand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeOneHand", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "2c", - /* long group */ "weapontwohand", - /* sound ID */ "Item Weapon Longblade", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 LongBladeTwoClose", - /* usage skill */ ESM::Skill::LongBlade, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "2c", + /* long group */ "weapontwohand", + /* sound ID */ "Item Weapon Longblade", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 LongBladeTwoClose", + /* usage skill */ ESM::Skill::LongBlade, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 AxeTwoClose", - /* usage skill */ ESM::Skill::Axe, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 AxeTwoClose", + /* usage skill */ ESM::Skill::Axe, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "2b", - /* long group */ "blunttwohand", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoClose", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "2b", + /* long group */ "blunttwohand", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoClose", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 BluntTwoWide", - /* usage skill */ ESM::Skill::BluntWeapon, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 BluntTwoWide", + /* usage skill */ ESM::Skill::BluntWeapon, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "2w", - /* long group */ "weapontwowide", - /* sound ID */ "Item Weapon Spear", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 SpearTwoWide", - /* usage skill */ ESM::Skill::Spear, - /* weapon class*/ ESM::WeaponType::Melee, - /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "2w", + /* long group */ "weapontwowide", + /* sound ID */ "Item Weapon Spear", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 SpearTwoWide", + /* usage skill */ ESM::Skill::Spear, + /* weapon class*/ ESM::WeaponType::Melee, + /* ammo type */ ESM::Weapon::None, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "bow", - /* long group */ "bowandarrow", - /* sound ID */ "Item Weapon Bow", - /* attach bone */ "Weapon Bone Left", - /* sheath bone */ "Bip01 MarksmanBow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Arrow, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "bow", + /* long group */ "bowandarrow", + /* sound ID */ "Item Weapon Bow", + /* attach bone */ "Weapon Bone Left", + /* sheath bone */ "Bip01 MarksmanBow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Arrow, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "crossbow", - /* long group */ "crossbow", - /* sound ID */ "Item Weapon Crossbow", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanCrossbow", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ranged, - /* ammo type */ ESM::Weapon::Bolt, - /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "crossbow", + /* long group */ "crossbow", + /* sound ID */ "Item Weapon Crossbow", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanCrossbow", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ranged, + /* ammo type */ ESM::Weapon::Bolt, + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "1t", - /* long group */ "throwweapon", - /* sound ID */ "Item Weapon Blunt", - /* attach bone */ "Weapon Bone", - /* sheath bone */ "Bip01 MarksmanThrown", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Thrown, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "1t", + /* long group */ "throwweapon", + /* sound ID */ "Item Weapon Blunt", + /* attach bone */ "Weapon Bone", + /* sheath bone */ "Bip01 MarksmanThrown", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Thrown, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "Bip01 Arrow", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "Bip01 Arrow", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType& getValue() - { - static const ESM::WeaponType value{ /* short group */ "", - /* long group */ "", - /* sound ID */ "Item Ammo", - /* attach bone */ "ArrowBone", - /* sheath bone */ "", - /* usage skill */ ESM::Skill::Marksman, - /* weapon class*/ ESM::WeaponType::Ammo, - /* ammo type */ ESM::Weapon::None, - /* flags */ 0 }; - return value; - } + inline static const ESM::WeaponType sValue{ /* short group */ "", + /* long group */ "", + /* sound ID */ "Item Ammo", + /* attach bone */ "ArrowBone", + /* sheath bone */ "", + /* usage skill */ ESM::Skill::Marksman, + /* weapon class*/ ESM::WeaponType::Ammo, + /* ammo type */ ESM::Weapon::None, + /* flags */ 0 }; }; MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int* weaptype) @@ -377,43 +305,43 @@ namespace MWMechanics switch (static_cast(weaponType)) { case ESM::Weapon::PickProbe: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::HandToHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::Spell: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::None: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::ShortBladeOneHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::LongBladeOneHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::LongBladeTwoHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::BluntOneHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::BluntTwoClose: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::BluntTwoWide: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::SpearTwoWide: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::AxeOneHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::AxeTwoHand: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::MarksmanBow: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::MarksmanCrossbow: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::MarksmanThrown: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::Arrow: - return &Weapon::getValue(); + return &Weapon::sValue; case ESM::Weapon::Bolt: - return &Weapon::getValue(); + return &Weapon::sValue; } - return &Weapon::getValue(); + return &Weapon::sValue; } } diff --git a/components/esm3/loadskil.cpp b/components/esm3/loadskil.cpp index 14dd9acac2..983ef8a152 100644 --- a/components/esm3/loadskil.cpp +++ b/components/esm3/loadskil.cpp @@ -7,34 +7,6 @@ namespace ESM { - const RefId Skill::Block = Skill::indexToRefId(0); - const RefId Skill::Armorer = Skill::indexToRefId(1); - const RefId Skill::MediumArmor = Skill::indexToRefId(2); - const RefId Skill::HeavyArmor = Skill::indexToRefId(3); - const RefId Skill::BluntWeapon = Skill::indexToRefId(4); - const RefId Skill::LongBlade = Skill::indexToRefId(5); - const RefId Skill::Axe = Skill::indexToRefId(6); - const RefId Skill::Spear = Skill::indexToRefId(7); - const RefId Skill::Athletics = Skill::indexToRefId(8); - const RefId Skill::Enchant = Skill::indexToRefId(9); - const RefId Skill::Destruction = Skill::indexToRefId(10); - const RefId Skill::Alteration = Skill::indexToRefId(11); - const RefId Skill::Illusion = Skill::indexToRefId(12); - const RefId Skill::Conjuration = Skill::indexToRefId(13); - const RefId Skill::Mysticism = Skill::indexToRefId(14); - const RefId Skill::Restoration = Skill::indexToRefId(15); - const RefId Skill::Alchemy = Skill::indexToRefId(16); - const RefId Skill::Unarmored = Skill::indexToRefId(17); - const RefId Skill::Security = Skill::indexToRefId(18); - const RefId Skill::Sneak = Skill::indexToRefId(19); - const RefId Skill::Acrobatics = Skill::indexToRefId(20); - const RefId Skill::LightArmor = Skill::indexToRefId(21); - const RefId Skill::ShortBlade = Skill::indexToRefId(22); - const RefId Skill::Marksman = Skill::indexToRefId(23); - const RefId Skill::Mercantile = Skill::indexToRefId(24); - const RefId Skill::Speechcraft = Skill::indexToRefId(25); - const RefId Skill::HandToHand = Skill::indexToRefId(26); - const std::string Skill::sSkillNames[Length] = { "Block", "Armorer", diff --git a/components/esm3/loadskil.hpp b/components/esm3/loadskil.hpp index bd956475bf..ea3dd6954b 100644 --- a/components/esm3/loadskil.hpp +++ b/components/esm3/loadskil.hpp @@ -48,33 +48,33 @@ namespace ESM std::string mIcon; float mWerewolfValue{}; - static const RefId Block; - static const RefId Armorer; - static const RefId MediumArmor; - static const RefId HeavyArmor; - static const RefId BluntWeapon; - static const RefId LongBlade; - static const RefId Axe; - static const RefId Spear; - static const RefId Athletics; - static const RefId Enchant; - static const RefId Destruction; - static const RefId Alteration; - static const RefId Illusion; - static const RefId Conjuration; - static const RefId Mysticism; - static const RefId Restoration; - static const RefId Alchemy; - static const RefId Unarmored; - static const RefId Security; - static const RefId Sneak; - static const RefId Acrobatics; - static const RefId LightArmor; - static const RefId ShortBlade; - static const RefId Marksman; - static const RefId Mercantile; - static const RefId Speechcraft; - static const RefId HandToHand; + static constexpr IndexRefId Block{ sRecordId, 0 }; + static constexpr IndexRefId Armorer{ sRecordId, 1 }; + static constexpr IndexRefId MediumArmor{ sRecordId, 2 }; + static constexpr IndexRefId HeavyArmor{ sRecordId, 3 }; + static constexpr IndexRefId BluntWeapon{ sRecordId, 4 }; + static constexpr IndexRefId LongBlade{ sRecordId, 5 }; + static constexpr IndexRefId Axe{ sRecordId, 6 }; + static constexpr IndexRefId Spear{ sRecordId, 7 }; + static constexpr IndexRefId Athletics{ sRecordId, 8 }; + static constexpr IndexRefId Enchant{ sRecordId, 9 }; + static constexpr IndexRefId Destruction{ sRecordId, 10 }; + static constexpr IndexRefId Alteration{ sRecordId, 11 }; + static constexpr IndexRefId Illusion{ sRecordId, 12 }; + static constexpr IndexRefId Conjuration{ sRecordId, 13 }; + static constexpr IndexRefId Mysticism{ sRecordId, 14 }; + static constexpr IndexRefId Restoration{ sRecordId, 15 }; + static constexpr IndexRefId Alchemy{ sRecordId, 16 }; + static constexpr IndexRefId Unarmored{ sRecordId, 17 }; + static constexpr IndexRefId Security{ sRecordId, 18 }; + static constexpr IndexRefId Sneak{ sRecordId, 19 }; + static constexpr IndexRefId Acrobatics{ sRecordId, 20 }; + static constexpr IndexRefId LightArmor{ sRecordId, 21 }; + static constexpr IndexRefId ShortBlade{ sRecordId, 22 }; + static constexpr IndexRefId Marksman{ sRecordId, 23 }; + static constexpr IndexRefId Mercantile{ sRecordId, 24 }; + static constexpr IndexRefId Speechcraft{ sRecordId, 25 }; + static constexpr IndexRefId HandToHand{ sRecordId, 26 }; static constexpr int Length = 27; static const std::string sSkillNames[Length];