Merge pull request #986 from MiroslavR/resting-effects

Apply magic effects while waiting/sleeping
pull/1/head
scrawl 9 years ago committed by GitHub
commit b94a4c1c77

@ -79,9 +79,9 @@ namespace MWGui
MWWorld::Ptr player = MWMechanics::getPlayer();
MWBase::Environment::get().getWorld()->advanceTime(mDays * 24);
for (int i=0; i<mDays*24; ++i)
MWBase::Environment::get().getMechanicsManager()->rest(true);
MWBase::Environment::get().getWorld()->advanceTime(mDays * 24);
std::set<int> skills;
for (int day=0; day<mDays; ++day)

@ -176,9 +176,9 @@ namespace MWGui
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
// advance time
MWBase::Environment::get().getWorld ()->advanceTime (2);
MWBase::Environment::get().getMechanicsManager()->rest(false);
MWBase::Environment::get().getMechanicsManager()->rest(false);
MWBase::Environment::get().getWorld ()->advanceTime (2);
mProgressBar.setVisible(true);
mProgressBar.setProgress(0, 2);

@ -189,8 +189,12 @@ namespace MWGui
void WaitDialog::onWaitingProgressChanged(int cur, int total)
{
mProgressBar.setProgress(cur, total);
MWBase::Environment::get().getWorld()->advanceTime(1);
MWBase::Environment::get().getMechanicsManager()->rest(mSleeping);
MWBase::Environment::get().getWorld()->advanceTime(1);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if (player.getClass().getCreatureStats(player).isDead())
stopWaiting();
}
void WaitDialog::onWaitingInterrupted()

@ -493,6 +493,31 @@ namespace MWMechanics
stats.setFatigue (fatigue);
}
class ExpiryVisitor : public EffectSourceVisitor
{
private:
MWWorld::Ptr mActor;
float mDuration;
public:
ExpiryVisitor(const MWWorld::Ptr& actor, float duration)
: mActor(actor), mDuration(duration)
{
}
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 (magnitude > 0 && remainingTime > 0 && remainingTime < mDuration)
{
CreatureStats& creatureStats = mActor.getClass().getCreatureStats(mActor);
effectTick(creatureStats, mActor, key, magnitude * remainingTime);
creatureStats.getMagicEffects().add(key, -magnitude);
}
}
};
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration)
{
CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr);
@ -502,6 +527,11 @@ namespace MWMechanics
if (duration > 0)
{
// apply correct magnitude for tickable effects that have just expired,
// in case duration > remaining time of effect
ExpiryVisitor visitor(ptr, duration);
creatureStats.getActiveSpells().visitEffectSources(visitor);
for (MagicEffects::Collection::const_iterator it = effects.begin(); it != effects.end(); ++it)
{
// tickable effects (i.e. effects having a lasting impact after expiry)
@ -1298,10 +1328,32 @@ namespace MWMechanics
}
}
void Actors::restoreDynamicStats(bool sleep)
void Actors::rest(bool sleep)
{
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
float duration = 3600.f / MWBase::Environment::get().getWorld()->getTimeScaleFactor();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{
if (iter->first.getClass().getCreatureStats(iter->first).isDead())
continue;
restoreDynamicStats(iter->first, sleep);
if ((!iter->first.getRefData().getBaseNode()) ||
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2() > sqrAiProcessingDistance)
continue;
adjustMagicEffects (iter->first);
if (iter->first.getClass().getCreatureStats(iter->first).needToRecalcDynamicStats())
calculateDynamicStats (iter->first);
calculateCreatureStatModifiers (iter->first, duration);
if (iter->first.getClass().isNpc())
calculateNpcStatModifiers(iter->first, duration);
}
fastForwardAi();
}
int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const

@ -93,8 +93,8 @@ namespace MWMechanics
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
void restoreDynamicStats(bool sleep);
///< If the player is sleeping, this should be called every hour.
void rest(bool sleep);
///< Update actors while the player is waiting or sleeping. This should be called every hour.
void restoreDynamicStats(const MWWorld::Ptr& actor, bool sleep);

@ -499,8 +499,7 @@ namespace MWMechanics
void MechanicsManager::rest(bool sleep)
{
mActors.restoreDynamicStats (sleep);
mActors.fastForwardAi();
mActors.rest(sleep);
}
int MechanicsManager::getHoursToRest() const

@ -804,6 +804,9 @@ namespace MWWorld
mWeatherManager->advanceTime (hours, incremental);
if (!incremental)
mProjectileManager->clear();
hours += mGameHour->getFloat();
setHour (hours);

Loading…
Cancel
Save