fix(Scripts/BlackwingLair): Solve the issue with Nefarian occasionall… (#11398)

This commit is contained in:
Skjalf
2022-04-14 17:27:04 -03:00
committed by GitHub
parent 6800f79c00
commit 2f5a5dffcb
2 changed files with 84 additions and 124 deletions

View File

@@ -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<uint32> 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<Creature*> 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<Creature*> constructList;
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
for (std::list<Creature*>::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<uint32> 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<uint32> 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<Creature*> tmpMobList;
GetCreatureListWithEntryInGrid(tmpMobList, me, entry, 100.f);

View File

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