View Single Post
  #11  
Old 07-12-2010, 02:15 AM
Caryatis
Dragon
 
Join Date: May 2009
Location: Milky Way
Posts: 539
Default

OK think this is pretty solid now, its pretty annoying to test but I tested every possible combination and seems working good. The only minor thing is that if you have a DoT spell that has a DD component, the DD won't be affected by the vulnerability(the DoT will be so I'm not sure how vital it is).

mob.h
Code:
Index: mob.h
===================================================================
--- mob.h	(revision 1597)
+++ mob.h	(working copy)
@@ -87,6 +87,7 @@
 	focusResistRate,
 	focusSpellHateMod,
 	focusTriggerOnCast,
+	focusSpellVulnerability,
 } focusType;
 
 enum {
@@ -778,6 +779,7 @@
 	bool TryDeathSave();
 	void DoBuffWearOffEffect(uint32 index);
 	void TryTriggerOnCast(Mob *target, uint32 spell_id);
+	sint32 GetVulnerability(sint32 damage, Mob *caster, uint32 spell_id, int32 ticsremaining);
 
 	static int32 GetAppearanceValue(EmuAppearance iAppearance);
 	void SendAppearancePacket(int32 type, int32 value, bool WholeZone = true, bool iIgnoreSelf = false, Client *specific_target=NULL);
mob.cpp
Code:
Index: mob.cpp
===================================================================
--- mob.cpp	(revision 1597)
+++ mob.cpp	(working copy)
@@ -3036,4 +3036,88 @@
 			}
 		}
 	}
+}
+
+sint32 Mob::GetVulnerability(sint32 damage, Mob *caster, uint32 spell_id, int32 ticsremaining)
+{
+	// If we increased the datatype on GetBuffSlotFromType, this wouldnt be needed
+	uint32 buff_count = GetMaxTotalSlots();
+	for(int i = 0; i < buff_count; i++) 
+	{
+		if(IsEffectInSpell(buffs[i].spellid, SE_SpellVulnerability))
+		{
+			// For Clients, Pets and Bots that are casting the spell, see if the vulnerability affects their spell.
+			if(!caster->IsNPC())
+			{
+				sint32 focus = caster->CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id);
+				if(focus == 1)
+				{
+					damage += damage * spells[buffs[i].spellid].base[0] / 100;
+					break;
+				}
+			}
+			// If an NPC is casting the spell on a player that has a vulnerability, relaxed restrictions on focus 
+			// so that either the Client is vulnerable to DoTs or DDs of various resists or all.
+			else if (caster->IsNPC())
+			{
+				int npc_resist = 0;
+				int npc_instant = 0;
+				int npc_duration = 0;
+				for(int j = 0; j < EFFECT_COUNT; j++)
+				{
+					switch (spells[buffs[i].spellid].effectid[j]) 
+					{
+					
+					case SE_Blank:
+						break;
+
+					case SE_LimitResist:
+						if(spells[buffs[i].spellid].base[j])
+						{
+							if(spells[spell_id].resisttype == spells[buffs[i].spellid].base[j])
+								npc_resist = 1;
+						}
+						break;
+
+					case SE_LimitInstant:
+						if(!ticsremaining) 
+						{
+							npc_instant = 1;
+							break;
+						}
+
+					case SE_LimitMinDur:
+						if(ticsremaining) 
+						{
+							npc_duration = 1;
+							break;
+						}
+
+						default:{
+						// look pretty
+							break;
+						}	
+					}
+				}
+				// DDs and Dots of all resists 
+				if ((npc_instant) || (npc_duration)) 
+					damage += damage * spells[buffs[i].spellid].base[0] / 100;
+				
+				else if (npc_resist) 
+				{
+					// DDs and Dots restricted by resists
+					if ((npc_instant) || (npc_duration)) 
+					{
+						damage += damage * spells[buffs[i].spellid].base[0] / 100;
+					}
+					// DD and Dots of 1 resist ... these are to maintain compatibility with current spells, not ideal.
+					else if (!npc_instant && !npc_duration)
+					{
+						damage += damage * spells[buffs[i].spellid].base[0] / 100;
+					}
+				}
+			}
+		}
+	}
+	return damage;
 }
\ No newline at end of file
spell effects.cpp
Code:
Index: spell_effects.cpp
===================================================================
--- spell_effects.cpp	(revision 1597)
+++ spell_effects.cpp	(working copy)
@@ -203,8 +203,10 @@
 
 					//handles AAs and what not...
 					if(caster)
+					{
+						dmg = GetVulnerability(dmg, caster, spell_id, 0);
 						dmg = caster->GetActSpellDamage(spell_id, dmg);
-
+					}
 					dmg = -dmg;
 					Damage(caster, dmg, spell_id, spell.skill, false, buffslot, false);
 				}
@@ -2812,6 +2814,7 @@
 			case SE_LimitCastTime:
 			case SE_NoCombatSkills:
 			case SE_TriggerOnCast:
+			case SE_SpellVulnerability:
 			{
 				break;
 			}
@@ -3130,13 +3133,15 @@
 						if(!IsClient())
 							AddToHateList(caster, -effect_value);
 					}
-
+					effect_value = GetVulnerability(effect_value, caster, spell_id, ticsremaining);
 					TryDotCritical(spell_id, caster, effect_value);
 				}
 				effect_value = effect_value * modifier / 100;
 			}
 
 			if(effect_value < 0) {
+				if(caster && !caster->IsClient())
+					effect_value = GetVulnerability(effect_value, caster, spell_id, ticsremaining);
 				effect_value = -effect_value;
 				Damage(caster, effect_value, spell_id, spell.skill, false, i, true);
 			} else if(effect_value > 0) {
@@ -3860,6 +3865,14 @@
 			}
 			break;
 		}
+		case SE_SpellVulnerability:
+		{
+			if(type == focusSpellVulnerability)
+			{
+				value = 1;
+			}
+			break;
+		}
 #if EQDEBUG >= 6
 		//this spits up a lot of garbage when calculating spell focuses
 		//since they have all kinds of extra effects on them.
Reply With Quote