All pastes #912778 Raw Edit

Anonymous

public text v1 · immutable
·published 2008-02-21 17:02 UTC
rendered paste body
Index: game/Player.cpp
===================================================================
--- game/Player.cpp	(revision 5262)
+++ game/Player.cpp	(working copy)
@@ -4521,6 +4521,7 @@
         case MELEE_HIT_DODGE:
         case MELEE_HIT_PARRY:
         case MELEE_HIT_BLOCK:
+		case MELEE_HIT_BLOCK_CRIT:
             return;
 
         default:

Index: game/Unit.cpp
===================================================================
--- game/Unit.cpp	(revision 5262)
+++ game/Unit.cpp	(working copy)
@@ -1107,6 +1107,7 @@
             // Classify outcome
             switch (outcome)
             {
+				case MELEE_HIT_BLOCK_CRIT:
                 case MELEE_HIT_CRIT:
                 {
                     uint32 bonusDmg = *damage;
@@ -1137,18 +1138,30 @@
                         StartReactiveTimer( REACTIVE_HUNTER_CRIT );
                     }
 
+					if ( outcome == MELEE_HIT_BLOCK_CRIT )
+					{
+						blocked_amount = uint32(pVictim->GetShieldBlockValue());
+						if (blocked_amount >= *damage)
+						{
+							hitInfo |= HITINFO_SWINGNOHITSOUND;
+							victimState = VICTIMSTATE_BLOCKS;
+							cleanDamage->damage += *damage;     // To Help Calculate Rage
+							*damage = 0;
+						}
+						else
+						{
+																// To Help Calculate Rage
+							cleanDamage->damage += blocked_amount;
+							*damage = *damage - blocked_amount;
+						}
+
+						pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true);
+						pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
+					}
                     break;
                 }
                 case MELEE_HIT_PARRY:
                 {
-                    // this special attack can't be parryed
-                    if ( spellInfo->Attributes & 0x200000 )
-                    {
-                        outcome = MELEE_HIT_NORMAL;
-                        cleanDamage->hitOutCome = MELEE_HIT_NORMAL;
-                        break;
-                    }
-
                     cleanDamage->damage += *damage;         // To Help Calculate Rage
                     *damage = 0;
                     victimState = VICTIMSTATE_PARRY;
@@ -1212,14 +1225,6 @@
                 }
                 case MELEE_HIT_DODGE:
                 {
-                    // this special attack can't be dodged
-                    if ( spellInfo->Attributes & 0x200000 )
-                    {
-                        outcome = MELEE_HIT_NORMAL;
-                        cleanDamage->hitOutCome = MELEE_HIT_NORMAL;
-                        break;
-                    }
-
                     if(pVictim->GetTypeId() == TYPEID_PLAYER)
                         ((Player*)pVictim)->UpdateDefense();
 
@@ -1248,14 +1253,6 @@
                 }
                 case MELEE_HIT_BLOCK:
                 {
-                    // this special attack can't be blocked
-                    if ( spellInfo->Attributes & 0x200000 )
-                    {
-                        outcome = MELEE_HIT_NORMAL;
-                        cleanDamage->hitOutCome = MELEE_HIT_NORMAL;
-                        break;
-                    }
-
                     blocked_amount = uint32(pVictim->GetShieldBlockValue());
                     if (blocked_amount >= *damage)
                     {
@@ -1940,13 +1937,11 @@
 
 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)
 {
-    bool unavoidable = spellCasted && (spellCasted->Attributes & 0x200000);
-
     MeleeHitOutcome outcome;
 
     // If is casted Melee spell, calculate like physical
     if(!spellCasted)
-        outcome = RollMeleeOutcomeAgainst (pVictim, attType);
+        outcome = RollMeleeOutcomeAgainst (pVictim, attType, NULL);
     else
         outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted);
 
@@ -2010,6 +2005,7 @@
 
     switch (outcome)
     {
+		case MELEE_HIT_BLOCK_CRIT:
         case MELEE_HIT_CRIT:
         {
             //*hitInfo = 0xEA;
@@ -2063,11 +2059,35 @@
                 StartReactiveTimer( REACTIVE_HUNTER_CRIT );
             }
 
+            *blocked_amount = pVictim->GetShieldBlockValue();
+
+			if ( outcome == MELEE_HIT_BLOCK_CRIT )
+			{
+				if (pVictim->GetUnitBlockChance())
+					pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD);
+				else
+					pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED);
+
+				//Only set VICTIMSTATE_BLOCK on a full block
+				if (*blocked_amount >= uint32(*damage))
+				{
+					*victimState = VICTIMSTATE_BLOCKS;
+					*blocked_amount = uint32(*damage);
+				}
+
+				if(pVictim->GetTypeId() == TYPEID_PLAYER)
+					((Player*)pVictim)->UpdateDefense();
+
+				pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true);
+				pVictim->StartReactiveTimer( REACTIVE_DEFENSE );
+				break;
+			}
+
             pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);
             break;
         }
         case MELEE_HIT_PARRY:
-            if(attType == RANGED_ATTACK || unavoidable)     //range attack - no parry
+            if(attType == RANGED_ATTACK)     //range attack - no parry
             {
                 outcome = MELEE_HIT_NORMAL;
                 break;
@@ -2140,7 +2160,7 @@
             return;
 
         case MELEE_HIT_DODGE:
-            if(attType == RANGED_ATTACK || unavoidable )    //range attack - no dodge
+            if(attType == RANGED_ATTACK)    //range attack - no dodge
             {
                 outcome = MELEE_HIT_NORMAL;
                 break;
@@ -2172,12 +2192,6 @@
             return;
 
         case MELEE_HIT_BLOCK:
-            if( unavoidable )
-            {
-                outcome = MELEE_HIT_NORMAL;
-                break;
-            }
-
             *blocked_amount = pVictim->GetShieldBlockValue();
 
             if (pVictim->GetUnitBlockChance())
@@ -2474,10 +2488,10 @@
 
     DEBUG_LOG("PHYSICAL OUTCOME: hit %f crit %f miss %u",modHitChance,crit_chance,miss_chance);
 
-    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(modHitChance));
+    return RollMeleeOutcomeAgainst(pVictim, attType, spellInfo, int32(crit_chance * 100 ), miss_chance, int32(modHitChance));
 }
 
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const
+MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo) const
 {
     // This is only wrapper
 
@@ -2494,10 +2508,10 @@
     // Useful if want to specify crit & miss chances for melee, else it could be removed
     DEBUG_LOG("MELEE OUTCOME: hit %f crit %u miss %u", modHitChance,crit_chance,miss_chance);
 
-    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(modHitChance));
+    return RollMeleeOutcomeAgainst(pVictim, attType, spellInfo, int32(crit_chance * 100 ), miss_chance, int32(modHitChance));
 }
 
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 hit_chance) const
+MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo, int32 crit_chance, int32 miss_chance, int32 hit_chance) const
 {
     if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
         return MELEE_HIT_EVADE;
@@ -2560,6 +2574,9 @@
     // stunned target cannot dodge and this is check in GetUnitDodgeChance()
     float dodge = pVictim->GetUnitDodgeChance();
 
+	if ( spellInfo && spellInfo->Attributes & 0x200000 )
+        dodge = 0;
+
     // Reduce dodge chance by attacker expertise rating
     if (GetTypeId() == TYPEID_PLAYER)
         dodge-=((Player*)this)->GetExpertiseDodgeOrParryReduction();
@@ -2573,14 +2590,24 @@
     }
 
     int32   modCrit = 0;
+    // reduce crit chance from Rating for players
+    if (pVictim->GetTypeId()==TYPEID_PLAYER)
+    {
+        if (attType==RANGED_ATTACK)
+            modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING)*100);
+        else
+            modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING)*100);
+    }
 
-    // check if attack comes from behind
+	// check if attack comes from behind
     if (!pVictim->HasInArc(M_PI,this))
     {
-        // ASSUME +10% crit from behind
         DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind.");
-        modCrit += 1000;
     }
+	else if ( spellInfo && (spellInfo->Attributes & 0x200000))
+	{
+        DEBUG_LOG ("RollMeleeOutcomeAgainst: melee spell that cannot be evaded.");
+	}
     else
     {
         // cannot parry or block attacks from behind, but can from forward
@@ -2603,19 +2630,15 @@
             && (roll < (sum += tmp)))
         {
             DEBUG_LOG ("RollMeleeOutcomeAgainst: BLOCK <%d, %d)", sum-tmp, sum);
+			if ( GetTypeId() == TYPEID_PLAYER && spellInfo )
+			{
+				if ( roll_chance_f((crit_chance + skillBonus + modCrit)/100))
+					return MELEE_HIT_BLOCK_CRIT;
+			} 
             return MELEE_HIT_BLOCK;
         }
     }
 
-    // reduce crit chance from Rating for players
-    if (pVictim->GetTypeId()==TYPEID_PLAYER)
-    {
-        if (attType==RANGED_ATTACK)
-            modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING)*100);
-        else
-            modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING)*100);
-    }
-
     // Critical chance
     tmp = crit_chance + skillBonus + modCrit;
 
@@ -2626,7 +2649,10 @@
     }
 
     // Max 40% chance to score a glancing blow against mobs that are higher level (can do only players and pets and not with ranged weapon)
-    if( attType != RANGED_ATTACK && (GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet()) && pVictim->GetTypeId() != TYPEID_PLAYER && getLevel() < pVictim->getLevel() )
+    if( attType != RANGED_ATTACK && !spellInfo &&
+		(GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet()) &&
+		pVictim->GetTypeId() != TYPEID_PLAYER && !((Creature*)pVictim)->isPet() &&
+		getLevel() < pVictim->getLevel() )
     {
         // cap possible value (with bonuses > max skill)
         int32 skill = GetWeaponSkillValue(attType);
@@ -2650,7 +2676,7 @@
     tmp = tmp > tmpmax ? tmpmax : tmp;
     // tmp = mob's level * 5 - player's current defense skill
     tmp = GetMaxSkillValueForLevel() - tmp;
-    if (GetTypeId() != TYPEID_PLAYER && (tmp >= 15))
+    if (GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->isPet() && (tmp >= 15))
     {
         // add 2% chance per lacking skill point, min. is 15%
         tmp = tmp * 200 - 1500;
@@ -4185,11 +4211,17 @@
                 procAttacker = PROC_FLAG_MISS;
             }
             break;
+		case MELEE_HIT_BLOCK_CRIT:
         case MELEE_HIT_CRIT:
             if(spellCasted && attType == BASE_ATTACK)
             {
                 procAttacker |= PROC_FLAG_CRIT_SPELL;
                 procVictim   |= PROC_FLAG_STRUCK_CRIT_SPELL;
+				if ( outcome == MELEE_HIT_BLOCK_CRIT )
+				{
+					procVictim |= PROC_FLAG_BLOCK;
+					procAttacker |= PROC_FLAG_TARGET_BLOCK;
+				}
             }
             else if(attType == BASE_ATTACK || attType == OFF_ATTACK)
             {
Index: game/Unit.h
===================================================================
--- game/Unit.h	(revision 5262)
+++ game/Unit.h	(working copy)
@@ -419,7 +419,7 @@
 enum MeleeHitOutcome
 {
     MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY,
-    MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL
+    MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL, MELEE_HIT_BLOCK_CRIT
 };
 struct CleanDamage
 {
@@ -698,8 +698,8 @@
         float GetWeaponProcChance() const;
         float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;
         MeleeHitOutcome RollPhysicalOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo);
-        MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const;
-        MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 hit_chance) const;
+        MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo) const;
+        MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo, int32 crit_chance, int32 miss_chance, int32 hit_chance) const;
 
         bool isVendor()       const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ); }
         bool isTrainer()      const { return HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER ); }