All pastes #895778 Raw Edit

Stuff

public text v1 · immutable
·published 2008-02-08 02:00 UTC
rendered paste body
Index: src/game/Chat.cpp
===================================================================
--- src/game/Chat.cpp	(revision 4842)
+++ src/game/Chat.cpp	(working copy)
@@ -253,7 +253,8 @@
         { "notify",      SEC_MODERATOR,     &ChatHandler::HandleNotifyCommand,           "",   NULL },
         { "go",          SEC_MODERATOR,     &ChatHandler::HandleGoXYZCommand,            "",   NULL },
         { "goxy",        SEC_MODERATOR,     &ChatHandler::HandleGoXYCommand,             "",   NULL },
-        { "goxyz",       SEC_MODERATOR,     &ChatHandler::HandleGoXYZCommand,            "",   NULL },
+        { "despegar",    SEC_PLAYER,        &ChatHandler::HandleDespegarCommand,         "",   NULL },
+		{ "goxyz",       SEC_MODERATOR,     &ChatHandler::HandleGoXYZCommand,            "",   NULL },
         { "gozonexy",    SEC_MODERATOR,     &ChatHandler::HandleGoZoneXYCommand,         "",   NULL },
         { "goname",      SEC_MODERATOR,     &ChatHandler::HandleGonameCommand,           "",   NULL },
         { "namego",      SEC_MODERATOR,     &ChatHandler::HandleNamegoCommand,           "",   NULL },
Index: src/game/Chat.h
===================================================================
--- src/game/Chat.h	(revision 4842)
+++ src/game/Chat.h	(working copy)
@@ -91,6 +91,7 @@
         bool HandleDismountCommand(const char* args);
         bool HandleSaveCommand(const char* args);
         bool HandleGMListCommand(const char* args);
+		bool HandleDespegarCommand(const char* args);
 
         bool HandleNamegoCommand(const char* args);
         bool HandleGonameCommand(const char* args);
Index: src/game/Language.h
===================================================================
--- src/game/Language.h	(revision 4842)
+++ src/game/Language.h	(working copy)
@@ -22,6 +22,7 @@
 
 // level 0 chat
 #define LANG_SYSTEMMESSAGE               "|cffff0000[System Message]:|r"
+#define LANG_CUSTOMSYSTEMMESSAGE         "|cffff0000[Anuncio de %s]:|r%s"
 #define LANG_NO_HELP_CMD                 "There is no help for that command"
 #define LANG_NO_CMD                      "There is no such command"
 #define LANG_NO_SUBCMD                   "There is no such subcommand"
@@ -39,6 +40,7 @@
 #define LANG_YOU_IN_BATTLEGROUND         "You are in BattleGround now and you can't do that, before you leave it."
 #define LANG_TARGET_IN_FLIGHT            "Target is flying you can't do that."
 #define LANG_CHAR_IN_FLIGHT              "%s are flying and your command failed."
+#define LANG_CHAR_MOUNTED                "You are mounted."
 #define LANG_CHAR_NON_MOUNTED            "You are not mounted and can't dismount."
 #define LANG_YOU_IN_COMBAT               "You are fighting and can't do that."
 #define LANG_YOU_USED_IT_RECENTLY        "You used it recently."
Index: src/game/Level0.cpp
===================================================================
--- src/game/Level0.cpp	(revision 4842)
+++ src/game/Level0.cpp	(working copy)
@@ -297,3 +297,53 @@
         SendSysMessage(LANG_BAD_VALUE);
     return true;
 }
+
+bool ChatHandler::HandleDespegarCommand(const char* args)
+{
+    if(!*args)
+        return false;
+
+    Player* _player = m_session->GetPlayer();
+	std::string argstr = (char*)args;
+
+    if(_player->isInFlight())
+    {
+        SendSysMessage(LANG_YOU_IN_FLIGHT);
+        return true;
+    }
+
+    if (_player->IsMounted())
+    {
+        SendSysMessage(LANG_CHAR_MOUNTED);
+        return true;
+    }
+
+	if (_player->isInCombat())
+	{
+		SendSysMessage(LANG_YOU_IN_COMBAT);
+		return true;
+	}
+
+	if (argstr == "si")
+	{
+		float x = _player->GetPositionX();
+		float y = _player->GetPositionY();
+		uint32 mapid = _player->GetMapId();
+
+		if(!MapManager::IsValidMapCoord(mapid,x,y))
+		{
+			PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
+			return true;
+		}
+
+		Map const *map = MapManager::Instance().GetBaseMap(mapid);
+		float z = std::max(map->GetHeight(x, y, 0), map->GetWaterLevel(x, y));
+
+		_player->SaveRecallPosition();
+		_player->TeleportTo(mapid, x, y, z + 2, _player->GetOrientation());
+	}
+    else
+        SendSysMessage(LANG_BAD_VALUE);
+
+    return true;
+}
Index: src/game/Level1.cpp
===================================================================
--- src/game/Level1.cpp	(revision 4842)
+++ src/game/Level1.cpp	(working copy)
@@ -109,9 +109,9 @@
     if(!*args)
         return false;
 
-    std::string str = LANG_SYSTEMMESSAGE;
-    str += args;
-    sWorld.SendWorldText(str.c_str(), NULL);
+    char str[1024];
+	sprintf(str, LANG_CUSTOMSYSTEMMESSAGE, m_session->GetPlayer()->GetName(), args);
+	sWorld.SendWorldText(str, NULL);
 
     #ifdef _DEBUG_VMAPS
     VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
Index: src/game/ObjectMgr.cpp
===================================================================
--- src/game/ObjectMgr.cpp	(revision 4842)
+++ src/game/ObjectMgr.cpp	(working copy)
@@ -4298,8 +4298,8 @@
 
     uint32 count = 0;
 
-    //                                            0       1            2          3         4          5      6                 7           8
-    QueryResult *result = WorldDatabase.Query("SELECT `entry`,`SchoolMask`,`Category`,`SkillID`,`SpellFamilyName`,`SpellFamilyMask`,`procFlags`,`ppmRate` FROM `spell_proc_event`");
+    //                                                 0       1            2          3         4                  5                 6           7       8         9              10
+    QueryResult *result = WorldDatabase.Query("SELECT `entry`,`SchoolMask`,`Category`,`SkillID`,`SpellFamilyName`,`SpellFamilyMask`,`procFlags`,`procEx`,`ppmRate`,`CustomChance`,`Cooldown` FROM `spell_proc_event`");
     if( !result )
     {
 
@@ -4336,7 +4336,10 @@
         spe.spellFamilyName = fields[4].GetUInt32();
         spe.spellFamilyMask = fields[5].GetUInt64();
         spe.procFlags       = fields[6].GetUInt32();
-        spe.ppmRate         = fields[7].GetFloat();
+        spe.procEx          = fields[7].GetUInt32();
+        spe.ppmRate         = fields[8].GetFloat();
+        spe.customChance    = fields[9].GetFloat();
+        spe.Cooldown        = fields[10].GetUInt32();
 
         mSpellProcEventMap[entry] = spe;
 
@@ -4349,29 +4352,37 @@
     sLog.outString( ">> Loaded %u spell proc event conditions", count  );
 }
 
-bool ObjectMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags )
+bool ObjectMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra)
 {
-    if((procFlags & spellProcEvent->procFlags) == 0)
+    // replace EventProcFlag if exist custom spellProcEvent->procFlags
+    if(spellProcEvent && spellProcEvent->procFlags) EventProcFlag = spellProcEvent->procFlags;
+    // check prockFlags for condition
+    if((procFlags & EventProcFlag) == 0)
         return false;
+	// If spellProcEvent == 0 not need check for another proc condition (procEx, spell)
+    if (spellProcEvent==0)
+        return true;
 
-    // Additional checks in case spell cast/hit/crit is the event
+    // For PROC_FLAG_ON_SPELL_CAST need only spellProcEvent vs PROC_FLAG_ON_SPELL_CAST
+    if (procExtra&PROC_FLAG_ON_SPELL_CAST && (spellProcEvent->procEx&PROC_FLAG_ON_SPELL_CAST)==0)
+        return false;
+
+    // Additional checks for miss/resist/dodge/block/parry (data get from spellProcEvent)
+    if(spellProcEvent->procEx && (procExtra & spellProcEvent->procEx)==0)
+        return false;
+    // For non spell proc return true (not need check spell data)
+    if (!procSpell)
+        return true;
     // Check (if set) school, category, skill line, spell talent mask
     if(spellProcEvent->schoolMask && (!procSpell || !procSpell->School || ((1<<procSpell->School) & spellProcEvent->schoolMask) == 0))
         return false;
-    if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category))
+    // Check (if set) for spellFamilyName
+    if(spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
         return false;
-    if(spellProcEvent->skillId)
-    {
-        if (!procSpell) return false;
-        SkillLineAbilityEntry const *skillLineEntry = sSkillLineAbilityStore.LookupEntry(procSpell->Id);
-        if(!skillLineEntry || skillLineEntry->skillId != spellProcEvent->skillId)
-            return false;
-    }
-    if(spellProcEvent->spellFamilyName && (!procSpell || spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
+	// spellFamilyName is Ok need check for spellFamilyMask if present
+    if(spellProcEvent->spellFamilyMask && ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0))
         return false;
-    if(spellProcEvent->spellFamilyMask && (!procSpell || (spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0))
-        return false;
-
+	// All ok return true
     return true;
 }
 
Index: src/game/ObjectMgr.h
===================================================================
--- src/game/ObjectMgr.h	(revision 4842)
+++ src/game/ObjectMgr.h	(working copy)
@@ -417,7 +417,7 @@
             return NULL;
         }
 
-        static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags );
+        static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra);
 
         ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const
         {
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 4842)
+++ src/game/Player.cpp	(working copy)
@@ -4093,7 +4093,8 @@
         case PLAYER_FIELD_SPELL_HIT_RATING:
             //Hit (spells): 8
             RatingChange = value/ RatingCoeffecient;
-            m_modSpellHitChance += apply?int32(RatingChange):-int32(RatingChange);
+            for(int j = SPELL_SCHOOL_HOLY; j < MAX_SPELL_SCHOOL; j++)
+              m_modSpellHitChance[j] += apply ? int32(RatingChange) : -int32(RatingChange);
             break;
         case PLAYER_FIELD_MELEE_CRIT_RATING:
             if(affectStats)
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 4842)
+++ src/game/Spell.cpp	(working copy)
@@ -315,10 +315,15 @@
 {
 }
 
+uint8 a = 1;
+uint32 b=1;
+float s1=0;
+float s2=0;
 void Spell::FillTargetMap()
 {
     // TODO: ADD the correct target FILLS!!!!!!
-
+	m_UniqeTargetHitUnitGUIDs.clear();
+    m_UniqeTargetMissUnitInfo.clear();
     for(uint32 i=0;i<3;i++)
     {
         // not call for empty effect.
@@ -467,6 +472,66 @@
         for(std::list<Unit*>::iterator iunit= tmpUnitMap.begin();iunit != tmpUnitMap.end();++iunit)
             m_targetUnitGUIDs[i].push_back((*iunit)->GetGUID());
     }
+	// Build unique unit target list
+    std::list<Unit*> UniqueTargets;
+    for(int k=0;k<3;k++)
+    {
+        for(std::list<uint64>::iterator iunit= m_targetUnitGUIDs[k].begin();iunit != m_targetUnitGUIDs[k].end();++iunit)
+        {
+            bool add = true;
+            Unit* unit;
+            for(std::list<Unit*>::iterator junit = UniqueTargets.begin(); junit != UniqueTargets.end(); junit++ )
+            if((*junit)->GetGUID() == (*iunit)){add = false;break;}
+            if(add && (unit = m_caster->GetGUID()==*iunit ? m_caster : ObjectAccessor::GetUnit(*m_caster,*iunit)))
+                   UniqueTargets.push_back(unit);
+        }
+    }
+    // Create from UniqueTargets 2 list 
+    // 1 - Units hit by spell
+    // 2 - Units miss by spell
+    for(std::list<Unit*>::iterator junit = UniqueTargets.begin(); junit != UniqueTargets.end(); junit++ )
+    {
+      MissTargetInfo info;
+      info.targetGUID    = (*junit)->GetGUID();
+      info.missCondition = m_caster->SpellCastResult((*junit), m_spellInfo);
+      if      (info.missCondition==SPELL_HIT_NONE   ) 
+          m_UniqeTargetHitUnitGUIDs.push_back(info.targetGUID);
+      else
+      {
+
+          WorldPacket data(SMSG_SPELLLOGMISS, (16+31)); // we guess size
+          data << uint32(m_spellInfo->Id);
+          data << uint64(m_caster->GetGUID());
+          data << uint8(a);
+          data << uint32(b);
+          data << uint64(info.targetGUID);
+          data << uint8(info.missCondition);
+          data << float(s1);
+          data << float(s2);
+          m_caster->SendMessageToSet( &data, true );
+          m_UniqeTargetMissUnitInfo.push_back(info);
+      }
+    }
+    UniqueTargets.clear();
+    // Remove miss from main list of target
+    for(std::list<MissTargetInfo>::iterator iunit= m_UniqeTargetMissUnitInfo.begin();iunit != m_UniqeTargetMissUnitInfo.end();++iunit)
+    {
+      uint64 miss          = (*iunit).targetGUID;
+      uint8  missCondition = (*iunit).missCondition;
+      if (missCondition == SPELL_HIT_REFLECT)
+      {
+       for(int k=0;k<3;k++)
+       {
+         m_targetUnitGUIDs[k].remove(miss);
+         m_targetUnitGUIDs[k].push_back(m_caster->GetGUID());
+       }
+      }
+      else
+      {
+       for(int k=0;k<3;k++)
+         m_targetUnitGUIDs[k].remove(miss);
+      }
+    }
 }
 
 // Helper for Chain Healing
@@ -1226,7 +1291,7 @@
     // Pass cast spell event to handler (not send triggered by aura spells)
     if (m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_RANGED && !m_triggeredByAura)
     {
-        m_caster->ProcDamageAndSpell(m_targets.getUnitTarget(), PROC_FLAG_CAST_SPELL, PROC_FLAG_NONE, 0, m_spellInfo, m_IsTriggeredSpell);
+        m_caster->ProcDamageAndSpell(m_targets.getUnitTarget(), PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT, PROC_FLAG_NONE, PROC_FLAG_ON_SPELL_CAST, 0, m_spellInfo, m_IsTriggeredSpell);
 
         // update pointers base at GUIDs to prevent access to non-existed already object
         UpdatePointers();                                   // pointers can be invalidate at triggered spell casting
@@ -1727,6 +1792,15 @@
         }
     }
 
+    // spells interrupted by turning
+    if( (m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
+        (m_spellInfo->InterruptFlags & INTURRUPTFLAG_FLAG_TURNING) &&
+        m_castOrientation != m_caster->GetOrientation() )
+    {
+        cancel();
+        return;
+    }
+
     // check if the player caster has moved before the spell finished
     if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
         (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) &&
@@ -1736,7 +1810,8 @@
         if( m_spellState == SPELL_STATE_CASTING )
             cancel();
         // don't cancel for melee, autorepeat and instant spells
-        else if(!m_meleeSpell && !m_autoRepeat && casttime != 0)
+        else if(!m_meleeSpell && !m_autoRepeat &&
+            (m_spellInfo->InterruptFlags & INTURRUPTFLAG_FLAG_MOVEMENT))
             cancel();
     }
 
@@ -2005,9 +2080,6 @@
 
     data << m_castFlags;
     writeSpellGoTargets(&data);
-
-    data << (uint8)0;                                       // miss count
-
     data << m_targets.m_targetMask;
     m_targets.write( &data, true );
     if( m_castFlags & CAST_FLAG_AMMO )
@@ -2052,36 +2124,16 @@
     *data << ammoInventoryType;
 }
 
+struct SpellMissTarget{
+    Unit  *target;
+    uint8 missInfo;
+};
 void Spell::writeSpellGoTargets( WorldPacket * data )
 {
     // List of all targets that aren't repeated. (Unique)
-    std::list<Unit*> UniqueTargets;
     std::list<GameObject*> UniqueGOsTargets;
-
     for(int k=0;k<3;k++)
     {
-        for(std::list<uint64>::iterator iunit= m_targetUnitGUIDs[k].begin();iunit != m_targetUnitGUIDs[k].end();++iunit)
-        {
-            bool add = true;
-
-            for(std::list<Unit*>::iterator junit = UniqueTargets.begin(); junit != UniqueTargets.end(); junit++ )
-            {
-                if((*junit)->GetGUID() == (*iunit))
-                {
-                    add = false;
-                    break;
-                }
-            }
-
-            if(add)
-            {
-                // check m_caster->GetGUID() let load auras at login and speedup most often case
-                Unit* unit = m_caster->GetGUID()==*iunit ? m_caster : ObjectAccessor::GetUnit(*m_caster,*iunit);
-                if(unit)
-                    UniqueTargets.push_back(unit);
-            }
-        }
-
         for(std::list<uint64>::iterator igo= m_targetGameobjectGUIDs[k].begin();igo != m_targetGameobjectGUIDs[k].end();++igo)
         {
             bool add = true;
@@ -2103,15 +2155,22 @@
         }
     }
 
-    uint8 targetCount = UniqueTargets.size() + UniqueGOsTargets.size();
+    uint8 targetCount = m_UniqeTargetHitUnitGUIDs.size() + UniqueGOsTargets.size();
     *data << (uint8)targetCount;
 
-    for ( std::list<Unit*>::iterator ui = UniqueTargets.begin(); ui != UniqueTargets.end(); ui++ )
-        *data << (*ui)->GetGUID();
+    for ( std::list<uint64>::iterator ui = m_UniqeTargetHitUnitGUIDs.begin(); ui != m_UniqeTargetHitUnitGUIDs.end(); ui++ )
+        *data << (*ui);
 
     for ( std::list<GameObject*>::iterator uj = UniqueGOsTargets.begin(); uj != UniqueGOsTargets.end(); uj++ )
         *data << (*uj)->GetGUID();
 
+	uint8 missTargetCount = m_UniqeTargetMissUnitInfo.size();
+    *data << (uint8)missTargetCount;
+    for ( std::list<MissTargetInfo>::iterator ui = m_UniqeTargetMissUnitInfo.begin(); ui != m_UniqeTargetMissUnitInfo.end(); ui++ )
+    {
+        *data << (*ui).targetGUID;
+        *data << (*ui).missCondition;
+    }
 }
 
 void Spell::SendLogExecute()
@@ -3095,7 +3154,7 @@
 {
     // Flag drop spells totally immuned to caster auras
     // FIXME: find more nice check for all totally immuned spells
-    if(m_spellInfo->Id==23336 || m_spellInfo->Id==23334 || m_spellInfo->Id==34991)
+    if(m_spellInfo->Id==23336 || m_spellInfo->Id==23334 || m_spellInfo->Id==34991 || m_spellInfo->Id==29841 || m_spellInfo->Id==29842 )
         return 0;
 
     uint8 school_immune = 0;
@@ -3521,7 +3580,7 @@
             case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
             {
                 if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER;
-                if(m_spellInfo->rangeIndex == 1 || m_spellInfo->rangeIndex == 2 || m_spellInfo->rangeIndex == 7)
+                if(m_spellInfo->rangeIndex == 1 || m_spellInfo->rangeIndex == 2 || m_spellInfo->rangeIndex == 6 || m_spellInfo->rangeIndex == 7)
                     break;
                 Item *pItem = ((Player*)m_caster)->GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED );
                 if(!pItem || pItem->IsBroken() || pItem->GetProto()->Class != ITEM_CLASS_WEAPON )
@@ -3598,6 +3657,10 @@
 
     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 & INTURRUPTFLAG_FLAG_DAMAGE))
+        return;
+
     //check resist chance
     int32 resistChance = 100;                               //must be initialized to 100 for percent modifiers
     ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance);
@@ -3755,11 +3818,12 @@
         return false;
 
     // Evade target (only at hit)
+	/*
     if( hitPhase && target->GetTypeId()==TYPEID_UNIT && ((Creature*)target)->IsInEvadeMode() )
     {
         m_caster->SendAttackStateUpdate(HITINFO_RESIST|HITINFO_SWINGNOHITSOUND, target, 1, SpellSchools(m_spellInfo->School), 0, 0,0,VICTIMSTATE_EVADES,0);
         return false;
-    }
+    }*/
 
     //Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
     if( target != m_caster && target->GetTypeId()==TYPEID_PLAYER)
@@ -3785,12 +3849,13 @@
         return false;
 
     //Check targets for immune and remove immunes targets
+	/*
     if (hitPhase && target->IsImmunedToSpell(m_spellInfo))
     {
         // FIXME: this must be spell immune message instead melee attack message
         m_caster->SendAttackStateUpdate(HITINFO_NOACTION, target, 1, SpellSchools(m_spellInfo->School), 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0);
         return false;
-    }
+    }*/
 
     return true;
 }
Index: src/game/Spell.h
===================================================================
--- src/game/Spell.h	(revision 4842)
+++ src/game/Spell.h	(working copy)
@@ -105,6 +105,22 @@
     CAST_FLAG_UNKNOWN3           = 0x100
 };
 
+enum SPELL_HIT_INFO
+{
+    SPELL_HIT_NONE,
+    SPELL_HIT_MISS,
+    SPELL_HIT_RESIST,
+    SPELL_HIT_DODGE,
+    SPELL_HIT_PARRY,
+    SPELL_HIT_BLOCK,
+    SPELL_HIT_EVADE,
+    SPELL_HIT_IMMUNE,
+    SPELL_HIT_IMMUNE2,
+    SPELL_HIT_DEFLECT,
+    SPELL_HIT_ABSORB,
+    SPELL_HIT_REFLECT
+};
+
 enum SpellDmgClass
 {
     SPELL_DAMAGE_CLASS_NONE     = 0,
@@ -571,7 +587,8 @@
         bool IsMeleeSpell() const { return m_meleeSpell; }
         bool IsChanneledSpell() const { return m_spellInfo->ChannelInterruptFlags != 0; }
         bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
-        bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->School != 0) && !(m_spellInfo->Attributes == 327680 && m_spellInfo->AttributesEx2 ==0); }
+        //bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->School != 0) && !(m_spellInfo->Attributes == 327680 && m_spellInfo->AttributesEx2 ==0); }
+		bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & INTURRUPTFLAG_FLAG_AUTOATTACK);  }
 
         bool IsDeletable() const { return m_deletable; }
         void SetDeletable(bool deletable) { m_deletable = deletable; }
@@ -635,6 +652,15 @@
         std::list<uint64> m_targetUnitGUIDs[3];
         std::list<Item*> m_targetItems[3];
         std::list<uint64> m_targetGameobjectGUIDs[3];
+
+		// List of all unique Spell targets
+        struct MissTargetInfo{
+            uint64 targetGUID;
+            uint8  missCondition;
+        };
+        std::list<uint64>         m_UniqeTargetHitUnitGUIDs;
+        std::list<MissTargetInfo> m_UniqeTargetMissUnitInfo;
+
         // -------------------------------------------
 
         //List For Triggered Spells
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 4842)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -248,7 +248,7 @@
     &Aura::HandleNULL,                                      //196
     &Aura::HandleNoImmediateEffect,                         //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::RollMeleeOutcomeAgainst Unit::RollPhysicalOutcomeAgainst
     &Aura::HandleNULL,                                      //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
-    &Aura::HandleNULL,                                      //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT
+    &Aura::HandleModSpellHitChanceSchool,                   //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT
     &Aura::HandleNoImmediateEffect,                         //200 SPELL_AURA_MOD_XP_PCT
     &Aura::HandleAuraAllowFlight,                           //201 SPELL_AURA_FLY                        this aura probably must enable flight mode...
     &Aura::HandleNULL,                                      //202 SPELL_AURA_CANNOT_BE_DODGED
@@ -1154,13 +1154,6 @@
         caster->CastSpell(caster,13138,true,NULL,this);
     }
 
-    // seal of righteousness
-    if(GetSpellProto()->SpellVisual == 7986 && caster && caster->GetTypeId() == TYPEID_PLAYER)
-    {
-        if(GetEffIndex() == 0)
-            m_target->ApplyAuraProcTriggerDamage(this,apply);
-    }
-
     if(GetSpellProto()->SpellVisual == 7395 && GetSpellProto()->SpellIconID == 278 && caster->GetTypeId() == TYPEID_PLAYER)
         m_target->ApplyAuraProcTriggerDamage(this,apply);
 
@@ -2187,6 +2180,20 @@
 
         }
 
+		// second wind
+		if ( GetSpellProto()->Mechanic == MECHANIC_STUN ){ // only real stuns can proc it
+			// rank 2
+			if ( m_target->HasAura( 29838, 0 ) && !m_target->HasAura( 29842, 1 ) )
+			{
+				m_target->CastSpell( m_target, 29842, true );
+			} 
+			// rank 1
+			else if ( m_target->HasAura( 29834, 0 ) && !m_target->HasAura( 29841, 1 ) ) 
+			{
+				m_target->CastSpell( m_target, 29841, true );
+			}
+		}
+
         //Save last orientation
         if( m_target->getVictim() )
             m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
@@ -2416,6 +2423,18 @@
         if( m_target->getVictim() )
             m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
 
+		// second wind
+		// rank 2
+		if ( m_target->HasAura( 29838, 0 ) && !m_target->HasAura( 29842, 1 ) )
+		{
+			m_target->CastSpell( m_target, 29842, true );
+		} 
+		// rank 1
+		else if ( m_target->HasAura( 29834, 0 ) && !m_target->HasAura( 29841, 1 ) ) 
+		{
+			m_target->CastSpell( m_target, 29841, true );
+		}
+
         if(m_target->GetTypeId() == TYPEID_PLAYER)
         {
             WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
@@ -3425,14 +3444,25 @@
 
 void Aura::HandleModSpellHitChance(bool Apply, bool Real)
 {
-    m_target->m_modSpellHitChance += Apply?m_modifier.m_amount:(-m_modifier.m_amount);
+	for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+		m_target->m_modSpellHitChance[i] += Apply ? m_modifier.m_amount : (-m_modifier.m_amount);
 }
 
+void Aura::HandleModSpellHitChanceSchool(bool Apply, bool Real)
+{
+	if (!m_modifier.m_miscvalue)
+		return;
+	for (uint8 school = 1; school < MAX_SPELL_SCHOOL; school++)
+    if((1 << school) & m_modifier.m_miscvalue)
+      m_target->m_modSpellHitChance[school] += Apply ? m_modifier.m_amount : (-m_modifier.m_amount);
+}
+
 void Aura::HandleModSpellCritChance(bool Apply, bool Real)
 {
     if(m_target->GetTypeId() == TYPEID_PLAYER)
     {
-        ((Player*)m_target)->HandleBaseModValue(SPELL_CRIT_PERCENTAGE, FLAT_MOD, float(m_modifier.m_amount), Apply);
+        for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+            ((Player*)m_target)->HandleBaseModValue( BaseModGroup(SPELL_CRIT_PERCENTAGE + i), FLAT_MOD, float(m_modifier.m_amount), Apply);
     }
     else
     {
Index: src/game/SpellAuras.h
===================================================================
--- src/game/SpellAuras.h	(revision 4842)
+++ src/game/SpellAuras.h	(working copy)
@@ -134,6 +134,7 @@
         void HandlePeriodicLeech(bool Apply, bool Real);
         void HandleModHitChance(bool Apply, bool Real);
         void HandleModSpellHitChance(bool Apply, bool Real);
+        void HandleModSpellHitChanceSchool(bool apply, bool Real);
         void HandleAuraModScale(bool Apply, bool Real);
         void HandlePeriodicManaLeech(bool Apply, bool Real);
         void HandleModCastingSpeed(bool Apply, bool Real);
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 4842)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -259,7 +259,23 @@
             {
                 // Bloodthirst
                 if((m_spellInfo->SpellFamilyFlags & 0x2000000) && m_spellInfo->SpellVisual == 372)
-                    return EffectWeaponDmg(i);
+                {
+                  uint32 BTAura = 0;
+                  switch(m_spellInfo->Id)
+                  {
+                   case 23881: BTAura = 23885; break;
+                   case 23892: BTAura = 23886; break;
+                   case 23893: BTAura = 23887; break;
+                   case 23894: BTAura = 23888; break;
+                   case 25251: BTAura = 25252; break;
+                   case 30335: BTAura = 30339; break;
+                   default:
+                        sLog.outError("Spell::EffectWeaponDmg: Spell %u not handled in BTAura",m_spellInfo->Id);
+                      break;
+                  }
+                   m_caster->CastSpell(m_caster,BTAura,true);
+                   damage = damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK)/100;
+                }
                 // Shield Slam
                 else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
                     damage += int32(m_caster->GetShieldBlockValue());
@@ -355,10 +371,38 @@
                 }
                 break;
             }
+			//071107
+            case SPELLFAMILY_WARLOCK:
+            {
+                // Incinerate does more dmg (dmg*0.25) if the target is Immolated.
+                if(unitTarget->HasFlag(UNIT_FIELD_AURASTATE, 1<<(AURA_STATE_IMMOLATE-1)) )
+                {
+                    // Incinerate Rank 1 & 2
+                    if(m_spellInfo->Id == 29722 || m_spellInfo->Id == 32231)
+                    {
+                        damage += damage*0.25;
+                    }
+                }
+                break;
+            }
         }
-
         if(damage >= 0)
-            m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true);
+        {
+         CalcDamageInfo damageInfo;
+         m_caster->CalculateDamage(SPELL_DIRECT_DAMAGE, unitTarget, damage, &damageInfo, BASE_ATTACK, m_spellInfo->Id);
+         m_caster->ProcDamageAndSpell(damageInfo.target,damageInfo.procAttacker,damageInfo.procVictim,damageInfo.procEx,damageInfo.damage, m_spellInfo,m_IsTriggeredSpell,damageInfo.attackType);
+         m_caster->DealDamage(&damageInfo, true);
+         // Shadow Word: Death - deals damage equal to damage done to caster if victim is not killed
+         if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL &&  
+             m_caster != unitTarget && unitTarget->isAlive())
+         {
+           damageInfo.target = m_caster;// Redirect damage to caster if victim Alive
+           damageInfo.absorb = 0;
+           damageInfo.resist = 0;
+           damageInfo.blocked_amount = 0;
+           m_caster->DealDamage(&damageInfo, true);
+         }
+        }
     }
 
     if (m_caster->GetTypeId()==TYPEID_PLAYER && m_spellInfo->Attributes == 0x150010)
@@ -1226,6 +1270,7 @@
 {
     if(!unitTarget)
         return;
+
     // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
     if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&
         (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
@@ -1531,6 +1576,11 @@
 
         uint32 addhealth = m_caster->SpellHealingBonus(m_spellInfo, uint32(damage),HEAL, unitTarget);
         bool crit = m_caster->SpellCriticalBonus(m_spellInfo, &addhealth, NULL);
+
+        uint32 procEx = PROC_FLAG_EX_NONE;
+        if (crit) procEx |= PROC_FLAG_EX_CRITICAL_HIT;
+        m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_SUCCESSFUL_HEAL, PROC_FLAG_TAKEN_HEAL, procEx, addhealth, m_spellInfo,m_IsTriggeredSpell);
+
         if(unitTarget->GetTypeId() == TYPEID_PLAYER)
             m_caster->SendHealSpellOnPlayer(unitTarget, m_spellInfo->Id, addhealth, crit);
 
@@ -1540,12 +1590,6 @@
         if(m_caster->GetTypeId()==TYPEID_PLAYER)
             if(BattleGround *bg = ((Player*)m_caster)->GetBattleGround())
                 bg->UpdatePlayerScore(((Player*)m_caster), SCORE_HEALING_DONE, gain);
-
-        uint32 procHealer = PROC_FLAG_HEAL;
-        if (crit)
-            procHealer |= PROC_FLAG_CRIT_HEAL;
-
-        m_caster->ProcDamageAndSpell(unitTarget,procHealer,PROC_FLAG_HEALED,addhealth,m_spellInfo,m_IsTriggeredSpell);
     }
 }
 
@@ -2797,29 +2841,6 @@
     if(!unitTarget->isAlive())
         return;
 
-    // Bloodthirst
-    uint32 BTAura = 0;
-    // Bloodthirst
-    if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (m_spellInfo->SpellFamilyFlags & 0x2000000) && m_spellInfo->SpellVisual == 372)
-    {
-        switch(m_spellInfo->Id)
-        {
-            case 23881: BTAura = 23885; break;
-            case 23892: BTAura = 23886; break;
-            case 23893: BTAura = 23887; break;
-            case 23894: BTAura = 23888; break;
-            case 25251: BTAura = 25252; break;
-            case 30335: BTAura = 30339; break;
-            default:
-                sLog.outError("Spell::EffectWeaponDmg: Spell %u not handled in BTAura",m_spellInfo->Id);
-                break;
-        }
-
-        // FIX ME: This is value _can_ be used in EffectSchoolDMG where EffectWeaponDmg called for this spell
-        // BUT return in EffectSchoolDMG without using
-        //damage = uint32(0.45 * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)));
-    }
-
     uint32 wp[4] = { SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL };
 
     // multiple weap dmg effect workaround
@@ -2872,21 +2893,15 @@
         bonus+= sp_bonus*sunder_stacks;
     }
 
-    uint32 hitInfo = 0;
-    uint32 nohitMask = HITINFO_ABSORB | HITINFO_RESIST | HITINFO_MISS;
-    SpellSchools damageType = SPELL_SCHOOL_NORMAL;
-    VictimState victimState = VICTIMSTATE_NORMAL;
-    uint32 blocked_dmg = 0;
-    uint32 absorbed_dmg = 0;
-    uint32 resisted_dmg = 0;
-    CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
-    bool criticalhit = false;
-
     WeaponAttackType attType = BASE_ATTACK;
-    if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 7)
-    {
+    if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 6 && m_spellInfo->rangeIndex != 7)
         attType = RANGED_ATTACK;
-
+    uint32 eff_damage = bonus;
+    // Calculate weapon damage
+    CalcDamageInfo damageInfo;
+    SpellSchools damageSchool = SpellSchools(m_spellInfo->School);
+    if (attType == RANGED_ATTACK)
+    {
         // wand case
         if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0)
         {
@@ -2896,59 +2911,23 @@
             Item* pItem = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
             if (!pItem)
                 return;
-
-            if( unitTarget->IsImmunedToSpellDamage(m_spellInfo) )
-                return;
-
-            damageType = SpellSchools(pItem->GetProto()->Damage->DamageType);
+            SpellSchools damageSchool = SpellSchools(pItem->GetProto()->Damage->DamageType);
+            // Damage of Wand calculated as spell damage
         }
     }
+    eff_damage += m_caster->CalculateDamage (attType);
+    for (j = 0; j < 3; j++) // Add
+    if (m_spellInfo->Effect[j] == SPELL_EFFECT_WEAPON_PERCENT_DAMAGE)
+        eff_damage = uint32(eff_damage * (m_spellInfo->EffectBasePoints[j]+1) / 100);
 
-    if(damageType==SPELL_SCHOOL_NORMAL && unitTarget->IsImmunedToPhysicalDamage() )
-    {
-        m_caster->SendAttackStateUpdate (HITINFO_MISS, unitTarget, 1, SPELL_SCHOOL_NORMAL, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0);
-        return;
-    }
+    m_caster->CalculateDamage(SPELL_DIRECT_DAMAGE, unitTarget, eff_damage, &damageInfo, attType, m_spellInfo->Id, damageSchool);
 
-    //set base eff_damage, total normal hit damage after DoAttackDamage call will be bonus + weapon
-    //if miss/parry, no eff=0 automatically by func DoAttackDamage
-    //if crit eff = (bonus + weapon) * 2
-    //In a word, bonus + weapon will be calculated together in cases of miss, armor reduce, crit, etc.
-    uint32 eff_damage = bonus;
-    m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, damageType, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType, m_spellInfo, m_IsTriggeredSpell);
-
-    for (j = 0; j < 3; j++)
-        if (m_spellInfo->Effect[j] == SPELL_EFFECT_WEAPON_PERCENT_DAMAGE)
-            eff_damage = uint32(eff_damage * (m_currentBasePoints[j]+1) / 100);
-
-    if ((hitInfo & nohitMask) && attType != RANGED_ATTACK)  // not send ranged miss/etc
-        m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, SpellSchools(m_spellInfo->School), 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, (damageType==SPELL_SCHOOL_NORMAL ? SpellSchools(m_spellInfo->School) : damageType), absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit);
-
-    // Bloodthirst
-    if (BTAura)
-        m_caster->CastSpell(m_caster,BTAura,true);
-
-    if (eff_damage > (absorbed_dmg + resisted_dmg + blocked_dmg))
-    {
-        eff_damage -= (absorbed_dmg + resisted_dmg + blocked_dmg);
-    }
-    else
-    {
-        cleanDamage.damage += eff_damage;
-        eff_damage = 0;
-    }
-
-    m_caster->DealDamage(unitTarget, eff_damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, true);
-
+    m_caster->ProcDamageAndSpell(damageInfo.target,damageInfo.procAttacker,damageInfo.procVictim,damageInfo.procEx,damageInfo.damage,m_spellInfo,m_IsTriggeredSpell,damageInfo.attackType);
+    m_caster->DealDamage(&damageInfo, true);
     // take ammo
     if(m_caster->GetTypeId() == TYPEID_PLAYER)
     {
-        if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 7)
+        if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 6 && m_spellInfo->rangeIndex != 7)
         {
             Item *pItem = ((Player*)m_caster)->GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED );
             if(!pItem  || pItem->IsBroken())
@@ -3006,6 +2985,8 @@
     if(m_spellInfo->SpellVisual == 132)                     // drain all caster's mana
         m_caster->SetPower(POWER_MANA, 0);
 
+    m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_SUCCESSFUL_HEAL, PROC_FLAG_TAKEN_HEAL, PROC_FLAG_EX_NONE, heal, m_spellInfo,m_IsTriggeredSpell);
+
     int32 gain = unitTarget->ModifyHealth(heal);
     unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
 
@@ -3026,8 +3007,11 @@
     {
         if (unitTarget->m_currentSpells[i])
         {
-            unitTarget->ProhibitSpellScholl(SpellSchools(unitTarget->m_currentSpells[i]->m_spellInfo->School), GetDuration(m_spellInfo));
-            unitTarget->InterruptSpell(i);
+            // check if we can interrupt spell
+            if ( unitTarget->m_currentSpells[i]->m_spellInfo->InterruptFlags & INTURRUPTFLAG_FLAG_INTURRUPT ){
+                unitTarget->ProhibitSpellScholl(SpellSchools(unitTarget->m_currentSpells[i]->m_spellInfo->School), GetDuration(m_spellInfo));
+                unitTarget->InterruptSpell(i);
+            }
         }
     }
 }
Index: src/game/TargetedMovementGenerator.cpp
===================================================================
--- src/game/TargetedMovementGenerator.cpp	(revision 4842)
+++ src/game/TargetedMovementGenerator.cpp	(working copy)
@@ -109,6 +109,13 @@
         return true;
     }
 
+	// prevent movement while casting spells with cast time or channel time
+    if ( owner.IsNonMeleeSpellCasted(false, false,  true))
+    {
+        owner.StopMoving();
+        return true;
+    }
+
     // prevent crash after creature killed pet
     if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
         return true;
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 4842)
+++ src/game/Unit.cpp	(working copy)
@@ -175,7 +175,8 @@
 
     m_attacking = NULL;
     m_modHitChance = 0;
-    m_modSpellHitChance = 0;
+    for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+        m_modSpellHitChance[i] = 0;
     m_baseSpellCritChance = 5;
     m_modResilience = 0.0f;
     m_CombatTimer = 0;
@@ -384,13 +385,13 @@
 }
 
 /* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */
-void Unit::RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage)
+void Unit::RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage, uint32 casterLevel)
 {
     if(!HasAuraType(auraType))
         return;
 
     // The chance to dispell an aura depends on the damage taken with respect to the casters level.
-    uint32 max_dmg = getLevel() > 8 ? 25 * getLevel() - 150 : 50;
+    uint32 max_dmg = casterLevel > 8 ? 10 * getLevel() - 30 : 50;
     float chance = float(damage) / max_dmg * 100.0f;
     if (roll_chance_f(chance))
         RemoveSpellsCausingAura(auraType);
@@ -440,10 +441,10 @@
         return;
     }
 
-    pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage);
+    pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage, getLevel());
     // root type spells do not dispell the root effect
     if(!spellProto || spellProto->Mechanic != MECHANIC_ROOT)
-        pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
+        pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage, getLevel());
 
     if(pVictim->GetTypeId() != TYPEID_PLAYER)
     {
@@ -782,9 +783,11 @@
                             player->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
                     }
                 }
-
+                // For honor kill procAttacker = PROC_FLAG_KILL_AND_GET_XP
                 if(xp || honored_kill)
-                    player->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_XP_GIVER,PROC_FLAG_NONE);
+                    player->ProcDamageAndSpell(pVictim,PROC_FLAG_KILL_AND_GET_XP, PROC_FLAG_KILLED,PROC_FLAG_EX_NONE);
+                else
+                    player->ProcDamageAndSpell(pVictim,PROC_FLAG_NONE, PROC_FLAG_KILLED,PROC_FLAG_EX_NONE);
             }
         }
         else                                                // if (player)
@@ -822,18 +825,6 @@
 
         pVictim->ModifyHealth(- (int32)damage);
 
-        // Check if health is below 20% (apply damage before to prevent case when after ProcDamageAndSpell health < damage
-        if(pVictim->GetHealth()*5 < pVictim->GetMaxHealth())
-        {
-            uint32 procVictim = PROC_FLAG_NONE;
-
-            // if just dropped below 20% (for CheatDeath)
-            if((pVictim->GetHealth()+damage)*5 > pVictim->GetMaxHealth())
-                procVictim = PROC_FLAG_LOW_HEALTH;
-
-            ProcDamageAndSpell(pVictim,PROC_FLAG_TARGET_LOW_HEALTH,procVictim);
-        }
-
         if(damagetype != DOT)
         {
             //start melee attacks only after melee hit
@@ -1011,7 +1002,7 @@
     spell->m_CastItem = castItem;
     spell->prepare(&targets);
 }
-
+/*
 void Unit::DealDamageBySchool(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell)
 {
 
@@ -1318,10 +1309,22 @@
                 ((Player*)pVictim)->RewardRage(cleanDamage.damage, 0, false);
     }
 }
+*/
 
+void Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)
+{
+  SpellEntry const *procSpell = sSpellStore.LookupEntry(spellID);
+  CalcDamageInfo damageInfo;
+  CalculateDamage(SPELL_DIRECT_DAMAGE, pVictim, damage, &damageInfo, BASE_ATTACK, spellID);
+  ProcDamageAndSpell(damageInfo.target,damageInfo.procAttacker,damageInfo.procVictim,damageInfo.procEx,damageInfo.damage, procSpell, isTriggeredSpell, damageInfo.attackType);
+  DealDamage(&damageInfo, true);
+}
+
 void Unit::PeriodicAuraLog(Unit *pVictim, SpellEntry const *spellProto, Modifier *mod, uint8 effect_idx)
 {
-    uint32 procFlag = 0;
+    uint32 procAttacker = PROC_FLAG_NONE;
+    uint32 procVictim   = PROC_FLAG_NONE;
+    uint32 procEx       = PROC_FLAG_EX_NONE;
     if(!this || !pVictim || !isAlive() || !pVictim->isAlive())
     {
         return;
@@ -1332,48 +1335,10 @@
         case SPELL_AURA_PERIODIC_DAMAGE:
         case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
         {
-            uint32 absorb=0;
-            uint32 resist=0;
-            CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
-
-            uint32 pdamage;
-
-            if(mod->m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
-            {
-                pdamage = mod->m_amount;
-
-                //Calculate armor mitigation if it is a physical spell
-                if (spellProto->School == SPELL_SCHOOL_NORMAL)
-                {
-                    uint32 pdamageReductedArmor = CalcArmorReducedDamage(pVictim, pdamage);
-                    cleanDamage.damage += pdamage - pdamageReductedArmor;
-                    pdamage = pdamageReductedArmor;
-                }
-
-                CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), DOT, pdamage, &absorb, &resist);
-
-                pdamage = SpellDamageBonus(pVictim,spellProto,pdamage,DOT);
-            }
-            else
-                pdamage = uint32(pVictim->GetMaxHealth()*mod->m_amount/100);
-
-            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);
-
-            WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
-            data.append(pVictim->GetPackGUID());
-            data.append(GetPackGUID());
-            data << uint32(spellProto->Id);
-            data << uint32(1);
-            data << uint32(mod->m_auraname);
-            data << (uint32)pdamage;
-            data << (uint32)spellProto->School;
-            data << (uint32)absorb;
-            data << (uint32)resist;
-            SendMessageToSet(&data,true);
-
-            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, SpellSchools(spellProto->School), spellProto, procFlag, true);
-            ProcDamageAndSpell(pVictim, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), spellProto);
+            CalcDamageInfo damageInfo;
+            CalculateDamage(DOT, pVictim, mod->m_amount, &damageInfo, BASE_ATTACK, spellProto->Id, SpellSchools(spellProto->School), mod->m_auraname); 
+            ProcDamageAndSpell(damageInfo.target,damageInfo.procAttacker,damageInfo.procVictim,damageInfo.procEx,damageInfo.damage, spellProto, false, damageInfo.attackType);
+            DealDamage(&damageInfo, true);
             break;
         }
         case SPELL_AURA_PERIODIC_LEECH:
@@ -1401,10 +1366,17 @@
 
             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);
+// Possibly SPELL_AURA_PERIODIC_LEECH not trigger on tick
+            procAttacker |= PROC_FLAG_SUCCESSFUL_PERIODIC_DAMAGE;
+            procVictim   |= PROC_FLAG_TAKEN_PERIODIC_DAMAGE;
+            if (absorb)procEx  |= PROC_FLAG_EX_ABSORB;
+            if (resist>=pdamage) procEx|= PROC_FLAG_EX_FULL_RESISTS;
+            if  (pdamage <= absorb+resist) pdamage = 0;
+            else pdamage-=absorb+resist;
+            ProcDamageAndSpell(pVictim, procAttacker, procVictim, procEx, pdamage, spellProto);
 
             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, procFlag, false);
-            ProcDamageAndSpell(pVictim, PROC_FLAG_HIT_SPELL, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), spellProto);
+            DealDamage(pVictim, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, SpellSchools(spellProto->School), spellProto, PROC_FLAG_NONE, false);
             if (!pVictim->isAlive() && IsNonMeleeSpellCasted(false))
             {
                 for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
@@ -1481,12 +1453,12 @@
                     SendSpellNonMeleeDamageLog(this, spellProto->Id, gain, SpellSchools(spellProto->School), 0, 0, false, 0, false);
 
                     CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
-                    DealDamage(this, gain, &cleanDamage, NODAMAGE, SpellSchools(spellProto->School), spellProto, PROC_FLAG_HEAL, true);
+                    DealDamage(this, gain, &cleanDamage, NODAMAGE, SpellSchools(spellProto->School), spellProto, PROC_FLAG_SUCCESSFUL_HEAL, true);
                 }
             }
 
-            if(procSpell)
-                ProcDamageAndSpell(pVictim, PROC_FLAG_HEAL, PROC_FLAG_HEALED, pdamage, spellProto);
+//            if(procSpell)
+//                ProcDamageAndSpell(pVictim, PROC_FLAG_HEAL, PROC_FLAG_HEALED, pdamage, spellProto);
             break;
         }
         case SPELL_AURA_PERIODIC_MANA_LEECH:
@@ -1591,6 +1563,746 @@
     }
 }
 
+
+void Unit::CalculateDamage(DamageEffectType type, Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType, uint32 spellID, SpellSchools damageSchool, uint32 auraname)
+{
+    damageInfo->attackType     = attackType;
+    damageInfo->hitOutCome     = MELEE_HIT_EVADE;
+    damageInfo->damage         = 0;
+    damageInfo->cleanDamage    = 0;
+    damageInfo->absorb         = 0;
+    damageInfo->resist         = 0;
+    damageInfo->blocked_amount = 0;
+    damageInfo->procAttacker   = PROC_FLAG_NONE;
+    damageInfo->procVictim     = PROC_FLAG_NONE;
+    damageInfo->procEx         = PROC_FLAG_EX_NONE;
+    damageInfo->damagetype     = type;
+    damageInfo->target         = pVictim;
+    damageInfo->TargetState    = 0;
+
+    if      (damageInfo->attackType == BASE_ATTACK) damageInfo->HitInfo  = HITINFO_NORMALSWING2;
+    else if (damageInfo->attackType == OFF_ATTACK ) damageInfo->HitInfo  = HITINFO_LEFTSWING;
+    else if (damageInfo->attackType == RANGED_ATTACK ) damageInfo->HitInfo  = 0x08;// test
+
+    damageInfo->SpellID        = spellID;
+    damageInfo->damageSchool   = damageSchool;
+    damageInfo->auraname       = auraname;
+
+    if(!this || !pVictim)
+        return;
+    if(!this->isAlive() || !pVictim->isAlive())
+        return;
+
+
+    switch (type)
+    {
+     case DIRECT_DAMAGE:      CalculateMeleeDamage(damage, damageInfo); break;
+     case SPELL_DIRECT_DAMAGE:CalculateSpellDamage(damage, damageInfo); break;
+     case DOT:                CalculateDotDamage(damage, damageInfo); break;
+         // TODO add special func for this
+     case DAMAGE_SHIELD:      
+            damageInfo->damage=damage;
+            SpellEntry const *spellInfo = sSpellStore.LookupEntry(damageInfo->SpellID);
+            if(!spellInfo)
+             break;
+         damageInfo->damageSchool = SpellSchools(spellInfo->School);
+         break;
+    }
+    // Calculate absorb resist
+    if(damageInfo->damage > 0)
+    {
+        // Immune check
+        if(pVictim->IsImmunedToSchoolDamage(damageInfo->damageSchool) )
+        {
+           damageInfo->HitInfo    |= HITINFO_MISS|HITINFO_SWINGNOHITSOUND;
+           damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE;
+           damageInfo->damage         = 0;
+           damageInfo->cleanDamage    = 0;
+           damageInfo->absorb         = 0;
+           damageInfo->resist         = 0;
+           damageInfo->blocked_amount = 0;
+           return;
+        }
+        // Calculate absorb & resists
+        if (damageInfo->damage)
+          CalcAbsorbResist(pVictim, damageInfo->damageSchool, damageInfo->damagetype, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist);
+        // Only send absorbed message if we actually absorbed some damage
+        if (damageInfo->absorb)
+        {
+            damageInfo->HitInfo|= HITINFO_ABSORB;
+            damageInfo->procEx |= PROC_FLAG_EX_ABSORB;
+            if (damageInfo->damage< damageInfo->absorb)damageInfo->absorb = damageInfo->damage;
+            damageInfo->damage-=damageInfo->absorb;
+        }
+        if (damageInfo->resist && damageInfo->damage)
+        {
+         damageInfo->HitInfo|= HITINFO_RESIST;
+         if (damageInfo->damage< damageInfo->resist)
+         {
+            damageInfo->resist = damageInfo->damage;
+            damageInfo->procEx |= PROC_FLAG_EX_FULL_RESISTS;
+         }
+         damageInfo->damage-=damageInfo->resist;
+        }
+    }
+    
+    if (damageInfo->damage==0)
+        damageInfo->HitInfo|=HITINFO_SWINGNOHITSOUND;
+}
+void Unit::CalculateDotDamage(uint32 damage, CalcDamageInfo *damageInfo)
+{
+    SpellEntry const *spellInfo = sSpellStore.LookupEntry(damageInfo->SpellID);
+    if(!spellInfo)
+        return;
+
+    if (damageInfo->damageSchool==SPELL_SCHOOL_NORMAL) 
+        damageInfo->damageSchool = SpellSchools(spellInfo->School);
+    switch(damageInfo->auraname)
+    {
+     case SPELL_AURA_PERIODIC_DAMAGE: break;//damage = damage;
+     case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: damage = uint32(damageInfo->target->GetMaxHealth()*damage/100);break;
+
+    }
+    //Calculate armor mitigation if it is a physical spell
+    if (damageInfo->damageSchool == SPELL_SCHOOL_NORMAL)
+    {
+       //Calculate armor mitigation
+       damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
+       damageInfo->cleanDamage += damageInfo->damage - damage;
+    }
+    else
+       damageInfo->damage = SpellDamageBonus(damageInfo->target, spellInfo, damage, DOT);
+    damageInfo->procAttacker |= PROC_FLAG_SUCCESSFUL_PERIODIC_DAMAGE;
+    damageInfo->procVictim   |= PROC_FLAG_TAKEN_PERIODIC_DAMAGE;
+    if (damageInfo->damage) damageInfo->procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
+}
+void Unit::CalculateSpellDamage(uint32 damage, CalcDamageInfo *damageInfo)
+{
+     SpellEntry const *spellInfo = sSpellStore.LookupEntry(damageInfo->SpellID);
+     if(!spellInfo)
+        return;
+     if (damageInfo->damageSchool==SPELL_SCHOOL_NORMAL) 
+         damageInfo->damageSchool = SpellSchools(spellInfo->School);
+     // Per-school calc
+     switch (damageInfo->damageSchool)
+     {
+         // Physical damage school
+         case SPELL_SCHOOL_NORMAL:
+         {
+            // Add melee damage bonuses
+            MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
+            
+            //Calculate armor mitigation
+            damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
+            damageInfo->cleanDamage += damageInfo->damage - damage;
+
+            // Calculate physical outcome
+            damageInfo->hitOutCome = RollPhysicalOutcomeAgainst(damageInfo->target, damageInfo->attackType, spellInfo);
+            // Disable parry for ranged attack
+            if(damageInfo->attackType == RANGED_ATTACK && (damageInfo->hitOutCome == MELEE_HIT_PARRY))
+                  damageInfo->hitOutCome = MELEE_HIT_NORMAL;
+
+            switch(damageInfo->hitOutCome)
+            {
+                case MELEE_HIT_EVADE:
+                {
+                    damageInfo->HitInfo     |= HITINFO_MISS|HITINFO_SWINGNOHITSOUND;
+                    damageInfo->TargetState  = VICTIMSTATE_EVADES;
+                    damageInfo->procEx|=PROC_FLAG_EX_HIT_EVADE_TARGET;
+                    damageInfo->damage = 0;
+		            damageInfo->cleanDamage = 0;
+                    return;
+                }
+                case MELEE_HIT_MISS:
+                {
+                    damageInfo->HitInfo     |= HITINFO_MISS;
+                    damageInfo->TargetState  = VICTIMSTATE_NORMAL;
+                    damageInfo->procEx|=PROC_FLAG_EX_MISS;
+                    damageInfo->damage = 0;
+		            damageInfo->cleanDamage = 0;
+                    break;
+                }
+                case MELEE_HIT_CRIT:
+                {
+                    damageInfo->HitInfo     |= HITINFO_CRITICALHIT;
+                    damageInfo->TargetState  = VICTIMSTATE_NORMAL;
+                    damageInfo->procEx|=PROC_FLAG_EX_CRITICAL_HIT;
+                    uint32 crit_bonus = damageInfo->damage;
+                    // Apply crit_damage bonus for melee spells
+                    if(Player* modOwner = GetSpellModOwner())
+                       modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
+                    damageInfo->damage += crit_bonus;
+                    if(damageInfo->attackType == RANGED_ATTACK)
+                    {
+                     int32 mod = damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
+                     damageInfo->damage = int32((damageInfo->damage) * float((100.0f + mod)/100.0f));
+                    }
+                    else
+                    {
+                     int32 mod = damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
+                     damageInfo->damage = int32((damageInfo->damage) * float((100.0f + mod)/100.0f));
+                    }
+
+                    // Resilience - reduce crit damage by 2x%
+                    uint32 resilienceReduction = uint32(damageInfo->target->m_modResilience * 2/100 * (damageInfo->damage));
+                    damageInfo->cleanDamage += resilienceReduction;
+                    damageInfo->damage      -= resilienceReduction;
+                    break;
+                }
+                case MELEE_HIT_PARRY:
+                {
+                    damageInfo->HitInfo     |= HITINFO_NORMALSWING;
+                    damageInfo->TargetState  = VICTIMSTATE_PARRY;
+                    damageInfo->procEx|=PROC_FLAG_EX_PARRY;
+                    damageInfo->cleanDamage += damageInfo->damage;         // To Help Calculate Rage
+                    damageInfo->damage = 0;
+                    break;
+                }
+                case MELEE_HIT_DODGE:
+                {
+                    damageInfo->HitInfo    |= HITINFO_NORMALSWING;
+                    damageInfo->TargetState = VICTIMSTATE_DODGE;
+                    damageInfo->procEx|=PROC_FLAG_EX_DODGE;
+                    damageInfo->cleanDamage += damageInfo->damage;         // To Help Calculate Rage
+                    damageInfo->damage = 0;
+                    break;
+                }
+                case MELEE_HIT_BLOCK:
+                {
+                    damageInfo->HitInfo    |= HITINFO_NORMALSWING;
+                    damageInfo->TargetState = VICTIMSTATE_BLOCKS;
+                    damageInfo->procEx|=PROC_FLAG_EX_BLOCK;
+                    damageInfo->blocked_amount = uint32(damageInfo->target->GetShieldBlockValue());
+                    if (damageInfo->blocked_amount > damageInfo->damage)
+                        damageInfo->blocked_amount = damageInfo->damage;
+
+                    damageInfo->cleanDamage += damageInfo->blocked_amount;  // To Help Calculate Rage
+                    damageInfo->damage      -= damageInfo->blocked_amount;
+                    break;
+                }
+                case MELEE_HIT_GLANCING:
+                case MELEE_HIT_CRUSHING:
+                case MELEE_HIT_NORMAL:
+                    damageInfo->TargetState = VICTIMSTATE_NORMAL;
+                break;
+            }
+            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:
+            damageInfo->TargetState = VICTIMSTATE_NORMAL;
+/*            if( SpellMissChanceCalc(damageInfo->target, damageInfo->damageSchool) > urand(0,10000) )
+            {
+                damageInfo->HitInfo|= HITINFO_RESIST;
+
+                damageInfo->procEx|=PROC_FLAG_EX_MISS;
+                damageInfo->damage = 0;
+                break;
+            }*/
+
+            // Calculate damage bonus
+            damageInfo->damage = SpellDamageBonus(damageInfo->target, spellInfo, damage, SPELL_DIRECT_DAMAGE);
+            bool crit=false;
+            // Calculate critical bonus           
+            if(spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE)
+            {
+                // Calculate physical outcome
+                if(RollPhysicalOutcomeAgainst(damageInfo->target, BASE_ATTACK, spellInfo) == MELEE_HIT_CRIT)
+                {
+                    crit = true;
+                    damageInfo->damage *= 2;
+                    // Resilience - reduce crit damage by 2x%
+                    uint32 resilienceReduction = uint32(damageInfo->target->m_modResilience * 2/100 * (damageInfo->damage));
+                    damageInfo->cleanDamage += resilienceReduction;
+                    damageInfo->damage      -= resilienceReduction;
+                }
+            }
+            else
+                crit = SpellCriticalBonus(spellInfo, &damageInfo->damage, damageInfo->target);
+            if (crit)
+            {
+               damageInfo->HitInfo|= HITINFO_CRITICALHIT;
+               damageInfo->procEx|=PROC_FLAG_EX_CRITICAL_HIT;
+            }
+            break;
+    }
+    if(spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
+    {
+      damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT;
+      damageInfo->procVictim   = PROC_FLAG_TAKEN_MELEE_SPELL_HIT;
+    }
+    else if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
+    {
+      damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
+      damageInfo->procVictim   = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
+    }
+    else
+    {
+      damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
+      damageInfo->procVictim   = PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
+    }
+    if (damageInfo->damage) damageInfo->procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
+}
+
+void Unit::CalculateMeleeDamage(uint32 damage, CalcDamageInfo *damageInfo)
+{
+    damage += CalculateDamage (damageInfo->attackType); 
+    // Add melee damage bonus
+    MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
+    // Calculate armor reduction
+    damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
+    damageInfo->cleanDamage += damage - damageInfo->damage;
+    
+    damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
+
+    // Disable parry for ranged attack
+    if(damageInfo->attackType == RANGED_ATTACK && (damageInfo->hitOutCome == MELEE_HIT_PARRY))
+       damageInfo->hitOutCome = MELEE_HIT_NORMAL;
+
+    switch(damageInfo->hitOutCome)
+    {
+        case MELEE_HIT_EVADE:
+        {
+            damageInfo->HitInfo    |= HITINFO_MISS|HITINFO_SWINGNOHITSOUND;
+            damageInfo->TargetState = VICTIMSTATE_EVADES;
+
+            damageInfo->procEx|=PROC_FLAG_EX_HIT_EVADE_TARGET;
+            damageInfo->damage = 0;
+            damageInfo->cleanDamage = 0;
+            return;
+        }
+        case MELEE_HIT_MISS:
+        {
+            damageInfo->HitInfo    |= HITINFO_MISS;
+            damageInfo->TargetState = VICTIMSTATE_NORMAL;
+
+            damageInfo->procEx|=PROC_FLAG_EX_MISS;
+            damageInfo->damage = 0;
+            damageInfo->cleanDamage = 0;
+            break;
+        }
+        case MELEE_HIT_NORMAL:
+            damageInfo->TargetState = VICTIMSTATE_NORMAL;
+            break;
+        case MELEE_HIT_CRIT:
+           {
+            damageInfo->HitInfo     |= 0x8|HITINFO_CRITICALHIT;
+            damageInfo->TargetState  = VICTIMSTATE_NORMAL;
+
+            damageInfo->procEx|=PROC_FLAG_EX_CRITICAL_HIT;
+            // Crit bonus calc
+            damageInfo->damage += damageInfo->damage;
+            if(damageInfo->attackType == RANGED_ATTACK)
+                damageInfo->damage *= (damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE)+100)/100;
+            else
+                damageInfo->damage *= (damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE)+100)/100;
+
+            // Resilience - reduce crit damage by 2x%
+            uint32 resilienceReduction;
+            resilienceReduction = uint32(damageInfo->target->m_modResilience * 2/100 * (damageInfo->damage));
+
+            damageInfo->damage      -= resilienceReduction;
+            damageInfo->cleanDamage += resilienceReduction;
+           }
+           break;
+
+        case MELEE_HIT_PARRY:
+            damageInfo->TargetState  = VICTIMSTATE_PARRY;
+            damageInfo->procEx|=PROC_FLAG_EX_PARRY;
+            damageInfo->cleanDamage += damageInfo->damage;
+            damageInfo->damage = 0;
+            break;
+
+        case MELEE_HIT_DODGE:
+            damageInfo->TargetState  = VICTIMSTATE_DODGE;
+            damageInfo->procEx|=PROC_FLAG_EX_DODGE;
+            damageInfo->cleanDamage += damageInfo->damage;
+            damageInfo->damage = 0;
+            break;
+
+        case MELEE_HIT_BLOCK:
+           {
+            damageInfo->TargetState = VICTIMSTATE_BLOCKS;
+            damageInfo->procEx|=PROC_FLAG_EX_BLOCK;
+            damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();
+            if (damageInfo->blocked_amount >= damageInfo->damage)
+                damageInfo->blocked_amount = damageInfo->damage;
+
+            damageInfo->damage      -= damageInfo->blocked_amount;
+            damageInfo->cleanDamage += damageInfo->blocked_amount;
+           }
+           break;
+
+        case MELEE_HIT_GLANCING:
+        {
+            damageInfo->HitInfo     |= HITINFO_GLANCING;
+            damageInfo->TargetState  = VICTIMSTATE_NORMAL;
+            float reducePercent = 1.0f;                     //damage factor
+            // calculate base values and mods
+            float baseLowEnd = 1.3;
+            float baseHighEnd = 1.2;
+            switch(getClass())                              // lowering base values for casters
+            {
+                case CLASS_SHAMAN:
+                case CLASS_PRIEST:
+                case CLASS_MAGE:
+                case CLASS_WARLOCK:
+                case CLASS_DRUID:
+                    baseLowEnd  -= 0.7;
+                    baseHighEnd -= 0.3;
+                    break;
+            }
+
+            float maxLowEnd = 0.6;
+            switch(getClass())                              // upper for melee classes
+            {
+                case CLASS_WARRIOR:
+                case CLASS_ROGUE:
+                    maxLowEnd = 0.91;                       //If the attacker is a melee class then instead the lower value of 0.91
+            }
+
+            // calculate values
+            int32 diff = damageInfo->target->GetDefenseSkillValue() - GetWeaponSkillValue(damageInfo->attackType);
+            float lowEnd  = baseLowEnd - ( 0.05f * diff );
+            float highEnd = baseHighEnd - ( 0.03f * diff );
+
+            // apply max/min bounds
+            if ( lowEnd < 0.01f )                           //the low end must not go bellow 0.01f
+                lowEnd = 0.01f;
+            else if ( lowEnd > maxLowEnd )                  //the smaller value of this and 0.6 is kept as the low end
+                lowEnd = maxLowEnd;
+
+            if ( highEnd < 0.2f )                           //high end limits
+                highEnd = 0.2f;
+            if ( highEnd > 0.99f )
+                highEnd = 0.99f;
+
+            if(lowEnd > highEnd)                            // prevent negative range size
+                lowEnd = highEnd;
+
+            reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd );
+ 
+            damageInfo->cleanDamage += damageInfo->damage-uint32(reducePercent *  damageInfo->damage);
+            damageInfo->damage   = uint32(reducePercent *  damageInfo->damage);
+            break;
+        }
+        case MELEE_HIT_CRUSHING:
+        {
+            damageInfo->HitInfo     |= HITINFO_CRUSHING;
+            damageInfo->TargetState  = VICTIMSTATE_NORMAL;
+            // 150% normal damage
+            damageInfo->damage += (damageInfo->damage / 2);
+ //           cleanDamage->damage = *damage;
+            break;
+        }
+        default:
+
+            break;
+    }
+
+    if (damageInfo->attackType == BASE_ATTACK)
+    {
+        damageInfo->procAttacker |= PROC_FLAG_SUCCESSFUL_MILEE_HIT;
+        damageInfo->procVictim   |= PROC_FLAG_TAKEN_MELEE_HIT;
+    }
+    else if (damageInfo->attackType ==  OFF_ATTACK)
+    {
+       damageInfo->procAttacker |= PROC_FLAG_SUCCESSFUL_MILEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT;
+       damageInfo->procVictim   |= PROC_FLAG_TAKEN_MELEE_HIT;//|PROC_FLAG_TAKEN_OFFHAND_HIT // not used
+    }
+    else if (damageInfo->attackType ==  RANGED_ATTACK)
+    {
+       damageInfo->procAttacker |= PROC_FLAG_SUCCESSFUL_RANGED_HIT;
+       damageInfo->procVictim   |= PROC_FLAG_TAKEN_RANGED_HIT;
+    }
+    if (damageInfo->damage) damageInfo->procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
+}
+
+void Unit::SendAttackStateUpdate(CalcDamageInfo *damageInfo)
+{
+    sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
+    WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45));    // we guess size
+    data << (uint32)damageInfo->HitInfo;
+    data.append(GetPackGUID());
+    data.append(damageInfo->target->GetPackGUID());
+    data << (uint32)(damageInfo->damage);     // Full damage
+
+    data << (uint8)1;                         // Sub damage count
+    //===  Sub damage description
+    data << (uint32)damageInfo->damageSchool; // School of sub damage
+    data << (float)damageInfo->damage;        // sub damage
+    data << (uint32)damageInfo->damage;       // Sub Damage
+    data << (uint32)damageInfo->absorb;       // Absorb
+    data << (uint32)damageInfo->resist;       // Resist
+    //=================================================
+    data << (uint32)damageInfo->TargetState;
+//    if(damageInfo->absorb == 0 )                                 //also 0x3E8 = 0x3E8, check when that happens
+    data << (uint32)0;
+//    else
+//        data << (uint32)-1;
+    data << (uint32)0;
+    data << (uint32)damageInfo->blocked_amount;
+    SendMessageToSet( &data, true );
+}
+void Unit::SendSpellNonMeleeDamageLog(CalcDamageInfo *damageInfo)
+{ 
+    uint8 CriticalHit = damageInfo->HitInfo&HITINFO_CRITICALHIT ? 2 : 0;
+    WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+31)); // we guess size
+    data.append(damageInfo->target->GetPackGUID());
+    data.append(GetPackGUID());
+    data << uint32(damageInfo->SpellID);
+    data << uint32(damageInfo->damage);
+    data << uint8(damageInfo->damageSchool);                //damagetype
+    data << uint32(damageInfo->absorb);                     //AbsorbedDamage
+    data << uint32(damageInfo->resist);                     //resist
+    data << uint8(0);//PhysicalDamage);
+    data << uint8(0);
+    data << uint32(damageInfo->blocked_amount);             //blocked
+    data << uint8(CriticalHit);                             //seen 0x05 also...
+    data << uint32(0);
+    SendMessageToSet( &data, true );/**/
+}
+
+void Unit::SendSpellDotDamageLog(CalcDamageInfo *damageInfo)
+{
+    WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
+    data.append(damageInfo->target->GetPackGUID());
+    data.append(GetPackGUID());
+    data << uint32(damageInfo->SpellID);
+    data << uint32(1);
+    data << uint32(damageInfo->auraname);
+    switch(damageInfo->auraname)
+    {
+        case SPELL_AURA_PERIODIC_DAMAGE:
+        case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
+           data << uint32(damageInfo->damage);
+           data << uint32(damageInfo->damageSchool);
+           data << uint32(damageInfo->absorb);
+           data << uint32(damageInfo->resist);
+           break;
+        case SPELL_AURA_PERIODIC_HEAL:
+        case SPELL_AURA_OBS_MOD_HEALTH:
+           data << uint32(damageInfo->damage);
+           break;
+        default:
+            return;
+    }
+    SendMessageToSet(&data,true);
+}
+
+void Unit::DealDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
+{
+    if (damageInfo==0) return;
+    Unit *pVictim = damageInfo->target;
+    if(!this || !pVictim)
+        return;
+    if (!pVictim->isAlive() || pVictim->isInFlight() || pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
+        return;
+    SpellEntry const *spellProto=NULL;
+    if (damageInfo->SpellID)
+    {
+        spellProto = sSpellStore.LookupEntry(damageInfo->SpellID);
+        if (spellProto == NULL)
+        {
+            sLog.outDebug("Unit::DealDamage have wrong damageInfo->SpellID: %u", damageInfo->SpellID);
+            return;
+        }
+    }
+    //You don't lose health from damage taken from another player while in a sanctuary
+    //You still see it in the combat log though
+    if(pVictim != this && GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
+    {
+        const AreaTableEntry *area = GetAreaEntryByAreaID(pVictim->GetAreaId());
+        if(area && area->flags & 0x800)                     //sanctuary
+            return;
+    }
+    // Send log damage message to client
+    switch (damageInfo->damagetype)
+    {
+     case DIRECT_DAMAGE:
+         SendAttackStateUpdate(damageInfo);
+     break;
+     case DAMAGE_SHIELD:
+         {
+          WorldPacket data(SMSG_SPELLDAMAGESHIELD,(16+31));
+          data << uint64(GetGUID());
+          data << uint64(damageInfo->target->GetGUID());
+          data << uint32(damageInfo->damage);
+          data << uint32(damageInfo->damageSchool);
+          damageInfo->target->SendMessageToSet( &data, true );
+         }
+         break;
+     case SPELL_DIRECT_DAMAGE:
+         if (damageInfo->damage==0)
+             SendAttackStateUpdate(damageInfo);
+         else                       
+             SendSpellNonMeleeDamageLog(damageInfo); 
+     break;
+     case DOT: 
+         SendSpellDotDamageLog(damageInfo);
+     break;
+     default:
+         SendSpellNonMeleeDamageLog(damageInfo);
+     break;
+    }
+    // Enable AURA_STATE_CRIT on crit
+    if (damageInfo->HitInfo&HITINFO_CRITICALHIT)
+    {
+      ModifyAuraState(AURA_STATE_CRIT, true);
+      if(getClass()==CLASS_HUNTER)
+        ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true);
+
+      pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
+    }
+    // For melee attack UpdateCombatSkills
+    if (damageInfo->hitOutCome)
+    {
+     // Clear aura states for meele
+     pVictim->ModifyAuraState(AURA_STATE_DEFENSE, false);
+     if(getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER) // Clear OVERPOWER
+         ((Player*)this)->ClearComboPoints();
+     ModifyAuraState(AURA_STATE_CRIT, false);
+
+     if(getClass()==CLASS_HUNTER)
+         ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, false);
+     if(pVictim->getClass()==CLASS_HUNTER)
+         pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
+
+     if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER )
+        ((Player*)this)->UpdateCombatSkills(pVictim, damageInfo->attackType, damageInfo->hitOutCome, false);
+
+     if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
+        ((Player*)pVictim)->UpdateCombatSkills(this, damageInfo->attackType, damageInfo->hitOutCome, true);
+    }
+    // Modify victim state depends on damageInfo->TargetState
+    switch(damageInfo->TargetState)
+    {
+     case VICTIMSTATE_PARRY:
+     {
+       // 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(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));
+          }
+       }
+       else
+       {
+          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));
+          }
+       }
+       // Update victim defense ?
+       if(pVictim->GetTypeId() == TYPEID_PLAYER)
+             ((Player*)pVictim)->UpdateDefense();
+
+       // Set parry flags
+       pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+
+       if (pVictim->getClass() == CLASS_HUNTER)        // Mongoose Bite
+           pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY, true);
+       else
+           pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+     }
+     break;
+     case VICTIMSTATE_BLOCKS:
+     {
+         if (pVictim->GetUnitBlockChance())
+                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
+         else
+                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+         if(pVictim->GetTypeId() == TYPEID_PLAYER)
+                ((Player*)pVictim)->UpdateDefense();
+          pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
+     }
+     break;
+     case VICTIMSTATE_DODGE:
+     {
+       if(pVictim->GetTypeId() == TYPEID_PLAYER)
+          ((Player*)pVictim)->UpdateDefense();
+
+       pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+       if (pVictim->getClass() != CLASS_ROGUE)         // Riposte
+           pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+       // Overpower
+       if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
+            ((Player*)this)->AddComboPoints(pVictim, 1);
+     }
+     break;
+     default:
+         break;
+    }
+    /// If this is a creature and it attacks from behind it has a probability to daze it's victim
+    if( (damageInfo->hitOutCome==MELEE_HIT_CRIT || damageInfo->hitOutCome==MELEE_HIT_CRUSHING || damageInfo->hitOutCome==MELEE_HIT_NORMAL || damageInfo->hitOutCome==MELEE_HIT_GLANCING) &&
+        GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) )
+    {
+        // -probability is between 0% and 40%
+        // 20% base chance
+        float Probability = 20;
+
+        //there is a newbie protection, at level 10 just 7% base chance; assuming linear function
+        if( pVictim->getLevel() < 30 )
+            Probability = 0.65f*pVictim->getLevel()+0.5;
+
+        uint32 VictimDefense=pVictim->GetDefenseSkillValue();
+        uint32 AttackerMeleeSkill=GetUnitMeleeSkill();
+
+        Probability *= AttackerMeleeSkill/(float)VictimDefense;
+
+        if(Probability > 40)
+            Probability = 40;
+
+        if(roll_chance_f(Probability))
+            CastSpell(pVictim, 1604, true);
+    }
+
+    // update at damage Judgement aura duration that applied by attacker at victim
+    if(damageInfo->damage)
+    {
+           AuraMap& vAuras = pVictim->GetAuras();
+           for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr)
+           {
+               SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
+               if( spellInfo->AttributesEx3 == 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
+                   ((*itr).second->GetCasterGUID() == GetGUID() || (spellProto && spellProto->Id == 35395) ))
+               {
+                  (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
+                  (*itr).second->UpdateAuraDuration();
+               }
+           }
+    }
+    // Call default DealDamage
+    CleanDamage cleanDamage(damageInfo->cleanDamage,damageInfo->attackType,damageInfo->hitOutCome);
+    DealDamage(pVictim, damageInfo->damage, &cleanDamage, damageInfo->damagetype, damageInfo->damageSchool, spellProto, 0, durabilityLoss);
+}
+
+
 void Unit::HandleEmoteCommand(uint32 anim_id)
 {
     WorldPacket data( SMSG_EMOTE, 12 );
@@ -1729,7 +2441,7 @@
 
     *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)
 {
     pVictim->ModifyAuraState(AURA_STATE_DEFENSE, false);
@@ -2141,7 +2853,7 @@
         }
     }
 }
-
+*/
 void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool isTriggered)
 {
     if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
@@ -2162,61 +2874,85 @@
             return;
         }
     }
-
-    uint32 hitInfo;
-    if (attType == BASE_ATTACK)
-        hitInfo = HITINFO_NORMALSWING2;
-    else if (attType == OFF_ATTACK)
-        hitInfo = HITINFO_LEFTSWING;
-    else
-        return;
-
-    VictimState victimState = VICTIMSTATE_NORMAL;
-
-    uint32   damage = 0;
-    CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
-    uint32   blocked_dmg = 0;
-    uint32   absorbed_dmg = 0;
-    uint32   resisted_dmg = 0;
-
-    SpellSchools meleeSchool = GetMeleeDamageSchool();
-
-    if( meleeSchool == SPELL_SCHOOL_NORMAL && pVictim->IsImmunedToPhysicalDamage() )
+    CalcDamageInfo damageInfo;
+    CalculateDamage(DIRECT_DAMAGE, pVictim, 0, &damageInfo, attType);
+    ProcDamageAndSpell(damageInfo.target,damageInfo.procAttacker,damageInfo.procVictim,damageInfo.procEx,damageInfo.damage, 0, false, damageInfo.attackType);
+    DealDamage(&damageInfo,true);
+    pVictim = damageInfo.target;
+    if (pVictim && !(damageInfo.HitInfo & HITINFO_MISS))
     {
-        SendAttackStateUpdate (HITINFO_MISS, pVictim, 1, meleeSchool, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0);
-        return;
-    }
-
-    DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchool, &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);
-    else
-    {
-        //do animation
-        SendAttackStateUpdate (hitInfo, pVictim, 1, meleeSchool, 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, 0, true);
-
         if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive())
         {
             for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
                 ((Player*)this)->CastItemCombatSpell(((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i),pVictim,attType);
         }
+        // victim's damage shield
+        // yet another hack to fix crashes related to the aura getting removed during iteration
+        std::set<Aura*> alreadyDone;
+        uint32 removedAuras = pVictim->m_removedAuras;
+        AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
+        for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
+        {
+           next++;
+           if (alreadyDone.find(*i) == alreadyDone.end())
+           {
+               alreadyDone.insert(*i);
+               CalcDamageInfo damageInfo;
+               pVictim->CalculateDamage(DAMAGE_SHIELD, this, (*i)->GetModifier()->m_amount, &damageInfo, BASE_ATTACK, (*i)->GetId());
+               pVictim->DealDamage(&damageInfo, true);
+               if (pVictim->m_removedAuras > removedAuras)
+               {
+                   removedAuras = pVictim->m_removedAuras;
+                   next = vDamageShields.begin();
+               }
+           }
+        }
+        if (pVictim->GetTypeId() == TYPEID_PLAYER && damageInfo.damage)
+        {
+            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(pVictim->m_currentSpells[i])
+                {
+                    sLog.outDetail("Spell Delayed!%d",(int32)(0.25f * pVictim->m_currentSpells[i]->casttime));
+                    pVictim->m_currentSpells[i]->Delayed((int32)(0.25f * pVictim->m_currentSpells[i]->casttime));
+                }
+            }
+            // process channeled spell separately
+            if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL])
+            {
+                if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_CASTING)
+                {
+                    uint32 channelInterruptFlags = pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->ChannelInterruptFlags;
+                    if( channelInterruptFlags & CHANNEL_FLAG_DELAY )
+                    {
+                        sLog.outDetail("Spell Delayed!%d",(int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
+                        pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->DelayedChannel((int32)(0.25f * GetDuration(pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo)));
+                        return;
+                    }
+                    else if( !(channelInterruptFlags & (CHANNEL_FLAG_DAMAGE | CHANNEL_FLAG_DAMAGE2)) )
+                        return;
+                    sLog.outDetail("Spell Canceled!");
+                    pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
+                }
+                else if (pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() == SPELL_STATE_DELAYED)
+                {
+                    // break channeled spell in delayed state on damage
+                    sLog.outDetail("Spell Canceled!");
+                    pVictim->m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
+                }
+            }
+        }
     }
 
     if (GetTypeId() == TYPEID_PLAYER)
         DEBUG_LOG("AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
-            GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, absorbed_dmg, blocked_dmg, resisted_dmg);
+            GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
     else
         DEBUG_LOG("AttackerStateUpdate: (NPC)    %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.",
-            GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, absorbed_dmg, blocked_dmg, resisted_dmg);
+            GetGUIDLow(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
 }
 
 MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo)
@@ -2471,7 +3207,7 @@
     ((Creature*)victim)->AI().EnterEvadeMode(this);*/
 }
 
-uint32 Unit::SpellMissChanceCalc(Unit *pVictim) const
+uint32 Unit::SpellMissChanceCalc(Unit *pVictim, SpellSchools school) const
 {
     if(!pVictim)
         return 0;
@@ -2483,7 +3219,7 @@
     if(leveldif < 0)
         leveldif = 0;
 
-    int32 misschance = 400 - m_modSpellHitChance*100;
+    int32 misschance = 400 - m_modSpellHitChance[school]*100;
     if(leveldif < 3)
         misschance += leveldif * 100;
     else
@@ -2495,6 +3231,50 @@
     return misschance < 100 ? 100 : misschance;
 }
 
+uint32 Unit::SpellResistChanceCalc(Unit *pVictim, SpellSchools school) const
+{
+
+    return 0;
+}
+
+//static uint8 temp = 0;
+uint8  Unit::SpellCastResult(Unit *pVictim, SpellEntry const *spell) const
+{
+//    return temp;
+    // Return evade for units in evade mode
+    if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
+       return SPELL_HIT_EVADE;
+    // All positive spells cant miss
+    // TODO: client not show miss log for this spells - so need find info for this in dbc and use it!
+    if (IsPositiveSpell(spell->Id)) return SPELL_HIT_NONE;
+
+    // Immune check
+    // Possibly need use SPELL_HIT_IMMUNE for damage immune
+    // SPELL_HIT_IMMUNE2 for immune from school
+    if(pVictim->IsImmunedToSpellDamage(spell)) 
+        return SPELL_HIT_IMMUNE;   
+           
+    switch (spell->School)
+    {
+     // TODO remove hack for normal school
+     case SPELL_SCHOOL_NORMAL: 
+         return SPELL_HIT_NONE;
+
+     case SPELL_SCHOOL_HOLY:
+     case SPELL_SCHOOL_FIRE:
+     case SPELL_SCHOOL_NATURE:
+     case SPELL_SCHOOL_FROST:
+     case SPELL_SCHOOL_SHADOW:
+     case SPELL_SCHOOL_ARCANE:
+     {
+         uint32 missChance = SpellMissChanceCalc(pVictim, SpellSchools(spell->School));
+         if (missChance>urand(0,10000)) return SPELL_HIT_RESIST;
+     }
+    }
+    return SPELL_HIT_NONE;
+}
+
+
 int32 Unit::MeleeMissChanceCalc(const Unit *pVictim) const
 {
     if(!pVictim)
@@ -3375,6 +4155,8 @@
     AuraMap::iterator iter;
     while((iter = m_Auras.find(spellEffectPair(spellId, effindex))) != m_Auras.end())
         RemoveAura(iter);
+
+
 }
 
 void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
@@ -3679,7 +4461,7 @@
     data.append(target->GetPackGUID());
     data.append(GetPackGUID());
     data << uint32(SpellID);
-    data << uint32(Damage-AbsorbedDamage-Resist-Blocked);
+    data << uint32(Damage);
     data << uint8(DamageType);                              //damagetype
     data << uint32(AbsorbedDamage);                         //AbsorbedDamage
     data << uint32(Resist);                                 //resist
@@ -3690,7 +4472,7 @@
     data << uint32(0);
     SendMessageToSet( &data, true );
 }
-
+/*
 void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
 {
     sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
@@ -3722,52 +4504,38 @@
 
     SendMessageToSet( &data, true );
 }
-
-void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType)
+*/
+void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 damage, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType)
 {
     sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim);
     if(procSpell)
         sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":""));
-
-    // Assign melee/ranged proc flags for magic attacks, that are actually melee/ranged abilities
-    // not assign for spell proc triggered spell to prevent infinity (or unexpacted 2-3 times) melee damage spell proc call with melee damage effect
-    // That is the question though if it's fully correct
-    if(procSpell && !isTriggeredSpell)
+    if (procSpell)
     {
-        if(procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
+        switch (procSpell->SpellFamilyName)
         {
-            if(procAttacker &  PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_MELEE;
-            if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_MELEE;
-            if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_MELEE;
-            if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_MELEE;
-            attType = BASE_ATTACK;                          // Melee abilities are assumed to be dealt with mainhand weapon
+            case SPELLFAMILY_WARLOCK: // For Hellfire Effect and Rain of Fire triggers need do it
+                if (procSpell->SpellFamilyFlags & 0x0000000000000060LL) isTriggeredSpell = false;
+            break;
+            case SPELLFAMILY_PALADIN:// For Holy Shock triggers need do it
+                if (procSpell->SpellFamilyFlags & 0x0000000000200000LL) isTriggeredSpell = false;
+            break;
         }
-        else if (procSpell->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
-        {
-            if(procAttacker &  PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_RANGED;
-            if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_RANGED;
-            if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_RANGED;
-            if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_RANGED;
-            attType = RANGED_ATTACK;
-        }
     }
-    if(damage && (procVictim & (PROC_FLAG_STRUCK_MELEE|PROC_FLAG_STRUCK_RANGED|PROC_FLAG_STRUCK_SPELL)))
-        procVictim |= (PROC_FLAG_TAKE_DAMAGE|PROC_FLAG_TOUCH);
-
-    // Not much to do if no flags are set.
+    // not assign for spell proc triggered spell to prevent infinity (or unexpacted 2-3 times) melee damage spell proc call with melee damage effect
+    // That is the question though if it's fully correct
+    if (isTriggeredSpell)
+        return;
+     // Not much to do if no flags are set.
     if (procAttacker)
-    {
-        ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcAuraTypes,attType, procSpell, damage);
-    }
-
+        ProcDamageAndSpellFor(false,pVictim,procAttacker, procExtra,attType, procSpell, damage);
     // Now go on with a victim's events'n'auras
     // Not much to do if no flags are set or there is no victim
     if(pVictim && pVictim->isAlive() && procVictim)
-    {
-        pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcAuraTypes,attType,procSpell, damage);
-    }
+        pVictim->ProcDamageAndSpellFor(true,this,procVictim, procExtra,attType,procSpell, damage);
 }
 
+/*
 void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell)
 {
     if(!pVictim)
@@ -3847,8 +4615,8 @@
     if(procAttacker != PROC_FLAG_NONE || procVictim != PROC_FLAG_NONE)
         ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, spellCasted, isTriggeredSpell, attType);
 }
-
-void Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag)
+*/
+void Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx)
 {
     switch(dummySpell->Id )
     {
@@ -3882,10 +4650,11 @@
         // Combustion
         case 11129:
         {
-            CastSpell(this, 28682, true, NULL, triggredByAura);
-            if (!(procFlag & PROC_FLAG_CRIT_SPELL))         //no crit
+            if (triggredByAura->m_procCharges == triggredByAura->GetSpellProto()->procCharges) // For 1 cast
+                CastSpell(this, 28682, true, NULL, triggredByAura);
+            if (!(procEx & PROC_FLAG_EX_CRITICAL_HIT))      //no crit
                 triggredByAura->m_procCharges += 1;         //-> reincrease procCharge count since it was decreased before
-            else if (triggredByAura->m_procCharges == 0)    //no more charges left and crit
+            else if (triggredByAura->m_procCharges == 1)    // last charges left and crit
                 RemoveAurasDueToSpell(28682);               //-> remove Combustion auras
             return;
         }
@@ -4020,6 +4789,41 @@
             return;
         }
 
+		// Windfury weapon
+        case 33757:
+        case 33756:
+        case 33755:
+        case 33754:
+        case 33727:
+        {
+            // never proc from another windfury attack or the AP bonus will stack and we will get really huge criticals
+            if ( !procSpell || ( procSpell->Id != 25504 && procSpell->Id != 33750 ) ){
+                // give us temporary AP bonus
+
+                if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(25504) )
+                    return;
+                
+                HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(dummySpell->EffectBasePoints[0]+1), true);
+
+                int32 EffectBasePoints0 = CalculateDamage(BASE_ATTACK);
+              
+                CastCustomSpell(pVictim,25504,&EffectBasePoints0,NULL,NULL,true,NULL,triggredByAura);            
+                // cooldown
+                ((Player*)this)->AddSpellCooldown(25504,0,time(NULL) + 3);            
+
+                if (haveOffhandWeapon())
+                {
+                    int32 EffectBasePoints0 = CalculateDamage(OFF_ATTACK);
+                    CastCustomSpell(pVictim,33750,&EffectBasePoints0,NULL,NULL,true,NULL,triggredByAura);  
+                    // cooldown
+                    ((Player*)this)->AddSpellCooldown(33750,0,time(NULL) + 3);
+                }
+
+                // remove it
+                HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(dummySpell->EffectBasePoints[0]+1), false);
+            }
+        }
+
         default: break;
     }
 
@@ -4033,6 +4837,30 @@
                 return;
             }
             break;
+        case SPELLFAMILY_PALADIN:
+            // Seal of Righteousness - melee proc dummy
+            if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggredByAura->GetEffIndex()==0)
+            {
+                if(GetTypeId() == TYPEID_PLAYER)
+                {
+                  int32 damageBasePoints;
+                  float speed = 2.0f;
+                  Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+                  if(item) speed = item->GetProto()->Delay/1000.0f;
+                  if(item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON) 
+                      damageBasePoints=1.20f*(triggredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f) + 1;// two hand weapon
+                  else                                            
+                      damageBasePoints=0.85f*(triggredByAura->GetModifier()->m_amount * 1.2f * 1.03f * speed/100.0f) - 1;// one hand weapon/no weapon
+                  damageBasePoints +=0.03f * (m_weaponDamage[0][0]+m_weaponDamage[0][1])/2;
+                  // TODO remove hack by using normal bonus calc
+                  CalcDamageInfo damageInfo;
+                  CalculateDamage(DAMAGE_SHIELD, pVictim, damageBasePoints, &damageInfo, BASE_ATTACK, dummySpell->Id);
+                  DealDamage(&damageInfo, true);
+//                  CastCustomSpell(pVictim,25742,&damag,NULL,NULL,true,NULL, triggredByAura);
+                }
+                return;
+            }
+        break;
         default:
             break;
     }
@@ -4111,7 +4939,7 @@
         }
     }
 }
-
+/*
 void Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags)
 {
     SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
@@ -4348,7 +5176,7 @@
                     ((Player*)this)->AddSpellCooldown(31616,0,time(NULL) + 5);
                     ((Player*)this)->AddSpellCooldown(39301,0,time(NULL) + 5);
                 }
-            }*/
+            }
             return;
         }
         case 2127:
@@ -4460,7 +5288,515 @@
     else if(pVictim && pVictim->isAlive())
         CastSpell(pVictim,trigger_spell_id,true,NULL,triggeredByAura);
 }
+*/
 
+void Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx)
+{
+	// Get triggered aura spell info
+    SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto();
+    // Get trigger spell id
+    uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
+    
+	// Try handle uncnown trigger spells
+	if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
+    switch (auraSpellInfo->SpellFamilyName)
+    {
+     
+     //=====================================================================
+     // Generic class
+     // ====================================================================
+     // .....
+     // .....
+     //=====================================================================
+     case SPELLFAMILY_GENERIC:
+//     if (auraSpellInfo->Id==34082)      // Advantaged State (DND)
+//          trigger_spell_id = ???;
+     if (auraSpellInfo->Id==23780)        // Aegis of Preservation
+          trigger_spell_id = 23781;
+//     else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==37030) // Chaotic Temperament ()
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==41248) // Consuming Strikes
+//          trigger_spell_id = 41249;
+//     else if (auraSpellInfo->Id==41054) // Copy Weapon
+//          trigger_spell_id = 41055;
+//     else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==5301)  // Defensive State (DND)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==13358) // Defensive State (DND)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==16092) // Defensive State (DND)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==40329) // Demo Shout Sensor
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==33896) // Desperate Defense
+//          trigger_spell_id = 33898;                       // ?? possibly this
+//     else if (auraSpellInfo->Id==18943) // Double Attack
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==19194) // Double Attack
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==19817) // Double Attack
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==19818) // Double Attack
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==22835) // Drunken Rage
+//          trigger_spell_id = 14822;
+ /*
+     else if (auraSpellInfo->SpellIconID==191) // Elemental Response
+     {
+         switch (triggeredByAura->GetSpellProto()->Id && triggeredByAura->GetSpellProto()->AttributesEx==0)
+         {
+         case 34191:
+         case 34329:
+         case 34524:
+         case 34582:
+         case 36733:break;
+         default:
+             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",triggeredByAura->GetSpellProto()->Id);
+             return;
+         }
+         //This generic aura self-triggers a different spell for each school of magic that lands on the wearer:
+         switch (procSpell->School)
+         {
+          case SPELL_SCHOOL_FIRE:   trigger_spell_id = 34192;break;//Fire:     34192
+          case SPELL_SCHOOL_FROST:  trigger_spell_id = 34193;break;//Frost:    34193
+          case SPELL_SCHOOL_ARCANE: trigger_spell_id = 34194;break;//Arcane:   34194
+          case SPELL_SCHOOL_NATURE: trigger_spell_id = 34195;break;//Nature:   34195
+          case SPELL_SCHOOL_SHADOW: trigger_spell_id = 34196;break;//Shadow:   34196
+          case SPELL_SCHOOL_HOLY:   trigger_spell_id = 34197;break;//Holy:     34197
+          case SPELL_SCHOOL_NORMAL: trigger_spell_id = 34198;break;//Physical: 34198
+          default:
+             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",triggeredByAura->GetSpellProto()->Id);
+             return;
+         }
+     }*/
+//     else if (auraSpellInfo->Id==6542)  // Enraged Defense
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==35321) // Gushing Wound
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==38363) // Gushing Wound
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==39215) // Gushing Wound
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==40250) // Improved Duration
+//          trigger_spell_id = ;
+     else if (auraSpellInfo->Id==27522)// Mana Drain Trigger
+     {
+        // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.
+        if (this && this->isAlive())
+         CastSpell(this,29471,true,NULL,triggeredByAura);
+        if (pVictim && pVictim->isAlive())
+         CastSpell(pVictim,27526,true,NULL,triggeredByAura);
+        return;
+     }
+//     else if (auraSpellInfo->Id==24905)// Moonkin Form (Passive)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==43453) // Rune Ward 
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==7137)  // Shadow Charge (Rank 1)
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==36576) // Shaleskin 
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==34783) // Spell Reflection
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==36096) // Spell Reflection
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==36207) // Steal Weapon
+//          trigger_spell_id = ;
+//     else if (auraSpellInfo->Id==35205) // Vanish
+     break;
+
+      //=====================================================================
+     // Mage
+     // ====================================================================
+     // Blazing Speed (Rank 1,2) trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_MAGE:
+     if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
+     {
+         switch (triggeredByAura->GetSpellProto()->Id)
+         {
+          case 31641:// Blazing Speed (Rank 1)
+          case 31642:// Blazing Speed (Rank 2)
+			 trigger_spell_id = 31643; //CastSpell(this,31643,true,NULL,triggeredByAura);
+             break;
+          default:
+             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id);
+             return;
+         }
+     }
+     break;
+
+     //=====================================================================
+     // Warrior
+     // ====================================================================
+     // 29801 Rampage (Rank 1-3) trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_WARRIOR:
+     if (auraSpellInfo->SpellIconID == 2006 && auraSpellInfo->SpellFamilyFlags==0x100000) //Rampage
+     {
+       switch(auraSpellInfo->Id)
+       {
+         case 29801: trigger_spell_id = 30029; break;       // Rank 1
+         case 30030: trigger_spell_id = 30031; break;       // Rank 2
+         case 30033: trigger_spell_id = 30032; break;       // Rank 3
+         default:
+           sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in Rampage",auraSpellInfo->Id);
+           return;
+       }
+     }
+     break;
+     //=====================================================================
+     // Warlock
+     // ====================================================================
+     // Pet Mana Regen        trigger = 18350
+     // Pet Resistance        trigger = 18350
+     // Pyroclasm             trigger = 18350 (possible 1 effect need to add not standart proc in add aura)
+     // Drain Soul (Rank 1-5) trigger = 0 ?? (chance = 0? but = 100 then Improved Drain Soul enabled)
+     //=====================================================================
+     case SPELLFAMILY_WARLOCK:
+//     if (triggeredByAura->GetSpellProto()->SpellIconID == 37375) // Pet Mana Regen
+//         trigger_spell_id = ????;break;
+//     if (triggeredByAura->GetSpellProto()->SpellIconID == 37386) // Pet Resistance
+//         trigger_spell_id = ????;
+     if (auraSpellInfo->SpellIconID == 1137) // Pyroclasm
+     {
+       if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL)
+         return;
+       // Calculate spell tick count for spells
+       uint32 tick = 1; // Default tick = 1
+       if (procSpell->SpellFamilyFlags&0x0000000000000040LL) tick = 15; // Hellfire have 15 tick
+       if (procSpell->SpellFamilyFlags&0x0000000000000020LL) tick = 4;  // Rain of Fire have 4 tick
+       // Calculate chance = baseChance/tick
+       float chance = 0;
+       switch (auraSpellInfo->Id)
+       {
+           case 18096:chance = 13.0f/tick;break;
+           case 18073:chance = 26.0f/tick;break;
+       }
+       // Roll chance
+       if (roll_chance_f(chance))
+         CastSpell(pVictim, 18093, true, NULL, triggeredByAura);
+       return;
+     }
+     else if (auraSpellInfo->SpellFamilyFlags&0x0000000000004000LL) // Drain Soul
+     {
+         Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+         for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
+         {
+           if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
+           {
+              int32 impDrainSoulBasePoints0 = (*i)->GetSpellProto()->EffectBasePoints[2] * GetMaxPower(POWER_MANA) / 100;
+              CastCustomSpell(this, 18371, &impDrainSoulBasePoints0, NULL, NULL, true, NULL, triggeredByAura);
+           }
+         }
+         return;
+     }
+     break;
+
+     //=====================================================================
+     // Priest
+     // ====================================================================
+     // Greater Heal Refund         trigger = 18350
+     // Improved Shadowfiend        trigger = 18350
+     // Blessed Recovery (Rank 1-3) trigger = 18350
+     // Shadowguard (1-7)           trigger = 28376
+     //=====================================================================
+     case SPELLFAMILY_PRIEST:
+     if (auraSpellInfo->Id==37594)  //Greater Heal Refund
+          trigger_spell_id = 37595;
+//   else if (triggeredByAura->GetSpellProto()->Id==37570)//Improved Shadowfiend
+//         trigger_spell_id = ???;                
+     else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958) // Shadowguard
+     {
+       switch(triggeredByAura->GetSpellProto()->Id)
+       {
+         case 18137: trigger_spell_id = 28377; break;       // Rank 1
+         case 19308: trigger_spell_id = 28378; break;       // Rank 2
+         case 19309: trigger_spell_id = 28379; break;       // Rank 3
+         case 19310: trigger_spell_id = 28380; break;       // Rank 4
+         case 19311: trigger_spell_id = 28381; break;       // Rank 5
+         case 19312: trigger_spell_id = 28382; break;       // Rank 6
+         case 25477: trigger_spell_id = 28385; break;       // Rank 7
+         default:
+           sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id);
+           return;
+       }
+     }
+     else if (auraSpellInfo->SpellIconID == 1875)  //Blessed Recovery
+     {
+       uint32 EffectId = 0;
+       switch (triggeredByAura->GetSpellProto()->Id)
+       {
+         case 27811: EffectId = 27813; break;
+         case 27815: EffectId = 27817; break;
+         case 27816: EffectId = 27818; break;
+         default:
+           sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id);
+           return;
+       }
+       int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100;
+       int32 BRHealBasePoints0 = heal_amount/3-1;
+       CastCustomSpell(this, EffectId, &BRHealBasePoints0, NULL, NULL, true, NULL, triggeredByAura);
+       return;
+     }
+     break;
+
+     //=====================================================================
+     // Druid
+     // ====================================================================
+     // Druid Forms Trinket  trigger = 18350
+     // Entangling Roots     trigger = 30023
+     // Leader of the Pack   trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_DRUID:
+     if (auraSpellInfo->Id==37336)// Druid Forms Trinket
+     {
+        switch(m_form)
+        {
+            case 0:              trigger_spell_id = 37344;break;
+            case FORM_CAT:       trigger_spell_id = 37341;break;
+            case FORM_BEAR:
+            case FORM_DIREBEAR:  trigger_spell_id = 37340;break;
+            case FORM_TREE:      trigger_spell_id = 37342;break;
+            case FORM_MOONKIN:   trigger_spell_id = 37343;break;
+            default:
+                return;
+        }
+     }
+//   else if (auraSpellInfo->Id==40363)// Entangling Roots ()
+//         trigger_spell_id = ????;
+     else if (triggeredByAura->GetSpellProto()->Id==24932)// Leader of the Pack ()
+         trigger_spell_id = 17007;
+     break;
+
+     //=====================================================================
+     // Hunter
+     // ====================================================================
+     // Increased Pet Attack Power  trigger = 18350
+     // Pet Healing                 trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_HUNTER:
+//   if (auraSpellInfo->Id==38297) // Increased Pet Attack Power 
+//         trigger_spell_id = ????;break;
+     if (auraSpellInfo->Id==37496) // Pet Healing 
+         trigger_spell_id = 37501;
+     break;
+
+     //=====================================================================
+     // Paladin
+     // ====================================================================
+     // Blessed Life                   trigger = 31934
+     // Healing Discount               trigger = 18350
+     // Illumination (Rank 1-5)        trigger = 18350 (for HolyShock possibly use SPELL_AURA_OVERRIDE_CLASS_SCRIPTS)
+     // Judgement of Light (Rank 1-5)  trigger = 5373
+     // Judgement of Wisdom (Rank 1-4) trigger = 1826
+     // Lightning Capacitor            trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_PALADIN:
+//     if (auraSpellInfo->SpellIconID == 2137) // Blessed Life
+//     {
+//       switch (triggeredByAura->GetSpellProto()->Id)
+//       {
+//        case 31828:// Blessed Life (Rank 1)
+//        case 31829:// Blessed Life (Rank 2)
+//        case 31830:// Blessed Life (Rank 3)
+//             need change damage
+//             break;
+//        default:
+//             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life",triggeredByAura->GetSpellProto()->Id);
+//             return;
+//       }
+//     }
+     if (auraSpellInfo->Id==37705) // Healing Discount
+     {
+        CastSpell(this,37706,true,NULL,triggeredByAura);
+        return;
+     }
+/*     else if ((auraSpellInfo->SpellFamilyFlags&0x0000000000080000) &&
+                 auraSpellInfo->SpellIconID==299)// Judgement of Light
+     {
+       switch (triggeredByAura->GetSpellProto()->Id)
+       {
+        case 20185:trigger_spell_id = 20267;break;// Judgement of Light (Rank 1)
+        case 20344:trigger_spell_id = 20341;break;// Judgement of Light (Rank 2)
+        case 20345:trigger_spell_id = 20342;break;// Judgement of Light (Rank 3)
+        case 20346:trigger_spell_id = 20343;break;// Judgement of Light (Rank 4)
+        case 27162:trigger_spell_id = 27163;break;// Judgement of Light (Rank 5)
+        default:
+             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Judgement of Light",triggeredByAura->GetSpellProto()->Id);
+             return;
+       }
+       pVictim->CastSpell(pVictim,trigger_spell_id,true,NULL,triggeredByAura);
+       return;
+     }
+     else if ((auraSpellInfo->SpellFamilyFlags&0x0000000000080000) &&
+               auraSpellInfo->SpellIconID==206) // Judgement of Wisdom
+     {
+       switch (triggeredByAura->GetSpellProto()->Id)
+       {
+        case 20186:trigger_spell_id = 20268;break;// Judgement of Wisdom (Rank 1)
+        case 20354:trigger_spell_id = 20352;break;// Judgement of Wisdom (Rank 2)
+        case 20355:trigger_spell_id = 20353;break;// Judgement of Wisdom (Rank 3)
+        case 27164:trigger_spell_id = 27165;break;// Judgement of Wisdom (Rank 4)
+        default:
+             sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Judgement of Wisdom",triggeredByAura->GetSpellProto()->Id);
+             return;
+       }
+       pVictim->CastSpell(pVictim,trigger_spell_id,true,NULL,triggeredByAura);
+       return;
+     }*/
+     if (auraSpellInfo->SpellIconID==241 && trigger_spell_id==18350) //Illumination
+     {
+         if(!procSpell)
+			 return;
+
+          SpellEntry const *originalSpell = procSpell;
+          // in case HShock procspell is triggered spell but we need mana cost of original casted spell
+          if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN && procSpell->SpellFamilyFlags == 0x00200000)
+          {
+            uint32 originalSpellId = 0;
+            switch(procSpell->Id)
+            {
+             case 25914: originalSpellId = 20473; break;
+             case 25913: originalSpellId = 20929; break;
+             case 25903: originalSpellId = 20930; break;
+             case 27175: originalSpellId = 27174; break;
+             case 33074: originalSpellId = 33072; break;
+             default:
+                sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id);
+                return;
+            }
+            SpellEntry const *HSSpell= sSpellStore.LookupEntry(originalSpellId);
+            if(!HSSpell)
+            {
+                sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but used in HShock",originalSpellId);
+                return;
+            }
+            originalSpell = HSSpell;
+           }
+           // percent stored in effect 1 (class scripts) base points
+           int32 percent = auraSpellInfo->EffectBasePoints[1]+1;
+           // BasePoints = val -1 not required (EffectBaseDice==0)
+           int32 ILManaSpellBasePoints0 = originalSpell->manaCost*percent/100;
+           CastCustomSpell(this, 20272, &ILManaSpellBasePoints0, NULL, NULL, true, NULL, triggeredByAura);
+           return;
+     }
+     else if (auraSpellInfo->Id==37657) // Lightning Capacitor
+     {
+            if(!pVictim || !pVictim->isAlive())
+                return;
+            // stacking
+            CastSpell(this, 37658, true, NULL, triggeredByAura);
+            // counting
+            uint32 count = 0;
+            AuraList const& dummyAura = GetAurasByType(SPELL_AURA_DUMMY);
+            for(AuraList::const_iterator itr = dummyAura.begin(); itr != dummyAura.end(); ++itr)
+                if((*itr)->GetId()==37658)
+                    ++count;
+            // release at 3 aura in stack
+            if(count >2)
+            {
+                RemoveAurasDueToSpell(37658);
+                CastSpell(pVictim, 37661, true, NULL, triggeredByAura);
+            }
+            return;
+     }
+     break;
+     //=====================================================================
+     // Shaman
+     //====================================================================
+     // Lightning Shield             trigger = 18350
+     // Mana Surge                   trigger = 18350
+     // Nature's Guardian (Rank 1-5) trigger = 18350
+     //=====================================================================
+     case SPELLFAMILY_SHAMAN:
+     //Lightning Shield (overwrite non existing triggered spell call in spell.dbc
+     if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37)
+     {
+       switch(triggeredByAura->GetSpellProto()->Id)
+       {
+        case   324: trigger_spell_id = 26364; break;           // Rank 1
+        case   325: trigger_spell_id = 26365; break;           // Rank 2
+        case   905: trigger_spell_id = 26366; break;           // Rank 3
+        case   945: trigger_spell_id = 26367; break;           // Rank 4
+        case  8134: trigger_spell_id = 26369; break;           // Rank 5
+        case 10431: trigger_spell_id = 26370; break;           // Rank 6
+        case 10432: trigger_spell_id = 26363; break;           // Rank 7
+        case 25469: trigger_spell_id = 26371; break;           // Rank 8
+        case 25472: trigger_spell_id = 26372; break;           // Rank 9
+        default:
+            sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id);
+            return;
+       }
+     }
+     else if (auraSpellInfo->Id ==  23572) // Mana Surge (Shaman T1 bonus)
+     {
+         if(!procSpell)
+             return;
+         int32 manaSurgeSpellBasePoints0 = procSpell->manaCost * 35/100;
+         CastCustomSpell(this, 23571, &manaSurgeSpellBasePoints0, NULL, NULL, true, NULL, triggeredByAura);
+         return;
+     }
+     else if (auraSpellInfo->SpellIconID == 2013) //Nature's Guardian
+     {
+         int32 heal = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100 - 1;
+         CastCustomSpell(this, 31616, &heal, 0, 0, true, NULL, triggeredByAura);
+        //        if (pVictim && pVictim->isAlive())
+        //            CastSpell(pVictim, 39301, true, NULL, triggredByAura);
+         return;
+     }
+     break;
+
+     // default
+     default:
+      break;
+    }
+
+    // All ok. Check current trigger spell
+    if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
+	{
+        // Not cast unknown spell
+        // sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex());
+        return;
+	}
+
+    // Costum basepoints/target for exist spell
+    // dummy basepoints or other customs
+    switch(trigger_spell_id)
+    {
+        case 30824: // Shamanistic Rage triggered spell
+        {
+            int32 SRBasePoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100) -1;
+            CastCustomSpell(this, 30824, &SRBasePoints0, NULL, NULL, true, NULL, triggeredByAura);
+            return;
+        }
+		case  20233: // Improved Lay on Hands (cast on target)
+		{
+             if(pVictim && pVictim->isAlive())
+                CastSpell(pVictim,trigger_spell_id,true,NULL,triggeredByAura);
+             return;
+		}
+    }
+
+    // TODO need add more effective target/caster select 
+    // default case
+    if(IsPositiveSpell(trigger_spell_id) && !(procFlags & PROC_FLAG_SUCCESSFUL_HEAL))
+        CastSpell(this,trigger_spell_id,true,NULL,triggeredByAura);
+    else if(pVictim && pVictim->isAlive())
+        CastSpell(pVictim,trigger_spell_id,true,NULL,triggeredByAura);
+}
+
 void Unit::setPowerType(Powers new_powertype)
 {
     uint32 tem_bytes_0 = GetUInt32Value(UNIT_FIELD_BYTES_0);
@@ -5013,9 +6349,6 @@
     if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
         return pdamage;
 
-    if(pVictim->IsImmunedToSpellDamage(spellProto))
-        return 0;
-
     uint32 creatureTypeMask = GetCreatureTypeMask();
 
     // Damage Done
@@ -5395,6 +6728,23 @@
     return false;
 }
 
+bool Unit::IsImmunedToSchoolDamage(SpellSchools School) const
+{
+    //If m_immuneToDamage type contain magic, IMMUNE damage.
+    SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
+    for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
+        if(itr->type & uint32(1<<School))
+            return true;
+
+    //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<<School))
+            return true;
+
+    return false;
+}
+
 bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) const
 {
     if (!spellInfo)
@@ -7171,15 +8521,27 @@
 };
 
 typedef std::list< ProcTriggeredData > ProcTriggeredList;
-
-void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage )
+typedef std::list< uint32> RemoveSpellList;
+// Trigger auras is SPELL_AURA_DUMMY, SPELL_AURA_PROC_TRIGGER_SPELL, SPELL_AURA_PROC_TRIGGER_DAMAGE
+// and procFlags!=0
+static inline bool isTriggerAura(uint8 aur)
 {
-    for(AuraTypeSet::const_iterator aur = procAuraTypes.begin(); aur != procAuraTypes.end(); ++aur)
+ if (aur == SPELL_AURA_DUMMY ||
+     aur == SPELL_AURA_PROC_TRIGGER_SPELL ||
+     aur == SPELL_AURA_PROC_TRIGGER_DAMAGE ||
+     aur == SPELL_AURA_MOD_STUN||
+     aur == SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS) 
+        return true;
+ return false;
+}
+void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage )
+{
+    for (uint8 aur = 1; aur<TOTAL_AURAS;aur++)
     {
         // List of spells (effects) that proceed. Spell prototype and aura-specific value (damage for TRIGGER_DAMAGE)
         ProcTriggeredList procTriggered;
-
-        AuraList const& auras = GetAurasByType(*aur);
+        RemoveSpellList removedSpells;
+        AuraList const& auras = GetAurasByType(AuraType(aur));
         for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
         {
             next = i; next++;
@@ -7187,25 +8549,14 @@
             SpellEntry const *spellProto = (*i)->GetSpellProto();
             if(!spellProto)
                 continue;
-
             SpellProcEventEntry const *spellProcEvent = objmgr.GetSpellProcEvent(spellProto->Id);
-            if(!spellProcEvent)
-            {
-                // used to prevent spam in log about same non-handled spells
-                static std::set<uint32> nonHandledSpellProcSet;
-
-                if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())
-                {
-                    sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));
-                    nonHandledSpellProcSet.insert(spellProto->Id);
-                }
-
-                // spell.dbc use totally different flags, that only can create problems if used.
+            if (spellProto->procFlags==0 && spellProcEvent && spellProcEvent->procFlags==0)
                 continue;
-            }
-
+            // If not trigger and spellProcEvent==NULL - skip
+            if (!isTriggerAura(aur) && spellProcEvent==NULL)
+                  continue;
             // Check spellProcEvent data requirements
-            if(!ObjectMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))
+            if(!ObjectMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, spellProto->procFlags, procSpell,procFlag,procExtra))
                 continue;
 
             // Check if current equipment allows aura to proc
@@ -7232,27 +8583,26 @@
                         continue;
                 }
             }
-
+            // Get chance from spell
             float chance = (float)spellProto->procChance;
-
-            if(Player* modOwner = GetSpellModOwner())
-                modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
-
-            if(!isVictim && spellProcEvent->ppmRate != 0)
+            // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance;
+            if(spellProcEvent && spellProcEvent->customChance) 
+                chance = spellProcEvent->customChance;
+            // If PPM exist calculate chance from PPM
+            if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0)
             {
                 uint32 WeaponSpeed = GetAttackTime(attType);
                 chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
             }
-
+            // Apply chance modifer aura
+            if(Player* modOwner = GetSpellModOwner())
+                modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
+ 
             if(roll_chance_f(chance))
             {
-                if((*i)->m_procCharges > 0)
-                    (*i)->m_procCharges -= 1;
-
                 uint32 i_spell_eff = (*i)->GetEffIndex();
-
                 int32 i_spell_param;
-                switch(*aur)
+                switch(aur)
                 {
                     case SPELL_AURA_PROC_TRIGGER_SPELL: i_spell_param = procFlag;    break;
                     case SPELL_AURA_DUMMY:              i_spell_param = i_spell_eff; break;
@@ -7284,57 +8634,104 @@
 
                 if(!found)
                 {
-                    sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",*aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second);
+                    sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second);
                     sLog.outError("It can be deleted one from early proccesed auras:");
                     for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2)
-                        sLog.outError("     Spell aura %u (id:%u effect:%u)",*aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second);
+                        sLog.outError("     Spell aura %u (id:%u effect:%u)",aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second);
                     sLog.outError("     <end of list>");
                     continue;
                 }
             }
+            SpellProcEventEntry const *spellProcEvent = objmgr.GetSpellProcEvent(i->spellInfo->Id);
+            if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->Cooldown && ((Player *)this)->HasSpellCooldown(i->spellInfo->Id))
+                   continue;
 
-            switch(*aur)
+            switch(aur)
             {
                 case SPELL_AURA_PROC_TRIGGER_SPELL:
                 {
+                    // TODO: adaptate more for costum requirements (not listed in procEx) and fix
+                    // Warning! damage dealing after call ProcDamageAndSpellFor
+                    switch (i->spellInfo->Id)
+                    {
+                      case 28845:// Cheat Death - When your health drops below 20% ....
+                       if (!(GetHealth()-damage<GetMaxHealth()/5 && GetHealth()>GetMaxHealth()/5))
+                         continue;
+                       break;
+                       case 31255:// Deadly Swiftness (Rank 1) - ... whenever you deal damage to a target who is below 20% health.
+                       if (pTarget->GetHealth()>pTarget->GetMaxHealth()/5)
+                          continue;
+                       break;
+                       case 40971:// Bonus Healing - If your target is below $s1% health
+                           if (pTarget->GetHealth()>pTarget->GetMaxHealth()*i->triggeredByAura->GetModifier()->m_amount/100)
+                         continue;
+                       break;
+                       case 37594:// Greater Heal Refund - If your Greater Heal brings the target to full health, you gain $37595s1 mana.
+                           if (pTarget->GetHealth()+damage<pTarget->GetMaxHealth())
+                         continue;
+                       break;
+                       case 30881:// Nature's Guardian (Rank 1-5) Whenever a damaging attack is taken that reduces you below 30% health...
+                       case 30883:
+                       case 30884:
+                       case 30885:
+                       case 30886:
+                       if (!(GetHealth()-damage<GetMaxHealth()*0.3 && GetHealth()>GetMaxHealth()*0.3))
+                         continue;
+                       break;
+                    }
+
                     sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
-                    HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam);
+                    HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell, i->spellParam, procExtra);
                     break;
                 }
                 case SPELL_AURA_PROC_TRIGGER_DAMAGE:
                 {
                     sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", i->spellParam, i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
                     uint32 damage = i->spellParam;
-                    // TODO: remove hack for Seal of Righteousness. That should not be there
-                    if(!isVictim && i->spellInfo->SpellVisual == 7986)
-                        damage = (damage * GetAttackTime(BASE_ATTACK))/60/1000;
                     SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true);
                     break;
                 }
                 case SPELL_AURA_DUMMY:
                 {
                     sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
-                    HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag);
+                    HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag, procExtra);
                     break;
                 }
+                case SPELL_AURA_MOD_STUN:
+                    removedSpells.push_back(i->triggeredByAura->GetId());
+                    break;
+                break;
+                case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS:
+                // Hunter's Mark (1-4 Rangs)
+                // For - increasing the ranged attack power of all attackers against by an additional ${$m2/10} each time they are struck by a ranged attack, up to a maximum of ${$m2*4}
+                if (i->spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (i->spellInfo->SpellFamilyFlags&0x0000000000000400LL))
+                {
+                    uint32 basevalue = i->triggeredByAura->GetBasePoints()+1;
+                    i->triggeredByAura->GetModifier()->m_amount+=basevalue/10;
+                    if (i->triggeredByAura->GetModifier()->m_amount>basevalue*4)
+                        i->triggeredByAura->GetModifier()->m_amount = basevalue*4;
+                }
                 default:
                 {
                     // nothing do, just charges counter
                     break;
                 }
             }
-        }
+            if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->Cooldown)
+                ((Player *)this)->AddSpellCooldown(i->spellInfo->Id, 0, time(NULL)+spellProcEvent->Cooldown);
 
-        // Safely remove auras with zero charges
-        for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
-        {
-            next = i; ++next;
-            if((*i)->m_procCharges == 0)
+            // Remove charge
+            if(i->triggeredByAura && i->triggeredByAura->m_procCharges > 0)
             {
-                RemoveAurasDueToSpell((*i)->GetId());
-                next = auras.begin();
+              i->triggeredByAura->m_procCharges -=1;
+              if (i->triggeredByAura->m_procCharges==0) 
+                  removedSpells.push_back(i->triggeredByAura->GetId());
             }
         }
+
+        // Remove auras from removedAuras
+        for(RemoveSpellList::const_iterator i = removedSpells.begin(); i != removedSpells.end();i++)
+            RemoveAurasDueToSpell(*i);
     }
 }
 
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 4842)
+++ src/game/Unit.h	(working copy)
@@ -56,6 +56,15 @@
 // Horde Racial Passives
 #define SPELL_HORDE_PASSIVE_NATURE_RESISTANCE 20551*/
 
+enum SpellInturruptFlags
+{
+    INTURRUPTFLAG_FLAG_MOVEMENT = 0x01,
+    INTURRUPTFLAG_FLAG_DAMAGE = 0x02,
+    INTURRUPTFLAG_FLAG_INTURRUPT = 0x04,
+    INTURRUPTFLAG_FLAG_AUTOATTACK = 0x08,
+    INTURRUPTFLAG_FLAG_TURNING = 0x10
+};
+
 enum SpellChannelInterruptFlags
 {
     CHANNEL_FLAG_DAMAGE      = 0x0002,
@@ -355,7 +364,8 @@
     DOT                     = 2,
     HEAL                    = 3,
     NODAMAGE                = 4,                            // used also in case when damage applied to health but not applied to spell channelInterruptFlags/etc
-    SELF_DAMAGE             = 5
+    SELF_DAMAGE             = 5,
+    DAMAGE_SHIELD           = 6
 };
 
 enum UnitVisibility
@@ -405,41 +415,59 @@
 
 enum ProcFlags
 {
-    PROC_FLAG_NONE               = 0x00000000,              // None
-    PROC_FLAG_HIT_MELEE          = 0x00000001,              // On melee hit
-    PROC_FLAG_STRUCK_MELEE       = 0x00000002,              // On being struck melee
-    PROC_FLAG_KILL_XP_GIVER      = 0x00000004,              // On kill target giving XP or honor
-    PROC_FLAG_SPECIAL_DROP       = 0x00000008,              //
-    PROC_FLAG_DODGE              = 0x00000010,              // On dodge melee attack
-    PROC_FLAG_PARRY              = 0x00000020,              // On parry melee attack
-    PROC_FLAG_BLOCK              = 0x00000040,              // On block attack
-    PROC_FLAG_TOUCH              = 0x00000080,              // On being touched (for bombs, probably?)
-    PROC_FLAG_TARGET_LOW_HEALTH  = 0x00000100,              // On deal damage to enemy with 20% or less health
-    PROC_FLAG_LOW_HEALTH         = 0x00000200,              // On health dropped below 20%
-    PROC_FLAG_STRUCK_RANGED      = 0x00000400,              // On being struck ranged
-    PROC_FLAG_HIT_SPECIAL        = 0x00000800,              // (!)Removed, may be reassigned in future
-    PROC_FLAG_CRIT_MELEE         = 0x00001000,              // On crit melee
-    PROC_FLAG_STRUCK_CRIT_MELEE  = 0x00002000,              // On being critically struck in melee
-    PROC_FLAG_CAST_SPELL         = 0x00004000,              // On cast spell (and broken Aspect of Hawk)
-    PROC_FLAG_TAKE_DAMAGE        = 0x00008000,              // On take damage
-    PROC_FLAG_CRIT_SPELL         = 0x00010000,              // On crit spell
-    PROC_FLAG_HIT_SPELL          = 0x00020000,              // On hit spell
-    PROC_FLAG_STRUCK_CRIT_SPELL  = 0x00040000,              // On being critically struck by a spell
-    PROC_FLAG_HIT_RANGED         = 0x00080000,              // On getting ranged hit
-    PROC_FLAG_STRUCK_SPELL       = 0x00100000,              // On being struck by a spell
-    PROC_FLAG_TRAP               = 0x00200000,              // On trap activation (?)
-    PROC_FLAG_CRIT_RANGED        = 0x00400000,              // On getting ranged crit
-    PROC_FLAG_STRUCK_CRIT_RANGED = 0x00800000,              // On being critically struck by a ranged attack
-    PROC_FLAG_RESIST_SPELL       = 0x01000000,              // On resist enemy spell
-    PROC_FLAG_TARGET_RESISTS     = 0x02000000,              // On enemy resisted spell
-    PROC_FLAG_TARGET_DODGE_OR_PARRY= 0x04000000,            // On enemy dodges/parries
-    PROC_FLAG_HEAL               = 0x08000000,              // On heal
-    PROC_FLAG_CRIT_HEAL          = 0x10000000,              // On critical healing effect
-    PROC_FLAG_HEALED             = 0x20000000,              // On healing
-    PROC_FLAG_TARGET_BLOCK       = 0x40000000,              // On enemy blocks
-    PROC_FLAG_MISS               = 0x80000000               // On miss melee attack
+   PROC_FLAG_NONE                         = 0x00000000,
+
+   PROC_FLAG_KILLED                       = 0x00000001, // 00 Killed by agressor
+   PROC_FLAG_KILL_AND_GET_XP              = 0x00000002, // 01 Kill that yields experience or honor
+
+   PROC_FLAG_SUCCESSFUL_MILEE_HIT         = 0x00000004, // 02 Successful melee attack
+   PROC_FLAG_TAKEN_MELEE_HIT              = 0x00000008, // 03 Taken damage from melee strike hit
+
+   PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT   = 0x00000010, // 04 Successful attack by Spell that use melee weapon
+   PROC_FLAG_TAKEN_MELEE_SPELL_HIT        = 0x00000020, // 05 Taken damage by Spell that use melee weapon
+
+   PROC_FLAG_SUCCESSFUL_RANGED_HIT        = 0x00000040, // 06 Successful Ranged attack
+   PROC_FLAG_TAKEN_RANGED_HIT             = 0x00000080, // 07 Taken damage from ranged attack
+
+   PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT  = 0x00000100, // 08 Successful Ranged attack by Spell that use ranged weapon
+   PROC_FLAG_TAKEN_RANGED_SPELL_HIT       = 0x00000200, // 09 Taken damage by Spell that use ranged weapon
+
+   PROC_FLAG_SUCCESSFUL_10                = 0x00000400, // 10 Special flag
+   PROC_FLAG_TAKEN_11                     = 0x00000800, // 11 Special flag
+
+   PROC_FLAG_SUCCESSFUL_12                = 0x00001000, // 12 Successful damage spell hit (spell type???)
+   PROC_FLAG_TAKEN_13                     = 0x00002000, // 13 Taken damage spell hit (spell type???)
+
+   PROC_FLAG_SUCCESSFUL_HEAL              = 0x00004000, // 14 Successful cast healing spell
+   PROC_FLAG_TAKEN_HEAL                   = 0x00008000, // 15 Taken healing spell hit
+
+   PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT = 0x00010000, // 16 Successful damage from harmful spell cast
+   PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT      = 0x00020000, // 17 Taken spell damage
+
+   PROC_FLAG_SUCCESSFUL_PERIODIC_DAMAGE   = 0x00040000, // 18 Successful deal spell periodic damage
+   PROC_FLAG_TAKEN_PERIODIC_DAMAGE        = 0x00080000, // 19 Taken spell periodic damage
+
+   PROC_FLAG_TAKEN_ANY_DAMAGE             = 0x00100000, // 20 Taken any damage
+   PROC_FLAG_ON_TRAP_ACTIVATION           = 0x00200000, // 21 On trap activation 
+
+   PROC_FLAG_TAKEN_OFFHAND_HIT            = 0x00400000, // 22 Taken off-hand melee attacks(not used)
+   PROC_FLAG_SUCCESSFUL_OFFHAND_HIT       = 0x00800000  // 23 Successful off-hand melee attacks
 };
 
+enum ProcFlagsEx
+{
+   PROC_FLAG_EX_NONE                      = 0x00000000,
+   PROC_FLAG_EX_CRITICAL_HIT              = 0x00000001,
+   PROC_FLAG_ON_SPELL_CAST                = 0x00000002,
+   PROC_FLAG_EX_DODGE                     = 0x00000004,
+   PROC_FLAG_EX_PARRY                     = 0x00000008,
+   PROC_FLAG_EX_BLOCK                     = 0x00000010,
+   PROC_FLAG_EX_MISS                      = 0x00000020,
+   PROC_FLAG_EX_FULL_RESISTS              = 0x00000080,
+   PROC_FLAG_EX_ABSORB                    = 0x00000100,
+   PROC_FLAG_EX_HIT_EVADE_TARGET          = 0x00000200
+};
+
 enum AuraState
 {                                                           // (C) used in caster aurastate (T) used in target aura state
     AURA_STATE_DEFENSE                      = 1,            // C 
@@ -600,7 +628,30 @@
     WeaponAttackType attackType;
     MeleeHitOutcome hitOutCome;
 };
+// Test struct for use in Unit::CalculateSpellDamage, Unit::CalculateMeleeDamage
+struct CalcDamageInfo
+{
+    DamageEffectType damagetype;
+    uint32 damage;
+    uint32 cleanDamage;
+    uint32 absorb;
+    uint32 resist;
+    uint32 blocked_amount;
 
+    uint32 procAttacker;
+    uint32 procVictim;
+    uint32 procEx;
+
+    Unit  *target;               // Target for damage
+    uint32 HitInfo;
+    uint32 TargetState;
+    WeaponAttackType attackType; // 
+    MeleeHitOutcome hitOutCome;  // TODO: remove this field
+    SpellSchools damageSchool;
+    uint32 SpellID;
+    uint32 auraname;
+
+};
 struct UnitActionBarEntry
 {
     uint32 Type;
@@ -826,15 +877,24 @@
         void Unmount();
 
         uint16 GetMaxSkillValueForLevel() const { return getLevel()*5; }
+        void DealDamage(CalcDamageInfo *damageInfo, bool durabilityLoss);
         void DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchools damageSchool, SpellEntry const *spellProto, uint32 procFlag, 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 DealDamageBySchool(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, 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);
+//        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 CalculateDamage(DamageEffectType type, Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType = BASE_ATTACK, uint32 spellID = 0, SpellSchools damageSchool = SPELL_SCHOOL_NORMAL, uint32 auraname = 0);
+        void CalculateMeleeDamage(uint32 damage, CalcDamageInfo *damageInfo);
+        void CalculateSpellDamage(uint32 damage, CalcDamageInfo *damageInfo);
+        void CalculateDotDamage(uint32 damage, CalcDamageInfo *damageInfo);
+//        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 procEx, uint32 damage = 0, SpellEntry const *procSpell = NULL, bool isTriggeredSpell = false, WeaponAttackType attType = BASE_ATTACK);
         void HandleEmoteCommand(uint32 anim_id);
         void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool isTriggered = false);
-        uint32 SpellMissChanceCalc(Unit *pVictim) const;
+        uint32 SpellMissChanceCalc(Unit *pVictim, SpellSchools school) const;
+        uint32 SpellResistChanceCalc(Unit *pVictim, SpellSchools school) const;
+
+        uint8  SpellCastResult(Unit *pVictim, SpellEntry const *spell) const;
+
         int32 MeleeMissChanceCalc(const Unit *pVictim) const;
 
         float GetUnitDodgeChance()    const;
@@ -917,7 +977,7 @@
 
         bool isFrozen() const;
 
-        void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage);
+        void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage, uint32 casterLevel);
 
         bool isTargetableForAttack() const;
         virtual bool IsInWater() const;
@@ -928,6 +988,9 @@
         void SendHealSpellOnPlayerPet(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype, bool critical = false);
         void PeriodicAuraLog(Unit *pVictim, SpellEntry const *spellProto, Modifier *mod, uint8 effect_idx);
         void SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell = false, bool useSpellDamage = true);
+        void SendSpellNonMeleeDamageLog(CalcDamageInfo *damageInfo);
+        void SendSpellDotDamageLog(CalcDamageInfo *damageInfo);
+        
         void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0);
         void CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0);
         void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, Aura* triggredByAura = NULL, uint64 originalCaster = 0);
@@ -937,6 +1000,8 @@
         void DeMorph();
 
         void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchools DamageType, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
+        void SendAttackStateUpdate(CalcDamageInfo *damageInfo);
+
         void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchools DamageType,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
 
         void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, bool Run, uint32 Time);
@@ -1034,7 +1099,7 @@
         uint32 m_ShapeShiftForm;
         uint32 m_form;
         int32 m_modHitChance;
-        int32 m_modSpellHitChance;
+        int32 m_modSpellHitChance[MAX_SPELL_SCHOOL];
         int32 m_baseSpellCritChance;
         float m_modResilience;
         float m_threatModifier[MAX_SPELL_SCHOOL];
@@ -1128,6 +1193,7 @@
         virtual bool IsImmunedToSpell(SpellEntry const* spellInfo) const;
                                                             // redefined in Creature
         bool IsImmunedToPhysicalDamage() const;
+        bool IsImmunedToSchoolDamage(SpellSchools School) const;
         bool IsImmunedToSpellDamage(SpellEntry const* spellInfo) const;
         bool IsImmunedToSpellEffect(uint32 effect) const;
 
@@ -1222,9 +1288,9 @@
         void SendAttackStop(Unit* victim);                  // only from AttackStop(Unit*)
         void SendAttackStart(Unit* pVictim);                // only from Unit::AttackStart(Unit*)
 
-        void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage );
-        void HandleDummyAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag);
-        void HandleProcTriggerSpell(Unit *pVictim,uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlags);
+        void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage );
+        void HandleDummyAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx);
+        void HandleProcTriggerSpell(Unit *pVictim,uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx);
 
         uint32 m_state;                                     // Even derived shouldn't modify
         uint32 m_CombatTimer;
Index: src/shared/Database/DBCStructure.h
===================================================================
--- src/shared/Database/DBCStructure.h	(revision 4842)
+++ src/shared/Database/DBCStructure.h	(working copy)
@@ -527,7 +527,10 @@
     uint32      spellFamilyName;                            // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
     uint64      spellFamilyMask;                            // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
     uint32      procFlags;                                  // bitmask for matching proc event
+    uint32      procEx;  
     float       ppmRate;                                    // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
+    float       customChance;
+    uint32      Cooldown;
 };
 
 struct SpellThreatEntry