diff --git a/CHANGELOG.md b/CHANGELOG.md index 285301a1d8..369fe04708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work Bug #5416: Junk non-node records before the root node are not handled gracefully Bug #5424: Creatures do not headtrack player + Bug #5425: Poison effect only appears for one frame Bug #5427: GetDistance unknown ID error is misleading Feature #5362: Show the soul gems' trapped soul in count dialog diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 0568efeb45..74076641a9 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -443,6 +443,9 @@ namespace MWGui // constant effects have no duration and no target if (!mEffectParams.mIsConstant) { + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) + mEffectParams.mDuration = std::max(1, mEffectParams.mDuration); + if (mEffectParams.mDuration > 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) { spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfor", "") + " " + MyGUI::utility::toString(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index 6d30909180..9cee1aa318 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -262,6 +262,8 @@ namespace MWMechanics int duration = 0; if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) duration = effect.mDuration; + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) + duration = std::max(1, duration); static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore() .get().find("fEffectCostMult")->mValue.getFloat(); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 7699349860..7aec5d4716 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -208,10 +208,15 @@ namespace MWMechanics } bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration); - if (hasDuration && effectIt->mDuration == 0) + effect.mDuration = hasDuration ? static_cast(effectIt->mDuration) : 1.f; + + bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce; + if (!appliedOnce) + effect.mDuration = std::max(1.f, effect.mDuration); + + if (effect.mDuration == 0) { // We still should add effect to list to allow GetSpellEffects to detect this spell - effect.mDuration = 0.f; appliedLastingEffects.push_back(effect); // duration 0 means apply full magnitude instantly @@ -224,8 +229,6 @@ namespace MWMechanics } else { - effect.mDuration = hasDuration ? static_cast(effectIt->mDuration) : 1.f; - effect.mTimeLeft = effect.mDuration; targetEffects.add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(effect.mMagnitude)); diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index 9428beafc0..81658193d6 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -394,8 +394,9 @@ namespace MWMechanics priority = 10; const MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); const DynamicStat& current = stats.getDynamic(effect.mEffectID - ESM::MagicEffect::RestoreHealth); + // NB: this currently assumes the hardcoded magic effect flags are used const float magnitude = (effect.mMagnMin + effect.mMagnMax)/2.f; - const float toHeal = magnitude * effect.mDuration; + const float toHeal = magnitude * std::max(1, effect.mDuration); // Effect doesn't heal more than we need, *or* we are below 1/2 health if (current.getModified() - current.getCurrent() > toHeal || current.getCurrent() < current.getModified()*0.5) diff --git a/apps/openmw/mwmechanics/spellutil.cpp b/apps/openmw/mwmechanics/spellutil.cpp index def3bbbc84..bb4953e482 100644 --- a/apps/openmw/mwmechanics/spellutil.cpp +++ b/apps/openmw/mwmechanics/spellutil.cpp @@ -31,9 +31,12 @@ namespace MWMechanics magicEffect = store.get().find(effect.mEffectID); bool hasMagnitude = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude); bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration); + bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce; int minMagn = hasMagnitude ? effect.mMagnMin : 1; int maxMagn = hasMagnitude ? effect.mMagnMax : 1; int duration = hasDuration ? effect.mDuration : 1; + if (!appliedOnce) + duration = std::max(1, duration); static const float fEffectCostMult = store.get().find("fEffectCostMult")->mValue.getFloat(); float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));