1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 20:45:33 +00:00

Merge remote-tracking branch 'scrawl/spells'

This commit is contained in:
Marc Zinnschlag 2015-11-27 10:21:17 +01:00
commit b3532b6274
9 changed files with 102 additions and 93 deletions

View file

@ -95,8 +95,7 @@ namespace MWGui
for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter) for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter)
{ {
const ESM::Spell* spell = const ESM::Spell* spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType!=ESM::Spell::ST_Spell) if (spell->mData.mType!=ESM::Spell::ST_Spell)
continue; // don't try to sell diseases, curses or powers continue; // don't try to sell diseases, curses or powers
@ -110,10 +109,10 @@ namespace MWGui
continue; continue;
} }
if (playerHasSpell(iter->first)) if (playerHasSpell(iter->first->mId))
continue; continue;
addSpell (iter->first); addSpell (iter->first->mId);
} }
updateLabels(); updateLabels();

View file

@ -516,8 +516,7 @@ namespace MWGui
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{ {
const ESM::Spell* spell = const ESM::Spell* spell = it->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (it->first);
// only normal spells count // only normal spells count
if (spell->mData.mType != ESM::Spell::ST_Spell) if (spell->mData.mType != ESM::Spell::ST_Spell)

View file

@ -52,7 +52,7 @@ namespace MWGui
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{ {
const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(it->first); const ESM::Spell* spell = it->first;
if (spell->mData.mType != ESM::Spell::ST_Power && spell->mData.mType != ESM::Spell::ST_Spell) if (spell->mData.mType != ESM::Spell::ST_Power && spell->mData.mType != ESM::Spell::ST_Spell)
continue; continue;
@ -67,9 +67,9 @@ namespace MWGui
} }
else else
newSpell.mType = Spell::Type_Power; newSpell.mType = Spell::Type_Power;
newSpell.mId = it->first; newSpell.mId = spell->mId;
newSpell.mSelected = (MWBase::Environment::get().getWindowManager()->getSelectedSpell() == it->first); newSpell.mSelected = (MWBase::Environment::get().getWindowManager()->getSelectedSpell() == spell->mId);
newSpell.mActive = true; newSpell.mActive = true;
mSpells.push_back(newSpell); mSpells.push_back(newSpell);
} }

View file

@ -541,7 +541,7 @@ namespace MWMechanics
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{ {
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(it->first); const ESM::Spell* spell = it->first;
float rating = rateSpell(spell, actor, target); float rating = rateSpell(spell, actor, target);
if (rating > bestActionRating) if (rating > bestActionRating)

View file

@ -34,8 +34,7 @@ namespace MWMechanics
Spells& spells = carrier.getClass().getCreatureStats(carrier).getSpells(); Spells& spells = carrier.getClass().getCreatureStats(carrier).getSpells();
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{ {
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(it->first); const ESM::Spell* spell = it->first;
if (actor.getClass().getCreatureStats(actor).getSpells().hasSpell(spell->mId)) if (actor.getClass().getCreatureStats(actor).getSpells().hasSpell(spell->mId))
continue; continue;

View file

@ -124,7 +124,7 @@ namespace MWMechanics
} }
if (spell->mData.mType == ESM::Spell::ST_Power) if (spell->mData.mType == ESM::Spell::ST_Power)
return stats.getSpells().canUsePower(spell->mId) ? 100 : 0; return stats.getSpells().canUsePower(spell) ? 100 : 0;
if (spell->mData.mType != ESM::Spell::ST_Spell) if (spell->mData.mType != ESM::Spell::ST_Spell)
return 100; return 100;
@ -823,7 +823,7 @@ namespace MWMechanics
// A power can be used once per 24h // A power can be used once per 24h
if (spell->mData.mType == ESM::Spell::ST_Power) if (spell->mData.mType == ESM::Spell::ST_Power)
stats.getSpells().usePower(spell->mId); stats.getSpells().usePower(spell);
} }
if (mCaster == getPlayer() && spellIncreasesSkill(spell)) if (mCaster == getPlayer() && spellIncreasesSkill(spell))

View file

@ -25,9 +25,24 @@ namespace MWMechanics
return mSpells.end(); return mSpells.end();
} }
const ESM::Spell* Spells::getSpell(const std::string& id) const
{
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(id);
}
bool Spells::hasSpell(const std::string &spell) const
{
return hasSpell(getSpell(spell));
}
bool Spells::hasSpell(const ESM::Spell *spell) const
{
return mSpells.find(spell) != mSpells.end();
}
void Spells::add (const ESM::Spell* spell) void Spells::add (const ESM::Spell* spell)
{ {
if (mSpells.find (spell->mId)==mSpells.end()) if (mSpells.find (spell)==mSpells.end())
{ {
std::map<const int, float> random; std::map<const int, float> random;
@ -48,32 +63,32 @@ namespace MWMechanics
corprus.mWorsenings = 0; corprus.mWorsenings = 0;
corprus.mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod; corprus.mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod;
mCorprusSpells[spell->mId] = corprus; mCorprusSpells[spell] = corprus;
} }
mSpells.insert (std::make_pair (spell->mId, random)); mSpells.insert (std::make_pair (spell, random));
} }
} }
void Spells::add (const std::string& spellId) void Spells::add (const std::string& spellId)
{ {
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId); add(getSpell(spellId));
add(spell);
} }
void Spells::remove (const std::string& spellId) void Spells::remove (const std::string& spellId)
{ {
std::string lower = Misc::StringUtils::lowerCase(spellId); const ESM::Spell* spell = getSpell(spellId);
TContainer::iterator iter = mSpells.find (lower); TContainer::iterator iter = mSpells.find (spell);
std::map<std::string, CorprusStats>::iterator corprusIt = mCorprusSpells.find(lower);
std::map<SpellKey, CorprusStats>::iterator corprusIt = mCorprusSpells.find(spell);
// if it's corprus, remove negative and keep positive effects // if it's corprus, remove negative and keep positive effects
if (corprusIt != mCorprusSpells.end()) if (corprusIt != mCorprusSpells.end())
{ {
worsenCorprus(lower); worsenCorprus(spell);
if (mPermanentSpellEffects.find(lower) != mPermanentSpellEffects.end()) if (mPermanentSpellEffects.find(spell) != mPermanentSpellEffects.end())
{ {
MagicEffects & effects = mPermanentSpellEffects[lower]; MagicEffects & effects = mPermanentSpellEffects[spell];
for (MagicEffects::Collection::const_iterator effectIt = effects.begin(); effectIt != effects.end();) for (MagicEffects::Collection::const_iterator effectIt = effects.begin(); effectIt != effects.end();)
{ {
const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->first.mId); const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->first.mId);
@ -101,8 +116,7 @@ namespace MWMechanics
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight || 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) spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse)
@ -120,7 +134,7 @@ namespace MWMechanics
} }
} }
for (std::map<std::string, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it) for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it)
{ {
effects += it->second; effects += it->second;
} }
@ -145,11 +159,10 @@ namespace MWMechanics
bool Spells::isSpellActive(const std::string &id) const bool Spells::isSpellActive(const std::string &id) const
{ {
TContainer::const_iterator found = mSpells.find(id); TContainer::const_iterator found = mSpells.find(getSpell(id));
if (found != mSpells.end()) if (found != mSpells.end())
{ {
const ESM::Spell *spell = const ESM::Spell *spell = found->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (id);
return (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight || return (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); spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse);
@ -161,9 +174,7 @@ namespace MWMechanics
{ {
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType == ESM::Spell::ST_Disease) if (spell->mData.mType == ESM::Spell::ST_Disease)
return true; return true;
} }
@ -175,9 +186,7 @@ namespace MWMechanics
{ {
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType == ESM::Spell::ST_Blight) if (spell->mData.mType == ESM::Spell::ST_Blight)
return true; return true;
} }
@ -189,9 +198,7 @@ namespace MWMechanics
{ {
for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType == ESM::Spell::ST_Disease) if (spell->mData.mType == ESM::Spell::ST_Disease)
mSpells.erase(iter++); mSpells.erase(iter++);
else else
@ -203,9 +210,7 @@ namespace MWMechanics
{ {
for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell)) if (spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell))
mSpells.erase(iter++); mSpells.erase(iter++);
else else
@ -217,9 +222,7 @@ namespace MWMechanics
{ {
for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (hasCorprusEffect(spell)) if (hasCorprusEffect(spell))
mSpells.erase(iter++); mSpells.erase(iter++);
else else
@ -231,9 +234,7 @@ namespace MWMechanics
{ {
for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();)
{ {
const ESM::Spell *spell = const ESM::Spell *spell = iter->first;
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
if (spell->mData.mType == ESM::Spell::ST_Curse) if (spell->mData.mType == ESM::Spell::ST_Curse)
mSpells.erase(iter++); mSpells.erase(iter++);
else else
@ -245,7 +246,7 @@ namespace MWMechanics
{ {
for (TIterator it = begin(); it != end(); ++it) for (TIterator it = begin(); it != end(); ++it)
{ {
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(it->first); const ESM::Spell* spell = it->first;
// these are the spell types that are permanently in effect // these are the spell types that are permanently in effect
if (!(spell->mData.mType == ESM::Spell::ST_Ability) if (!(spell->mData.mType == ESM::Spell::ST_Ability)
@ -268,14 +269,13 @@ namespace MWMechanics
} }
} }
void Spells::worsenCorprus(const std::string &corpSpellId) void Spells::worsenCorprus(const ESM::Spell* spell)
{ {
mCorprusSpells[corpSpellId].mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod; mCorprusSpells[spell].mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod;
mCorprusSpells[corpSpellId].mWorsenings++; mCorprusSpells[spell].mWorsenings++;
// update worsened effects // update worsened effects
mPermanentSpellEffects[corpSpellId] = MagicEffects(); mPermanentSpellEffects[spell] = MagicEffects();
const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(corpSpellId);
int i=0; int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt, ++i) for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt, ++i)
{ {
@ -283,12 +283,12 @@ namespace MWMechanics
if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE
{ {
float random = 1.f; float random = 1.f;
if (mSpells[corpSpellId].find(i) != mSpells[corpSpellId].end()) if (mSpells[spell].find(i) != mSpells[spell].end())
random = mSpells[corpSpellId].at(i); random = mSpells[spell].at(i);
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random; float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
magnitude *= std::max(1, mCorprusSpells[corpSpellId].mWorsenings); magnitude *= std::max(1, mCorprusSpells[spell].mWorsenings);
mPermanentSpellEffects[corpSpellId].add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(magnitude)); mPermanentSpellEffects[spell].add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(magnitude));
} }
} }
} }
@ -305,43 +305,47 @@ namespace MWMechanics
return false; return false;
} }
const std::map<std::string, Spells::CorprusStats> &Spells::getCorprusSpells() const const std::map<Spells::SpellKey, Spells::CorprusStats> &Spells::getCorprusSpells() const
{ {
return mCorprusSpells; return mCorprusSpells;
} }
bool Spells::canUsePower(const std::string &power) const bool Spells::canUsePower(const ESM::Spell* spell) const
{ {
std::map<std::string, MWWorld::TimeStamp>::const_iterator it = mUsedPowers.find(Misc::StringUtils::lowerCase(power)); std::map<SpellKey, MWWorld::TimeStamp>::const_iterator it = mUsedPowers.find(spell);
if (it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp()) if (it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp())
return true; return true;
else else
return false; return false;
} }
void Spells::usePower(const std::string &power) void Spells::usePower(const ESM::Spell* spell)
{ {
mUsedPowers[Misc::StringUtils::lowerCase(power)] = MWBase::Environment::get().getWorld()->getTimeStamp(); mUsedPowers[spell] = MWBase::Environment::get().getWorld()->getTimeStamp();
} }
void Spells::readState(const ESM::SpellState &state) void Spells::readState(const ESM::SpellState &state)
{ {
for (TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it) for (ESM::SpellState::TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it)
{ {
// Discard spells that are no longer available due to changed content files // Discard spells that are no longer available due to changed content files
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first); const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
if (spell) if (spell)
{ {
mSpells[it->first] = it->second; mSpells[spell] = it->second;
if (it->first == state.mSelectedSpell) if (it->first == state.mSelectedSpell)
mSelectedSpell = it->first; mSelectedSpell = it->first;
} }
} }
// No need to discard spells here (doesn't really matter if non existent ids are kept)
for (std::map<std::string, ESM::TimeStamp>::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it) for (std::map<std::string, ESM::TimeStamp>::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it)
mUsedPowers[it->first] = MWWorld::TimeStamp(it->second); {
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
if (!spell)
continue;
mUsedPowers[spell] = MWWorld::TimeStamp(it->second);
}
for (std::map<std::string, std::vector<ESM::SpellState::PermanentSpellEffectInfo> >::const_iterator it = for (std::map<std::string, std::vector<ESM::SpellState::PermanentSpellEffectInfo> >::const_iterator it =
state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it) state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it)
@ -350,33 +354,35 @@ namespace MWMechanics
if (!spell) if (!spell)
continue; continue;
mPermanentSpellEffects[it->first] = MagicEffects(); mPermanentSpellEffects[spell] = MagicEffects();
for (std::vector<ESM::SpellState::PermanentSpellEffectInfo>::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) for (std::vector<ESM::SpellState::PermanentSpellEffectInfo>::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt)
{ {
mPermanentSpellEffects[it->first].add(EffectKey(effectIt->mId, effectIt->mArg), effectIt->mMagnitude); mPermanentSpellEffects[spell].add(EffectKey(effectIt->mId, effectIt->mArg), effectIt->mMagnitude);
} }
} }
mCorprusSpells.clear(); mCorprusSpells.clear();
for (std::map<std::string, ESM::SpellState::CorprusStats>::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it) for (std::map<std::string, ESM::SpellState::CorprusStats>::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it)
{ {
if (mSpells.find(it->first) != mSpells.end()) // Discard unavailable corprus spells const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
{ if (!spell) // Discard unavailable corprus spells
mCorprusSpells[it->first].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings; continue;
mCorprusSpells[it->first].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening); mCorprusSpells[spell].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings;
} mCorprusSpells[spell].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening);
} }
} }
void Spells::writeState(ESM::SpellState &state) const void Spells::writeState(ESM::SpellState &state) const
{ {
state.mSpells = mSpells; for (TContainer::const_iterator it = mSpells.begin(); it != mSpells.end(); ++it)
state.mSpells.insert(std::make_pair(it->first->mId, it->second));
state.mSelectedSpell = mSelectedSpell; state.mSelectedSpell = mSelectedSpell;
for (std::map<std::string, MWWorld::TimeStamp>::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it) for (std::map<SpellKey, MWWorld::TimeStamp>::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it)
state.mUsedPowers[it->first] = it->second.toEsm(); state.mUsedPowers[it->first->mId] = it->second.toEsm();
for (std::map<std::string, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it) for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it)
{ {
std::vector<ESM::SpellState::PermanentSpellEffectInfo> effectList; std::vector<ESM::SpellState::PermanentSpellEffectInfo> effectList;
for (MagicEffects::Collection::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) for (MagicEffects::Collection::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt)
@ -388,13 +394,13 @@ namespace MWMechanics
effectList.push_back(info); effectList.push_back(info);
} }
state.mPermanentSpellEffects[it->first] = effectList; state.mPermanentSpellEffects[it->first->mId] = effectList;
} }
for (std::map<std::string, CorprusStats>::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) for (std::map<SpellKey, CorprusStats>::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it)
{ {
state.mCorprusSpells[it->first].mWorsenings = mCorprusSpells.at(it->first).mWorsenings; state.mCorprusSpells[it->first->mId].mWorsenings = mCorprusSpells.at(it->first).mWorsenings;
state.mCorprusSpells[it->first].mNextWorsening = mCorprusSpells.at(it->first).mNextWorsening.toEsm(); state.mCorprusSpells[it->first->mId].mNextWorsening = mCorprusSpells.at(it->first).mNextWorsening.toEsm();
} }
} }
} }

View file

@ -31,7 +31,9 @@ namespace MWMechanics
{ {
public: public:
typedef std::map<std::string, std::map<const int, float> > TContainer; // ID, <effect index, normalised random magnitude> typedef const ESM::Spell* SpellKey;
typedef std::map<SpellKey, std::map<const int, float> > TContainer; // ID, <effect index, normalised random magnitude>
typedef TContainer::const_iterator TIterator; typedef TContainer::const_iterator TIterator;
struct CorprusStats struct CorprusStats
@ -47,23 +49,26 @@ namespace MWMechanics
TContainer mSpells; TContainer mSpells;
// spell-tied effects that will be applied even after removing the spell (currently used to keep positive effects when corprus is removed) // spell-tied effects that will be applied even after removing the spell (currently used to keep positive effects when corprus is removed)
std::map<std::string, MagicEffects> mPermanentSpellEffects; std::map<SpellKey, MagicEffects> mPermanentSpellEffects;
// Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different) // Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different)
std::string mSelectedSpell; std::string mSelectedSpell;
std::map<std::string, MWWorld::TimeStamp> mUsedPowers; std::map<SpellKey, MWWorld::TimeStamp> mUsedPowers;
std::map<std::string, CorprusStats> mCorprusSpells; std::map<SpellKey, CorprusStats> mCorprusSpells;
/// Get spell from ID, throws exception if not found
const ESM::Spell* getSpell(const std::string& id) const;
public: public:
void worsenCorprus(const std::string &corpSpellId); void worsenCorprus(const ESM::Spell* spell);
static bool hasCorprusEffect(const ESM::Spell *spell); static bool hasCorprusEffect(const ESM::Spell *spell);
const std::map<std::string, CorprusStats> & getCorprusSpells() const; const std::map<SpellKey, CorprusStats> & getCorprusSpells() const;
bool canUsePower (const std::string& power) const; bool canUsePower (const ESM::Spell* spell) const;
void usePower (const std::string& power); void usePower (const ESM::Spell* spell);
void purgeCommonDisease(); void purgeCommonDisease();
void purgeBlightDisease(); void purgeBlightDisease();
@ -74,7 +79,8 @@ namespace MWMechanics
TIterator end() const; TIterator end() const;
bool hasSpell(const std::string& spell) const { return mSpells.find(Misc::StringUtils::lowerCase(spell)) != mSpells.end(); } bool hasSpell(const std::string& spell) const;
bool hasSpell(const ESM::Spell* spell) const;
void add (const std::string& spell); void add (const std::string& spell);
///< Adding a spell that is already listed in *this is a no-op. ///< Adding a spell that is already listed in *this is a no-op.

View file

@ -2581,7 +2581,7 @@ namespace MWWorld
} }
// If this is a power, check if it was already used in the last 24h // If this is a power, check if it was already used in the last 24h
if (!fail && spell->mData.mType == ESM::Spell::ST_Power && !stats.getSpells().canUsePower(spell->mId)) if (!fail && spell->mData.mType == ESM::Spell::ST_Power && !stats.getSpells().canUsePower(spell))
{ {
message = "#{sPowerAlreadyUsed}"; message = "#{sPowerAlreadyUsed}";
fail = true; fail = true;