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

No worries, I'm excited about the work you guys are doing on the Underfoot client and while I have no ability to help with that, at least I can help out this way. Hopefully soon my understanding of the code increases to where your oversight is minimal however atm I bet there is still many ways to fine tune my code(like you did with the triggeroncast).

edit... ok one more fix to this logic as I think its better to negate spells first, originally I was thinking that would only apply to DDs but really there shouldnt be a limit on that.

new AffectMagicalDamage function...
Code:
sint32 Mob::AffectMagicalDamage(sint32 damage, int16 spell_id, const bool iBuffTic, Mob* attacker) 
{
	if(damage <= 0)
	{
		return damage;
	}

	// See if we block the spell outright first
	int slot = GetBuffSlotFromType(SE_NegateAttacks);
	if(slot >= 0 && buffs[slot].magic_rune > 0)
	{
		if(--buffs[slot].melee_rune == 0)
		{
			BuffFadeBySlot(slot);
			UpdateRuneFlags();
		}
		return -6;
	}
	
	// Increase magical damage before runes
	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(!attacker->IsNPC())
			{
				sint32 focus = attacker->CalcFocusEffect(focusSpellVulnerability, buffs[i].spellid, spell_id);
				if(focus == 1)
				{
					damage += damage * spells[buffs[i].spellid].base[0] / 100;
				}
			}
			// 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 (attacker->IsNPC())
			{
				int npc_vulnerable = 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_vulnerable = 1;
						}
						break;

					case SE_LimitInstant:
						if(!iBuffTic) 
						{
							npc_vulnerable = 1;
							break;
						}

					case SE_LimitMinDur:
						if(iBuffTic) 
						{
							npc_vulnerable = 1;
							break;
						}

					default:{
						// look pretty
						}	
					}
				}
				if (npc_vulnerable) 
				{
					damage += damage * spells[buffs[i].spellid].base[0] / 100;
				}
			}
		}
	}
	
	// If this is a DoT, use DoT Shielding...
	if(iBuffTic)
	{
		damage -= (damage * this->itembonuses.DoTShielding / 100);
	}
	// This must be a DD then so lets apply Spell Shielding and all the various runes that can block or negate DD spells.
	else 
	{
		// Reduce damage by the Spell Shielding first so that the runes don't take the raw damage.
		damage -= (damage * this->itembonuses.SpellDamageShield / 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;
				BuffFadeBySlot(slot);
				UpdateRuneFlags();
			}
			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;
			}
		}

		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;
			}
			else
			{
				if(magic_rune_left > 0)
					damage -= magic_rune_left;
				BuffFadeBySlot(slot);
				slot = GetBuffSlotFromType(SE_AbsorbMagicAtt);
				UpdateRuneFlags();
			}
		}
	}
	return damage;
}
Reply With Quote