sleeping restoration of health, magicka, and fatigue

This commit is contained in:
scrawl 2012-09-21 17:53:16 +02:00
parent a161b34c67
commit 872fcf3e3d
8 changed files with 78 additions and 3 deletions

View file

@ -71,6 +71,9 @@ namespace MWBase
virtual void setPlayerClass (const ESM::Class& class_) = 0; virtual void setPlayerClass (const ESM::Class& class_) = 0;
///< Set player class to custom class. ///< Set player class to custom class.
virtual void restoreDynamicStats() = 0;
///< If the player is sleeping, this should be called every hour.
}; };
} }

View file

@ -7,6 +7,7 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/timestamp.hpp" #include "../mwworld/timestamp.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
@ -186,7 +187,11 @@ namespace MWGui
mProgressBar.setProgress (mCurHour, mHours); mProgressBar.setProgress (mCurHour, mHours);
if (mCurHour <= mHours) if (mCurHour <= mHours)
{
MWBase::Environment::get().getWorld ()->advanceTime (1); MWBase::Environment::get().getWorld ()->advanceTime (1);
if (mSleeping)
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
}
} }
if (mCurHour > mHours) if (mCurHour > mHours)

View file

@ -7,9 +7,15 @@
#include <components/esm/loadnpc.hpp> #include <components/esm/loadnpc.hpp>
#include <components/esm_store/store.hpp>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
namespace MWMechanics namespace MWMechanics
@ -20,7 +26,7 @@ namespace MWMechanics
adjustMagicEffects (ptr); adjustMagicEffects (ptr);
calculateCreatureStatModifiers (ptr); calculateCreatureStatModifiers (ptr);
calculateDynamicStats (ptr); calculateDynamicStats (ptr);
// AI // AI
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
creatureStats.getAiSequence().execute (ptr); creatureStats.getAiSequence().execute (ptr);
@ -76,6 +82,46 @@ namespace MWMechanics
creatureStats.getFatigue().setBase(strength+willpower+agility+endurance); creatureStats.getFatigue().setBase(strength+willpower+agility+endurance);
} }
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
{
CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
if (duration == 3600)
{
// stunted magicka
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0;
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
stats.getHealth().setCurrent(stats.getHealth ().getCurrent ()
+ 0.1 * endurance);
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
float fFatigueReturnBase = store.gameSettings.find("fFatigueReturnBase")->getFloat ();
float fFatigueReturnMult = store.gameSettings.find("fFatigueReturnMult")->getFloat ();
float fEndFatigueMult = store.gameSettings.find("fEndFatigueMult")->getFloat ();
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
x *= fEndFatigueMult * endurance;
stats.getFatigue ().setCurrent (stats.getFatigue ().getCurrent () + 3600 * x);
if (!stunted)
{
float fRestMagicMult = store.gameSettings.find("fRestMagicMult")->getFloat ();
stats.getMagicka().setCurrent (stats.getMagicka ().getCurrent ()
+ fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ());
}
}
}
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr) void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr)
{ {
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
@ -159,4 +205,12 @@ namespace MWMechanics
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
} }
} }
void Actors::restoreDynamicStats()
{
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
{
calculateRestoration (*iter, 3600);
}
}
} }

View file

@ -31,6 +31,9 @@ namespace MWMechanics
void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr); void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr);
void calculateRestoration (const MWWorld::Ptr& ptr, float duration);
public: public:
Actors(); Actors();
@ -54,6 +57,8 @@ namespace MWMechanics
///< This function is normally called automatically during the update process, but it can ///< This function is normally called automatically during the update process, but it can
/// also be called explicitly at any time to force an update. /// also be called explicitly at any time to force an update.
void restoreDynamicStats();
///< If the player is sleeping, this should be called every hour.
}; };
} }

View file

@ -282,6 +282,11 @@ namespace MWMechanics
mActors.update (movement, duration, paused); mActors.update (movement, duration, paused);
} }
void MechanicsManager::restoreDynamicStats()
{
mActors.restoreDynamicStats ();
}
void MechanicsManager::setPlayerName (const std::string& name) void MechanicsManager::setPlayerName (const std::string& name)
{ {
MWBase::Environment::get().getWorld()->getPlayer().setName (name); MWBase::Environment::get().getWorld()->getPlayer().setName (name);

View file

@ -73,6 +73,9 @@ namespace MWMechanics
virtual void setPlayerClass (const ESM::Class& class_); virtual void setPlayerClass (const ESM::Class& class_);
///< Set player class to custom class. ///< Set player class to custom class.
virtual void restoreDynamicStats();
///< If the player is sleeping, this should be called every hour.
}; };
} }

View file

@ -186,7 +186,7 @@ int GameSetting::getInt() const
} }
} }
int GameSetting::getFloat() const float GameSetting::getFloat() const
{ {
switch (type) switch (type)
{ {

View file

@ -87,7 +87,7 @@ struct GameSetting
int getInt() const; int getInt() const;
///< Throws an exception if GMST is not of type int or float. ///< Throws an exception if GMST is not of type int or float.
int getFloat() const; float getFloat() const;
///< Throws an exception if GMST is not of type int or float. ///< Throws an exception if GMST is not of type int or float.
std::string getString() const; std::string getString() const;