From affa6f90846b2f7e1da4ad02afe2e53bf21324f4 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Tue, 9 Nov 2021 00:54:44 +0100 Subject: [PATCH] refactor(Core/Combat): Cleanup DoZoneInCombat function. (#8789) * Core/Combat: Cleanup DoZoneInCombat function. Updates #7960 * Restore distance parameter. * You don't belong here. * Update --- src/server/game/AI/CreatureAI.cpp | 84 ++++++++++++------- src/server/game/AI/CreatureAI.h | 2 +- .../game/Entities/Creature/Creature.cpp | 36 +------- 3 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 3a173d7ce..689927f29 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -56,13 +56,47 @@ void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= nullptr*/) sCreatureTextMgr->SendChat(me, id, whisperTarget); } -void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRangeToNearestTarget /* = 50.0f*/) +inline bool IsValidCombatTarget(Creature* source, Player* target) +{ + if (target->IsGameMaster()) + { + return false; + } + + if (!source->IsInWorld() || !target->IsInWorld()) + { + return false; + } + + if (!source->IsAlive() || !target->IsAlive()) + { + return false; + } + + if (!source->InSamePhase(target)) + { + return false; + } + + if (source->HasUnitState(UNIT_STATE_IN_FLIGHT) || target->HasUnitState(UNIT_STATE_IN_FLIGHT)) + { + return false; + } + + return true; +} + +void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRangeToNearestTarget /*= 250.0f*/) { if (!creature) + { creature = me; + } - if (!creature->CanHaveThreatList() || creature->IsInEvadeMode()) + if (creature->IsInEvadeMode()) + { return; + } Map* map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated @@ -71,45 +105,31 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange return; } - if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim()) - { - if (Unit* nearTarget = creature->SelectNearestTarget(maxRangeToNearestTarget)) - creature->AI()->AttackStart(nearTarget); - else if (creature->IsSummon()) - { - if (Unit* summoner = creature->ToTempSummon()->GetSummonerUnit()) - { - Unit* target = summoner->getAttackerForHelper(); - if (!target && summoner->CanHaveThreatList() && !summoner->getThreatMgr().isThreatListEmpty()) - target = summoner->getThreatMgr().getHostilTarget(); - if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target))) - creature->AI()->AttackStart(target); - } - } - } - - if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim()) - { - LOG_ERROR("entities.unit.ai", "DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); - return; - } - Map::PlayerList const& playerList = map->GetPlayers(); - if (playerList.isEmpty()) + { return; + } for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if (Player* player = itr->GetSource()) { - if (player->IsGameMaster()) - continue; - - if (player->IsAlive()) + if (!IsValidCombatTarget(creature, player)) + { + continue; + } + + if (!creature->IsWithinDistInMap(player, maxRangeToNearestTarget)) + { + continue; + } + + creature->SetInCombatWith(player); + player->SetInCombatWith(creature); + + if (creature->CanHaveThreatList()) { - creature->SetInCombatWith(player); - player->SetInCombatWith(creature); creature->AddThreat(player, 0.0f); } diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 6404bfbdf..b6f8791d8 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -137,7 +137,7 @@ public: // Called at reaching home after evade virtual void JustReachedHome() {} - void DoZoneInCombat(Creature* creature = nullptr, float maxRangeToNearestTarget = 50.0f); + void DoZoneInCombat(Creature* creature = nullptr, float maxRangeToNearestTarget = 250.0f); // Called at text emote receive from player virtual void ReceiveEmote(Player* /*player*/, uint32 /*emoteId*/) {} diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dc7b8f5ba..958bf061d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2549,40 +2549,8 @@ void Creature::SendZoneUnderAttackMessage(Player* attacker) void Creature::SetInCombatWithZone() { - if (!CanHaveThreatList()) - { - LOG_ERROR("entities.unit", "Creature entry %u call SetInCombatWithZone but creature cannot have threat list.", GetEntry()); - return; - } - - Map* map = GetMap(); - - if (!map->IsDungeon()) - { - LOG_ERROR("entities.unit", "Creature entry %u call SetInCombatWithZone for map (id: %u) that isn't an instance.", GetEntry(), map->GetId()); - return; - } - - Map::PlayerList const& PlList = map->GetPlayers(); - - if (PlList.isEmpty()) - return; - - for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i) - { - if (Player* player = i->GetSource()) - { - if (player->IsGameMaster()) - continue; - - if (player->IsAlive()) - { - this->SetInCombatWith(player); - player->SetInCombatWith(this); - AddThreat(player, 0.0f); - } - } - } + if (IsAIEnabled) + AI()->DoZoneInCombat(); } void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)