Cache magic effects in MWMechanics::Spells

pull/1/head
MiroslavR 9 years ago
parent 700dde116e
commit c8b61cb234

@ -15,6 +15,11 @@
namespace MWMechanics
{
Spells::Spells()
: mSpellsChanged(false)
{
}
Spells::TIterator Spells::begin() const
{
return mSpells.begin();
@ -30,6 +35,44 @@ namespace MWMechanics
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(id);
}
void Spells::rebuildEffects() const
{
mEffects = MagicEffects();
mSourcedEffects.clear();
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{
const ESM::Spell *spell = iter->first;
if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight ||
spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse)
{
int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it)
{
if (iter->second.mPurgedEffects.find(i) != iter->second.mPurgedEffects.end())
continue; // effect was purged
float random = 1.f;
if (iter->second.mEffectRands.find(i) != iter->second.mEffectRands.end())
random = iter->second.mEffectRands.at(i);
float magnitude = it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random;
mEffects.add (*it, magnitude);
mSourcedEffects[spell].add(MWMechanics::EffectKey(*it), magnitude);
++i;
}
}
}
for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it)
{
mEffects += it->second;
mSourcedEffects[it->first] += it->second;
}
}
bool Spells::hasSpell(const std::string &spell) const
{
return hasSpell(getSpell(spell));
@ -69,6 +112,7 @@ namespace MWMechanics
SpellParams params;
params.mEffectRands = random;
mSpells.insert (std::make_pair (spell, params));
mSpellsChanged = true;
}
}
@ -104,7 +148,10 @@ namespace MWMechanics
}
if (iter!=mSpells.end())
{
mSpells.erase (iter);
mSpellsChanged = true;
}
if (spellId==mSelectedSpell)
mSelectedSpell.clear();
@ -112,44 +159,17 @@ namespace MWMechanics
MagicEffects Spells::getMagicEffects() const
{
// TODO: These are recalculated every frame, no need to do that
MagicEffects effects;
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{
const ESM::Spell *spell = iter->first;
if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight ||
spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse)
{
int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it)
{
if (iter->second.mPurgedEffects.find(i) != iter->second.mPurgedEffects.end())
continue; // effect was purged
float random = 1.f;
if (iter->second.mEffectRands.find(i) != iter->second.mEffectRands.end())
random = iter->second.mEffectRands.at(i);
effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random);
++i;
}
}
}
for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it)
{
effects += it->second;
if (mSpellsChanged) {
rebuildEffects();
mSpellsChanged = false;
}
return effects;
return mEffects;
}
void Spells::clear()
{
mSpells.clear();
mSpellsChanged = true;
}
void Spells::setSelectedSpell (const std::string& spellId)
@ -205,7 +225,10 @@ namespace MWMechanics
{
const ESM::Spell *spell = iter->first;
if (spell->mData.mType == ESM::Spell::ST_Disease)
{
mSpells.erase(iter++);
mSpellsChanged = true;
}
else
++iter;
}
@ -217,7 +240,10 @@ namespace MWMechanics
{
const ESM::Spell *spell = iter->first;
if (spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell))
{
mSpells.erase(iter++);
mSpellsChanged = true;
}
else
++iter;
}
@ -229,7 +255,10 @@ namespace MWMechanics
{
const ESM::Spell *spell = iter->first;
if (hasCorprusEffect(spell))
{
mSpells.erase(iter++);
mSpellsChanged = true;
}
else
++iter;
}
@ -241,7 +270,10 @@ namespace MWMechanics
{
const ESM::Spell *spell = iter->first;
if (spell->mData.mType == ESM::Spell::ST_Curse)
{
mSpells.erase(iter++);
mSpellsChanged = true;
}
else
++iter;
}
@ -249,45 +281,13 @@ namespace MWMechanics
void Spells::visitEffectSources(EffectSourceVisitor &visitor) const
{
// needed to combine effects from mSpells and mPermanentSpellEffects,
// while still grouping them by their source spell
std::map<SpellKey, MagicEffects> combinedEffects;
for (TIterator it = begin(); it != end(); ++it)
{
const ESM::Spell* spell = it->first;
// these are the spell types that are permanently in effect
if (!(spell->mData.mType == ESM::Spell::ST_Ability)
&& !(spell->mData.mType == ESM::Spell::ST_Disease)
&& !(spell->mData.mType == ESM::Spell::ST_Curse)
&& !(spell->mData.mType == ESM::Spell::ST_Blight))
continue;
const ESM::EffectList& list = spell->mEffects;
int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = list.mList.begin();
effectIt != list.mList.end(); ++effectIt, ++i)
{
if (it->second.mPurgedEffects.find(i) != it->second.mPurgedEffects.end())
continue; // effect was purged
float random = 1.f;
if (it->second.mEffectRands.find(i) != it->second.mEffectRands.end())
random = it->second.mEffectRands.at(i);
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
combinedEffects[spell].add(MWMechanics::EffectKey(*effectIt), magnitude);
}
}
for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin();
it != mPermanentSpellEffects.end(); ++it)
{
combinedEffects[it->first] += it->second;
if (mSpellsChanged) {
rebuildEffects();
mSpellsChanged = false;
}
for (std::map<SpellKey, MagicEffects>::const_iterator it = combinedEffects.begin();
it != combinedEffects.end(); ++it)
for (std::map<SpellKey, MagicEffects>::const_iterator it = mSourcedEffects.begin();
it != mSourcedEffects.end(); ++it)
{
const ESM::Spell * spell = it->first;
for (MagicEffects::Collection::const_iterator effectIt = it->second.begin();
@ -318,6 +318,7 @@ namespace MWMechanics
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
magnitude *= std::max(1, mCorprusSpells[spell].mWorsenings);
mPermanentSpellEffects[spell].add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(magnitude));
mSpellsChanged = true;
}
}
}
@ -347,7 +348,10 @@ namespace MWMechanics
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spellIt->first->mEffects.mList.begin(); effectIt != spellIt->first->mEffects.mList.end(); ++effectIt)
{
if (effectIt->mEffectID == effectId)
{
spellIt->second.mPurgedEffects.insert(i);
mSpellsChanged = true;
}
++i;
}
}
@ -364,7 +368,10 @@ namespace MWMechanics
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spellIt->first->mEffects.mList.begin(); effectIt != spellIt->first->mEffects.mList.end(); ++effectIt)
{
if (effectIt->mEffectID == effectId)
{
spellIt->second.mPurgedEffects.insert(i);
mSpellsChanged = true;
}
++i;
}
}
@ -430,6 +437,8 @@ namespace MWMechanics
mCorprusSpells[spell].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings;
mCorprusSpells[spell].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening);
}
mSpellsChanged = true;
}
void Spells::writeState(ESM::SpellState &state) const

@ -50,7 +50,6 @@ namespace MWMechanics
};
private:
TContainer mSpells;
// spell-tied effects that will be applied even after removing the spell (currently used to keep positive effects when corprus is removed)
@ -63,10 +62,16 @@ namespace MWMechanics
std::map<SpellKey, CorprusStats> mCorprusSpells;
mutable bool mSpellsChanged;
mutable MagicEffects mEffects;
mutable std::map<SpellKey, MagicEffects> mSourcedEffects;
void rebuildEffects() const;
/// Get spell from ID, throws exception if not found
const ESM::Spell* getSpell(const std::string& id) const;
public:
Spells();
void worsenCorprus(const ESM::Spell* spell);
static bool hasCorprusEffect(const ESM::Spell *spell);

Loading…
Cancel
Save