From d554eb3423d677304b5157783767a0b3522ebdf5 Mon Sep 17 00:00:00 2001 From: nytmyr <53322305+nytmyr@users.noreply.github.com> Date: Sat, 29 Mar 2025 15:17:33 -0500 Subject: [PATCH] [Bots] Fix rule Bots:FinishBuffing (#4788) --- common/spdat.h | 5 +++-- common/spdat_bot.cpp | 16 ++++++++++++++++ zone/bot.cpp | 9 ++++++++- zone/botspellsai.cpp | 4 +++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/common/spdat.h b/common/spdat.h index 9b42e2bd4..9f4e787ff 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -900,8 +900,8 @@ const uint32 SPELL_TYPES_BENEFICIAL = (SpellType_Heal | SpellType_Buff | SpellTy const uint32 SPELL_TYPES_INNATE = (SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root); // Bot related functions -bool IsBotSpellTypeDetrimental (uint16 spell_type); -bool IsBotSpellTypeBeneficial (uint16 spell_type); +bool IsBotSpellTypeDetrimental(uint16 spell_type); +bool IsBotSpellTypeBeneficial(uint16 spell_type); bool BotSpellTypeUsesTargetSettings(uint16 spell_type); bool IsBotSpellTypeInnate (uint16 spell_type); bool IsAEBotSpellType(uint16 spell_type); @@ -917,6 +917,7 @@ bool IsCommandedBotSpellType(uint16 spell_type); bool IsPullingBotSpellType(uint16 spell_type); uint16 GetCorrectBotSpellType(uint16 spell_type, uint16 spell_id); uint16 GetPetBotSpellType(uint16 spell_type); +bool IsBotBuffSpellType(uint16 spell_type); // These should not be used to determine spell category.. // They are a graphical affects (effects?) index only diff --git a/common/spdat_bot.cpp b/common/spdat_bot.cpp index 413a5e00c..6627d3674 100644 --- a/common/spdat_bot.cpp +++ b/common/spdat_bot.cpp @@ -468,3 +468,19 @@ uint16 GetPetBotSpellType(uint16 spell_type) { return spell_type; } + +bool IsBotBuffSpellType(uint16 spell_type) { + switch (spell_type) { + case BotSpellTypes::Buff: + case BotSpellTypes::PetBuffs: + case BotSpellTypes::ResistBuffs: + case BotSpellTypes::PetResistBuffs: + case BotSpellTypes::DamageShields: + case BotSpellTypes::PetDamageShields: + return true; + default: + return false; + } + + return false; +} diff --git a/zone/bot.cpp b/zone/bot.cpp index 14d320373..bbe473b9d 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9533,7 +9533,14 @@ bool Bot::CastChecks(uint16 spell_id, Mob* tar, uint16 spell_type, bool precheck return false; } - if (!BotHasEnoughMana(spell_id)) { + if ( + !BotHasEnoughMana(spell_id) && + ( + !RuleB(Bots, FinishBuffing) || + IsEngaged() || + IsBotBuffSpellType(spell_type) + ) + ) { LogBotSpellChecksDetail("{} says, 'Cancelling cast of {} due to !BotHasEnoughMana.'", GetCleanName(), GetSpellName(spell_id)); return false; } diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index bb0f6b8e5..2dd8c608c 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -562,7 +562,9 @@ bool Bot::AIDoSpellCast(int32 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain // Allow bots to cast buff spells even if they are out of mana if ( RuleB(Bots, FinishBuffing) && - manaCost > hasMana && AIBot_spells[i].type == BotSpellTypes::Buff + manaCost > hasMana && + !IsEngaged() && + IsBotBuffSpellType(AIBot_spells[i].type) ) { SetMana(manaCost); }