[Spells] Implemented SPA 463 SE_SHIELD_TARGET (#4224)

SPA 463 SE_SHIELD_TARGET

Live description: "Shields your target, taking a percentage of their damage".

Only example spell on live is an NPC who uses it during a raid event "Laurion's Song" expansion. SPA 54492 'Guardian Stance' Described as 100% Melee Shielding

Example of mechanic. Base value = 70. Caster puts buff on target. Each melee hit Buff Target takes 70% less damage, Buff Caster receives 30% of the melee damage.
Added mechanic to cause buff to fade if target or caster are separated by a distance greater than the casting range of the spell. This allows similar mechanics to the /shield ability, without a range removal mechanic it would be too easy to abuse if put on a player spell. *can not confirm live does this currently

Can not be cast on self.
This commit is contained in:
KayenEQ
2024-03-30 13:34:03 -04:00
committed by GitHub
parent cd89926435
commit 9e3bf91374
6 changed files with 101 additions and 5 deletions
+69 -4
View File
@@ -6285,9 +6285,24 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + defender->GetPositionalDmgTakenAmt(this);
if (defender->GetShielderID()) {
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
hit.damage_done -= hit.damage_done * defender->GetShieldTargetMitigation() / 100; //Default shielded takes 50 pct damage
if (defender->GetShielderID() || defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]) {
bool use_shield_ability = true;
//If defender is being shielded by an ability AND has a shield spell effect buff use highest mitigation value.
if ((defender->GetShieldTargetMitigation() && defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]) &&
(defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] >= defender->GetShieldTargetMitigation())){
bool use_shield_ability = false;
}
//use targeted /shield ability values
if (defender->GetShielderID() && use_shield_ability) {
DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill);
hit.damage_done -= hit.damage_done * defender->GetShieldTargetMitigation() / 100; //Default shielded takes 50 pct damage
}
//use spell effect SPA 463 values
else if (defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT]){
DoShieldDamageOnShielderSpellEffect(defender, hit.damage_done, hit.skill);
hit.damage_done -= hit.damage_done * defender->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT] / 100;
}
}
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
@@ -6330,7 +6345,57 @@ void Mob::DoShieldDamageOnShielder(Mob *shield_target, int64 hit_damage_done, EQ
hit_damage_done -= hit_damage_done * mitigation / 100;
shielder->Damage(this, hit_damage_done, SPELL_UNKNOWN, skillInUse, true, -1, false, m_specialattacks);
shielder->CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
}
void Mob::DoShieldDamageOnShielderSpellEffect(Mob* shield_target, int64 hit_damage_done, EQ::skills::SkillType skillInUse)
{
if (!shield_target) {
return;
}
/*
SPA 463 SE_SHIELD_TARGET
Live description: "Shields your target, taking a percentage of their damage".
Only example spell on live is an NPC who uses it during a raid event "Laurion's Song" expansion. SPA 54492 'Guardian Stance' Described as 100% Melee Shielding
Example of mechanic. Base value = 70. Caster puts buff on target. Each melee hit Buff Target takes 70% less damage, Buff Caster receives 30% of the melee damage.
Added mechanic to cause buff to fade if target or caster are seperated by a distance greater than the casting range of the spell. This allows similiar mechanics
to the /shield ability, without a range removal mechanic it would be too easy to abuse if put on a player spell. *can not confirm live does this currently
Can not be cast on self.
*/
if (shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT])
{
if (shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT] >= 0)
{
Mob *shielder = entity_list.GetMob(shield_target->buffs[shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]].casterid);
if (!shielder) {
shield_target->BuffFadeBySlot(shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]);
return;
}
int shield_spell_id = shield_target->buffs[shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]].spellid;
if (!IsValidSpell(shield_spell_id)) {
return;
}
float max_range = spells[shield_spell_id].range;
if (spells[shield_spell_id].aoe_range > max_range) {
max_range = spells[shield_spell_id].aoe_range;
}
max_range += 5.0f; //small buffer in case casted at exactly max range.
if (shield_target->CalculateDistance(shielder->GetX(), shielder->GetY(), shielder->GetZ()) > max_range) {
shield_target->BuffFadeBySlot(shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_BUFFSLOT]);
return;
}
int mitigation = 100 - shield_target->spellbonuses.ShieldTargetSpa[SBIndex::SHIELD_TARGET_MITIGATION_PERCENT];
hit_damage_done -= hit_damage_done * mitigation / 100;
shielder->Damage(this, hit_damage_done, SPELL_UNKNOWN, skillInUse, true, -1, false, m_specialattacks);
}
}
}
void Mob::CommonBreakInvisibleFromCombat()