From f5eacfcf63e412eb9c6133528f3f258f8d9c8ed3 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 6 Feb 2019 22:40:50 +0400 Subject: [PATCH] Support for temporary stunted magicka effects --- apps/openmw/mwmechanics/actors.cpp | 71 +++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 31d4ef42cb..b627bdafa9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -130,23 +130,45 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); - bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); - health = 0.1f * endurance; - magicka = 0; - if (!stunted) - { - float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat (); - magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); - } + float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat (); + magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); } } namespace MWMechanics { + class GetStuntedMagickaDuration : public MWMechanics::EffectSourceVisitor + { + public: + float mRemainingTime; + + GetStuntedMagickaDuration(const MWWorld::Ptr& actor) + : mRemainingTime(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 (mRemainingTime == -1) return; + + if (key.mId == ESM::MagicEffect::StuntedMagicka) + { + if (totalTime == -1) + { + mRemainingTime = -1; + return; + } + + if (remainingTime > mRemainingTime) + mRemainingTime = remainingTime; + } + } + }; + class SoulTrap : public MWMechanics::EffectSourceVisitor { MWWorld::Ptr mCreature; @@ -585,9 +607,33 @@ namespace MWMechanics stat.setCurrent(stat.getCurrent() + health * hours); stats.setHealth(stat); - stat = stats.getMagicka(); - stat.setCurrent(stat.getCurrent() + magicka * hours); - stats.setMagicka(stat); + double restoreHours = hours; + bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; + if (stunted) + { + // Stunted Magicka effect should be taken into account. + GetStuntedMagickaDuration visitor(ptr); + stats.getActiveSpells().visitEffectSources(visitor); + stats.getSpells().visitEffectSources(visitor); + if (ptr.getClass().hasInventoryStore(ptr)) + ptr.getClass().getInventoryStore(ptr).visitEffectSources(visitor); + + // Take a maximum remaining duration of Stunted Magicka effects (-1 is a constant one) in game hours. + if (visitor.mRemainingTime > 0) + { + double timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + restoreHours = std::max(0.0, hours - visitor.mRemainingTime * timeScale / 3600.f); + } + else if (visitor.mRemainingTime == -1) + restoreHours = 0; + } + + if (restoreHours > 0) + { + stat = stats.getMagicka(); + stat.setCurrent(stat.getCurrent() + magicka * restoreHours); + stats.setMagicka(stat); + } } // Current fatigue can be above base value due to a fortify effect. @@ -1809,11 +1855,12 @@ namespace MWMechanics getRestorationPerHourOfSleep(ptr, healthPerHour, magickaPerHour); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; float healthHours = healthPerHour > 0 ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour : 1.0f; - float magickaHours = magickaPerHour > 0 + float magickaHours = magickaPerHour > 0 && !stunted ? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour : 1.0f;