All pastes #987294 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-04-16 12:37 UTC
rendered paste body
Index: src/game/HostilRefManager.cpp
===================================================================
--- src/game/HostilRefManager.cpp	(revision 5635)
+++ src/game/HostilRefManager.cpp	(working copy)
@@ -20,6 +20,7 @@
 #include "ThreatManager.h"
 #include "Unit.h"
 #include "Database/DBCStructure.h"
+#include "SpellMgr.h"
 
 HostilRefManager::~HostilRefManager()
 {
@@ -39,7 +40,7 @@
     ref = getFirst();
     while(ref != NULL)
     {
-        float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, (pThreatSpell ? SpellSchools(pThreatSpell->School) : SPELL_SCHOOL_NORMAL), pThreatSpell);
+        float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
         if(pVictim == getOwner())
             ref->addThreat(float (threat) / size);          // It is faster to modify the threat durectly if possible
         else
Index: src/game/Level3.cpp
===================================================================
--- src/game/Level3.cpp	(revision 5636)
+++ src/game/Level3.cpp	(working copy)
@@ -2802,7 +2802,7 @@
 
     if( target->isAlive() )
     {
-        m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
+        m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
     }
 
     return true;
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 5636)
+++ src/game/Player.cpp	(working copy)
@@ -609,7 +609,7 @@
     //m_session->SendPacket(&data);
     //Let other players see that you get damage
     SendMessageToSet(&data, true);
-    DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
+    DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
 
     if(type==DAMAGE_FALL && !isAlive())                     // DealDamage not apply item durability loss at self damage
     {
@@ -1934,7 +1934,7 @@
 
 bool Player::IsInSameGroupWith(Player const* p) const
 {
-    return  GetGroup() != NULL &&
+    return  p==this || GetGroup() != NULL &&
         GetGroup() == p->GetGroup() &&
         GetGroup()->SameSubGroup((Player*)this, (Player*)p);
 }
@@ -15324,7 +15324,7 @@
     return true;
 }
 
-void Player::ProhibitSpellScholl(SpellSchools idSchool, uint32 unTimeMs )
+void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs )
 {
                                                             // last check 2.0.10
     WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8);
@@ -15342,7 +15342,7 @@
             ASSERT(spellInfo);
             continue;
         }
-        if(idSchool == SpellSchools(spellInfo->School) && GetSpellCooldownDelay(unSpellId) < unTimeMs )
+        if((idSchoolMask & GetSpellSchoolMask(spellInfo)) && GetSpellCooldownDelay(unSpellId) < unTimeMs )
         {
             data << unSpellId;
             data << unTimeMs;                               // in m.secs
Index: src/game/Player.h
===================================================================
--- src/game/Player.h	(revision 5635)
+++ src/game/Player.h	(working copy)
@@ -1389,7 +1389,7 @@
             return itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0;
         }
         void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time);
-        void ProhibitSpellScholl(SpellSchools idSchool, uint32 unTimeMs );
+        void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs );
         void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); }
         void RemoveAllSpellCooldown();
         void _LoadSpellCooldowns(QueryResult *result);
@@ -1432,7 +1432,7 @@
 
         bool IsGroupVisibleFor(Player* p) const;
         bool IsInSameGroupWith(Player const* p) const;
-        bool IsInSameRaidWith(Player const* p) const { return GetGroup() != NULL && GetGroup() == p->GetGroup(); }
+        bool IsInSameRaidWith(Player const* p) const { return p==this || GetGroup() != NULL && GetGroup() == p->GetGroup(); }
         void UninviteFromGroup();
         static void RemoveFromGroup(Group* group, uint64 guid);
         void RemoveFromGroup() { RemoveFromGroup(GetGroup(),GetGUID()); }
Index: src/game/SharedDefines.h
===================================================================
--- src/game/SharedDefines.h	(revision 5635)
+++ src/game/SharedDefines.h	(working copy)
@@ -148,6 +148,27 @@
 
 #define MAX_SPELL_SCHOOL                  7
 
+enum SpellSchoolMask
+{
+    SPELL_SCHOOL_MASK_NONE    = 0x00,                       // not exist
+    SPELL_SCHOOL_MASK_NORMAL  = (1 << SPELL_SCHOOL_NORMAL), // PHYSICAL (Armor)
+    SPELL_SCHOOL_MASK_HOLY    = (1 << SPELL_SCHOOL_HOLY  ),
+    SPELL_SCHOOL_MASK_FIRE    = (1 << SPELL_SCHOOL_FIRE  ),
+    SPELL_SCHOOL_MASK_NATURE  = (1 << SPELL_SCHOOL_NATURE),
+    SPELL_SCHOOL_MASK_FROST   = (1 << SPELL_SCHOOL_FROST ),
+    SPELL_SCHOOL_MASK_SHADOW  = (1 << SPELL_SCHOOL_SHADOW),
+    SPELL_SCHOOL_MASK_ARCANE  = (1 << SPELL_SCHOOL_ARCANE)
+};
+
+inline SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
+{
+    for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
+        if(mask & (1 << i))
+            return SpellSchools(i);
+
+    return SPELL_SCHOOL_NORMAL;
+}
+
 enum ItemQualities
 {
     ITEM_QUALITY_POOR                  = 0,                 //GREY
@@ -488,24 +509,6 @@
     IMMUNE_SCHOOL_MAGIC        = 126
 };
 
-inline SpellSchools immuneToSchool(ImmuneToSchool immune)
-{
-    switch(immune)
-    {
-        case IMMUNE_SCHOOL_PHYSICAL: return SPELL_SCHOOL_NORMAL;
-        case IMMUNE_SCHOOL_HOLY:     return SPELL_SCHOOL_HOLY;
-        case IMMUNE_SCHOOL_FIRE:     return SPELL_SCHOOL_FIRE;
-        case IMMUNE_SCHOOL_NATURE:   return SPELL_SCHOOL_NATURE;
-        case IMMUNE_SCHOOL_FROST:    return SPELL_SCHOOL_FROST;
-        case IMMUNE_SCHOOL_SHADOW:   return SPELL_SCHOOL_SHADOW;
-        case IMMUNE_SCHOOL_ARCANE:   return SPELL_SCHOOL_ARCANE;
-        case IMMUNE_SCHOOL_MAGIC:    break;
-    }
-
-    assert(false);
-    return SPELL_SCHOOL_NORMAL;
-}
-
 enum Targets
 {
     TARGET_SELF                        = 1,
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 5636)
+++ src/game/Spell.cpp	(working copy)
@@ -281,15 +281,16 @@
          else                         m_attackType = BASE_ATTACK;
          break;
     }
-    m_spellSchool = SpellSchools(info->School);             // Can be override for some spell (wand shoot for example)
 
+    m_spellSchoolMask = GetSpellSchoolMask(info);           // Can be override for some spell (wand shoot for example)
+
     if(m_attackType == RANGED_ATTACK)
     {
         // wand case
         if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId()==TYPEID_PLAYER)
         {
             if(Item* pItem = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
-                m_spellSchool = SpellSchools(pItem->GetProto()->Damage->DamageType);
+                m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
         }
     }
 
@@ -992,13 +993,13 @@
 struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*, bool>
 {
     const Unit* MainTarget;
-    ChainHealingOrder(const Unit* Target) : MainTarget(Target) {};
+    ChainHealingOrder(Unit const* Target) : MainTarget(Target) {};
     // functor for operator ">"
-    bool operator()(const Unit* _Left, const Unit* _Right) const
+    bool operator()(Unit const* _Left, Unit const* _Right) const
     {
         return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
     }
-    int32 ChainHealingHash(const Unit* Target) const
+    int32 ChainHealingHash(Unit const* Target) const
     {
         if (Target == MainTarget)
             return 0;
@@ -3451,7 +3452,7 @@
                     return SPELL_FAILED_BAD_TARGETS;
 
                 Player* target = objmgr.GetPlayer(((Player*)m_caster)->GetSelection());
-                if( !target || !target->IsInSameGroupWith((Player*)m_caster) )
+                if( !target || ((Player*)m_caster)==target || !target->IsInSameGroupWith((Player*)m_caster) )
                     return SPELL_FAILED_BAD_TARGETS;
 
                 if( target->isInCombat() )
@@ -3691,9 +3692,9 @@
         prevented_reason = SPELL_FAILED_CONFUSED;
     else if(m_caster->hasUnitState(UNIT_STAT_FLEEING))
         prevented_reason = SPELL_FAILED_FLEEING;
-    else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && m_spellInfo->School != SPELL_SCHOOL_NORMAL)
+    else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && (GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL)==0)
         prevented_reason = SPELL_FAILED_SILENCED;
-    else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->School == SPELL_SCHOOL_NORMAL && !m_triggeredByAuraSpell)
+    else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && (GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL) && !m_triggeredByAuraSpell)
         prevented_reason = SPELL_FAILED_PACIFIED;
 
     // Attr must make flag drop spell totally immuned from all effects
@@ -3707,8 +3708,8 @@
             {
                 if(itr->second)
                 {
-                    if( ((1 << itr->second->GetSpellProto()->School) & school_immune)     ||
-                        ((1 << itr->second->GetSpellProto()->Mechanic) & mechanic_immune) ||
+                    if( (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune) ||
+                        ((1 << itr->second->GetSpellProto()->Mechanic) & mechanic_immune)  ||
                         ((1 << itr->second->GetSpellProto()->EffectMechanic[itr->second->GetEffIndex()]) & mechanic_immune))
                         continue;
 
@@ -3723,11 +3724,11 @@
                         case SPELL_AURA_MOD_FEAR:
                             return SPELL_FAILED_FLEEING;
                         case SPELL_AURA_MOD_SILENCE:
-                            if(m_spellInfo->School != SPELL_SCHOOL_NORMAL)
+                            if((GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL)==0)
                                 return SPELL_FAILED_SILENCED;
                             break;
                         case SPELL_AURA_MOD_PACIFY:
-                            if(m_spellInfo->School == SPELL_SCHOOL_NORMAL)
+                            if(GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL)
                                 return SPELL_FAILED_PACIFIED;
                             break;
                     }
@@ -3858,8 +3859,11 @@
         else
             manaCost += float(m_spellInfo->ManaCostPercentage)/100.0f * m_caster->GetMaxPower(powerType);
     }
-    manaCost += m_caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+m_spellInfo->School);
 
+    SpellSchools school = GetFirstSchoolInMask(GetSpellSchoolMask(m_spellInfo));
+
+    manaCost += m_caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+school);
+
     // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
     if ( m_spellInfo->manaCost > 0 && m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellInfo->SpellIconID == 1834 )
     {
@@ -3869,7 +3873,7 @@
     if(Player* modOwner = m_caster->GetSpellModOwner())
         modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, manaCost, this);
 
-    manaCost*= (1.0f+m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+m_spellInfo->School));
+    manaCost*= (1.0f+m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+school));
     if (manaCost < 0)
         manaCost = 0;
 
Index: src/game/Spell.h
===================================================================
--- src/game/Spell.h	(revision 5635)
+++ src/game/Spell.h	(working copy)
@@ -407,7 +407,7 @@
         Spell** m_triggeringContainer;                      // pointer to container with spell that has triggered us
 
         //Spell data
-        SpellSchools m_spellSchool;                         // Spell school (can be owerrided for some spells (wand shoot for example)
+        SpellSchoolMask m_spellSchoolMask;                  // Spell school (can be overwrite for some spells (wand shoot for example)
         WeaponAttackType m_attackType;                      // For weapon based attack
         bool m_canReflect;                                  // can reflect this spell?
         bool m_autoRepeat;
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 5635)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -2815,12 +2815,6 @@
     if(!caster || !caster->isAlive())
         return;
 
-    if(m_modifier.m_miscvalue < SPELL_SCHOOL_NORMAL || m_modifier.m_miscvalue >= (1<<MAX_SPELL_SCHOOL))
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_THREAT not valid");
-        return;
-    }
-
     bool positive = m_modifier.m_miscvalue2 == 0;
 
     for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
@@ -3108,10 +3102,10 @@
                 next = iter;
                 ++next;
                 SpellEntry const *spell = iter->second->GetSpellProto();
-                if( ( (1 << spell->School) & school_mask)   //Check for school mask
+                if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
                     && !( spell->Attributes & 0x20000000)   //Spells unaffected by invulnerability
                     && !iter->second->IsPositive()          //Don't remove positive spells
-                    && spell->Id != GetId())                //Don't remove self
+                    && spell->Id != GetId() )               //Don't remove self
                 {
                     m_target->RemoveAurasDueToSpell(spell->Id);
                     if(Auras.empty())
@@ -3314,12 +3308,6 @@
 
 void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
 {
-    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_RESISTANCE_EXCLUS not valid");
-        return;
-    }
-
     bool positive = m_modifier.m_miscvalue2 == 0;
 
     for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
@@ -3335,12 +3323,6 @@
 
 void Aura::HandleAuraModResistance(bool apply, bool Real)
 {
-    if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
-    {
-        sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_RESISTANCE not valid");
-        return;
-    }
-
     bool positive = m_modifier.m_miscvalue2 == 0;
 
     for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
@@ -3356,12 +3338,6 @@
 
 void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
 {
-    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)
     {
@@ -3592,7 +3568,7 @@
     if(m_target->GetTypeId() != TYPEID_PLAYER)
         return;
 
-    if(m_modifier.m_miscvalue != (1<<SPELL_SCHOOL_NORMAL))
+    if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL)
     {
         // support required adding replace UpdateArmor by loop by UpdateResistence at intelect update
         // and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
@@ -4563,7 +4539,7 @@
     }
     // die at aura end
     else
-        m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, GetSpellProto(), false);
+        m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, GetSpellProto(), false);
 }
 
 void Aura::CleanupTriggeredSpells()
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 5635)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -255,7 +255,7 @@
     }
 
     uint32 health = unitTarget->GetHealth();
-    m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
+    m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
 }
 
 void Spell::EffectEnvirinmentalDMG(uint32 i)
@@ -268,9 +268,9 @@
     // currently each eanemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc
     damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i];
 
-    m_caster->CalcAbsorbResist(m_caster,SpellSchools(m_spellInfo->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+    m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
 
-    m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, SpellSchools(m_spellInfo->School), absorb, resist, false, 0, false);
+    m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false);
     if(m_caster->GetTypeId() == TYPEID_PLAYER)
         ((Player*)m_caster)->EnvironmentalDamage(m_caster->GetGUID(),DAMAGE_FIRE,damage);
 }
@@ -937,7 +937,8 @@
                         uint32 classspell = itr->first;
                         SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);
 
-                        if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && spellInfo->School == SPELL_SCHOOL_FROST &&
+                        if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && 
+                            (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) &&
                             spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 )
                         {
                             ((Player*)m_caster)->RemoveSpellCooldown(classspell);
@@ -993,8 +994,8 @@
 
                 if(int32(m_caster->GetHealth()) > dmg)
                 {
-                    m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, dmg, SpellSchools(m_spellInfo->School), 0, 0, false, 0, false);
-                    m_caster->DealDamage(m_caster,dmg,NULL,DIRECT_DAMAGE,SpellSchools(m_spellInfo->School),m_spellInfo,false);
+                    m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, dmg, GetSpellSchoolMask(m_spellInfo), 0, 0, false, 0, false);
+                    m_caster->DealDamage(m_caster,dmg,NULL,DIRECT_DAMAGE,GetSpellSchoolMask(m_spellInfo),m_spellInfo,false);
 
                     int32 mana = dmg;
 
@@ -1477,7 +1478,7 @@
                 if( // ignore positive and passive auras
                     !iter->second->IsPositive() && !iter->second->IsPassive()    &&
                     // ignore physical auras
-                    iter->second->GetSpellProto()->School != SPELL_SCHOOL_NORMAL &&
+                    (GetSpellSchoolMask(iter->second->GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)==0 &&
                     // ignore immunity persistent spells
                     !( iter->second->GetSpellProto()->AttributesEx & 0x10000 ) )
                 {
@@ -3526,8 +3527,8 @@
             // Seal of Command - receive benefit from Spell Damage and Healing
             if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL)
             {
-                bonus += int32(0.20f*m_caster->SpellBaseDamageBonus((int32)(1<<m_spellInfo->School)));
-                bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim((int32)(1<<m_spellInfo->School), unitTarget));
+                bonus += int32(0.20f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));
+                bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget));
             }
             break;
         }
@@ -3557,15 +3558,15 @@
     // prevent negative damage
     uint32 eff_damage = uint32(bonus > 0 ? bonus : 0);
 
-    m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, m_spellSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, m_attackType, m_spellInfo, m_IsTriggeredSpell);
+    m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, m_spellSchoolMask, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, m_attackType, m_spellInfo, m_IsTriggeredSpell);
 
     if ((hitInfo & nohitMask) && m_attackType != RANGED_ATTACK)  // not send ranged miss/etc
-        m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, m_spellSchool, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg);
+        m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, m_spellSchoolMask, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg);
 
     if(hitInfo & HITINFO_CRITICALHIT)
         criticalhit = true;
 
-    m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, m_spellSchool, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit);
+    m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, m_spellSchoolMask, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit);
 
     if (eff_damage > (absorbed_dmg + resisted_dmg + blocked_dmg))
     {
@@ -3578,7 +3579,7 @@
     }
 
     // SPELL_SCHOOL_NORMAL use for weapon-like threat and rage calculation
-    m_caster->DealDamage(unitTarget, eff_damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, true);
+    m_caster->DealDamage(unitTarget, eff_damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, true);
 
     // Hemorrhage
     if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & 0x2000000))
@@ -3659,7 +3660,7 @@
             // check if we can interrupt spell
             if ( unitTarget->m_currentSpells[i]->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTURRUPT )
             {
-                unitTarget->ProhibitSpellScholl(SpellSchools(unitTarget->m_currentSpells[i]->m_spellInfo->School), GetSpellDuration(m_spellInfo));
+                unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), GetSpellDuration(m_spellInfo));
                 unitTarget->InterruptSpell(i,false);
             }
         }
Index: src/game/SpellMgr.cpp
===================================================================
--- src/game/SpellMgr.cpp	(revision 5635)
+++ src/game/SpellMgr.cpp	(working copy)
@@ -218,7 +218,7 @@
     }
 
     // only hunter aspects have this (but not all aspects in hunter family)
-    if( spellInfo->activeIconID == 122 && spellInfo->School == SPELL_SCHOOL_NATURE &&
+    if( spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) &&
         (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0)
     {
         return SPELL_ASPECT;
@@ -861,7 +861,7 @@
 
     // Additional checks in case spell cast/hit/crit is the event
     // Check (if set) school, category, skill line, spell talent mask
-    if(spellProcEvent->schoolMask && (!procSpell || !procSpell->School || ((1<<procSpell->School) & spellProcEvent->schoolMask) == 0))
+    if(spellProcEvent->schoolMask && (!procSpell || (GetSpellSchoolMask(procSpell) & spellProcEvent->schoolMask) == 0))
         return false;
     if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category))
         return false;
Index: src/game/SpellMgr.h
===================================================================
--- src/game/SpellMgr.h	(revision 5635)
+++ src/game/SpellMgr.h	(working copy)
@@ -324,6 +324,12 @@
     return (spellInfo->AttributesEx & 0x44);
 }
 
+inline
+SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)
+{
+    return SpellSchoolMask(1 << spellInfo->School);         // in 2.4.* this will replaced by simple field access
+}
+
 // Spell affects related declarations (accessed using SpellMgr functions)
 struct SpellAffection
 {
Index: src/game/StatSystem.cpp
===================================================================
--- src/game/StatSystem.cpp	(revision 5635)
+++ src/game/StatSystem.cpp	(working copy)
@@ -146,7 +146,7 @@
     //add dynamic flat mods
     AuraList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT);
     for(AuraList::const_iterator i = mResbyIntellect.begin();i != mResbyIntellect.end(); ++i)
-        if((*i)->GetModifier()->m_miscvalue & (1<<SPELL_SCHOOL_NORMAL))
+        if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
             value += int32(GetStat(STAT_INTELLECT) * (*i)->GetModifier()->m_amount / 100.0f);
 
     value *= GetModifierValue(unitMod, TOTAL_PCT);
Index: src/game/ThreatManager.cpp
===================================================================
--- src/game/ThreatManager.cpp	(revision 5635)
+++ src/game/ThreatManager.cpp	(working copy)
@@ -31,7 +31,7 @@
 //==============================================================
 
 // The pHatingUnit is not used yet
-float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, SpellSchools pSchool, SpellEntry const *pThreatSpell)
+float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
 {
     if(pThreatSpell)
     {
@@ -39,7 +39,7 @@
             modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, pThreat);
     }
 
-    float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, pSchool);
+    float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, schoolMask);
     return threat;
 }
 
@@ -325,7 +325,7 @@
 
 //============================================================
 
-void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchools pSchool, SpellEntry const *pThreatSpell)
+void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
 {
     //function deals with adding threat and adding players and pets into ThreatList
     //mobs, NPCs, guards have ThreatList and HateOfflineList
@@ -340,7 +340,7 @@
 
     assert(getOwner()->GetTypeId()== TYPEID_UNIT);
 
-    float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, pSchool, pThreatSpell);
+    float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
 
     HostilReference* ref = iThreatContainer.addThreat(pVictim, threat);
     // Ref is not in the online refs, search the offline refs next
Index: src/game/ThreatManager.h
===================================================================
--- src/game/ThreatManager.h	(revision 5635)
+++ src/game/ThreatManager.h	(working copy)
@@ -39,7 +39,7 @@
 class ThreatCalcHelper
 {
     public:
-        static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float threat, SpellSchools school = SPELL_SCHOOL_NORMAL, SpellEntry const *threatSpell = NULL);
+        static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
 };
 
 //==============================================================
@@ -180,7 +180,7 @@
 
         void clearReferences();
 
-        void addThreat(Unit* pVictim, float threat, SpellSchools school = SPELL_SCHOOL_NORMAL, SpellEntry const *threatSpell = NULL);
+        void addThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
         void modifyThreatPercent(Unit *pVictim, int32 pPercent);
 
         float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 5635)
+++ src/game/Unit.cpp	(working copy)
@@ -422,7 +422,7 @@
         RemoveSpellsCausingAura(auraType);
 }
 
-void Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchools damageSchool, SpellEntry const *spellProto, bool durabilityLoss)
+void Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss)
 {
     if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
         return;
@@ -463,7 +463,7 @@
     if(!damage)
     {
         // Rage from physical damage received .
-        if(cleanDamage && cleanDamage->damage && damageSchool==SPELL_SCHOOL_NORMAL && pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
+        if(cleanDamage && cleanDamage->damage && (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) && pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE))
             ((Player*)pVictim)->RewardRage(cleanDamage->damage, 0, false);
 
         return;
@@ -790,7 +790,7 @@
         {
             if(spellProto && IsDamageToThreatSpell(spellProto))
                 damage *= 2;
-            pVictim->AddThreat(this, damage, damageSchool, spellProto);
+            pVictim->AddThreat(this, damage, damageSchoolMask, spellProto);
         }
         else                                                // victim is a player
         {
@@ -963,299 +963,288 @@
 
 void Unit::DealDamageBySchool(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell)
 {
+    SpellSchoolMask schoolMask = GetSpellSchoolMask(spellInfo);
 
     // TODO this in only generic way, check for exceptions
-    DEBUG_LOG("DealDamageBySchool (BEFORE) SCHOOL %u >> DMG:%u", spellInfo->School, *damage);
+    DEBUG_LOG("DealDamageBySchool (BEFORE) SCHOOL %u (mask: %u) >> DMG:%u", GetFirstSchoolInMask(schoolMask), schoolMask, *damage);
 
-    // Per-school calc
-    switch (spellInfo->School)
+    // Physical damage school
+    if(schoolMask & SPELL_SCHOOL_MASK_NORMAL)
     {
-        // Physical damage school
-        case SPELL_SCHOOL_NORMAL:
-        {
-            // Calculate physical outcome
-            MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo);
+        // Calculate physical outcome
+        MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo);
 
-            //Used to store the Hit Outcome
-            cleanDamage->hitOutCome = outcome;
+        //Used to store the Hit Outcome
+        cleanDamage->hitOutCome = outcome;
 
-            // Return miss/evade first (sends miss message)
-            switch(outcome)
+        // Return miss/evade first (sends miss message)
+        switch(outcome)
+        {
+        case MELEE_HIT_EVADE:
             {
-                case MELEE_HIT_EVADE:
-                {
-                    SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, SpellSchools(spellInfo->School), 0, 0,0,VICTIMSTATE_EVADES,0);
-                    *damage = 0;
-                    return;
-                }
-                case MELEE_HIT_MISS:
-                {
-                    SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, SpellSchools(spellInfo->School), 0, 0,0,VICTIMSTATE_NORMAL,0);
-                    *damage = 0;
+                SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_EVADES,0);
+                *damage = 0;
+                return;
+            }
+        case MELEE_HIT_MISS:
+            {
+                SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_NORMAL,0);
+                *damage = 0;
 
-                    if(GetTypeId()== TYPEID_PLAYER)
-                        ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK);
+                if(GetTypeId()== TYPEID_PLAYER)
+                    ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK);
 
-                    CastMeleeProcDamageAndSpell(pVictim,0,BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell);
-                    return;
-                }
+                CastMeleeProcDamageAndSpell(pVictim,0,BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell);
+                return;
             }
+        }
 
-            //  Hitinfo, Victimstate
-            uint32 hitInfo = HITINFO_NORMALSWING;
-            VictimState victimState = VICTIMSTATE_NORMAL;
+        //  Hitinfo, Victimstate
+        uint32 hitInfo = HITINFO_NORMALSWING;
+        VictimState victimState = VICTIMSTATE_NORMAL;
 
-            //Calculate armor mitigation
-            uint32 damageAfterArmor;
-            damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
-            cleanDamage->damage += *damage - damageAfterArmor;
-            *damage = damageAfterArmor;
+        //Calculate armor mitigation
+        uint32 damageAfterArmor;
+        damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
+        cleanDamage->damage += *damage - damageAfterArmor;
+        *damage = damageAfterArmor;
 
-            uint32 blocked_amount = 0;
+        uint32 blocked_amount = 0;
 
-            // Classify outcome
-            switch (outcome)
+        // Classify outcome
+        switch (outcome)
+        {
+        case MELEE_HIT_BLOCK_CRIT:
+        case MELEE_HIT_CRIT:
             {
-                case MELEE_HIT_BLOCK_CRIT:
-                case MELEE_HIT_CRIT:
+                uint32 bonusDmg = *damage;
+
+                // Apply crit_damage bonus
+                if(Player* modOwner = GetSpellModOwner())
+                    modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg);
+
+                uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+                AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
+                for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
+                    if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
+                        bonusDmg = uint32(bonusDmg * ((*i)->GetModifier()->m_amount+100.0f)/100.0f);
+
+                *damage += bonusDmg;
+
+                // Resilience - reduce crit damage
+                if (pVictim->GetTypeId()==TYPEID_PLAYER)
                 {
-                    uint32 bonusDmg = *damage;
+                    uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
+                    cleanDamage->damage += resilienceReduction;
+                    *damage -=  resilienceReduction;
+                }
 
-                    // Apply crit_damage bonus
-                    if(Player* modOwner = GetSpellModOwner())
-                        modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg);
+                *crit = true;
+                hitInfo |= HITINFO_CRITICALHIT;
 
-                    uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
-                    AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS);
-                    for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
-                        if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
-                            bonusDmg = uint32(bonusDmg * ((*i)->GetModifier()->m_amount+100.0f)/100.0f);
+                ModifyAuraState(AURA_STATE_CRIT, true);
+                StartReactiveTimer( REACTIVE_CRIT );
 
-                    *damage += bonusDmg;
+                if(getClass()==CLASS_HUNTER)
+                {
+                    ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
+                    StartReactiveTimer( REACTIVE_HUNTER_CRIT );
+                }
 
-                    // Resilience - reduce crit damage
-                    if (pVictim->GetTypeId()==TYPEID_PLAYER)
+                if ( outcome == MELEE_HIT_BLOCK_CRIT )
+                {
+                    blocked_amount = uint32(pVictim->GetShieldBlockValue());
+                    if (blocked_amount >= *damage)
                     {
-                        uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
-                        cleanDamage->damage += resilienceReduction;
-                        *damage -=  resilienceReduction;
+                        hitInfo |= HITINFO_SWINGNOHITSOUND;
+                        victimState = VICTIMSTATE_BLOCKS;
+                        cleanDamage->damage += *damage; // To Help Calculate Rage
+                        *damage = 0;
                     }
+                    else
+                    {
+                        // To Help Calculate Rage
+                        cleanDamage->damage += blocked_amount;
+                        *damage = *damage - blocked_amount;
+                    }
 
-                    *crit = true;
-                    hitInfo |= HITINFO_CRITICALHIT;
+                    pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+                    pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
+                }
+                break;
+            }
+        case MELEE_HIT_PARRY:
+            {
+                cleanDamage->damage += *damage;         // To Help Calculate Rage
+                *damage = 0;
+                victimState = VICTIMSTATE_PARRY;
 
-                    ModifyAuraState(AURA_STATE_CRIT, true);
-                    StartReactiveTimer( REACTIVE_CRIT );
+                // Counter-attack ( explained in Unit::DoAttackDamage() )
+                {
+                    // Get attack timers
+                    float offtime  = float(pVictim->getAttackTimer(OFF_ATTACK));
+                    float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
 
-                    if(getClass()==CLASS_HUNTER)
+                    // Reduce attack time
+                    if (pVictim->haveOffhandWeapon() && offtime < basetime)
                     {
-                        ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
-                        StartReactiveTimer( REACTIVE_HUNTER_CRIT );
-                    }
-
-                    if ( outcome == MELEE_HIT_BLOCK_CRIT )
-                    {
-                        blocked_amount = uint32(pVictim->GetShieldBlockValue());
-                        if (blocked_amount >= *damage)
+                        float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20;
+                        float percent60 = 3 * percent20;
+                        if(offtime > percent20 && offtime <= percent60)
                         {
-                            hitInfo |= HITINFO_SWINGNOHITSOUND;
-                            victimState = VICTIMSTATE_BLOCKS;
-                            cleanDamage->damage += *damage; // To Help Calculate Rage
-                            *damage = 0;
+                            pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
                         }
-                        else
+                        else if(offtime > percent60)
                         {
-                            // To Help Calculate Rage
-                            cleanDamage->damage += blocked_amount;
-                            *damage = *damage - blocked_amount;
+                            offtime -= 2 * percent20;
+                            pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
                         }
-
-                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
-                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
                     }
-                    break;
-                }
-                case MELEE_HIT_PARRY:
-                {
-                    cleanDamage->damage += *damage;         // To Help Calculate Rage
-                    *damage = 0;
-                    victimState = VICTIMSTATE_PARRY;
-
-                    // Counter-attack ( explained in Unit::DoAttackDamage() )
+                    else
                     {
-                        // Get attack timers
-                        float offtime  = float(pVictim->getAttackTimer(OFF_ATTACK));
-                        float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
-
-                        // Reduce attack time
-                        if (pVictim->haveOffhandWeapon() && offtime < basetime)
+                        float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20;
+                        float percent60 = 3 * percent20;
+                        if(basetime > percent20 && basetime <= percent60)
                         {
-                            float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20;
-                            float percent60 = 3 * percent20;
-                            if(offtime > percent20 && offtime <= percent60)
-                            {
-                                pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
-                            }
-                            else if(offtime > percent60)
-                            {
-                                offtime -= 2 * percent20;
-                                pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
-                            }
+                            pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
                         }
-                        else
+                        else if(basetime > percent60)
                         {
-                            float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20;
-                            float percent60 = 3 * percent20;
-                            if(basetime > percent20 && basetime <= percent60)
-                            {
-                                pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
-                            }
-                            else if(basetime > percent60)
-                            {
-                                basetime -= 2 * percent20;
-                                pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
-                            }
+                            basetime -= 2 * percent20;
+                            pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
                         }
                     }
+                }
 
-                    // Update victim defense ?
-                    if(pVictim->GetTypeId() == TYPEID_PLAYER)
-                        ((Player*)pVictim)->UpdateDefense();
+                // Update victim defense ?
+                if(pVictim->GetTypeId() == TYPEID_PLAYER)
+                    ((Player*)pVictim)->UpdateDefense();
 
-                    // Set parry flags
-                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+                // Set parry flags
+                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
 
-                    // Mongoose bite - set only Counterattack here
-                    if (pVictim->getClass() == CLASS_HUNTER)
-                    {
-                        pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
-                        pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
-                    }
-                    else
-                    {
-                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
-                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-                    }
-                    break;
+                // Mongoose bite - set only Counterattack here
+                if (pVictim->getClass() == CLASS_HUNTER)
+                {
+                    pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
+                    pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
                 }
-                case MELEE_HIT_DODGE:
+                else
                 {
-                    if(pVictim->GetTypeId() == TYPEID_PLAYER)
-                        ((Player*)pVictim)->UpdateDefense();
+                    pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+                    pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
+                }
+                break;
+            }
+        case MELEE_HIT_DODGE:
+            {
+                if(pVictim->GetTypeId() == TYPEID_PLAYER)
+                    ((Player*)pVictim)->UpdateDefense();
 
-                    cleanDamage->damage += *damage;         // To Help Calculate Rage
-                    *damage = 0;
-                    hitInfo |= HITINFO_SWINGNOHITSOUND;
-                    victimState = VICTIMSTATE_DODGE;
+                cleanDamage->damage += *damage;         // To Help Calculate Rage
+                *damage = 0;
+                hitInfo |= HITINFO_SWINGNOHITSOUND;
+                victimState = VICTIMSTATE_DODGE;
 
-                    // Set dodge flags
-                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+                // Set dodge flags
+                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
 
-                    // Overpower
-                    if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
-                    {
-                        ((Player*)this)->AddComboPoints(pVictim, 1);
-                        StartReactiveTimer( REACTIVE_OVERPOWER );
-                    }
-
-                    // Riposte
-                    if (pVictim->getClass() != CLASS_ROGUE)
-                    {
-                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
-                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-                    }
-                    break;
-                }
-                case MELEE_HIT_BLOCK:
+                // Overpower
+                if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
                 {
-                    blocked_amount = uint32(pVictim->GetShieldBlockValue());
-                    if (blocked_amount >= *damage)
-                    {
-                        hitInfo |= HITINFO_SWINGNOHITSOUND;
-                        victimState = VICTIMSTATE_BLOCKS;
-                        cleanDamage->damage += *damage;     // To Help Calculate Rage
-                        *damage = 0;
-                    }
-                    else
-                    {
-                                                            // To Help Calculate Rage
-                        cleanDamage->damage += blocked_amount;
-                        *damage = *damage - blocked_amount;
-                    }
+                    ((Player*)this)->AddComboPoints(pVictim, 1);
+                    StartReactiveTimer( REACTIVE_OVERPOWER );
+                }
 
+                // Riposte
+                if (pVictim->getClass() != CLASS_ROGUE)
+                {
                     pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
                     pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
-
-                    break;
-
                 }
-                case MELEE_HIT_EVADE:                       // already processed early
-                case MELEE_HIT_MISS:                        // already processed early
-                case MELEE_HIT_GLANCING:
-                case MELEE_HIT_CRUSHING:
-                case MELEE_HIT_NORMAL:
-                    break;
+                break;
             }
+        case MELEE_HIT_BLOCK:
+            {
+                blocked_amount = uint32(pVictim->GetShieldBlockValue());
+                if (blocked_amount >= *damage)
+                {
+                    hitInfo |= HITINFO_SWINGNOHITSOUND;
+                    victimState = VICTIMSTATE_BLOCKS;
+                    cleanDamage->damage += *damage;     // To Help Calculate Rage
+                    *damage = 0;
+                }
+                else
+                {
+                    // To Help Calculate Rage
+                    cleanDamage->damage += blocked_amount;
+                    *damage = *damage - blocked_amount;
+                }
 
-            // Not correct, but this is what is used elsewhere to send misses and resists
-            if ( hitInfo & (HITINFO_ABSORB|HITINFO_RESIST|HITINFO_MISS) )
-                SendAttackStateUpdate(hitInfo & (HITINFO_ABSORB|HITINFO_RESIST|HITINFO_MISS), pVictim, 1, SpellSchools(spellInfo->School), *damage, 0,0,victimState,blocked_amount);
+                pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+                pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
 
-            // do all damage=0 cases here
-            if(damage <= 0)
-                CastMeleeProcDamageAndSpell(pVictim,0,BASE_ATTACK,outcome,spellInfo,isTriggeredSpell);
+                break;
 
+            }
+        case MELEE_HIT_EVADE:                       // already processed early
+        case MELEE_HIT_MISS:                        // already processed early
+        case MELEE_HIT_GLANCING:
+        case MELEE_HIT_CRUSHING:
+        case MELEE_HIT_NORMAL:
             break;
         }
 
-        // Other schools
-        case SPELL_SCHOOL_HOLY:
-        case SPELL_SCHOOL_FIRE:
-        case SPELL_SCHOOL_NATURE:
-        case SPELL_SCHOOL_FROST:
-        case SPELL_SCHOOL_SHADOW:
-        case SPELL_SCHOOL_ARCANE:
-            // Calculate damage bonus
-            *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
+        // Not correct, but this is what is used elsewhere to send misses and resists
+        if ( hitInfo & (HITINFO_ABSORB|HITINFO_RESIST|HITINFO_MISS) )
+            SendAttackStateUpdate(hitInfo & (HITINFO_ABSORB|HITINFO_RESIST|HITINFO_MISS), pVictim, 1, GetSpellSchoolMask(spellInfo), *damage, 0,0,victimState,blocked_amount);
 
-            // Calculate critical bonus
-            if(spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE)
+        // do all damage=0 cases here
+        if(damage <= 0)
+            CastMeleeProcDamageAndSpell(pVictim,0,BASE_ATTACK,outcome,spellInfo,isTriggeredSpell);
+    }
+    // Other schools
+    else
+    {
+        // Calculate damage bonus
+        *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE);
+
+        // Calculate critical bonus
+        if(spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE)
+        {
+            // Calculate physical outcome
+            if(RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo) == MELEE_HIT_CRIT)
             {
-                // Calculate physical outcome
-                if(RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo) == MELEE_HIT_CRIT)
+                *crit = true;
+                *damage *= 2;
+                // Resilience - reduce crit damage by
+                if (pVictim->GetTypeId()==TYPEID_PLAYER)
                 {
-                    *crit = true;
-                    *damage *= 2;
-                    // Resilience - reduce crit damage by
-                    if (pVictim->GetTypeId()==TYPEID_PLAYER)
-                    {
-                        uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
-                        cleanDamage->damage += resilienceReduction;
-                        *damage -=  resilienceReduction;
-                    }
+                    uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);
+                    cleanDamage->damage += resilienceReduction;
+                    *damage -=  resilienceReduction;
                 }
             }
-            else
-                *crit = SpellCriticalBonus(spellInfo, damage, pVictim);
+        }
+        else
+            *crit = SpellCriticalBonus(spellInfo, damage, pVictim);
 
-            if(*crit)
-                cleanDamage->hitOutCome = MELEE_HIT_CRIT;
+        if(*crit)
+            cleanDamage->hitOutCome = MELEE_HIT_CRIT;
 
-            // spell proc all magic damage==0 case in this function
-            if(*damage == 0)
-            {
-                // Procflags
-                uint32 procAttacker = PROC_FLAG_HIT_SPELL;
-                uint32 procVictim   = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
+        // spell proc all magic damage==0 case in this function
+        if(*damage == 0)
+        {
+            // Procflags
+            uint32 procAttacker = PROC_FLAG_HIT_SPELL;
+            uint32 procVictim   = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE);
 
-                ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, spellInfo, isTriggeredSpell);
-            }
-
-            break;
+            ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, spellInfo, isTriggeredSpell);
+        }
     }
 
     // TODO this in only generic way, check for exceptions
-    DEBUG_LOG("DealDamageBySchool (AFTER) SCHOOL %u >> DMG:%u", spellInfo->School, *damage);
+    DEBUG_LOG("DealDamageBySchool (AFTER) SCHOOL %u (mask: %u) >> DMG:%u", GetFirstSchoolInMask(schoolMask), schoolMask, *damage);
 }
 
 uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
@@ -1282,7 +1271,7 @@
         uint32 absorb = 0;
         uint32 resist = 0;
 
-        CalcAbsorbResist(pVictim,SpellSchools(spellInfo->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
+        CalcAbsorbResist(pVictim,GetSpellSchoolMask(spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
 
         // Only send absorbed message if we actually absorbed some damage
         if(damage > 0)
@@ -1290,13 +1279,13 @@
             // Handle absorb & resists
             if(damage <= absorb + resist && absorb)
             {
-                SendAttackStateUpdate(HITINFO_ABSORB|HITINFO_SWINGNOHITSOUND, pVictim, 1, SpellSchools(spellInfo->School),damage, absorb,resist,VICTIMSTATE_NORMAL,0);
+                SendAttackStateUpdate(HITINFO_ABSORB|HITINFO_SWINGNOHITSOUND, pVictim, 1, GetSpellSchoolMask(spellInfo),damage, absorb,resist,VICTIMSTATE_NORMAL,0);
                 return 0;
             }
             else if(damage <= resist)                       // If we didn't fully absorb check if we fully resisted
             {
                 ProcDamageAndSpell(pVictim, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, spellInfo,isTriggeredSpell);
-                SendAttackStateUpdate(HITINFO_RESIST|HITINFO_SWINGNOHITSOUND, pVictim, 1, SpellSchools(spellInfo->School), damage, absorb,resist,VICTIMSTATE_NORMAL,0);
+                SendAttackStateUpdate(HITINFO_RESIST|HITINFO_SWINGNOHITSOUND, pVictim, 1, GetSpellSchoolMask(spellInfo), damage, absorb,resist,VICTIMSTATE_NORMAL,0);
                 return 0;
             }
         }
@@ -1304,10 +1293,10 @@
         // Send damage log
         sLog.outDetail("SpellNonMeleeDamageLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u,absorb is %u,resist is %u",
             GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist);
-        SendSpellNonMeleeDamageLog(pVictim, spellID, damage, SpellSchools(spellInfo->School), absorb, resist, false, 0, crit);
+        SendSpellNonMeleeDamageLog(pVictim, spellID, damage, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit);
 
         // Deal damage done
-        DealDamage(pVictim, (damage-absorb-resist), &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchools(spellInfo->School), spellInfo, true);
+        DealDamage(pVictim, (damage-absorb-resist), &cleanDamage, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellInfo), spellInfo, true);
 
         // Procflags
         uint32 procAttacker = PROC_FLAG_HIT_SPELL;
@@ -1365,7 +1354,7 @@
                 pdamage = amount;
 
                 //Calculate armor mitigation if it is a physical spell
-                if (spellProto->School == SPELL_SCHOOL_NORMAL)
+                if (GetSpellSchoolMask(spellProto) & SPELL_SCHOOL_MASK_NORMAL)
                 {
                     uint32 pdamageReductedArmor = CalcArmorReducedDamage(pVictim, pdamage);
                     cleanDamage.damage += pdamage - pdamageReductedArmor;
@@ -1382,7 +1371,7 @@
             if (pVictim->GetTypeId()==TYPEID_PLAYER)
                 pdamage-=((Player*)pVictim)->GetDotDamageReduction(pdamage);
 
-            CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), DOT, pdamage, &absorb, &resist);
+            CalcAbsorbResist(pVictim, GetSpellSchoolMask(spellProto), DOT, pdamage, &absorb, &resist);
 
             sLog.outDetail("PeriodicAuraLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
                 GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), pdamage, spellProto->Id,absorb);
@@ -1394,12 +1383,12 @@
             data << uint32(1);
             data << uint32(mod->m_auraname);
             data << (uint32)pdamage;
-            data << (uint32)spellProto->School;
+            data << (uint32)spellProto->School;             // will be mask in 2.4.x
             data << (uint32)absorb;
             data << (uint32)resist;
             SendMessageToSet(&data,true);
 
-            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, SpellSchools(spellProto->School), spellProto, true);
+            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, true);
             ProcDamageAndSpell(pVictim, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), spellProto);
             break;
         }
@@ -1416,7 +1405,7 @@
             uint32 pdamage = mod->m_amount > 0 ? mod->m_amount : 0;
 
             //Calculate armor mitigation if it is a physical spell
-            if (spellProto->School == SPELL_SCHOOL_NORMAL)
+            if (GetSpellSchoolMask(spellProto) & SPELL_SCHOOL_MASK_NORMAL)
             {
                 uint32 pdamageReductedArmor = CalcArmorReducedDamage(pVictim, pdamage);
                 cleanDamage.damage += pdamage - pdamageReductedArmor;
@@ -1477,7 +1466,7 @@
             if (pVictim->GetTypeId()==TYPEID_PLAYER)
                 pdamage-=((Player*)pVictim)->GetDotDamageReduction(pdamage);
 
-            CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), DOT, pdamage, &absorb, &resist);
+            CalcAbsorbResist(pVictim, GetSpellSchoolMask(spellProto), DOT, pdamage, &absorb, &resist);
 
             if(pVictim->GetHealth() < pdamage)
                 pdamage = uint32(pVictim->GetHealth());
@@ -1485,8 +1474,8 @@
             sLog.outDetail("PeriodicAuraLog: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
                 GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), pdamage, spellProto->Id,absorb);
 
-            SendSpellNonMeleeDamageLog(pVictim, spellProto->Id, pdamage, SpellSchools(spellProto->School), absorb, resist, false, 0);
-            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, SpellSchools(spellProto->School), spellProto, false);
+            SendSpellNonMeleeDamageLog(pVictim, spellProto->Id, pdamage, GetSpellSchoolMask(spellProto), absorb, resist, false, 0);
+            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, false);
             ProcDamageAndSpell(pVictim, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), spellProto);
             if (!pVictim->isAlive() && IsNonMeleeSpellCasted(false))
             {
@@ -1563,10 +1552,10 @@
                 }
                 else
                 {
-                    SendSpellNonMeleeDamageLog(this, spellProto->Id, gain, SpellSchools(spellProto->School), 0, 0, false, 0, false);
+                    SendSpellNonMeleeDamageLog(this, spellProto->Id, gain, GetSpellSchoolMask(spellProto), 0, 0, false, 0, false);
 
                     CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
-                    DealDamage(this, gain, &cleanDamage, NODAMAGE, SpellSchools(spellProto->School), spellProto, true);
+                    DealDamage(this, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(spellProto), spellProto, true);
                 }
             }
 
@@ -1622,7 +1611,7 @@
             if(gain_amount)
             {
                 int32 gain = ModifyPower(power,gain_amount);
-                pVictim->AddThreat(this, float(gain) * 0.5f, SpellSchools(spellProto->School), spellProto);
+                pVictim->AddThreat(this, float(gain) * 0.5f, GetSpellSchoolMask(spellProto), spellProto);
             }
             break;
         }
@@ -1718,7 +1707,7 @@
 
     AuraList const& mModTargetRes = GetAurasByType(SPELL_AURA_MOD_TARGET_RESISTANCE);
     for(AuraList::const_iterator i = mModTargetRes.begin(); i != mModTargetRes.end(); ++i)
-        if ((*i)->GetModifier()->m_miscvalue & int32(1 << SPELL_SCHOOL_NORMAL))
+        if ((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL)
             armor += float((*i)->GetModifier()->m_amount);
     if (armor<0.0f) armor=0.0f;
 
@@ -1739,19 +1728,19 @@
     return (newdamage > 1) ? newdamage : 1;
 }
 
-void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchools school, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
+void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist)
 {
     if(!pVictim || !pVictim->isAlive() || !damage)
         return;
 
     // Magic damage, check for resists
-    if (school != SPELL_SCHOOL_NORMAL)
+    if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL)==0)
     {
         float tmpvalue2 = 0.0f;
-        tmpvalue2 += (float)pVictim->GetResistance(SpellSchools(school));
+        tmpvalue2 += (float)pVictim->GetResistance(GetFirstSchoolInMask(schoolMask));
         AuraList const& mModTargetRes = GetAurasByType(SPELL_AURA_MOD_TARGET_RESISTANCE);
         for(AuraList::const_iterator i = mModTargetRes.begin(); i != mModTargetRes.end(); ++i)
-            if ((*i)->GetModifier()->m_miscvalue & int32(1 << school))
+            if ((*i)->GetModifier()->m_miscvalue & schoolMask)
                 tmpvalue2 += (float)((*i)->GetModifier()->m_amount);
         tmpvalue2 *= (float)(0.15f / getLevel());
         if (tmpvalue2 < 0.0f)
@@ -1790,7 +1779,7 @@
     {
         next = i; ++next;
 
-        if (((*i)->GetModifier()->m_miscvalue & int32(1<<school))==0)
+        if (((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
             continue;
 
         // Cheat Death
@@ -1870,7 +1859,7 @@
         next = i; ++next;
 
         // check damage school mask
-        if(((*i)->GetModifier()->m_miscvalue & int32(1<< school))==0)
+        if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
             continue;
 
         int32 currentAbsorb;
@@ -1906,7 +1895,7 @@
         next = i; ++next;
 
         // check damage school mask
-        if(((*i)->GetModifier()->m_miscvalue & int32(1<< school))==0)
+        if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
             continue;
 
         // Damage can be splitted only if aura has an alive caster
@@ -1922,10 +1911,10 @@
 
         RemainingDamage -= currentAbsorb;
 
-        pVictim->SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, SpellSchools((*i)->GetSpellProto()->School), 0, 0, false, 0, false);
+        pVictim->SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, currentAbsorb, GetSpellSchoolMask((*i)->GetSpellProto()), 0, 0, false, 0, false);
 
         CleanDamage cleanDamage = CleanDamage(currentAbsorb, BASE_ATTACK, MELEE_HIT_NORMAL);
-        pVictim->DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, SpellSchools((*i)->GetSpellProto()->School), (*i)->GetSpellProto(), false);
+        pVictim->DealDamage(caster, currentAbsorb, &cleanDamage, DIRECT_DAMAGE, GetSpellSchoolMask((*i)->GetSpellProto()), (*i)->GetSpellProto(), false);
     }
 
     AuraList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
@@ -1934,7 +1923,7 @@
         next = i; ++next;
 
         // check damage school mask
-        if(((*i)->GetModifier()->m_miscvalue & int32(1<< school))==0)
+        if(((*i)->GetModifier()->m_miscvalue & schoolMask)==0)
             continue;
 
         // Damage can be splitted only if aura has an alive caster
@@ -1946,16 +1935,16 @@
 
         RemainingDamage -= splitted;
 
-        pVictim->SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, SpellSchools((*i)->GetSpellProto()->School), 0, 0, false, 0, false);
+        pVictim->SendSpellNonMeleeDamageLog(caster, (*i)->GetSpellProto()->Id, splitted, GetSpellSchoolMask((*i)->GetSpellProto()), 0, 0, false, 0, false);
 
         CleanDamage cleanDamage = CleanDamage(splitted, BASE_ATTACK, MELEE_HIT_NORMAL);
-        pVictim->DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, SpellSchools((*i)->GetSpellProto()->School), (*i)->GetSpellProto(), false);
+        pVictim->DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, GetSpellSchoolMask((*i)->GetSpellProto()), (*i)->GetSpellProto(), false);
     }
 
     *absorb = damage - RemainingDamage - *resist;
 }
 
-void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell)
+void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell)
 {
     MeleeHitOutcome outcome;
 
@@ -2010,7 +1999,7 @@
     }
 
     //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL
-    if (damageType == SPELL_SCHOOL_NORMAL)
+    if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
     {
         uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage);
         cleanDamage->damage += *damage - damageAfterArmor;
@@ -2314,7 +2303,7 @@
     if(*victimState != VICTIMSTATE_BLOCKS)
     {
         MeleeDamageBonus(pVictim, damage,attType,spellCasted);
-        CalcAbsorbResist(pVictim, damageType, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
+        CalcAbsorbResist(pVictim, damageSchoolMask, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage);
     }
 
     if (*absorbDamage) *hitInfo |= HITINFO_ABSORB;
@@ -2447,32 +2436,32 @@
     uint32   absorbed_dmg = 0;
     uint32   resisted_dmg = 0;
 
-    SpellSchools meleeSchool = GetMeleeDamageSchool();
+    SpellSchoolMask meleeSchoolMask = GetMeleeDamageSchoolMask();
 
-    if( meleeSchool == SPELL_SCHOOL_NORMAL && pVictim->IsImmunedToPhysicalDamage() )
+    if( (meleeSchoolMask & SPELL_SCHOOL_MASK_NORMAL) && pVictim->IsImmunedToPhysicalDamage() )
     {
-        SendAttackStateUpdate (HITINFO_MISS, pVictim, 1, meleeSchool, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0);
+        SendAttackStateUpdate (HITINFO_MISS, pVictim, 1, meleeSchoolMask, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0);
         return;
     }
 
     uint32 damage = CalculateDamage (attType, false);
 
-    DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType);
+    DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchoolMask, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType);
 
     if (hitInfo & HITINFO_MISS)
         //send miss
-        SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchool, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg);
+        SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchoolMask, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg);
     else
     {
         //do animation
-        SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchool, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg);
+        SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchoolMask, damage, absorbed_dmg, resisted_dmg, victimState, blocked_dmg);
 
         if (damage > (absorbed_dmg + resisted_dmg + blocked_dmg))
             damage -= (absorbed_dmg + resisted_dmg + blocked_dmg);
         else
             damage = 0;
 
-        DealDamage (pVictim, damage, &cleanDamage, DIRECT_DAMAGE, meleeSchool, NULL, true);
+        DealDamage (pVictim, damage, &cleanDamage, DIRECT_DAMAGE, meleeSchoolMask, NULL, true);
 
         if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive())
         {
@@ -2506,7 +2495,7 @@
         // Talents
         AuraList const& mSpellCritSchool = GetAurasByType(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL);
         for(AuraList::const_iterator i = mSpellCritSchool.begin(); i != mSpellCritSchool.end(); ++i)
-            if((*i)->GetModifier()->m_miscvalue == -2 || ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellInfo->School)) != 0)
+            if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellInfo))
                 crit_chance += (*i)->GetModifier()->m_amount;
 
         AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_CANNOT_BE_DODGED);
@@ -2944,7 +2933,7 @@
     if (!pVictim->isAlive())
         return SPELL_MISS_NONE;
 
-    uint32 schoolMask = 1<<spell->School;
+    SpellSchoolMask schoolMask = GetSpellSchoolMask(spell);
     // PvP - PvE spell misschances per leveldif > 2
     int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 7 : 11;
     int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel());
@@ -3027,7 +3016,7 @@
         Unit::AuraList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
         for(Unit::AuraList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
         {
-            if((*i)->GetModifier()->m_miscvalue & int32(1 << spell->School))
+            if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spell))
             {
                 int32 reflectchance = (*i)->GetModifier()->m_amount;
                 if (reflectchance > 0 && roll_chance_i(reflectchance))
@@ -3071,7 +3060,7 @@
             return SPELL_MISS_NONE;
     }
 
-    if (spell->School == SPELL_SCHOOL_NORMAL)
+    if (GetSpellSchoolMask(spell) & SPELL_SCHOOL_MASK_NORMAL)
         return SPELL_MISS_NONE;
 
     // TODO need use this code for spell hit result calculation
@@ -3102,7 +3091,7 @@
         bool isNormal = false;
         for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
         {
-            if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->School == SPELL_SCHOOL_NORMAL)
+            if( m_currentSpells[i] && (GetSpellSchoolMask(m_currentSpells[i]->m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL) )
             {
                 isNormal = true;
                 break;
@@ -4367,14 +4356,14 @@
     }
 }
 
-void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchools DamageType,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
+void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
 {
     WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+31)); // we guess size
     data.append(target->GetPackGUID());
     data.append(GetPackGUID());
     data << uint32(SpellID);
     data << uint32(Damage-AbsorbedDamage-Resist-Blocked);
-    data << uint8(DamageType);                              // spell school
+    data << uint8(GetFirstSchoolInMask(damageSchoolMask));  // spell school
     data << uint32(AbsorbedDamage);                         // AbsorbedDamage
     data << uint32(Resist);                                 // resist
     data << uint8(PhysicalDamage);
@@ -4399,7 +4388,7 @@
     SendMessageToSet(&data, true);
 }
 
-void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
+void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
 {
     sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
 
@@ -4412,7 +4401,7 @@
     data << (uint8)SwingType;                               // count?
 
     // for(i = 0; i < SwingType; ++i)
-    data << (uint32)DamageType;
+    data << (uint32)GetFirstSchoolInMask(damageSchoolMask);
     data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount);
     // still need to double check damage
     data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
@@ -4626,7 +4615,7 @@
                         return;
 
                     uint32 spellId = 0;
-                    switch(procSpell->School)
+                    switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
                     {
                         case SPELL_SCHOOL_NORMAL:
                         case SPELL_SCHOOL_HOLY:
@@ -4666,7 +4655,7 @@
                         return;
 
                     uint32 spellId = 0;
-                    switch(procSpell->School)
+                    switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
                     {
                         case SPELL_SCHOOL_NORMAL:
                             return;                         // ignore
@@ -5014,7 +5003,7 @@
                     if(!castItem)
                         return;
 
-                    if(!procSpell || procSpell->School != SPELL_SCHOOL_FROST && procSpell->School != SPELL_SCHOOL_SHADOW )
+                    if(!procSpell || (GetSpellSchoolMask(procSpell) & (SPELL_SCHOOL_FROST | SPELL_SCHOOL_SHADOW))==0 )
                         return;
 
                     int32 healamount = int32(damage * 2 / 100);
@@ -6801,8 +6790,8 @@
     if (CastingTime < 1500) CastingTime = 1500;
 
     // Taken/Done fixed damage bonus auras
-    int32 DoneAdvertisedBenefit  = SpellBaseDamageBonus((int32)(1<<spellProto->School));
-    int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim((int32)(1<<spellProto->School), pVictim);
+    int32 DoneAdvertisedBenefit  = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
+    int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
 
     // Damage over Time spells bonus calculation
     float DotFactor = 1.0f;
@@ -6847,7 +6836,7 @@
     AuraList const& mModDamagePercentDone = this->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
     for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
     {
-        if( ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellProto->School)) != 0 &&
+        if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
             (*i)->GetSpellProto()->EquippedItemClass == -1 &&
                                                             // -1 == any item class (not wand then)
             (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
@@ -6866,7 +6855,7 @@
     // ..taken
     AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
     for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
-        if( ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellProto->School)) != 0 )
+        if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
             TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
 
     // .. taken pct: scripted (increases damage of * against targets *)
@@ -7205,11 +7194,11 @@
         crit_chance = m_baseSpellCritChance;
         AuraList const& mSpellCritSchool = GetAurasByType(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL);
         for(AuraList::const_iterator i = mSpellCritSchool.begin(); i != mSpellCritSchool.end(); ++i)
-            if((*i)->GetModifier()->m_miscvalue == -2 || ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellProto->School)) != 0)
+            if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))
                 crit_chance += (*i)->GetModifier()->m_amount;
     }
     else
-        crit_chance = GetFloatValue( PLAYER_SPELL_CRIT_PERCENTAGE1 + spellProto->School);
+        crit_chance = GetFloatValue( PLAYER_SPELL_CRIT_PERCENTAGE1 + GetFirstSchoolInMask(GetSpellSchoolMask(spellProto)));
 
     // percent done
     // only players use intelligence for critical chance computations
@@ -7222,7 +7211,7 @@
         // flat
         AuraList const& mAttackerSpellCrit = pVictim->GetAurasByType(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE);
         for(AuraList::const_iterator i = mAttackerSpellCrit.begin(); i != mAttackerSpellCrit.end(); ++i)
-            if((*i)->GetModifier()->m_miscvalue == -2 || ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellProto->School)) != 0)
+            if((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))
                 crit_chance += (*i)->GetModifier()->m_amount;
 
         if (pVictim->GetTypeId() == TYPEID_PLAYER)
@@ -7297,13 +7286,13 @@
         return healamount;
 
     bool Channeled = IsChanneledSpell(spellProto);
-    int32 AdvertisedBenefit = SpellBaseHealingBonus(1<<spellProto->School);
+    int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
     uint32 CastingTime = GetSpellCastTime(sCastTimesStore.LookupEntry(spellProto->CastingTimeIndex));
     if (CastingTime > 7000) CastingTime = 7000;
     if (CastingTime < 1500) CastingTime = 1500;
 
     // Healing Taken
-    AdvertisedBenefit += SpellBaseHealingBonusForVictim(1<<spellProto->School, pVictim);
+    AdvertisedBenefit += SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
 
     //Blessing of Light dummy effects healing taken
     if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && (spellProto->SpellFamilyFlags & 0x6000))
@@ -7491,7 +7480,7 @@
     //If m_immuneToSchool type contain this school type, IMMUNE damage.
     SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
     for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
-        if(itr->type & uint32(1<<spellInfo->School))
+        if(itr->type & GetSpellSchoolMask(spellInfo))
             return true;
 
     // charges dependent checks
@@ -7500,7 +7489,7 @@
     SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
     for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
     {
-        if(itr->type & uint32(1<<spellInfo->School))
+        if(itr->type & GetSpellSchoolMask(spellInfo))
         {
             if(useCharges)
             {
@@ -7556,8 +7545,8 @@
         // not have spells with charges currently
         SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
         for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
-            if(!(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id))
-                && (itr->type & (1 << spellInfo->School)))
+            if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) &&
+                (itr->type & GetSpellSchoolMask(spellInfo)) )
                 return true;
     }
 
@@ -8408,27 +8397,23 @@
 
 //======================================================================
 
-float Unit::ApplyTotalThreatModifier(float threat, SpellSchools school)
+float Unit::ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask)
 {
     if(!HasAuraType(SPELL_AURA_MOD_THREAT))
         return threat;
 
-    if(school >= MAX_SPELL_SCHOOL)
-    {
-        sLog.outError("Unit::ApplyTotalThreatModifier: Spell school with out-of-range value: %u",uint32(school));
-        return threat;
-    }
+    SpellSchools school = GetFirstSchoolInMask(schoolMask);
 
     return threat * m_threatModifier[school];
 }
 
 //======================================================================
 
-void Unit::AddThreat(Unit* pVictim, float threat, SpellSchools school, SpellEntry const *threatSpell)
+void Unit::AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask, SpellEntry const *threatSpell)
 {
     // Only mobs can manage threat lists
     if(CanHaveThreatList())
-        m_ThreatManager.addThreat(pVictim, threat, school, threatSpell);
+        m_ThreatManager.addThreat(pVictim, threat, schoolMask, threatSpell);
 }
 
 //======================================================================
@@ -9329,7 +9314,7 @@
 {
     AuraList const& mRoot = GetAurasByType(SPELL_AURA_MOD_ROOT);
     for(AuraList::const_iterator i = mRoot.begin(); i != mRoot.end(); ++i)
-        if( (*i)->GetSpellProto()->School == SPELL_SCHOOL_FROST)
+        if( GetSpellSchoolMask((*i)->GetSpellProto()) & SPELL_SCHOOL_MASK_FROST)
             return true;
     return false;
 }
@@ -9519,18 +9504,18 @@
     }
 }
 
-SpellSchools Unit::GetMeleeDamageSchool() const
+SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const
 {
     if(GetTypeId()==TYPEID_UNIT)
     {
         CreatureInfo const* cInfo = ((Creature*)this)->GetCreatureInfo();
         if(cInfo)
-            return SpellSchools(cInfo->dmgschool);          // checked at creature_template loading
+            return SpellSchoolMask(1 << cInfo->dmgschool);  // checked at creature_template loading
         else
-            return SPELL_SCHOOL_NORMAL;
+            return SPELL_SCHOOL_MASK_NORMAL;
     }
     else
-        return SPELL_SCHOOL_NORMAL;
+        return SPELL_SCHOOL_MASK_NORMAL;
 }
 
 Player* Unit::GetSpellModOwner()
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 5635)
+++ src/game/Unit.h	(working copy)
@@ -731,9 +731,9 @@
         void Unmount();
 
         uint16 GetMaxSkillValueForLevel() const { return getLevel()*5; }
-        void DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchools damageSchool, SpellEntry const *spellProto, bool durabilityLoss);
+        void DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
         void DealDamageBySchool(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, bool isTriggeredSpell = false);
-        void DoAttackDamage(Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchools damageType, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false);
+        void DoAttackDamage(Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false);
 
         void CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false);
         void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage = 0, SpellEntry const *procSpell = NULL, bool isTriggeredSpell = false, WeaponAttackType attType = BASE_ATTACK);
@@ -830,8 +830,8 @@
 
         void DeMorph();
 
-        void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
-        void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchools DamageType,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
+        void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
+        void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
         void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
 
         void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time);
@@ -904,7 +904,7 @@
         float GetCreateStat(Stats stat) const { return m_createStats[stat]; }
 
         void SetCurrentCastedSpell(Spell * pSpell);
-        virtual void ProhibitSpellScholl(SpellSchools /*idSchool*/, uint32 /*unTimeMs*/ ) { }
+        virtual void ProhibitSpellScholl(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { }
         void InterruptSpell(uint32 spellType, bool withDelayed = true);
 
         // set withDelayed to true to account delayed spells as casted
@@ -983,8 +983,8 @@
 
         // Threat related methodes
         bool CanHaveThreatList() const;
-        void AddThreat(Unit* pVictim, float threat, SpellSchools school = SPELL_SCHOOL_NORMAL, SpellEntry const *threatSpell = NULL);
-        float ApplyTotalThreatModifier(float threat, SpellSchools school = SPELL_SCHOOL_NORMAL);
+        void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
+        float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
         void DeleteThreatList();
         bool SelectHostilTarget();
         void TauntApply(Unit* pVictim);
@@ -1039,7 +1039,7 @@
                                                             // redefined in Creature
 
         uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
-        void CalcAbsorbResist(Unit *pVictim, SpellSchools school, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
+        void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist);
 
         float GetSpeed( UnitMoveType mtype ) const;
         float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; }
@@ -1129,7 +1129,7 @@
 
         CharmInfo *m_charmInfo;
 
-        SpellSchools GetMeleeDamageSchool() const;
+        SpellSchoolMask GetMeleeDamageSchoolMask() const;
 
         MotionMaster i_motionMaster;
         bool m_moveRun;
Index: src/shared/Database/DBCStructure.h
===================================================================
--- src/shared/Database/DBCStructure.h	(revision 5635)
+++ src/shared/Database/DBCStructure.h	(working copy)
@@ -444,7 +444,7 @@
 struct SpellEntry
 {
     uint32    Id;                                           // 0 normally counted from 0 field (but some tools start counting from 1, check this before tool use for data view!)
-    uint32    School;                                       // 1
+    uint32    School;                                       // 1 (will removed in 2.4.0)
     uint32    Category;                                     // 2
                                                             // 3 not used
     uint32    Dispel;                                       // 4