Jump to content

[9035] Ardent Defender EXPLOIT


Auntie Mangos

Recommended Posts

isn't it problem with insiders repo and fix given by laise http://getmangos.eu/community/viewtopic.php?id=6846&highlight=ardent ?

you can move code triggering "arden defender cooldown spell" under part that is checking if aura is present but it will probably broke up " In addition, attacks which would otherwise kill you" part, it will trigger just once every 2 mins.

Alternative for us is http://dev.trinitycore.org/trinitycore2/changeset/c418e7f83583/ didn't tested dough

Link to comment
Share on other sites

  • 39 years later...

Convert for mangos, ty n0n4m3 for patch. http://bitbucket.org/n0n4m3/

KAPATEJIb i miss that, sry. Test new patch please, work perfect i think. I just correct visual part for this spell. Time to add this spell for mangos source :)

diff --git a/.gitignore b/.gitignore
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 4d1feeb..59c8965 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1857,20 +1857,43 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
                break;
            }
            case SPELLFAMILY_PALADIN:
-            {
-                // Ardent Defender
-                if (spellProto->SpellIconID == 2135)
-                {
-                    // uses 66233 as a cooldown for healing effect
-                    if (!((Player*)pVictim)->HasAura(66233))
-                        preventDeathSpell = (*i)->GetSpellProto();
-
-                    if(pVictim->GetHealth() - RemainingDamage <= pVictim->GetMaxHealth() * 0.7f)
-                        RemainingDamage -= RemainingDamage * currentAbsorb / 100;
-
-                    continue;
-                }
-            }
+                {
+                    // Ardent Defender
+                    if (spellProto->SpellIconID == 2135 && pVictim->GetTypeId() == TYPEID_PLAYER)
+                    {
+                        int32 remainingHealth = pVictim->GetHealth() - RemainingDamage;
+                        uint32 allowedHealth = pVictim->GetMaxHealth() * 0.35f;
+                        // If damage kills us
+                        if (remainingHealth <= 0 && !((Player*)pVictim)->HasSpellCooldown(66235))
+                        {
+                            // Cast healing spell, completely avoid damage
+                            RemainingDamage = 0;
+                            
+                            uint32 defenseSkillValue = pVictim->GetDefenseSkillValue();
+                            // Max heal when defense skill denies critical hits from raid bosses
+                            // Formula: max defense at level + 140 (raiting from gear)
+                            uint32 reqDefForMaxHeal  = pVictim->getLevel() * 5 + 140;
+                            float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal)
+                                ? 1.0f
+                                : float(defenseSkillValue) / float(reqDefForMaxHeal);
+    
+                            int32 healAmount = pVictim->GetMaxHealth() * ((*i)->GetSpellProto()->EffectBasePoints[1] + 1) / 100.0f * pctFromDefense;
+                            pVictim->CastCustomSpell(pVictim, 66235, &healAmount, NULL, NULL, true);
+                            ((Player*)pVictim)->AddSpellCooldown(66235,0,time(NULL) + 120);
+                        }
+                        else if (remainingHealth < allowedHealth)
+                        {
+                            // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
+                            uint32 damageToReduce = (pVictim->GetHealth() < allowedHealth)
+                                ? RemainingDamage
+                                : allowedHealth - remainingHealth;
+                            RemainingDamage -= damageToReduce * currentAbsorb / 100;
+                        }
+                        continue;
+    
+                    }
+                    break;
+                }
            case SPELLFAMILY_PRIEST:
            {
                // Guardian Spirit
@@ -2180,31 +2203,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
                }
                break;
            }
-            // Ardent Defender
-            case SPELLFAMILY_PALADIN:
-            {
-                // Ardent Defender
-                if (preventDeathSpell->SpellIconID == 2135)
-                {
-                    int32 healAmount = preventDeathSpell->EffectBasePoints[1]; // get from dummy aura instead?
-                    int32 defRate = pVictim->GetDefenseSkillValue();
-                    defRate -= (pVictim->getLevel() * 5);
-
-                    // if no defence rating bonus don't absorb
-                    if (!defRate || defRate < 0)
-                        break;
-
-                    int32 heal = int32(defRate * pVictim->GetMaxHealth() * healAmount / 14000) - pVictim->GetHealth();
-                    if(heal > 0)
-                    {
-                        //cast heal
-                        pVictim->CastCustomSpell(pVictim, 66235, &heal, NULL, NULL, true);
-                        pVictim->CastSpell(pVictim, 66233, true);
-                    }
-                    RemainingDamage = 0;
-                }
-                break;
-            }
            // Guardian Spirit
            case SPELLFAMILY_PRIEST:
            {

Link to comment
Share on other sites

i think trinity formula is wrong. when defense is equal to level*5 healing should be 0. max cup is achieved when defense = level*5+140. so it is not scaling from 0 but between level*5 <=> level*5+140.

also cooldown was hacked. there is detached spell that is handling spell cooldown (insider branch code is using it)

my sollution (framework based on TC2, diff taken from insiders repo, for clean mangos apply only "+" lines)

diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index aec0b52..c4378e9 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1857,20 +1857,44 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
                break;
            }
            case SPELLFAMILY_PALADIN:
-            {
-                // Ardent Defender
-                if (spellProto->SpellIconID == 2135)
-                {
-                    // uses 66233 as a cooldown for healing effect
-                    if (!((Player*)pVictim)->HasAura(66233))
-                        preventDeathSpell = (*i)->GetSpellProto();
-
-                    if(pVictim->GetHealth() - RemainingDamage <= pVictim->GetMaxHealth() * 0.7f)
-                        RemainingDamage -= RemainingDamage * currentAbsorb / 100;
-
-                    continue;
-                }
-            }
+                {
+                    // Ardent Defender
+                    if (spellProto->SpellIconID == 2135 && pVictim->GetTypeId() == TYPEID_PLAYER)
+                    {
+                        int32 remainingHealth = pVictim->GetHealth() - RemainingDamage;
+                        uint32 allowedHealth = pVictim->GetMaxHealth() * 0.35f;
+                        // If damage kills us
+                        if (remainingHealth <= 0 && !((Player*)pVictim)->HasAura(66233))
+                        {
+                            // Cast healing spell, completely avoid damage
+                            RemainingDamage = 0;
+                          
+                            uint32 defenseSkillValue = pVictim->GetDefenseSkillValue();
+                            uint32 baseLevelSkillValue = pVictim->getLevel() * 5;
+                            // If player does not achieve even lvl cap of defense return 0%
+                            float pctFromDefense = (defenseSkillValue <= baseLevelSkillValue) ? 0.0f :
+                            // If player overexeceded maxlevelcap+140 return 100%
+                            (((defenseSkillValue - baseLevelSkillValue) >= 140) ? 1.0f : 
+                            // else scale pct
+                            ((float(defenseSkillValue) - float(baseLevelSkillValue)) / 140));
+    
+                            int32 healAmount = pVictim->GetMaxHealth() * (*i)->GetSpellProto()->EffectBasePoints[1] *  pctFromDefense / 100;
+                            pVictim->CastCustomSpell(pVictim, 66235, &healAmount, NULL, NULL, true);
+                            pVictim->CastSpell(pVictim, 66233, true);
+                        }
+                        else if (remainingHealth < allowedHealth)
+                        {
+                            // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
+                            uint32 damageToReduce = (pVictim->GetHealth() < allowedHealth)
+                                ? RemainingDamage
+                                : allowedHealth - remainingHealth;
+                            RemainingDamage -= damageToReduce * currentAbsorb / 100;
+                        }
+                        continue;
+    
+                    }
+                    break;
+                }
            case SPELLFAMILY_PRIEST:
            {
                // Guardian Spirit
@@ -2180,31 +2204,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
                }
                break;
            }
-            // Ardent Defender
-            case SPELLFAMILY_PALADIN:
-            {
-                // Ardent Defender
-                if (preventDeathSpell->SpellIconID == 2135)
-                {
-                    int32 healAmount = preventDeathSpell->EffectBasePoints[1]; // get from dummy aura instead?
-                    int32 defRate = pVictim->GetDefenseSkillValue();
-                    defRate -= (pVictim->getLevel() * 5);
-
-                    // if no defence rating bonus don't absorb
-                    if (!defRate || defRate < 0)
-                        break;
-
-                    int32 heal = int32(defRate * pVictim->GetMaxHealth() * healAmount / 14000) - pVictim->GetHealth();
-                    if(heal > 0)
-                    {
-                        //cast heal
-                        pVictim->CastCustomSpell(pVictim, 66235, &heal, NULL, NULL, true);
-                        pVictim->CastSpell(pVictim, 66233, true);
-                    }
-                    RemainingDamage = 0;
-                }
-                break;
-            }
            // Guardian Spirit
            case SPELLFAMILY_PRIEST:
            {

Link to comment
Share on other sites

  • 1 month later...
               // Ardent Defender
               if (spellProto->SpellIconID == 2135 && pVictim->GetTypeId() == TYPEID_PLAYER)
               {
                   // count HP after this attack
                   int32 remainingHealth = int32(pVictim->GetHealth()) - RemainingDamage;
                   // count how much HP required to turn on absorb effect
                   int32 allowedHealth = int32(pVictim->GetMaxHealth() * 0.35f);
                   // If current processed attack would kill us
                   if (remainingHealth <= 0 && !((Player*)pVictim)->HasAura(66233))
                   {
                       // Cast healing spell, completely avoid damage
                       RemainingDamage = 0;

                       uint32 defenseSkillValue = pVictim->GetDefenseSkillValue();
                       uint32 baseLevelSkillValue = pVictim->getLevel() * 5;
                       // If player does not achieve even lvl cap of defense return 0%
                       float pctFromDefense = (defenseSkillValue <= baseLevelSkillValue) ? 0.0f :
                       // If player overexeceded maxlevelcap+140 return 100%
                       (((defenseSkillValue - baseLevelSkillValue) >= 140) ? 1.0f : 
                       // else scale pct
                       ((float(defenseSkillValue) - float(baseLevelSkillValue)) / 140));

                       int32 healAmount = int32(pVictim->GetMaxHealth() * (*i)->GetSpellProto()->EffectBasePoints[EFFECT_INDEX_1] *  pctFromDefense / 100);
                       pVictim->CastCustomSpell(pVictim, 66235, &healAmount, NULL, NULL, true);
                       pVictim->CastSpell(pVictim, 66233, true);
                   }
                   else if (remainingHealth < allowedHealth)
                   {
                       // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
                       int32 damageToReduce = (int32(pVictim->GetHealth()) < allowedHealth)
                           ? RemainingDamage
                           : allowedHealth - remainingHealth;
                       RemainingDamage -= damageToReduce * currentAbsorb / 100;
                   }
                   continue;

               }

Link to comment
Share on other sites

  • 2 months later...
  • 4 months later...

I use this Code for Ardent Defender and it works very good. In my opinion ready to add in master.

diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 988f822..748c1b8 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2060,6 +2060,26 @@ void Unit::CalculateAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolMask, D
                }
                break;
            }
+            case SPELLFAMILY_PALADIN:
+            {
+                // Ardent Defender
+                if (spellProto->SpellIconID == 2135)
+                {
+                    // Apply absorb only on damage below 35% hp 
+                    int32 absorbableDamage = RemainingDamage + 0.35f * GetMaxHealth() - GetHealth();
+                    if (absorbableDamage > RemainingDamage)
+                        absorbableDamage = RemainingDamage;
+                    if (absorbableDamage > 0)
+                        RemainingDamage -= absorbableDamage * currentAbsorb / 100;
+
+                    // 66233 is cooldown aura
+                    if (!((Player*)this)->HasAura(66233))
+                        preventDeathSpell = (*i)->GetSpellProto();
+
+                    continue;
+                }
+                break;
+           } 
            case SPELLFAMILY_DEATHKNIGHT:
            {
                // Shadow of Death
@@ -2316,6 +2336,33 @@ void Unit::CalculateAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolMask, D
                }
                break;
            }
+            case SPELLFAMILY_PALADIN:
+            {
+                // Ardent Defender
+                if (preventDeathSpell->SpellIconID == 2135)
+                {
+                    // Calculate defense over level * 5
+                    int32 defenseAmount = GetDefenseSkillValue() - getLevel() * 5;
+                    // Proceed if positive value
+                    if (defenseAmount > 0)
+                    {
+                        // Defense cap
+                        if (defenseAmount > 140)
+                            defenseAmount = 140;
+                        // Trigger cooldown aura
+                        CastSpell(this, 66233, true);
+                        // Calculate heal amount
+                        int32 healAmount = preventDeathSpell->CalculateSimpleValue(EFFECT_INDEX_1);
+                        healAmount = defenseAmount * GetMaxHealth() * healAmount / 14000 - GetHealth();
+                        // Heal if positive value
+                        if (healAmount > 0)
+                            CastCustomSpell(this, 66235, &healAmount, NULL, NULL, true);
+                        // Absorb Everything
+                        RemainingDamage = 0;
+                    }
+                }
+                break;
+            }
        }
    }

EDIT: i forgot my Revision: 10410

Breakwater

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use