diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 1a6a62fc3..2a5995e0c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -512,8 +512,8 @@ namespace MWMechanics if (magnitude > 0 && remainingTime > 0 && remainingTime < mDuration) { CreatureStats& creatureStats = mActor.getClass().getCreatureStats(mActor); - effectTick(creatureStats, mActor, key, magnitude * remainingTime); - creatureStats.getMagicEffects().add(key, -magnitude); + if (effectTick(creatureStats, mActor, key, magnitude * remainingTime)) + creatureStats.getMagicEffects().add(key, -magnitude); } } }; @@ -527,8 +527,10 @@ namespace MWMechanics if (duration > 0) { - // apply correct magnitude for tickable effects that have just expired, - // in case duration > remaining time of effect + // Apply correct magnitude for tickable effects that have just expired, + // in case duration > remaining time of effect. + // One case where this will happen is when the player uses the rest/wait command + // while there is a tickable effect active that should expire before the end of the rest/wait. ExpiryVisitor visitor(ptr, duration); creatureStats.getActiveSpells().visitEffectSources(visitor); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 5865c32b9..72f0cddff 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -1009,10 +1009,10 @@ namespace MWMechanics creatureStats.setDynamic(index, stat); } - void effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const EffectKey &effectKey, float magnitude) + bool effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const EffectKey &effectKey, float magnitude) { if (magnitude == 0.f) - return; + return false; bool receivedMagicDamage = false; @@ -1144,10 +1144,13 @@ namespace MWMechanics case ESM::MagicEffect::RemoveCurse: actor.getClass().getCreatureStats(actor).getSpells().purgeCurses(); break; + default: + return false; } if (receivedMagicDamage && actor == getPlayer()) MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); + return true; } } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 852ae79dc..6e25acf50 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -63,7 +63,9 @@ namespace MWMechanics int getEffectiveEnchantmentCastCost (float castCost, const MWWorld::Ptr& actor); - void effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const MWMechanics::EffectKey& effectKey, float magnitude); + /// Apply a magic effect that is applied in tick intervals until its remaining time ends or it is removed + /// @return Was the effect a tickable effect with a magnitude? + bool effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const MWMechanics::EffectKey& effectKey, float magnitude); class CastSpell {