1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-02 06:06:41 +00:00

Elsid comments

This commit is contained in:
Mads Buvik Sandvei 2023-05-23 19:06:08 +02:00
parent b5aefc872b
commit 410e8b100a
33 changed files with 199 additions and 318 deletions

View file

@ -73,9 +73,9 @@ namespace MWClass
{ {
float weight = getContainerStore(ptr).getWeight(); float weight = getContainerStore(ptr).getWeight();
const MWMechanics::MagicEffects& effects = getCreatureStats(ptr).getMagicEffects(); 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()) 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; return (weight < 0) ? 0.0f : weight;
} }

View file

@ -28,7 +28,7 @@ namespace MWClass
float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects, float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects,
float baseSpeed) const 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() * (gmst.fSwimRunBase->mValue.getFloat()
+ 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat()); + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat());
} }

View file

@ -555,11 +555,11 @@ namespace MWClass
if (getEncumbrance(ptr) > getCapacity(ptr)) if (getEncumbrance(ptr) > getCapacity(ptr))
moveSpeed = 0.0f; moveSpeed = 0.0f;
else if (canFly(ptr) 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 float flySpeed = 0.01f
* (stats.getAttribute(ESM::Attribute::Speed).getModified() * (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.fMinFlySpeed->mValue.getFloat()
+ flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat());
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
@ -614,7 +614,7 @@ namespace MWClass
float Creature::getArmorRating(const MWWorld::Ptr& ptr) const float Creature::getArmorRating(const MWWorld::Ptr& ptr) const
{ {
// Equipment armor rating is deliberately ignored. // 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 float Creature::getCapacity(const MWWorld::Ptr& ptr) const

View file

@ -1021,11 +1021,11 @@ namespace MWClass
float moveSpeed; float moveSpeed;
if (getEncumbrance(ptr) > getCapacity(ptr)) if (getEncumbrance(ptr) > getCapacity(ptr))
moveSpeed = 0.0f; 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 float flySpeed = 0.01f
* (stats.getAttribute(ESM::Attribute::Speed).getModified() * (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.fMinFlySpeed->mValue.getFloat()
+ flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat());
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance;
@ -1071,7 +1071,7 @@ namespace MWClass
float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() float x = gmst.fJumpAcrobaticsBase->mValue.getFloat()
+ std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat()); + std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat());
x += 3.0f * b * 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; x *= encumbranceTerm;
if (stats.getStance(MWMechanics::CreatureStats::Stance_Run)) 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 return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3f
+ (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet]

View file

@ -582,7 +582,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con
return player.getClass() return player.getClass()
.getCreatureStats(player) .getCreatureStats(player)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Corprus) .getOrDefault(ESM::MagicEffect::Corprus)
.getMagnitude() .getMagnitude()
!= 0; != 0;
@ -601,7 +601,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con
return player.getClass() return player.getClass()
.getCreatureStats(player) .getCreatureStats(player)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Vampirism) .getOrDefault(ESM::MagicEffect::Vampirism)
.getMagnitude() .getMagnitude()
> 0; > 0;

View file

@ -37,8 +37,8 @@ namespace
const MWWorld::Store<ESM::GameSetting>& gmst const MWWorld::Store<ESM::GameSetting>& gmst
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>(); = MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
return gmst.find(ESM::MagicEffect::effectIdToGmstString(id1))->mValue.getString() return gmst.find(ESM::MagicEffect::indexToGmstString(id1))->mValue.getString()
< gmst.find(ESM::MagicEffect::effectIdToGmstString(id2))->mValue.getString(); < gmst.find(ESM::MagicEffect::indexToGmstString(id2))->mValue.getString();
} }
void init(ESM::ENAMstruct& effect) void init(ESM::ENAMstruct& effect)
@ -196,7 +196,7 @@ namespace MWGui
mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath( mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath(
effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); 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; mEffect.mEffectID = effect->mIndex;
@ -552,7 +552,7 @@ namespace MWGui
mAvailableEffectsList->addItem(MWBase::Environment::get() mAvailableEffectsList->addItem(MWBase::Environment::get()
.getESMStore() .getESMStore()
->get<ESM::GameSetting>() ->get<ESM::GameSetting>()
.find(ESM::MagicEffect::effectIdToGmstString(effectId)) .find(ESM::MagicEffect::indexToGmstString(effectId))
->mValue.getString()); ->mValue.getString());
mButtonMapping[i] = effectId; mButtonMapping[i] = effectId;
++i; ++i;
@ -565,7 +565,7 @@ namespace MWGui
const std::string& name = MWBase::Environment::get() const std::string& name = MWBase::Environment::get()
.getESMStore() .getESMStore()
->get<ESM::GameSetting>() ->get<ESM::GameSetting>()
.find(ESM::MagicEffect::effectIdToGmstString(effectId)) .find(ESM::MagicEffect::indexToGmstString(effectId))
->mValue.getString(); ->mValue.getString();
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);

View file

@ -162,7 +162,7 @@ namespace MWGui
image->setImageTexture(Misc::ResourceHelpers::correctIconPath( image->setImageTexture(Misc::ResourceHelpers::correctIconPath(
effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); 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 tooltipInfo;
tooltipInfo.caption = "#{" + name + "}"; tooltipInfo.caption = "#{" + name + "}";

View file

@ -954,7 +954,7 @@ namespace MWGui
void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id) void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id)
{ {
const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(id); const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(id);
const std::string& name = ESM::MagicEffect::effectIdToGmstString(id); const std::string& name = ESM::MagicEffect::indexToGmstString(id);
std::string icon = effect->mIcon; std::string icon = effect->mIcon;
int slashPos = icon.rfind('\\'); int slashPos = icon.rfind('\\');

View file

@ -191,7 +191,7 @@ namespace MWLua
sol::table effect(context.mLua->sol(), sol::create); sol::table effect(context.mLua->sol(), sol::create);
magicApi["EFFECT_TYPE"] = LuaUtil::makeStrictReadOnly(effect); 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); effect[name] = Misc::StringUtils::lowerCase(name);
} }
@ -263,7 +263,7 @@ namespace MWLua
auto effectParamsT = lua.new_usertype<ESM::ENAMstruct>("ESM3_EffectParams"); auto effectParamsT = lua.new_usertype<ESM::ENAMstruct>("ESM3_EffectParams");
effectParamsT[sol::meta_function::to_string] = [magicEffectStore](const ESM::ENAMstruct& params) { effectParamsT[sol::meta_function::to_string] = [magicEffectStore](const ESM::ENAMstruct& params) {
const ESM::MagicEffect* const rec = magicEffectStore->find(params.mEffectID); 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"] effectParamsT["effect"]
= sol::readonly_property([magicEffectStore](const ESM::ENAMstruct& params) -> const ESM::MagicEffect* { = sol::readonly_property([magicEffectStore](const ESM::ENAMstruct& params) -> const ESM::MagicEffect* {
@ -296,10 +296,10 @@ namespace MWLua
auto magicEffectT = context.mLua->sol().new_usertype<ESM::MagicEffect>("ESM3_MagicEffect"); auto magicEffectT = context.mLua->sol().new_usertype<ESM::MagicEffect>("ESM3_MagicEffect");
magicEffectT[sol::meta_function::to_string] = [](const ESM::MagicEffect& rec) { 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 { 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); return Misc::StringUtils::lowerCase(name);
}); });
magicEffectT["name"] = sol::readonly_property([](const ESM::MagicEffect& rec) -> std::string_view { magicEffectT["name"] = sol::readonly_property([](const ESM::MagicEffect& rec) -> std::string_view {
@ -307,7 +307,7 @@ namespace MWLua
.getWorld() .getWorld()
->getStore() ->getStore()
.get<ESM::GameSetting>() .get<ESM::GameSetting>()
.find(ESM::MagicEffect::effectIdToGmstString(rec.mIndex)) .find(ESM::MagicEffect::indexToGmstString(rec.mIndex))
->mValue.getString(); ->mValue.getString();
}); });
magicEffectT["school"] magicEffectT["school"]
@ -327,10 +327,10 @@ namespace MWLua
auto activeEffectT = context.mLua->sol().new_usertype<ActiveEffect>("ActiveEffect"); auto activeEffectT = context.mLua->sol().new_usertype<ActiveEffect>("ActiveEffect");
activeEffectT[sol::meta_function::to_string] = [](const ActiveEffect& effect) { 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 { 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); return Misc::StringUtils::lowerCase(name);
}); });
activeEffectT["name"] activeEffectT["name"]
@ -570,7 +570,7 @@ namespace MWLua
if (!effects.isActor()) if (!effects.isActor())
return sol::nullopt; return sol::nullopt;
auto id = ESM::MagicEffect::effectNameToId(idStr); auto id = ESM::MagicEffect::indexNameToIndex(idStr);
auto* rec = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id); auto* rec = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id);
MWMechanics::EffectKey key = MWMechanics::EffectKey(id); MWMechanics::EffectKey key = MWMechanics::EffectKey(id);
@ -586,10 +586,10 @@ namespace MWLua
key = MWMechanics::EffectKey(id, ESM::Skill::stringToSkillId(argStr.value())); key = MWMechanics::EffectKey(id, ESM::Skill::stringToSkillId(argStr.value()));
} }
MWMechanics::EffectParam param; std::optional<MWMechanics::EffectParam> param;
if (auto* store = effects.getStore()) if (auto* store = effects.getStore())
if (store->get(key, param)) if (store->get(key, param))
return ActiveEffect{ key, param }; return ActiveEffect{ key, param.value() };
return sol::nullopt; return sol::nullopt;
}; };
} }

View file

@ -374,7 +374,7 @@ namespace MWMechanics
{ {
ESM::MagicEffect::Effects effect ESM::MagicEffect::Effects effect
= ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature; = 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(); creatureStats.getAiSequence().stopCombat();
} }
} }

View file

@ -158,7 +158,7 @@ namespace
void soulTrap(const MWWorld::Ptr& creature) void soulTrap(const MWWorld::Ptr& creature)
{ {
const auto& stats = creature.getClass().getCreatureStats(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; return;
const int creatureSoulValue = creature.get<ESM::Creature>()->mBase->mData.mSoul; const int creatureSoulValue = creature.get<ESM::Creature>()->mBase->mData.mSoul;
if (creatureSoulValue == 0) 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; return;
// Stop here if target is unreachable // Stop here if target is unreachable
@ -828,7 +828,8 @@ namespace MWMechanics
stats.setHealth(stat); stats.setHealth(stat);
double restoreHours = hours; 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) if (stunted)
{ {
// Stunted Magicka effect should be taken into account. // Stunted Magicka effect should be taken into account.
@ -954,7 +955,7 @@ namespace MWMechanics
const bool knockedOutUnderwater const bool knockedOutUnderwater
= (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3()))); = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
if ((world->isSubmerged(ptr) || knockedOutUnderwater) 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; float timeLeft = 0.0f;
if (knockedOutUnderwater) if (knockedOutUnderwater)
@ -1110,7 +1111,7 @@ namespace MWMechanics
if (actorClass.isClass(ptr, "Guard") && !creatureStats.getAiSequence().isInPursuit() if (actorClass.isClass(ptr, "Guard") && !creatureStats.getAiSequence().isInPursuit()
&& !creatureStats.getAiSequence().isInCombat() && !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(); const MWWorld::ESMStore& esmStore = world->getStore();
static const int cutoff = esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->mValue.getInteger(); static const int cutoff = esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->mValue.getInteger();
@ -1814,7 +1815,8 @@ namespace MWMechanics
// Reset magic effects and recalculate derived effects // Reset magic effects and recalculate derived effects
// One case where we need this is to make sure bound items are removed upon death // 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()); stats.getActiveSpells().clear(actor.getPtr());
// Make sure spell effects are removed // Make sure spell effects are removed
purgeSpellEffects(stats.getActorId()); purgeSpellEffects(stats.getActorId());
@ -2002,7 +2004,7 @@ namespace MWMechanics
const auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr); const auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr);
CreatureStats& stats = ptr.getClass().getCreatureStats(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 const float healthHours = healthPerHour > 0
? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour

View file

@ -32,13 +32,13 @@ namespace MWMechanics
bool hasWaterWalking(const MWWorld::Ptr& actor) bool hasWaterWalking(const MWWorld::Ptr& actor)
{ {
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects(); 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) bool isTargetMagicallyHidden(const MWWorld::Ptr& actor)
{ {
const MagicEffects& magicEffects = actor.getClass().getCreatureStats(actor).getMagicEffects(); const MagicEffects& magicEffects = actor.getClass().getCreatureStats(actor).getMagicEffects();
return (magicEffects.get(ESM::MagicEffect::Invisibility).getMagnitude() > 0) return (magicEffects.getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude() > 0)
|| (magicEffects.get(ESM::MagicEffect::Chameleon).getMagnitude() > 75); || (magicEffects.getOrDefault(ESM::MagicEffect::Chameleon).getMagnitude() > 75);
} }
} }

View file

@ -464,7 +464,7 @@ namespace MWMechanics
if (enemy.getClass() if (enemy.getClass()
.getCreatureStats(enemy) .getCreatureStats(enemy)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Levitate) .getOrDefault(ESM::MagicEffect::Levitate)
.getMagnitude() .getMagnitude()
> 0) > 0)
{ {
@ -484,7 +484,11 @@ namespace MWMechanics
if (!actor.getClass().canWalk(actor) && !actor.getClass().isBipedal(actor)) if (!actor.getClass().canWalk(actor) && !actor.getClass().isBipedal(actor))
return true; 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) > 0)
return true; return true;

View file

@ -284,8 +284,11 @@ namespace
if (fallHeight >= fallDistanceMin) if (fallHeight >= fallDistanceMin)
{ {
const float acrobaticsSkill = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics)); const float acrobaticsSkill = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics));
const float jumpSpellBonus const float jumpSpellBonus = ptr.getClass()
= ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude(); .getCreatureStats(ptr)
.getMagicEffects()
.getOrDefault(ESM::MagicEffect::Jump)
.getMagnitude();
const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat(); const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat();
const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat(); const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat();
const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat(); const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat();
@ -2387,7 +2390,11 @@ namespace MWMechanics
{ {
if (cls.getCreatureStats(mPtr).isDead() if (cls.getCreatureStats(mPtr).isDead()
|| (!godmode || (!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; moved.z() = 1.0;
} }
@ -2644,7 +2651,7 @@ namespace MWMechanics
|| mPtr.getClass() || mPtr.getClass()
.getCreatureStats(mPtr) .getCreatureStats(mPtr)
.getMagicEffects() .getMagicEffects()
.get(MWMechanics::EffectKey(effectId)) .getOrDefault(MWMechanics::EffectKey(effectId))
.getMagnitude() .getMagnitude()
<= 0) <= 0)
mAnimation->removeEffect(effectId); mAnimation->removeEffect(effectId);
@ -2656,16 +2663,22 @@ namespace MWMechanics
if (!mPtr.getClass().isActor()) if (!mPtr.getClass().isActor())
return; return;
float light float light = mPtr.getClass()
= mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude(); .getCreatureStats(mPtr)
.getMagicEffects()
.getOrDefault(ESM::MagicEffect::Light)
.getMagnitude();
mAnimation->setLightEffect(light); mAnimation->setLightEffect(light);
// If you're dead you don't care about whether you've started/stopped being a vampire or not // 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()) if (mPtr.getClass().getCreatureStats(mPtr).isDead())
return; return;
bool vampire bool vampire = mPtr.getClass()
= mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() .getCreatureStats(mPtr)
.getMagicEffects()
.getOrDefault(ESM::MagicEffect::Vampirism)
.getMagnitude()
> 0.0f; > 0.0f;
mAnimation->setVampire(vampire); mAnimation->setVampire(vampire);
} }
@ -2679,7 +2692,7 @@ namespace MWMechanics
if (mPtr.getClass() if (mPtr.getClass()
.getCreatureStats(mPtr) .getCreatureStats(mPtr)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Invisibility) .getOrDefault(ESM::MagicEffect::Invisibility)
.getModifier()) // Ignore base magnitude (see bug #3555). .getModifier()) // Ignore base magnitude (see bug #3555).
{ {
if (mPtr == getPlayer()) if (mPtr == getPlayer())
@ -2690,7 +2703,7 @@ namespace MWMechanics
float chameleon = mPtr.getClass() float chameleon = mPtr.getClass()
.getCreatureStats(mPtr) .getCreatureStats(mPtr)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Chameleon) .getOrDefault(ESM::MagicEffect::Chameleon)
.getMagnitude(); .getMagnitude();
if (chameleon) if (chameleon)
{ {

View file

@ -185,8 +185,8 @@ namespace MWMechanics
return; return;
const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects(); const MWMechanics::MagicEffects& effects = actor.getClass().getCreatureStats(actor).getMagicEffects();
const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f; const float resistance = effects.getOrDefault(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f;
const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f; const float weakness = effects.getOrDefault(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f;
damage *= 1.f - std::min(1.f, resistance - weakness); damage *= 1.f - std::min(1.f, resistance - weakness);
@ -313,15 +313,17 @@ namespace MWMechanics
} }
static const float fCombatInvisoMult = gmst.find("fCombatInvisoMult")->mValue.getFloat(); static const float fCombatInvisoMult = gmst.find("fCombatInvisoMult")->mValue.getFloat();
defenseTerm += std::min(100.f, 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, 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) float attackTerm = skillValue + (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f)
+ (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
attackTerm *= stats.getFatigueTerm(); attackTerm *= stats.getFatigueTerm();
attackTerm += mageffects.get(ESM::MagicEffect::FortifyAttack).getMagnitude() attackTerm += mageffects.getOrDefault(ESM::MagicEffect::FortifyAttack).getMagnitude()
- mageffects.get(ESM::MagicEffect::Blind).getMagnitude(); - mageffects.getOrDefault(ESM::MagicEffect::Blind).getMagnitude();
return round(attackTerm - defenseTerm); return round(attackTerm - defenseTerm);
} }
@ -338,7 +340,7 @@ namespace MWMechanics
float magnitude = victim.getClass() float magnitude = victim.getClass()
.getCreatureStats(victim) .getCreatureStats(victim)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::FireShield + i) .getOrDefault(ESM::MagicEffect::FireShield + i)
.getMagnitude(); .getMagnitude();
if (!magnitude) if (!magnitude)

View file

@ -225,8 +225,8 @@ namespace MWMechanics
void CreatureStats::modifyMagicEffects(const MagicEffects& effects) void CreatureStats::modifyMagicEffects(const MagicEffects& effects)
{ {
bool recalc = effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() bool recalc = effects.getOrDefault(ESM::MagicEffect::FortifyMaximumMagicka).getModifier()
!= mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier(); != mMagicEffects.getOrDefault(ESM::MagicEffect::FortifyMaximumMagicka).getModifier();
mMagicEffects.setModifiers(effects); mMagicEffects.setModifiers(effects);
if (recalc) if (recalc)
recalculateMagicka(); recalculateMagicka();
@ -246,7 +246,7 @@ namespace MWMechanics
bool CreatureStats::isParalyzed() const bool CreatureStats::isParalyzed() const
{ {
return mMagicEffects.get(ESM::MagicEffect::Paralyze).getMagnitude() > 0; return mMagicEffects.getOrDefault(ESM::MagicEffect::Paralyze).getMagnitude() > 0;
} }
bool CreatureStats::isDead() const bool CreatureStats::isDead() const
@ -359,7 +359,7 @@ namespace MWMechanics
float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f)
+ (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); + (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
evasion *= getFatigueTerm(); 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; return evasion;
} }
@ -436,8 +436,8 @@ namespace MWMechanics
else else
base = world->getStore().get<ESM::GameSetting>().find("fNPCbaseMagickaMult")->mValue.getFloat(); base = world->getStore().get<ESM::GameSetting>().find("fNPCbaseMagickaMult")->mValue.getFloat();
double magickaFactor double magickaFactor = base
= base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; + mMagicEffects.getOrDefault(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1;
DynamicStat<float> magicka = getMagicka(); DynamicStat<float> magicka = getMagicka();
float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0; float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0;

View file

@ -46,18 +46,18 @@ namespace MWMechanics
if (Spells::hasCorprusEffect(spell)) if (Spells::hasCorprusEffect(spell))
resist = 1.f resist = 1.f
- 0.01f - 0.01f
* (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() * (actorEffects.getOrDefault(ESM::MagicEffect::ResistCorprusDisease).getMagnitude()
- actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude());
else if (spell->mData.mType == ESM::Spell::ST_Disease) else if (spell->mData.mType == ESM::Spell::ST_Disease)
resist = 1.f resist = 1.f
- 0.01f - 0.01f
* (actorEffects.get(ESM::MagicEffect::ResistCommonDisease).getMagnitude() * (actorEffects.getOrDefault(ESM::MagicEffect::ResistCommonDisease).getMagnitude()
- actorEffects.get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude()); - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude());
else if (spell->mData.mType == ESM::Spell::ST_Blight) else if (spell->mData.mType == ESM::Spell::ST_Blight)
resist = 1.f resist = 1.f
- 0.01f - 0.01f
* (actorEffects.get(ESM::MagicEffect::ResistBlightDisease).getMagnitude() * (actorEffects.getOrDefault(ESM::MagicEffect::ResistBlightDisease).getMagnitude()
- actorEffects.get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude()); - actorEffects.getOrDefault(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude());
else else
continue; continue;

View file

@ -147,7 +147,7 @@ namespace MWMechanics
{ {
for (Collection::iterator it = mCollection.begin(); it != mCollection.end(); ++it) 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) 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<EffectParam> param;
get(key, 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<EffectParam>& param) const
{ {
Collection::const_iterator iter = mCollection.find(key); Collection::const_iterator iter = mCollection.find(key);
@ -268,7 +268,7 @@ namespace MWMechanics
if (spellLine.empty()) if (spellLine.empty())
{ {
auto& effectIDStr = ESM::MagicEffect::effectIdToGmstString(effect.mIndex); auto& effectIDStr = ESM::MagicEffect::indexToGmstString(effect.mIndex);
spellLine = windowManager->getGameSettingString(effectIDStr, {}); spellLine = windowManager->getGameSettingString(effectIDStr, {});
} }

View file

@ -3,6 +3,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <optional>
namespace ESM namespace ESM
{ {
@ -104,8 +105,8 @@ namespace MWMechanics
/// Copy Modifier values from \a effects, but keep original mBase values. /// Copy Modifier values from \a effects, but keep original mBase values.
void setModifiers(const MagicEffects& effects); void setModifiers(const MagicEffects& effects);
EffectParam get(const EffectKey& key) const; EffectParam getOrDefault(const EffectKey& key) const;
bool get(const EffectKey& key, EffectParam& param) const; bool get(const EffectKey& key, std::optional<EffectParam>& param) const;
///< This function can safely be used for keys that are not present. ///< This function can safely be used for keys that are not present.
static MagicEffects diff(const MagicEffects& prev, const MagicEffects& now); static MagicEffects diff(const MagicEffects& prev, const MagicEffects& now);

View file

@ -577,7 +577,11 @@ namespace MWMechanics
if (playerStats.getDrawState() == MWMechanics::DrawState::Weapon) if (playerStats.getDrawState() == MWMechanics::DrawState::Weapon)
x += fDispWeaponDrawn; 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) if (clamp)
return std::clamp<int>(x, 0, 100); //, normally clamped to [0..100] when used return std::clamp<int>(x, 0, 100); //, normally clamped to [0..100] when used
@ -1558,8 +1562,8 @@ namespace MWMechanics
osg::Vec3f pos2(observer.getRefData().getPosition().asVec3()); osg::Vec3f pos2(observer.getRefData().getPosition().asVec3());
float distTerm = fSneakDistBase + fSneakDistMult * (pos1 - pos2).length(); float distTerm = fSneakDistBase + fSneakDistMult * (pos1 - pos2).length();
float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); float chameleon = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Chameleon).getMagnitude();
float invisibility = stats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude(); float invisibility = stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Invisibility).getMagnitude();
float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon; float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon;
if (invisibility > 0.f) if (invisibility > 0.f)
x += 100.f; x += 100.f;
@ -1567,7 +1571,7 @@ namespace MWMechanics
CreatureStats& observerStats = observer.getClass().getCreatureStats(observer); CreatureStats& observerStats = observer.getClass().getCreatureStats(observer);
float obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified(); float obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
float obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).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 obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind; float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind;
@ -1755,14 +1759,14 @@ namespace MWMechanics
&& ptr.getClass() && ptr.getClass()
.getCreatureStats(ptr) .getCreatureStats(ptr)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::CalmHumanoid) .getOrDefault(ESM::MagicEffect::CalmHumanoid)
.getMagnitude() .getMagnitude()
> 0) > 0)
|| (!ptr.getClass().isNpc() || (!ptr.getClass().isNpc()
&& ptr.getClass() && ptr.getClass()
.getCreatureStats(ptr) .getCreatureStats(ptr)
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::CalmCreature) .getOrDefault(ESM::MagicEffect::CalmCreature)
.getMagnitude() .getMagnitude()
> 0)) > 0))
return false; return false;

View file

@ -319,9 +319,9 @@ namespace
{ {
bool canReflect = !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable) bool canReflect = !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable)
&& !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Reflect) && !(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) 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) if (canReflect || canAbsorb)
{ {
auto& prng = MWBase::Environment::get().getWorld()->getPrng(); auto& prng = MWBase::Environment::get().getWorld()->getPrng();
@ -561,7 +561,8 @@ namespace MWMechanics
{ {
const auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); const auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects();
float volume = std::clamp( 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, MWBase::Environment::get().getSoundManager()->playSound3D(target,
ESM::RefId::stringRefId("magic sound"), volume, 1.f, MWSound::Type::Sfx, ESM::RefId::stringRefId("magic sound"), volume, 1.f, MWSound::Type::Sfx,
MWSound::PlayMode::LoopNoEnv); MWSound::PlayMode::LoopNoEnv);
@ -1058,7 +1059,7 @@ namespace MWMechanics
{ {
case ESM::MagicEffect::CommandCreature: case ESM::MagicEffect::CommandCreature:
case ESM::MagicEffect::CommandHumanoid: 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(); auto& seq = target.getClass().getCreatureStats(target).getAiSequence();
seq.erasePackageIf([&](const auto& package) { seq.erasePackageIf([&](const auto& package) {
@ -1068,7 +1069,7 @@ namespace MWMechanics
} }
break; break;
case ESM::MagicEffect::ExtraSpell: 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(); target.getClass().getInventoryStore(target).autoEquip();
break; break;
case ESM::MagicEffect::TurnUndead: case ESM::MagicEffect::TurnUndead:
@ -1096,7 +1097,7 @@ namespace MWMechanics
break; break;
case ESM::MagicEffect::NightEye: 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) if (nightEye.getMagnitude() < 0.f && nightEye.getBase() < 0)
{ {
// The PCVisionBonus functions are different from every other magic effect function in that they // 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); target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, effect.mMagnitude, invalid);
break; break;
case ESM::MagicEffect::Sound: 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( MWBase::Environment::get().getSoundManager()->stopSound3D(
target, ESM::RefId::stringRefId("magic sound")); target, ESM::RefId::stringRefId("magic sound"));
break; break;
@ -1275,7 +1276,7 @@ namespace MWMechanics
auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects();
magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(-effect.mMagnitude)); magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(-effect.mMagnitude));
removeMagicEffect(target, spellParams, effect); 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); auto anim = MWBase::Environment::get().getWorld()->getAnimation(target);
if (anim) if (anim)

View file

@ -265,7 +265,7 @@ namespace MWMechanics
const CreatureStats& stats = enemy.getClass().getCreatureStats(enemy); const CreatureStats& stats = enemy.getClass().getCreatureStats(enemy);
// Enemy can't cast spells // 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; return 0.f;
if (stats.isParalyzed() || stats.getKnockedDown()) if (stats.isParalyzed() || stats.getKnockedDown())
@ -596,7 +596,7 @@ namespace MWMechanics
if (effect.mEffectID <= ESM::MagicEffect::BoundLongbow) if (effect.mEffectID <= ESM::MagicEffect::BoundLongbow)
{ {
for (int e = ESM::MagicEffect::BoundDagger; e <= ESM::MagicEffect::BoundLongbow; ++e) 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 && (e != ESM::MagicEffect::BoundLongbow || effect.mEffectID == e
|| rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f)) || rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f))
return 0.f; return 0.f;
@ -619,7 +619,11 @@ namespace MWMechanics
// Prefer summoning items we know how to use // Prefer summoning items we know how to use
rating *= (50.f + actor.getClass().getSkill(actor, skill)) / 100.f; 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) > 0.f)
return 0.f; return 0.f;
} }
@ -662,14 +666,14 @@ namespace MWMechanics
{ {
CreatureStats& stats = enemy.getClass().getCreatureStats(enemy); 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; return 0.f;
} }
else else
{ {
CreatureStats& stats = actor.getClass().getCreatureStats(actor); 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; return 0.f;
} }
} }

View file

@ -79,16 +79,16 @@ namespace MWMechanics
float resistance = 0; float resistance = 0;
if (resistanceEffect != -1) if (resistanceEffect != -1)
resistance += actorEffects->get(resistanceEffect).getMagnitude(); resistance += actorEffects->getOrDefault(resistanceEffect).getMagnitude();
if (weaknessEffect != -1) if (weaknessEffect != -1)
resistance -= actorEffects->get(weaknessEffect).getMagnitude(); resistance -= actorEffects->getOrDefault(weaknessEffect).getMagnitude();
if (effectId == ESM::MagicEffect::FireDamage) if (effectId == ESM::MagicEffect::FireDamage)
resistance += actorEffects->get(ESM::MagicEffect::FireShield).getMagnitude(); resistance += actorEffects->getOrDefault(ESM::MagicEffect::FireShield).getMagnitude();
if (effectId == ESM::MagicEffect::ShockDamage) if (effectId == ESM::MagicEffect::ShockDamage)
resistance += actorEffects->get(ESM::MagicEffect::LightningShield).getMagnitude(); resistance += actorEffects->getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude();
if (effectId == ESM::MagicEffect::FrostDamage) if (effectId == ESM::MagicEffect::FrostDamage)
resistance += actorEffects->get(ESM::MagicEffect::FrostShield).getMagnitude(); resistance += actorEffects->getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude();
return resistance; return resistance;
} }

View file

@ -151,7 +151,7 @@ namespace MWMechanics
CreatureStats& stats = actor.getClass().getCreatureStats(actor); 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; return 0;
if (spell->mData.mType == ESM::Spell::ST_Power) if (spell->mData.mType == ESM::Spell::ST_Power)
@ -169,7 +169,7 @@ namespace MWMechanics
if (spell->mData.mFlags & ESM::Spell::F_Always) if (spell->mData.mFlags & ESM::Spell::F_Always)
return 100; return 100;
float castBonus = -stats.getMagicEffects().get(ESM::MagicEffect::Sound).getMagnitude(); float castBonus = -stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Sound).getMagnitude();
float castChance = baseChance + castBonus; float castChance = baseChance + castBonus;
castChance *= stats.getFatigueTerm(); castChance *= stats.getFatigueTerm();

View file

@ -666,7 +666,7 @@ namespace MWPhysics
// check if Actor should spawn above water // check if Actor should spawn above water
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); 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<Actor>(ptr, shape, mTaskScheduler.get(), canWaterWalk, mActorCollisionShapeType); auto actor = std::make_shared<Actor>(ptr, shape, mTaskScheduler.get(), canWaterWalk, mActorCollisionShapeType);
@ -750,7 +750,7 @@ namespace MWPhysics
const MWMechanics::MagicEffects& effects = stats.getMagicEffects(); const MWMechanics::MagicEffects& effects = stats.getMagicEffects();
bool waterCollision = false; 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() if (physicActor->getCollisionMode()
|| !world->isUnderwater(ptr.getCell(), ptr.getRefData().getPosition().asVec3())) || !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) // Slow fall reduces fall speed by a factor of (effect magnitude / 200)
const float slowFall 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 godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState();
const bool inert = stats.isDead() 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{ simulations.emplace_back(ActorSimulation{
physicActor, ActorFrameData{ *physicActor, inert, waterCollision, slowFall, waterlevel } }); physicActor, ActorFrameData{ *physicActor, inert, waterCollision, slowFall, waterlevel } });

View file

@ -222,7 +222,7 @@ namespace MWRender
{ {
const MWWorld::Class& cls = ptr.getClass(); const MWWorld::Class& cls = ptr.getClass();
NpcAnimation::NpcType curType = Type_Normal; 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; curType = Type_Vampire;
if (cls.getNpcStats(ptr).isWerewolf()) if (cls.getNpcStats(ptr).isWerewolf())
curType = Type_Werewolf; curType = Type_Werewolf;

View file

@ -582,7 +582,7 @@ namespace MWScript
k.has_value() && *k >= 0 && *k <= 32767) k.has_value() && *k >= 0 && *k <= 32767)
key = *k; key = *k;
else else
key = ESM::MagicEffect::effectGmstIdToId(effect); key = ESM::MagicEffect::effectGmstIdToIndex(effect);
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);

View file

@ -1193,17 +1193,17 @@ namespace MWScript
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
float currentValue = effects.get(mPositiveEffect).getMagnitude(); float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude();
if (mNegativeEffect != -1) if (mNegativeEffect != -1)
currentValue -= effects.get(mNegativeEffect).getMagnitude(); currentValue -= effects.getOrDefault(mNegativeEffect).getMagnitude();
// GetResist* should take in account elemental shields // GetResist* should take in account elemental shields
if (mPositiveEffect == ESM::MagicEffect::ResistFire) if (mPositiveEffect == ESM::MagicEffect::ResistFire)
currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::FireShield).getMagnitude();
if (mPositiveEffect == ESM::MagicEffect::ResistShock) if (mPositiveEffect == ESM::MagicEffect::ResistShock)
currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude();
if (mPositiveEffect == ESM::MagicEffect::ResistFrost) if (mPositiveEffect == ESM::MagicEffect::ResistFrost)
currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude();
int ret = static_cast<int>(currentValue); int ret = static_cast<int>(currentValue);
runtime.push(ret); runtime.push(ret);
@ -1227,17 +1227,17 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
float currentValue = effects.get(mPositiveEffect).getMagnitude(); float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude();
if (mNegativeEffect != -1) if (mNegativeEffect != -1)
currentValue -= effects.get(mNegativeEffect).getMagnitude(); currentValue -= effects.getOrDefault(mNegativeEffect).getMagnitude();
// SetResist* should take in account elemental shields // SetResist* should take in account elemental shields
if (mPositiveEffect == ESM::MagicEffect::ResistFire) if (mPositiveEffect == ESM::MagicEffect::ResistFire)
currentValue += effects.get(ESM::MagicEffect::FireShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::FireShield).getMagnitude();
if (mPositiveEffect == ESM::MagicEffect::ResistShock) if (mPositiveEffect == ESM::MagicEffect::ResistShock)
currentValue += effects.get(ESM::MagicEffect::LightningShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::LightningShield).getMagnitude();
if (mPositiveEffect == ESM::MagicEffect::ResistFrost) if (mPositiveEffect == ESM::MagicEffect::ResistFrost)
currentValue += effects.get(ESM::MagicEffect::FrostShield).getMagnitude(); currentValue += effects.getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude();
int arg = runtime[0].mInteger; int arg = runtime[0].mInteger;
runtime.pop(); runtime.pop();
@ -1276,7 +1276,8 @@ namespace MWScript
{ {
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::Ptr player = MWMechanics::getPlayer();
MWMechanics::EffectParam nightEye 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)); runtime.push(std::clamp(nightEye.getMagnitude() / 100.f, 0.f, 1.f));
} }
}; };
@ -1290,8 +1291,8 @@ namespace MWScript
runtime.pop(); runtime.pop();
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::Ptr player = MWMechanics::getPlayer();
auto& effects = player.getClass().getCreatureStats(player).getMagicEffects(); auto& effects = player.getClass().getCreatureStats(player).getMagicEffects();
float delta float delta = std::clamp(arg * 100.f, 0.f, 100.f)
= std::clamp(arg * 100.f, 0.f, 100.f) - effects.get(ESM::MagicEffect::NightEye).getMagnitude(); - effects.getOrDefault(ESM::MagicEffect::NightEye).getMagnitude();
effects.modifyBase(ESM::MagicEffect::NightEye, static_cast<int>(delta)); effects.modifyBase(ESM::MagicEffect::NightEye, static_cast<int>(delta));
} }
}; };
@ -1305,7 +1306,7 @@ namespace MWScript
runtime.pop(); runtime.pop();
MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::Ptr player = MWMechanics::getPlayer();
auto& effects = player.getClass().getCreatureStats(player).getMagicEffects(); 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); float newBase = std::clamp(nightEye.getMagnitude() + arg * 100.f, 0.f, 100.f);
newBase -= nightEye.getModifier(); newBase -= nightEye.getModifier();
float delta = std::clamp(newBase, 0.f, 100.f) - nightEye.getMagnitude(); float delta = std::clamp(newBase, 0.f, 100.f) - nightEye.getMagnitude();

View file

@ -538,8 +538,8 @@ namespace MWWorld
{ {
iter->mAttribute = -1; iter->mAttribute = -1;
Log(Debug::Verbose) Log(Debug::Verbose)
<< ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) << " effect of spell '" << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '" << spell.mId
<< spell.mId << "' has an attribute argument present. Dropping the argument."; << "' has an attribute argument present. Dropping the argument.";
changed = true; changed = true;
} }
} }
@ -549,8 +549,8 @@ namespace MWWorld
{ {
iter->mSkill = -1; iter->mSkill = -1;
Log(Debug::Verbose) Log(Debug::Verbose)
<< ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) << " effect of spell '" << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '" << spell.mId
<< spell.mId << "' has a skill argument present. Dropping the argument."; << "' has a skill argument present. Dropping the argument.";
changed = true; changed = true;
} }
} }
@ -558,9 +558,8 @@ namespace MWWorld
{ {
iter->mSkill = -1; iter->mSkill = -1;
iter->mAttribute = -1; iter->mAttribute = -1;
Log(Debug::Verbose) << ESM::MagicEffect::effectIdToGmstString(iter->mEffectID) Log(Debug::Verbose) << ESM::MagicEffect::indexToGmstString(iter->mEffectID) << " effect of spell '"
<< " effect of spell '" << spell.mId << spell.mId << "' has argument(s) present. Dropping the argument(s).";
<< "' has argument(s) present. Dropping the argument(s).";
changed = true; changed = true;
} }

View file

@ -503,10 +503,10 @@ namespace MWWorld
int blind = 0; int blind = 0;
const auto& magicEffects = playerClass.getCreatureStats(player).getMagicEffects(); const auto& magicEffects = playerClass.getCreatureStats(player).getMagicEffects();
if (!world->getGodModeState()) if (!world->getGodModeState())
blind = static_cast<int>(magicEffects.get(ESM::MagicEffect::Blind).getModifier()); blind = static_cast<int>(magicEffects.getOrDefault(ESM::MagicEffect::Blind).getModifier());
windowMgr->setBlindness(std::clamp(blind, 0, 100)); windowMgr->setBlindness(std::clamp(blind, 0, 100));
int nightEye = static_cast<int>(magicEffects.get(ESM::MagicEffect::NightEye).getMagnitude()); int nightEye = static_cast<int>(magicEffects.getOrDefault(ESM::MagicEffect::NightEye).getMagnitude());
rendering->setNightEyeFactor(std::min(1.f, (nightEye / 100.f))); rendering->setNightEyeFactor(std::min(1.f, (nightEye / 100.f)));
} }

View file

@ -2137,13 +2137,15 @@ namespace MWWorld
return false; return false;
const bool isPlayer = ptr == getPlayerConstPtr(); 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; return false;
if (ptr.getClass().canFly(ptr)) if (ptr.getClass().canFly(ptr))
return true; return true;
if (stats.getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && isLevitationEnabled()) if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Levitate).getMagnitude() > 0
&& isLevitationEnabled())
return true; return true;
const MWPhysics::Actor* actor = mPhysics->getActor(ptr); const MWPhysics::Actor* actor = mPhysics->getActor(ptr);
@ -2159,7 +2161,7 @@ namespace MWWorld
return false; return false;
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); 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 true;
return false; return false;
@ -3446,11 +3448,11 @@ namespace MWWorld
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
float dist = 0; float dist = 0;
if (type == World::Detect_Creature) 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) 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) else if (type == World::Detect_Enchantment)
dist = effects.get(ESM::MagicEffect::DetectEnchantment).getMagnitude(); dist = effects.getOrDefault(ESM::MagicEffect::DetectEnchantment).getMagnitude();
if (!dist) if (!dist)
return; return;
@ -3478,7 +3480,7 @@ namespace MWWorld
.getClass() .getClass()
.getCreatureStats(mPlayer->getPlayer()) .getCreatureStats(mPlayer->getPlayer())
.getMagicEffects() .getMagicEffects()
.get(ESM::MagicEffect::Telekinesis) .getOrDefault(ESM::MagicEffect::Telekinesis)
.getMagnitude(); .getMagnitude();
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);

View file

@ -24,156 +24,6 @@ namespace ESM
0x1048, 0x1048, 0x1048, 0x1048 }; 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) void MagicEffect::load(ESMReader& esm, bool& isDeleted)
{ {
isDeleted = false; // MagicEffect record can't be deleted now (may be changed in the future) 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 // Map effect ID to identifying name
const std::array<std::string, MagicEffect::Length> MagicEffect::sEffectNames = { const std::array<std::string_view, MagicEffect::Length> MagicEffect::sIndexNames = {
"WaterBreathing", "WaterBreathing",
"SwiftSwim", "SwiftSwim",
"WaterWalking", "WaterWalking",
@ -654,21 +504,21 @@ namespace ESM
"SummonCreature05", "SummonCreature05",
}; };
static std::map<std::string_view, int, Misc::StringUtils::CiComp> initStringToIntMap( template <typename Collection>
const std::array<std::string, MagicEffect::Length>& strings) static std::map<std::string_view, int, Misc::StringUtils::CiComp> initStringToIntMap(const Collection& strings)
{ {
std::map<std::string_view, int, Misc::StringUtils::CiComp> map; std::map<std::string_view, int, Misc::StringUtils::CiComp> map;
for (int i = 0; i < (int)strings.size(); i++) for (size_t i = 0; i < strings.size(); i++)
map[strings[i]] = i; map[strings[i]] = i;
return map; return map;
} }
const std::map<std::string_view, int, Misc::StringUtils::CiComp> MagicEffect::sGmstEffectIdToEffectIdMap const std::map<std::string_view, int, Misc::StringUtils::CiComp> MagicEffect::sGmstEffectIdToIndexMap
= initStringToIntMap(MagicEffect::sGmstEffectIds); = initStringToIntMap(MagicEffect::sGmstEffectIds);
const std::map<std::string_view, int, Misc::StringUtils::CiComp> MagicEffect::sEffectNameToEffectIdMap const std::map<std::string_view, int, Misc::StringUtils::CiComp> MagicEffect::sIndexNameToIndexMap
= initStringToIntMap(MagicEffect::sEffectNames); = initStringToIntMap(MagicEffect::sIndexNames);
class FindSecond class FindSecond
{ {
@ -729,35 +579,35 @@ namespace ESM
mDescription.clear(); 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<std::size_t>(effectID) >= sGmstEffectIds.size())
throw std::runtime_error(std::string("Unimplemented effect ID ") + std::to_string(effectID)); throw std::runtime_error(std::string("Unimplemented effect ID ") + std::to_string(effectID));
return sGmstEffectIds[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<std::size_t>(effectID) >= sIndexNames.size())
throw std::runtime_error(std::string("Unimplemented effect ID ") + std::to_string(effectID)); 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); auto name = sIndexNameToIndexMap.find(effect);
if (name == sEffectNameToEffectIdMap.end()) if (name == sIndexNameToIndexMap.end())
throw std::runtime_error("Unimplemented effect " + std::string(effect)); throw std::runtime_error("Unimplemented effect " + std::string(effect));
return name->second; return name->second;
} }
int MagicEffect::effectGmstIdToId(std::string_view gmstId) int MagicEffect::effectGmstIdToIndex(std::string_view gmstId)
{ {
auto name = sGmstEffectIdToEffectIdMap.find(gmstId); auto name = sGmstEffectIdToIndexMap.find(gmstId);
if (name == sGmstEffectIdToEffectIdMap.end()) if (name == sGmstEffectIdToIndexMap.end())
throw std::runtime_error("Unimplemented effect " + std::string(gmstId)); throw std::runtime_error("Unimplemented effect " + std::string(gmstId));
return name->second; return name->second;

View file

@ -267,16 +267,14 @@ namespace ESM
}; };
static const std::array<std::string, Length> sGmstEffectIds; static const std::array<std::string, Length> sGmstEffectIds;
static const std::array<std::string, Length> sEffectNames; static const std::array<std::string_view, Length> sIndexNames;
static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sGmstEffectIdToEffectIdMap; static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sGmstEffectIdToIndexMap;
static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sEffectNameToEffectIdMap; static const std::map<std::string_view, int, Misc::StringUtils::CiComp> sIndexNameToIndexMap;
static const std::string& effectIdToGmstString(int effectID); static const std::string& indexToGmstString(int effectID);
static const std::string& effectIdToName(int effectID); static std::string_view indexToName(int effectID);
static int effectNameToId(std::string_view effect); static int indexNameToIndex(std::string_view effect);
static int effectGmstIdToId(std::string_view gmstId); static int effectGmstIdToIndex(std::string_view gmstId);
static const std::string_view sIndexNames[MagicEffect::Length];
static RefId indexToRefId(int index); static RefId indexToRefId(int index);
}; };