diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 1cb6ce012..c908c4456 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -242,11 +242,10 @@ public: // Victor Nefarius weekly mechanic drakonid spawn // Pick 2 drakonids and keep them for the whole save duration (the drakonids can't be repeated). std::vector nefarianDrakonidSpawners = { NPC_BLACK_SPAWNER, NPC_BLUE_SPAWNER, NPC_BRONZE_SPAWNER, NPC_GREEN_SPAWNER, NPC_RED_SPAWNER }; - _nefarianRightTunnel = Acore::Containers::SelectRandomContainerElement(nefarianDrakonidSpawners); - // delete the previous picked one so we don't get any repeated. - nefarianDrakonidSpawners.erase(std::remove(nefarianDrakonidSpawners.begin(), nefarianDrakonidSpawners.end(), _nefarianRightTunnel), nefarianDrakonidSpawners.end()); - // Pick another one - _nefarianLeftTunnel = Acore::Containers::SelectRandomContainerElement(nefarianDrakonidSpawners); + Acore::Containers::RandomResize(nefarianDrakonidSpawners, 2); + + _nefarianRightTunnel = nefarianDrakonidSpawners[0]; + _nefarianLeftTunnel = nefarianDrakonidSpawners[1]; // save it to instance instance->SetData(DATA_NEFARIAN_LEFT_TUNNEL, _nefarianLeftTunnel); @@ -293,6 +292,23 @@ public: Reset(); } + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() != NPC_NEFARIAN) + { + BossAI::JustSummoned(summon); + } + } + + void SummonedCreatureDies(Creature* summon, Unit* /*unit*/) override + { + if (summon->GetEntry() == NPC_NEFARIAN) + { + summons.DespawnAll(); + Unit::Kill(me, me); + } + } + void DoAction(int32 action) override { if (action == ACTION_RESET) @@ -304,12 +320,26 @@ public: if (action == ACTION_ADD_KILLED) { KilledAdds++; - } - if (action == ACTION_KILLED) - { - summons.DespawnEntry(NPC_BONE_CONSTRUCT); - Unit::Kill(me, me); + if (KilledAdds == MAX_DRAKONID_KILLED) + { + if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianSpawn)) + { + nefarian->setActive(true); + nefarian->SetCanFly(true); + nefarian->SetDisableGravity(true); + nefarian->GetMotionMaster()->MovePath(NEFARIAN_PATH, false); + } + + events.Reset(); + DoCastSelf(SPELL_ROOT_SELF, true); + me->SetVisible(false); + // Stop spawning adds + EntryCheckPredicate pred(_nefarianRightTunnel); + summons.DoAction(ACTION_SPAWNER_STOP, pred); + EntryCheckPredicate pred2(_nefarianLeftTunnel); + summons.DoAction(ACTION_SPAWNER_STOP, pred2); + } } } @@ -335,14 +365,11 @@ public: events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000)); events.ScheduleEvent(EVENT_MIND_CONTROL, urand(30000, 35000)); events.ScheduleEvent(EVENT_SPAWN_ADDS, 10000); - events.ScheduleEvent(EVENT_CHECK_PHASE_2, 10000); } - void JustSummoned(Creature* summon) override { summons.Summon(summon); } - void SetData(uint32 type, uint32 data) override { - if ( type == 1 && data == 1) + if (type == 1 && data == 1) { me->StopMoving(); events.ScheduleEvent(EVENT_PATH_2, 9000); @@ -428,8 +455,7 @@ public: events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, 19000, 25000); break; case EVENT_FEAR: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true)) - DoCast(target, SPELL_FEAR); + DoCastRandomTarget(SPELL_FEAR, 0, 40.0f); events.ScheduleEvent(EVENT_FEAR, urand(10000, 20000)); break; case EVENT_SILENCE: @@ -437,8 +463,7 @@ public: events.ScheduleEvent(EVENT_SILENCE, urand(14000, 23000)); break; case EVENT_MIND_CONTROL: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40, true)) - DoCast(target, SPELL_SHADOW_COMMAND); + DoCastRandomTarget(SPELL_SHADOW_COMMAND, 0, 40.0f); events.ScheduleEvent(EVENT_MIND_CONTROL, urand(24000, 30000)); break; case EVENT_SHADOWBLINK: @@ -450,32 +475,6 @@ public: me->SummonCreature(_nefarianLeftTunnel, spawnerPositions[0]); me->SummonCreature(_nefarianRightTunnel, spawnerPositions[1]); break; - case EVENT_CHECK_PHASE_2: - if (KilledAdds >= MAX_DRAKONID_KILLED) - { - if (Creature* nefarian = me->SummonCreature(NPC_NEFARIAN, NefarianSpawn)) - { - nefarian->setActive(true); - nefarian->SetCanFly(true); - nefarian->SetDisableGravity(true); - nefarian->GetMotionMaster()->MovePath(NEFARIAN_PATH, false); - } - events.CancelEvent(EVENT_MIND_CONTROL); - events.CancelEvent(EVENT_FEAR); - events.CancelEvent(EVENT_SHADOW_BOLT); - events.CancelEvent(EVENT_SHADOW_BOLT_VOLLEY); - events.CancelEvent(EVENT_SILENCE); - DoCastSelf(SPELL_ROOT_SELF, true); - me->SetVisible(false); - // Stop spawning adds - EntryCheckPredicate pred(_nefarianRightTunnel); - summons.DoAction(ACTION_SPAWNER_STOP, pred); - EntryCheckPredicate pred2(_nefarianLeftTunnel); - summons.DoAction(ACTION_SPAWNER_STOP, pred2); - return; - } - events.ScheduleEvent(EVENT_CHECK_PHASE_2, 1000); - break; } if (me->HasUnitState(UNIT_STATE_CASTING)) @@ -500,8 +499,6 @@ public: me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); me->SetStandState(UNIT_STAND_STATE_STAND); me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); - // Due to Nefarius despawning himself on Vael, we need to update the guid on instance to prevent unwanted behaviours as encounter not resetting at all. - instance->SetGuidData(DATA_LORD_VICTOR_NEFARIUS, me->GetGUID()); } } @@ -556,14 +553,6 @@ struct boss_nefarian : public BossAI { _JustDied(); Talk(SAY_DEATH); - - if (Creature* victor = me->FindNearestCreature(NPC_VICTOR_NEFARIUS, 200.f, true)) - { - if (victor->AI()) - { - victor->AI()->DoAction(ACTION_KILLED); - } - } } void KilledUnit(Unit* victim) override @@ -620,6 +609,29 @@ struct boss_nefarian : public BossAI _introDone = true; } + void DamageTaken(Unit* /*unit*/, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (me->HealthBelowPctDamaged(20, damage) && !Phase3) + { + std::list constructList; + me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f); + for (Creature* const& summon : constructList) + { + if (summon && !summon->IsAlive()) + { + summon->Respawn(); + summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + summon->SetReactState(REACT_AGGRESSIVE); + summon->SetStandState(UNIT_STAND_STATE_STAND); + DoZoneInCombat(summon); + } + } + + Phase3 = true; + Talk(SAY_RAISE_SKELETONS); + } + } + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) @@ -734,27 +746,6 @@ struct boss_nefarian : public BossAI } } - // Phase3 begins when health below 20 pct - if (!Phase3 && HealthBelowPct(20)) - { - std::list constructList; - me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f); - for (std::list::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr) - { - if ((*itr) && !(*itr)->IsAlive()) - { - (*itr)->Respawn(); - DoZoneInCombat((*itr)); - (*itr)->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - (*itr)->SetReactState(REACT_AGGRESSIVE); - (*itr)->SetStandState(UNIT_STAND_STATE_STAND); - } - } - - Phase3 = true; - Talk(SAY_RAISE_SKELETONS); - } - DoMeleeAttackIfReady(); } @@ -818,17 +809,19 @@ struct npc_corrupted_totem : public ScriptedAI return; } - std::vector mobsEntries; - mobsEntries.push_back(NPC_NEFARIAN); - mobsEntries.push_back(NPC_BONE_CONSTRUCT); - mobsEntries.push_back(NPC_BRONZE_DRAKONID); - mobsEntries.push_back(NPC_BLUE_DRAKONID); - mobsEntries.push_back(NPC_RED_DRAKONID); - mobsEntries.push_back(NPC_GREEN_DRAKONID); - mobsEntries.push_back(NPC_BLACK_DRAKONID); - mobsEntries.push_back(NPC_CHROMATIC_DRAKONID); + std::vector mobsEntries = + { + NPC_NEFARIAN, + NPC_BONE_CONSTRUCT, + NPC_BRONZE_DRAKONID, + NPC_BLUE_DRAKONID, + NPC_RED_DRAKONID, + NPC_GREEN_DRAKONID, + NPC_BLACK_DRAKONID, + NPC_CHROMATIC_DRAKONID + }; - for (auto& entry : mobsEntries) + for (auto const& entry : mobsEntries) { std::list tmpMobList; GetCreatureListWithEntryInGrid(tmpMobList, me, entry, 100.f); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp index 778575711..7855cf891 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp @@ -45,8 +45,9 @@ DoorData const doorData[] = ObjectData const creatureData[] = { - { NPC_GRETHOK, DATA_GRETHOK }, - { NPC_NEFARIAN_TROOPS, DATA_NEFARIAN_TROOPS } + { NPC_GRETHOK, DATA_GRETHOK }, + { NPC_NEFARIAN_TROOPS, DATA_NEFARIAN_TROOPS }, + { NPC_VICTOR_NEFARIUS, DATA_LORD_VICTOR_NEFARIUS } }; Position const SummonPosition[8] = @@ -127,26 +128,19 @@ public: case NPC_NEFARIAN: nefarianGUID = creature->GetGUID(); break; - case NPC_VICTOR_NEFARIUS: - victorNefariusGUID = creature->GetGUID(); - break; case NPC_BLACK_DRAKONID: case NPC_BLUE_DRAKONID: case NPC_BRONZE_DRAKONID: case NPC_CHROMATIC_DRAKONID: case NPC_GREEN_DRAKONID: case NPC_RED_DRAKONID: - if (Creature* nefarius = instance->GetCreature(victorNefariusGUID)) + if (Creature* nefarius = GetCreature(DATA_LORD_VICTOR_NEFARIUS)) { if (CreatureAI* nefariusAI = nefarius->AI()) { nefariusAI->JustSummoned(creature); } } - if (creature->AI()) - { - creature->AI()->DoZoneInCombat(); - } break; default: break; @@ -369,8 +363,6 @@ public: { case DATA_RAZORGORE_THE_UNTAMED: return razorgoreGUID; - case DATA_LORD_VICTOR_NEFARIUS: - return victorNefariusGUID; case DATA_CHROMAGGUS: return chromaggusGUID; case DATA_GO_CHROMAGGUS_DOOR: @@ -382,18 +374,6 @@ public: return ObjectGuid::Empty; } - void SetGuidData(uint32 type, ObjectGuid data) override - { - switch (type) - { - case DATA_LORD_VICTOR_NEFARIUS: - victorNefariusGUID = data; - break; - default: - break; - } - } - void OnUnitDeath(Unit* unit) override { switch (unit->GetEntry()) @@ -413,25 +393,13 @@ public: summon->SetStandState(UNIT_STAND_STATE_DEAD); summon->SetHomePosition(summon->GetPosition()); - if (Creature* nefarius = instance->GetCreature(victorNefariusGUID)) + if (Creature* nefarius = GetCreature(DATA_LORD_VICTOR_NEFARIUS)) { if (nefarius->AI()) { nefarius->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED); } } - else // Something happened, try another way - { - if (Creature* nefarius = summon->FindNearestCreature(NPC_VICTOR_NEFARIUS, 500.f, true)) - { - victorNefariusGUID = nefarius->GetGUID(); - - if (nefarius->AI()) - { - nefarius->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED); - } - } - } } break; case NPC_BLACKWING_DRAGON: @@ -514,7 +482,7 @@ public: razor->AI()->DoAction(ACTION_PHASE_TWO); break; case EVENT_RESPAWN_NEFARIUS: - if (Creature* nefarius = instance->GetCreature(victorNefariusGUID)) + if (Creature* nefarius = GetCreature(DATA_LORD_VICTOR_NEFARIUS)) { nefarius->SetPhaseMask(1, true); nefarius->setActive(true); @@ -580,7 +548,6 @@ public: ObjectGuid chromaggusDoorGUID; ObjectGuid nefarianGUID; ObjectGuid nefarianDoorGUID; - ObjectGuid victorNefariusGUID; // Razorgore uint8 EggCount;