mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Scripts/AzjolNerub): Call next watcher when a watcher pack dies (#23799)
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
--
|
||||||
|
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (12758, 12759, 12760);
|
||||||
|
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `groupAI`) VALUES
|
||||||
|
(12758, 12758, 7),
|
||||||
|
(12758, 12762, 7),
|
||||||
|
(12758, 12761, 7),
|
||||||
|
(12759, 12759, 7),
|
||||||
|
(12759, 12763, 7),
|
||||||
|
(12759, 12764, 7),
|
||||||
|
(12760, 12760, 7),
|
||||||
|
(12760, 12765, 7),
|
||||||
|
(12760, 12766, 7);
|
||||||
|
|
||||||
|
DELETE FROM `linked_respawn` WHERE `linkedGuid` = 127214 AND `linkType` = 0;
|
||||||
|
INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`) VALUES
|
||||||
|
(12758, 127214, 0),
|
||||||
|
(12759, 127214, 0),
|
||||||
|
(12760, 127214, 0),
|
||||||
|
(12761, 127214, 0),
|
||||||
|
(12762, 127214, 0),
|
||||||
|
(12763, 127214, 0),
|
||||||
|
(12764, 127214, 0),
|
||||||
|
(12765, 127214, 0),
|
||||||
|
(12766, 127214, 0);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28729) AND (`source_type` = 0) AND (`id` IN (5));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28730) AND (`source_type` = 0) AND (`id` IN (4));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28731) AND (`source_type` = 0) AND (`id` IN (5));
|
||||||
@@ -417,6 +417,15 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z, uint32 move_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreatureGroup::DespawnFormation(Milliseconds timeToDespawn /*=0ms*/, Seconds forcedRespawnTimer /*=0s*/)
|
||||||
|
{
|
||||||
|
for (auto const& itr : m_members)
|
||||||
|
{
|
||||||
|
if (itr.first)
|
||||||
|
itr.first->DespawnOrUnsummon(timeToDespawn, forcedRespawnTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CreatureGroup::RespawnFormation(bool force)
|
void CreatureGroup::RespawnFormation(bool force)
|
||||||
{
|
{
|
||||||
for (auto const& itr : m_members)
|
for (auto const& itr : m_members)
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ public:
|
|||||||
void MemberEngagingTarget(Creature* member, Unit* target);
|
void MemberEngagingTarget(Creature* member, Unit* target);
|
||||||
Unit* GetNewTargetForMember(Creature* member);
|
Unit* GetNewTargetForMember(Creature* member);
|
||||||
void MemberEvaded(Creature* member);
|
void MemberEvaded(Creature* member);
|
||||||
|
void DespawnFormation(Milliseconds timeToDespawn = 0ms, Seconds forcedRespawnTimer = 0s);
|
||||||
void RespawnFormation(bool force = false);
|
void RespawnFormation(bool force = false);
|
||||||
[[nodiscard]] bool IsFormationInCombat();
|
[[nodiscard]] bool IsFormationInCombat();
|
||||||
[[nodiscard]] bool IsAnyMemberAlive(bool ignoreLeader = false);
|
[[nodiscard]] bool IsAnyMemberAlive(bool ignoreLeader = false);
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ enum ANIds
|
|||||||
NPC_WATCHER_NARJIL = 28729,
|
NPC_WATCHER_NARJIL = 28729,
|
||||||
NPC_WATCHER_GASHRA = 28730,
|
NPC_WATCHER_GASHRA = 28730,
|
||||||
NPC_WATCHER_SILTHIK = 28731,
|
NPC_WATCHER_SILTHIK = 28731,
|
||||||
|
NPC_ANUBAR_SKIRMISHER = 28734,
|
||||||
|
NPC_ANUBAR_SHADOWCASTER = 28733,
|
||||||
|
NPC_ANUBAR_WARRIOR = 28732,
|
||||||
NPC_SKITTERING_SWARMER = 28735,
|
NPC_SKITTERING_SWARMER = 28735,
|
||||||
NPC_SKITTERING_INFECTIOR = 28736,
|
NPC_SKITTERING_INFECTIOR = 28736,
|
||||||
NPC_KRIKTHIR_THE_GATEWATCHER = 28684,
|
NPC_KRIKTHIR_THE_GATEWATCHER = 28684,
|
||||||
@@ -60,6 +63,11 @@ enum ANIds
|
|||||||
SPELL_WEB_WRAP_TRIGGER = 52087
|
SPELL_WEB_WRAP_TRIGGER = 52087
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ANActions
|
||||||
|
{
|
||||||
|
ACTION_MINION_DIED = 2,
|
||||||
|
};
|
||||||
|
|
||||||
template <class AI, class T>
|
template <class AI, class T>
|
||||||
inline AI* GetAzjolNerubAI(T* obj)
|
inline AI* GetAzjolNerubAI(T* obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "CreatureGroups.h"
|
#include "CreatureGroups.h"
|
||||||
#include "CreatureScript.h"
|
#include "CreatureScript.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "SpellInfo.h"
|
||||||
#include "azjol_nerub.h"
|
#include "azjol_nerub.h"
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
@@ -30,13 +31,6 @@ enum Spells
|
|||||||
SPELL_FRENZY = 28747
|
SPELL_FRENZY = 28747
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Npcs
|
|
||||||
{
|
|
||||||
NPC_WARRIOR = 28732,
|
|
||||||
NPC_SKIRMISHER = 28734,
|
|
||||||
NPC_SHADOWCASTER = 28733
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Yells
|
enum Yells
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 0,
|
SAY_AGGRO = 0,
|
||||||
@@ -50,7 +44,8 @@ enum Yells
|
|||||||
enum MiscActions
|
enum MiscActions
|
||||||
{
|
{
|
||||||
ACTION_MINION_ENGAGED = 1,
|
ACTION_MINION_ENGAGED = 1,
|
||||||
GROUP_SWARM = 1
|
GROUP_SWARM = 1,
|
||||||
|
GROUP_WATCHERS = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_krik_thir : public CreatureScript
|
class boss_krik_thir : public CreatureScript
|
||||||
@@ -91,6 +86,11 @@ public:
|
|||||||
|
|
||||||
_canTalk = true;
|
_canTalk = true;
|
||||||
_minionInCombat = false;
|
_minionInCombat = false;
|
||||||
|
_firstCall = true;
|
||||||
|
_minionsEngaged = 0;
|
||||||
|
|
||||||
|
if (me->IsInEvadeMode())
|
||||||
|
return;
|
||||||
|
|
||||||
Creature* narjil = instance->GetCreature(DATA_NARJIL);
|
Creature* narjil = instance->GetCreature(DATA_NARJIL);
|
||||||
Creature* gashra = instance->GetCreature(DATA_GASHRA);
|
Creature* gashra = instance->GetCreature(DATA_GASHRA);
|
||||||
@@ -117,6 +117,9 @@ public:
|
|||||||
|
|
||||||
void DoAction(int32 actionId) override
|
void DoAction(int32 actionId) override
|
||||||
{
|
{
|
||||||
|
if (actionId == ACTION_MINION_ENGAGED)
|
||||||
|
++_minionsEngaged;
|
||||||
|
|
||||||
if (actionId == ACTION_MINION_ENGAGED && !_minionInCombat)
|
if (actionId == ACTION_MINION_ENGAGED && !_minionInCombat)
|
||||||
{
|
{
|
||||||
_minionInCombat = true;
|
_minionInCombat = true;
|
||||||
@@ -124,20 +127,46 @@ public:
|
|||||||
Talk(SAY_SEND_GROUP, 10s);
|
Talk(SAY_SEND_GROUP, 10s);
|
||||||
|
|
||||||
for (Seconds const& timer : { 60s, 120s })
|
for (Seconds const& timer : { 60s, 120s })
|
||||||
{
|
CallWatcher(timer);
|
||||||
me->m_Events.AddEventAtOffset([this] {
|
|
||||||
Talk(SAY_SEND_GROUP);
|
|
||||||
|
|
||||||
me->m_Events.AddEventAtOffset([this] {
|
|
||||||
me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true);
|
|
||||||
}, 5s);
|
|
||||||
}, timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
me->m_Events.AddEventAtOffset([this] {
|
me->m_Events.AddEventAtOffset([this] {
|
||||||
me->SetInCombatWithZone();
|
me->SetInCombatWithZone();
|
||||||
}, IsHeroic() ? 200s : 180s);
|
}, IsHeroic() ? 200s : 180s);
|
||||||
}
|
}
|
||||||
|
else if (actionId == ACTION_MINION_DIED)
|
||||||
|
{
|
||||||
|
me->m_Events.CancelEventGroup(GROUP_WATCHERS);
|
||||||
|
|
||||||
|
// Check if any of the watchers is alive
|
||||||
|
if (!me->FindNearestCreature(NPC_WATCHER_SILTHIK, 100.0f) &&
|
||||||
|
!me->FindNearestCreature(NPC_WATCHER_NARJIL, 100.0f) &&
|
||||||
|
!me->FindNearestCreature(NPC_WATCHER_GASHRA, 100.0f))
|
||||||
|
return;
|
||||||
|
|
||||||
|
me->m_Events.AddEventAtOffset([this] {
|
||||||
|
SummonWatcher();
|
||||||
|
}, 5s, GROUP_WATCHERS);
|
||||||
|
|
||||||
|
// Schedule the next (10s + 60s)
|
||||||
|
CallWatcher(70s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallWatcher(Seconds timer)
|
||||||
|
{
|
||||||
|
me->m_Events.AddEventAtOffset([this] {
|
||||||
|
_firstCall = false;
|
||||||
|
Talk(SAY_SEND_GROUP);
|
||||||
|
SummonWatcher();
|
||||||
|
}, timer, GROUP_WATCHERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SummonWatcher()
|
||||||
|
{
|
||||||
|
me->m_Events.AddEventAtOffset([this] {
|
||||||
|
me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true);
|
||||||
|
_firstCall = false;
|
||||||
|
}, 5s, GROUP_WATCHERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetData(uint32 data) const override
|
uint32 GetData(uint32 data) const override
|
||||||
@@ -182,7 +211,26 @@ public:
|
|||||||
DoCastRandomTarget(SPELL_CURSE_OF_FATIGUE);
|
DoCastRandomTarget(SPELL_CURSE_OF_FATIGUE);
|
||||||
}, 27s, 35s);
|
}, 27s, 35s);
|
||||||
|
|
||||||
summons.DoZoneInCombat();
|
if (Creature* narjil = instance->GetCreature(DATA_NARJIL))
|
||||||
|
narjil->SetInCombatWithZone();
|
||||||
|
|
||||||
|
if (Creature* gashra = instance->GetCreature(DATA_GASHRA))
|
||||||
|
gashra->SetInCombatWithZone();
|
||||||
|
|
||||||
|
if (Creature* silthik = instance->GetCreature(DATA_SILTHIK))
|
||||||
|
silthik->SetInCombatWithZone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
|
||||||
|
{
|
||||||
|
if (spellInfo->Id == SPELL_SUBBOSS_AGGRO_TRIGGER)
|
||||||
|
{
|
||||||
|
if (_minionsEngaged == 2 && _firstCall)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Creature* creature = target->ToCreature())
|
||||||
|
creature->SetInCombatWithZone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* killer) override
|
void JustDied(Unit* killer) override
|
||||||
@@ -212,6 +260,8 @@ public:
|
|||||||
bool _initTalk;
|
bool _initTalk;
|
||||||
bool _canTalk;
|
bool _canTalk;
|
||||||
bool _minionInCombat;
|
bool _minionInCombat;
|
||||||
|
uint8 _minionsEngaged;
|
||||||
|
bool _firstCall;
|
||||||
|
|
||||||
[[nodiscard]] bool IsInFrenzy() const { return me->HasAura(SPELL_FRENZY); }
|
[[nodiscard]] bool IsInFrenzy() const { return me->HasAura(SPELL_FRENZY); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AreaBoundary.h"
|
#include "AreaBoundary.h"
|
||||||
|
#include "CreatureGroups.h"
|
||||||
#include "CreatureScript.h"
|
#include "CreatureScript.h"
|
||||||
#include "InstanceMapScript.h"
|
#include "InstanceMapScript.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
@@ -80,9 +81,59 @@ public:
|
|||||||
|
|
||||||
void OnCreatureEvade(Creature* creature) override
|
void OnCreatureEvade(Creature* creature) override
|
||||||
{
|
{
|
||||||
if (creature->EntryEquals(NPC_WATCHER_NARJIL, NPC_WATCHER_GASHRA, NPC_WATCHER_SILTHIK))
|
switch (creature->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_WATCHER_NARJIL:
|
||||||
|
case NPC_WATCHER_GASHRA:
|
||||||
|
case NPC_WATCHER_SILTHIK:
|
||||||
if (Creature* krikthir = GetCreature(DATA_KRIKTHIR))
|
if (Creature* krikthir = GetCreature(DATA_KRIKTHIR))
|
||||||
krikthir->AI()->EnterEvadeMode();
|
krikthir->AI()->EnterEvadeMode();
|
||||||
|
break;
|
||||||
|
case NPC_ANUBAR_SHADOWCASTER:
|
||||||
|
case NPC_ANUBAR_SKIRMISHER:
|
||||||
|
case NPC_ANUBAR_WARRIOR:
|
||||||
|
if (CreatureGroup* formation = creature->GetFormation())
|
||||||
|
if (Creature* leader = formation->GetLeader())
|
||||||
|
if (leader->EntryEquals(NPC_WATCHER_GASHRA, NPC_WATCHER_NARJIL, NPC_WATCHER_SILTHIK))
|
||||||
|
if (Creature* krikthir = GetCreature(DATA_KRIKTHIR))
|
||||||
|
krikthir->AI()->EnterEvadeMode();
|
||||||
|
break;
|
||||||
|
case NPC_KRIKTHIR_THE_GATEWATCHER:
|
||||||
|
if (Creature* narjil = GetCreature(DATA_NARJIL))
|
||||||
|
if (CreatureGroup* formation = narjil->GetFormation())
|
||||||
|
formation->DespawnFormation(0s, 20s);
|
||||||
|
|
||||||
|
if (Creature* gashra = GetCreature(DATA_GASHRA))
|
||||||
|
if (CreatureGroup* formation = gashra->GetFormation())
|
||||||
|
formation->DespawnFormation(0s, 20s);
|
||||||
|
|
||||||
|
if (Creature* silthik = GetCreature(DATA_SILTHIK))
|
||||||
|
if (CreatureGroup* formation = silthik->GetFormation())
|
||||||
|
formation->DespawnFormation(0s, 20s);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUnitDeath(Unit* unit) override
|
||||||
|
{
|
||||||
|
if (unit->EntryEquals(NPC_WATCHER_GASHRA, NPC_WATCHER_NARJIL, NPC_WATCHER_SILTHIK, NPC_ANUBAR_SHADOWCASTER, NPC_ANUBAR_SKIRMISHER, NPC_ANUBAR_WARRIOR))
|
||||||
|
{
|
||||||
|
if (Creature* creature = unit->ToCreature())
|
||||||
|
{
|
||||||
|
ObjectGuid creatureGuid = creature->GetGUID();
|
||||||
|
scheduler.CancelAll();
|
||||||
|
scheduler.Schedule(1s, [this, creatureGuid](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
if (Creature* creature = instance->GetCreature(creatureGuid))
|
||||||
|
if (CreatureGroup* formation = creature->GetFormation())
|
||||||
|
if (!formation->IsAnyMemberAlive())
|
||||||
|
if (Creature* krikthir = GetCreature(DATA_KRIKTHIR))
|
||||||
|
krikthir->AI()->DoAction(ACTION_MINION_DIED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user