From 3722c7adc3095fedc25946955c2f97597d25a6c9 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Mon, 18 Aug 2014 15:33:12 +0200 Subject: [PATCH 1/5] Initial work on implementing corprus worsening effect --- apps/openmw/mwmechanics/actors.cpp | 19 +++++++++++++++ apps/openmw/mwmechanics/spells.cpp | 39 +++++++++++++++++++++++++++++- apps/openmw/mwmechanics/spells.hpp | 12 +++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index fbc840df8..6e11caee7 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -477,6 +477,25 @@ namespace MWMechanics creatureStats.setAttribute(i, stat); } + { + Spells & spells = creatureStats.getSpells(); + for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) + { + if (spells.mCorprusSpells.find(it->first) != spells.mCorprusSpells.end()) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(it->first); + + if (MWBase::Environment::get().getWorld()->getTimeStamp() >= spells.mCorprusSpells[it->first].mNextWorsening) + { + spells.worsenCorprus(it->first); + + if (ptr.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCorprusWorsens}"); + } + } + } + } + // dynamic stats for(int i = 0;i < 3;++i) { diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index dee1a1b05..da4fa6556 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -44,6 +44,25 @@ namespace MWMechanics } } + bool hasCorprusEffect = false; + for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + { + if (effectIt->mEffectID == ESM::MagicEffect::Corprus) + { + hasCorprusEffect = true; + break; + } + } + + if (hasCorprusEffect) + { + CorprusStats corprus; + corprus.mWorsenings = 0; + corprus.mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod; + + mCorprusSpells[spellId] = corprus; + } + mSpells.insert (std::make_pair (Misc::StringUtils::lowerCase(spellId), random)); } } @@ -52,10 +71,14 @@ namespace MWMechanics { std::string lower = Misc::StringUtils::lowerCase(spellId); TContainer::iterator iter = mSpells.find (lower); + std::map::iterator corprusIt = mCorprusSpells.find(lower); if (iter!=mSpells.end()) mSpells.erase (iter); + if (corprusIt != mCorprusSpells.end()) + mCorprusSpells.erase(corprusIt); + if (spellId==mSelectedSpell) mSelectedSpell.clear(); } @@ -81,7 +104,15 @@ namespace MWMechanics if (iter->second.find(i) != iter->second.end()) random = iter->second.at(i); - effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random); + int applyTimes = 1; + if (mCorprusSpells.find(spell->mId) != mCorprusSpells.end()) + { + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(spell->mEffects.mList.front().mEffectID); + if ((it->mEffectID != ESM::MagicEffect::Corprus) && (effect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE + applyTimes += mCorprusSpells.at(spell->mId).mWorsenings; + } + for (int j = 0; j < applyTimes; j++) + effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random); ++i; } } @@ -216,6 +247,12 @@ namespace MWMechanics } } + void Spells::worsenCorprus(const std::string &corpSpellId) + { + mCorprusSpells[corpSpellId].mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod; + mCorprusSpells[corpSpellId].mWorsenings++; + } + bool Spells::canUsePower(const std::string &power) const { std::map::const_iterator it = mUsedPowers.find(power); diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 6997a9d7a..039ad57fa 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -44,6 +44,18 @@ namespace MWMechanics std::map mUsedPowers; + public: + struct CorprusStats + { + static const int sWorseningPeriod = 24; + + int mWorsenings; + MWWorld::TimeStamp mNextWorsening; + }; + + std::map mCorprusSpells; + void worsenCorprus(const std::string &corpSpellId); + public: bool canUsePower (const std::string& power) const; From 96e7ff666dd4ca1eb7c3d067a103aaac764f840f Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Tue, 19 Aug 2014 03:17:31 +0200 Subject: [PATCH 2/5] Implement saving/loading of corprus stats, remove redundant code --- apps/openmw/mwmechanics/actors.cpp | 2 -- apps/openmw/mwmechanics/spells.cpp | 48 ++++++++++++++++++++---------- apps/openmw/mwmechanics/spells.hpp | 2 ++ components/esm/spellstate.cpp | 20 +++++++++++++ components/esm/spellstate.hpp | 8 +++++ 5 files changed, 63 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 6e11caee7..e1d738078 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -483,8 +483,6 @@ namespace MWMechanics { if (spells.mCorprusSpells.find(it->first) != spells.mCorprusSpells.end()) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(it->first); - if (MWBase::Environment::get().getWorld()->getTimeStamp() >= spells.mCorprusSpells[it->first].mNextWorsening) { spells.worsenCorprus(it->first); diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index da4fa6556..b16fc0aa6 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -44,17 +44,7 @@ namespace MWMechanics } } - bool hasCorprusEffect = false; - for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) - { - if (effectIt->mEffectID == ESM::MagicEffect::Corprus) - { - hasCorprusEffect = true; - break; - } - } - - if (hasCorprusEffect) + if (hasCorprusEffect(spell)) { CorprusStats corprus; corprus.mWorsenings = 0; @@ -104,15 +94,15 @@ namespace MWMechanics if (iter->second.find(i) != iter->second.end()) random = iter->second.at(i); - int applyTimes = 1; + int magnMult = 1; if (mCorprusSpells.find(spell->mId) != mCorprusSpells.end()) { const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(spell->mEffects.mList.front().mEffectID); if ((it->mEffectID != ESM::MagicEffect::Corprus) && (effect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE - applyTimes += mCorprusSpells.at(spell->mId).mWorsenings; + magnMult += mCorprusSpells.at(spell->mId).mWorsenings; } - for (int j = 0; j < applyTimes; j++) - effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random); + + effects.add (*it, (it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random) * magnMult); ++i; } } @@ -253,6 +243,18 @@ namespace MWMechanics mCorprusSpells[corpSpellId].mWorsenings++; } + bool Spells::hasCorprusEffect(const ESM::Spell *spell) + { + for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + { + if (effectIt->mEffectID == ESM::MagicEffect::Corprus) + { + return true; + } + } + return false; + } + bool Spells::canUsePower(const std::string &power) const { std::map::const_iterator it = mUsedPowers.find(power); @@ -289,6 +291,16 @@ namespace MWMechanics // No need to discard spells here (doesn't really matter if non existent ids are kept) for (std::map::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it) mUsedPowers[it->first] = MWWorld::TimeStamp(it->second); + + mCorprusSpells.clear(); + for (std::map::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it) + { + if (mSpells.find(it->first) != mSpells.end()) // Discard unavailable corprus spells + { + mCorprusSpells[it->first].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings; + mCorprusSpells[it->first].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening); + } + } } void Spells::writeState(ESM::SpellState &state) const @@ -298,5 +310,11 @@ namespace MWMechanics for (std::map::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it) state.mUsedPowers[it->first] = it->second.toEsm(); + + for (std::map::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) + { + state.mCorprusSpells[it->first].mWorsenings = mCorprusSpells.at(it->first).mWorsenings; + state.mCorprusSpells[it->first].mNextWorsening = mCorprusSpells.at(it->first).mNextWorsening.toEsm(); + } } } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 039ad57fa..576aca9af 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -56,6 +56,8 @@ namespace MWMechanics std::map mCorprusSpells; void worsenCorprus(const std::string &corpSpellId); + static bool hasCorprusEffect(const ESM::Spell *spell); + public: bool canUsePower (const std::string& power) const; diff --git a/components/esm/spellstate.cpp b/components/esm/spellstate.cpp index 2dca2dcec..238f93901 100644 --- a/components/esm/spellstate.cpp +++ b/components/esm/spellstate.cpp @@ -27,6 +27,17 @@ namespace ESM mSpells[id] = random; } + while (esm.isNextSub("CORP")) + { + std::string id = esm.getHString(); + + CorprusStats stats; + esm.getHNT(stats.mWorsenings, "WORS"); + esm.getHNT(stats.mNextWorsening, "TIME"); + + mCorprusSpells[id] = stats; + } + while (esm.isNextSub("USED")) { std::string id = esm.getHString(); @@ -53,6 +64,15 @@ namespace ESM } } + for (std::map::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) + { + esm.writeHNString("CORP", it->first); + + const CorprusStats & stats = it->second; + esm.writeHNT("WORS", stats.mWorsenings); + esm.writeHNT("TIME", stats.mNextWorsening); + } + for (std::map::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it) { esm.writeHNString("USED", it->first); diff --git a/components/esm/spellstate.hpp b/components/esm/spellstate.hpp index cb5c0ff0d..bf8240246 100644 --- a/components/esm/spellstate.hpp +++ b/components/esm/spellstate.hpp @@ -13,9 +13,17 @@ namespace ESM struct SpellState { + struct CorprusStats + { + int mWorsenings; + TimeStamp mNextWorsening; + }; + typedef std::map > TContainer; TContainer mSpells; + std::map mCorprusSpells; + std::map mUsedPowers; std::string mSelectedSpell; From 26732bc2283fce8411b9450b83d33991008b8239 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Tue, 19 Aug 2014 22:13:37 +0200 Subject: [PATCH 3/5] Purge blight should not remove corprus --- apps/openmw/mwmechanics/spells.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index b16fc0aa6..3d8a78bcc 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -175,7 +175,7 @@ namespace MWMechanics const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().get().find (iter->first); - if (spell->mData.mType == ESM::Spell::ST_Blight) + if (spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell)) mSpells.erase(iter++); else ++iter; @@ -189,7 +189,7 @@ namespace MWMechanics const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().get().find (iter->first); - if (Misc::StringUtils::ciEqual(spell->mId, "corprus")) + if (hasCorprusEffect(spell)) mSpells.erase(iter++); else ++iter; From 2cbe17ca0a27fd4260d68662995e8994333addc9 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Wed, 20 Aug 2014 12:40:38 +0200 Subject: [PATCH 4/5] Make Spells::mCorprusSpells private --- apps/openmw/mwmechanics/actors.cpp | 4 ++-- apps/openmw/mwmechanics/spells.cpp | 5 +++++ apps/openmw/mwmechanics/spells.hpp | 25 ++++++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index e1d738078..c0f9e803d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -481,9 +481,9 @@ namespace MWMechanics Spells & spells = creatureStats.getSpells(); for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it) { - if (spells.mCorprusSpells.find(it->first) != spells.mCorprusSpells.end()) + if (spells.getCorprusSpells().find(it->first) != spells.getCorprusSpells().end()) { - if (MWBase::Environment::get().getWorld()->getTimeStamp() >= spells.mCorprusSpells[it->first].mNextWorsening) + if (MWBase::Environment::get().getWorld()->getTimeStamp() >= spells.getCorprusSpells().at(it->first).mNextWorsening) { spells.worsenCorprus(it->first); diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 3d8a78bcc..1d2ef827f 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -255,6 +255,11 @@ namespace MWMechanics return false; } + const std::map &Spells::getCorprusSpells() const + { + return mCorprusSpells; + } + bool Spells::canUsePower(const std::string &power) const { std::map::const_iterator it = mUsedPowers.find(power); diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 576aca9af..c1dd3e159 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -31,10 +31,17 @@ namespace MWMechanics { public: - typedef std::map > TContainer; // ID, typedef TContainer::const_iterator TIterator; + struct CorprusStats + { + static const int sWorseningPeriod = 24; + + int mWorsenings; + MWWorld::TimeStamp mNextWorsening; + }; + private: TContainer mSpells; @@ -44,22 +51,14 @@ namespace MWMechanics std::map mUsedPowers; - public: - struct CorprusStats - { - static const int sWorseningPeriod = 24; - - int mWorsenings; - MWWorld::TimeStamp mNextWorsening; - }; - std::map mCorprusSpells; - void worsenCorprus(const std::string &corpSpellId); - - static bool hasCorprusEffect(const ESM::Spell *spell); public: + void worsenCorprus(const std::string &corpSpellId); + static bool hasCorprusEffect(const ESM::Spell *spell); + const std::map & getCorprusSpells() const; + bool canUsePower (const std::string& power) const; void usePower (const std::string& power); From 85aa237baf96fe9bd9e91c73a89d1bc149258983 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Thu, 21 Aug 2014 03:11:49 +0200 Subject: [PATCH 5/5] Implement removal of corprus spells --- apps/openmw/mwmechanics/spells.cpp | 83 +++++++++++++++++++++++++----- apps/openmw/mwmechanics/spells.hpp | 3 ++ components/esm/spellstate.cpp | 30 +++++++++++ components/esm/spellstate.hpp | 10 ++++ 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 1d2ef827f..681f01f04 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -63,12 +63,26 @@ namespace MWMechanics TContainer::iterator iter = mSpells.find (lower); std::map::iterator corprusIt = mCorprusSpells.find(lower); + // if it's corprus, remove negative and keep positive effects + if (corprusIt != mCorprusSpells.end()) + { + worsenCorprus(lower); + if (mPermanentSpellEffects.find(lower) != mPermanentSpellEffects.end()) + { + MagicEffects & effects = mPermanentSpellEffects[lower]; + for (MagicEffects::Collection::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) + { + const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->first.mId); + if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful) + effects.remove(effectIt->first); + } + } + mCorprusSpells.erase(corprusIt); + } + if (iter!=mSpells.end()) mSpells.erase (iter); - if (corprusIt != mCorprusSpells.end()) - mCorprusSpells.erase(corprusIt); - if (spellId==mSelectedSpell) mSelectedSpell.clear(); } @@ -94,20 +108,17 @@ namespace MWMechanics if (iter->second.find(i) != iter->second.end()) random = iter->second.at(i); - int magnMult = 1; - if (mCorprusSpells.find(spell->mId) != mCorprusSpells.end()) - { - const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(spell->mEffects.mList.front().mEffectID); - if ((it->mEffectID != ESM::MagicEffect::Corprus) && (effect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE - magnMult += mCorprusSpells.at(spell->mId).mWorsenings; - } - - effects.add (*it, (it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random) * magnMult); + effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random); ++i; } } } + for (std::map::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it) + { + effects += it->second; + } + return effects; } @@ -241,6 +252,25 @@ namespace MWMechanics { mCorprusSpells[corpSpellId].mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod; mCorprusSpells[corpSpellId].mWorsenings++; + + // update worsened effects + mPermanentSpellEffects[corpSpellId] = MagicEffects(); + const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get().find(corpSpellId); + int i=0; + for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt, ++i) + { + const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE + { + float random = 1.f; + if (mSpells[corpSpellId].find(i) != mSpells[corpSpellId].end()) + random = mSpells[corpSpellId].at(i); + + float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random; + magnitude *= std::max(1, mCorprusSpells[corpSpellId].mWorsenings); + mPermanentSpellEffects[corpSpellId].add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(magnitude)); + } + } } bool Spells::hasCorprusEffect(const ESM::Spell *spell) @@ -297,6 +327,20 @@ namespace MWMechanics for (std::map::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it) mUsedPowers[it->first] = MWWorld::TimeStamp(it->second); + for (std::map >::const_iterator it = + state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it) + { + const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get().search(it->first); + if (!spell) + continue; + + mPermanentSpellEffects[it->first] = MagicEffects(); + for (std::vector::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) + { + mPermanentSpellEffects[it->first].add(EffectKey(effectIt->mId, effectIt->mArg), effectIt->mMagnitude); + } + } + mCorprusSpells.clear(); for (std::map::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it) { @@ -316,6 +360,21 @@ namespace MWMechanics for (std::map::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it) state.mUsedPowers[it->first] = it->second.toEsm(); + for (std::map::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it) + { + std::vector effectList; + for (MagicEffects::Collection::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) + { + ESM::SpellState::PermanentSpellEffectInfo info; + info.mId = effectIt->first.mId; + info.mArg = effectIt->first.mArg; + info.mMagnitude = effectIt->second.getModifier(); + + effectList.push_back(info); + } + state.mPermanentSpellEffects[it->first] = effectList; + } + for (std::map::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) { state.mCorprusSpells[it->first].mWorsenings = mCorprusSpells.at(it->first).mWorsenings; diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index c1dd3e159..7caeba6e8 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -46,6 +46,9 @@ namespace MWMechanics TContainer mSpells; + // spell-tied effects that will be applied even after removing the spell (currently used to keep positive effects when corprus is removed) + std::map mPermanentSpellEffects; + // 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; diff --git a/components/esm/spellstate.cpp b/components/esm/spellstate.cpp index 238f93901..3ed3329b4 100644 --- a/components/esm/spellstate.cpp +++ b/components/esm/spellstate.cpp @@ -27,6 +27,23 @@ namespace ESM mSpells[id] = random; } + while (esm.isNextSub("PERM")) + { + std::string spellId = esm.getHString(); + + std::vector permEffectList; + while (esm.isNextSub("EFID")) + { + PermanentSpellEffectInfo info; + esm.getHT(info.mId); + esm.getHNT(info.mArg, "ARG_"); + esm.getHNT(info.mMagnitude, "MAGN"); + + permEffectList.push_back(info); + } + mPermanentSpellEffects[spellId] = permEffectList; + } + while (esm.isNextSub("CORP")) { std::string id = esm.getHString(); @@ -64,6 +81,19 @@ namespace ESM } } + for (std::map >::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it) + { + esm.writeHNString("PERM", it->first); + + const std::vector & effects = it->second; + for (std::vector::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) + { + esm.writeHNT("EFID", effectIt->mId); + esm.writeHNT("ARG_", effectIt->mArg); + esm.writeHNT("MAGN", effectIt->mMagnitude); + } + } + for (std::map::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) { esm.writeHNString("CORP", it->first); diff --git a/components/esm/spellstate.hpp b/components/esm/spellstate.hpp index bf8240246..2ab27e908 100644 --- a/components/esm/spellstate.hpp +++ b/components/esm/spellstate.hpp @@ -2,6 +2,7 @@ #define OPENMW_ESM_SPELLSTATE_H #include +#include #include #include "defs.hpp" @@ -19,9 +20,18 @@ namespace ESM TimeStamp mNextWorsening; }; + struct PermanentSpellEffectInfo + { + int mId; + int mArg; + float mMagnitude; + }; + typedef std::map > TContainer; TContainer mSpells; + std::map > mPermanentSpellEffects; + std::map mCorprusSpells; std::map mUsedPowers;