diff options
author | Treeston <treeston.mmoc@gmail.com> | 2018-08-20 19:04:21 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-10-22 00:48:20 +0200 |
commit | 6a5edf04725502d749636fc6c6bb3935d83c222f (patch) | |
tree | 57c9f011bf9cebf68f27fb9a6691dc7b50d1e074 /src | |
parent | 2d72e79ac4ec30cc4754024ae67c956c8fedf4a2 (diff) |
Core/AI: Some cleanup to DoZoneInCombat and Malygos' AI that I found while working out #22226.
(cherry picked from commit eb1972f21d6e79da32a89cb58c5c28eb98b0a4fb)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CreatureAI.cpp | 51 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 54 |
2 files changed, 30 insertions, 75 deletions
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 4e8e035bf5b..e3f3cabb5ef 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -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 diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 5f85069674d..25416696d1f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -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. |