mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/AI: Some cleanup to DoZoneInCombat and Malygos' AI that I found while working out #22226.
(cherry picked from commit eb1972f21d)
This commit is contained in:
@@ -67,49 +67,28 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange
|
||||
creature = me;
|
||||
|
||||
Map* map = creature->GetMap();
|
||||
if (creature->CanHaveThreatList())
|
||||
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
|
||||
{
|
||||
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
|
||||
{
|
||||
TC_LOG_ERROR("misc", "DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
|
||||
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()->GetSummoner())
|
||||
{
|
||||
if (creature->IsFriendlyTo(summoner))
|
||||
{
|
||||
Unit* target = summoner->getAttackerForHelper();
|
||||
if (target && creature->IsHostileTo(target))
|
||||
creature->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intended duplicated check, the code above this should select a victim
|
||||
// If it can't find a suitable attack target then we should error out.
|
||||
if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim())
|
||||
{
|
||||
TC_LOG_ERROR("misc.dozoneincombat", "DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry());
|
||||
return;
|
||||
}
|
||||
TC_LOG_ERROR("misc", "DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
|
||||
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->IsAlive())
|
||||
creature->EngageWithTarget(player);
|
||||
for (auto const& ref : playerList)
|
||||
if (Player* player = ref.GetSource())
|
||||
{
|
||||
if (!player->IsAlive() || !CombatManager::CanBeginCombat(creature, player))
|
||||
continue;
|
||||
|
||||
creature->EngageWithTarget(player);
|
||||
for (Unit* pet : player->m_Controlled)
|
||||
creature->EngageWithTarget(pet);
|
||||
if (Unit* vehicle = player->GetVehicleBase())
|
||||
creature->EngageWithTarget(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// scripts does not take care about MoveInLineOfSight loops
|
||||
|
||||
@@ -355,7 +355,6 @@ public:
|
||||
guid.Clear();
|
||||
|
||||
_killSpamFilter = false;
|
||||
_canAttack = false;
|
||||
_executingVortex = false;
|
||||
_arcaneReinforcements = true;
|
||||
_flyingOutOfPlatform = false;
|
||||
@@ -465,7 +464,6 @@ public:
|
||||
alexstraszaBunny->GetNearPoint2D(nullptr, pos.m_positionX, pos.m_positionY, 30.0f, alexstraszaBunny->GetAbsoluteAngle(me));
|
||||
me->GetMotionMaster()->MoveLand(POINT_LAND_P_ONE, pos);
|
||||
me->SetImmuneToAll(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_LAND_START_ENCOUNTER, 7*IN_MILLISECONDS, 1, PHASE_NOT_STARTED);
|
||||
}
|
||||
@@ -560,13 +558,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// There are moments where boss will do nothing while being attacked
|
||||
void AttackStart(Unit* target) override
|
||||
{
|
||||
if (_canAttack)
|
||||
BossAI::AttackStart(target);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
// We can't call full function here since it includes DoZoneInCombat(),
|
||||
@@ -588,30 +579,10 @@ public:
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
instance->SetBossState(DATA_MALYGOS_EVENT, FAIL);
|
||||
instance->SetBossState(DATA_MALYGOS_EVENT, NOT_STARTED);
|
||||
|
||||
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS);
|
||||
|
||||
if (_phase == PHASE_THREE)
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
|
||||
uint32 corpseDelay = me->GetCorpseDelay();
|
||||
uint32 respawnDelay = me->GetRespawnDelay();
|
||||
me->SetCorpseDelay(1);
|
||||
me->SetRespawnDelay(29);
|
||||
me->DespawnOrUnsummon();
|
||||
me->SetCorpseDelay(corpseDelay);
|
||||
me->SetRespawnDelay(respawnDelay);
|
||||
|
||||
// Set speed to normal value
|
||||
me->SetSpeedRate(MOVE_FLIGHT, _flySpeed);
|
||||
me->RemoveAllAuras();
|
||||
me->CombatStop(); // Sometimes threat can remain, so it's a safety measure
|
||||
|
||||
if (!_despawned)
|
||||
_despawned = true;
|
||||
|
||||
me->ResetLootMode();
|
||||
events.Reset();
|
||||
if (!summons.empty())
|
||||
{
|
||||
if (_phase == PHASE_TWO)
|
||||
@@ -625,7 +596,7 @@ public:
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
instance->SetBossState(DATA_MALYGOS_EVENT, NOT_STARTED);
|
||||
me->DespawnOrUnsummon(0, 30s);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
@@ -705,7 +676,7 @@ public:
|
||||
case POINT_LAND_AFTER_VORTEX_P_ONE:
|
||||
me->SetDisableGravity(false);
|
||||
_executingVortex = false;
|
||||
_canAttack = true;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
case POINT_LIFT_IN_AIR_P_ONE:
|
||||
me->SetDisableGravity(true);
|
||||
@@ -751,9 +722,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*cause*/, uint32& damage) override
|
||||
{
|
||||
if (damage > me->GetHealth() && _phase != PHASE_THREE)
|
||||
damage = me->GetHealth() - 1;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!instance || (!UpdateVictim() && _phase != PHASE_NOT_STARTED && _phase != PHASE_TWO))
|
||||
if (!UpdateVictim() && _phase != PHASE_NOT_STARTED && _phase != PHASE_TWO)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
@@ -766,7 +743,7 @@ public:
|
||||
if (_phase == PHASE_ONE && me->GetHealthPct() <= 50.0f)
|
||||
{
|
||||
SetPhase(PHASE_TWO, true);
|
||||
_canAttack = false;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
Talk(SAY_END_P_ONE);
|
||||
}
|
||||
@@ -788,7 +765,7 @@ public:
|
||||
me->SetFacingToObject(iris);
|
||||
iris->Delete(); // this is not the best way.
|
||||
}
|
||||
_canAttack = true;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
SetPhase(PHASE_ONE, true);
|
||||
break;
|
||||
case EVENT_SAY_INTRO:
|
||||
@@ -801,7 +778,7 @@ public:
|
||||
events.ScheduleEvent(EVENT_VORTEX, urand(60, 80)*IN_MILLISECONDS, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_MOVE_TO_VORTEX_POINT:
|
||||
_canAttack = false;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(POINT_VORTEX_P_ONE, MalygosPositions[1]);
|
||||
break;
|
||||
@@ -943,9 +920,9 @@ public:
|
||||
me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_ARCANE_RUNES, 1 * IN_MILLISECONDS);
|
||||
DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
|
||||
DoCast(me, SPELL_IMMUNE_CURSES);
|
||||
_canAttack = true;
|
||||
UpdateVictim();
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoZoneInCombat();
|
||||
SetPhase(PHASE_THREE, true);
|
||||
break;
|
||||
case EVENT_SURGE_OF_POWER_P_THREE:
|
||||
@@ -1022,7 +999,6 @@ public:
|
||||
ObjectGuid _surgeTargetGUID[3]; // All these three are used to keep current tagets to which warning should be sent.
|
||||
|
||||
bool _killSpamFilter; // Prevent text spamming on killed player by helping implement a CD.
|
||||
bool _canAttack; // Used to control attacking (Move Chase not being applied after Stop Attack, only few times should act like this).
|
||||
bool _despawned; // Checks if boss pass through evade on reset.
|
||||
bool _executingVortex; // Prevents some events being sheduled during Vortex takeoff/land.
|
||||
bool _arcaneReinforcements; // Checks if 10 or 25 man arcane trash will be spawned.
|
||||
|
||||
Reference in New Issue
Block a user