@ -7,9 +7,13 @@
# include "../mwbase/environment.hpp"
# include "../mwbase/world.hpp"
# include "../mwworld/class.hpp"
# include "../mwworld/esmstore.hpp"
# include "actorutil.hpp"
# include "creaturestats.hpp"
# include "magiceffects.hpp"
# include "stat.hpp"
namespace MWMechanics
{
@ -63,12 +67,6 @@ namespace MWMechanics
}
}
}
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
@ -101,15 +99,6 @@ namespace MWMechanics
}
}
if ( hasCorprusEffect ( spell ) )
{
CorprusStats corprus ;
corprus . mWorsenings = 0 ;
corprus . mNextWorsening = MWBase : : Environment : : get ( ) . getWorld ( ) - > getTimeStamp ( ) + CorprusStats : : sWorseningPeriod ;
mCorprusSpells [ spell ] = corprus ;
}
SpellParams params ;
params . mEffectRands = random ;
mSpells . insert ( std : : make_pair ( spell , params ) ) ;
@ -127,27 +116,6 @@ namespace MWMechanics
const ESM : : Spell * spell = getSpell ( spellId ) ;
TContainer : : iterator iter = mSpells . find ( spell ) ;
std : : map < SpellKey , CorprusStats > : : iterator corprusIt = mCorprusSpells . find ( spell ) ;
// if it's corprus, remove negative and keep positive effects
if ( corprusIt ! = mCorprusSpells . end ( ) )
{
worsenCorprus ( spell ) ;
if ( mPermanentSpellEffects . find ( spell ) ! = mPermanentSpellEffects . end ( ) )
{
MagicEffects & effects = mPermanentSpellEffects [ spell ] ;
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 ) ;
if ( magicEffect - > mData . mFlags & ESM : : MagicEffect : : Harmful )
effects . remove ( ( effectIt + + ) - > first ) ;
else
+ + effectIt ;
}
}
mCorprusSpells . erase ( corprusIt ) ;
}
if ( iter ! = mSpells . end ( ) )
{
mSpells . erase ( iter ) ;
@ -320,31 +288,6 @@ namespace MWMechanics
}
}
void Spells : : worsenCorprus ( const ESM : : Spell * spell )
{
mCorprusSpells [ spell ] . mNextWorsening = MWBase : : Environment : : get ( ) . getWorld ( ) - > getTimeStamp ( ) + CorprusStats : : sWorseningPeriod ;
mCorprusSpells [ spell ] . mWorsenings + + ;
// update worsened effects
mPermanentSpellEffects [ spell ] = MagicEffects ( ) ;
int i = 0 ;
for ( std : : vector < ESM : : ENAMstruct > : : const_iterator effectIt = spell - > mEffects . mList . begin ( ) ; effectIt ! = spell - > mEffects . mList . end ( ) ; + + effectIt , + + i )
{
const ESM : : MagicEffect * magicEffect = MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) . get < ESM : : MagicEffect > ( ) . find ( effectIt - > mEffectID ) ;
if ( ( effectIt - > mEffectID ! = ESM : : MagicEffect : : Corprus ) & & ( magicEffect - > mData . mFlags & ESM : : MagicEffect : : AppliedOnce ) )
{
float random = 1.f ;
if ( mSpells [ spell ] . mEffectRands . find ( i ) ! = mSpells [ spell ] . mEffectRands . end ( ) )
random = mSpells [ spell ] . mEffectRands . at ( i ) ;
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 ;
}
}
}
bool Spells : : hasCorprusEffect ( const ESM : : Spell * spell )
{
for ( std : : vector < ESM : : ENAMstruct > : : const_iterator effectIt = spell - > mEffects . mList . begin ( ) ; effectIt ! = spell - > mEffects . mList . end ( ) ; + + effectIt )
@ -357,11 +300,6 @@ namespace MWMechanics
return false ;
}
const std : : map < Spells : : SpellKey , Spells : : CorprusStats > & Spells : : getCorprusSpells ( ) const
{
return mCorprusSpells ;
}
void Spells : : purgeEffect ( int effectId )
{
for ( TContainer : : iterator spellIt = mSpells . begin ( ) ; spellIt ! = mSpells . end ( ) ; + + spellIt )
@ -412,7 +350,7 @@ namespace MWMechanics
mUsedPowers [ spell ] = MWBase : : Environment : : get ( ) . getWorld ( ) - > getTimeStamp ( ) ;
}
void Spells : : readState ( const ESM : : SpellState & state )
void Spells : : readState ( const ESM : : SpellState & state , CreatureStats * creatureStats )
{
for ( ESM : : SpellState : : TContainer : : const_iterator it = state . mSpells . begin ( ) ; it ! = state . mSpells . end ( ) ; + + it )
{
@ -436,31 +374,64 @@ namespace MWMechanics
mUsedPowers [ spell ] = MWWorld : : TimeStamp ( it - > second ) ;
}
for ( std : : map < std : : string , std : : vector < ESM : : SpellState : : PermanentSpellEffectInfo > > : : const_iterator it =
state . mPermanentSpellEffects . begin ( ) ; it ! = state . mPermanentSpellEffects . end ( ) ; + + it )
for ( std : : map < std : : string , ESM : : SpellState : : CorprusStats > : : const_iterator it = state . mCorprusSpells . begin ( ) ; it ! = state . mCorprusSpells . end ( ) ; + + it )
{
const ESM : : Spell * spell = MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) . get < ESM : : Spell > ( ) . search ( it - > first ) ;
if ( ! spell )
continue ;
mPermanentSpellEffects [ spell ] = MagicEffects ( ) ;
for ( std : : vector < ESM : : SpellState : : PermanentSpellEffectInfo > : : const_iterator effectIt = it - > second . begin ( ) ; effectIt ! = it - > second . end ( ) ; + + effectIt )
CorprusStats stats ;
int worsening = state . mCorprusSpells . at ( it - > first ) . mWorsenings ;
for ( int i = 0 ; i < ESM : : Attribute : : Length ; + + i )
stats . mWorsenings [ i ] = 0 ;
for ( auto & effect : spell - > mEffects . mList )
{
mPermanentSpellEffects [ spell ] . add ( EffectKey ( effectIt - > mId , effectIt - > mArg ) , effectIt - > mMagnitude ) ;
if ( effect . mEffectID = = ESM : : MagicEffect : : DrainAttribute )
stats . mWorsenings [ effect . mAttribute ] = worsening ;
}
stats . mNextWorsening = MWWorld : : TimeStamp ( state . mCorprusSpells . at ( it - > first ) . mNextWorsening ) ;
creatureStats - > addCorprusSpell ( it - > first , stats ) ;
}
mCorprusSpells . clear ( ) ;
for ( std : : map < std : : string , ESM : : SpellState : : CorprusStats > : : const_iterator it = state . mCorprusSpells . begin ( ) ; it ! = state . mCorprusSpells . end ( ) ; + + it )
mSpellsChanged = true ;
// Permanent effects are used only to keep the custom magnitude of corprus spells effects (after cure too), and only in old saves. Convert data to the new approach.
for ( std : : map < std : : string , std : : vector < ESM : : SpellState : : PermanentSpellEffectInfo > > : : const_iterator it =
state . mPermanentSpellEffects . begin ( ) ; it ! = state . mPermanentSpellEffects . end ( ) ; + + it )
{
const ESM : : Spell * spell = MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) . get < ESM : : Spell > ( ) . search ( it - > first ) ;
if ( ! spell ) // Discard unavailable corprus spells
const ESM : : Spell * spell = MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) . get < ESM : : Spell > ( ) . search ( it - > first ) ;
if ( ! spell )
continue ;
mCorprusSpells [ spell ] . mWorsenings = state . mCorprusSpells . at ( it - > first ) . mWorsenings ;
mCorprusSpells [ spell ] . mNextWorsening = MWWorld : : TimeStamp ( state . mCorprusSpells . at ( it - > first ) . mNextWorsening ) ;
}
mSpellsChanged = true ;
// Import data only for player, other actors should not suffer from corprus worsening.
MWWorld : : Ptr player = getPlayer ( ) ;
if ( creatureStats - > getActorId ( ) ! = player . getClass ( ) . getCreatureStats ( player ) . getActorId ( ) )
return ;
// Note: if target actor has the Restore attirbute effects, stats will be restored.
for ( std : : vector < ESM : : SpellState : : PermanentSpellEffectInfo > : : const_iterator effectIt = it - > second . begin ( ) ; effectIt ! = it - > second . end ( ) ; + + effectIt )
{
// Applied corprus effects are already in loaded stats modifiers
if ( effectIt - > mId = = ESM : : MagicEffect : : FortifyAttribute )
{
AttributeValue attr = creatureStats - > getAttribute ( effectIt - > mArg ) ;
attr . setModifier ( attr . getModifier ( ) - effectIt - > mMagnitude ) ;
attr . damage ( - effectIt - > mMagnitude ) ;
creatureStats - > setAttribute ( effectIt - > mArg , attr ) ;
}
else if ( effectIt - > mId = = ESM : : MagicEffect : : DrainAttribute )
{
AttributeValue attr = creatureStats - > getAttribute ( effectIt - > mArg ) ;
attr . setModifier ( attr . getModifier ( ) + effectIt - > mMagnitude ) ;
attr . damage ( effectIt - > mMagnitude ) ;
creatureStats - > setAttribute ( effectIt - > mArg , attr ) ;
}
}
}
}
void Spells : : writeState ( ESM : : SpellState & state ) const
@ -477,26 +448,5 @@ namespace MWMechanics
for ( std : : map < SpellKey , MWWorld : : TimeStamp > : : const_iterator it = mUsedPowers . begin ( ) ; it ! = mUsedPowers . end ( ) ; + + it )
state . mUsedPowers [ it - > first - > mId ] = it - > second . toEsm ( ) ;
for ( std : : map < SpellKey , MagicEffects > : : const_iterator it = mPermanentSpellEffects . begin ( ) ; it ! = mPermanentSpellEffects . end ( ) ; + + it )
{
std : : vector < ESM : : SpellState : : PermanentSpellEffectInfo > 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 - > mId ] = effectList ;
}
for ( std : : map < SpellKey , CorprusStats > : : const_iterator it = mCorprusSpells . begin ( ) ; it ! = mCorprusSpells . end ( ) ; + + it )
{
state . mCorprusSpells [ it - > first - > mId ] . mWorsenings = mCorprusSpells . at ( it - > first ) . mWorsenings ;
state . mCorprusSpells [ it - > first - > mId ] . mNextWorsening = mCorprusSpells . at ( it - > first ) . mNextWorsening . toEsm ( ) ;
}
}
}