1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-15 21:49:56 +00:00
openmw-tes3mp/apps/openmw/mwmechanics/activespells.cpp

193 lines
5.6 KiB
C++
Raw Normal View History

#include "activespells.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWMechanics
{
void ActiveSpells::update() const
{
bool rebuild = false;
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
// Erase no longer active spells
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)
rebuildEffects();
}
void ActiveSpells::rebuildEffects() const
{
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
mEffects = MagicEffects();
for (TIterator iter (begin()); iter!=end(); ++iter)
{
const MWWorld::TimeStamp& start = iter->second.mTimeStamp;
const std::vector<Effect>& effects = iter->second.mEffects;
for (std::vector<Effect>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt)
{
int duration = effectIt->mDuration;
MWWorld::TimeStamp end = start;
end += static_cast<double> (duration)*
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
if (end>now)
mEffects.add(effectIt->mKey, MWMechanics::EffectParam(effectIt->mMagnitude));
}
}
}
ActiveSpells::ActiveSpells()
: mSpellsChanged (false)
, mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp())
{}
const MagicEffects& ActiveSpells::getMagicEffects() const
{
update();
return mEffects;
}
ActiveSpells::TIterator ActiveSpells::begin() const
{
return mSpells.begin();
}
ActiveSpells::TIterator ActiveSpells::end() const
{
return mSpells.end();
}
double ActiveSpells::timeToExpire (const TIterator& iterator) const
{
const std::vector<Effect>& effects = iterator->second.mEffects;
int duration = 0;
for (std::vector<Effect>::const_iterator iter (effects.begin());
iter!=effects.end(); ++iter)
{
2012-09-17 07:37:50 +00:00
if (iter->mDuration > duration)
duration = iter->mDuration;
}
double scaledDuration = duration *
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
double usedUp = MWBase::Environment::get().getWorld()->getTimeStamp() - iterator->second.mTimeStamp;
if (usedUp>=scaledDuration)
return 0;
return scaledDuration-usedUp;
}
2012-11-25 00:26:29 +00:00
bool ActiveSpells::isSpellActive(std::string id) const
{
2013-01-09 19:51:52 +00:00
Misc::StringUtils::toLower(id);
2012-11-25 00:26:29 +00:00
for (TContainer::iterator iter = mSpells.begin(); iter != mSpells.end(); ++iter)
{
std::string left = iter->first;
2013-01-09 19:51:52 +00:00
Misc::StringUtils::toLower(left);
2012-11-25 00:26:29 +00:00
if (iter->first == id)
return true;
}
return false;
}
2013-03-03 11:01:19 +00:00
const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const
{
return mSpells;
}
void ActiveSpells::addSpell(const std::string &id, bool stack, std::vector<Effect> effects, const std::string &displayName)
{
bool exists = false;
for (TContainer::const_iterator it = begin(); it != end(); ++it)
{
if (id == it->first)
exists = true;
}
ActiveSpellParams params;
params.mTimeStamp = MWBase::Environment::get().getWorld()->getTimeStamp();
params.mEffects = effects;
params.mDisplayName = displayName;
if (!exists || stack)
mSpells.insert (std::make_pair(id, params));
else
mSpells.find(id)->second = params;
mSpellsChanged = true;
}
void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const
{
for (TContainer::const_iterator it = begin(); it != end(); ++it)
{
float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor();
for (std::vector<Effect>::const_iterator effectIt = it->second.mEffects.begin();
effectIt != it->second.mEffects.end(); ++effectIt)
{
std::string name = it->second.mDisplayName;
float remainingTime = effectIt->mDuration +
(it->second.mTimeStamp - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale;
float magnitude = effectIt->mMagnitude;
if (magnitude)
visitor.visit(effectIt->mKey, name, magnitude, remainingTime);
}
}
}
void ActiveSpells::purgeAll()
{
mSpells.clear();
}
void ActiveSpells::purgeEffect(short effectId)
{
for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it)
{
for (std::vector<Effect>::iterator effectIt = it->second.mEffects.begin();
effectIt != it->second.mEffects.end();)
{
if (effectIt->mKey.mId == effectId)
effectIt = it->second.mEffects.erase(effectIt);
else
effectIt++;
}
}
}
}