aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2025-07-22 22:26:15 +0300
committerGitHub <noreply@github.com>2025-07-22 21:26:15 +0200
commit4dece3fe4efb06661083bfd565976ed61e4ed7b3 (patch)
tree9ad5658f13ce0e35c5b8f946eabe3802f8673e49 /src
parentcfa9fb701a7d5ec14750f55d1fa30247e8c0def9 (diff)
Scripts/Arcatraz: Rewrite Mellichar's event (#31081)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/SpellMgr.cpp9
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp898
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.h19
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp87
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp67
5 files changed, 623 insertions, 457 deletions
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index f5bd8748a44..5dd878fdddb 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3519,6 +3519,15 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->_GetEffect(EFFECT_0).RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_150_YARDS); // 150yd
});
+ // Radius in DBC is not enough
+ ApplySpellFix({
+ 36854, // Channel
+ 36856 // Channel
+ }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd
+ });
+
// Master Shapeshifter: missing stance data for forms other than bear - bear version has correct data
// To prevent aura staying on target after talent unlearned
ApplySpellFix({ 48420 }, [](SpellInfo* spellInfo)
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
index 765d655a6c9..4ec8b22c8a5 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
@@ -15,485 +15,669 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Arcatraz
-SD%Complete: 60
-SDComment: Warden Mellichar, event controller for Skyriss event. Millhouse Manastorm. @todo make better combatAI for Millhouse.
-SDCategory: Tempest Keep, The Arcatraz
-EndScriptData */
-
-/* ContentData
-npc_millhouse_manastorm
-npc_warden_mellichar
-EndContentData */
+/*
+ * The way Mellichar's event is reset requires additional research
+ */
#include "ScriptMgr.h"
#include "arcatraz.h"
#include "InstanceScript.h"
#include "MotionMaster.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
-/*#####
-# npc_millhouse_manastorm
-#####*/
-
-enum MillhouseSays
+enum MillhouseTexts
{
SAY_INTRO_1 = 0,
SAY_INTRO_2 = 1,
- SAY_WATER = 2,
- SAY_BUFFS = 3,
- SAY_DRINK = 4,
- SAY_READY = 5,
- SAY_KILL = 6,
- SAY_PYRO = 7,
- SAY_ICEBLOCK = 8,
- SAY_LOWHP = 9,
- SAY_DEATH = 10,
- SAY_COMPLETE = 11,
+ SAY_INTRO_3 = 2,
+ SAY_INTRO_4 = 3,
+ SAY_WATER = 4,
+ SAY_BUFFS = 5,
+ SAY_DRINK = 6,
+ SAY_READY = 7,
+ SAY_SLAY = 8,
+ SAY_PYRO = 9,
+ SAY_ICEBLOCK = 10,
+ SAY_LOWHP = 11,
+ SAY_DEATH = 12,
+ SAY_COMPLETE = 13
};
enum MillhouseSpells
{
+ SPELL_SIMPLE_TELEPORT = 12980,
SPELL_CONJURE_WATER = 36879,
SPELL_ARCANE_INTELLECT = 36880,
SPELL_ICE_ARMOR = 36881,
- SPELL_ARCANE_MISSILES = 33833,
- SPELL_CONE_OF_COLD = 12611,
- SPELL_FIRE_BLAST = 13341,
+ SPELL_DRINK = 30024,
+
SPELL_FIREBALL = 14034,
SPELL_FROSTBOLT = 15497,
+ SPELL_ARCANE_MISSILES = 33832,
+ SPELL_CONE_OF_COLD = 12611,
+ SPELL_FIRE_BLAST = 13341,
SPELL_PYROBLAST = 33975,
+ SPELL_ICE_BLOCK = 36911
+};
+
+enum MillhouseEvents
+{
+ EVENT_INTRO_1 = 1,
+ EVENT_INTRO_2,
+ EVENT_INTRO_3,
+ EVENT_INTRO_4,
+ EVENT_INTRO_5,
+ EVENT_INTRO_6,
+ EVENT_INTRO_7,
+ EVENT_INTRO_8,
+ EVENT_INTRO_9,
+ EVENT_INTRO_10,
+ EVENT_INTRO_11,
+ EVENT_INTRO_12,
+
+ EVENT_MAIN_SPELL,
+ EVENT_ARCANE_MISSILES,
+ EVENT_CONE_OF_COLD,
+ EVENT_FIRE_BLAST,
+ EVENT_PYROBLAST,
+ EVENT_ICE_BLOCK,
+ EVENT_LOW_HEALTH
};
+enum MillhouseMisc
+{
+ POINT_CENTER = 1
+};
+
+Position const CenterPos = { 445.88043f, -158.70554f, 43.068977f, 0.0f };
+
+// 20977 - Millhouse Manastorm
struct npc_millhouse_manastorm : public ScriptedAI
{
- npc_millhouse_manastorm(Creature* creature) : ScriptedAI(creature), Init(false)
+ npc_millhouse_manastorm(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript()), _lowHealth(false), _hasIceBlock(false) { }
+
+ void JustAppeared() override
{
- Initialize();
- instance = creature->GetInstanceScript();
+ me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
+ _events.ScheduleEvent(EVENT_INTRO_1, 0s);
}
- void Initialize()
+ void Reset() override
{
- EventProgress_Timer = 2000;
- LowHp = false;
- Phase = 1;
+ _events.Reset();
+ _lowHealth = false;
+ _hasIceBlock = false;
- Pyroblast_Timer = 1000;
- Fireball_Timer = 2500;
+ if (_instance->GetBossState(DATA_HARBINGER_SKYRISS) == DONE)
+ {
+ Talk(SAY_COMPLETE);
+ me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
+ }
}
- InstanceScript* instance;
-
- uint32 EventProgress_Timer;
- uint32 Phase;
- bool Init;
- bool LowHp;
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_MAIN_SPELL, 0s);
+ _events.ScheduleEvent(EVENT_ARCANE_MISSILES, 10s, 20s);
+ _events.ScheduleEvent(EVENT_CONE_OF_COLD, 15s, 25s);
+ _events.ScheduleEvent(EVENT_FIRE_BLAST, 20s, 30s);
+ _events.ScheduleEvent(EVENT_PYROBLAST, 30s, 45s);
+ }
- uint32 Pyroblast_Timer;
- uint32 Fireball_Timer;
+ void AttackStart(Unit* who) override
+ {
+ ScriptedAI::AttackStartCaster(who, 30.0f);
+ }
- void Reset() override
+ void MovementInform(uint32 type, uint32 pointId) override
{
- Initialize();
+ if (type != POINT_MOTION_TYPE)
+ return;
- if (instance->GetData(DATA_WARDEN_2) == DONE)
+ if (pointId == POINT_CENTER)
+ _events.ScheduleEvent(EVENT_INTRO_12, 0s);
+ }
+
+ void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!_lowHealth && me->HealthBelowPctDamaged(20, damage))
{
- Init = true;
- me->SetImmuneToNPC(false);
+ _lowHealth = true;
+ _events.ScheduleEvent(EVENT_LOW_HEALTH, 0s);
}
+ // Guessed, how this spell should be used?
+ if (!_hasIceBlock && me->HealthBelowPctDamaged(10, damage))
+ {
+ _hasIceBlock = true;
+ _events.ScheduleEvent(EVENT_ICE_BLOCK, 0s);
+ }
+ }
- if (instance->GetBossState(DATA_HARBINGER_SKYRISS) == DONE)
- Talk(SAY_COMPLETE);
+ void OnSpellStart(SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_PYROBLAST)
+ Talk(SAY_PYRO);
}
- void AttackStart(Unit* who) override
+ void OnSpellCast(SpellInfo const* spell) override
{
- if (me->Attack(who, true))
- {
- AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- me->GetMotionMaster()->MoveChase(who, 25.0f);
- }
+ if (spell->Id == SPELL_ICE_BLOCK)
+ Talk(SAY_ICEBLOCK);
}
- void KilledUnit(Unit* who) override
+ void KilledUnit(Unit* /*who*/) override
{
- if (who->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KILL);
+ Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
-
- /*for questId 10886 (heroic mode only)
- if (instance->GetBossState(DATA_HARBINGER_SKYRISS) != DONE)
- ->FailQuest();*/
}
void UpdateAI(uint32 diff) override
{
- if (!Init)
+ if (!UpdateVictim())
{
- if (EventProgress_Timer <= diff)
- {
- if (Phase < 8)
- {
- switch (Phase)
- {
- case 1:
- Talk(SAY_INTRO_1);
- EventProgress_Timer = 18000;
- break;
- case 2:
- Talk(SAY_INTRO_2);
- EventProgress_Timer = 18000;
- break;
- case 3:
- Talk(SAY_WATER);
- DoCast(me, SPELL_CONJURE_WATER);
- EventProgress_Timer = 7000;
- break;
- case 4:
- Talk(SAY_BUFFS);
- DoCast(me, SPELL_ICE_ARMOR);
- EventProgress_Timer = 7000;
- break;
- case 5:
- Talk(SAY_DRINK);
- DoCast(me, SPELL_ARCANE_INTELLECT);
- EventProgress_Timer = 7000;
- break;
- case 6:
- Talk(SAY_READY);
- EventProgress_Timer = 6000;
- break;
- case 7:
- instance->SetData(DATA_WARDEN_2, DONE);
- Init = true;
- me->SetImmuneToNPC(false);
- break;
- }
- ++Phase;
- }
- }
- else
- EventProgress_Timer -= diff;
+ UpdateIntroEvents(diff);
+ return;
}
- if (!UpdateVictim())
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- if (!LowHp && HealthBelowPct(20))
- {
- Talk(SAY_LOWHP);
- LowHp = true;
- }
- if (Pyroblast_Timer <= diff)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (me->IsNonMeleeSpellCast(false))
+ switch (eventId)
+ {
+ case EVENT_MAIN_SPELL:
+ DoCastVictim(RAND(SPELL_FIREBALL, SPELL_FROSTBOLT));
+ _events.Repeat(3s);
+ break;
+ case EVENT_ARCANE_MISSILES:
+ DoCastVictim(SPELL_ARCANE_MISSILES);
+ _events.Repeat(20s, 30s);
+ break;
+ case EVENT_CONE_OF_COLD:
+ DoCastSelf(SPELL_CONE_OF_COLD);
+ _events.Repeat(20s, 30s);
+ break;
+ case EVENT_FIRE_BLAST:
+ DoCastVictim(SPELL_FIRE_BLAST);
+ _events.Repeat(25s, 40s);
+ break;
+ case EVENT_PYROBLAST:
+ DoCastVictim(SPELL_PYROBLAST);
+ _events.Repeat(40s, 60s);
+ break;
+ case EVENT_ICE_BLOCK:
+ DoCastSelf(SPELL_ICE_BLOCK);
+ break;
+ case EVENT_LOW_HEALTH:
+ Talk(SAY_LOWHP);
+ break;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
+ }
- Talk(SAY_PYRO);
+ DoMeleeAttackIfReady();
+ }
- DoCastVictim(SPELL_PYROBLAST);
- Pyroblast_Timer = 40000;
- }
- else
- Pyroblast_Timer -=diff;
+ void UpdateIntroEvents(uint32 diff)
+ {
+ _events.Update(diff);
- if (Fireball_Timer <= diff)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- DoCastVictim(SPELL_FIREBALL);
- Fireball_Timer = 4000;
+ switch (eventId)
+ {
+ case EVENT_INTRO_1:
+ DoCastSelf(SPELL_SIMPLE_TELEPORT);
+ _events.ScheduleEvent(EVENT_INTRO_2, 2s);
+ break;
+ case EVENT_INTRO_2:
+ Talk(SAY_INTRO_1);
+ _events.ScheduleEvent(EVENT_INTRO_3, 4s + 500ms);
+ break;
+ case EVENT_INTRO_3:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ _events.ScheduleEvent(EVENT_INTRO_4, 14s);
+ break;
+ case EVENT_INTRO_4:
+ if (Creature* mellichar = _instance->GetCreature(DATA_MELLICHAR))
+ me->SetFacingToObject(mellichar);
+ Talk(SAY_INTRO_2);
+ _events.ScheduleEvent(EVENT_INTRO_5, 9s);
+ break;
+ case EVENT_INTRO_5:
+ Talk(SAY_INTRO_3);
+ me->SetFacingTo(0.03490658476948738f);
+ _events.ScheduleEvent(EVENT_INTRO_6, 8s);
+ break;
+ case EVENT_INTRO_6:
+ if (Creature* mellichar = _instance->GetCreature(DATA_MELLICHAR))
+ me->SetFacingToObject(mellichar);
+ Talk(SAY_INTRO_4);
+ _events.ScheduleEvent(EVENT_INTRO_7, 5s);
+ break;
+ case EVENT_INTRO_7:
+ Talk(SAY_WATER);
+ DoCastSelf(SPELL_CONJURE_WATER);
+ _events.ScheduleEvent(EVENT_INTRO_8, 7s);
+ break;
+ case EVENT_INTRO_8:
+ Talk(SAY_BUFFS);
+ DoCastSelf(SPELL_ARCANE_INTELLECT);
+ _events.ScheduleEvent(EVENT_INTRO_9, 3s);
+ break;
+ case EVENT_INTRO_9:
+ DoCastSelf(SPELL_ICE_ARMOR);
+ _events.ScheduleEvent(EVENT_INTRO_10, 6s);
+ break;
+ case EVENT_INTRO_10:
+ Talk(SAY_DRINK);
+ DoCastSelf(SPELL_DRINK);
+ _events.ScheduleEvent(EVENT_INTRO_11, 6s);
+ break;
+ case EVENT_INTRO_11:
+ Talk(SAY_READY);
+ // Clear stand state from Drink spell manually, otherwise it will be not cleared
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->GetMotionMaster()->MovePoint(POINT_CENTER, CenterPos);
+ break;
+ case EVENT_INTRO_12:
+ if (Creature* mellichar = _instance->GetCreature(DATA_MELLICHAR))
+ me->SetFacingToObject(mellichar);
+ me->SetImmuneToAll(false);
+ me->SetHomePosition(me->GetPosition());
+ break;
+ default:
+ break;
+ }
}
- else
- Fireball_Timer -=diff;
-
- DoMeleeAttackIfReady();
}
-};
-/*#####
-# npc_warden_mellichar
-#####*/
-enum WardenSays
-{
- YELL_INTRO1 = 0,
- YELL_INTRO2 = 1,
- YELL_RELEASE1 = 2,
- YELL_RELEASE2A = 3,
- YELL_RELEASE2B = 4,
- YELL_RELEASE3 = 5,
- YELL_RELEASE4 = 6,
- YELL_WELCOME = 7,
+private:
+ EventMap _events;
+ InstanceScript* _instance;
+ bool _lowHealth;
+ bool _hasIceBlock;
};
-enum WardenUnits
+enum WardenTexts
{
- //phase 2(acid mobs)
- ENTRY_TRICKSTER = 20905,
- ENTRY_PH_HUNTER = 20906,
- //phase 3
- ENTRY_MILLHOUSE = 20977,
- //phase 4(acid mobs)
- ENTRY_AKKIRIS = 20908,
- ENTRY_SULFURON = 20909,
- //phase 5(acid mobs)
- ENTRY_TW_DRAK = 20910,
- ENTRY_BL_DRAK = 20911,
- //phase 6
- ENTRY_SKYRISS = 20912,
+ SAY_RELEASE_1 = 0,
+ SAY_RELEASE_2 = 1,
+ SAY_RELEASE_3 = 2,
+ SAY_RELEASE_4 = 3,
+ SAY_RELEASE_5 = 4,
+ SAY_RELEASE_6 = 5,
+ SAY_RELEASE_7 = 6,
+ SAY_RELEASE_8 = 7
};
enum WardenSpells
{
- //TARGET_SCRIPT
- SPELL_TARGET_ALPHA = 36856,
- SPELL_TARGET_BETA = 36854,
- SPELL_TARGET_DELTA = 36857,
- SPELL_TARGET_GAMMA = 36858,
- SPELL_TARGET_OMEGA = 36852,
- SPELL_BUBBLE_VISUAL = 36849,
+ SPELL_SEAL_SPHERE = 36849,
+ SPELL_TARGET_OMEGA = 36852,
+ SPELL_TARGET_ALPHA = 36854,
+ SPELL_TARGET_BETA = 36856,
+ SPELL_TARGET_DELTA = 36857,
+ SPELL_TARGET_GAMMA = 36858,
+ SPELL_QUIET_SUICIDE = 3617
};
-struct npc_warden_mellichar : public ScriptedAI
+enum WardenEvents
{
- npc_warden_mellichar(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- IsRunning = false;
- CanSpawn = false;
-
- EventProgress_Timer = 22000;
- Phase = 1;
- }
+ EVENT_MAIN_CHANNEL = 1,
+
+ EVENT_RELEASE_1_1,
+ EVENT_RELEASE_1_2,
+ EVENT_RELEASE_1_3,
+ EVENT_RELEASE_1_4,
+ EVENT_RELEASE_1_5,
+ EVENT_RELEASE_1_6,
+ EVENT_RELEASE_1_7,
+ EVENT_RELEASE_1_8,
+ EVENT_RELEASE_1_9,
+
+ EVENT_RELEASE_2_1,
+ EVENT_RELEASE_2_2,
+ EVENT_RELEASE_2_3,
+ EVENT_RELEASE_2_4,
+ EVENT_RELEASE_2_5,
+ EVENT_RELEASE_2_6,
+
+ EVENT_RELEASE_3_1,
+ EVENT_RELEASE_3_2,
+ EVENT_RELEASE_3_3,
+ EVENT_RELEASE_3_4,
+ EVENT_RELEASE_3_5,
+ EVENT_RELEASE_3_6,
+ EVENT_RELEASE_3_7,
+
+ EVENT_RELEASE_4_1,
+ EVENT_RELEASE_4_2,
+ EVENT_RELEASE_4_3,
+ EVENT_RELEASE_4_4,
+ EVENT_RELEASE_4_5,
+ EVENT_RELEASE_4_6,
+
+ EVENT_RELEASE_5_1,
+ EVENT_RELEASE_5_2,
+ EVENT_RELEASE_5_3,
+ EVENT_RELEASE_5_4,
+ EVENT_RELEASE_5_5
+};
- InstanceScript* instance;
+enum WardenCreatures
+{
+ // Prisoner 1
+ NPC_TRICKSTER = 20905,
+ NPC_PH_HUNTER = 20906,
+ // Prisoner 2
+ NPC_MILLHOUSE_M = 20977,
+ // Prisoner 3
+ NPC_AKKIRIS = 20908,
+ NPC_SULFURON = 20909,
+ // Prisoner 4
+ NPC_TW_DRAK = 20910,
+ NPC_BL_DRAK = 20911,
+ // Prisoner 5
+ NPC_SKYRISS = 20912
+};
- bool IsRunning;
- bool CanSpawn;
+Position const PrisonerSpawnPos[5] =
+{
+ { 472.231f, -150.860f, 42.6573f, 3.106690f },
+ { 417.242f, -149.795f, 42.6548f, 0.191986f },
+ { 420.851f, -174.337f, 42.6655f, 0.122173f },
+ { 470.364f, -174.656f, 42.6753f, 3.595380f },
+ { 446.086f, -182.506f, 44.0852f, 1.570800f }
+};
- uint32 EventProgress_Timer;
- uint32 Phase;
+// 20904 - Warden Mellichar
+struct npc_warden_mellichar : public ScriptedAI
+{
+ npc_warden_mellichar(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript()), _summons(me), _inProgress(false) { }
void Reset() override
{
- Initialize();
-
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- DoCast(me, SPELL_TARGET_OMEGA);
-
- instance->SetBossState(DATA_HARBINGER_SKYRISS, NOT_STARTED);
+ _events.Reset();
+ _summons.DespawnAll();
+ _events.ScheduleEvent(EVENT_MAIN_CHANNEL, 0s);
+ me->SetReactState(REACT_PASSIVE);
+
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_STASIS_POD_ALPHA));
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_STASIS_POD_BETA));
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_STASIS_POD_DELTA));
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_STASIS_POD_GAMMA));
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_STASIS_POD_OMEGA));
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_WARDENS_SHIELD));
+
+ if (_instance->GetBossState(DATA_HARBINGER_SKYRISS) == FAIL)
+ {
+ _instance->SetBossState(DATA_HARBINGER_SKYRISS, NOT_STARTED);
+ me->DespawnOrUnsummon(0s, 1min);
+ }
}
- void AttackStart(Unit* /*who*/) override { }
-
void MoveInLineOfSight(Unit* who) override
{
- if (IsRunning)
+ if (_inProgress)
return;
- if (!me->GetVictim() && me->CanCreatureAttack(who))
- {
- if (!me->CanFly() && me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
- if (who->GetTypeId() != TYPEID_PLAYER)
- return;
+ if (who->GetTypeId() != TYPEID_PLAYER || !who->IsWithinDist(me, INTERACTION_DISTANCE))
+ return;
- float attackRadius = me->GetAttackDistance(who)/10;
- if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
- JustEngagedWith(who);
- }
+ JustEngagedWith(who);
}
void JustEngagedWith(Unit* /*who*/) override
{
- Talk(YELL_INTRO1);
- DoCast(me, SPELL_BUBBLE_VISUAL);
+ if (_inProgress)
+ return;
- instance->SetBossState(DATA_HARBINGER_SKYRISS, IN_PROGRESS);
- instance->HandleGameObject(instance->GetGuidData(DATA_WARDENS_SHIELD), false);
- IsRunning = true;
+ _inProgress = true;
+ _events.ScheduleEvent(EVENT_RELEASE_1_1, 1s);
+ _instance->SetBossState(DATA_HARBINGER_SKYRISS, IN_PROGRESS);
}
- void JustSummoned(Creature* summon) override
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
- DoZoneInCombat(summon);
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
- summon->AI()->AttackStart(target);
+ if (spellInfo->Id == SPELL_SEAL_SPHERE)
+ _instance->HandleGameObject(ObjectGuid::Empty, false, _instance->GetGameObject(DATA_WARDENS_SHIELD));
}
- bool CanProgress()
+ void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
- if (Phase == 7 && instance->GetData(DATA_WARDEN_4) == DONE)
- return true;
- if (Phase == 6 && instance->GetData(DATA_WARDEN_3) == DONE)
- return true;
- if (Phase == 5 && instance->GetData(DATA_WARDEN_2) == DONE)
- return true;
- if (Phase == 4)
- return true;
- if (Phase == 3 && instance->GetData(DATA_WARDEN_1) == DONE)
- return true;
- if (Phase == 2 && instance->GetBossState(DATA_HARBINGER_SKYRISS) == IN_PROGRESS)
- return true;
- if (Phase == 1 && instance->GetBossState(DATA_HARBINGER_SKYRISS) == IN_PROGRESS)
- return true;
-
- return false;
+ // Creature is unkillable by default. But allow to kill self with Quiet Suicide spell
+ if (damage >= me->GetHealth() && who != me)
+ damage = me->GetHealth() -1;
}
- void DoPrepareForPhase()
+ void DoAction(int32 action) override
{
- me->InterruptNonMeleeSpells(true);
- me->RemoveAurasByType(SPELL_AURA_DUMMY);
+ if (action == ACTION_RESET_PRISON)
+ Reset();
+ }
- switch (Phase)
+ void JustSummoned(Creature* summon) override
+ {
+ _summons.Summon(summon);
+ DoZoneInCombat(summon);
+ }
+
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
+ {
+ // Not entirely correct. Next phase is started when prisoner is about to die, not when he's dead
+ switch (summon->GetEntry())
{
- case 2:
- DoCast(me, SPELL_TARGET_ALPHA);
- instance->SetData(DATA_WARDEN_1, IN_PROGRESS);
- instance->HandleGameObject(instance->GetGuidData(DATA_WARDENS_SHIELD), false);
- break;
- case 3:
- DoCast(me, SPELL_TARGET_BETA);
- instance->SetData(DATA_WARDEN_2, IN_PROGRESS);
+ case NPC_TRICKSTER:
+ case NPC_PH_HUNTER:
+ _events.ScheduleEvent(EVENT_RELEASE_2_1, 0s);
break;
- case 5:
- DoCast(me, SPELL_TARGET_DELTA);
- instance->SetData(DATA_WARDEN_3, IN_PROGRESS);
+ case NPC_AKKIRIS:
+ case NPC_SULFURON:
+ _events.ScheduleEvent(EVENT_RELEASE_4_1, 0s);
break;
- case 6:
- DoCast(me, SPELL_TARGET_GAMMA);
- instance->SetData(DATA_WARDEN_4, IN_PROGRESS);
+ case NPC_TW_DRAK:
+ case NPC_BL_DRAK:
+ _events.ScheduleEvent(EVENT_RELEASE_5_1, 0s);
break;
- case 7:
- instance->SetData(DATA_WARDEN_5, IN_PROGRESS);
+ default:
break;
}
- CanSpawn = true;
}
void UpdateAI(uint32 diff) override
{
- if (!IsRunning)
- return;
+ _events.Update(diff);
- if (EventProgress_Timer <= diff)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (instance->GetBossState(DATA_HARBINGER_SKYRISS) == FAIL)
+ switch (eventId)
{
- Reset();
- return;
- }
+ case EVENT_MAIN_CHANNEL:
+ DoCastSelf(SPELL_TARGET_OMEGA);
+ _events.Repeat(12s);
+ break;
- if (CanSpawn)
- {
- //continue beam omega pod, unless we are about to summon skyriss
- if (Phase != 7)
- DoCast(me, SPELL_TARGET_OMEGA);
-
- switch (Phase)
- {
- case 2:
- switch (urand(0, 1))
- {
- case 0:
- me->SummonCreature(ENTRY_TRICKSTER, 472.231f, -150.86f, 42.6573f, 3.10669f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- case 1:
- me->SummonCreature(ENTRY_PH_HUNTER, 472.231f, -150.86f, 42.6573f, 3.10669f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- }
- break;
- case 3:
- me->SummonCreature(ENTRY_MILLHOUSE, 417.242f, -149.795f, 42.6548f, 0.191986f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // static pos
- break;
- case 4:
- Talk(YELL_RELEASE2B);
- break;
- case 5:
- switch (urand(0, 1))
- {
- case 0:
- me->SummonCreature(ENTRY_AKKIRIS, 420.851f, -174.337f, 42.6655f, 0.122173f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- case 1:
- me->SummonCreature(ENTRY_SULFURON, 420.851f, -174.337f, 42.6655f, 0.122173f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- }
- break;
- case 6:
- switch (urand(0, 1))
- {
- case 0:
- me->SummonCreature(ENTRY_TW_DRAK, 470.364f, -174.656f, 42.6753f, 3.59538f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- case 1:
- me->SummonCreature(ENTRY_BL_DRAK, 470.364f, -174.656f, 42.6753f, 3.59538f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // random pos
- break;
- }
- break;
- case 7:
- me->SummonCreature(ENTRY_SKYRISS, 446.086f, -182.506f, 44.0852f, 1.5708f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10min); // static pos
- Talk(YELL_WELCOME);
- break;
- }
- CanSpawn = false;
- ++Phase;
- }
- if (CanProgress())
- {
- switch (Phase)
- {
- case 1:
- Talk(YELL_INTRO2);
- EventProgress_Timer = 10000;
- ++Phase;
- break;
- case 2:
- Talk(YELL_RELEASE1);
- DoPrepareForPhase();
- EventProgress_Timer = 7000;
- break;
- case 3:
- Talk(YELL_RELEASE2A);
- DoPrepareForPhase();
- EventProgress_Timer = 10000;
- break;
- case 4:
- DoPrepareForPhase();
- EventProgress_Timer = 15000;
- break;
- case 5:
- Talk(YELL_RELEASE3);
- DoPrepareForPhase();
- EventProgress_Timer = 15000;
- break;
- case 6:
- Talk(YELL_RELEASE4);
- DoPrepareForPhase();
- EventProgress_Timer = 15000;
- break;
- case 7:
- DoPrepareForPhase();
- EventProgress_Timer = 15000;
- break;
- }
+ case EVENT_RELEASE_1_1:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAurasDueToSpell(SPELL_TARGET_OMEGA);
+ me->SetImmuneToPC(true);
+ _events.CancelEvent(EVENT_MAIN_CHANNEL);
+ _events.ScheduleEvent(EVENT_RELEASE_1_2, 2s);
+ break;
+ case EVENT_RELEASE_1_2:
+ me->SetFacingTo(1.605702877044677734f);
+ // Apparently casting this spell makes him reset orientation to default
+ DoCastSelf(SPELL_SEAL_SPHERE);
+ Talk(SAY_RELEASE_1);
+ _events.ScheduleEvent(EVENT_RELEASE_1_3, 23s);
+ break;
+ case EVENT_RELEASE_1_3:
+ Talk(SAY_RELEASE_2);
+ _events.ScheduleEvent(EVENT_RELEASE_1_4, 2s);
+ break;
+ case EVENT_RELEASE_1_4:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ _events.ScheduleEvent(EVENT_RELEASE_1_5, 2s);
+ break;
+ case EVENT_RELEASE_1_5:
+ DoCastSelf(SPELL_TARGET_ALPHA);
+ _events.ScheduleEvent(EVENT_RELEASE_1_6, 4s);
+ break;
+ case EVENT_RELEASE_1_6:
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_STASIS_POD_ALPHA));
+ _events.ScheduleEvent(EVENT_RELEASE_1_7, 2s);
+ break;
+ case EVENT_RELEASE_1_7:
+ me->SetFacingTo(4.747295379638671875f);
+ _events.ScheduleEvent(EVENT_RELEASE_1_8, 2s);
+ break;
+ case EVENT_RELEASE_1_8:
+ _events.ScheduleEvent(EVENT_MAIN_CHANNEL, 0s);
+ _events.ScheduleEvent(EVENT_RELEASE_1_9, 6s);
+ break;
+ case EVENT_RELEASE_1_9:
+ me->SummonCreature(RAND(NPC_TRICKSTER, NPC_PH_HUNTER), PrisonerSpawnPos[0], TEMPSUMMON_MANUAL_DESPAWN);
+ break;
+
+ case EVENT_RELEASE_2_1:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAurasDueToSpell(SPELL_TARGET_OMEGA);
+ me->SetFacingTo(1.675516128540039062f);
+ Talk(SAY_RELEASE_3);
+ _events.CancelEvent(EVENT_MAIN_CHANNEL);
+ _events.ScheduleEvent(EVENT_RELEASE_2_2, 5s);
+ break;
+ case EVENT_RELEASE_2_2:
+ DoCastSelf(SPELL_TARGET_BETA);
+ _events.ScheduleEvent(EVENT_RELEASE_2_3, 3s);
+ break;
+ case EVENT_RELEASE_2_3:
+ me->SetFacingTo(4.747295379638671875f);
+ Talk(SAY_RELEASE_4);
+ _events.ScheduleEvent(EVENT_RELEASE_2_4, 1s);
+ break;
+ case EVENT_RELEASE_2_4:
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_STASIS_POD_BETA));
+ _events.ScheduleEvent(EVENT_RELEASE_2_5, 1s);
+ break;
+ case EVENT_RELEASE_2_5:
+ _events.ScheduleEvent(EVENT_MAIN_CHANNEL, 0s);
+ _events.ScheduleEvent(EVENT_RELEASE_2_6, 7s);
+ break;
+ case EVENT_RELEASE_2_6:
+ me->SummonCreature(NPC_MILLHOUSE_M, PrisonerSpawnPos[1], TEMPSUMMON_MANUAL_DESPAWN);
+ _events.ScheduleEvent(EVENT_RELEASE_3_1, 12s);
+ break;
+
+ case EVENT_RELEASE_3_1:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAurasDueToSpell(SPELL_TARGET_OMEGA);
+ _events.CancelEvent(EVENT_MAIN_CHANNEL);
+ _events.ScheduleEvent(EVENT_RELEASE_3_2, 2s);
+ break;
+ case EVENT_RELEASE_3_2:
+ me->SetFacingTo(2.478367567062377929f);
+ Talk(SAY_RELEASE_5);
+ _events.ScheduleEvent(EVENT_RELEASE_3_3, 6s);
+ break;
+ case EVENT_RELEASE_3_3:
+ DoCastSelf(SPELL_TARGET_DELTA);
+ _events.ScheduleEvent(EVENT_RELEASE_3_4, 3s);
+ break;
+ case EVENT_RELEASE_3_4:
+ me->SetFacingTo(4.747295379638671875f);
+ _events.ScheduleEvent(EVENT_RELEASE_3_5, 1s);
+ break;
+ case EVENT_RELEASE_3_5:
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_STASIS_POD_DELTA));
+ _events.ScheduleEvent(EVENT_RELEASE_3_6, 4s);
+ break;
+ case EVENT_RELEASE_3_6:
+ _events.ScheduleEvent(EVENT_MAIN_CHANNEL, 0s);
+ _events.ScheduleEvent(EVENT_RELEASE_3_7, 4s);
+ break;
+ case EVENT_RELEASE_3_7:
+ me->SummonCreature(RAND(NPC_AKKIRIS, NPC_SULFURON), PrisonerSpawnPos[2], TEMPSUMMON_MANUAL_DESPAWN);
+ break;
+
+ case EVENT_RELEASE_4_1:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAurasDueToSpell(SPELL_TARGET_OMEGA);
+ me->SetFacingTo(6.056292533874511718f);
+ Talk(SAY_RELEASE_6);
+ _events.CancelEvent(EVENT_MAIN_CHANNEL);
+ _events.ScheduleEvent(EVENT_RELEASE_4_2, 5s);
+ break;
+ case EVENT_RELEASE_4_2:
+ DoCastSelf(SPELL_TARGET_GAMMA);
+ _events.ScheduleEvent(EVENT_RELEASE_4_3, 2s);
+ break;
+ case EVENT_RELEASE_4_3:
+ me->SetFacingTo(4.747295379638671875f);
+ _events.ScheduleEvent(EVENT_RELEASE_4_4, 1s);
+ break;
+ case EVENT_RELEASE_4_4:
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_STASIS_POD_GAMMA));
+ _events.ScheduleEvent(EVENT_RELEASE_4_5, 2s);
+ break;
+ case EVENT_RELEASE_4_5:
+ _events.ScheduleEvent(EVENT_MAIN_CHANNEL, 0s);
+ _events.ScheduleEvent(EVENT_RELEASE_4_6, 7s);
+ break;
+ case EVENT_RELEASE_4_6:
+ me->SummonCreature(RAND(NPC_TW_DRAK, NPC_BL_DRAK), PrisonerSpawnPos[3], TEMPSUMMON_MANUAL_DESPAWN);
+ break;
+
+ case EVENT_RELEASE_5_1:
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAurasDueToSpell(SPELL_TARGET_OMEGA);
+ Talk(SAY_RELEASE_7);
+ _events.CancelEvent(EVENT_MAIN_CHANNEL);
+ _events.ScheduleEvent(EVENT_RELEASE_5_2, 1s);
+ break;
+ case EVENT_RELEASE_5_2:
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_STASIS_POD_OMEGA));
+ _events.ScheduleEvent(EVENT_RELEASE_5_3, 10s);
+ break;
+ case EVENT_RELEASE_5_3:
+ me->SummonCreature(NPC_SKYRISS, PrisonerSpawnPos[4], TEMPSUMMON_MANUAL_DESPAWN);
+ _events.ScheduleEvent(EVENT_RELEASE_5_4, 24s);
+ break;
+ case EVENT_RELEASE_5_4:
+ Talk(SAY_RELEASE_8);
+ _events.ScheduleEvent(EVENT_RELEASE_5_5, 7s);
+ break;
+ case EVENT_RELEASE_5_5:
+ DoCastSelf(SPELL_QUIET_SUICIDE);
+ _instance->HandleGameObject(ObjectGuid::Empty, true, _instance->GetGameObject(DATA_WARDENS_SHIELD));
+ me->DespawnOrUnsummon(18s);
+ break;
+ default:
+ break;
}
}
- else
- EventProgress_Timer -= diff;
}
+
+private:
+ InstanceScript* _instance;
+ EventMap _events;
+ SummonList _summons;
+ bool _inProgress;
};
void AddSC_arcatraz()
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.h b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.h
index 9e30c8bb381..a6ef0631565 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.h
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.h
@@ -31,7 +31,7 @@ enum AZDataTypes
DATA_ZEREKETH = 0,
DATA_DALLIAH = 1,
DATA_SOCCOTHRATES = 2,
- DATA_HARBINGER_SKYRISS = 3,
+ DATA_HARBINGER_SKYRISS = 3, // used by SmartAI
// Additional Data
DATA_CONVERSATION = 4,
@@ -40,16 +40,20 @@ enum AZDataTypes
DATA_WARDEN_3 = 7, // used by SmartAI
DATA_WARDEN_4 = 8, // used by SmartAI
DATA_WARDEN_5 = 9, // used by SmartAI
- DATA_MELLICHAR = 10,
- DATA_WARDENS_SHIELD = 11
+ DATA_MELLICHAR,
+ DATA_WARDENS_SHIELD,
+ DATA_STASIS_POD_ALPHA,
+ DATA_STASIS_POD_BETA,
+ DATA_STASIS_POD_DELTA,
+ DATA_STASIS_POD_GAMMA,
+ DATA_STASIS_POD_OMEGA
};
enum AZCreatureIds
{
NPC_DALLIAH = 20885,
NPC_SOCCOTHRATES = 20886,
- NPC_MELLICHAR = 20904, // skyriss will kill this unit
- NPC_ALPHA_POD_TARGET = 21436,
+ NPC_MELLICHAR = 20904,
NPC_MILLHOUSE = 20977
};
@@ -70,6 +74,11 @@ enum AZSpellIds
SPELL_QID_10886 = 39564
};
+enum AZMisc
+{
+ ACTION_RESET_PRISON = 1
+};
+
template <class AI, class T>
inline AI* GetArcatrazAI(T* obj)
{
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp
index 2dcad062e32..9c75c590f6d 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp
@@ -15,8 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Need more docs on how event fully work. Reset all event and force start over if fail at one point? */
-
#include "ScriptMgr.h"
#include "SpellInfo.h"
#include "SpellScript.h"
@@ -29,7 +27,7 @@ enum SkyrissTexts
{
SAY_INTRO = 0,
SAY_AGGRO = 1,
- SAY_KILL = 2,
+ SAY_SLAY = 2,
SAY_MIND = 3,
SAY_FEAR = 4,
SAY_IMAGE = 5,
@@ -50,7 +48,7 @@ enum SkyrissSpells
SPELL_SUMMON_66_ILLUSION = 36931,
SPELL_SUMMON_33_ILLUSION = 36932,
-
+ // Illusion
SPELL_BIRTH = 26262,
SPELL_BLINK_VISUAL = 36937,
SPELL_66_HEALTH = 36928,
@@ -66,7 +64,11 @@ enum SkyrissEvents
EVENT_DOMINATION,
EVENT_MANA_BURN,
EVENT_SUMMON_66,
- EVENT_SUMMON_33
+ EVENT_SUMMON_33,
+
+ EVENT_INTRO_1,
+ EVENT_INTRO_2,
+ EVENT_INTRO_3
};
enum SkyrissMisc
@@ -85,25 +87,17 @@ enum SkyrissPhases : uint8
// 20912 - Harbinger Skyriss
struct boss_harbinger_skyriss : public BossAI
{
- boss_harbinger_skyriss(Creature* creature) : BossAI(creature, DATA_HARBINGER_SKYRISS), _intro(false), _phase(PHASE_NONE) { }
+ boss_harbinger_skyriss(Creature* creature) : BossAI(creature, DATA_HARBINGER_SKYRISS), _phase(PHASE_NONE) { }
- void Initialize()
+ void JustAppeared() override
{
- Intro_Phase = 1;
- Intro_Timer = 5000;
+ events.ScheduleEvent(EVENT_INTRO_1, 0s);
}
- uint32 Intro_Phase;
- uint32 Intro_Timer;
-
void Reset() override
{
- DoCastSelf(SPELL_SIMPLE_TELEPORT);
_Reset();
- _intro = false;
_phase = PHASE_NONE;
- me->SetImmuneToAll(!_intro);
- Initialize();
}
void JustEngagedWith(Unit* who) override
@@ -132,13 +126,9 @@ struct boss_harbinger_skyriss : public BossAI
}
}
- void KilledUnit(Unit* victim) override
+ void KilledUnit(Unit* /*victim*/) override
{
- // Won't yell killing pet/other unit
- if (victim->GetEntry() == NPC_ALPHA_POD_TARGET)
- return;
-
- Talk(SAY_KILL);
+ Talk(SAY_SLAY);
}
void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
@@ -163,42 +153,34 @@ struct boss_harbinger_skyriss : public BossAI
void UpdateAI(uint32 diff) override
{
- if (!_intro)
+ if (!UpdateVictim())
{
- if (Intro_Timer <= diff)
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- switch (Intro_Phase)
+ switch (eventId)
{
- case 1:
- Talk(SAY_INTRO);
- instance->HandleGameObject(instance->GetGuidData(DATA_WARDENS_SHIELD), true);
- ++Intro_Phase;
- Intro_Timer = 25000;
- break;
- case 2:
- Talk(SAY_AGGRO);
- if (Unit* mellic = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MELLICHAR)))
- {
- //should have a better way to do this. possibly spell exist.
- mellic->setDeathState(JUST_DIED);
- mellic->SetHealth(0);
- instance->HandleGameObject(instance->GetGuidData(DATA_WARDENS_SHIELD), false);
- }
- ++Intro_Phase;
- Intro_Timer = 3000;
- break;
- case 3:
- me->SetImmuneToAll(false);
- _intro = true;
- break;
+ case EVENT_INTRO_1:
+ Talk(SAY_INTRO);
+ DoCastSelf(SPELL_SIMPLE_TELEPORT);
+ events.ScheduleEvent(EVENT_INTRO_2, 30s);
+ break;
+ case EVENT_INTRO_2:
+ Talk(SAY_AGGRO);
+ DoCastSelf(SPELL_MIND_REND_COSMETIC);
+ events.ScheduleEvent(EVENT_INTRO_3, 2s);
+ break;
+ case EVENT_INTRO_3:
+ me->SetImmuneToAll(false);
+ DoZoneInCombat();
+ break;
+ default:
+ break;
}
}
- else
- Intro_Timer -=diff;
- }
-
- if (!UpdateVictim())
return;
+ }
events.Update(diff);
@@ -251,7 +233,6 @@ struct boss_harbinger_skyriss : public BossAI
}
private:
- bool _intro;
uint8 _phase;
};
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
index 5f1321fb762..18a830bdcd9 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
@@ -18,6 +18,7 @@
#include "ScriptMgr.h"
#include "arcatraz.h"
#include "Creature.h"
+#include "CreatureAI.h"
#include "GameObject.h"
#include "InstanceScript.h"
#include "Map.h"
@@ -29,6 +30,23 @@ DoorData const doorData[] =
{ 0, 0, DOOR_TYPE_ROOM } // END
};
+ObjectData const creatureData[] =
+{
+ { NPC_MELLICHAR, DATA_MELLICHAR },
+ { 0, 0 } // END
+};
+
+ObjectData const gameObjectData[] =
+{
+ { GO_STASIS_POD_ALPHA, DATA_STASIS_POD_ALPHA },
+ { GO_STASIS_POD_BETA, DATA_STASIS_POD_BETA },
+ { GO_STASIS_POD_DELTA, DATA_STASIS_POD_DELTA },
+ { GO_STASIS_POD_GAMMA, DATA_STASIS_POD_GAMMA },
+ { GO_STASIS_POD_OMEGA, DATA_STASIS_POD_OMEGA },
+ { GO_WARDENS_SHIELD, DATA_WARDENS_SHIELD },
+ { 0, 0 } //END
+};
+
class instance_arcatraz : public InstanceMapScript
{
public:
@@ -41,6 +59,7 @@ class instance_arcatraz : public InstanceMapScript
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
+ LoadObjectData(creatureData, gameObjectData);
ConversationState = NOT_STARTED;
@@ -59,9 +78,6 @@ class instance_arcatraz : public InstanceMapScript
case NPC_SOCCOTHRATES:
SoccothratesGUID = creature->GetGUID();
break;
- case NPC_MELLICHAR:
- MellicharGUID = creature->GetGUID();
- break;
case NPC_MILLHOUSE:
MillhouseGUID = creature->GetGUID();
break;
@@ -70,35 +86,6 @@ class instance_arcatraz : public InstanceMapScript
}
}
- void OnGameObjectCreate(GameObject* go) override
- {
- InstanceScript::OnGameObjectCreate(go);
-
- switch (go->GetEntry())
- {
- case GO_STASIS_POD_ALPHA:
- StasisPodGUIDs[0] = go->GetGUID();
- break;
- case GO_STASIS_POD_BETA:
- StasisPodGUIDs[1] = go->GetGUID();
- break;
- case GO_STASIS_POD_DELTA:
- StasisPodGUIDs[2] = go->GetGUID();
- break;
- case GO_STASIS_POD_GAMMA:
- StasisPodGUIDs[3] = go->GetGUID();
- break;
- case GO_STASIS_POD_OMEGA:
- StasisPodGUIDs[4] = go->GetGUID();
- break;
- case GO_WARDENS_SHIELD:
- WardensShieldGUID = go->GetGUID();
- break;
- default:
- break;
- }
- }
-
void SetData(uint32 type, uint32 data) override
{
switch (type)
@@ -108,8 +95,6 @@ class instance_arcatraz : public InstanceMapScript
case DATA_WARDEN_3:
case DATA_WARDEN_4:
case DATA_WARDEN_5:
- if (data == IN_PROGRESS)
- HandleGameObject(StasisPodGUIDs[type - DATA_WARDEN_1], true);
StasisPodStates[type - DATA_WARDEN_1] = uint8(data);
break;
case DATA_CONVERSATION:
@@ -146,10 +131,6 @@ class instance_arcatraz : public InstanceMapScript
return DalliahGUID;
case DATA_SOCCOTHRATES:
return SoccothratesGUID;
- case DATA_MELLICHAR:
- return MellicharGUID;
- case DATA_WARDENS_SHIELD:
- return WardensShieldGUID;
default:
break;
}
@@ -172,7 +153,7 @@ class instance_arcatraz : public InstanceMapScript
SetData(DATA_WARDEN_4, NOT_STARTED);
SetData(DATA_WARDEN_5, NOT_STARTED);
}
- else if (state == DONE)
+ if (state == DONE)
{
if (!instance->IsHeroic())
break;
@@ -181,6 +162,11 @@ class instance_arcatraz : public InstanceMapScript
if (millhouse->IsAlive())
DoCastSpellOnPlayers(SPELL_QID_10886);
}
+ if (state == FAIL)
+ {
+ if (Creature* mellichar = GetCreature(DATA_MELLICHAR))
+ mellichar->AI()->DoAction(ACTION_RESET_PRISON);
+ }
break;
default:
break;
@@ -191,9 +177,6 @@ class instance_arcatraz : public InstanceMapScript
protected:
ObjectGuid DalliahGUID;
ObjectGuid SoccothratesGUID;
- ObjectGuid StasisPodGUIDs[5];
- ObjectGuid MellicharGUID;
- ObjectGuid WardensShieldGUID;
ObjectGuid MillhouseGUID;
uint8 ConversationState;