1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-30 12:32:36 +00:00
OpenMW/apps/openmw/mwmechanics/spellresistance.cpp
florent.teppe 1ced0c912e partially revert "Store: moved all the template specialization to its own heaper file, included where it's needed"
This reverts commit 80a25bcd3021f7ebfaf2f864e34532009b9b8aeb.
It didn't really make sense to do all those changes in the same MR

partially Revert "Store refactoring: more forgotten storeSpecialization.hpp"

This reverts commit 9943a5bc96b9025f06cbaac5bb7f1bf51ebc746f.

removed remaining references to storeSpecialization  CMakeLists.txt,  and landmanager.cpp
2022-09-05 17:35:06 +02:00

95 lines
3.5 KiB
C++

#include "spellresistance.hpp"
#include <components/misc/rng.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "creaturestats.hpp"
#include "spellutil.hpp"
namespace MWMechanics
{
float getEffectMultiplier(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster,
const ESM::Spell* spell, const MagicEffects* effects)
{
if (!actor.getClass().isActor())
return 1;
float resistance = getEffectResistance(effectId, actor, caster, spell, effects);
return 1 - resistance / 100.f;
}
float getEffectResistance (short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster,
const ESM::Spell* spell, const MagicEffects* effects)
{
// Effects with no resistance attribute belonging to them can not be resisted
if (ESM::MagicEffect::getResistanceEffect(effectId) == -1)
return 0.f;
const auto magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectId);
const MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
const MWMechanics::MagicEffects* magicEffects = &stats.getMagicEffects();
if (effects)
magicEffects = effects;
float resistance = getEffectResistanceAttribute(effectId, magicEffects);
float willpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
float x = (willpower + 0.1f * luck) * stats.getFatigueTerm();
// This makes spells that are easy to cast harder to resist and vice versa
float castChance = 100.f;
if (spell != nullptr && !caster.isEmpty() && caster.getClass().isActor())
castChance = getSpellSuccessChance(spell, caster, nullptr, false, false); // Uncapped casting chance
if (castChance > 0)
x *= 50 / castChance;
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
float roll = Misc::Rng::rollClosedProbability(prng) * 100;
if (magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)
roll -= resistance;
if (x <= roll)
x = 0;
else
{
if (magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)
x = 100;
else
x = roll / std::min(x, 100.f);
}
x = std::min(x + resistance, 100.f);
return x;
}
float getEffectResistanceAttribute (short effectId, const MagicEffects* actorEffects)
{
short resistanceEffect = ESM::MagicEffect::getResistanceEffect(effectId);
short weaknessEffect = ESM::MagicEffect::getWeaknessEffect(effectId);
float resistance = 0;
if (resistanceEffect != -1)
resistance += actorEffects->get(resistanceEffect).getMagnitude();
if (weaknessEffect != -1)
resistance -= actorEffects->get(weaknessEffect).getMagnitude();
if (effectId == ESM::MagicEffect::FireDamage)
resistance += actorEffects->get(ESM::MagicEffect::FireShield).getMagnitude();
if (effectId == ESM::MagicEffect::ShockDamage)
resistance += actorEffects->get(ESM::MagicEffect::LightningShield).getMagnitude();
if (effectId == ESM::MagicEffect::FrostDamage)
resistance += actorEffects->get(ESM::MagicEffect::FrostShield).getMagnitude();
return resistance;
}
}