Implemented SPA 483

Implemented
Fc_Spell_Damage_Pct_IncomingPC	483
- Focus effect that modifies iby percent incoming spell damage on the target.
Base1= min Base2= max. Final percent is random between max and min each time focus is applied from a spell cast.

Note: Written to stack with similar functioning focus SPA 269 SE_FcSpellVulnerability.
This commit is contained in:
KayenEQ
2021-07-14 22:13:39 -04:00
parent 4ada3fccdf
commit a08fa7f2bf
5 changed files with 101 additions and 22 deletions
+3 -3
View File
@@ -638,7 +638,7 @@ typedef enum {
#define SE_FrontalStunResist 293 // implemented[AA] - Reduce chance to be stunned from front. -- live descriptions sounds like this isn't limited to frontal anymore
#define SE_CriticalSpellChance 294 // implemented - increase chance to critical hit and critical damage modifier.
//#define SE_ReduceTimerSpecial 295 // not used
#define SE_FcSpellVulnerability 296 // implemented - increase in incoming spell damage
#define SE_FcSpellVulnerability 296 // implemented - increase in incoming spell damage [base1= min dmg base2= max dmg]
#define SE_FcDamageAmtIncoming 297 // implemented - debuff that adds points damage to spells cast on target (focus effect).
#define SE_ChangeHeight 298 // implemented
#define SE_WakeTheDead 299 // implemented
@@ -825,7 +825,7 @@ typedef enum {
//#define SE_Ff_Value_Max 480 //
//#define SE_Fc_Cast_Spell_On_Land 481 //
//#define SE_Skill_Base_Damage_Mod 482 //
//#define SE_Fc_Spell_Damage_Pct_IncomingPC 483 //
#define SE_Fc_Spell_Damage_Pct_IncomingPC 483 //
//#define SE_Fc_Spell_Damage_Amt_IncomingPC 484 //
//#define SE_Ff_CasterClass 485 //
//#define SE_Ff_Same_Caster 486 //
@@ -856,7 +856,7 @@ typedef enum {
//#define SE_Ff_FocusTimerMin 511 //
//#define SE_Proc_Timer_Modifier 512 //
//#define SE_Mana_Max_Percent 513 //
//#define SE_Endurance_Max_Percent 514 //
//#define SE_Endurance_Max_Percent 514 //
#define SE_AC_Avoidance_Max_Percent 515 // implemented - stackable avoidance modifier
#define SE_AC_Mitigation_Max_Percent 516 // implemented - stackable defense modifier
//#define SE_Attack_Offense_Max_Percent 517 //
+3
View File
@@ -3736,6 +3736,8 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
return 0; //This is calculated as an actual bonus
case SE_FcSpellVulnerability:
return focusSpellVulnerability;
case SE_Fc_Spell_Damage_Pct_IncomingPC:
return focusFcSpellDamagePctIncomingPC;
case SE_BlockNextSpellFocus:
//return focusBlockNextSpell;
return 0; //This is calculated as an actual bonus
@@ -3775,6 +3777,7 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
return focusFcHealAmt;
case SE_FcHealAmtCrit:
return focusFcHealAmtCrit;
}
return 0;
}
+1
View File
@@ -124,6 +124,7 @@ typedef enum { //focus types
focusSpellHateMod,
focusTriggerOnCast,
focusSpellVulnerability,
focusFcSpellDamagePctIncomingPC,
focusTwincast,
focusSympatheticProc,
focusFcDamageAmt,
+67 -15
View File
@@ -3767,28 +3767,40 @@ void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
{
/*
Modifies incoming spell damage by percent, to increase or decrease damage, can be limited to specific resists.
Can be applied through quest function, spell focus or npc_spells_effects table. This function is run on the target of the spell.
*/
if (!IsValidSpell(spell_id))
return 0;
if (!caster)
return 0;
int32 value = 0;
int32 total_mod = 0;
int32 innate_mod = 0;
int32 fc_spell_vulnerability_mod = 0;
int32 fc_spell_damage_pct_incomingPC_mod = 0;
//Apply innate vulnerabilities
//Apply innate vulnerabilities from quest functions and tables
if (Vulnerability_Mod[GetSpellResistType(spell_id)] != 0)
value = Vulnerability_Mod[GetSpellResistType(spell_id)];
innate_mod = Vulnerability_Mod[GetSpellResistType(spell_id)];
else if (Vulnerability_Mod[HIGHEST_RESIST+1] != 0)
value = Vulnerability_Mod[HIGHEST_RESIST+1];
innate_mod = Vulnerability_Mod[HIGHEST_RESIST+1];
//Apply spell derived vulnerabilities
if (spellbonuses.FocusEffects[focusSpellVulnerability]){
//[Apply spell derived vulnerabilities] Step 1: Check this focus effect exists on the mob.
if (spellbonuses.FocusEffects[focusSpellVulnerability]){
int32 tmp_focus = 0;
int tmp_buffslot = -1;
/*
Find all buffs that may contain SPA 296, then find which slot has the highest possible effect. Since the focus can use
a min and max amount value to determine final focus amt. To find the best focus, use only max value if possible. Once the
best is found. Run it again to get the final value randoming between min and max.
*/
int buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++) {
@@ -3808,21 +3820,61 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
tmp_focus = focus;
tmp_buffslot = i;
}
}
}
tmp_focus = caster->CalcFocusEffect(focusSpellVulnerability, buffs[tmp_buffslot].spellid, spell_id);
if (tmp_focus < -99)
tmp_focus = -99;
value += tmp_focus;
fc_spell_vulnerability_mod = caster->CalcFocusEffect(focusSpellVulnerability, buffs[tmp_buffslot].spellid, spell_id);
if (tmp_buffslot >= 0)
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
}
return value;
if (spellbonuses.FocusEffects[focusFcSpellDamagePctIncomingPC]) {
int32 tmp_focus = 0;
int tmp_buffslot = -1;
/*
Find all buffs that may contain SPA 483, then find which slot has the highest possible effect. Since the focus can use
a min and max amount value to determine final focus amt. To find the best focus, use only max value if possible. Once the
best is found. Run it again to get the final value randoming between min and max.
*/
int buff_count = GetMaxTotalSlots();
for (int i = 0; i < buff_count; i++) {
if ((IsValidSpell(buffs[i].spellid) && IsEffectInSpell(buffs[i].spellid, SE_Fc_Spell_Damage_Pct_IncomingPC))) {
int32 focus = caster->CalcFocusEffect(focusFcSpellDamagePctIncomingPC, buffs[i].spellid, spell_id, true);
if (!focus)
continue;
if (tmp_focus && focus > tmp_focus) {
tmp_focus = focus;
tmp_buffslot = i;
}
else if (!tmp_focus) {
tmp_focus = focus;
tmp_buffslot = i;
}
}
}
fc_spell_damage_pct_incomingPC_mod = caster->CalcFocusEffect(focusFcSpellDamagePctIncomingPC, buffs[tmp_buffslot].spellid, spell_id);
if (tmp_buffslot >= 0)
CheckNumHitsRemaining(NumHit::MatchingSpells, tmp_buffslot);
}
total_mod = fc_spell_vulnerability_mod + fc_spell_damage_pct_incomingPC_mod;
//Don't let focus derived mods reduce past 99% mitigation. Quest related can, and for custom functionality if negative will give a healing affect instead of damage.
if (total_mod < -99)
total_mod = -99;
total_mod += innate_mod;
return total_mod;
}
int32 Mob::GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts)
+27 -4
View File
@@ -3060,6 +3060,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_HealRate:
case SE_SkillDamageTaken:
case SE_FcSpellVulnerability:
case SE_Fc_Spell_Damage_Pct_IncomingPC:
case SE_FcTwincast:
case SE_DelayDeath:
case SE_CastOnFadeEffect:
@@ -4769,6 +4770,11 @@ int16 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
if (type == focusSpellVulnerability)
value = base1;
break;
case SE_Fc_Spell_Damage_Pct_IncomingPC:
if (type == focusFcSpellDamagePctIncomingPC)
value = base1;
break;
case SE_BlockNextSpellFocus:
if (type == focusBlockNextSpell) {
@@ -5284,13 +5290,30 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
if (type == focusSpellVulnerability) {
if (best_focus) {
if (focus_spell.base2[i] != 0)
value = focus_spell.base2[i];
value = focus_spell.base2[i]; //max damage
else
value = focus_spell.base[i];
value = focus_spell.base[i]; //min damage
} else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
value = focus_spell.base[i];
value = focus_spell.base[i]; //If no max damage set, then default to min damage
} else {
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]);
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]); //else random for value
}
}
break;
case SE_Fc_Spell_Damage_Pct_IncomingPC:
if (type == focusFcSpellDamagePctIncomingPC) {
if (best_focus) {
if (focus_spell.base2[i] != 0)
value = focus_spell.base2[i]; //max damage
else
value = focus_spell.base[i]; //min damage
}
else if (focus_spell.base2[i] == 0 || focus_spell.base[i] == focus_spell.base2[i]) {
value = focus_spell.base[i]; //If no max damage set, then default to min damage
}
else {
value = zone->random.Int(focus_spell.base[i], focus_spell.base2[i]); //else random for value
}
}
break;