diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 77bfaddf64..4157a03bc0 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -73,9 +73,9 @@ namespace MWClass { float weight = getContainerStore(ptr).getWeight(); const MWMechanics::MagicEffects& effects = getCreatureStats(ptr).getMagicEffects(); - weight -= effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Feather)).getMagnitude(); + weight -= effects.getOrDefault(MWMechanics::EffectKey(ESM::MagicEffect::Feather)).getMagnitude(); if (ptr != MWMechanics::getPlayer() || !MWBase::Environment::get().getWorld()->getGodModeState()) - weight += effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); + weight += effects.getOrDefault(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); return (weight < 0) ? 0.0f : weight; } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index fae31b8d20..5a143c7a7d 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -28,7 +28,7 @@ namespace MWClass float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects, float baseSpeed) const { - return baseSpeed * (1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude()) + return baseSpeed * (1.0f + 0.01f * mageffects.getOrDefault(ESM::MagicEffect::SwiftSwim).getMagnitude()) * (gmst.fSwimRunBase->mValue.getFloat() + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat()); } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 7ea0c7c111..39de4a5b1d 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -555,11 +555,11 @@ namespace MWClass if (getEncumbrance(ptr) > getCapacity(ptr)) moveSpeed = 0.0f; else if (canFly(ptr) - || (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled())) + || (mageffects.getOrDefault(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled())) { float flySpeed = 0.01f * (stats.getAttribute(ESM::Attribute::Speed).getModified() - + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); + + mageffects.getOrDefault(ESM::MagicEffect::Levitate).getMagnitude()); flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); @@ -614,7 +614,7 @@ namespace MWClass float Creature::getArmorRating(const MWWorld::Ptr& ptr) const { // Equipment armor rating is deliberately ignored. - return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude(); + return getCreatureStats(ptr).getMagicEffects().getOrDefault(ESM::MagicEffect::Shield).getMagnitude(); } float Creature::getCapacity(const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index d734a3868c..7aba7b2b50 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1021,11 +1021,11 @@ namespace MWClass float moveSpeed; if (getEncumbrance(ptr) > getCapacity(ptr)) moveSpeed = 0.0f; - else if (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled()) + else if (mageffects.getOrDefault(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled()) { float flySpeed = 0.01f * (stats.getAttribute(ESM::Attribute::Speed).getModified() - + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); + + mageffects.getOrDefault(ESM::MagicEffect::Levitate).getMagnitude()); flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; @@ -1071,7 +1071,7 @@ namespace MWClass float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() + std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat()); x += 3.0f * b * gmst.fJumpAcroMultiplier->mValue.getFloat(); - x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64; + x += mageffects.getOrDefault(ESM::MagicEffect::Jump).getMagnitude() * 64; x *= encumbranceTerm; if (stats.getStance(MWMechanics::CreatureStats::Stance_Run)) @@ -1217,7 +1217,7 @@ namespace MWClass } } - float shield = stats.getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude(); + float shield = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Shield).getMagnitude(); return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3f + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 0ad82be488..c5ec812a8f 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -582,7 +582,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con return player.getClass() .getCreatureStats(player) .getMagicEffects() - .get(ESM::MagicEffect::Corprus) + .getOrDefault(ESM::MagicEffect::Corprus) .getMagnitude() != 0; @@ -601,7 +601,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con return player.getClass() .getCreatureStats(player) .getMagicEffects() - .get(ESM::MagicEffect::Vampirism) + .getOrDefault(ESM::MagicEffect::Vampirism) .getMagnitude() > 0; diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 7039c757e3..a1d3ea6f9f 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -37,8 +37,8 @@ namespace const MWWorld::Store& gmst = MWBase::Environment::get().getESMStore()->get(); - return gmst.find(ESM::MagicEffect::effectIdToGmstString(id1))->mValue.getString() - < gmst.find(ESM::MagicEffect::effectIdToGmstString(id2))->mValue.getString(); + return gmst.find(ESM::MagicEffect::indexToGmstString(id1))->mValue.getString() + < gmst.find(ESM::MagicEffect::indexToGmstString(id2))->mValue.getString(); } void init(ESM::ENAMstruct& effect) @@ -196,7 +196,7 @@ namespace MWGui mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath( effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); - mEffectName->setCaptionWithReplacing("#{" + ESM::MagicEffect::effectIdToGmstString(effect->mIndex) + "}"); + mEffectName->setCaptionWithReplacing("#{" + ESM::MagicEffect::indexToGmstString(effect->mIndex) + "}"); mEffect.mEffectID = effect->mIndex; @@ -552,7 +552,7 @@ namespace MWGui mAvailableEffectsList->addItem(MWBase::Environment::get() .getESMStore() ->get() - .find(ESM::MagicEffect::effectIdToGmstString(effectId)) + .find(ESM::MagicEffect::indexToGmstString(effectId)) ->mValue.getString()); mButtonMapping[i] = effectId; ++i; @@ -565,7 +565,7 @@ namespace MWGui const std::string& name = MWBase::Environment::get() .getESMStore() ->get() - .find(ESM::MagicEffect::effectIdToGmstString(effectId)) + .find(ESM::MagicEffect::indexToGmstString(effectId)) ->mValue.getString(); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index d8747d2426..ba94eaba95 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -162,7 +162,7 @@ namespace MWGui image->setImageTexture(Misc::ResourceHelpers::correctIconPath( effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); - const std::string& name = ESM::MagicEffect::effectIdToGmstString(effectId); + const std::string& name = ESM::MagicEffect::indexToGmstString(effectId); ToolTipInfo tooltipInfo; tooltipInfo.caption = "#{" + name + "}"; diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 5b152fe5b8..2904f20236 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -954,7 +954,7 @@ namespace MWGui void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id) { const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get().find(id); - const std::string& name = ESM::MagicEffect::effectIdToGmstString(id); + const std::string& name = ESM::MagicEffect::indexToGmstString(id); std::string icon = effect->mIcon; int slashPos = icon.rfind('\\'); diff --git a/apps/openmw/mwlua/magicbindings.cpp b/apps/openmw/mwlua/magicbindings.cpp index 2b4afab6d1..e5723f1c34 100644 --- a/apps/openmw/mwlua/magicbindings.cpp +++ b/apps/openmw/mwlua/magicbindings.cpp @@ -191,7 +191,7 @@ namespace MWLua sol::table effect(context.mLua->sol(), sol::create); magicApi["EFFECT_TYPE"] = LuaUtil::makeStrictReadOnly(effect); - for (const auto& name : ESM::MagicEffect::sEffectNames) + for (const auto& name : ESM::MagicEffect::sIndexNames) { effect[name] = Misc::StringUtils::lowerCase(name); } @@ -263,7 +263,7 @@ namespace MWLua auto effectParamsT = lua.new_usertype("ESM3_EffectParams"); effectParamsT[sol::meta_function::to_string] = [magicEffectStore](const ESM::ENAMstruct& params) { const ESM::MagicEffect* const rec = magicEffectStore->find(params.mEffectID); - return "ESM3_EffectParams[" + ESM::MagicEffect::effectIdToGmstString(rec->mIndex) + "]"; + return "ESM3_EffectParams[" + ESM::MagicEffect::indexToGmstString(rec->mIndex) + "]"; }; effectParamsT["effect"] = sol::readonly_property([magicEffectStore](const ESM::ENAMstruct& params) -> const ESM::MagicEffect* { @@ -296,10 +296,10 @@ namespace MWLua auto magicEffectT = context.mLua->sol().new_usertype("ESM3_MagicEffect"); magicEffectT[sol::meta_function::to_string] = [](const ESM::MagicEffect& rec) { - return "ESM3_MagicEffect[" + ESM::MagicEffect::effectIdToGmstString(rec.mIndex) + "]"; + return "ESM3_MagicEffect[" + ESM::MagicEffect::indexToGmstString(rec.mIndex) + "]"; }; magicEffectT["id"] = sol::readonly_property([](const ESM::MagicEffect& rec) -> std::string { - auto name = ESM::MagicEffect::effectIdToName(rec.mIndex); + auto name = ESM::MagicEffect::indexToName(rec.mIndex); return Misc::StringUtils::lowerCase(name); }); magicEffectT["name"] = sol::readonly_property([](const ESM::MagicEffect& rec) -> std::string_view { @@ -307,7 +307,7 @@ namespace MWLua .getWorld() ->getStore() .get() - .find(ESM::MagicEffect::effectIdToGmstString(rec.mIndex)) + .find(ESM::MagicEffect::indexToGmstString(rec.mIndex)) ->mValue.getString(); }); magicEffectT["school"] @@ -327,10 +327,10 @@ namespace MWLua auto activeEffectT = context.mLua->sol().new_usertype("ActiveEffect"); activeEffectT[sol::meta_function::to_string] = [](const ActiveEffect& effect) { - return "ActiveEffect[" + ESM::MagicEffect::effectIdToGmstString(effect.key.mId) + "]"; + return "ActiveEffect[" + ESM::MagicEffect::indexToGmstString(effect.key.mId) + "]"; }; activeEffectT["id"] = sol::readonly_property([](const ActiveEffect& effect) -> std::string { - auto name = ESM::MagicEffect::effectIdToName(effect.key.mId); + auto name = ESM::MagicEffect::indexToName(effect.key.mId); return Misc::StringUtils::lowerCase(name); }); activeEffectT["name"] @@ -570,7 +570,7 @@ namespace MWLua if (!effects.isActor()) return sol::nullopt; - auto id = ESM::MagicEffect::effectNameToId(idStr); + auto id = ESM::MagicEffect::indexNameToIndex(idStr); auto* rec = MWBase::Environment::get().getWorld()->getStore().get().find(id); MWMechanics::EffectKey key = MWMechanics::EffectKey(id); @@ -586,10 +586,10 @@ namespace MWLua key = MWMechanics::EffectKey(id, ESM::Skill::stringToSkillId(argStr.value())); } - MWMechanics::EffectParam param; + std::optional param; if (auto* store = effects.getStore()) if (store->get(key, param)) - return ActiveEffect{ key, param }; + return ActiveEffect{ key, param.value() }; return sol::nullopt; }; } diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 69c73c2130..65683ea2b5 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -374,7 +374,7 @@ namespace MWMechanics { ESM::MagicEffect::Effects effect = ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature; - if (creatureStats.getMagicEffects().get(effect).getMagnitude() > 0.f) + if (creatureStats.getMagicEffects().getOrDefault(effect).getMagnitude() > 0.f) creatureStats.getAiSequence().stopCombat(); } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index dddf3f5ec9..20e765fc5e 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -158,7 +158,7 @@ namespace void soulTrap(const MWWorld::Ptr& creature) { const auto& stats = creature.getClass().getCreatureStats(creature); - if (!stats.getMagicEffects().get(ESM::MagicEffect::Soultrap).getMagnitude()) + if (!stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Soultrap).getMagnitude()) return; const int creatureSoulValue = creature.get()->mBase->mData.mSoul; if (creatureSoulValue == 0) @@ -668,7 +668,7 @@ namespace MWMechanics } } - if (creatureStats2.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude() > 0) + if (creatureStats2.getMagicEffects().getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude() > 0) return; // Stop here if target is unreachable @@ -828,7 +828,8 @@ namespace MWMechanics stats.setHealth(stat); double restoreHours = hours; - const bool stunted = stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; + const bool stunted + = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; if (stunted) { // Stunted Magicka effect should be taken into account. @@ -954,7 +955,7 @@ namespace MWMechanics const bool knockedOutUnderwater = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3()))); if ((world->isSubmerged(ptr) || knockedOutUnderwater) - && stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0) + && stats.getMagicEffects().getOrDefault(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0) { float timeLeft = 0.0f; if (knockedOutUnderwater) @@ -1110,7 +1111,7 @@ namespace MWMechanics if (actorClass.isClass(ptr, "Guard") && !creatureStats.getAiSequence().isInPursuit() && !creatureStats.getAiSequence().isInCombat() - && creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) + && creatureStats.getMagicEffects().getOrDefault(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) { const MWWorld::ESMStore& esmStore = world->getStore(); static const int cutoff = esmStore.get().find("iCrimeThreshold")->mValue.getInteger(); @@ -1814,7 +1815,8 @@ namespace MWMechanics // Reset magic effects and recalculate derived effects // One case where we need this is to make sure bound items are removed upon death - const float vampirism = stats.getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude(); + const float vampirism + = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Vampirism).getMagnitude(); stats.getActiveSpells().clear(actor.getPtr()); // Make sure spell effects are removed purgeSpellEffects(stats.getActorId()); @@ -2002,7 +2004,7 @@ namespace MWMechanics const auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - const bool stunted = stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; + const bool stunted = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; const float healthHours = healthPerHour > 0 ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour diff --git a/apps/openmw/mwmechanics/actorutil.cpp b/apps/openmw/mwmechanics/actorutil.cpp index 5b255b3d78..c414ff3032 100644 --- a/apps/openmw/mwmechanics/actorutil.cpp +++ b/apps/openmw/mwmechanics/actorutil.cpp @@ -32,13 +32,13 @@ namespace MWMechanics bool hasWaterWalking(const MWWorld::Ptr& actor) { const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects(); - return effects.get(ESM::MagicEffect::WaterWalking).getMagnitude() > 0; + return effects.getOrDefault(ESM::MagicEffect::WaterWalking).getMagnitude() > 0; } bool isTargetMagicallyHidden(const MWWorld::Ptr& actor) { const MagicEffects& magicEffects = actor.getClass().getCreatureStats(actor).getMagicEffects(); - return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0) - || (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75); + return (magicEffects.getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude() > 0) + || (magicEffects.getOrDefault(ESM::MagicEffect::Chameleon).getMagnitude() > 75); } } diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 7981ed123a..86943b1786 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -464,7 +464,7 @@ namespace MWMechanics if (enemy.getClass() .getCreatureStats(enemy) .getMagicEffects() - .get(ESM::MagicEffect::Levitate) + .getOrDefault(ESM::MagicEffect::Levitate) .getMagnitude() > 0) { @@ -484,7 +484,11 @@ namespace MWMechanics if (!actor.getClass().canWalk(actor) && !actor.getClass().isBipedal(actor)) return true; - if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() + if (actor.getClass() + .getCreatureStats(actor) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Levitate) + .getMagnitude() > 0) return true; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f4f53a7110..38788c3445 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -284,8 +284,11 @@ namespace if (fallHeight >= fallDistanceMin) { const float acrobaticsSkill = static_cast(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics)); - const float jumpSpellBonus - = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude(); + const float jumpSpellBonus = ptr.getClass() + .getCreatureStats(ptr) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Jump) + .getMagnitude(); const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat(); const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat(); const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat(); @@ -2387,7 +2390,11 @@ namespace MWMechanics { if (cls.getCreatureStats(mPtr).isDead() || (!godmode - && cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0)) + && cls.getCreatureStats(mPtr) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Paralyze) + .getModifier() + > 0)) { moved.z() = 1.0; } @@ -2644,7 +2651,7 @@ namespace MWMechanics || mPtr.getClass() .getCreatureStats(mPtr) .getMagicEffects() - .get(MWMechanics::EffectKey(effectId)) + .getOrDefault(MWMechanics::EffectKey(effectId)) .getMagnitude() <= 0) mAnimation->removeEffect(effectId); @@ -2656,16 +2663,22 @@ namespace MWMechanics if (!mPtr.getClass().isActor()) return; - float light - = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude(); + float light = mPtr.getClass() + .getCreatureStats(mPtr) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Light) + .getMagnitude(); mAnimation->setLightEffect(light); // If you're dead you don't care about whether you've started/stopped being a vampire or not if (mPtr.getClass().getCreatureStats(mPtr).isDead()) return; - bool vampire - = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() + bool vampire = mPtr.getClass() + .getCreatureStats(mPtr) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Vampirism) + .getMagnitude() > 0.0f; mAnimation->setVampire(vampire); } @@ -2679,7 +2692,7 @@ namespace MWMechanics if (mPtr.getClass() .getCreatureStats(mPtr) .getMagicEffects() - .get(ESM::MagicEffect::Invisibility) + .getOrDefault(ESM::MagicEffect::Invisibility) .getModifier()) // Ignore base magnitude (see bug #3555). { if (mPtr == getPlayer()) @@ -2690,7 +2703,7 @@ namespace MWMechanics float chameleon = mPtr.getClass() .getCreatureStats(mPtr) .getMagicEffects() - .get(ESM::MagicEffect::Chameleon) + .getOrDefault(ESM::MagicEffect::Chameleon) .getMagnitude(); if (chameleon) { diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index f835652561..917d06bea6 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -185,8 +185,8 @@ namespace MWMechanics return; const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects(); - const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f; - const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f; + const float resistance = effects.getOrDefault(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f; + const float weakness = effects.getOrDefault(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f; damage *= 1.f - std::min(1.f, resistance - weakness); @@ -313,15 +313,17 @@ namespace MWMechanics } static const float fCombatInvisoMult = gmst.find("fCombatInvisoMult")->mValue.getFloat(); defenseTerm += std::min(100.f, - fCombatInvisoMult * victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude()); + fCombatInvisoMult + * victimStats.getMagicEffects().getOrDefault(ESM::MagicEffect::Chameleon).getMagnitude()); defenseTerm += std::min(100.f, - fCombatInvisoMult * victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude()); + fCombatInvisoMult + * victimStats.getMagicEffects().getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude()); } float attackTerm = skillValue + (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); attackTerm *= stats.getFatigueTerm(); - attackTerm += mageffects.get(ESM::MagicEffect::FortifyAttack).getMagnitude() - - mageffects.get(ESM::MagicEffect::Blind).getMagnitude(); + attackTerm += mageffects.getOrDefault(ESM::MagicEffect::FortifyAttack).getMagnitude() + - mageffects.getOrDefault(ESM::MagicEffect::Blind).getMagnitude(); return round(attackTerm - defenseTerm); } @@ -338,7 +340,7 @@ namespace MWMechanics float magnitude = victim.getClass() .getCreatureStats(victim) .getMagicEffects() - .get(ESM::MagicEffect::FireShield + i) + .getOrDefault(ESM::MagicEffect::FireShield + i) .getMagnitude(); if (!magnitude) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 0ef77f9f5c..44e1f4d2e1 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -225,8 +225,8 @@ namespace MWMechanics void CreatureStats::modifyMagicEffects(const MagicEffects& effects) { - bool recalc = effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() - != mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier(); + bool recalc = effects.getOrDefault(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() + != mMagicEffects.getOrDefault(ESM::MagicEffect::FortifyMaximumMagicka).getModifier(); mMagicEffects.setModifiers(effects); if (recalc) recalculateMagicka(); @@ -246,7 +246,7 @@ namespace MWMechanics bool CreatureStats::isParalyzed() const { - return mMagicEffects.get(ESM::MagicEffect::Paralyze).getMagnitude() > 0; + return mMagicEffects.getOrDefault(ESM::MagicEffect::Paralyze).getMagnitude() > 0; } bool CreatureStats::isDead() const @@ -359,7 +359,7 @@ namespace MWMechanics float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); evasion *= getFatigueTerm(); - evasion += std::min(100.f, mMagicEffects.get(ESM::MagicEffect::Sanctuary).getMagnitude()); + evasion += std::min(100.f, mMagicEffects.getOrDefault(ESM::MagicEffect::Sanctuary).getMagnitude()); return evasion; } @@ -436,8 +436,8 @@ namespace MWMechanics else base = world->getStore().get().find("fNPCbaseMagickaMult")->mValue.getFloat(); - double magickaFactor - = base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; + double magickaFactor = base + + mMagicEffects.getOrDefault(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; DynamicStat magicka = getMagicka(); float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0; diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index f4d2cc9067..c793d5d540 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -46,18 +46,18 @@ namespace MWMechanics if (Spells::hasCorprusEffect(spell)) resist = 1.f - 0.01f - * (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); + * (actorEffects.getOrDefault(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() + - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); else if (spell->mData.mType == ESM::Spell::ST_Disease) resist = 1.f - 0.01f - * (actorEffects.get(ESM::MagicEffect::ResistCommonDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude()); + * (actorEffects.getOrDefault(ESM::MagicEffect::ResistCommonDisease).getMagnitude() + - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude()); else if (spell->mData.mType == ESM::Spell::ST_Blight) resist = 1.f - 0.01f - * (actorEffects.get(ESM::MagicEffect::ResistBlightDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude()); + * (actorEffects.getOrDefault(ESM::MagicEffect::ResistBlightDisease).getMagnitude() + - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude()); else continue; diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index d291d9798d..293d61c082 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -147,7 +147,7 @@ namespace MWMechanics { for (Collection::iterator it = mCollection.begin(); it != mCollection.end(); ++it) { - it->second.setModifier(effects.get(it->first).getModifier()); + it->second.setModifier(effects.getOrDefault(it->first).getModifier()); } for (Collection::const_iterator it = effects.begin(); it != effects.end(); ++it) @@ -156,14 +156,14 @@ namespace MWMechanics } } - EffectParam MagicEffects::get(const EffectKey& key) const + EffectParam MagicEffects::getOrDefault(const EffectKey& key) const { - EffectParam param = EffectParam(); + std::optional param; get(key, param); - return param; + return param.value_or(EffectParam()); } - bool MagicEffects::get(const EffectKey& key, EffectParam& param) const + bool MagicEffects::get(const EffectKey& key, std::optional& param) const { Collection::const_iterator iter = mCollection.find(key); @@ -268,7 +268,7 @@ namespace MWMechanics if (spellLine.empty()) { - auto& effectIDStr = ESM::MagicEffect::effectIdToGmstString(effect.mIndex); + auto& effectIDStr = ESM::MagicEffect::indexToGmstString(effect.mIndex); spellLine = windowManager->getGameSettingString(effectIDStr, {}); } diff --git a/apps/openmw/mwmechanics/magiceffects.hpp b/apps/openmw/mwmechanics/magiceffects.hpp index 4f3f3a1d48..b55bf54ff1 100644 --- a/apps/openmw/mwmechanics/magiceffects.hpp +++ b/apps/openmw/mwmechanics/magiceffects.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace ESM { @@ -104,8 +105,8 @@ namespace MWMechanics /// Copy Modifier values from \a effects, but keep original mBase values. void setModifiers(const MagicEffects& effects); - EffectParam get(const EffectKey& key) const; - bool get(const EffectKey& key, EffectParam& param) const; + EffectParam getOrDefault(const EffectKey& key) const; + bool get(const EffectKey& key, std::optional& param) const; ///< This function can safely be used for keys that are not present. static MagicEffects diff(const MagicEffects& prev, const MagicEffects& now); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index c8cc7ba32a..3268c01ecc 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -577,7 +577,11 @@ namespace MWMechanics if (playerStats.getDrawState() == MWMechanics::DrawState::Weapon) x += fDispWeaponDrawn; - x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude(); + x += ptr.getClass() + .getCreatureStats(ptr) + .getMagicEffects() + .getOrDefault(ESM::MagicEffect::Charm) + .getMagnitude(); if (clamp) return std::clamp(x, 0, 100); //, normally clamped to [0..100] when used @@ -1558,8 +1562,8 @@ namespace MWMechanics osg::Vec3f pos2(observer.getRefData().getPosition().asVec3()); float distTerm = fSneakDistBase + fSneakDistMult * (pos1 - pos2).length(); - float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); - float invisibility = stats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude(); + float chameleon = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Chameleon).getMagnitude(); + float invisibility = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude(); float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon; if (invisibility > 0.f) x += 100.f; @@ -1567,7 +1571,7 @@ namespace MWMechanics CreatureStats& observerStats = observer.getClass().getCreatureStats(observer); float obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified(); float obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified(); - float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude(); + float obsBlind = observerStats.getMagicEffects().getOrDefault(ESM::MagicEffect::Blind).getMagnitude(); float obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak); float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind; @@ -1755,14 +1759,14 @@ namespace MWMechanics && ptr.getClass() .getCreatureStats(ptr) .getMagicEffects() - .get(ESM::MagicEffect::CalmHumanoid) + .getOrDefault(ESM::MagicEffect::CalmHumanoid) .getMagnitude() > 0) || (!ptr.getClass().isNpc() && ptr.getClass() .getCreatureStats(ptr) .getMagicEffects() - .get(ESM::MagicEffect::CalmCreature) + .getOrDefault(ESM::MagicEffect::CalmCreature) .getMagnitude() > 0)) return false; diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index 1ccb8f3396..3afe220a24 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -319,9 +319,9 @@ namespace { bool canReflect = !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable) && !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Reflect) - && magnitudes.get(ESM::MagicEffect::Reflect).getMagnitude() > 0.f && !caster.isEmpty(); + && magnitudes.getOrDefault(ESM::MagicEffect::Reflect).getMagnitude() > 0.f && !caster.isEmpty(); bool canAbsorb = !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_SpellAbsorption) - && magnitudes.get(ESM::MagicEffect::SpellAbsorption).getMagnitude() > 0.f; + && magnitudes.getOrDefault(ESM::MagicEffect::SpellAbsorption).getMagnitude() > 0.f; if (canReflect || canAbsorb) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); @@ -561,7 +561,8 @@ namespace MWMechanics { const auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); float volume = std::clamp( - (magnitudes.get(effect.mEffectId).getModifier() + effect.mMagnitude) / 100.f, 0.f, 1.f); + (magnitudes.getOrDefault(effect.mEffectId).getModifier() + effect.mMagnitude) / 100.f, 0.f, + 1.f); MWBase::Environment::get().getSoundManager()->playSound3D(target, ESM::RefId::stringRefId("magic sound"), volume, 1.f, MWSound::Type::Sfx, MWSound::PlayMode::LoopNoEnv); @@ -1058,7 +1059,7 @@ namespace MWMechanics { case ESM::MagicEffect::CommandCreature: case ESM::MagicEffect::CommandHumanoid: - if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + if (magnitudes.getOrDefault(effect.mEffectId).getMagnitude() <= 0.f) { auto& seq = target.getClass().getCreatureStats(target).getAiSequence(); seq.erasePackageIf([&](const auto& package) { @@ -1068,7 +1069,7 @@ namespace MWMechanics } break; case ESM::MagicEffect::ExtraSpell: - if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + if (magnitudes.getOrDefault(effect.mEffectId).getMagnitude() <= 0.f) target.getClass().getInventoryStore(target).autoEquip(); break; case ESM::MagicEffect::TurnUndead: @@ -1096,7 +1097,7 @@ namespace MWMechanics break; case ESM::MagicEffect::NightEye: { - const MWMechanics::EffectParam nightEye = magnitudes.get(effect.mEffectId); + const MWMechanics::EffectParam nightEye = magnitudes.getOrDefault(effect.mEffectId); if (nightEye.getMagnitude() < 0.f && nightEye.getBase() < 0) { // The PCVisionBonus functions are different from every other magic effect function in that they @@ -1115,7 +1116,7 @@ namespace MWMechanics target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, effect.mMagnitude, invalid); break; case ESM::MagicEffect::Sound: - if (magnitudes.get(effect.mEffectId).getModifier() <= 0.f && target == getPlayer()) + if (magnitudes.getOrDefault(effect.mEffectId).getModifier() <= 0.f && target == getPlayer()) MWBase::Environment::get().getSoundManager()->stopSound3D( target, ESM::RefId::stringRefId("magic sound")); break; @@ -1275,7 +1276,7 @@ namespace MWMechanics auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(-effect.mMagnitude)); removeMagicEffect(target, spellParams, effect); - if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + if (magnitudes.getOrDefault(effect.mEffectId).getMagnitude() <= 0.f) { auto anim = MWBase::Environment::get().getWorld()->getAnimation(target); if (anim) diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index e491332bfd..4e813ec37c 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -265,7 +265,7 @@ namespace MWMechanics const CreatureStats& stats = enemy.getClass().getCreatureStats(enemy); // Enemy can't cast spells - if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).getMagnitude() > 0) + if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Silence).getMagnitude() > 0) return 0.f; if (stats.isParalyzed() || stats.getKnockedDown()) @@ -596,7 +596,7 @@ namespace MWMechanics if (effect.mEffectID <= ESM::MagicEffect::BoundLongbow) { for (int e = ESM::MagicEffect::BoundDagger; e <= ESM::MagicEffect::BoundLongbow; ++e) - if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(e).getMagnitude() > 0.f + if (actor.getClass().getCreatureStats(actor).getMagicEffects().getOrDefault(e).getMagnitude() > 0.f && (e != ESM::MagicEffect::BoundLongbow || effect.mEffectID == e || rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f)) return 0.f; @@ -619,7 +619,11 @@ namespace MWMechanics // Prefer summoning items we know how to use rating *= (50.f + actor.getClass().getSkill(actor, skill)) / 100.f; } - else if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(effect.mEffectID).getMagnitude() + else if (actor.getClass() + .getCreatureStats(actor) + .getMagicEffects() + .getOrDefault(effect.mEffectID) + .getMagnitude() > 0.f) return 0.f; } @@ -662,14 +666,14 @@ namespace MWMechanics { CreatureStats& stats = enemy.getClass().getCreatureStats(enemy); - if (stats.getMagicEffects().get(effect.mEffectID).getMagnitude() > 0) + if (stats.getMagicEffects().getOrDefault(effect.mEffectID).getMagnitude() > 0) return 0.f; } else { CreatureStats& stats = actor.getClass().getCreatureStats(actor); - if (stats.getMagicEffects().get(effect.mEffectID).getMagnitude() > 0) + if (stats.getMagicEffects().getOrDefault(effect.mEffectID).getMagnitude() > 0) return 0.f; } } diff --git a/apps/openmw/mwmechanics/spellresistance.cpp b/apps/openmw/mwmechanics/spellresistance.cpp index 0fb864aa8a..e55d851ec6 100644 --- a/apps/openmw/mwmechanics/spellresistance.cpp +++ b/apps/openmw/mwmechanics/spellresistance.cpp @@ -79,16 +79,16 @@ namespace MWMechanics float resistance = 0; if (resistanceEffect != -1) - resistance += actorEffects->get(resistanceEffect).getMagnitude(); + resistance += actorEffects->getOrDefault(resistanceEffect).getMagnitude(); if (weaknessEffect != -1) - resistance -= actorEffects->get(weaknessEffect).getMagnitude(); + resistance -= actorEffects->getOrDefault(weaknessEffect).getMagnitude(); if (effectId == ESM::MagicEffect::FireDamage) - resistance += actorEffects->get(ESM::MagicEffect::FireShield).getMagnitude(); + resistance += actorEffects->getOrDefault(ESM::MagicEffect::FireShield).getMagnitude(); if (effectId == ESM::MagicEffect::ShockDamage) - resistance += actorEffects->get(ESM::MagicEffect::LightningShield).getMagnitude(); + resistance += actorEffects->getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude(); if (effectId == ESM::MagicEffect::FrostDamage) - resistance += actorEffects->get(ESM::MagicEffect::FrostShield).getMagnitude(); + resistance += actorEffects->getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude(); return resistance; } diff --git a/apps/openmw/mwmechanics/spellutil.cpp b/apps/openmw/mwmechanics/spellutil.cpp index 344597bca0..60574880a1 100644 --- a/apps/openmw/mwmechanics/spellutil.cpp +++ b/apps/openmw/mwmechanics/spellutil.cpp @@ -151,7 +151,7 @@ namespace MWMechanics CreatureStats& stats = actor.getClass().getCreatureStats(actor); - if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).getMagnitude() && !godmode) + if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Silence).getMagnitude() && !godmode) return 0; if (spell->mData.mType == ESM::Spell::ST_Power) @@ -169,7 +169,7 @@ namespace MWMechanics if (spell->mData.mFlags & ESM::Spell::F_Always) return 100; - float castBonus = -stats.getMagicEffects().get(ESM::MagicEffect::Sound).getMagnitude(); + float castBonus = -stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Sound).getMagnitude(); float castChance = baseChance + castBonus; castChance *= stats.getFatigueTerm(); diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 1c37ac029e..d1f13326cb 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -666,7 +666,7 @@ namespace MWPhysics // check if Actor should spawn above water const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); - const bool canWaterWalk = effects.get(ESM::MagicEffect::WaterWalking).getMagnitude() > 0; + const bool canWaterWalk = effects.getOrDefault(ESM::MagicEffect::WaterWalking).getMagnitude() > 0; auto actor = std::make_shared(ptr, shape, mTaskScheduler.get(), canWaterWalk, mActorCollisionShapeType); @@ -750,7 +750,7 @@ namespace MWPhysics const MWMechanics::MagicEffects& effects = stats.getMagicEffects(); bool waterCollision = false; - if (cell->getCell()->hasWater() && effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()) + if (cell->getCell()->hasWater() && effects.getOrDefault(ESM::MagicEffect::WaterWalking).getMagnitude()) { if (physicActor->getCollisionMode() || !world->isUnderwater(ptr.getCell(), ptr.getRefData().getPosition().asVec3())) @@ -761,10 +761,10 @@ namespace MWPhysics // Slow fall reduces fall speed by a factor of (effect magnitude / 200) const float slowFall - = 1.f - std::clamp(effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f, 0.f, 1.f); + = 1.f - std::clamp(effects.getOrDefault(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f, 0.f, 1.f); const bool godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState(); const bool inert = stats.isDead() - || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0); + || (!godmode && stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Paralyze).getModifier() > 0); simulations.emplace_back(ActorSimulation{ physicActor, ActorFrameData{ *physicActor, inert, waterCollision, slowFall, waterlevel } }); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 14558e8047..43769c7ef1 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -222,7 +222,7 @@ namespace MWRender { const MWWorld::Class& cls = ptr.getClass(); NpcAnimation::NpcType curType = Type_Normal; - if (cls.getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() > 0) + if (cls.getCreatureStats(ptr).getMagicEffects().getOrDefault(ESM::MagicEffect::Vampirism).getMagnitude() > 0) curType = Type_Vampire; if (cls.getNpcStats(ptr).isWerewolf()) curType = Type_Werewolf; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 2d4d5d045a..7787c15ad3 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -582,7 +582,7 @@ namespace MWScript k.has_value() && *k >= 0 && *k <= 32767) key = *k; else - key = ESM::MagicEffect::effectGmstIdToId(effect); + key = ESM::MagicEffect::effectGmstIdToIndex(effect); const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 1b2fe0275f..877fa79099 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1193,17 +1193,17 @@ namespace MWScript MWWorld::Ptr ptr = R()(runtime); const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); - float currentValue = effects.get(mPositiveEffect).getMagnitude(); + float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude(); if (mNegativeEffect != -1) - currentValue -= effects.get(mNegativeEffect).getMagnitude(); + currentValue -= effects.getOrDefault(mNegativeEffect).getMagnitude(); // GetResist* should take in account elemental shields if (mPositiveEffect == ESM::MagicEffect::ResistFire) - currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::FireShield).getMagnitude(); if (mPositiveEffect == ESM::MagicEffect::ResistShock) - currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude(); if (mPositiveEffect == ESM::MagicEffect::ResistFrost) - currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude(); int ret = static_cast(currentValue); runtime.push(ret); @@ -1227,17 +1227,17 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); - float currentValue = effects.get(mPositiveEffect).getMagnitude(); + float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude(); if (mNegativeEffect != -1) - currentValue -= effects.get(mNegativeEffect).getMagnitude(); + currentValue -= effects.getOrDefault(mNegativeEffect).getMagnitude(); // SetResist* should take in account elemental shields if (mPositiveEffect == ESM::MagicEffect::ResistFire) - currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::FireShield).getMagnitude(); if (mPositiveEffect == ESM::MagicEffect::ResistShock) - currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude(); if (mPositiveEffect == ESM::MagicEffect::ResistFrost) - currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude(); + currentValue += effects.getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude(); int arg = runtime[0].mInteger; runtime.pop(); @@ -1276,7 +1276,8 @@ namespace MWScript { MWWorld::Ptr player = MWMechanics::getPlayer(); MWMechanics::EffectParam nightEye - = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye); + = player.getClass().getCreatureStats(player).getMagicEffects().getOrDefault( + ESM::MagicEffect::NightEye); runtime.push(std::clamp(nightEye.getMagnitude() / 100.f, 0.f, 1.f)); } }; @@ -1290,8 +1291,8 @@ namespace MWScript runtime.pop(); MWWorld::Ptr player = MWMechanics::getPlayer(); auto& effects = player.getClass().getCreatureStats(player).getMagicEffects(); - float delta - = std::clamp(arg * 100.f, 0.f, 100.f) - effects.get(ESM::MagicEffect::NightEye).getMagnitude(); + float delta = std::clamp(arg * 100.f, 0.f, 100.f) + - effects.getOrDefault(ESM::MagicEffect::NightEye).getMagnitude(); effects.modifyBase(ESM::MagicEffect::NightEye, static_cast(delta)); } }; @@ -1305,7 +1306,7 @@ namespace MWScript runtime.pop(); MWWorld::Ptr player = MWMechanics::getPlayer(); auto& effects = player.getClass().getCreatureStats(player).getMagicEffects(); - const MWMechanics::EffectParam nightEye = effects.get(ESM::MagicEffect::NightEye); + const MWMechanics::EffectParam nightEye = effects.getOrDefault(ESM::MagicEffect::NightEye); float newBase = std::clamp(nightEye.getMagnitude() + arg * 100.f, 0.f, 100.f); newBase -= nightEye.getModifier(); float delta = std::clamp(newBase, 0.f, 100.f) - nightEye.getMagnitude(); diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 915a6b5a4b..3041c7cb5a 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -538,8 +538,8 @@ namespace MWWorld { iter->mAttribute = -1; Log(Debug::Verbose) - << ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) << " effect of spell '" - << spell.mId << "' has an attribute argument present. Dropping the argument."; + << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '" << spell.mId + << "' has an attribute argument present. Dropping the argument."; changed = true; } } @@ -549,8 +549,8 @@ namespace MWWorld { iter->mSkill = -1; Log(Debug::Verbose) - << ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) << " effect of spell '" - << spell.mId << "' has a skill argument present. Dropping the argument."; + << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '" << spell.mId + << "' has a skill argument present. Dropping the argument."; changed = true; } } @@ -558,9 +558,8 @@ namespace MWWorld { iter->mSkill = -1; iter->mAttribute = -1; - Log(Debug::Verbose) << ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) - << " effect of spell '" << spell.mId - << "' has argument(s) present. Dropping the argument(s)."; + Log(Debug::Verbose) << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '" + << spell.mId << "' has argument(s) present. Dropping the argument(s)."; changed = true; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 00a0ee7aa6..38eb728268 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -503,10 +503,10 @@ namespace MWWorld int blind = 0; const auto& magicEffects = playerClass.getCreatureStats(player).getMagicEffects(); if (!world->getGodModeState()) - blind = static_cast(magicEffects.get(ESM::MagicEffect::Blind).getModifier()); + blind = static_cast(magicEffects.getOrDefault(ESM::MagicEffect::Blind).getModifier()); windowMgr->setBlindness(std::clamp(blind, 0, 100)); - int nightEye = static_cast(magicEffects.get(ESM::MagicEffect::NightEye).getMagnitude()); + int nightEye = static_cast(magicEffects.getOrDefault(ESM::MagicEffect::NightEye).getMagnitude()); rendering->setNightEyeFactor(std::min(1.f, (nightEye / 100.f))); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 1f130a6b45..8d8eccf17b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2137,13 +2137,15 @@ namespace MWWorld return false; const bool isPlayer = ptr == getPlayerConstPtr(); - if (!(isPlayer && mGodMode) && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0) + if (!(isPlayer && mGodMode) + && stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Paralyze).getModifier() > 0) return false; if (ptr.getClass().canFly(ptr)) return true; - if (stats.getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && isLevitationEnabled()) + if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Levitate).getMagnitude() > 0 + && isLevitationEnabled()) return true; const MWPhysics::Actor* actor = mPhysics->getActor(ptr); @@ -2159,7 +2161,7 @@ namespace MWWorld return false; const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - if (stats.getMagicEffects().get(ESM::MagicEffect::SlowFall).getMagnitude() > 0) + if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::SlowFall).getMagnitude() > 0) return true; return false; @@ -3446,11 +3448,11 @@ namespace MWWorld const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); float dist = 0; if (type == World::Detect_Creature) - dist = effects.get(ESM::MagicEffect::DetectAnimal).getMagnitude(); + dist = effects.getOrDefault(ESM::MagicEffect::DetectAnimal).getMagnitude(); else if (type == World::Detect_Key) - dist = effects.get(ESM::MagicEffect::DetectKey).getMagnitude(); + dist = effects.getOrDefault(ESM::MagicEffect::DetectKey).getMagnitude(); else if (type == World::Detect_Enchantment) - dist = effects.get(ESM::MagicEffect::DetectEnchantment).getMagnitude(); + dist = effects.getOrDefault(ESM::MagicEffect::DetectEnchantment).getMagnitude(); if (!dist) return; @@ -3478,7 +3480,7 @@ namespace MWWorld .getClass() .getCreatureStats(mPlayer->getPlayer()) .getMagicEffects() - .get(ESM::MagicEffect::Telekinesis) + .getOrDefault(ESM::MagicEffect::Telekinesis) .getMagnitude(); telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); diff --git a/components/esm3/loadmgef.cpp b/components/esm3/loadmgef.cpp index 3a12c69ea1..ee5b48038f 100644 --- a/components/esm3/loadmgef.cpp +++ b/components/esm3/loadmgef.cpp @@ -24,156 +24,6 @@ namespace ESM 0x1048, 0x1048, 0x1048, 0x1048 }; } - const std::string_view MagicEffect::sIndexNames[MagicEffect::Length] = { - "WaterBreathing", - "SwiftSwim", - "WaterWalking", - "Shield", - "FireShield", - "LightningShield", - "FrostShield", - "Burden", - "Feather", - "Jump", - "Levitate", - "SlowFall", - "Lock", - "Open", - "FireDamage", - "ShockDamage", - "FrostDamage", - "DrainAttribute", - "DrainHealth", - "DrainMagicka", - "DrainFatigue", - "DrainSkill", - "DamageAttribute", - "DamageHealth", - "DamageMagicka", - "DamageFatigue", - "DamageSkill", - "Poison", - "WeaknessToFire", - "WeaknessToFrost", - "WeaknessToShock", - "WeaknessToMagicka", - "WeaknessToCommonDisease", - "WeaknessToBlightDisease", - "WeaknessToCorprusDisease", - "WeaknessToPoison", - "WeaknessToNormalWeapons", - "DisintegrateWeapon", - "DisintegrateArmor", - "Invisibility", - "Chameleon", - "Light", - "Sanctuary", - "NightEye", - "Charm", - "Paralyze", - "Silence", - "Blind", - "Sound", - "CalmHumanoid", - "CalmCreature", - "FrenzyHumanoid", - "FrenzyCreature", - "DemoralizeHumanoid", - "DemoralizeCreature", - "RallyHumanoid", - "RallyCreature", - "Dispel", - "Soultrap", - "Telekinesis", - "Mark", - "Recall", - "DivineIntervention", - "AlmsiviIntervention", - "DetectAnimal", - "DetectEnchantment", - "DetectKey", - "SpellAbsorption", - "Reflect", - "CureCommonDisease", - "CureBlightDisease", - "CureCorprusDisease", - "CurePoison", - "CureParalyzation", - "RestoreAttribute", - "RestoreHealth", - "RestoreMagicka", - "RestoreFatigue", - "RestoreSkill", - "FortifyAttribute", - "FortifyHealth", - "FortifyMagicka", - "FortifyFatigue", - "FortifySkill", - "FortifyMaximumMagicka", - "AbsorbAttribute", - "AbsorbHealth", - "AbsorbMagicka", - "AbsorbFatigue", - "AbsorbSkill", - "ResistFire", - "ResistFrost", - "ResistShock", - "ResistMagicka", - "ResistCommonDisease", - "ResistBlightDisease", - "ResistCorprusDisease", - "ResistPoison", - "ResistNormalWeapons", - "ResistParalysis", - "RemoveCurse", - "TurnUndead", - "SummonScamp", - "SummonClannfear", - "SummonDaedroth", - "SummonDremora", - "SummonAncestralGhost", - "SummonSkeletalMinion", - "SummonBonewalker", - "SummonGreaterBonewalker", - "SummonBonelord", - "SummonWingedTwilight", - "SummonHunger", - "SummonGoldenSaint", - "SummonFlameAtronach", - "SummonFrostAtronach", - "SummonStormAtronach", - "FortifyAttack", - "CommandCreature", - "CommandHumanoid", - "BoundDagger", - "BoundLongsword", - "BoundMace", - "BoundBattleAxe", - "BoundSpear", - "BoundLongbow", - "ExtraSpell", - "BoundCuirass", - "BoundHelm", - "BoundBoots", - "BoundShield", - "BoundGloves", - "Corprus", - "Vampirism", - "SummonCenturionSphere", - "SunDamage", - "StuntedMagicka", - - // Tribunal only - "SummonFabricant", - - // Bloodmoon only - "SummonWolf", - "SummonBear", - "SummonBonewolf", - "SummonCreature04", - "SummonCreature05", - }; - void MagicEffect::load(ESMReader& esm, bool& isDeleted) { isDeleted = false; // MagicEffect record can't be deleted now (may be changed in the future) @@ -504,7 +354,7 @@ namespace ESM }; // Map effect ID to identifying name - const std::array MagicEffect::sEffectNames = { + const std::array MagicEffect::sIndexNames = { "WaterBreathing", "SwiftSwim", "WaterWalking", @@ -654,21 +504,21 @@ namespace ESM "SummonCreature05", }; - static std::map initStringToIntMap( - const std::array& strings) + template + static std::map initStringToIntMap(const Collection& strings) { std::map map; - for (int i = 0; i < (int)strings.size(); i++) + for (size_t i = 0; i < strings.size(); i++) map[strings[i]] = i; return map; } - const std::map MagicEffect::sGmstEffectIdToEffectIdMap + const std::map MagicEffect::sGmstEffectIdToIndexMap = initStringToIntMap(MagicEffect::sGmstEffectIds); - const std::map MagicEffect::sEffectNameToEffectIdMap - = initStringToIntMap(MagicEffect::sEffectNames); + const std::map MagicEffect::sIndexNameToIndexMap + = initStringToIntMap(MagicEffect::sIndexNames); class FindSecond { @@ -729,35 +579,35 @@ namespace ESM mDescription.clear(); } - const std::string& MagicEffect::effectIdToGmstString(int effectID) + const std::string& MagicEffect::indexToGmstString(int effectID) { - if (effectID >= (int)sGmstEffectIds.size() || effectID < 0) + if (effectID < 0 || static_cast(effectID) >= sGmstEffectIds.size()) throw std::runtime_error(std::string("Unimplemented effect ID ") + std::to_string(effectID)); return sGmstEffectIds[effectID]; } - const std::string& MagicEffect::effectIdToName(int effectID) + std::string_view MagicEffect::indexToName(int effectID) { - if (effectID >= (int)sEffectNames.size() || effectID < 0) + if (effectID < 0 || static_cast(effectID) >= sIndexNames.size()) throw std::runtime_error(std::string("Unimplemented effect ID ") + std::to_string(effectID)); - return sEffectNames[effectID]; + return sIndexNames[effectID]; } - int MagicEffect::effectNameToId(std::string_view effect) + int MagicEffect::indexNameToIndex(std::string_view effect) { - auto name = sEffectNameToEffectIdMap.find(effect); - if (name == sEffectNameToEffectIdMap.end()) + auto name = sIndexNameToIndexMap.find(effect); + if (name == sIndexNameToIndexMap.end()) throw std::runtime_error("Unimplemented effect " + std::string(effect)); return name->second; } - int MagicEffect::effectGmstIdToId(std::string_view gmstId) + int MagicEffect::effectGmstIdToIndex(std::string_view gmstId) { - auto name = sGmstEffectIdToEffectIdMap.find(gmstId); - if (name == sGmstEffectIdToEffectIdMap.end()) + auto name = sGmstEffectIdToIndexMap.find(gmstId); + if (name == sGmstEffectIdToIndexMap.end()) throw std::runtime_error("Unimplemented effect " + std::string(gmstId)); return name->second; diff --git a/components/esm3/loadmgef.hpp b/components/esm3/loadmgef.hpp index eead3a7015..1de3fb8a0a 100644 --- a/components/esm3/loadmgef.hpp +++ b/components/esm3/loadmgef.hpp @@ -267,16 +267,14 @@ namespace ESM }; static const std::array sGmstEffectIds; - static const std::array sEffectNames; - static const std::map sGmstEffectIdToEffectIdMap; - static const std::map sEffectNameToEffectIdMap; + static const std::array sIndexNames; + static const std::map sGmstEffectIdToIndexMap; + static const std::map sIndexNameToIndexMap; - static const std::string& effectIdToGmstString(int effectID); - static const std::string& effectIdToName(int effectID); - static int effectNameToId(std::string_view effect); - static int effectGmstIdToId(std::string_view gmstId); - - static const std::string_view sIndexNames[MagicEffect::Length]; + static const std::string& indexToGmstString(int effectID); + static std::string_view indexToName(int effectID); + static int indexNameToIndex(std::string_view effect); + static int effectGmstIdToIndex(std::string_view gmstId); static RefId indexToRefId(int index); };