Thread: Rune Update
View Single Post
  #1  
Old 09-09-2011, 12:29 AM
Caryatis
Dragon
 
Join Date: May 2009
Location: Milky Way
Posts: 539
Default 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.
Reply With Quote