From 140bf3130904c7ad62f75d53edf217d752ac202e Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 14 Jul 2021 15:35:37 -0400 Subject: [PATCH] Implemented SPA 465,477,478 Implemented SE_PC_Pet_AE_Rampage 465 Chance for pet to AE rampage with a damage modifier SE_Hatelist_To_Top_Index 477 Chance to be put on top of RAMPAGE list SE_Hatelist_To_Tail_Index 478 Chance to be put on bottom of RAMPAGE list --- common/spdat.h | 6 ++--- zone/attack.cpp | 13 +++++++--- zone/bonuses.cpp | 31 ++++++++++++++++++++++++ zone/common.h | 1 + zone/mob.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++ zone/mob.h | 2 ++ zone/mob_ai.cpp | 21 ++++++++++------ zone/spell_effects.cpp | 13 +++++++++- 8 files changed, 128 insertions(+), 14 deletions(-) diff --git a/common/spdat.h b/common/spdat.h index 187cadcf4..ec4dca3fa 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -807,7 +807,7 @@ typedef enum { #define SE_FcDamageAmt2 462 // implemented - Increase spell damage by flat amount (SE_Fc_Damage_Amt2) //#define SE_Shield_Target 463 // #define SE_PC_Pet_Rampage 464 // implemented - Base1 % chance to do rampage for base2 % of damage each melee round -//#define SE_PC_Pet_AE_Rampage 465 // Would assume as above but need to confirm. +#define SE_PC_Pet_AE_Rampage 465 // implemented - Base1 % chance to do AE rampage for base2 % of damage each melee round #define SE_PC_Pet_Flurry_Chance 466 // implemented - Base1 % chance to do flurry from double attack hit. #define SE_DS_Mitigation_Amount 467 // implemented - Modify incoming damage shield damage by a flat amount #define SE_DS_Mitigation_Percentage 468 // implemented - Modify incoming damage shield damage by percentage @@ -819,8 +819,8 @@ typedef enum { #define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner #define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click. //#define SE_Weapon_Stance 476 // -//#define SE_Hatelist_To_Top_Index 477 // -//#define SE_Hatelist_To_Tail_Index 478 // +#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list +#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list //#define SE_Ff_Value_Min 479 // //#define SE_Ff_Value_Max 480 // //#define SE_Fc_Cast_Spell_On_Land 481 // diff --git a/zone/attack.cpp b/zone/attack.cpp index a49131365..d09271c55 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -5254,15 +5254,22 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac if (mod > 0) spec_mod = mod; if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { - int spell = spellbonuses.PC_Pet_Rampage[1] + itembonuses.PC_Pet_Rampage[1] + aabonuses.PC_Pet_Rampage[1]; - if (spell > spec_mod) - spec_mod = spell; + //SE_PC_Pet_Rampage SPA 464 on pet, damage modifier + int spell_mod = spellbonuses.PC_Pet_Rampage[1] + itembonuses.PC_Pet_Rampage[1] + aabonuses.PC_Pet_Rampage[1]; + if (spell_mod > spec_mod) + spec_mod = spell_mod; } } else if (IsSpecialAttack(eSpecialAttacks::AERampage)) { int mod = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 2); if (mod > 0) spec_mod = mod; + if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { + //SE_PC_Pet_AE_Rampage SPA 465 on pet, damage modifier + int spell_mod = spellbonuses.PC_Pet_AE_Rampage[1] + itembonuses.PC_Pet_AE_Rampage[1] + aabonuses.PC_Pet_AE_Rampage[1]; + if (spell_mod > spec_mod) + spec_mod = spell_mod; + } } if (spec_mod > 0) hit.damage_done = (hit.damage_done * spec_mod) / 100; diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index f973ab14c..fd635ffee 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1438,6 +1438,13 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) break; } + case SE_PC_Pet_AE_Rampage: { + newbon->PC_Pet_AE_Rampage[0] += base1; //Chance to rampage + if (newbon->PC_Pet_AE_Rampage[1] < base2) + newbon->PC_Pet_AE_Rampage[1] = base2; //Damage modifer - take highest + break; + } + case SE_PC_Pet_Flurry_Chance: newbon->PC_Pet_Flurry += base1; //Chance to Flurry break; @@ -3290,6 +3297,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne break; } + case SE_PC_Pet_AE_Rampage: { + new_bonus->PC_Pet_AE_Rampage[0] += effect_value; //Chance to rampage + if (new_bonus->PC_Pet_AE_Rampage[1] < base2) + new_bonus->PC_Pet_AE_Rampage[1] = base2; //Damage modifer - take highest + break; + } + case SE_PC_Pet_Flurry_Chance: new_bonus->PC_Pet_Flurry += effect_value; //Chance to Flurry break; @@ -5004,6 +5018,23 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) aabonuses.Pet_Add_Atk = effect_value; break; + case SE_PC_Pet_Rampage: + spellbonuses.PC_Pet_Rampage[0] = effect_value; + itembonuses.PC_Pet_Rampage[0] = effect_value; + aabonuses.PC_Pet_Rampage[0] = effect_value; + spellbonuses.PC_Pet_Rampage[1] = effect_value; + itembonuses.PC_Pet_Rampage[1] = effect_value; + aabonuses.PC_Pet_Rampage[1] = effect_value; + break; + + case SE_PC_Pet_AE_Rampage: + spellbonuses.PC_Pet_AE_Rampage[0] = effect_value; + itembonuses.PC_Pet_AE_Rampage[0] = effect_value; + aabonuses.PC_Pet_AE_Rampage[0] = effect_value; + spellbonuses.PC_Pet_AE_Rampage[1] = effect_value; + itembonuses.PC_Pet_AE_Rampage[1] = effect_value; + aabonuses.PC_Pet_AE_Rampage[1] = effect_value; + break; case SE_SkillProcSuccess:{ for(int e = 0; e < MAX_SKILL_PROCS; e++) diff --git a/zone/common.h b/zone/common.h index 1df689416..5455162ae 100644 --- a/zone/common.h +++ b/zone/common.h @@ -524,6 +524,7 @@ struct StatBonuses { uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs. 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_AE_Rampage[2]; // 0= % chance to AE rampage, 1=damage modifier uint32 PC_Pet_Flurry; // Percent chance flurry from double attack int32 Attack_Accuracy_Max_Percent; // Increase ATK accuracy by percent. int32 AC_Mitigation_Max_Percent; // Increase AC mitigation by percent diff --git a/zone/mob.cpp b/zone/mob.cpp index 0695545ab..80c1ccfcd 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3881,6 +3881,61 @@ int16 Mob::GetHealRate(uint16 spell_id, Mob* caster) { return heal_rate; } +void Mob::SetBottomRampageList() +{ + auto &mob_list = entity_list.GetCloseMobList(this); + + for (auto &e : mob_list) { + auto mob = e.second; + if (!mob) { + continue; + } + + if (!mob->GetSpecialAbility(SPECATK_RAMPAGE)) { + continue; + } + + if (mob->IsNPC() && mob->CheckAggro(this)) { + for (int i = 0; i < mob->RampageArray.size(); i++) { + // Find this mob in the rampage list + if (this->GetID() == mob->RampageArray[i]) { + //Move to bottom of Rampage List + auto it = mob->RampageArray.begin() + i; + std::rotate(it, it + 1, mob->RampageArray.end()); + } + } + } + } +} + +void Mob::SetTopRampageList() +{ + auto &mob_list = entity_list.GetCloseMobList(this); + + for (auto &e : mob_list) { + auto mob = e.second; + if (!mob) { + continue; + } + + if (!mob->GetSpecialAbility(SPECATK_RAMPAGE)) { + continue; + } + + if (mob->IsNPC() && mob->CheckAggro(this)) { + for (int i = 0; i < mob->RampageArray.size(); i++) { + // Find this mob in the rampage list + if (this->GetID() == mob->RampageArray[i]) { + //Move to Top of Rampage List + auto it = mob->RampageArray.begin() + i; + std::rotate(it, it + 1, mob->RampageArray.end()); + std::rotate(mob->RampageArray.rbegin(), mob->RampageArray.rbegin() + 1, mob->RampageArray.rend()); + } + } + } + } +} + bool Mob::TryFadeEffect(int slot) { if (!buffs[slot].spellid) diff --git a/zone/mob.h b/zone/mob.h index a4cf3b07e..64425112a 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -969,6 +969,8 @@ public: bool Rampage(ExtraAttackOptions *opts); bool AddRampage(Mob*); void ClearRampage(); + void SetBottomRampageList(); + void SetTopRampageList(); void AreaRampage(ExtraAttackOptions *opts); inline bool IsSpecialAttack(eSpecialAttacks in) { return m_specialattacks == in; } diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 306c6dd64..3791ed3f9 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1218,16 +1218,15 @@ void Mob::AI_Process() { } } + + //SE_PC_Pet_Rampage SPA 464 on pet, chance modifier if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { - if (spellbonuses.PC_Pet_Rampage[0] || itembonuses.PC_Pet_Rampage[0] || - aabonuses.PC_Pet_Rampage[0]) { - int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + - aabonuses.PC_Pet_Rampage[0]; - if (zone->random.Roll(chance)) { - Rampage(nullptr); - } + int chance = spellbonuses.PC_Pet_Rampage[0] + itembonuses.PC_Pet_Rampage[0] + aabonuses.PC_Pet_Rampage[0]; + if (chance && zone->random.Roll(chance)) { + Rampage(nullptr); } } + if (GetSpecialAbility(SPECATK_RAMPAGE) && !specialed) { int rampage_chance = GetSpecialAbilityParam(SPECATK_RAMPAGE, 0); @@ -1263,6 +1262,14 @@ void Mob::AI_Process() { } } + //SE_PC_Pet_Rampage SPA 465 on pet, chance modifier + if ((IsPet() || IsTempPet()) && IsPetOwnerClient()) { + int chance = spellbonuses.PC_Pet_AE_Rampage[0] + itembonuses.PC_Pet_AE_Rampage[0] + aabonuses.PC_Pet_AE_Rampage[0]; + if (chance && zone->random.Roll(chance)) { + Rampage(nullptr); + } + } + if (GetSpecialAbility(SPECATK_AREA_RAMPAGE) && !specialed) { int rampage_chance = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 0); rampage_chance = rampage_chance > 0 ? rampage_chance : 20; diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 1b7e02257..59682fc52 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2906,7 +2906,18 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove break; } - + + case SE_Hatelist_To_Tail_Index: { + if (caster && zone->random.Roll(spells[spell_id].base[i])) + caster->SetBottomRampageList(); + break; + } + + case SE_Hatelist_To_Top_Index: { + if (caster && zone->random.Roll(spells[spell_id].base[i])) + caster->SetTopRampageList(); + break; + } case SE_PersistentEffect: MakeAura(spell_id);