1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 00:15:32 +00:00

Merge branch 'effects'

This commit is contained in:
Marc Zinnschlag 2012-05-19 17:41:47 +02:00
commit 420cd53be0
18 changed files with 548 additions and 51 deletions

View file

@ -48,6 +48,7 @@ add_openmw_dir (mwworld
refdata world physicssystem scene globals class action nullaction actionteleport refdata world physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr actionread cells localscripts customdata weather inventorystore ptr actionread
timestamp
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass
@ -57,6 +58,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells mechanicsmanager stat creaturestats magiceffects movement actors drawstate spells
activespells
) )
add_openmw_dir (mwbase add_openmw_dir (mwbase

View file

@ -0,0 +1,162 @@
#include "activespells.hpp"
#include <cstdlib>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
namespace MWMechanics
{
void ActiveSpells::update() const
{
bool rebuild = false;
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
if (mLastUpdate!=now)
{
TContainer::iterator iter (mSpells.begin());
while (iter!=mSpells.end())
if (!timeToExpire (iter))
{
mSpells.erase (iter++);
rebuild = true;
}
else
++iter;
mLastUpdate = now;
}
if (mSpellsChanged)
{
mSpellsChanged = false;
rebuild = true;
}
if (rebuild)
{
mEffects = MagicEffects();
for (TIterator iter (begin()); iter!=end(); ++iter)
{
const ESM::Spell& spell =
*MWBase::Environment::get().getWorld()->getStore().spells.find (iter->first);
const MWWorld::TimeStamp& start = iter->second.first;
float magnitude = iter->second.second;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (spell.effects.list.begin());
iter!=spell.effects.list.end(); ++iter)
{
if (iter->duration)
{
MWWorld::TimeStamp end = start;
end += static_cast<double> (iter->duration)*
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
if (end>now)
{
EffectParam param;
param.mMagnitude = static_cast<int> (
(iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin);
mEffects.add (*iter, param);
}
}
}
}
}
}
ActiveSpells::ActiveSpells()
: mSpellsChanged (false), mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp())
{}
void ActiveSpells::addSpell (const std::string& id)
{
const ESM::Spell& spell = *MWBase::Environment::get().getWorld()->getStore().spells.find (id);
bool found = false;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (spell.effects.list.begin());
iter!=spell.effects.list.end(); ++iter)
{
if (iter->duration)
{
found = true;
break;
}
}
if (!found)
return;
TContainer::iterator iter = mSpells.find (id);
float random = static_cast<float> (std::rand()) / RAND_MAX;
if (iter==mSpells.end())
mSpells.insert (std::make_pair (id,
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
else
iter->second = std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random);
mSpellsChanged = true;
}
void ActiveSpells::removeSpell (const std::string& id)
{
TContainer::iterator iter = mSpells.find (id);
if (iter!=mSpells.end())
{
mSpells.erase (iter);
mSpellsChanged = true;
}
}
const MagicEffects& ActiveSpells::getMagicEffects() const
{
update();
return mEffects;
}
ActiveSpells::TIterator ActiveSpells::begin() const
{
update();
return mSpells.begin();
}
ActiveSpells::TIterator ActiveSpells::end() const
{
update();
return mSpells.end();
}
double ActiveSpells::timeToExpire (const TIterator& iterator) const
{
const ESM::Spell& spell =
*MWBase::Environment::get().getWorld()->getStore().spells.find (iterator->first);
int duration = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (spell.effects.list.begin());
iter!=spell.effects.list.end(); ++iter)
{
if (iter->duration>duration)
duration = iter->duration;
}
double scaledDuration = duration *
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
double usedUp = MWBase::Environment::get().getWorld()->getTimeStamp()-iterator->second.first;
if (usedUp>=scaledDuration)
return 0;
return scaledDuration-usedUp;
}
}

View file

@ -0,0 +1,58 @@
#ifndef GAME_MWMECHANICS_ACTIVESPELLS_H
#define GAME_MWMECHANICS_ACTIVESPELLS_H
#include <map>
#include <vector>
#include <string>
#include "../mwworld/timestamp.hpp"
#include "magiceffects.hpp"
namespace ESM
{
struct Spell;
}
namespace MWMechanics
{
/// \brief Lasting spell effects
class ActiveSpells
{
public:
typedef std::map<std::string, std::pair<MWWorld::TimeStamp, float> > TContainer;
typedef TContainer::const_iterator TIterator;
private:
mutable TContainer mSpells; // spellId, (time of casting, relative magnitude)
mutable MagicEffects mEffects;
mutable bool mSpellsChanged;
mutable MWWorld::TimeStamp mLastUpdate;
void update() const;
public:
ActiveSpells();
void addSpell (const std::string& id);
///< Overwrites an existing spell with the same ID. If the spell does not have any
/// non-instant effects, it is ignored.
void removeSpell (const std::string& id);
const MagicEffects& getMagicEffects() const;
TIterator begin() const;
TIterator end() const;
double timeToExpire (const TIterator& iterator) const;
///< Returns time (in in-game hours) until the spell pointed to by \a iterator
/// expires.
};
}
#endif

View file

@ -8,11 +8,30 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "creaturestats.hpp"
namespace MWMechanics namespace MWMechanics
{ {
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
{ {
// magic effects
adjustMagicEffects (ptr);
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
// calculate dynamic stats
int strength = creatureStats.mAttributes[0].getBase();
int intelligence = creatureStats.mAttributes[1].getBase();
int willpower = creatureStats.mAttributes[2].getBase();
int agility = creatureStats.mAttributes[3].getBase();
int endurance = creatureStats.mAttributes[5].getBase();
double magickaFactor = creatureStats.mMagicEffects.get (EffectKey (84)).mMagnitude*0.1 + 0.5;
creatureStats.mDynamic[0].setBase (static_cast<int> (0.5 * (strength + endurance)));
creatureStats.mDynamic[1].setBase (static_cast<int> (intelligence +
magickaFactor * intelligence));
creatureStats.mDynamic[2].setBase (strength+willpower+agility+endurance);
} }
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
@ -22,6 +41,27 @@ namespace MWMechanics
MWWorld::Class::get (ptr).getNpcStats (ptr)); MWWorld::Class::get (ptr).getNpcStats (ptr));
} }
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
{
CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now = creatureStats.mSpells.getMagicEffects();
if (creature.getTypeName()==typeid (ESM::NPC).name())
{
MWWorld::InventoryStore& store = MWWorld::Class::get (creature).getInventoryStore (creature);
now += store.getMagicEffects();
}
now += creatureStats.mActiveSpells.getMagicEffects();
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
creatureStats.mMagicEffects = now;
// TODO apply diff to other stats
}
Actors::Actors() : mDuration (0) {} Actors::Actors() : mDuration (0) {}
void Actors::addActor (const MWWorld::Ptr& ptr) void Actors::addActor (const MWWorld::Ptr& ptr)

View file

@ -19,10 +19,10 @@ namespace MWMechanics
std::set<MWWorld::Ptr> mActors; std::set<MWWorld::Ptr> mActors;
float mDuration; float mDuration;
void updateActor (const MWWorld::Ptr& ptr, float duration);
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused); void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
void adjustMagicEffects (const MWWorld::Ptr& creature);
public: public:
Actors(); Actors();
@ -39,6 +39,11 @@ namespace MWMechanics
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
float duration, bool paused); float duration, bool paused);
///< Update actor stats and store desired velocity vectors in \a movement ///< Update actor stats and store desired velocity vectors in \a movement
void updateActor (const MWWorld::Ptr& ptr, float duration);
///< This function is normally called automatically during the update process, but it can
/// also be called explicitly at any time to force an update.
}; };
} }

View file

@ -7,6 +7,7 @@
#include "stat.hpp" #include "stat.hpp"
#include "magiceffects.hpp" #include "magiceffects.hpp"
#include "spells.hpp" #include "spells.hpp"
#include "activespells.hpp"
namespace MWMechanics namespace MWMechanics
{ {
@ -16,6 +17,7 @@ namespace MWMechanics
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
int mLevel; int mLevel;
Spells mSpells; Spells mSpells;
ActiveSpells mActiveSpells;
MagicEffects mMagicEffects; MagicEffects mMagicEffects;
}; };
} }

View file

@ -1,6 +1,8 @@
#include "magiceffects.hpp" #include "magiceffects.hpp"
#include <cstdlib>
#include <stdexcept> #include <stdexcept>
#include <components/esm/defs.hpp> #include <components/esm/defs.hpp>
@ -66,6 +68,46 @@ namespace MWMechanics
} }
} }
void MagicEffects::add (const ESM::EffectList& list)
{
for (std::vector<ESM::ENAMstruct>::const_iterator iter (list.list.begin()); iter!=list.list.end();
++iter)
{
EffectParam param;
if (iter->magnMin>=iter->magnMax)
param.mMagnitude = iter->magnMin;
else
param.mMagnitude = static_cast<int> (
(iter->magnMax-iter->magnMin+1)*
(static_cast<float> (std::rand()) / RAND_MAX) + iter->magnMin);
add (*iter, param);
}
}
MagicEffects& MagicEffects::operator+= (const MagicEffects& effects)
{
if (this==&effects)
{
MagicEffects temp (effects);
*this += temp;
return *this;
}
for (Collection::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter)
{
Collection::iterator result = mCollection.find (iter->first);
if (result!=mCollection.end())
result->second += iter->second;
else
mCollection.insert (*iter);
}
return *this;
}
EffectParam MagicEffects::get (const EffectKey& key) const EffectParam MagicEffects::get (const EffectKey& key) const
{ {
Collection::const_iterator iter = mCollection.find (key); Collection::const_iterator iter = mCollection.find (key);
@ -85,11 +127,11 @@ namespace MWMechanics
MagicEffects result; MagicEffects result;
// adding/changing // adding/changing
for (Collection::const_iterator iter (now.Begin()); iter!=now.End(); ++iter) for (Collection::const_iterator iter (now.begin()); iter!=now.end(); ++iter)
{ {
Collection::const_iterator other = prev.mCollection.find (iter->first); Collection::const_iterator other = prev.mCollection.find (iter->first);
if (other==prev.End()) if (other==prev.end())
{ {
// adding // adding
result.add (iter->first, iter->second); result.add (iter->first, iter->second);
@ -102,17 +144,16 @@ namespace MWMechanics
} }
// removing // removing
for (Collection::const_iterator iter (prev.Begin()); iter!=prev.End(); ++iter) for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter)
{ {
Collection::const_iterator other = now.mCollection.find (iter->first); Collection::const_iterator other = now.mCollection.find (iter->first);
if (other==prev.End()) if (other==prev.end())
{ {
result.add (iter->first, EffectParam() - iter->second); result.add (iter->first, EffectParam() - iter->second);
} }
} }
return result; return result;
} }
} }

View file

@ -6,6 +6,7 @@
namespace ESM namespace ESM
{ {
struct ENAMstruct; struct ENAMstruct;
struct EffectList;
} }
namespace MWMechanics namespace MWMechanics
@ -60,12 +61,16 @@ namespace MWMechanics
public: public:
Collection::const_iterator Begin() const { return mCollection.begin(); } Collection::const_iterator begin() const { return mCollection.begin(); }
Collection::const_iterator End() const { return mCollection.end(); } Collection::const_iterator end() const { return mCollection.end(); }
void add (const EffectKey& key, const EffectParam& param); void add (const EffectKey& key, const EffectParam& param);
void add (const ESM::EffectList& list);
MagicEffects& operator+= (const MagicEffects& effects);
EffectParam get (const EffectKey& key) const; EffectParam get (const EffectKey& key) const;
///< This function can safely be used for keys that are not present. ///< This function can safely be used for keys that are not present.

View file

@ -139,42 +139,13 @@ namespace MWMechanics
} }
} }
// magic effects // forced update and current value adjustments
adjustMagicEffects (ptr); mActors.updateActor (ptr, 0);
// calculate dynamic stats
int strength = creatureStats.mAttributes[0].getBase();
int intelligence = creatureStats.mAttributes[1].getBase();
int willpower = creatureStats.mAttributes[2].getBase();
int agility = creatureStats.mAttributes[3].getBase();
int endurance = creatureStats.mAttributes[5].getBase();
double magickaFactor = creatureStats.mMagicEffects.get (EffectKey (84)).mMagnitude*0.1 + 0.5;
creatureStats.mDynamic[0].setBase (static_cast<int> (0.5 * (strength + endurance)));
creatureStats.mDynamic[1].setBase (static_cast<int> (intelligence +
magickaFactor * intelligence));
creatureStats.mDynamic[2].setBase (strength+willpower+agility+endurance);
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified()); creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified());
} }
void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature)
{
MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now = creatureStats.mSpells.getMagicEffects();
/// \todo add effects from active spells and equipment
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
creatureStats.mMagicEffects = now;
// TODO apply diff to other stats
}
MechanicsManager::MechanicsManager() MechanicsManager::MechanicsManager()
: mUpdatePlayer (true), mClassSelected (false), : mUpdatePlayer (true), mClassSelected (false),

View file

@ -31,8 +31,6 @@ namespace MWMechanics
///< build player according to stored class/race/birthsign information. Will ///< build player according to stored class/race/birthsign information. Will
/// default to the values of the ESM::NPC object, if no explicit information is given. /// default to the values of the ESM::NPC object, if no explicit information is given.
void adjustMagicEffects (MWWorld::Ptr& creature);
public: public:
MechanicsManager (); MechanicsManager ();

View file

@ -13,13 +13,7 @@ namespace MWMechanics
{ {
void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const
{ {
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin(); effects.add (spell->effects);
iter!=spell->effects.list.end(); ++iter)
{
EffectParam param;
param.mMagnitude = iter->magnMax; /// \todo calculate magnitude
effects.add (EffectKey (*iter), param);
}
} }
Spells::TIterator Spells::begin() const Spells::TIterator Spells::begin() const

View file

@ -90,7 +90,7 @@ namespace MWWorld
void clear(); void clear();
///< Empty container. ///< Empty container.
void flagAsModified(); virtual void flagAsModified();
///< \attention This function is internal to the world model and should not be called from ///< \attention This function is internal to the world model and should not be called from
/// outside. /// outside.

View file

@ -4,6 +4,12 @@
#include <iterator> #include <iterator>
#include <algorithm> #include <algorithm>
#include <components/esm/loadench.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "class.hpp" #include "class.hpp"
@ -32,7 +38,7 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots)
slots.push_back (end()); slots.push_back (end());
} }
MWWorld::InventoryStore::InventoryStore() MWWorld::InventoryStore::InventoryStore() : mMagicEffectsUpToDate (false)
{ {
initSlots (mSlots); initSlots (mSlots);
} }
@ -40,11 +46,15 @@ MWWorld::InventoryStore::InventoryStore()
MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
: ContainerStore (store) : ContainerStore (store)
{ {
mMagicEffects = store.mMagicEffects;
mMagicEffectsUpToDate = store.mMagicEffectsUpToDate;
copySlots (store); copySlots (store);
} }
MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStore& store) MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStore& store)
{ {
mMagicEffects = store.mMagicEffects;
mMagicEffectsUpToDate = store.mMagicEffectsUpToDate;
ContainerStore::operator= (store); ContainerStore::operator= (store);
mSlots.clear(); mSlots.clear();
copySlots (store); copySlots (store);
@ -201,6 +211,39 @@ void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats)
} }
} }
const MWMechanics::MagicEffects& MWWorld::InventoryStore::getMagicEffects()
{
if (!mMagicEffectsUpToDate)
{
mMagicEffects = MWMechanics::MagicEffects();
for (TSlots::const_iterator iter (mSlots.begin()); iter!=mSlots.end(); ++iter)
if (*iter!=end())
{
std::string enchantmentId = MWWorld::Class::get (**iter).getEnchantment (**iter);
if (!enchantmentId.empty())
{
const ESM::Enchantment& enchantment =
*MWBase::Environment::get().getWorld()->getStore().enchants.find (enchantmentId);
if (enchantment.data.type==ESM::Enchantment::ConstantEffect)
mMagicEffects.add (enchantment.effects);
}
}
mMagicEffectsUpToDate = true;
}
return mMagicEffects;
}
void MWWorld::InventoryStore::flagAsModified()
{
ContainerStore::flagAsModified();
mMagicEffectsUpToDate = false;
}
bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2) bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
{ {
bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2); bool canStack = MWWorld::ContainerStore::stacks(ptr1, ptr2);

View file

@ -3,6 +3,8 @@
#include "containerstore.hpp" #include "containerstore.hpp"
#include "../mwmechanics/magiceffects.hpp"
namespace MWMechanics namespace MWMechanics
{ {
struct NpcStats; struct NpcStats;
@ -41,6 +43,9 @@ namespace MWWorld
private: private:
mutable MWMechanics::MagicEffects mMagicEffects;
mutable bool mMagicEffectsUpToDate;
typedef std::vector<ContainerStoreIterator> TSlots; typedef std::vector<ContainerStoreIterator> TSlots;
mutable TSlots mSlots; mutable TSlots mSlots;
@ -65,6 +70,15 @@ namespace MWWorld
void autoEquip (const MWMechanics::NpcStats& stats); void autoEquip (const MWMechanics::NpcStats& stats);
///< Auto equip items according to stats and item value. ///< Auto equip items according to stats and item value.
const MWMechanics::MagicEffects& getMagicEffects();
///< Return magic effects from worn items.
///
/// \todo make this const again, after the constness of Ptrs and iterators has been addressed.
virtual void flagAsModified();
///< \attention This function is internal to the world model and should not be called from
/// outside.
protected: protected:
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2); virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);

View file

@ -0,0 +1,108 @@
#include "timestamp.hpp"
#include <cmath>
#include <stdexcept>
namespace MWWorld
{
TimeStamp::TimeStamp (float hour, int day)
: mHour (hour), mDay (day)
{
if (hour<0 || hour>=24 || day<0)
throw std::runtime_error ("invalid time stamp");
}
float TimeStamp::getHour() const
{
return mHour;
}
int TimeStamp::getDay() const
{
return mDay;
}
TimeStamp& TimeStamp::operator+= (double hours)
{
if (hours<0)
throw std::runtime_error ("can't move time stamp backwards in time");
hours += mHour;
mHour = static_cast<float> (std::fmod (hours, 24));
mDay += hours / 24;
return *this;
}
bool operator== (const TimeStamp& left, const TimeStamp& right)
{
return left.getHour()==right.getHour() && left.getDay()==right.getDay();
}
bool operator!= (const TimeStamp& left, const TimeStamp& right)
{
return !(left==right);
}
bool operator< (const TimeStamp& left, const TimeStamp& right)
{
if (left.getDay()<right.getDay())
return true;
if (left.getDay()>right.getDay())
return false;
return left.getHour()<right.getHour();
}
bool operator<= (const TimeStamp& left, const TimeStamp& right)
{
return left<right || left==right;
}
bool operator> (const TimeStamp& left, const TimeStamp& right)
{
return !(left<=right);
}
bool operator>= (const TimeStamp& left, const TimeStamp& right)
{
return !(left<right);
}
TimeStamp operator+ (const TimeStamp& stamp, double hours)
{
return TimeStamp (stamp) + hours;
}
TimeStamp operator+ (double hours, const TimeStamp& stamp)
{
return TimeStamp (stamp) + hours;
}
double operator- (const TimeStamp& left, const TimeStamp& right)
{
if (left<right)
return -(right-left);
int days = left.getDay() - right.getDay();
double hours = 0;
if (left.getHour()<right.getHour())
{
hours = 24-right.getHour()+left.getHour();
++days;
}
else
{
hours = left.getHour()-right.getHour();
}
return hours + 24*days;
}
}

View file

@ -0,0 +1,44 @@
#ifndef GAME_MWWORLD_TIMESTAMP_H
#define GAME_MWWORLD_TIMESTAMP_H
namespace MWWorld
{
/// \brief In-game time stamp
///
/// This class is based on the global variables GameHour and DaysPassed.
class TimeStamp
{
float mHour;
int mDay;
public:
explicit TimeStamp (float hour = 0, int day = 0);
///< \oaram hour [0, 23)
/// \param day >=0
float getHour() const;
int getDay() const;
TimeStamp& operator+= (double hours);
///< \param hours >=0
};
bool operator== (const TimeStamp& left, const TimeStamp& right);
bool operator!= (const TimeStamp& left, const TimeStamp& right);
bool operator< (const TimeStamp& left, const TimeStamp& right);
bool operator<= (const TimeStamp& left, const TimeStamp& right);
bool operator> (const TimeStamp& left, const TimeStamp& right);
bool operator>= (const TimeStamp& left, const TimeStamp& right);
TimeStamp operator+ (const TimeStamp& stamp, double hours);
TimeStamp operator+ (double hours, const TimeStamp& stamp);
double operator- (const TimeStamp& left, const TimeStamp& right);
///< Returns the difference between \a left and \a right in in-game hours.
}
#endif

View file

@ -471,6 +471,12 @@ namespace MWWorld
mRendering->skySetDate (mGlobalVariables->getInt ("day"), month); mRendering->skySetDate (mGlobalVariables->getInt ("day"), month);
} }
TimeStamp World::getTimeStamp() const
{
return TimeStamp (mGlobalVariables->getFloat ("gamehour"),
mGlobalVariables->getInt ("dayspassed"));
}
bool World::toggleSky() bool World::toggleSky()
{ {
if (mSky) if (mSky)

View file

@ -18,6 +18,7 @@
#include "physicssystem.hpp" #include "physicssystem.hpp"
#include "cells.hpp" #include "cells.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
#include "timestamp.hpp"
#include <openengine/bullet/physic.hpp> #include <openengine/bullet/physic.hpp>
#include <openengine/ogre/fader.hpp> #include <openengine/ogre/fader.hpp>
@ -185,6 +186,9 @@ namespace MWWorld
void setDay (int day); void setDay (int day);
///< Set in-game time day. ///< Set in-game time day.
TimeStamp getTimeStamp() const;
///< Return current in-game time stamp.
bool toggleSky(); bool toggleSky();
///< \return Resulting mode ///< \return Resulting mode