All pastes #248354 Raw Edit

Untitled

public text v1 · immutable
#248354 ·published 2006-11-14 15:53 UTC
rendered paste body
Index: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp	(revision 2652)
+++ src/game/Creature.cpp	(working copy)
@@ -1005,13 +1005,13 @@
     SetUInt32Value(UNIT_FIELD_FLAGS,cinfo->Flags);
     SetUInt32Value(UNIT_DYNAMIC_FLAGS,cinfo->dynamicflags);
 
-    SetArmor(cinfo->armor);
-    SetResistance(SPELL_SCHOOL_HOLY,cinfo->resistance1);
-    SetResistance(SPELL_SCHOOL_FIRE,cinfo->resistance2);
-    SetResistance(SPELL_SCHOOL_NATURE,cinfo->resistance3);
-    SetResistance(SPELL_SCHOOL_FROST,cinfo->resistance4);
-    SetResistance(SPELL_SCHOOL_SHADOW,cinfo->resistance5);
-    SetResistance(SPELL_SCHOOL_ARCANE,cinfo->resistance6);
+    SetBaseArmor(cinfo->armor);
+    SetBaseResistance(SPELL_SCHOOL_HOLY,cinfo->resistance1);
+    SetBaseResistance(SPELL_SCHOOL_FIRE,cinfo->resistance2);
+    SetBaseResistance(SPELL_SCHOOL_NATURE,cinfo->resistance3);
+    SetBaseResistance(SPELL_SCHOOL_FROST,cinfo->resistance4);
+    SetBaseResistance(SPELL_SCHOOL_SHADOW,cinfo->resistance5);
+    SetBaseResistance(SPELL_SCHOOL_ARCANE,cinfo->resistance6);
 
     //this is probably wrong
     SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, cinfo->equipmodel[0]);
@@ -1379,12 +1379,12 @@
     SetUInt32Value(UNIT_FIELD_BYTES_1,(getloyalty()<<8));
     SetHealth( 28 + 10 * level);
     SetMaxHealth( 28 + 10 * level);
-    SetStat(STAT_STRENGTH,uint32(20+level*1.55));
-    SetStat(STAT_AGILITY,uint32(20+level*0.64));
-    SetStat(STAT_STAMINA,uint32(20+level*1.27));
-    SetStat(STAT_INTELLECT,uint32(20+level*0.18));
-    SetStat(STAT_SPIRIT,uint32(20+level*0.36));
-    SetArmor(level*50);
+    SetBaseStat(STAT_STRENGTH,uint32(20+level*1.55));
+    SetBaseStat(STAT_AGILITY,uint32(20+level*0.64));
+    SetBaseStat(STAT_STAMINA,uint32(20+level*1.27));
+    SetBaseStat(STAT_INTELLECT,uint32(20+level*0.18));
+    SetBaseStat(STAT_SPIRIT,uint32(20+level*0.36));
+    SetBaseArmor(level*50);
 
     if(level - cinfo->minlevel >= 21)
         loyalty = 7;
Index: src/game/Level3.cpp
===================================================================
--- src/game/Level3.cpp	(revision 2653)
+++ src/game/Level3.cpp	(working copy)
@@ -2570,12 +2570,12 @@
             player->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.35f);
         }
         else player->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
-        player->SetStat(STAT_STRENGTH,info->strength );
-        player->SetStat(STAT_AGILITY,info->agility );
-        player->SetStat(STAT_STAMINA,info->stamina );
-        player->SetStat(STAT_INTELLECT,info->intellect );
-        player->SetStat(STAT_SPIRIT,info->spirit );
-        player->SetArmor(info->basearmor );
+        player->SetBaseStat(STAT_STRENGTH,info->strength );
+        player->SetBaseStat(STAT_AGILITY,info->agility );
+        player->SetBaseStat(STAT_STAMINA,info->stamina );
+        player->SetBaseStat(STAT_INTELLECT,info->intellect );
+        player->SetBaseStat(STAT_SPIRIT,info->spirit );
+        player->SetBaseArmor(info->basearmor );
         player->SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
         player->SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 );
 
@@ -2634,11 +2634,11 @@
         // reinitilize potential block chance (used if item with Block value equiped)
         player->SetFloatValue(PLAYER_BLOCK_PERCENTAGE, 5 + (float(player->GetDefenceSkillValue()) - player->getLevel()*5)*0.04);
         player->SetFloatValue(PLAYER_CRIT_PERCENTAGE, 5);
-        for (int i = 0; i < 7; i++)
+        for (int i = 0; i < SPELL_SCHOOL_COUNT; i++)
         {
-            player->SetResistance(SpellSchools(i), 0);
-            player->SetResistanceBuffMods(SpellSchools(i), true, 0);
-            player->SetResistanceBuffMods(SpellSchools(i), false, 0);
+            player->SetBaseResistance(SpellSchools(i), 0);
+            player->SetResistanceBuff(SpellSchools(i), true, 0);
+            player->SetResistanceBuff(SpellSchools(i), false, 0);
         }
         return true;
     }
Index: src/game/MiscHandler.cpp
===================================================================
--- src/game/MiscHandler.cpp	(revision 2652)
+++ src/game/MiscHandler.cpp	(working copy)
@@ -711,10 +711,10 @@
     GetPlayer()->SpawnCorpseBones();
 
     // set health, mana
-    GetPlayer()->ApplyStats(false);
+    GetPlayer()->_RemoveStatsMods();
     GetPlayer()->SetHealth(GetPlayer()->GetMaxHealth()/2);
     GetPlayer()->SetPower(POWER_MANA,GetPlayer()->GetMaxPower(POWER_MANA)/2);
-    GetPlayer()->ApplyStats(true);
+    GetPlayer()->_ApplyStatsMods();
 
     // update world right away
     MapManager::Instance().GetMap(GetPlayer()->GetMapId())->Add(GetPlayer());
Index: src/game/NPCHandler.cpp
===================================================================
--- src/game/NPCHandler.cpp	(revision 2652)
+++ src/game/NPCHandler.cpp	(working copy)
@@ -407,12 +407,12 @@
         }
     }
 
-    _player->ApplyStats(false);
+    _player->_RemoveStatsMods();
     _player->SetHealth( _player->GetMaxHealth()/2 );
     _player->SetPower(POWER_MANA, _player->GetMaxPower(POWER_MANA)/2 );
     _player->SetPower(POWER_RAGE, 0 );
     _player->SetPower(POWER_ENERGY, _player->GetMaxPower(POWER_ENERGY));
-    _player->ApplyStats(true);
+    _player->_ApplyStatsMods();
 
     _player->DurabilityLossAll(0.25);
     _player->SpawnCorpseBones();
Index: src/game/Pet.cpp
===================================================================
--- src/game/Pet.cpp	(revision 2652)
+++ src/game/Pet.cpp	(working copy)
@@ -90,12 +90,12 @@
         petlevel=owner->getLevel();
 
         SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
-        SetStat(STAT_STRENGTH,22);
-        SetStat(STAT_AGILITY,22);
-        SetStat(STAT_STAMINA,25);
-        SetStat(STAT_INTELLECT,28);
-        SetStat(STAT_SPIRIT,27);
-        SetArmor(petlevel*50);
+        SetBaseStat(STAT_STRENGTH,22);
+        SetBaseStat(STAT_AGILITY,22);
+        SetBaseStat(STAT_STAMINA,25);
+        SetBaseStat(STAT_INTELLECT,28);
+        SetBaseStat(STAT_SPIRIT,27);
+        SetBaseArmor(petlevel*50);
     }
     else if(owner->getClass() == CLASS_HUNTER && cinfo->type == CREATURE_TYPE_BEAST)
     {
@@ -108,12 +108,12 @@
         SetMaxPower(POWER_HAPPINESS,1000000);
         SetPower(   POWER_HAPPINESS,fields[11].GetUInt32());
         setPowerType(POWER_FOCUS);
-        SetStat(STAT_STRENGTH,uint32(20+petlevel*1.55));
-        SetStat(STAT_AGILITY,uint32(20+petlevel*0.64));
-        SetStat(STAT_STAMINA,uint32(20+petlevel*1.27));
-        SetStat(STAT_INTELLECT,uint32(20+petlevel*0.18));
-        SetStat(STAT_SPIRIT,uint32(20+petlevel*0.36));
-        SetArmor(petlevel*50);
+        SetBaseStat(STAT_STRENGTH,uint32(20+petlevel*1.55));
+        SetBaseStat(STAT_AGILITY,uint32(20+petlevel*0.64));
+        SetBaseStat(STAT_STAMINA,uint32(20+petlevel*1.27));
+        SetBaseStat(STAT_INTELLECT,uint32(20+petlevel*0.18));
+        SetBaseStat(STAT_SPIRIT,uint32(20+petlevel*0.36));
+        SetBaseArmor(petlevel*50);
     }
     SetLevel( petlevel);
     SetHealth( 28 + 10 * petlevel);
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 2653)
+++ src/game/Player.cpp	(working copy)
@@ -159,6 +159,21 @@
 
     m_resetTalentsCost = 0;
     m_resetTalentsTime = 0;
+
+    for(int i = 0; i < MAX_STATS; ++i)
+        m_createStats_field[i] = 0;
+
+    for(int i = 0; i < MAX_STATS; ++i)
+        m_PosStat[i] = 0;
+    for(int i = 0; i < MAX_STATS; ++i)
+        m_NegStat[i] = 0;
+    for(int i = 0; i < MAX_STATS; ++i)
+        m_CreateStat[i] = 0;
+    for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+    {
+        m_ResistanceBuff[i][0] = 0;
+        m_ResistanceBuff[i][1] = 0;
+    }
 }
 
 Player::~Player ()
@@ -225,11 +240,11 @@
         return false;
     }
 
-    m_createStats[STAT_AGILITY] = (float)info->agility;
-    m_createStats[STAT_INTELLECT] = (float)info->intellect;
-    m_createStats[STAT_SPIRIT] = (float)info->spirit;
-    m_createStats[STAT_STAMINA] = (float)info->stamina;
-    m_createStats[STAT_STRENGTH] = (float)info->strength;
+    SetCreateStat(STAT_AGILITY,  (float)info->agility);
+    SetCreateStat(STAT_INTELLECT,(float)info->intellect);
+    SetCreateStat(STAT_SPIRIT,   (float)info->spirit);
+    SetCreateStat(STAT_STAMINA,  (float)info->stamina);
+    SetCreateStat(STAT_STRENGTH, (float)info->strength);
 
     for (i = 0; i < BANK_SLOT_BAG_END; i++)
         m_items[i] = NULL;
@@ -288,12 +303,13 @@
         SetFloatValue(OBJECT_FIELD_SCALE_X, 1.35f);
     }
     else SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
-    SetStat(STAT_STRENGTH,info->strength );
-    SetStat(STAT_AGILITY,info->agility );
-    SetStat(STAT_STAMINA,info->stamina );
-    SetStat(STAT_INTELLECT,info->intellect );
-    SetStat(STAT_SPIRIT,info->spirit );
-    SetArmor(info->basearmor );
+
+    SetBaseArmor(info->basearmor);
+    SetBaseStat(STAT_STRENGTH,info->strength );
+    SetBaseStat(STAT_AGILITY,info->agility );
+    SetBaseStat(STAT_STAMINA,info->stamina );
+    SetBaseStat(STAT_INTELLECT,info->intellect );
+    SetBaseStat(STAT_SPIRIT,info->spirit );
     SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
 
     SetHealth(info->health);
@@ -1591,7 +1607,7 @@
     SetMaxHealth(uint32(newHP));                            // only integer part
 
     for(int i = STAT_STRENGTH; i < MAX_STATS; ++i)
-        SetStat(Stats(i), uint32(newStats[i]));             // only integer part
+        SetBaseStat(Stats(i), uint32(newStats[i]));             // only integer part
 
     // update dependent from level part BlockChanceWithoutMods = 5 + (GetDefenceSkillValue() - getLevel()*5)*0.04);
     UpdateBlockPercentage();
@@ -4186,15 +4202,11 @@
     }
 
     _RemoveStatsMods();
-    AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
-    for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
-        (*i)->ApplyModifier(false);
 
     _ApplyItemBonuses(proto,slot,apply);
 
-    for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
-        (*i)->ApplyModifier(true);
     _ApplyStatsMods();
+    
 
     if(apply)
         CastItemEquipSpell(item);
@@ -4235,28 +4247,23 @@
                 typestr = "Health";
                 break;
             case AGILITY:                                   // modify agility
-                ApplyStatMod(STAT_AGILITY,                val, apply);
                 ApplyPosStatMod(STAT_AGILITY,             val, apply);
                 typestr = "AGILITY";
                 break;
             case STRENGHT:                                  //modify strength
-                ApplyStatMod(STAT_STRENGTH,               val, apply);
                 ApplyPosStatMod(STAT_STRENGTH,            val, apply);
                 typestr = "STRENGHT";
                 break;
             case INTELLECT:                                 //modify intellect
-                ApplyStatMod(STAT_INTELLECT,               val,    apply);
                 ApplyPosStatMod(STAT_INTELLECT,            val,    apply);
                 //ApplyMaxPowerMod(POWER_MANA,              val*15, apply);
                 typestr = "INTELLECT";
                 break;
             case SPIRIT:                                    //modify spirit
-                ApplyStatMod(STAT_SPIRIT,                 val, apply);
                 ApplyPosStatMod(STAT_SPIRIT,              val, apply);
                 typestr = "SPIRIT";
                 break;
             case STAMINA:                                   //modify stamina
-                ApplyStatMod(STAT_STAMINA                ,val,   apply);
                 ApplyPosStatMod(STAT_STAMINA             ,val,   apply);
                 //ApplyMaxHealthMod(                        val*10,apply);
                 typestr = "STAMINA";
@@ -4269,7 +4276,7 @@
 
     if (proto->Armor)
     {
-        ApplyArmorMod( proto->Armor, apply);
+        ApplyBaseArmorMod( proto->Armor, apply);
         sLog.outDebug("%s Armor: \t\t%u", applystr.c_str(),  proto->Armor);
     }
 
@@ -4281,37 +4288,37 @@
 
     if (proto->HolyRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_HOLY, proto->HolyRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_HOLY, proto->HolyRes, apply);
         sLog.outDebug("%s HolyRes: \t\t%u", applystr.c_str(),  proto->HolyRes);
     }
 
     if (proto->FireRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_FIRE, proto->FireRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_FIRE, proto->FireRes, apply);
         sLog.outDebug("%s FireRes: \t\t%u", applystr.c_str(),  proto->FireRes);
     }
 
     if (proto->NatureRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_NATURE, proto->NatureRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_NATURE, proto->NatureRes, apply);
         sLog.outDebug("%s NatureRes: \t\t%u", applystr.c_str(),  proto->NatureRes);
     }
 
     if (proto->FrostRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_FROST, proto->FrostRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_FROST, proto->FrostRes, apply);
         sLog.outDebug("%s FrostRes: \t\t%u", applystr.c_str(),  proto->FrostRes);
     }
 
     if (proto->ShadowRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_SHADOW, proto->ShadowRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_SHADOW, proto->ShadowRes, apply);
         sLog.outDebug("%s ShadowRes: \t\t%u", applystr.c_str(),  proto->ShadowRes);
     }
 
     if (proto->ArcaneRes)
     {
-        ApplyResistanceMod(SPELL_SCHOOL_ARCANE, proto->ArcaneRes, apply);
+        ApplyBaseResistanceMod(SPELL_SCHOOL_ARCANE, proto->ArcaneRes, apply);
         sLog.outDebug("%s ArcaneRes: \t\t%u", applystr.c_str(),  proto->ArcaneRes);
     }
 
@@ -4603,10 +4610,6 @@
 
     _RemoveStatsMods();
 
-    AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
-    for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
-        (*i)->ApplyModifier(false);
-
     for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++)
     {
         if(m_items[i])
@@ -4622,9 +4625,6 @@
         }
     }
 
-    for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
-        (*i)->ApplyModifier(true);
-
     _ApplyStatsMods();
 
     sLog.outDebug("_ApplyAllItemMods complete.");
@@ -7712,7 +7712,7 @@
                         //uint32 enchant_description = pEnchant->description;
                         //SpellEntry *enchantSpell_info = sSpellStore.LookupEntry(enchant_spell_id);
                         if(enchant_display ==4)
-                            SetArmor(GetArmor()-enchant_value1);
+                            ApplyBaseArmorMod(enchant_value1,false);
                         else if(enchant_display ==2)
                         {
                             SetFloatValue(UNIT_FIELD_MINDAMAGE,GetFloatValue(UNIT_FIELD_MINDAMAGE)-enchant_value1);
@@ -9889,12 +9889,19 @@
         return false;
     }
 
-    m_createStats[STAT_AGILITY] = (float)info->agility;
-    m_createStats[STAT_INTELLECT] = (float)info->intellect;
-    m_createStats[STAT_SPIRIT] = (float)info->spirit;
-    m_createStats[STAT_STAMINA] = (float)info->stamina;
-    m_createStats[STAT_STRENGTH] = (float)info->strength;
+    // init create stats before stats initiaization
+    SetCreateStat(STAT_AGILITY,  (float)info->agility);
+    SetCreateStat(STAT_INTELLECT,(float)info->intellect);
+    SetCreateStat(STAT_SPIRIT,   (float)info->spirit);
+    SetCreateStat(STAT_STAMINA,  (float)info->stamina);
+    SetCreateStat(STAT_STRENGTH, (float)info->strength);
 
+    // currently in m_uint32Values stored base stats, move its to correct fields
+    for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+        SetBaseResistance(SpellSchools(i),GetResistance(SpellSchools(i)));
+    for(int i = 0; i < MAX_STATS; ++i)
+        SetBaseStat(Stats(i),GetStat(Stats(i)));
+
     uint32 transGUID = fields[29].GetUInt32();
     m_positionX = fields[7].GetFloat();
     m_positionY = fields[8].GetFloat();
@@ -10461,7 +10468,18 @@
     uint16 i;
     for( i = 0; i < m_valuesCount; i++ )
     {
-        ss << GetUInt32Value(i) << " ";
+        if(i >= UNIT_FIELD_STATS && i < UNIT_FIELD_STATS + MAX_STATS)
+        {
+
+            ss << reinterpret_cast<uint32&>(m_BaseStat[Stats(i-UNIT_FIELD_STATS)]) << " ";
+        }
+        else
+        if(i >= UNIT_FIELD_RESISTANCES && i < UNIT_FIELD_RESISTANCES + SPELL_SCHOOL_COUNT)
+        {
+            ss << reinterpret_cast<uint32&>(m_BaseResistance[SpellSchools(i-UNIT_FIELD_RESISTANCES)]) << " ";
+        }
+        else
+            ss << GetUInt32Value(i) << " ";
     }
 
     ss << "', '";
@@ -11098,3 +11116,29 @@
     //RestTickUpdate
     SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, rest_bonus);
 }
+
+void Player::UpdateStatsBuffs(Stats stat, float totalpct)
+{
+    float stat_pos = m_PosStat[stat];
+    ApplyPercentModFloatVar(stat_pos,totalpct,true);
+    SetFloatValue(PLAYER_FIELD_POSSTAT0+stat,stat_pos);
+        
+    float stat_neg = m_NegStat[stat];
+    ApplyPercentModFloatVar(stat_neg,totalpct,true);
+    SetFloatValue(PLAYER_FIELD_NEGSTAT0+stat,stat_neg);
+
+    float stat_create = m_CreateStat[stat];
+    ApplyPercentModFloatVar(stat_create,totalpct,true);
+    m_createStats_field[stat] = stat_create;
+}
+
+void Player::UpdateResistanceBuffs(SpellSchools res, float totalpct)
+{
+    float res_buf_pos = m_ResistanceBuff[res][true];
+    ApplyPercentModFloatVar(res_buf_pos,totalpct,true);
+    SetFloatValue(PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+res,res_buf_pos);
+
+    float res_buf_neg = m_ResistanceBuff[res][false];
+    ApplyPercentModFloatVar(res_buf_neg,totalpct,true);
+    SetFloatValue(PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+res,res_buf_neg);
+}
Index: src/game/Player.h
===================================================================
--- src/game/Player.h	(revision 2653)
+++ src/game/Player.h	(working copy)
@@ -510,23 +510,6 @@
         void UnTamePet(Creature* pet = NULL);
         void Uncharm();
 
-        float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
-        void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); }
-        void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); }
-        void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); }
-        void SetPosStat(Stats stat, float val) { SetFloatValue(PLAYER_FIELD_POSSTAT0+stat, val); }
-        void ApplyPosStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(PLAYER_FIELD_POSSTAT0+stat, val, apply); }
-        void ApplyPosStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(PLAYER_FIELD_POSSTAT0+stat, val, apply); }
-        void SetNegStat(Stats stat, float val) { SetFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val); }
-        void ApplyNegStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val, apply); }
-        void ApplyNegStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val, apply); }
-        void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; }
-        void ApplyCreateStatMod(Stats stat, float val, bool apply) { m_createStats[stat] += (apply ? val : -val); }
-        void ApplyCreateStatPercentMod(Stats stat, float val, bool apply) { m_createStats[stat] *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)); }
-        float GetPosStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_POSSTAT0+stat); }
-        float GetNegStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_NEGSTAT0+stat); }
-        float GetCreateStat(Stats stat) const { return m_createStats[stat]; }
-
         /*********************************************************/
         /***                    STORAGE SYSTEM                 ***/
         /*********************************************************/
@@ -1111,6 +1094,26 @@
         float GetTransOffsetZ() const { return m_transZ; }
         float GetTransOffsetO() const { return m_transO; }
 
+        //// Cascade Update System /////////////////////////
+        // Stats
+        float GetPosStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_POSSTAT0+stat); }
+        void SetPosStat(Stats stat, float val) { m_PosStat[stat] = val; CascadeUpdateStat(stat); }
+        void ApplyPosStatMod(Stats stat, float addval, bool apply) { m_PosStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+        float GetNegStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_NEGSTAT0+stat); }
+        void SetNegStat(Stats stat, float val) { m_NegStat[stat] = val; CascadeUpdateStat(stat); }
+        void ApplyNegStatMod(Stats stat, float addval, bool apply) { m_NegStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+        float GetCreateStat(Stats stat) const { return m_createStats_field[stat]; }
+                                                            // called without cascade update, used only at create/load/reset for initial setup
+        void SetCreateStat(Stats stat, float val) { m_CreateStat[stat] = val; m_createStats_field[stat] = val; } 
+        void ApplyCreateStatMod(Stats stat, float addval, bool apply) { m_CreateStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+        // ...called from Unit::CascadeUpdateResistance only
+        void UpdateStatsBuffs(Stats stat, float totalpct);
+        // Resistance
+        float GetResistanceBuff(SpellSchools school, bool positive) const { return GetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
+        void SetResistanceBuff(SpellSchools res,bool positive, float value) { m_ResistanceBuff[res][positive] = value; CascadeUpdateResistance(res); }
+        void ApplyResistanceBuffMod(SpellSchools res, bool positive, float addval, bool apply) { m_ResistanceBuff[res][positive] += (apply ? addval : -addval); CascadeUpdateResistance(res); }
+        // ...called from Unit::CascadeUpdateResistance only
+        void UpdateResistanceBuffs(SpellSchools res, float totalpct); 
     protected:
 
         /*********************************************************/
@@ -1191,7 +1194,7 @@
         std::string m_rank_name;
 
         PlayerCreateInfo *info;
-        float m_createStats[5];
+        float m_createStats_field[5];                       // with applied percent mods
 
         uint32 m_race;
         uint32 m_class;
@@ -1291,7 +1294,6 @@
         float inn_pos_z;
         float rest_bonus;
         int rest_type;
-        ////////////////////Rest System/////////////////////
 
         // Transports
         float m_transX;
@@ -1303,6 +1305,12 @@
 
         uint32 m_resetTalentsCost;
         time_t m_resetTalentsTime;
+
+        //// Cascade Update System /////////////////////////
+        float m_PosStat[MAX_STATS];                         //(with not applied percent modifiers)
+        float m_NegStat[MAX_STATS];                         //(with not applied percent modifiers)
+        float m_CreateStat[MAX_STATS];                      //(with not applied percent modifiers)
+        float m_ResistanceBuff[SPELL_SCHOOL_COUNT][2];      //(with not applied percent modifiers)
 };
 
 int32 irand(int32 min, int32 max);
Index: src/game/SharedDefines.h
===================================================================
--- src/game/SharedDefines.h	(revision 2652)
+++ src/game/SharedDefines.h	(working copy)
@@ -91,6 +91,8 @@
     SPELL_SCHOOL_ARCANE                = 6
 };
 
+#define SPELL_SCHOOL_COUNT 7
+
 #define ITEM_QUALITY_POOR                   0               //GREY
 #define ITEM_QUALITY_NORMAL                 1               //WHITE
 #define ITEM_QUALITY_UNCOMMON               2               //GREEN
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 2652)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -587,9 +587,7 @@
     if( m_modifier.m_auraname==SPELL_AURA_MOD_REGEN || m_modifier.m_auraname==SPELL_AURA_MOD_POWER_REGEN )
         m_periodicTimer = 5000;
 
-    m_target->ApplyStats(false);
     ApplyModifier(true);
-    m_target->ApplyStats(true);
 
     sLog.outDebug("Aura %u now is in use", m_modifier.m_auraname);
 
@@ -644,7 +642,6 @@
         if( m_target->GetTypeId() == TYPEID_PLAYER )
             UpdateAuraDuration();
     }
-
 }
 
 void Aura::_RemoveAura()
@@ -653,10 +650,10 @@
     if(m_modifier.m_auraname == SPELL_AURA_MOD_SHAPESHIFT)  // remove the shapeshift aura's boosts
         HandleShapeshiftBoosts(false, this);
 
-    m_target->ApplyStats(false);
+    m_target->_RemoveStatsMods();
     sLog.outDebug("Aura %u now is remove", m_modifier.m_auraname);
     ApplyModifier(false);
-    m_target->ApplyStats(true);
+    m_target->_ApplyStatsMods();
 
     Unit* caster = GetCaster();
 
@@ -915,10 +912,8 @@
                 return;
             SpellCastTargets targets;
             targets.setUnitTarget(target);
-            // prevent double stat apply for triggered auras
-            target->ApplyStats(true);
+
             spell.prepare(&targets);
-            target->ApplyStats(false);
         }
     }
 }
@@ -1854,90 +1849,20 @@
 
 void Aura::HandleAuraModResistanceExclusive(bool apply)
 {
-    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
-        return;
-    }
-
-    bool positive = m_modifier.m_miscvalue2 == 0;
-
-    for(int8 x=0;x < 7;x++)
-    {
-        if(m_modifier.m_miscvalue & int32(1<<x))
-        {
-            SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
-
-            m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
-            if(m_target->GetTypeId() == TYPEID_PLAYER)
-                ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
-        }
-    }
+    // applied at aura add/remove
 }
 
 void Aura::HandleAuraModResistance(bool apply)
 {
-    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
-        return;
-    }
-
-    bool positive = m_modifier.m_miscvalue2 == 0;
-
-    for(int8 x=0;x < 7;x++)
-    {
-        if(m_modifier.m_miscvalue & int32(1<<x))
-        {
-            SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
-
-            m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
-            if(m_target->GetTypeId() == TYPEID_PLAYER)
-                ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
-        }
-    }
 }
 
 void Aura::HandleAuraModBaseResistancePCT(bool apply)
 {
-    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
-        return;
-    }
-
-    // only players have base stats
-    if(m_target->GetTypeId() != TYPEID_PLAYER)
-        return;
-    Player *p_target = (Player*)m_target;
-
-    for(int8 x=0;x < 7;x++)
-    {
-        if(m_modifier.m_miscvalue & int32(1<<x))
-        {
-            SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
-            float curRes = p_target->GetResistance(school);
-            float baseRes = curRes + p_target->GetResistanceBuffMods(school, false) - p_target->GetResistanceBuffMods(school, true);
-            float baseRes_new = baseRes * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
-            p_target->SetResistance(school, curRes + baseRes_new - baseRes);
-        }
-    }
 }
 
 void Aura::HandleModResistancePercent(bool apply)
 {
-    for(int8 i = 0; i < 7; i++)
-    {
-        if(m_modifier.m_miscvalue & int32(1<<i))
-        {
-            m_target->ApplyResistancePercentMod(SpellSchools(i), m_modifier.m_amount, apply );
-            if(m_target->GetTypeId() == TYPEID_PLAYER)
-            {
-                ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
-                ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
-            }
-        }
-    }
+    // all done in cascade update system and at aura add/remove
 }
 
 void Aura::HandleModBaseResistance(bool apply)
@@ -1949,7 +1874,7 @@
 
     for(int i = 0; i < 7; i++)
         if(m_modifier.m_miscvalue & (1<<i))
-            p_target->ApplyResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
+            p_target->ApplyBaseResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
 }
 
 /********************************/
@@ -1968,7 +1893,6 @@
     {
         if (m_modifier.m_miscvalue == -1 || m_modifier.m_miscvalue == i)
         {
-            m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
             if(m_target->GetTypeId() == TYPEID_PLAYER)
             {
                 if (m_modifier.m_miscvalue2 == 0)
@@ -1976,57 +1900,19 @@
                 else
                     ((Player*)m_target)->ApplyNegStatMod(Stats(i),m_modifier.m_amount,apply);
             }
+            else
+                m_target->ApplyBaseStatMod(Stats(i), m_modifier.m_amount,apply);
         }
     }
 }
 
 void Aura::HandleModPercentStat(bool apply)
 {
-    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
-        return;
-    }
-
-    // only players have base stats
-    if (m_target->GetTypeId() != TYPEID_PLAYER)
-        return;
-    Player *p_target = (Player*)m_target;
-
-    for (int32 i = 0; i < 5; i++)
-    {
-        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
-        {
-            float curStat = p_target->GetStat(Stats(i));
-            float baseStat = curStat + p_target->GetNegStat(Stats(i)) - p_target->GetPosStat(Stats(i));
-            float baseStat_new = baseStat * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
-            p_target->SetStat(Stats(i), curStat + baseStat_new - baseStat);
-            p_target->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
-        }
-    }
 }
 
 void Aura::HandleModTotalPercentStat(bool apply)
 {
-    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
-        return;
-    }
-
-    for (int32 i = 0; i < 5; i++)
-    {
-        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
-        {
-            m_target->ApplyStatPercentMod(Stats(i), m_modifier.m_amount, apply );
-            if (m_target->GetTypeId() == TYPEID_PLAYER)
-            {
-                ((Player*)m_target)->ApplyPosStatPercentMod(Stats(i), m_modifier.m_amount, apply );
-                ((Player*)m_target)->ApplyNegStatPercentMod(Stats(i), m_modifier.m_amount, apply );
-                ((Player*)m_target)->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
-            }
-        }
-    }
+    // all done in cascade update system and at aura add/remove
 }
 
 /********************************/
@@ -2520,3 +2406,112 @@
     double healthPercentage = (double)unit_target->GetHealth() / (double)unit_target->GetMaxHealth();
     unit_target->SetHealth(uint32(ceil((double)unit_target->GetMaxHealth() * healthPercentage)));
 }
+
+//// Cascade Update System
+void Aura::ApplyModResistancePercent(bool)
+{
+    for(int8 i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+    {
+        if(m_modifier.m_miscvalue & int32(1<<i))
+            m_target->CascadeUpdateResistance(SpellSchools(i));
+    }
+}
+
+void Aura::ApplyAuraModResistanceExclusive(bool apply)
+{
+    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+    {
+        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+        return;
+    }
+
+    bool positive = m_modifier.m_miscvalue2 == 0;
+
+    for(int8 x=0;x < SPELL_SCHOOL_COUNT; ++x)
+    {
+        if(m_modifier.m_miscvalue & int32(1<<x))
+        {
+            SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
+
+            if(m_target->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)m_target)->ApplyResistanceBuffMod(school,positive,m_modifier.m_amount, apply);
+            else
+                m_target->ApplyBaseResistanceMod(school,m_modifier.m_amount, apply);
+        }
+    }
+}
+
+void Aura::ApplyModTotalPercentStat(bool)
+{
+    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+    {
+        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+        return;
+    }
+
+    for (int32 i = 0; i < MAX_STATS; ++i)
+    {
+        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+            m_target->CascadeUpdateStat(Stats(i));
+    }
+}
+
+void Aura::ApplyAuraModResistance(bool apply)
+{
+    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+    {
+        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+        return;
+    }
+
+    bool positive = m_modifier.m_miscvalue2 == 0;
+
+    for(int8 x=0;x < SPELL_SCHOOL_COUNT;x++)
+    {
+        if(m_modifier.m_miscvalue & int32(1<<x))
+        {
+            SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
+
+            if(m_target->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)m_target)->ApplyResistanceBuffMod(school,positive,m_modifier.m_amount, apply);
+            else
+                m_target->ApplyBaseResistanceMod(school,m_modifier.m_amount, apply);
+        }
+    }
+}
+
+void Aura::ApplyAuraModBaseResistancePCT(bool)
+{
+    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+    {
+        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+        return;
+    }
+
+    // only players have base stats
+    if(m_target->GetTypeId() != TYPEID_PLAYER)
+        return;
+    Player *p_target = (Player*)m_target;
+
+    for(int8 x=0;x < SPELL_SCHOOL_COUNT;x++)
+        if(m_modifier.m_miscvalue & int32(1<<x))
+            m_target->CascadeUpdateResistance(SpellSchools(SPELL_SCHOOL_NORMAL + x));
+}
+
+void Aura::ApplyModPercentStat(bool apply)
+{
+    if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+    {
+        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+        return;
+    }
+
+    // only players have base stats
+    if (m_target->GetTypeId() != TYPEID_PLAYER)
+        return;
+    Player *p_target = (Player*)m_target;
+
+    for (int32 i = 0; i < MAX_STATS; i++)
+        if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+            p_target->CascadeUpdateStat(Stats(i));
+}
Index: src/game/SpellAuras.h
===================================================================
--- src/game/SpellAuras.h	(revision 2652)
+++ src/game/SpellAuras.h	(working copy)
@@ -144,6 +144,15 @@
         void HandleRangedAmmoHaste(bool Apply);
         void HandleModTotalPercentStat(bool Apply);
 
+        // Cascade updates at aura adding/removing
+        void ApplyModTotalPercentStat(bool); 
+        void ApplyModPercentStat(bool);
+        void ApplyModResistancePercent(bool);
+        void ApplyAuraModBaseResistancePCT(bool);
+        void ApplyAuraModResistanceExclusive(bool apply);
+        void ApplyAuraModResistance(bool apply);
+
+        // Common methods
         Aura(SpellEntry* spellproto, uint32 eff, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
         virtual ~Aura();
 
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 2652)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -804,7 +804,7 @@
     spawnCreature->SetStat(STAT_INTELLECT,int(20+level*0.18));
     spawnCreature->SetStat(STAT_SPIRIT,int(20+level*0.36));
     */
-    spawnCreature->SetArmor(level*50);
+    spawnCreature->SetBaseArmor(level*50);
     spawnCreature->AIM_Initialize();
 
     std::string name;
@@ -1048,7 +1048,7 @@
     spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
     spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
 
-    spawnCreature->SetArmor(level*50);
+    spawnCreature->SetBaseArmor(level*50);
     spawnCreature->AIM_Initialize();
 
     MapManager::Instance().GetMap(m_caster->GetMapId())->Add((Creature*)spawnCreature);
@@ -1311,11 +1311,11 @@
         NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0);
         NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
         NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
-        NewSummon->SetStat(STAT_STRENGTH,22);
-        NewSummon->SetStat(STAT_AGILITY,22);
-        NewSummon->SetStat(STAT_STAMINA,25);
-        NewSummon->SetStat(STAT_INTELLECT,28);
-        NewSummon->SetStat(STAT_SPIRIT,27);
+        NewSummon->SetBaseStat(STAT_STRENGTH,22);
+        NewSummon->SetBaseStat(STAT_AGILITY,22);
+        NewSummon->SetBaseStat(STAT_STAMINA,25);
+        NewSummon->SetBaseStat(STAT_INTELLECT,28);
+        NewSummon->SetBaseStat(STAT_SPIRIT,27);
 
         for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++)
             NewSummon->m_spells[i] = 0;
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 2652)
+++ src/game/Unit.cpp	(working copy)
@@ -81,6 +81,11 @@
     m_baseSpellCritChance = 5;
     m_modCastSpeedPct = 0;
     m_CombatTimer = 0;
+
+    for(int i = 0; i < MAX_STATS; ++i)
+        m_BaseStat[i] = 0;
+    for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+        m_BaseResistance[i] = 0;
 }
 
 Unit::~Unit()
@@ -1673,14 +1678,38 @@
         }
     }
 
+    if(Aur->GetTarget())
+    {
+        Aur->GetTarget()->_RemoveStatsMods();
+    }
+
     Aur->_AddAura();
+
     m_Auras.insert(AuraMap::value_type(spellEffectPair(Aur->GetId(), Aur->GetEffIndex()), Aur));
+
     if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
     {
         m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur);
         m_AuraModifiers[Aur->GetModifier()->m_auraname] += (Aur->GetModifier()->m_amount);
     }
 
+    //// Cascaded Update System
+    switch(Aur->GetModifier()->m_auraname)
+    {
+        case SPELL_AURA_MOD_RESISTANCE_PCT:         Aur->ApplyModResistancePercent(true);       break;
+        case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE:   Aur->ApplyAuraModResistanceExclusive(true); break;
+        case SPELL_AURA_MOD_BASE_RESISTANCE_PCT:    Aur->ApplyAuraModBaseResistancePCT(true);   break;
+        case SPELL_AURA_MOD_RESISTANCE:             Aur->ApplyAuraModResistance(true);          break;
+        case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:  Aur->ApplyModTotalPercentStat(true);        break;
+        case SPELL_AURA_MOD_PERCENT_STAT:           Aur->ApplyModPercentStat(true);             break;
+    }
+
+    if(Aur->GetTarget())
+    {
+        Aur->GetTarget()->_ApplyStatsMods();
+    }
+
+
     if (IsSingleTarget(Aur->GetId()) && Aur->GetTarget() && Aur->GetSpellProto())
     {
         if(Unit* caster = Aur->GetCaster())
@@ -1932,6 +1961,7 @@
             }
         }
     }
+
     if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS)
     {
         m_AuraModifiers[(*i).second->GetModifier()->m_auraname] -= ((*i).second->GetModifier()->m_amount);
@@ -1939,9 +1969,23 @@
     }
     (*i).second->SetRemoveOnDeath(onDeath);
     (*i).second->_RemoveAura();
-    delete (*i).second;
+
+    Aura* Aur = (*i).second;
     m_Auras.erase(i++);
     m_removedAuras++;                                       // internal count used by unit update
+
+    //// Cascaded Update System
+        switch(Aur->GetModifier()->m_auraname)
+    {
+        case SPELL_AURA_MOD_RESISTANCE_PCT:         Aur->ApplyModResistancePercent(false);      break;
+        case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE:   Aur->ApplyAuraModResistanceExclusive(false);break;
+        case SPELL_AURA_MOD_BASE_RESISTANCE_PCT:    Aur->ApplyAuraModBaseResistancePCT(false);  break;
+        case SPELL_AURA_MOD_RESISTANCE:             Aur->ApplyAuraModResistance(false);         break;
+        case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:  Aur->ApplyModTotalPercentStat(false);       break;
+        case SPELL_AURA_MOD_PERCENT_STAT:           Aur->ApplyModPercentStat(false);            break;
+    }
+
+    delete Aur;
 }
 
 bool Unit::SetAurDuration(uint32 spellId, uint32 effindex,uint32 duration)
@@ -2001,15 +2045,15 @@
 
 void Unit::_RemoveStatsMods()
 {
-    ApplyStats(false);
+    _ApplyStats(false);
 }
 
 void Unit::_ApplyStatsMods()
 {
-    ApplyStats(true);
+    _ApplyStats(true);
 }
 
-void Unit::ApplyStats(bool apply)
+void Unit::_ApplyStats(bool apply)
 {
     // TODO:
     // -- add --
@@ -2021,71 +2065,7 @@
 
     float val;
     int32 val2,tem_att_power;
-    float totalstatmods[5] = {1,1,1,1,1};
-    float totalresmods[7] = {1,1,1,1,1,1,1};
 
-    AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
-    for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
-    {
-        if((*i)->GetModifier()->m_miscvalue != -1)
-            totalstatmods[(*i)->GetModifier()->m_miscvalue] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
-        else
-            for (uint8 j = 0; j < 5; j++)
-                totalstatmods[j] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
-    }
-    AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
-    for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
-        for(uint8 j = 0; j <= 6; j++)
-            if((*i)->GetModifier()->m_miscvalue & (1<<j))
-                totalresmods[j] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
-
-    for (uint8 i = 0; i < 5; i++)
-        totalstatmods[i] = totalstatmods[i] * 100.0f - 100.0f;
-    for (uint8 i = 0; i < 7; i++)
-        totalresmods[i] = totalresmods[i] * 100.0f - 100.0f;
-
-    // restore percent mods
-    if (apply)
-    {
-        for (uint8 i = 0; i < 5; i++)
-        {
-            if (totalstatmods[i] != 0)
-            {
-                ApplyStatPercentMod(Stats(i),totalstatmods[i], apply );
-                ((Player*)this)->ApplyPosStatPercentMod(Stats(i),totalstatmods[i], apply );
-                ((Player*)this)->ApplyNegStatPercentMod(Stats(i),totalstatmods[i], apply );
-            }
-        }
-        for (uint8 i = 0; i < 7; i++)
-        {
-            if (totalresmods[i] != 0)
-            {
-                ApplyResistancePercentMod(SpellSchools(i), totalresmods[i], apply );
-                ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true, totalresmods[i], apply);
-                ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false, totalresmods[i], apply);
-            }
-        }
-    }
-
-    // Armor
-    val = 2*(GetStat(STAT_AGILITY) - ((Player*)this)->GetCreateStat(STAT_AGILITY));
-
-    ApplyArmorMod( val, apply);
-
-    // HP
-    val2 = uint32((GetStat(STAT_STAMINA) - ((Player*)this)->GetCreateStat(STAT_STAMINA))*10);
-
-    ApplyMaxHealthMod( val2, apply);
-
-    // MP
-    if(getClass() != WARRIOR && getClass() != ROGUE)
-    {
-        val2 = uint32((GetStat(STAT_INTELLECT) - ((Player*)this)->GetCreateStat(STAT_INTELLECT))*15);
-
-        ApplyMaxPowerMod(POWER_MANA, val2, apply);
-
-    }
-
     float classrate = 0;
 
     // Melee Attack Power
@@ -2174,80 +2154,26 @@
 
     ApplyModFloatValue(PLAYER_PARRY_PERCENTAGE, val, apply);
 
-    // remove percent mods to see original stats when adding buffs/items
-    if (!apply)
-    {
-        for (uint8 i = 0; i < 5; i++)
-        {
-            if (totalstatmods[i])
-            {
-                ApplyStatPercentMod(Stats(i),totalstatmods[i], apply );
-                ((Player*)this)->ApplyPosStatPercentMod(Stats(i),totalstatmods[i], apply );
-                ((Player*)this)->ApplyNegStatPercentMod(Stats(i),totalstatmods[i], apply );
-            }
-        }
-        for (uint8 i = 0; i < 7; i++)
-        {
-            if (totalresmods[i])
-            {
-                ApplyResistancePercentMod(SpellSchools(i), totalresmods[i], apply );
-                ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true, totalresmods[i], apply);
-                ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false, totalresmods[i], apply);
-            }
-        }
-    }
 }
 
 void Unit::_RemoveAllAuraMods()
 {
-    ApplyStats(false);
+    _RemoveStatsMods();
+
     for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
-    {
-        switch ((*i).second->GetModifier()->m_auraname)
-        {
-            case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:
-            case SPELL_AURA_MOD_RESISTANCE_PCT:
-                // these are already removed by applystats
-                break;
-            default:
-                (*i).second->ApplyModifier(false);
-        }
-    }
-    ApplyStats(true);
+        (*i).second->ApplyModifier(false);
 
-    // these must be removed after applystats
-    AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
-    for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
-        (*i)->ApplyModifier(false);
-    AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
-    for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
-        (*i)->ApplyModifier(false);
+    _ApplyStatsMods();
 }
 
 void Unit::_ApplyAllAuraMods()
 {
-    // these must be applied before applystats
-    AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
-    for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
-        (*i)->ApplyModifier(true);
-    AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
-    for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
-        (*i)->ApplyModifier(true);
-    ApplyStats(false);
+    _RemoveStatsMods();
 
     for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
-    {
-        switch ((*i).second->GetModifier()->m_auraname)
-        {
-            case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:
-            case SPELL_AURA_MOD_RESISTANCE_PCT:
-                // these are already applied by applystats
-                break;
-            default:
-                (*i).second->ApplyModifier(true);
-        }
-    }
-    ApplyStats(true);
+        (*i).second->ApplyModifier(true);
+
+    _ApplyStatsMods();
 }
 
 // TODO: FIX-ME!!!
@@ -2355,7 +2281,7 @@
 
     if(enchant_display ==4)
     {
-        ApplyArmorMod(enchant_value1,apply);
+        ApplyBaseArmorMod(enchant_value1,apply);
     }
     else if(enchant_display ==2)
     {
@@ -3273,3 +3199,94 @@
     if(curPower != maxPower)
         SetPower(power,maxPower);
 }
+
+//#### Cascade update methods
+float Unit::GetResistance(SpellSchools res) const { 
+    return GetFloatValue(UNIT_FIELD_RESISTANCES+res) + 
+        (GetTypeId()==TYPEID_PLAYER ? (((Player*)this)->GetResistanceBuff(res,true) - ((Player*)this)->GetResistanceBuff(res,false)) : 0);
+}
+
+void Unit::CascadeUpdateResistance(SpellSchools res)
+{
+
+    // base percent modifiers
+    float basePercentModifier = 0;
+    AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
+    for(AuraList::iterator i = mModBaseResistancePct .begin(); i != mModBaseResistancePct .end(); ++i)
+        if((*i)->GetModifier()->m_miscvalue & int32(1<<res))
+            basePercentModifier += (*i)->GetModifier()->m_amount;
+
+    // total percent modifiers
+    float totalPercentModifier = 0;
+    AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
+    for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
+        if((*i)->GetModifier()->m_miscvalue & int32(1<<res))
+            totalPercentModifier += (*i)->GetModifier()->m_amount;
+
+    float cur_res = m_BaseResistance[res];
+    ApplyPercentModFloatVar(cur_res,basePercentModifier,true);
+    ApplyPercentModFloatVar(cur_res,totalPercentModifier,true);
+
+    // calculate total resistance
+    if(GetTypeId()==TYPEID_PLAYER)
+    {
+        ((Player*)this)->UpdateResistanceBuffs(res,totalPercentModifier);
+    }
+ 
+    SetFloatValue(UNIT_FIELD_RESISTANCES+res,cur_res);
+}
+
+void Unit::CascadeUpdateStat(Stats stat)
+{
+    // temporary until not converted to cascade update
+    _RemoveStatsMods();
+
+    // base stat percent modifier
+    float basePercentModifier = 0;
+    AuraList& mModBaseStatPct = GetAurasByType(SPELL_AURA_MOD_PERCENT_STAT);
+    for(AuraList::iterator i = mModBaseStatPct.begin(); i != mModBaseStatPct.end(); ++i)
+        if((*i)->GetModifier()->m_miscvalue & int32(1<<stat))
+            basePercentModifier += (*i)->GetModifier()->m_amount;
+
+    // total stat modifier
+    float totalPercentModifier = 0;
+    AuraList& mModStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+    for(AuraList::iterator i = mModStatPct .begin(); i != mModStatPct .end(); ++i)
+        if((*i)->GetModifier()->m_miscvalue & int32(1<<stat))
+            totalPercentModifier += (*i)->GetModifier()->m_amount;
+    
+    float cur_stat = m_BaseStat[stat];
+    ApplyPercentModFloatVar(cur_stat,basePercentModifier,true);
+    ApplyPercentModFloatVar(cur_stat,totalPercentModifier,true);
+
+    float stat_delta = 0;
+    
+    // calculate total resistance
+    if(GetTypeId()==TYPEID_PLAYER)
+    {
+
+        stat_delta = -(GetStat(stat) - ((Player*)this)->GetCreateStat(stat));
+
+        ((Player*)this)->UpdateStatsBuffs(stat,totalPercentModifier);
+
+        cur_stat += ((Player*)this)->GetPosStat(stat) - ((Player*)this)->GetNegStat(stat);
+
+        stat_delta += cur_stat - ((Player*)this)->GetCreateStat(stat);
+    }
+
+    SetFloatValue(UNIT_FIELD_STATS+stat,cur_stat);
+
+    switch(stat)
+    {
+        case STAT_AGILITY:   ApplyBaseArmorMod(2*stat_delta,true);          break;
+        case STAT_STAMINA:   ApplyMaxHealthMod(int32(10*stat_delta),true);  break;
+        case STAT_INTELLECT: 
+            if(getClass() != WARRIOR && getClass() != ROGUE) 
+                ApplyMaxPowerMod(POWER_MANA,int32(10*stat_delta),true);  
+            break;
+    }
+
+
+    // temporary until not converted to cascade update
+    _ApplyStatsMods();
+}
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 2652)
+++ src/game/Unit.h	(working copy)
@@ -389,27 +389,12 @@
         uint32 getClassMask() const { return 1 << (getClass()-1); };
         uint8 getGender() const { return (uint8)((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 16) & 0xFF); };
 
-        float GetStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_STATS+stat); }
-        void SetStat(Stats stat, float val) { SetFloatValue(UNIT_FIELD_STATS+stat, val); }
-        void ApplyStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(UNIT_FIELD_STATS+stat, val, apply); }
-        void ApplyStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_STATS+stat, val, apply); }
-
-        float GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; }
-        void SetArmor(float val) { SetResistance(SPELL_SCHOOL_NORMAL, val); }
-        void ApplyArmorMod(float val, bool apply) { ApplyResistanceMod(SPELL_SCHOOL_NORMAL, val, apply); }
-        void ApplyArmorPercentMod(float val, bool apply) { ApplyResistancePercentMod(SPELL_SCHOOL_NORMAL, val, apply); }
-
-        float GetResistance(SpellSchools school) const { return GetFloatValue(UNIT_FIELD_RESISTANCES+school); }
-        void SetResistance(SpellSchools school, float val) { SetFloatValue(UNIT_FIELD_RESISTANCES+school,val); }
-        void ApplyResistanceMod(SpellSchools school, float val, bool apply) { ApplyModFloatValue(UNIT_FIELD_RESISTANCES+school, val, apply); }
-        void ApplyResistancePercentMod(SpellSchools school, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_RESISTANCES+school, val, apply); }
-
         uint32 GetHealth()    const { return GetUInt32Value(UNIT_FIELD_HEALTH); }
         uint32 GetMaxHealth() const { return (uint32)GetFloatValue(UNIT_FIELD_MAXHEALTH); }
         void SetHealth(   uint32 val) { SetUInt32Value(UNIT_FIELD_HEALTH,val); }
         void SetMaxHealth(uint32 val) { SetFloatValue(UNIT_FIELD_MAXHEALTH,val); }
         void ModifyHealth(int32 val);
-        void ApplyMaxHealthMod(uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
+        void ApplyMaxHealthMod(int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
         void ApplyMaxHealthPercentMod(float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
 
         Powers getPowerType() const { return Powers((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 24) & 0xFF); };
@@ -419,9 +404,9 @@
         void SetPower(   Powers power, uint32 val) { SetFloatValue(UNIT_FIELD_POWER1   +power,val); }
         void SetMaxPower(Powers power, uint32 val) { SetFloatValue(UNIT_FIELD_MAXPOWER1+power,val); }
         void ModifyPower(Powers power, int32 val);
-        void ApplyPowerMod(Powers power, uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
+        void ApplyPowerMod(Powers power, int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
         void ApplyPowerPercentMod(Powers power, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
-        void ApplyMaxPowerMod(Powers power, uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
+        void ApplyMaxPowerMod(Powers power, int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
         void ApplyMaxPowerPercentMod(Powers power, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
 
         uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att); }
@@ -629,7 +614,6 @@
         uint32 CalculateDamage(WeaponAttackType attType);
         void SetStateFlag(uint32 index, uint32 newFlag );
         void RemoveStateFlag(uint32 index, uint32 oldFlag );
-        void ApplyStats(bool apply);
         void UnsummonTotem(int8 slot = -1);
         uint32 SpellDamageBonus(Unit *pVictim, SpellEntry *spellProto, uint32 damage);
         uint32 SpellHealingBonus(SpellEntry *spellProto, uint32 healamount);
@@ -637,11 +621,28 @@
         void MeleeDamageBonus(Unit *pVictim, uint32 *damage);
         void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
 
+        void _RemoveStatsMods();
+        void _ApplyStatsMods();
+
+        //// Cascade Update System /////////////////////////
+        // Stats
+        float GetStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_STATS+stat); }
+        void SetBaseStat(Stats stat, float value) { m_BaseStat[stat] = value; CascadeUpdateStat(stat); }
+        void ApplyBaseStatMod(Stats stat, float addvalue, bool apply) { m_BaseStat[stat] += (apply ? addvalue : -addvalue); CascadeUpdateStat(stat); }
+        void CascadeUpdateStat(Stats stat);
+
+        // Resistance
+        float GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; }
+        float GetResistance(SpellSchools school) const;
+        void SetBaseArmor(float addvalue) { SetBaseResistance(SPELL_SCHOOL_NORMAL,addvalue); }
+        void ApplyBaseArmorMod(float addvalue,bool apply) { ApplyBaseResistanceMod(SPELL_SCHOOL_NORMAL,addvalue,apply); }
+        void SetBaseResistance(SpellSchools res,float value) { m_BaseResistance[res] = value; CascadeUpdateResistance(res); }
+        void ApplyBaseResistanceMod(SpellSchools res,float addvalue,bool apply) { m_BaseResistance[res] += (apply ? addvalue : -addvalue); CascadeUpdateResistance(res); }
+        void CascadeUpdateResistance(SpellSchools res);
     protected:
         Unit ( );
 
-        void _RemoveStatsMods();
-        void _ApplyStatsMods();
+        void _ApplyStats(bool apply);
 
         void _RemoveAllAuraMods();
         void _ApplyAllAuraMods();
@@ -673,6 +674,9 @@
         long m_AuraModifiers[TOTAL_AURAS];
         //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS];  // TODO: use this if ok for mem
 
+        //// Cascade Update System /////////////////////////
+        float m_BaseStat[MAX_STATS];                        // Base Stats      (with not applied percent modifiers)
+        float m_BaseResistance[SPELL_SCHOOL_COUNT];         // Base Resistance (with not applied percent modifiers)
     private:
         void SendAttackStop(Unit* victim);                  // only from AttackStop(Unit*)
         void SendAttackStart(Unit* pVictim);                // only from Unit::AttackStart(Unit*)