EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   Rune Update (https://www.eqemulator.org/forums/showthread.php?t=34137)

Caryatis 09-09-2011 12:29 AM

Rune Update
 
Although it seems that SE_AbsorbMagicAtt works in the stock source(not sure why Kayen was having trouble with it), the code got pretty sloppy and normal runes were not blocking spells at all.

This update:
- streamlines both the magic and normal runes
- adds a client message for blocked spells
- stops negated spells(SE_NegateAttacks) from healing for 6pts of dmg.
- removes defaulting to true on MitigateMeleeDamage & MitigateSpellDamage when runes are updated
- adds a proper message for Mind Over Matter AA
- fixes hit limited buffs dropping 1 hit too early

Code:

Index: zone/attack.cpp
===================================================================
--- zone/attack.cpp        (revision 2007)
+++ zone/attack.cpp        (working copy)
@@ -2958,172 +2958,168 @@
 
 sint32 Mob::ReduceDamage(sint32 damage)
 {
-        if(damage <= 0)
-                return damage;
+        if(damage <= 0) { return damage; }
 
+        // Block it first
        int slot = GetBuffSlotFromType(SE_NegateAttacks);
        if(slot >= 0) {
                if(CheckHitsRemaining(slot, false, true))
                        return -6;
        }
-
-        slot = GetBuffSlotFromType(SE_MitigateMeleeDamage);
-        if(slot >= 0)
-        {
-                int damage_to_reduce = damage * GetPartialMeleeRuneReduction(buffs[slot].spellid) / 100;
-                if(damage_to_reduce > buffs[slot].melee_rune)
-                {
-                        mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
-                                " damage remaining, fading buff.", damage_to_reduce, buffs[slot].melee_rune);
-                        damage -= damage_to_reduce;
-                        if(!TryFadeEffect(slot))
-                                BuffFadeBySlot(slot);
-                        UpdateRuneFlags();
+        // Mitigate it
+        if(HasPartialMeleeRune()) {
+                slot = GetBuffSlotFromType(SE_MitigateMeleeDamage);
+                while(slot >= 0) {
+                        int damage_to_reduce = damage * GetPartialMeleeRuneReduction(buffs[slot].spellid) / 100;
+                        if(damage_to_reduce >= buffs[slot].melee_rune) {
+                                damage -= damage_to_reduce;
+                                if(!TryFadeEffect(slot))
+                                        BuffFadeBySlot(slot);
+                                UpdateRuneFlags();
+                                slot = GetBuffSlotFromType(SE_MitigateMeleeDamage);
+                        }
+                        else {
+                                buffs[slot].melee_rune -= damage_to_reduce;
+                                damage -= damage_to_reduce;
+                                break;
+                        }
                }
-                else
-                {
-                        mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
-                                " damage remaining.", damage_to_reduce, buffs[slot].melee_rune);
-                        buffs[slot].melee_rune = (buffs[slot].melee_rune - damage_to_reduce);
-                        damage -= damage_to_reduce;
-                }
        }
-
-        if(damage < 1)
-        {
-                return -6;
-        }
-
-        slot = GetBuffSlotFromType(SE_Rune);
-        while(slot >= 0)
-        {
-                int16 melee_rune_left = buffs[slot].melee_rune;
-                if(melee_rune_left >= damage)
-                {
-                        melee_rune_left -= damage;
-                        damage = -6;
-                        buffs[slot].melee_rune = melee_rune_left;
-                        break;
+        // Normal Rune
+        if(HasRune()) {
+                slot = GetBuffSlotFromType(SE_Rune);
+                while(slot >= 0) {
+                        if(damage >= buffs[slot].melee_rune) {
+                                damage -= buffs[slot].melee_rune;
+                                if(!TryFadeEffect(slot))
+                                        BuffFadeBySlot(slot);
+                                UpdateRuneFlags();
+                                slot = GetBuffSlotFromType(SE_Rune);
+                        }
+                        else {
+                                buffs[slot].melee_rune -= damage;
+                                return -6;
+                        }
                }
-                else
-                {
-                        if(melee_rune_left > 0)
-                                damage -= melee_rune_left;
-                        if(!TryFadeEffect(slot))
-                                BuffFadeBySlot(slot);
-                        slot = GetBuffSlotFromType(SE_Rune);
-                        UpdateRuneFlags();
-                }
        }
-       
-        if(damage < 1)
-        {
-                return -6;
-        }
-       
+        // Mana Absorb Damage
        slot = GetBuffSlotFromType(SE_ManaAbsorbPercentDamage);
        if(slot >= 0) {
                for (int i = 0; i < EFFECT_COUNT; i++) {
                        if (spells[buffs[slot].spellid].effectid[i] == SE_ManaAbsorbPercentDamage) {
-                                if(GetMana() > damage * spells[buffs[slot].spellid].base[i] / 100) {
-                                        damage -= (damage * spells[buffs[slot].spellid].base[i] / 100);
-                                        SetMana(GetMana() - damage);
+                                uint32 absorbed_dmg = damage * spells[buffs[slot].spellid].base[i] / 100;
+                                if(GetMana() >= absorbed_dmg) {
+                                        damage -= absorbed_dmg;
+                                        SetMana(GetMana() - absorbed_dmg);
+                                        Message_StringID(MT_Spells, MANA_ABSORB, absorbed_dmg);
                                }
                        }
                }
        }
+        if(damage < 1) { return -6; }
 
-        return(damage);
+        return damage;
 }
       
-sint32 Mob::AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic, Mob* attacker)
+sint32 Mob::AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic)
 {
-        if(damage <= 0)
-        {
-                return damage;
-        }
+        if(damage <= 0) { return damage; }
 
        // See if we block the spell outright first
        int slot = GetBuffSlotFromType(SE_NegateAttacks);
        if(slot >= 0) {
                if(CheckHitsRemaining(slot, false, true))
-                        return -6;
+                        damage = 0;
        }
       
        // If this is a DoT, use DoT Shielding...
-        if(iBuffTic)
-        {
+        if(iBuffTic && damage > 0) {
                damage -= (damage * this->itembonuses.DoTShielding / 100);
        }
        // This must be a DD then so lets apply Spell Shielding and runes.
-        else
+        else if(damage > 0)
        {
                // Reduce damage by the Spell Shielding first so that the runes don't take the raw damage.
                damage -= (damage * this->itembonuses.SpellShield / 100);
-       
-                // Do runes now.
-                slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
-                if(slot >= 0)
-                {
-                        int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
-                        if(damage_to_reduce > buffs[slot].magic_rune)
-                        {
-                                mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
-                                        " damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
-                                damage -= damage_to_reduce;
-                                if(!TryFadeEffect(slot))
-                                        BuffFadeBySlot(slot);
-                                UpdateRuneFlags();
+               
+                // Partial Spell Rune first(arbitrary order that seems most beneficial)
+                if(HasPartialSpellRune() && damage > 0) {
+                        slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
+                        while(slot >= 0) {
+                                int damage_to_reduce = damage * GetPartialMagicRuneReduction(buffs[slot].spellid) / 100;
+                                if(damage_to_reduce >= buffs[slot].magic_rune) {
+                                        damage -= damage_to_reduce;
+                                        if(!TryFadeEffect(slot))
+                                                BuffFadeBySlot(slot);
+                                        UpdateRuneFlags();
+                                        slot = GetBuffSlotFromType(SE_MitigateSpellDamage);
+                                }
+                                else {
+                                        buffs[slot].magic_rune -= damage_to_reduce;
+                                        damage -= damage_to_reduce;
+                                        break;
+                                }
                        }
-                        else
-                        {
-                                mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
-                                        " damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
-                                buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
-                                damage -= damage_to_reduce;
+                }
+                // Spell Rune Next
+                if(HasSpellRune() && damage > 0) {
+                        slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
+                        while(slot >= 0) {
+                                if(damage >= buffs[slot].magic_rune) {
+                                        damage -= buffs[slot].magic_rune;
+                                        if(!TryFadeEffect(slot))
+                                                BuffFadeBySlot(slot);
+                                        UpdateRuneFlags();
+                                        slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
+                                }
+                                else {
+                                        buffs[slot].magic_rune -= damage;
+                                        damage = 0;
+                                        break;
+                                }
                        }
                }
-
-                if(damage < 1)
-                {
-                        return -6;
-                }
-
-
-                slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
-                while(slot >= 0)
-                {
-                        int16 magic_rune_left = buffs[slot].magic_rune;
-                        if(magic_rune_left >= damage)
-                        {
-                                magic_rune_left -= damage;
-                                damage = 0;
-                                buffs[slot].magic_rune = magic_rune_left;
-                                break;
+                // Normal
+                if(HasRune() && damage > 0) {
+                        slot = GetBuffSlotFromType(SE_Rune);
+                        while(slot >= 0) {
+                                if(damage >= buffs[slot].melee_rune) {
+                                        damage -= buffs[slot].melee_rune;
+                                        if(!TryFadeEffect(slot))
+                                                BuffFadeBySlot(slot);
+                                        UpdateRuneFlags();
+                                        slot = GetBuffSlotFromType(SE_Rune);
+                                }
+                                else {
+                                        buffs[slot].melee_rune -= damage;
+                                        damage = 0;
+                                        break;
+                                }
                        }
-                        else
-                        {
-                                if(magic_rune_left > 0)
-                                        damage -= magic_rune_left;
-                                if(!TryFadeEffect(slot))
-                                        BuffFadeBySlot(slot);
-                                slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
-                                UpdateRuneFlags();
-                        }
                }
-               
+                // Mana Absorb Damage(Mind Over Matter)
                slot = GetBuffSlotFromType(SE_ManaAbsorbPercentDamage);
-                if(slot >= 0) {
-                        for (int k = 0; k < EFFECT_COUNT; k++) {
-                                if (spells[buffs[slot].spellid].effectid[k] == SE_ManaAbsorbPercentDamage) {
-                                        if(GetMana() > damage * spells[buffs[slot].spellid].base[k] / 100) {
-                                                damage -= (damage * spells[buffs[slot].spellid].base[k] / 100);
-                                                SetMana(GetMana() - damage);
+                if(slot >= 0 && damage > 0) {
+                        for (int i = 0; i < EFFECT_COUNT; i++) {
+                                if (spells[buffs[slot].spellid].effectid[i] == SE_ManaAbsorbPercentDamage) {
+                                        uint32 absorbed_dmg = damage * spells[buffs[slot].spellid].base[i] / 100;
+                                        if(GetMana() >= absorbed_dmg) {
+                                                damage -= absorbed_dmg;
+                                                SetMana(GetMana() - absorbed_dmg);
+                                                Message_StringID(MT_Spells, MANA_ABSORB, absorbed_dmg);
+                                               
+                                                if(damage == 0) { return damage; }
                                        }
                                }
                        }
                }
        }
+        // -6 doesnt return "YOUR Magical Skin Absorbs..." for spells hitting runes
+        if(damage < 1) {
+                damage = 0;
+                Message_StringID(MT_Spells, SPELL_ABSORB, spells[spell_id].name);
+        }
+
        return damage;
 }
 
@@ -3283,41 +3279,22 @@
                        mlog(COMBAT__HITS, "Melee Damage reduced to %d", damage);
                } else {
                        sint32 origdmg = damage;
-                        damage = AffectMagicalDamage(damage, spell_id, iBuffTic, attacker);
-                        mlog(COMBAT__HITS, "Melee Damage reduced to %d", damage);
+                        damage = AffectMagicalDamage(damage, spell_id, iBuffTic);
+                        mlog(COMBAT__HITS, "Spell Damage reduced to %d", damage);
                        if (origdmg != damage && attacker && attacker->IsClient()) {
                                if(attacker->CastToClient()->GetFilter(FILTER_DAMAGESHIELD) != FilterHide)
                                        attacker->Message(15, "The Spellshield absorbed %d of %d points of damage", origdmg - damage, origdmg);
                        }
                }
               
-
-        if(IsClient() && CastToClient()->sneaking){
-                CastToClient()->sneaking = false;
-                SendAppearancePacket(AT_Sneak, 0);
-        }
-        if(attacker && attacker->IsClient() && attacker->CastToClient()->sneaking){
-                attacker->CastToClient()->sneaking = false;
-                attacker->SendAppearancePacket(AT_Sneak, 0);
-        }
-                //final damage has been determined.
-               
-                /*
-                //check for death conditions
-                if(IsClient()) {
-                        if((GetHP()) <= -10) {
-                                Death(attacker, damage, spell_id, skill_used);
-                                return;
-                        }
-                } else {
-                        if (damage >= GetHP()) {
-                                //killed...
-                                SetHP(-100);
-                                Death(attacker, damage, spell_id, skill_used);
-                                return;
-                        }
+                if(IsClient() && CastToClient()->sneaking){
+                        CastToClient()->sneaking = false;
+                        SendAppearancePacket(AT_Sneak, 0);
                }
-                */
+                if(attacker && attacker->IsClient() && attacker->CastToClient()->sneaking){
+                        attacker->CastToClient()->sneaking = false;
+                        attacker->SendAppearancePacket(AT_Sneak, 0);
+                }
               
                SetHP(GetHP() - damage);
 
Index: zone/mob.h
===================================================================
--- zone/mob.h        (revision 2007)
+++ zone/mob.h        (working copy)
@@ -941,7 +941,7 @@
        inline int16        GetErrorNumber() const {return adverrorinfo;}
 
        sint32        ReduceDamage(sint32 damage);
-        sint32  AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic, Mob* attacker);
+        sint32  AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic);
 
        virtual void DoSpecialAttackDamage(Mob *who, SkillType skill, sint32 max_damage, sint32 min_damage = 1, sint32 hate_override = -1);
    bool Flurry();
Index: zone/spell_effects.cpp
===================================================================
--- zone/spell_effects.cpp        (revision 2007)
+++ zone/spell_effects.cpp        (working copy)
@@ -1157,7 +1157,7 @@
                                snprintf(effect_desc, _EDLEN, "Melee Absorb Rune: %+i", effect_value);
 #endif
                                buffs[buffslot].melee_rune = effect_value;       
-                                        SetHasRune(true);
+                                SetHasRune(true);
                                break;
                        }
 
@@ -1166,10 +1166,8 @@
 #ifdef SPELL_EFFECT_SPAM
                                snprintf(effect_desc, _EDLEN, "Spell Absorb Rune: %+i", effect_value);
 #endif
-                                if(effect_value > 0) {
                                buffs[buffslot].magic_rune = effect_value;       
-                                        SetHasSpellRune(true);
-                                }
+                                SetHasSpellRune(true);
                                break;
                        }
 
@@ -4271,7 +4269,7 @@
                                continue;
                        // Double check to make sure the saved spell matches the buff in that slot
                        if (m_spellHitsLeft[d] == buffs[d].spellid) {
-                                if(buffs[d].numhits > 1) {
+                                if(buffs[d].numhits > 0) {
                                        buffs[d].numhits--;
                                        return true;
                                }
@@ -4284,7 +4282,7 @@
        }
        // This is where hit limited DS and other effects are processed
        else if(spells[buffs[buff_slot].spellid].numhits > 0 || negate)  {
-                if(buffs[buff_slot].numhits > 1) {
+                if(buffs[buff_slot].numhits > 0) {
                        buffs[buff_slot].numhits--;
                        return true;
                }
Index: zone/spells.cpp
===================================================================
--- zone/spells.cpp        (revision 2007)
+++ zone/spells.cpp        (working copy)
@@ -5188,42 +5188,16 @@
 }
 void Mob::UpdateRuneFlags()
 {
-        bool Has_SE_Rune = false, Has_SE_AbsorbMagicAtt = false, Has_SE_MitigateMeleeDamage = true, Has_SE_MitigateSpellDamage = true;
+        bool Has_SE_Rune = false, Has_SE_AbsorbMagicAtt = false, Has_SE_MitigateMeleeDamage = false, Has_SE_MitigateSpellDamage = false;
        uint32 buff_count = GetMaxTotalSlots();
-        for (unsigned int i = 0; i < buff_count; ++i)
+        for (int b = 0; b < buff_count; b++)
        {
-                if (buffs[i].spellid != SPELL_UNKNOWN)
-                {
-                        for (int j = 0; j < EFFECT_COUNT; ++j)
-                        {
-                                switch(spells[buffs[i].spellid].effectid[j])
-                                {
-                                        case SE_Rune:
-                                        {
-                                                Has_SE_Rune = true;
-                                                break;
-                                        }
-                                        case SE_AbsorbMagicAtt:
-                                        {
-                                                Has_SE_AbsorbMagicAtt = true;
-                                                break;
-                                        }
-                                        case SE_MitigateMeleeDamage:
-                                        {
-                                                Has_SE_MitigateMeleeDamage = true;
-                                                break;
-                                        }
-                                        case SE_MitigateSpellDamage:
-                                        {
-                                                Has_SE_MitigateSpellDamage = true;
-                                                break;
-                                        }
-
-                                        default:
-                                                break;
-                                }                                       
-                        }
-                }
+                if (buffs[b].spellid == SPELL_UNKNOWN) { continue; }
+               
+                if(IsEffectInSpell(buffs[b].spellid, SE_Rune))                                        { Has_SE_Rune = true; }
+                if(IsEffectInSpell(buffs[b].spellid, SE_MitigateMeleeDamage))        { Has_SE_MitigateMeleeDamage = true; }
+                if(IsEffectInSpell(buffs[b].spellid, SE_AbsorbMagicAtt))                { Has_SE_AbsorbMagicAtt = true; }
+                if(IsEffectInSpell(buffs[b].spellid, SE_MitigateSpellDamage))        { Has_SE_MitigateSpellDamage = true; }
        }
 
        SetHasRune(Has_SE_Rune);
Index: zone/StringIDs.h
===================================================================
--- zone/StringIDs.h        (revision 2007)
+++ zone/StringIDs.h        (working copy)
@@ -205,12 +205,13 @@
 #define TRADESKILL_MISSING_ITEM                3455        //You are missing a %1.
 #define TRADESKILL_MISSING_COMPONENTS        3456        //Sorry, but you don't have everything you need for this recipe in your general inventory.
 #define TRADESKILL_LEARN_RECIPE                3457        //You have learned the recipe %1!
-#define CORPSEDRAG_LIMIT                4061        //You are already dragging as much as you can!
-#define CORPSEDRAG_ALREADY                4062        //You are already dragging %1.
+#define MANA_ABSORB                                        3569        //Your mana has absorbed %1 points of damage.
+#define CORPSEDRAG_LIMIT                        4061        //You are already dragging as much as you can!
+#define CORPSEDRAG_ALREADY                        4062        //You are already dragging %1.
 #define CORPSEDRAG_SOMEONE_ELSE                4063        //Someone else is dragging %1.
-#define CORPSEDRAG_BEGIN                4064        //You begin to drag %1.
-#define CORPSEDRAG_STOPALL                4065        //You stop dragging the corpses.
-#define CORPSEDRAG_STOP                        4066        //You stop dragging the corpse.
+#define CORPSEDRAG_BEGIN                        4064        //You begin to drag %1.
+#define CORPSEDRAG_STOPALL                        4065        //You stop dragging the corpses.
+#define CORPSEDRAG_STOP                                4066        //You stop dragging the corpse.
 #define WHOALL_NO_RESULTS                        5029        //There are no players in EverQuest that match those who filters.
 #define PETITION_NO_DELETE                        5053        //You do not have a petition in the queue.
 #define PETITION_DELETED                        5054        //Your petition was successfully deleted.
@@ -261,6 +262,7 @@
 #define SHAKE_OFF_STUN                                9077
 #define STRIKETHROUGH_STRING                9078        //You strike through your opponent's defenses!
 #define SPELL_REFLECT                                9082        //%1's spell has been reflected by %2.
+#define SPELL_ABSORB                                9083        //YOUR magical skin absorbs %1 spell.
 #define NEW_SPELLS_AVAIL                        9149        //You have new spells available to you.  Check the merchants near your guild master.
 #define FACE_ACCEPTED                                12028        //Facial features accepted.
 #define SPELL_LEVEL_TO_LOW                        12048        //You will have to achieve level %1 before you can scribe the %2.


Tabasco 09-10-2011 11:15 AM

This looks a lot cleaner than what was there. Thanks for digging into it.

I initially got the, "Your mana has absorbed %1 points of damage." message without the actual damage listed, but I can see the correct amount of mana being taken.
It looks like the Message_StringID() call is matching a template that doesn't apply parameters to the message.
I dump that to a stringstream and then pass it viewdmg.str().c_str() and the number displays.

Edit: I had some existing spell shield items that were muddying results.
Nice work, and thanks again for digging into this.


All times are GMT -4. The time now is 10:26 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.