refactor(Core/Combat): Cleanup DoZoneInCombat function. (#8789)

* Core/Combat: Cleanup DoZoneInCombat function.

Updates #7960

* Restore distance parameter.

* You don't belong here.

* Update
This commit is contained in:
UltraNix
2021-11-09 00:54:44 +01:00
committed by GitHub
parent 5d1a7a4dc9
commit affa6f9084
3 changed files with 55 additions and 67 deletions

View File

@@ -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);
}

View File

@@ -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*/) {}

View File

@@ -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)