mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Make spell absorption multiplicative (bug #4684)
This commit is contained in:
parent
0fad2449f3
commit
bf9e8c4556
@ -143,6 +143,7 @@
|
||||
Bug #4674: Journal can be opened when settings window is open
|
||||
Bug #4677: Crash in ESM reader when NPC record has DNAM record without DODT one
|
||||
Bug #4678: Crash in ESP parser when SCVR has no variable names
|
||||
Bug #4684: Spell Absorption is additive
|
||||
Bug #4685: Missing sound causes an exception inside Say command
|
||||
Bug #4689: Default creature soundgen entries are not used
|
||||
Feature #912: Editor: Add missing icons to UniversalId tables
|
||||
|
@ -324,6 +324,34 @@ namespace MWMechanics
|
||||
return true;
|
||||
}
|
||||
|
||||
class GetAbsorptionProbability : public MWMechanics::EffectSourceVisitor
|
||||
{
|
||||
public:
|
||||
float mProbability;
|
||||
|
||||
GetAbsorptionProbability(const MWWorld::Ptr& actor)
|
||||
: mProbability(0.f){}
|
||||
|
||||
virtual void visit (MWMechanics::EffectKey key,
|
||||
const std::string& sourceName, const std::string& sourceId, int casterActorId,
|
||||
float magnitude, float remainingTime = -1, float totalTime = -1)
|
||||
{
|
||||
if (key.mId == ESM::MagicEffect::SpellAbsorption)
|
||||
{
|
||||
if (mProbability == 0.f)
|
||||
mProbability = magnitude / 100;
|
||||
else
|
||||
{
|
||||
// If there are different sources of SpellAbsorption effect, multiply failing probability for all effects.
|
||||
// Real absorption probability will be the (1 - total fail chance) in this case.
|
||||
float failProbability = 1.f - mProbability;
|
||||
failProbability *= 1.f - magnitude / 100;
|
||||
mProbability = 1.f - failProbability;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target, const bool fromProjectile, const bool manualSpell)
|
||||
: mCaster(caster)
|
||||
, mTarget(target)
|
||||
@ -444,12 +472,18 @@ namespace MWMechanics
|
||||
MWBase::Environment::get().getWindowManager()->setEnemy(target);
|
||||
|
||||
// Try absorbing if it's a spell
|
||||
// NOTE: Vanilla does this once per spell absorption effect source instead of adding the % from all sources together, not sure
|
||||
// if that is worth replicating.
|
||||
// NOTE: Vanilla does this once per spell absorption effect source instead of adding the % from all sources together, so use the same approach here
|
||||
bool absorbed = false;
|
||||
if (spell && caster != target && target.getClass().isActor())
|
||||
{
|
||||
float absorb = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::SpellAbsorption).getMagnitude();
|
||||
GetAbsorptionProbability check(target);
|
||||
MWMechanics::CreatureStats& stats = target.getClass().getCreatureStats(target);
|
||||
stats.getActiveSpells().visitEffectSources(check);
|
||||
stats.getSpells().visitEffectSources(check);
|
||||
if (target.getClass().hasInventoryStore(target))
|
||||
target.getClass().getInventoryStore(target).visitEffectSources(check);
|
||||
|
||||
int absorb = check.mProbability * 100;
|
||||
absorbed = (Misc::Rng::roll0to99() < absorb);
|
||||
if (absorbed)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user