From 56608e84bdf830feec98f4c04c09700fd7bec0aa Mon Sep 17 00:00:00 2001 From: nytmyr <53322305+nytmyr@users.noreply.github.com> Date: Sun, 29 Sep 2024 16:59:26 -0500 Subject: [PATCH] [Bots] Add attack flag when told to attack (#4490) This adds a flag to mobs that are told to attack by their owner to prevent unintended attacks. Previously, if you were to send your bots to attack a target and then switch targets: before casters land their spell or if melee (especially anyone with pets) hasn't engaged before the target switch, they could switch to your new target and attack. This adds a flag upon attack and bots will only attack flagged targets. --- zone/bot.cpp | 2 +- zone/bot_commands/attack.cpp | 5 +++++ zone/mob.cpp | 27 ++++++++++++++++++++++++++- zone/mob.h | 11 +++++++++++ zone/npc.cpp | 5 +++++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index c2c06ce5a..331216e58 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2978,7 +2978,7 @@ void Bot::SetOwnerTarget(Client* bot_owner) { if (NOT_HOLDING && NOT_PASSIVE) { auto attack_target = bot_owner->GetTarget(); - if (attack_target) { + if (attack_target && HasBotAttackFlag(attack_target)) { InterruptSpell(); WipeHateList(); diff --git a/zone/bot_commands/attack.cpp b/zone/bot_commands/attack.cpp index 0253a2f7a..60cad8cd8 100644 --- a/zone/bot_commands/attack.cpp +++ b/zone/bot_commands/attack.cpp @@ -35,6 +35,11 @@ void bot_command_attack(Client *c, const Seperator *sep) return; } + if (!c->HasBotAttackFlag(target_mob)) { + target_mob->SetBotAttackFlag(c->CharacterID()); + target_mob->bot_attack_flag_timer.Start(10000); + } + size_t attacker_count = 0; Bot *first_attacker = nullptr; sbl.remove(nullptr); diff --git a/zone/mob.cpp b/zone/mob.cpp index 25ce4a486..64ac3a6e2 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -129,7 +129,8 @@ Mob::Mob( position_update_melee_push_timer(500), hate_list_cleanup_timer(6000), mob_close_scan_timer(6000), - mob_check_moving_timer(1000) + mob_check_moving_timer(1000), + bot_attack_flag_timer(10000) { mMovementManager = &MobMovementManager::Get(); mMovementManager->AddMob(this); @@ -400,6 +401,10 @@ Mob::Mob( pet_owner_npc = false; pet_targetlock_id = 0; + //bot attack flag + bot_attack_flags.clear(); + bot_attack_flag_timer.Disable(); + attacked_count = 0; mezzed = false; stunned = false; @@ -8623,3 +8628,23 @@ bool Mob::IsCloseToBanker() return false; } + +bool Mob::HasBotAttackFlag(Mob* tar) { + if (!tar) { + return false; + } + + std::vector l = tar->GetBotAttackFlags(); + + for (uint32 e : l) { + if (IsBot() && e == CastToBot()->GetBotOwnerCharacterID()) { + return true; + } + + if (IsClient() && e == CastToClient()->CharacterID()) { + return true; + } + } + + return false; +} diff --git a/zone/mob.h b/zone/mob.h index 6bb442ff5..61e82c1fe 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -205,6 +205,9 @@ public: Timer mob_close_scan_timer; Timer mob_check_moving_timer; + // Bot attack flag + Timer bot_attack_flag_timer; + //Somewhat sorted: needs documenting! //Attack @@ -1102,6 +1105,11 @@ public: bool invulnerable; bool qglobal; + inline std::vector GetBotAttackFlags() { return bot_attack_flags; } + inline void SetBotAttackFlag(uint32 value) { bot_attack_flags.push_back(value); } + inline void ClearBotAttackFlags() { bot_attack_flags.clear(); } + bool HasBotAttackFlag(Mob* tar); + virtual void SetAttackTimer(); inline void SetInvul(bool invul) { invulnerable=invul; } inline bool GetInvul(void) { return invulnerable; } @@ -1863,6 +1871,9 @@ protected: bool pet_owner_npc; // Flags pets as belonging to an NPC uint32 pet_targetlock_id; + //bot attack flags + std::vector bot_attack_flags; + glm::vec3 m_TargetRing; GravityBehavior flymode; diff --git a/zone/npc.cpp b/zone/npc.cpp index 6f7f016ae..d776fb8bc 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -799,6 +799,11 @@ bool NPC::Process() } } + if (bot_attack_flag_timer.Check()) { + bot_attack_flag_timer.Disable(); + ClearBotAttackFlags(); + } + AI_Process(); return true;