mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:53:53 +00:00
Apply magic effects while waiting/sleeping
This commit is contained in:
parent
41484432b4
commit
80f2ae0ca7
6 changed files with 61 additions and 10 deletions
|
@ -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().getMechanicsManager()->rest(false);
|
||||
MWBase::Environment::get().getMechanicsManager()->rest(false);
|
||||
MWBase::Environment::get().getWorld ()->advanceTime (2);
|
||||
MWBase::Environment::get().getMechanicsManager()->rest(false);
|
||||
MWBase::Environment::get().getMechanicsManager()->rest(false);
|
||||
|
||||
mProgressBar.setVisible(true);
|
||||
mProgressBar.setProgress(0, 2);
|
||||
|
|
|
@ -189,8 +189,8 @@ 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())
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue