Index: /trunk/src/game/Unit.h
===================================================================
--- /trunk/src/game/Unit.h (revision 215)
+++ /trunk/src/game/Unit.h (revision 226)
@@ -40,9 +40,9 @@
 enum SpellInterruptFlags
 {
-    SPELL_INTERRUPT_FLAG_MOVEMENT     = 0x01,
-    SPELL_INTERRUPT_FLAG_DAMAGE       = 0x02,
-    SPELL_INTERRUPT_FLAG_INTERRUPT    = 0x04,
-    SPELL_INTERRUPT_FLAG_AUTOATTACK   = 0x08,
-    //SPELL_INTERRUPT_FLAG_TURNING      = 0x10              // not turning - maybe _complete_ interrupt on direct damage?
+    SPELL_INTERRUPT_FLAG_MOVEMENT     = 0x01, // why need this for instant?
+    SPELL_INTERRUPT_FLAG_PUSH_BACK    = 0x02, // push back
+    SPELL_INTERRUPT_FLAG_INTERRUPT    = 0x04, // interrupt
+    SPELL_INTERRUPT_FLAG_AUTOATTACK   = 0x08, // no
+    SPELL_INTERRUPT_FLAG_DAMAGE       = 0x10  // _complete_ interrupt on direct damage?
 };
 
@@ -1189,4 +1189,7 @@
 
         Aura* GetDummyAura(uint32 spell_id) const;
+        uint32 GetInterruptMask() const { return m_interruptMask; }
+        void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; }
+        void UpdateInterruptMask();
 
         uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); }
@@ -1335,4 +1338,5 @@
 
         AuraList m_modAuras[TOTAL_AURAS];
+        uint32 m_interruptMask;
         AuraList m_interruptableAuras;
         AuraList m_ccAuras;
Index: /trunk/src/game/ArenaTeam.cpp
===================================================================
--- /trunk/src/game/ArenaTeam.cpp (revision 207)
+++ /trunk/src/game/ArenaTeam.cpp (revision 226)
@@ -11,10 +11,10 @@
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
Index: /trunk/src/game/SharedDefines.h
===================================================================
--- /trunk/src/game/SharedDefines.h (revision 168)
+++ /trunk/src/game/SharedDefines.h (revision 226)
@@ -221,9 +221,9 @@
 #define SPELL_ATTR_STOP_ATTACK_TARGET             0x00100000            // 20 Stop attack after use this spell (and not begin attack if use)
 #define SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK   0x00200000            // 21 Cannot be dodged/parried/blocked
-#define SPELL_ATTR_UNK22                          0x00400000            // 22
+#define SPELL_ATTR_UNK22                          0x00400000            // 22 shoot spells
 #define SPELL_ATTR_UNK23                          0x00800000            // 23 castable while dead?
 #define SPELL_ATTR_CASTABLE_WHILE_MOUNTED         0x01000000            // 24 castable while mounted
 #define SPELL_ATTR_DISABLED_WHILE_ACTIVE          0x02000000            // 25 Activate and start cooldown after aura fade or remove summoned creature or go
-#define SPELL_ATTR_UNK26                          0x04000000            // 26
+#define SPELL_ATTR_UNK26                          0x04000000            // 26 Aura ignore immune?
 #define SPELL_ATTR_CASTABLE_WHILE_SITTING         0x08000000            // 27 castable while sitting
 #define SPELL_ATTR_CANT_USED_IN_COMBAT            0x10000000            // 28 Cannot be used in combat
@@ -267,5 +267,5 @@
 #define SPELL_ATTR_EX2_UNK0                       0x00000001            // 0
 #define SPELL_ATTR_EX2_UNK1                       0x00000002            // 1
-#define SPELL_ATTR_EX2_UNK2                       0x00000004            // 2
+#define SPELL_ATTR_EX2_UNK2                       0x00000004            // 2 boss spells?
 #define SPELL_ATTR_EX2_UNK3                       0x00000008            // 3
 #define SPELL_ATTR_EX2_UNK4                       0x00000010            // 4
@@ -306,5 +306,5 @@
 #define SPELL_ATTR_EX3_UNK6                       0x00000040            // 6
 #define SPELL_ATTR_EX3_UNK7                       0x00000080            // 7
-#define SPELL_ATTR_EX3_UNK8                       0x00000100            // 8
+#define SPELL_ATTR_EX3_PLAYERS_ONLY               0x00000100            // 8 Player only?
 #define SPELL_ATTR_EX3_UNK9                       0x00000200            // 9
 #define SPELL_ATTR_EX3_MAIN_HAND                  0x00000400            // 10 Main hand weapon required
Index: /trunk/src/game/ArenaTeamHandler.cpp
===================================================================
--- /trunk/src/game/ArenaTeamHandler.cpp (revision 102)
+++ /trunk/src/game/ArenaTeamHandler.cpp (revision 226)
@@ -11,10 +11,10 @@
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 217)
+++ /trunk/src/game/Unit.cpp (revision 226)
@@ -182,4 +182,5 @@
     m_Visibility = VISIBILITY_ON;
 
+    m_interruptMask = 0;
     m_detectInvisibilityMask = 0;
     m_invisibilityMask = 0;
@@ -466,4 +467,8 @@
 void Unit::RemoveAurasWithInterruptFlags(uint32 flag)
 {
+    if(!(m_interruptMask & flag))
+        return;
+
+    // interrupt auras
     AuraList::iterator iter, next;
     for (iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); iter = next)
@@ -479,7 +484,25 @@
                 next = m_interruptableAuras.begin();
             else
-                return;
-        }
-    }
+                break;
+        }
+    }
+
+    // interrupt channeled spell
+    if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
+        if(spell->getState() == SPELL_STATE_CASTING && (spell->m_spellInfo->AuraInterruptFlags & flag))
+            InterruptNonMeleeSpells(false);
+}
+
+void Unit::UpdateInterruptMask()
+{
+    m_interruptMask = 0;
+    for(AuraList::iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
+    {
+        if(*i)
+            m_interruptMask |= (*i)->GetSpellProto()->AuraInterruptFlags;
+    }
+    if(Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
+        if(spell->getState() == SPELL_STATE_CASTING)
+            m_interruptMask |= spell->m_spellInfo->AuraInterruptFlags;
 }
 
@@ -527,20 +550,9 @@
     }
 
-    // remove affects from victim (including from 0 damage and DoTs)
-    //if(pVictim != this)
-    //    pVictim->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
-
-    // remove affects from attacker at any non-DoT damage (including 0 damage)
-    if( damagetype != DOT)
-    {
-        if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED))
-            pVictim->SetStandState(PLAYER_STATE_NONE);
-    }
-
     //Script Event damage taken
     if( pVictim->GetTypeId()== TYPEID_UNIT && ((Creature *)pVictim)->AI() )
         ((Creature *)pVictim)->AI()->DamageTaken(this, damage);
 
-    if(!damage)
+    if(!damage) //when will zero damage? need interrupt aura?
     {
         // Rage from physical damage received .
@@ -869,8 +881,4 @@
         }
 
-        // polymorphed and other negative transformed cases
-        if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED))
-            pVictim->RemoveAurasDueToSpell(pVictim->getTransForm());
-
         if(damagetype == DIRECT_DAMAGE|| damagetype == SPELL_DIRECT_DAMAGE)
             pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE);
@@ -910,66 +918,35 @@
         }
 
-        // TODO: Store auras by interrupt flag to speed this up.
-        /*AuraMap& vAuras = pVictim->GetAuras();
-        for (AuraMap::iterator i = vAuras.begin(), next; i != vAuras.end(); i = next)
-        {
-            const SpellEntry *se = i->second->GetSpellProto();
-            next = i; ++next;
-            if( se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE )
-            {
-                bool remove = true;
-                if (se->procFlags & (1<<3))
-                {
-                    if (!roll_chance_i(se->procChance))
-                        remove = false;
-                }
-                if (remove)
-                {
-                    pVictim->RemoveAurasDueToSpell(i->second->GetId());
-                    // FIXME: this may cause the auras with proc chance to be rerolled several times
-                    next = vAuras.begin();
-                }
-            }
-            else */
-        pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE);
-        pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0);
-
-        if (damagetype != NODAMAGE && damage && pVictim->GetTypeId() == TYPEID_PLAYER)
-        {
-            if( damagetype != DOT )
-            {
-                for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
-                {
-                    // skip channeled spell (processed differently below)
-                    if (i == CURRENT_CHANNELED_SPELL)
-                        continue;
-
-                    if(Spell* spell = pVictim->m_currentSpells[i])
+        if (damagetype != NODAMAGE && damage)// && pVictim->GetTypeId() == TYPEID_PLAYER)
+        {
+            //if (se->procFlags & (1<<3))
+            pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DAMAGE);
+            pVictim->RemoveSpellbyDamageTaken(damage, spellProto ? spellProto->Id : 0);
+
+            if(pVictim != this && pVictim->GetTypeId() == TYPEID_PLAYER) // does not support creature push_back
+            {
+                if(damagetype != DOT)
+                {
+                    if(Spell* spell = pVictim->m_currentSpells[CURRENT_GENERIC_SPELL])
+                    {
                         if(spell->getState() == SPELL_STATE_PREPARING)
-                            spell->Delayed();
-                }
-            }
-
-            if(Spell* spell = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
-            {
-                if (spell->getState() == SPELL_STATE_CASTING)
-                {
-                    uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags;
-                    if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
+                        {
+                            uint32 interruptFlags = spell->m_spellInfo->InterruptFlags;
+                            if(interruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)
+                                pVictim->InterruptNonMeleeSpells(false);
+                            else if(interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK)
+                                spell->Delayed();
+                        }
+                    }
+                }
+
+                if(Spell* spell = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
+                {
+                    if(spell->getState() == SPELL_STATE_CASTING)
                     {
-                        if(pVictim!=this)                   //don't shorten the duration of channeling if you damage yourself
+                        uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags;
+                        if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
                             spell->DelayedChannel();
                     }
-                    else if( (channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) )
-                    {
-                        sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id);
-                        pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
-                    }
-                }
-                else if (spell->getState() == SPELL_STATE_DELAYED)
-                    // break channeled spell in delayed state on damage
-                {
-                    sLog.outDetail("Spell %u canceled at damage!",spell->m_spellInfo->Id);
-                    pVictim->InterruptSpell(CURRENT_CHANNELED_SPELL);
                 }
             }
@@ -3796,5 +3773,8 @@
         m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur);
         if(Aur->GetSpellProto()->AuraInterruptFlags)
+        {
             m_interruptableAuras.push_back(Aur);
+            AddInterruptMask(Aur->GetSpellProto()->AuraInterruptFlags);
+        }
         if(Aur->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
         {
@@ -4164,5 +4144,8 @@
         m_modAuras[(*i).second->GetModifier()->m_auraname].remove((*i).second);
         if((*i).second->GetSpellProto()->AuraInterruptFlags)
+        {
             m_interruptableAuras.remove((*i).second);
+            UpdateInterruptMask();
+        }
         if((*i).second->GetSpellProto()->Attributes & SPELL_ATTR_BREAKABLE_BY_DAMAGE)
             m_ccAuras.remove((*i).second);
@@ -8485,4 +8468,7 @@
 void Unit::CombatStart(Unit* target)
 {
+    if(!target->IsStandState() && !target->hasUnitState(UNIT_STAT_STUNNED))
+        target->SetStandState(PLAYER_STATE_NONE);
+
     if(!target->isInCombat() && target->GetTypeId() != TYPEID_PLAYER && ((Creature*)target)->AI())
         ((Creature*)target)->AI()->AttackStart(this);
Index: /trunk/src/game/Spell.cpp
===================================================================
--- /trunk/src/game/Spell.cpp (revision 220)
+++ /trunk/src/game/Spell.cpp (revision 226)
@@ -955,7 +955,4 @@
         if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
         {
-            if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))
-                unit->SetStandState(PLAYER_STATE_NONE);
-
             m_caster->CombatStart(unit);
         }
@@ -1283,5 +1280,5 @@
         cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(m_caster->GetMapId(), m_caster));
     }
-    if(!(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_PLAYERS_ONLY))
+    if(!(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY))
     {
         TypeContainerVisitor<Trinity::SpellNotifierCreatureAndPlayer, GridTypeMapContainer >  grid_object_notifier(notifier);
@@ -2298,5 +2295,5 @@
 
     // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
-    if (m_spellInfo->speed > 0.0f)
+    if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo))
     {
 
@@ -2325,4 +2322,5 @@
     {
         m_spellState = SPELL_STATE_CASTING;
+        m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
         SendChannelStart(GetSpellDuration(m_spellInfo));
     }
@@ -2568,8 +2566,9 @@
     {
         // always cancel for channeled spells
-        if( m_spellState == SPELL_STATE_CASTING )
-            cancel();
+        //if( m_spellState == SPELL_STATE_CASTING )
+        //    cancel();
         // don't cancel for melee, autorepeat, triggered and instant spells
-        else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
+        //else
+        if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
             cancel();
     }
@@ -2602,8 +2601,4 @@
                     // check for incapacitating player states
                     if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
-                        cancel();
-
-                    // check if player has turned if flag is set
-                    if( m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation() )
                         cancel();
                 }
@@ -2669,4 +2664,7 @@
     if(!m_caster)
         return;
+
+    if(IsChanneledSpell(m_spellInfo))
+        m_caster->UpdateInterruptMask();
 
     if(m_spellState == SPELL_STATE_FINISHED)
@@ -4762,15 +4760,15 @@
 }
 
-void Spell::Delayed()
-{
-    if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER)
-        return;
-
-    if (m_spellState == SPELL_STATE_DELAYED)
-        return;                                             // spell is active and can't be time-backed
+void Spell::Delayed() // only called in DealDamage()
+{
+    if(!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER)
+        return;
+
+    //if (m_spellState == SPELL_STATE_DELAYED)
+    //    return;                                             // spell is active and can't be time-backed
 
     // spells not loosing casting time ( slam, dynamites, bombs.. )
-    if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
-        return;
+    //if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
+    //    return;
 
     //check resist chance
