From 37758b2afa2ca2a9f35e9d89cfaea75121ade98c Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Sat, 10 Jul 2021 09:45:39 -0400 Subject: [PATCH] Implemented SE_HealthTransfer 509 Implemented SE_Health_Transfer 509 'life burn' Consume base2 % of Hit Points to Damage for base % of Hit Points Can be used for heal Act of Valor --- common/spdat.h | 14 ++++++++------ zone/attack.cpp | 9 +++++++-- zone/bonuses.cpp | 7 ++++++- zone/common.h | 1 + zone/mob.cpp | 26 ++++++++++++++++++++++++++ zone/mob.h | 1 + zone/spell_effects.cpp | 19 +++++++++++++++++-- zone/spells.cpp | 2 ++ 8 files changed, 68 insertions(+), 11 deletions(-) diff --git a/common/spdat.h b/common/spdat.h index 0fe8bd3cd..a427349aa 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -62,6 +62,8 @@ #define SPELL_SHAPECHANGE60 1924 #define SPELL_COMMAND_OF_DRUZZIL 3355 #define SPELL_SHAPECHANGE70 6503 +#define SPELL_MANA_BURN 2751 +#define SPELL_LIFE_BURN 2755 // these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed #define SPELL_THE_DAINS_JUSTICE 1476 #define SPELL_MODULATION 1502 @@ -152,7 +154,7 @@ #define SPELL_RESURRECTION_SICKNESS 756 #define SPELL_RESURRECTION_SICKNESS2 5249 #define SPELL_REVIVAL_SICKNESS 13087 -#define SPELL_MANA_BURN 2751 + #define EFFECT_COUNT 12 @@ -849,16 +851,16 @@ typedef enum { //#define SE_Damage_Taken_Position_Amt 506 // //#define SE_Fc_Amplify_Mod 507 // //#define SE_Fc_Amplify_Amt 508 // -//#define SE_Health_Transfer 509 // +#define SE_Health_Transfer 509 // //#define SE_Fc_ResistIncoming 510 // //#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_AC_Avoidance_Max_Percent 515 // -//#define SE_AC_Mitigation_Max_Percent 516 // -//#define SE_Attack_Offense_Max_Percent 517 // -//#define SE_Attack_Accuracy_Max_Percent 518 // +//#define SE_AC_Avoidance_Max_Percent 515 // 515 is before 172 TotalEffect(515) * static_cast(avoidance_ac) * 0.0001 that value is then rounded with a +/- 0.5 +//#define SE_AC_Mitigation_Max_Percent 516 // 516 is after AGI bonus +//#define SE_Attack_Offense_Max_Percent 517 // Requires too much rewrite of code. +#define SE_Attack_Accuracy_Max_Percent 518 // //#define SE_Luck_Amount 519 // //#define SE_Luck_Percent 520 // #define SE_Endurance_Absorb_Pct_Damage 521 // diff --git a/zone/attack.cpp b/zone/attack.cpp index 8b0def2bc..5b87af1ed 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -188,6 +188,11 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod) if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing) accuracy += itembonuses.HitChance; + //518 Increase ATK accuracy by percentage, stackable + auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent; + + accuracy += (accuracy * atkhit_bonus) / 10000; + // 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] + aabonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] + @@ -3333,8 +3338,8 @@ int32 Mob::ReduceAllDamage(int32 damage) } if (spellbonuses.EnduranceAbsorbPercentDamage[0]) { - int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000; - int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000; + int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000; //If hit for 1000, at 10% then lower damage by 100; + int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000; //Reduce endurance by 0.05% per HP loss if (endurance_drain < 1) endurance_drain = 1; diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 2be2bd39c..fef8f23fc 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1487,7 +1487,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) } break; - + case SE_Attack_Accuracy_Max_Percent: + newbon->Attack_Accuracy_Max_Percent += base1; + break; // to do case SE_PetDiscipline: @@ -3261,6 +3263,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne new_bonus->trap_slots = effect_value; break; + case SE_Attack_Accuracy_Max_Percent: + new_bonus->Attack_Accuracy_Max_Percent += effect_value; + break; //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { diff --git a/zone/common.h b/zone/common.h index e1c6b1787..3d9e93e3d 100644 --- a/zone/common.h +++ b/zone/common.h @@ -524,6 +524,7 @@ struct StatBonuses { uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success. uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier uint32 PC_Pet_Flurry; // Percent chance flurry from double attack + int32 Attack_Accuracy_Max_Percent; // Increase ATK accuracy by percent. // AAs int8 Packrat; //weight reduction for items, 1 point = 10% diff --git a/zone/mob.cpp b/zone/mob.cpp index dd1ad6475..1ba1a0221 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3711,6 +3711,32 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id) } } +//Used for effects that should occur after the completion of the spell +void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id) +{ + if (!IsValidSpell(spell_id)) + return; + + /*Apply damage from Lifeburn type effects on caster at end of spell cast. + This allows for the AE spells to function without repeatedly killing caster + Damage or heal portion can be found as regular single use spell effect + */ + if (IsEffectInSpell(spell_id, SE_Health_Transfer)){ + for (int i = 0; i < EFFECT_COUNT; i++) { + + if (spells[spell_id].effectid[i] == SE_Health_Transfer) { + int new_hp = GetMaxHP(); + new_hp -= GetMaxHP() * spells[spell_id].base[i] / 1000; + + if (new_hp > 0) + SetHP(new_hp); + else + Kill(); + } + } + } +} + int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining) { if (!IsValidSpell(spell_id)) diff --git a/zone/mob.h b/zone/mob.h index ea5723fa6..81ded3b3e 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -353,6 +353,7 @@ public: void CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ); void BeamDirectional(uint16 spell_id, int16 resist_adjust); void ConeDirectional(uint16 spell_id, int16 resist_adjust); + void TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id); //Buff void BuffProcess(); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index a64fe854a..0e655026b 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -275,11 +275,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif int32 dmg = effect_value; - if (spell_id == 2751 && caster) //Manaburn + if (spell_id == SPELL_MANA_BURN && caster) //Manaburn { dmg = caster->GetMana()*-3; caster->SetMana(0); - } else if (spell_id == 2755 && caster) //Lifeburn + } else if (spell_id == SPELL_LIFE_BURN && caster) //Lifeburn { dmg = caster->GetHP(); // just your current HP caster->SetHP(dmg / 4); // 2003 patch notes say ~ 1/4 HP. Should this be 1/4 your current HP or do 3/4 max HP dmg? Can it kill you? @@ -303,6 +303,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove break; } + case SE_PercentalHeal: { #ifdef SPELL_EFFECT_SPAM @@ -2860,6 +2861,19 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove } break; } + /*Calc for base1 is found in TryOnSpellFinished() due to needing to account for AOE functionality + since effect can potentially kill caster*/ + case SE_Health_Transfer: { + effect_value = spells[spell_id].base2[i]; + int32 amt = abs(caster->GetMaxHP() * effect_value / 1000); + + if (effect_value < 0) + Damage(caster, amt, spell_id, spell.skill, false, buffslot, false); + else + HealDamage(amt, caster); + break; + } + case SE_PersistentEffect: MakeAura(spell_id); @@ -3107,6 +3121,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove case SE_Duration_HP_Pct: case SE_Duration_Mana_Pct: case SE_Duration_Endurance_Pct: + case SE_Endurance_Absorb_Pct_Damage: { break; } diff --git a/zone/spells.cpp b/zone/spells.cpp index c7029b73d..5e0db7c8a 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1393,6 +1393,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo TrySympatheticProc(target, spell_id); } + TryOnSpellFinished(this, target, spell_id); + TryTwincast(this, target, spell_id); TryTriggerOnCast(spell_id, 0);