1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-21 10:23:52 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Marc Zinnschlag 2018-10-26 13:02:06 +02:00
commit 3ead33814f
2 changed files with 38 additions and 3 deletions

View file

@ -143,6 +143,7 @@
Bug #4674: Journal can be opened when settings window is open 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 #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 #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 #4685: Missing sound causes an exception inside Say command
Bug #4689: Default creature soundgen entries are not used Bug #4689: Default creature soundgen entries are not used
Feature #912: Editor: Add missing icons to UniversalId tables Feature #912: Editor: Add missing icons to UniversalId tables

View file

@ -324,6 +324,34 @@ namespace MWMechanics
return true; 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) CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target, const bool fromProjectile, const bool manualSpell)
: mCaster(caster) : mCaster(caster)
, mTarget(target) , mTarget(target)
@ -444,12 +472,18 @@ namespace MWMechanics
MWBase::Environment::get().getWindowManager()->setEnemy(target); MWBase::Environment::get().getWindowManager()->setEnemy(target);
// Try absorbing if it's a spell // 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 // NOTE: Vanilla does this once per spell absorption effect source instead of adding the % from all sources together, so use the same approach here
// if that is worth replicating.
bool absorbed = false; bool absorbed = false;
if (spell && caster != target && target.getClass().isActor()) 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); absorbed = (Misc::Rng::roll0to99() < absorb);
if (absorbed) if (absorbed)
{ {