From e5bcb6acfc4315fbb2d027755f5da2833014a0a3 Mon Sep 17 00:00:00 2001 From: nytmyr <53322305+nytmyr@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:40:47 -0600 Subject: [PATCH] Correct pet buff type logic to catch DS/Resists with other spell effects in them --- common/spdat.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++ common/spdat.h | 2 ++ zone/bot.cpp | 7 +++--- zone/botspellsai.cpp | 5 +--- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/common/spdat.cpp b/common/spdat.cpp index 5151d4d5a..831c7f35e 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -2824,6 +2824,34 @@ bool IsResurrectSpell(uint16 spell_id) return IsEffectInSpell(spell_id, SE_Revive); } +bool IsResistanceBuffSpell(uint16 spell_id) { + if (!IsValidSpell(spell_id)) { + return false; + } + + const auto& spell = spells[spell_id]; + + for (int i = 0; i < EFFECT_COUNT; i++) { + if (IsBlankSpellEffect(spell_id, i)) { + continue; + } + + if ( + spell.effect_id[i] == SE_ResistFire || + spell.effect_id[i] == SE_ResistCold || + spell.effect_id[i] == SE_ResistPoison || + spell.effect_id[i] == SE_ResistDisease || + spell.effect_id[i] == SE_ResistMagic || + spell.effect_id[i] == SE_ResistCorruption || + spell.effect_id[i] == SE_ResistAll + ) { + return true; + } + } + + return false; +} + bool IsResistanceOnlySpell(uint16 spell_id) { if (!IsValidSpell(spell_id)) { return false; @@ -2876,6 +2904,35 @@ bool IsDamageShieldOnlySpell(uint16 spell_id) { return true; } +bool IsDamageShieldAndResistSpell(uint16 spell_id) { + if (!IsValidSpell(spell_id)) { + return false; + } + + const auto& spell = spells[spell_id]; + + for (int i = 0; i < EFFECT_COUNT; i++) { + if (IsBlankSpellEffect(spell_id, i)) { + continue; + } + + if ( + spell.effect_id[i] != SE_DamageShield && + spell.effect_id[i] != SE_ResistFire && + spell.effect_id[i] != SE_ResistCold && + spell.effect_id[i] != SE_ResistPoison && + spell.effect_id[i] != SE_ResistDisease && + spell.effect_id[i] != SE_ResistMagic && + spell.effect_id[i] != SE_ResistCorruption && + spell.effect_id[i] != SE_ResistAll + ) { + return false; + } + } + + return true; +} + bool IsHateSpell(uint16 spell_id) { if (!IsValidSpell(spell_id)) { return false; diff --git a/common/spdat.h b/common/spdat.h index 08cf55ee8..b60ab5186 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -1908,8 +1908,10 @@ bool IsLichSpell(uint16 spell_id); bool IsInstantHealSpell(uint32 spell_id); bool IsResurrectSpell(uint16 spell_id); bool RequiresStackCheck(uint16 spell_type); +bool IsResistanceBuffSpell(uint16 spell_id); bool IsResistanceOnlySpell(uint16 spell_id); bool IsDamageShieldOnlySpell(uint16 spell_id); +bool IsDamageShieldAndResistSpell(uint16 spell_id); bool IsHateSpell(uint16 spell_id); #endif diff --git a/zone/bot.cpp b/zone/bot.cpp index 22f18f774..7657f8b36 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -11572,7 +11572,8 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) { case BotSpellTypes::PetBuffs: if ( IsResistanceOnlySpell(spell_id) || - IsDamageShieldOnlySpell(spell_id) + IsDamageShieldOnlySpell(spell_id) || + IsDamageShieldAndResistSpell(spell_id) ) { return false; } @@ -11580,14 +11581,14 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spell_type, uint16 spell_id) { return true; case BotSpellTypes::ResistBuffs: case BotSpellTypes::PetResistBuffs: - if (IsResistanceOnlySpell(spell_id)) { + if (IsResistanceBuffSpell(spell_id)) { return true; } return false; case BotSpellTypes::DamageShields: case BotSpellTypes::PetDamageShields: - if (IsDamageShieldOnlySpell(spell_id)) { + if (IsEffectInSpell(spell_id, SE_DamageShield)) { return true; } diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index f08d78b7e..8eab457e0 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -32,10 +32,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 chance, uint16 spell_type, uint16 sub_targ !AI_HasSpells() || (spell_type == BotSpellTypes::Pet && tar != this) || (IsPetBotSpellType(spell_type) && !tar->IsPet()) || - (spell_type == BotSpellTypes::Buff && tar->IsPet()) || - (spell_type == BotSpellTypes::InCombatBuffSong && tar->IsPet()) || - (spell_type == BotSpellTypes::OutOfCombatBuffSong && tar->IsPet()) || - (spell_type == BotSpellTypes::PreCombatBuffSong && tar->IsPet()) || + (!IsPetBotSpellType(spell_type) && tar->IsPet()) || (!RuleB(Bots, AllowBuffingHealingFamiliars) && tar->IsFamiliar()) || (tar->IsPet() && tar->IsCharmed() && spell_type == BotSpellTypes::PetBuffs && !RuleB(Bots, AllowCharmedPetBuffs)) || (tar->IsPet() && tar->IsCharmed() && spell_type == BotSpellTypes::PetCures && !RuleB(Bots, AllowCharmedPetCures)) ||