Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 09-09-2011, 12:29 AM
Caryatis
Dragon
 
Join Date: May 2009
Location: Milky Way
Posts: 541
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
  #2  
Old 09-10-2011, 11:15 AM
Tabasco's Avatar
Tabasco
Discordant
 
Join Date: Sep 2009
Posts: 270
Default

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.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 01:43 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3