Index: /trunk/src/game/SpellEffects.cpp
===================================================================
--- /trunk/src/game/SpellEffects.cpp (revision 207)
+++ /trunk/src/game/SpellEffects.cpp (revision 213)
@@ -3480,5 +3480,5 @@
         {
             // Reveal action + get attack
-            m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_STEALTH);
+            m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LOOT);
             if (((Creature*)unitTarget)->AI())
                 ((Creature*)unitTarget)->AI()->AttackStart(m_caster);
Index: /trunk/src/game/Unit.h
===================================================================
--- /trunk/src/game/Unit.h (revision 203)
+++ /trunk/src/game/Unit.h (revision 213)
@@ -58,28 +58,27 @@
 enum SpellAuraInterruptFlags
 {
-    AURA_INTERRUPT_FLAG_UNK0                = 0x00000001,   // 0    removed when getting hit by a negative spell?
+    AURA_INTERRUPT_FLAG_HITBYSPELL          = 0x00000001,   // 0    removed when getting hit by a negative spell?
     AURA_INTERRUPT_FLAG_DAMAGE              = 0x00000002,   // 1    removed by any damage
-    AURA_INTERRUPT_FLAG_UNK2                = 0x00000004,   // 2
+    AURA_INTERRUPT_FLAG_CC                  = 0x00000004,   // 2    crowd control
     AURA_INTERRUPT_FLAG_MOVE                = 0x00000008,   // 3    removed by any movement
     AURA_INTERRUPT_FLAG_TURNING             = 0x00000010,   // 4    removed by any turning
-    AURA_INTERRUPT_FLAG_ENTER_COMBAT        = 0x00000020,   // 5    removed by entering combat
+    AURA_INTERRUPT_FLAG_JUMP                = 0x00000020,   // 5    removed by entering combat
     AURA_INTERRUPT_FLAG_NOT_MOUNTED         = 0x00000040,   // 6    removed by unmounting
     AURA_INTERRUPT_FLAG_NOT_ABOVEWATER      = 0x00000080,   // 7    removed by entering water
     AURA_INTERRUPT_FLAG_NOT_UNDERWATER      = 0x00000100,   // 8    removed by leaving water
     AURA_INTERRUPT_FLAG_NOT_SHEATHED        = 0x00000200,   // 9    removed by unsheathing
-    AURA_INTERRUPT_FLAG_UNK10               = 0x00000400,   // 10
-    AURA_INTERRUPT_FLAG_UNK11               = 0x00000800,   // 11
-    AURA_INTERRUPT_FLAG_UNK12               = 0x00001000,   // 12   removed by attack?
-    AURA_INTERRUPT_FLAG_UNK13               = 0x00002000,   // 13
-    AURA_INTERRUPT_FLAG_STEALTH             = 0x00003C00,
+    AURA_INTERRUPT_FLAG_LOOT                = 0x00000400,   // 10
+    AURA_INTERRUPT_FLAG_MOUNT               = 0x00000800,   // 11   removed by mounting
+    AURA_INTERRUPT_FLAG_ATTACK              = 0x00001000,   // 12   removed by attacking
+    AURA_INTERRUPT_FLAG_CAST                = 0x00002000,   // 13   ???
     AURA_INTERRUPT_FLAG_UNK14               = 0x00004000,   // 14
-    AURA_INTERRUPT_FLAG_UNK15               = 0x00008000,   // 15   removed by casting a spell?
+    AURA_INTERRUPT_FLAG_TRANSFORM           = 0x00008000,   // 15   removed by transform?
     AURA_INTERRUPT_FLAG_UNK16               = 0x00010000,   // 16
-    AURA_INTERRUPT_FLAG_MOUNTING            = 0x00020000,   // 17   removed by mounting
+    AURA_INTERRUPT_FLAG_UNK17               = 0x00020000,   // 17   misdirect, aspect, swim speed
     AURA_INTERRUPT_FLAG_NOT_SEATED          = 0x00040000,   // 18   removed by standing up
     AURA_INTERRUPT_FLAG_CHANGE_MAP          = 0x00080000,   // 19   leaving map/getting teleported
-    AURA_INTERRUPT_FLAG_UNK20               = 0x00100000,   // 20
+    AURA_INTERRUPT_FLAG_UNATTACKABLE        = 0x00100000,   // 20   invulnerable or stealth
     AURA_INTERRUPT_FLAG_UNK21               = 0x00200000,   // 21
-    AURA_INTERRUPT_FLAG_UNK22               = 0x00400000,   // 22
+    AURA_INTERRUPT_FLAG_TELEPORTED          = 0x00400000,   // 22
     AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT    = 0x00800000,   // 23   removed by entering pvp combat
     AURA_INTERRUPT_FLAG_DIRECT_DAMAGE       = 0x01000000    // 24   removed by any direct damage
@@ -845,4 +844,5 @@
 
         uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
+        void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell);
         uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
         void DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, bool isTriggeredSpell = false);
@@ -903,4 +903,5 @@
 
         bool isInCombat()  const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); }
+        void CombatStart(Unit* target);
         void SetInCombatState(bool PvP);
         void SetInCombatWith(Unit* enemy);
@@ -1335,4 +1336,5 @@
         AuraList m_modAuras[TOTAL_AURAS];
         AuraList m_interruptableAuras;
+        AuraList m_ccAuras;
         float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
         float m_weaponDamage[MAX_ATTACK][2];
Index: /trunk/src/game/SpellAuras.cpp
===================================================================
--- /trunk/src/game/SpellAuras.cpp (revision 207)
+++ /trunk/src/game/SpellAuras.cpp (revision 213)
@@ -3072,4 +3072,5 @@
         m_target->addUnitState(UNIT_STAT_DIED);
         m_target->CombatStop();
+        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
 
         // prevent interrupt message
@@ -3211,9 +3212,6 @@
         {
             // drop flag at stealth in bg
-            if(((Player*)m_target)->InBattleGround())
-            {
-                if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
-                    bg->EventPlayerDroppedFlag((Player*)m_target);
-            }
+            m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+
             // remove player from the objective's active player count at stealth
             if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
@@ -3299,4 +3297,6 @@
         m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
 
+        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+
         if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
         {
@@ -3306,9 +3306,4 @@
             if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
                 pvp->HandlePlayerActivityChanged((Player*)m_target);
-
-            // drop flag at invisible in bg
-            if(((Player*)m_target)->InBattleGround())
-                if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
-                    bg->EventPlayerDroppedFlag((Player*)m_target);
         }
 
@@ -3817,4 +3812,7 @@
 void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
 {
+    if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL)
+        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ 
     m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
 
@@ -5377,5 +5375,8 @@
 {
     if(Real && Apply)
+    {
         m_target->CombatStop();
+        m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+    }
 
     m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply);
Index: /trunk/src/game/Player.h
===================================================================
--- /trunk/src/game/Player.h (revision 207)
+++ /trunk/src/game/Player.h (revision 213)
@@ -1915,4 +1915,5 @@
         bool GetBGAccessByLevel(uint32 bgTypeId) const;
         bool isAllowUseBattleGroundObject();
+        bool isTotalImmunity();
 
         /*********************************************************/
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 186)
+++ /trunk/src/game/Unit.cpp (revision 213)
@@ -473,5 +473,5 @@
 
         //sLog.outDetail("auraflag:%u flag:%u = %u",(*iter)->GetSpellProto()->AuraInterruptFlags,flag,(*iter)->GetSpellProto()->AuraInterruptFlags & flag);
-        if(*iter && ((*iter)->GetSpellProto()->AuraInterruptFlags & flag) == flag)
+        if(*iter && ((*iter)->GetSpellProto()->AuraInterruptFlags & flag))
         {
             RemoveAurasDueToSpell((*iter)->GetId());
@@ -489,4 +489,28 @@
 }
 
+/* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */
+void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell)
+{
+    // The chance to dispel an aura depends on the damage taken with respect to the casters level.
+    uint32 max_dmg = getLevel() > 8 ? 25 * getLevel() - 150 : 50;
+    float chance = float(damage) / max_dmg * 100.0f;
+
+    AuraList::iterator i, next;
+    for(i = m_ccAuras.begin(); i != m_ccAuras.end(); i = next)
+    {
+        next = i;
+        ++next;
+
+        if(*i && (!spell || (*i)->GetId() != spell) && roll_chance_f(chance))
+        {
+            RemoveAurasDueToSpell((*i)->GetId());
+            if (!m_ccAuras.empty())
+                next = m_ccAuras.begin();
+            else
+                return;
+        }
+    }
+}
+
 uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
 {
@@ -510,6 +534,4 @@
     if( damagetype != DOT)
     {
-        RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_STEALTH);
-
         if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED))
             pVictim->SetStandState(PLAYER_STATE_NONE);
@@ -889,5 +911,5 @@
 
         // TODO: Store auras by interrupt flag to speed this up.
-        AuraMap& vAuras = pVictim->GetAuras();
+        /*AuraMap& vAuras = pVictim->GetAuras();
         for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next)
         {
@@ -909,15 +931,7 @@
                 }
             }
-            else if ( (se->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE) && (!spellProto || se->Id != spellProto->Id) )
-            {
-                uint32 max_dmg = pVictim->getLevel() > 8 ? 25 * pVictim->getLevel() - 150 : 50;
-                float chance = float(damage) / max_dmg * 100.0f;
-                if (roll_chance_f(chance))
-                {
-                    pVictim->RemoveAurasDueToSpell(i->second->GetId());
-                    next = vAuras.begin();
-                }
-            }
-        }
+            else */
+        RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE);
+        pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0);
 
         if (damagetype != NODAMAGE && damage && pVictim->GetTypeId() == TYPEID_PLAYER)
@@ -2193,12 +2207,5 @@
         return;
 
-    if(!pVictim->isInCombat() && pVictim->GetTypeId() != TYPEID_PLAYER && ((Creature*)pVictim)->AI())
-        ((Creature*)pVictim)->AI()->AttackStart(this);
-
-    SetInCombatWith(pVictim);
-    pVictim->SetInCombatWith(this);
-
-    if(Player* attackedPlayer = pVictim->GetCharmerOrOwnerPlayerOrPlayerItself())
-        SetContestedPvP(attackedPlayer);
+    CombatStart(pVictim);
 
     uint32 hitInfo;
@@ -3790,4 +3797,9 @@
         if(Aur->GetSpellProto()->AuraInterruptFlags)
             m_interruptableAuras.push_back(Aur);
+        if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
+        {
+            m_ccAuras.push_back(Aur);
+            RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC);
+        }
     }
 
@@ -4153,4 +4165,6 @@
         if((*i).second->GetSpellProto()->AuraInterruptFlags)
             m_interruptableAuras.remove((*i).second);
+        if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
+            m_ccAuras.remove((*i).second);
     }
 
@@ -8399,5 +8413,5 @@
         return;
 
-    RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNTING);
+    RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
 
     SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount);
@@ -8467,4 +8481,19 @@
     }
     SetInCombatState(false);
+}
+
+void Unit::CombatStart(Unit* target)
+{
+    if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI())
+        ((Creature*)target)->AI()->AttackStart(this);
+
+    SetInCombatWith(target);
+    target->SetInCombatWith(this);
+
+    if(Player* attackedPlayer = target->GetCharmerOrOwnerPlayerOrPlayerItself())
+        SetContestedPvP(attackedPlayer);
+
+    if(!isInCombat()) // remove this?
+        RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ATTACK);
 }
 
Index: /trunk/src/game/Player.cpp
===================================================================
--- /trunk/src/game/Player.cpp (revision 212)
+++ /trunk/src/game/Player.cpp (revision 213)
@@ -16606,5 +16606,5 @@
 
     // prevent stealth flight
-    RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_STEALTH);
+    RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LOOT);
 
     WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
@@ -18886,4 +18886,5 @@
     return ( //InBattleGround() &&                            // in battleground - not need, check in other cases
              !IsMounted() &&                                  // not mounted
+             !isTotalImmunity() &&                              // not totally immuned
              !HasStealthAura() &&                             // not stealthed
              !HasInvisibilityAura() &&                        // not invisible
@@ -18901,2 +18902,26 @@
     return false;
 }
+
+bool Player::isTotalImmunity()
+{
+    AuraList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
+
+    for(AuraList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
+    {
+        if (((*itr)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_ALL) !=0)   // total immunity
+        {
+            return true;
+        }
+        if (((*itr)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) !=0)   // physical damage immunity
+        {
+            for(AuraList::const_iterator i = immune.begin(); i != immune.end(); ++i)
+            {
+                if (((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) !=0)   // magic immunity
+                {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
Index: /trunk/src/game/Spell.cpp
===================================================================
--- /trunk/src/game/Spell.cpp (revision 203)
+++ /trunk/src/game/Spell.cpp (revision 213)
@@ -957,12 +957,5 @@
                 unit->SetStandState(PLAYER_STATE_NONE);
 
-            if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI())
-                ((Creature*)unit)->AI()->AttackStart(m_caster);
-
-            unit->SetInCombatWith(m_caster);
-            m_caster->SetInCombatWith(unit);
-
-            if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
-                m_caster->SetContestedPvP(attackedPlayer);
+            m_caster->CombatStart(unit);
         }
     }
@@ -1003,9 +996,5 @@
             }
 
-            //if(!IsPositiveSpell(m_spellInfo->Id))
-            {
-                //do not remove feign death
-                unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_STEALTH + AURA_INTERRUPT_FLAG_DAMAGE);
-            }
+            unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
         }
         else
@@ -2248,5 +2237,5 @@
     if ( !m_IsTriggeredSpell && isSpellBreakStealth(m_spellInfo) )
     {
-        m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_STEALTH);
+        m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST);
     }
 
