diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp index fd998bd7d..d4b72fcb3 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp @@ -28,6 +28,7 @@ enum Spells SPELL_LIGHTNING_SHIELD = 50831, SPELL_STATIC_CHARGE = 50834, SPELL_LIGHTNING_RING = 50840, + SPELL_LIGHTNING_RING_5S = 51849, // IRON SLUDGE SPELL_TOXIC_VOLLEY = 50838, @@ -41,7 +42,6 @@ enum Spells enum Npc { - NPC_IRON_SLUDGE = 28165, // if 2 ooze then spawn 1 iron_sludge NPC_DWARFES_FRIENDLY = 27980, //after fix the machine by Brann NPC_OOZE = 27981, //spawn after killing dwarf NPC_FORGED_IRON_DWARF = 27982, @@ -57,15 +57,6 @@ enum Yells enum Events { - // SJONNIR - EVENT_SHIELD = 1, - EVENT_CHAIN_LIGHTNING = 2, - EVENT_STATIC_CHARGE = 3, - EVENT_LIGHTNING_RING = 4, - EVENT_CHECK_HEALTH = 5, - EVENT_SUMMON = 6, - EVENT_SUMMON_SPEACH = 7, - // TRASH EVENT_MALFORMED_OOZE_CHECK = 10, EVENT_TOXIC_VOLLEY = 11, @@ -73,8 +64,11 @@ enum Events EVENT_FORGED_LIGHTNING_TETHER = 13, }; -enum Misc +enum SjonnirMisc { + GROUP_SUMMONS = 1, + GROUP_LIGHTNING_RING = 2, + POS_GEN_RIGHT = 0, POS_GEN_LEFT = 1, POS_ROOM_CENTER = 2, @@ -83,13 +77,6 @@ enum Misc ACTION_SLUG_KILLED = 1, }; -enum SummonPhases -{ - PHASE_SUMMON_UNFRIENDLY_DWARFES = 0, - PHASE_SUMMON_OOZE = 1, - PHASE_SUMMON_FRIENDLY_DWARFES = 2, -}; - static Position RoomPosition[] = { {1293.0f, 610.0f, 199.3f, 0.0f}, @@ -107,75 +94,135 @@ public: return GetHallsOfStoneAI(pCreature); } - struct boss_sjonnirAI : public ScriptedAI + struct boss_sjonnirAI : public BossAI { - boss_sjonnirAI(Creature* c) : ScriptedAI(c), summons(me) - { - pInstance = c->GetInstanceScript(); - } + boss_sjonnirAI(Creature* c) : BossAI(c, BOSS_SJONNIR) { } - InstanceScript* pInstance; - EventMap events; - SummonList summons; - - uint8 SummonPhase; uint8 SlugeCount; void Reset() override { - events.Reset(); - summons.DespawnAll(); - + _Reset(); + scheduler.ClearValidator(); SlugeCount = 0; - SummonPhase = PHASE_SUMMON_UNFRIENDLY_DWARFES; + instance->SetData(DATA_SJONNIR_ACHIEVEMENT, false); - if (pInstance) + if (instance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) { - pInstance->SetData(BOSS_SJONNIR, NOT_STARTED); - pInstance->SetData(DATA_SJONNIR_ACHIEVEMENT, false); + if (GameObject* console = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_CONSOLE))) + console->SetGoState(GO_STATE_READY); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) { - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - if (GameObject* console = me->GetMap()->GetGameObject( pInstance->GetGuidData(GO_SJONNIR_CONSOLE))) - console->SetGoState(GO_STATE_READY); - - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->setDeathState(DeathState::JustDied); - brann->Respawn(); - brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START); - } + brann->setDeathState(DeathState::JustDied); + brann->Respawn(); + brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START); } } + + ScheduleHealthCheckEvent(75, [&] { + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(1s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + me->SummonCreature(NPC_FORGED_IRON_TROGG, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); + ActivatePipe(Pos); + context.Repeat(5s, 7s); + }); + }); + + ScheduleHealthCheckEvent(50, [&] { + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_OOZE); + + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(3s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + if (Creature* ooze = me->SummonCreature(NPC_OOZE, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + { + ActivatePipe(pos); + ooze->GetMotionMaster()->MovePoint(0, RoomPosition[POS_ROOM_CENTER].GetPositionX(), RoomPosition[POS_ROOM_CENTER].GetPositionY(), RoomPosition[POS_ROOM_CENTER].GetPositionZ()); + ooze->SetReactState(REACT_PASSIVE); + ooze->SetWalk(true); + } + + context.Repeat(); + }); + }); + + ScheduleHealthCheckEvent(25, [&] { + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_EARTHEN); + + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(1s, GROUP_SUMMONS, [&](TaskContext context) { + for (int i = 0; i < 3; i++) + { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + if (Creature* dwarf = me->SummonCreature(NPC_DWARFES_FRIENDLY, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + { + if (Player* plr = SelectTargetFromPlayerList(100.0f)) + dwarf->SetFaction(plr->GetFaction()); + + ActivatePipe(pos); + dwarf->AI()->AttackStart(me); + } + } + + context.Repeat(10s, 20s); + }); + }); + + ScheduleHealthCheckEvent(20, [&] { + scheduler.CancelGroup(GROUP_LIGHTNING_RING); + DoCastSelf(SPELL_FRENZY, true); + + ScheduleTimedEvent(1s, [&] { + DoCastSelf(SPELL_LIGHTNING_RING_5S); + }, 11s); + }); + } + + void ScheduleTasks() override + { + ScheduleTimedEvent(14s, 19s, [&] { + DoCastSelf(SPELL_LIGHTNING_SHIELD); + }, 14s, 19s); + + ScheduleTimedEvent(6s, 12s, [&] { + DoCastVictim(SPELL_CHAIN_LIGHTNING); + }, 6s, 12s); + + ScheduleTimedEvent(24s, [&] { + DoCastRandomTarget(SPELL_STATIC_CHARGE, 0, 50.0f); + }, 20s); + + scheduler.Schedule(30s, GROUP_LIGHTNING_RING, [&](TaskContext context) { + DoCastAOE(SPELL_LIGHTNING_RING); + context.Repeat(40s); + }); + + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_TROGG, 20s); + + scheduler.Schedule(5s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + me->SummonCreature(NPC_FORGED_IRON_DWARF, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); + ActivatePipe(pos); + context.Repeat(30s); + }); } void JustEngagedWith(Unit* /*who*/) override { + _JustEngagedWith(); Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s); - events.ScheduleEvent(EVENT_SHIELD, 14s, 19s); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 6s, 12s); - events.ScheduleEvent(EVENT_STATIC_CHARGE, 24s); - events.ScheduleEvent(EVENT_LIGHTNING_RING, 25s, 31s); - events.ScheduleEvent(EVENT_SUMMON, 20s); - events.ScheduleEvent(EVENT_SUMMON, 21s + 500ms); - events.ScheduleEvent(EVENT_SUMMON_SPEACH, 20s); + if (GameObject* doors = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_DOOR))) + doors->SetGoState(GO_STATE_READY); - if (pInstance) - { - pInstance->SetData(BOSS_SJONNIR, IN_PROGRESS); - - if (GameObject* doors = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_SJONNIR_DOOR))) - doors->SetGoState(GO_STATE_READY); - - if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - brann->AI()->DoAction(ACTION_START_SJONNIR_FIGHT); - } + if (instance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->DoAction(ACTION_START_SJONNIR_FIGHT); } void DoAction(int32 param) override @@ -183,144 +230,20 @@ public: if (param == ACTION_SLUG_KILLED) { SlugeCount++; - if (SlugeCount >= 5 && pInstance) - pInstance->SetData(DATA_SJONNIR_ACHIEVEMENT, true); + if (SlugeCount >= 5) + instance->SetData(DATA_SJONNIR_ACHIEVEMENT, true); } } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHECK_HEALTH: - { - if (SummonPhase == PHASE_SUMMON_UNFRIENDLY_DWARFES && HealthBelowPct(50)) - { - SummonPhase = PHASE_SUMMON_OOZE; - events.CancelEvent(EVENT_SUMMON); - events.ScheduleEvent(EVENT_SUMMON, 0ms); - events.ScheduleEvent(EVENT_SUMMON, 1500ms); - - if (pInstance) - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_OOZE); - } - } - - if (HealthBelowPct(20)) - { - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_EARTHEN); - } - SummonPhase = PHASE_SUMMON_FRIENDLY_DWARFES; - me->CastSpell(me, SPELL_FRENZY, false); - - events.CancelEvent(EVENT_SUMMON); - events.ScheduleEvent(EVENT_SUMMON, 0ms); - break; - } - - events.Repeat(1s); - break; - } - case EVENT_SHIELD: - { - me->CastSpell(me, SPELL_LIGHTNING_SHIELD, false); - events.Repeat(14s, 19s); - break; - } - case EVENT_CHAIN_LIGHTNING: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0)) - me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); - - events.Repeat(6s, 12s); - break; - } - case EVENT_STATIC_CHARGE: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0)) - me->CastSpell(target, SPELL_STATIC_CHARGE, false); - - events.Repeat(20s); - break; - } - case EVENT_LIGHTNING_RING: - { - me->CastSpell(me, SPELL_LIGHTNING_RING, false); - events.Repeat(25s, 31s); - events.DelayEvents(10s); // Channel duration - break; - } - case EVENT_SUMMON_SPEACH: - { - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_TROGG); - } - - break; - } - case EVENT_SUMMON: - { - switch (SummonPhase) - { - case PHASE_SUMMON_UNFRIENDLY_DWARFES: - { - SummonDwarfes(false); - events.Repeat(20s); - break; - } - case PHASE_SUMMON_OOZE: - { - for (uint8 i = POS_GEN_RIGHT; i <= POS_GEN_LEFT; i++) - { - if (Creature* ooze = me->SummonCreature(NPC_OOZE, RoomPosition[i].GetPositionX(), RoomPosition[i].GetPositionY(), RoomPosition[i].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - ActivatePipe(i); - ooze->GetMotionMaster()->MovePoint(0, RoomPosition[POS_ROOM_CENTER].GetPositionX(), RoomPosition[POS_ROOM_CENTER].GetPositionY(), RoomPosition[POS_ROOM_CENTER].GetPositionZ()); - summons.Summon(ooze); - } - } - events.Repeat(10s); - break; - } - case PHASE_SUMMON_FRIENDLY_DWARFES: - { - SummonDwarfes(true); - break; - } - } - break; - } - } - - DoMeleeAttackIfReady(); - } - void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); + _JustDied(); + if (GameObject* sd = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_DOOR))) + sd->SetGoState(GO_STATE_ACTIVE); - summons.DespawnAll(); - if (pInstance) - { - pInstance->SetData(BOSS_SJONNIR, DONE); - if (GameObject* sd = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_SJONNIR_DOOR))) - sd->SetGoState(GO_STATE_ACTIVE); - - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - brann->AI()->DoAction(ACTION_SJONNIR_DEAD); - } + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->DoAction(ACTION_SJONNIR_DEAD); } void KilledUnit(Unit* /*victim*/) override @@ -333,42 +256,8 @@ public: void ActivatePipe(uint8 side) { - if (pInstance) - if (GameObject* pipe = me->GetMap()->GetGameObject(pInstance->GetGuidData(side == POS_GEN_RIGHT ? GO_RIGHT_PIPE : GO_LEFT_PIPE))) - pipe->SendCustomAnim(0); - } - - void SummonDwarfes(bool friendly) - { - if (friendly) - { - for (int i = 0; i < 3; i++) - { - uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); - if (Creature* dwarf = me->SummonCreature(NPC_DWARFES_FRIENDLY, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - if (Player* plr = SelectTargetFromPlayerList(100.0f)) - dwarf->SetFaction(plr->GetFaction()); - - ActivatePipe(Pos); - dwarf->AI()->AttackStart(me); - summons.Summon(dwarf); - } - } - } - else - { - for (int i = 0; i < 2; i++) - { - uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); - if (Creature* dwarf = me->SummonCreature(urand(0, 1) ? NPC_FORGED_IRON_TROGG : NPC_FORGED_IRON_DWARF, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - ActivatePipe(Pos); - dwarf->SetInCombatWithZone(); - summons.Summon(dwarf); - } - } - } + if (GameObject* pipe = me->GetMap()->GetGameObject(instance->GetGuidData(side == POS_GEN_RIGHT ? GO_RIGHT_PIPE : GO_LEFT_PIPE))) + pipe->SendCustomAnim(0); } }; }; @@ -423,8 +312,8 @@ public: } void JustDied(Unit* /*killer*/) override { - if (InstanceScript* pInstance = me->GetInstanceScript()) - if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_SJONNIR))) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* sjonnir = instance->GetCreature(BOSS_SJONNIR)) sjonnir->AI()->DoAction(ACTION_SLUG_KILLED); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp index 31b4a18b3..a78379465 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp @@ -886,8 +886,6 @@ void brann_bronzebeard::brann_bronzebeardAI::WaypointReached(uint32 id) { pInstance->SetData(BRANN_BRONZEBEARD, 4); me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); - if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_SJONNIR))) - cr->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); me->SetOrientation(3.132660f); DoCast(me, 58506, false); me->SendMovementFlagUpdate(); diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h index 9039c0eba..d45d3009b 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h @@ -78,6 +78,7 @@ enum npcs NPC_ABEDNEUM = 30899, NPC_SJONNIR = 27978, NPC_BRANN = 28070, + NPC_IRON_SLUDGE = 28165, ACTION_START_ESCORT_EVENT = 0, ACTION_START_TRIBUNAL = 1, diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp index 521c1ba61..c6c8b65dd 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp @@ -20,6 +20,18 @@ #include "ScriptedCreature.h" #include "halls_of_stone.h" +ObjectData const summonData[] = +{ + { NPC_IRON_SLUDGE, BOSS_SJONNIR }, + { 0, 0 } +}; + +ObjectData const creatureData[] = +{ + { NPC_SJONNIR, BOSS_SJONNIR }, + { 0, 0 } +}; + class instance_halls_of_stone : public InstanceMapScript { public: @@ -57,6 +69,9 @@ public: void Initialize() override { SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTER); + LoadObjectData(creatureData, nullptr); + LoadSummonData(summonData); memset(&Encounter, 0, sizeof(Encounter)); brannAchievement = false; @@ -121,13 +136,12 @@ public: { switch (creature->GetEntry()) { - case NPC_SJONNIR: - SjonnirGUID = creature->GetGUID(); - break; case NPC_BRANN: BrannGUID = creature->GetGUID(); break; } + + InstanceScript::OnCreatureCreate(creature); } ObjectGuid GetGuidData(uint32 id) const override