From a4a278a0e7fc8c908ad7ddb470f0af55710af774 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 30 Nov 2024 20:25:27 -0300 Subject: [PATCH] refactor(Scripts/UtgardeKeep): Upgrade scripts to new register method (#20795) --- .../UtgardeKeep/boss_ingvar_the_plunderer.cpp | 523 +++++++++--------- .../UtgardeKeep/UtgardeKeep/boss_keleseth.cpp | 435 +++++++-------- .../UtgardeKeep/boss_skarvald_dalronn.cpp | 276 +++++---- .../UtgardeKeep/UtgardeKeep/utgarde_keep.cpp | 272 +++++---- .../UtgardeKeep/UtgardeKeep/utgarde_keep.h | 2 + 5 files changed, 711 insertions(+), 797 deletions(-) diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index 7b44e22c6..6d80f9216 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -99,299 +99,288 @@ enum eEvents EVENT_AXE_PICKUP, }; -class boss_ingvar_the_plunderer : public CreatureScript +struct boss_ingvar_the_plunderer : public ScriptedAI { -public: - boss_ingvar_the_plunderer() : CreatureScript("boss_ingvar_the_plunderer") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_ingvar_the_plunderer(Creature* c) : ScriptedAI(c), summons(me) { - return GetUtgardeKeepAI(pCreature); + pInstance = c->GetInstanceScript(); } - struct boss_ingvar_the_plundererAI : public ScriptedAI + InstanceScript* pInstance; + EventMap events; + SummonList summons; + ObjectGuid ValkyrGUID; + ObjectGuid ThrowGUID; + + void Reset() override { - boss_ingvar_the_plundererAI(Creature* c) : ScriptedAI(c), summons(me) - { - pInstance = c->GetInstanceScript(); - } + ValkyrGUID.Clear(); + ThrowGUID.Clear(); + events.Reset(); + summons.DespawnAll(); + me->SetDisplayId(DISPLAYID_DEFAULT); + me->LoadEquipment(1); + FeignDeath(false); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); - InstanceScript* pInstance; - EventMap events; - SummonList summons; - ObjectGuid ValkyrGUID; - ObjectGuid ThrowGUID; + if (pInstance) + pInstance->SetData(DATA_INGVAR, NOT_STARTED); + } - void Reset() override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth()) { - ValkyrGUID.Clear(); - ThrowGUID.Clear(); - events.Reset(); - summons.DespawnAll(); - me->SetDisplayId(DISPLAYID_DEFAULT); - me->LoadEquipment(1); - FeignDeath(false); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + damage = 0; + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STATE_ROOT); me->DisableRotate(false); - - if (pInstance) - pInstance->SetData(DATA_INGVAR, NOT_STARTED); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth()) - { - damage = 0; - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - FeignDeath(true); - events.Reset(); - events.RescheduleEvent(EVENT_START_RESURRECTION, 1s); - events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms); - } - } - - void JustEngagedWith(Unit* /*who*/) override - { + me->GetMotionMaster()->MovementExpired(); + me->GetMotionMaster()->MoveIdle(); + me->StopMoving(); + FeignDeath(true); events.Reset(); - // schedule Phase 1 abilities + events.RescheduleEvent(EVENT_START_RESURRECTION, 1s); + events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms); + } + } + + void JustEngagedWith(Unit* /*who*/) override + { + events.Reset(); + // schedule Phase 1 abilities + events.RescheduleEvent(EVENT_SPELL_ROAR, 15s); + events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s); + events.RescheduleEvent(EVENT_SPELL_SMASH, 5s); + events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s); + + Talk(YELL_AGGRO_1); + me->LowerPlayerDamageReq(me->GetMaxHealth()); + + if (pInstance) + pInstance->SetData(DATA_INGVAR, IN_PROGRESS); + } + + void JustSummoned(Creature* s) override + { + summons.Summon(s); + if (s->GetEntry() == NPC_ANNHYLDE) + { + ValkyrGUID = s->GetGUID(); + s->SetCanFly(true); + s->SetDisableGravity(true); + s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation()); + s->SetFacingTo(s->GetOrientation()); + } + else if (s->GetEntry() == NPC_THROW) + { + ThrowGUID = s->GetGUID(); + if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true)) + s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ()); + } + } + + void KilledUnit(Unit* /*who*/) override + { + if (me->GetDisplayId() == DISPLAYID_DEFAULT) + Talk(YELL_KILL_2); + else + Talk(YELL_KILL_1); + } + + void FeignDeath(bool apply) + { + if (apply) + { + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); + me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); + } + else + { + me->SetStandState(UNIT_STAND_STATE_STAND); + me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); + me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); + } + } + + void JustDied(Unit* /*killer*/) override + { + events.Reset(); + summons.DespawnAll(); + Talk(YELL_DEAD_2); + if (pInstance) + { + pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements + pInstance->SetData(DATA_INGVAR, DONE); + } + } + + void EnterEvadeMode(EvadeReason why) override + { + me->SetControlled(false, UNIT_STATE_ROOT); + me->DisableRotate(false); + ScriptedAI::EnterEvadeMode(why); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case 0: + break; + case EVENT_YELL_DEAD_1: + Talk(YELL_DEAD_1); + break; + case EVENT_START_RESURRECTION: + me->CastSpell(me, SPELL_SUMMON_VALKYR, true); + events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s); + events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms); + events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s); + break; + case EVENT_VALKYR_MOVE: + if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID)) + s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f); + break; + case EVENT_ANNHYLDE_YELL: + if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID)) + s->AI()->Talk(YELL_ANHYLDE_2); + break; + case EVENT_VALKYR_BEAM: + me->RemoveAura(SPELL_SUMMON_VALKYR); + if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID)) + c->CastSpell(me, SPELL_RESURRECTION_BEAM, false); + events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s); + break; + case EVENT_RESURRECTION_BALL: + me->CastSpell(me, SPELL_RESURRECTION_BALL, true); + events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s); + break; + case EVENT_RESURRECTION_HEAL: + me->RemoveAura(SPELL_RESURRECTION_BALL); + me->CastSpell(me, SPELL_RESURRECTION_HEAL, true); + FeignDeath(false); + events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s); + break; + case EVENT_MORPH_TO_UNDEAD: + me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true); + events.RescheduleEvent(EVENT_START_PHASE_2, 1s); + break; + case EVENT_START_PHASE_2: + if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID)) + { + c->DespawnOrUnsummon(); + summons.DespawnAll(); + } + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + AttackStart(me->GetVictim()); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + Talk(YELL_AGGRO_2); + + // schedule Phase 2 abilities events.RescheduleEvent(EVENT_SPELL_ROAR, 15s); events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s); events.RescheduleEvent(EVENT_SPELL_SMASH, 5s); events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s); - Talk(YELL_AGGRO_1); - me->LowerPlayerDamageReq(me->GetMaxHealth()); + break; - if (pInstance) - pInstance->SetData(DATA_INGVAR, IN_PROGRESS); - } - - void JustSummoned(Creature* s) override - { - summons.Summon(s); - if (s->GetEntry() == NPC_ANNHYLDE) - { - ValkyrGUID = s->GetGUID(); - s->SetCanFly(true); - s->SetDisableGravity(true); - s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation()); - s->SetFacingTo(s->GetOrientation()); - } - else if (s->GetEntry() == NPC_THROW) - { - ThrowGUID = s->GetGUID(); - if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true)) - s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ()); - } - } - - void KilledUnit(Unit* /*who*/) override - { - if (me->GetDisplayId() == DISPLAYID_DEFAULT) - Talk(YELL_KILL_2); - else - Talk(YELL_KILL_1); - } - - void FeignDeath(bool apply) - { - if (apply) - { - me->SetStandState(UNIT_STAND_STATE_DEAD); - me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); - me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); - me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); - } - else - { - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); - me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); - me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); - } - } - - void JustDied(Unit* /*killer*/) override - { - events.Reset(); - summons.DespawnAll(); - Talk(YELL_DEAD_2); - if (pInstance) - { - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements - pInstance->SetData(DATA_INGVAR, DONE); - } - } - - void EnterEvadeMode(EvadeReason why) override - { + // ABILITIES HERE: + case EVENT_UNROOT: me->SetControlled(false, UNIT_STATE_ROOT); me->DisableRotate(false); - ScriptedAI::EnterEvadeMode(why); - } + break; + case EVENT_SPELL_ROAR: + Talk(EMOTE_ROAR); - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0); + me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0); - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + if (me->GetDisplayId() == DISPLAYID_DEFAULT) + me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false); + else + me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false); + events.Repeat(15s, 20s); + break; + case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE: + if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0) { - case 0: - break; - case EVENT_YELL_DEAD_1: - Talk(YELL_DEAD_1); - break; - case EVENT_START_RESURRECTION: - me->CastSpell(me, SPELL_SUMMON_VALKYR, true); - events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s); - events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms); - events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s); - break; - case EVENT_VALKYR_MOVE: - if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID)) - s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f); - break; - case EVENT_ANNHYLDE_YELL: - if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID)) - s->AI()->Talk(YELL_ANHYLDE_2); - break; - case EVENT_VALKYR_BEAM: - me->RemoveAura(SPELL_SUMMON_VALKYR); - if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID)) - c->CastSpell(me, SPELL_RESURRECTION_BEAM, false); - events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s); - break; - case EVENT_RESURRECTION_BALL: - me->CastSpell(me, SPELL_RESURRECTION_BALL, true); - events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s); - break; - case EVENT_RESURRECTION_HEAL: - me->RemoveAura(SPELL_RESURRECTION_BALL); - me->CastSpell(me, SPELL_RESURRECTION_HEAL, true); - FeignDeath(false); - events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s); - break; - case EVENT_MORPH_TO_UNDEAD: - me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true); - events.RescheduleEvent(EVENT_START_PHASE_2, 1s); - break; - case EVENT_START_PHASE_2: - if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID)) - { - c->DespawnOrUnsummon(); - summons.DespawnAll(); - } - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - AttackStart(me->GetVictim()); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - Talk(YELL_AGGRO_2); - - // schedule Phase 2 abilities - events.RescheduleEvent(EVENT_SPELL_ROAR, 15s); - events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s); - events.RescheduleEvent(EVENT_SPELL_SMASH, 5s); - events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s); - - break; - - // ABILITIES HERE: - case EVENT_UNROOT: - me->SetControlled(false, UNIT_STATE_ROOT); - me->DisableRotate(false); - break; - case EVENT_SPELL_ROAR: - Talk(EMOTE_ROAR); - - me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0); - me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0); - - if (me->GetDisplayId() == DISPLAYID_DEFAULT) - me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false); - else - me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false); - events.Repeat(15s, 20s); - break; - case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE: - if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 ) - { - events.Repeat(3s); - break; - } - if (me->GetDisplayId() == DISPLAYID_DEFAULT) - me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); - else - me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false); - events.Repeat(3s, 7s); - break; - case EVENT_SPELL_SMASH: - if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 ) - { - events.Repeat(3s); - break; - } - me->SetControlled(true, UNIT_STATE_ROOT); - me->DisableRotate(true); - me->SendMovementFlagUpdate(); - if (me->GetDisplayId() == DISPLAYID_DEFAULT) - me->CastSpell((Unit*)nullptr, SPELL_SMASH, false); - else - me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false); - events.Repeat(9s, 11s); - events.RescheduleEvent(EVENT_UNROOT, 3750ms); - break; - case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE: - if (me->GetDisplayId() == DISPLAYID_DEFAULT) - { - me->CastSpell(me, SPELL_ENRAGE, false); - events.Repeat(10s); - } - else - { - me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true); - SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); - events.Repeat(35s); - events.RescheduleEvent(EVENT_AXE_RETURN, 10s); - } - break; - case EVENT_AXE_RETURN: - if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID)) - c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms); - break; - case EVENT_AXE_PICKUP: - if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID)) - { - c->DestroyForNearbyPlayers(); - c->DespawnOrUnsummon(); - summons.DespawnAll(); - } - ThrowGUID.Clear(); - SetEquipmentSlots(true); - break; + events.Repeat(3s); + break; } - - if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - DoMeleeAttackIfReady(); + if (me->GetDisplayId() == DISPLAYID_DEFAULT) + me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); + else + me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false); + events.Repeat(3s, 7s); + break; + case EVENT_SPELL_SMASH: + if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0) + { + events.Repeat(3s); + break; + } + me->SetControlled(true, UNIT_STATE_ROOT); + me->DisableRotate(true); + me->SendMovementFlagUpdate(); + if (me->GetDisplayId() == DISPLAYID_DEFAULT) + me->CastSpell((Unit*)nullptr, SPELL_SMASH, false); + else + me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false); + events.Repeat(9s, 11s); + events.RescheduleEvent(EVENT_UNROOT, 3750ms); + break; + case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE: + if (me->GetDisplayId() == DISPLAYID_DEFAULT) + { + me->CastSpell(me, SPELL_ENRAGE, false); + events.Repeat(10s); + } + else + { + me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true); + SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); + events.Repeat(35s); + events.RescheduleEvent(EVENT_AXE_RETURN, 10s); + } + break; + case EVENT_AXE_RETURN: + if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID)) + c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms); + break; + case EVENT_AXE_PICKUP: + if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID)) + { + c->DestroyForNearbyPlayers(); + c->DespawnOrUnsummon(); + summons.DespawnAll(); + } + ThrowGUID.Clear(); + SetEquipmentSlots(true); + break; } - }; + + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + DoMeleeAttackIfReady(); + } }; void AddSC_boss_ingvar_the_plunderer() { - new boss_ingvar_the_plunderer(); + RegisterUtgardeKeepCreatureAI(boss_ingvar_the_plunderer); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp index e03daa35b..b51d5c4c9 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp @@ -58,176 +58,154 @@ enum eEvents EVENT_SUMMON_SKELETONS, }; -class npc_frost_tomb : public CreatureScript +struct npc_frost_tomb : public NullCreatureAI { -public: - npc_frost_tomb() : CreatureScript("npc_frost_tomb") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_frost_tomb(Creature* c) : NullCreatureAI(c) { - return GetUtgardeKeepAI(pCreature); - } - - struct npc_frost_tombAI : public NullCreatureAI - { - npc_frost_tombAI(Creature* c) : NullCreatureAI(c) - { - if (TempSummon* t = c->ToTempSummon()) - if (Unit* s = t->GetSummonerUnit()) - { - PrisonerGUID = s->GetGUID(); - if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic()) - { - const int32 dmg = 2000; - c->CastCustomSpell(s, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true); - } - else - c->CastSpell(s, SPELL_FROST_TOMB_AURA, true); - } - } - ObjectGuid PrisonerGUID; - - void JustDied(Unit* killer) override - { - if (killer && killer->GetGUID() != me->GetGUID()) - if (InstanceScript* pInstance = me->GetInstanceScript()) - pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0); - - if (PrisonerGUID) - if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID)) - p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA); - me->DespawnOrUnsummon(5000); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (PrisonerGUID) + if (TempSummon* t = c->ToTempSummon()) + if (Unit* s = t->GetSummonerUnit()) { - if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID)) + PrisonerGUID = s->GetGUID(); + if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic()) { - if (!p->HasAura(SPELL_FROST_TOMB_AURA)) - me->KillSelf(); + const int32 dmg = 2000; + c->CastCustomSpell(s, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true); } else - me->KillSelf(); + c->CastSpell(s, SPELL_FROST_TOMB_AURA, true); } - } - }; -}; + } + ObjectGuid PrisonerGUID; -class boss_keleseth : public CreatureScript -{ -public: - boss_keleseth() : CreatureScript("boss_keleseth") { } - - CreatureAI* GetAI(Creature* pCreature) const override + void JustDied(Unit* killer) override { - return GetUtgardeKeepAI(pCreature); + if (killer && killer->GetGUID() != me->GetGUID()) + if (InstanceScript* pInstance = me->GetInstanceScript()) + pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0); + + if (PrisonerGUID) + if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID)) + p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA); + me->DespawnOrUnsummon(5000); } - struct boss_kelesethAI : public ScriptedAI + void UpdateAI(uint32 /*diff*/) override { - boss_kelesethAI(Creature* c) : ScriptedAI(c) + if (PrisonerGUID) { - pInstance = c->GetInstanceScript(); - } - - InstanceScript* pInstance; - EventMap events; - - void Reset() override - { - events.Reset(); - if (pInstance) - pInstance->SetData(DATA_KELESETH, NOT_STARTED); - } - - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer()) + if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID)) { - Talk(SAY_KILL); + if (!p->HasAura(SPELL_FROST_TOMB_AURA)) + me->KillSelf(); } + else + me->KillSelf(); } + } +}; - void JustDied(Unit* /*killer*/) override +struct boss_keleseth : public ScriptedAI +{ + boss_keleseth(Creature* c) : ScriptedAI(c) + { + pInstance = c->GetInstanceScript(); + } + + InstanceScript* pInstance; + EventMap events; + + void Reset() override + { + events.Reset(); + if (pInstance) + pInstance->SetData(DATA_KELESETH, NOT_STARTED); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer()) { - Talk(SAY_DEATH); - if (pInstance) - pInstance->SetData(DATA_KELESETH, DONE); + Talk(SAY_KILL); } + } - void JustEngagedWith(Unit* /*who*/) override + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + if (pInstance) + pInstance->SetData(DATA_KELESETH, DONE); + } + + void JustEngagedWith(Unit* /*who*/) override + { + events.Reset(); + events.RescheduleEvent(EVENT_SPELL_SHADOWBOLT, 0ms); + events.RescheduleEvent(EVENT_FROST_TOMB, 28s); + events.RescheduleEvent(EVENT_SUMMON_SKELETONS, 4s); + + Talk(SAY_START_COMBAT); + DoZoneInCombat(); + + if (pInstance) + pInstance->SetData(DATA_KELESETH, IN_PROGRESS); + } + + void AttackStart(Unit* who) override + { + if (!who) + return; + + UnitAI::AttackStartCaster(who, 12.0f); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - events.Reset(); - events.RescheduleEvent(EVENT_SPELL_SHADOWBOLT, 0ms); - events.RescheduleEvent(EVENT_FROST_TOMB, 28s); - events.RescheduleEvent(EVENT_SUMMON_SKELETONS, 4s); - - Talk(SAY_START_COMBAT); - DoZoneInCombat(); - - if (pInstance) - pInstance->SetData(DATA_KELESETH, IN_PROGRESS); - } - - void AttackStart(Unit* who) override - { - if (!who) - return; - - UnitAI::AttackStartCaster(who, 12.0f); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + case 0: + break; + case EVENT_SPELL_SHADOWBOLT: + me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false); + events.Repeat(4s, 5s); + break; + case EVENT_FROST_TOMB: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true)) + if (!target->HasAura(SPELL_FROST_TOMB_AURA)) + { + Talk(SAY_FROST_TOMB_EMOTE, target); + Talk(SAY_FROST_TOMB); + me->CastSpell(target, SPELL_FROST_TOMB, false); + events.Repeat(15s); + break; + } + events.Repeat(1s); + break; + case EVENT_SUMMON_SKELETONS: + Talk(SAY_SUMMON_SKELETONS); + for (uint8 i = 0; i < 5; ++i) { - case 0: - break; - case EVENT_SPELL_SHADOWBOLT: - me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false); - events.Repeat(4s, 5s); - break; - case EVENT_FROST_TOMB: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true)) - if (!target->HasAura(SPELL_FROST_TOMB_AURA)) - { - Talk(SAY_FROST_TOMB_EMOTE, target); - Talk(SAY_FROST_TOMB); - me->CastSpell(target, SPELL_FROST_TOMB, false); - events.Repeat(15s); - break; - } - events.Repeat(1s); - break; - case EVENT_SUMMON_SKELETONS: - Talk(SAY_SUMMON_SKELETONS); - for (uint8 i = 0; i < 5; ++i) + float dist = rand_norm() * 4 + 3.0f; + float angle = rand_norm() * 2 * M_PI; + if (Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + if (Unit* target = c->SelectNearestTarget(250.0f)) { - float dist = rand_norm() * 4 + 3.0f; - float angle = rand_norm() * 2 * M_PI; - if (Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - if (Unit* target = c->SelectNearestTarget(250.0f)) - { - c->AddThreat(target, 5.0f); - DoZoneInCombat(c); - } + c->AddThreat(target, 5.0f); + DoZoneInCombat(c); } - break; } - - DoMeleeAttackIfReady(); + break; } - }; + + DoMeleeAttackIfReady(); + } }; enum eSkeletonEnum @@ -242,105 +220,94 @@ enum eSkeletonEnum EVENT_RESURRECT_2, }; -class npc_vrykul_skeleton : public CreatureScript +struct npc_vrykul_skeleton : public ScriptedAI { -public: - npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_vrykul_skeleton(Creature* c) : ScriptedAI(c) { - return GetUtgardeKeepAI(pCreature); + pInstance = c->GetInstanceScript(); } - struct npc_vrykul_skeletonAI : public ScriptedAI + InstanceScript* pInstance; + EventMap events; + + void Reset() override { - npc_vrykul_skeletonAI(Creature* c) : ScriptedAI(c) + events.Reset(); + events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s); + if (IsHeroic()) + events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s); + } + + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override + { + if (damage >= me->GetHealth()) { - pInstance = c->GetInstanceScript(); + damage = 0; + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetControlled(true, UNIT_STATE_ROOT); + me->GetMotionMaster()->MovementExpired(); + me->GetMotionMaster()->MoveIdle(); + me->StopMoving(); + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); + me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); + events.RescheduleEvent(EVENT_RESURRECT, 12s); + } + } + + void UpdateAI(uint32 diff) override + { + if (pInstance && pInstance->GetData(DATA_KELESETH) != IN_PROGRESS) + { + if (me->IsAlive()) + me->KillSelf(); + return; } - InstanceScript* pInstance; - EventMap events; + if (!UpdateVictim()) + return; - void Reset() override + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - events.Reset(); - events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s); - if (IsHeroic()) - events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s); - } - - void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override - { - if (damage >= me->GetHealth()) - { - damage = 0; - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetControlled(true, UNIT_STATE_ROOT); - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - me->SetStandState(UNIT_STAND_STATE_DEAD); - me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); - me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); - me->SetDynamicFlag(UNIT_DYNFLAG_DEAD); - events.RescheduleEvent(EVENT_RESURRECT, 12s); - } - } - - void UpdateAI(uint32 diff) override - { - if (pInstance && pInstance->GetData(DATA_KELESETH) != IN_PROGRESS ) - { - if (me->IsAlive()) - me->KillSelf(); - return; - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case 0: - break; - case EVENT_SPELL_DECREPIFY: - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false); - events.Repeat(15s, 25s); - break; - case EVENT_SPELL_BONE_ARMOR: - if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false); - events.Repeat(40s, 120s); - break; - case EVENT_RESURRECT: - events.DelayEvents(3500ms); - DoCast(me, SPELL_SCOURGE_RESURRECTION, true); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); - me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); - me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); - events.RescheduleEvent(EVENT_RESURRECT_2, 3s); - break; - case EVENT_RESURRECT_2: - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetControlled(false, UNIT_STATE_ROOT); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - break; - } - + case 0: + break; + case EVENT_SPELL_DECREPIFY: if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - DoMeleeAttackIfReady(); + me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false); + events.Repeat(15s, 25s); + break; + case EVENT_SPELL_BONE_ARMOR: + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false); + events.Repeat(40s, 120s); + break; + case EVENT_RESURRECT: + events.DelayEvents(3500ms); + DoCast(me, SPELL_SCOURGE_RESURRECTION, true); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); + me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD); + events.RescheduleEvent(EVENT_RESURRECT_2, 3s); + break; + case EVENT_RESURRECT_2: + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetControlled(false, UNIT_STATE_ROOT); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + break; } - }; + + if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + DoMeleeAttackIfReady(); + } }; class spell_frost_tomb_aura : public AuraScript @@ -368,8 +335,8 @@ class spell_frost_tomb_aura : public AuraScript void AddSC_boss_keleseth() { - new boss_keleseth(); - new npc_frost_tomb(); - new npc_vrykul_skeleton(); + RegisterUtgardeKeepCreatureAI(boss_keleseth); + RegisterUtgardeKeepCreatureAI(npc_frost_tomb); + RegisterUtgardeKeepCreatureAI(npc_vrykul_skeleton); RegisterSpellScript(spell_frost_tomb_aura); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp index 4acb81dbd..6e3ea7f52 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp @@ -66,182 +66,161 @@ enum eEvents EVENT_MATE_DIED }; -class boss_skarvald_the_constructor : public CreatureScript +struct boss_skarvald_the_constructor : public ScriptedAI { -public: - boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { } - - CreatureAI* GetAI(Creature* pCreature) const override + boss_skarvald_the_constructor(Creature* c) : ScriptedAI(c) { - return GetUtgardeKeepAI(pCreature); + pInstance = c->GetInstanceScript(); } - struct boss_skarvald_the_constructorAI : public ScriptedAI + InstanceScript* pInstance; + EventMap events; + + void Reset() override { - boss_skarvald_the_constructorAI(Creature* c) : ScriptedAI(c) + me->SetLootMode(0); + events.Reset(); + if (me->GetEntry() == NPC_SKARVALD) { - pInstance = c->GetInstanceScript(); - } - - InstanceScript* pInstance; - EventMap events; - - void Reset() override - { - me->SetLootMode(0); - events.Reset(); - if (me->GetEntry() == NPC_SKARVALD) - { - if (pInstance) - { - pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED); - } - } - else // NPC_SKARVALD_GHOST - { - if (Unit* target = me->SelectNearestTarget(50.0f)) - { - me->AddThreat(target, 0.0f); - AttackStart(target); - } - } - } - - void DoAction(int32 param) override - { - switch (param) - { - case 1: - events.RescheduleEvent(EVENT_MATE_DIED, 3500ms); - break; - } - } - - void JustEngagedWith(Unit* who) override - { - events.Reset(); - events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s); - events.RescheduleEvent(EVENT_STONE_STRIKE, 10s); - if (me->GetEntry() == NPC_SKARVALD) - { - Talk(YELL_SKARVALD_AGGRO); - if (IsHeroic()) - { - events.ScheduleEvent(EVENT_ENRAGE, 1s); - } - } if (pInstance) { - pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS); - if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN))) + pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED); + } + } + else // NPC_SKARVALD_GHOST + { + if (Unit* target = me->SelectNearestTarget(50.0f)) + { + me->AddThreat(target, 0.0f); + AttackStart(target); + } + } + } + + void DoAction(int32 param) override + { + switch (param) + { + case 1: + events.RescheduleEvent(EVENT_MATE_DIED, 3500ms); + break; + } + } + + void JustEngagedWith(Unit* who) override + { + events.Reset(); + events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s); + events.RescheduleEvent(EVENT_STONE_STRIKE, 10s); + if (me->GetEntry() == NPC_SKARVALD) + { + Talk(YELL_SKARVALD_AGGRO); + if (IsHeroic()) + { + events.ScheduleEvent(EVENT_ENRAGE, 1s); + } + } + if (pInstance) + { + pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS); + if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN))) + { + if (!dalronn->IsInCombat() && who) { - if (!dalronn->IsInCombat() && who) - { - dalronn->AddThreat(who, 0.0f); - dalronn->AI()->AttackStart(who); - } + dalronn->AddThreat(who, 0.0f); + dalronn->AI()->AttackStart(who); } } } + } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* /*victim*/) override + { + if (me->GetEntry() == NPC_SKARVALD) { - if (me->GetEntry() == NPC_SKARVALD) - { - Talk(YELL_SKARVALD_KILL); - } + Talk(YELL_SKARVALD_KILL); } + } - void JustDied(Unit* /*Killer*/) override + void JustDied(Unit* /*Killer*/) override + { + if (me->GetEntry() != NPC_SKARVALD) + return; + + if (pInstance) { - if (me->GetEntry() != NPC_SKARVALD) - return; - - if (pInstance) + if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN))) { - if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN))) + if (dalronn->isDead()) { - if (dalronn->isDead()) - { - Talk(YELL_SKARVALD_SKA_DIEDFIRST); - pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE); - pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0); - return; - } - else - { - Talk(YELL_SKARVALD_DAL_DIED); - dalronn->AI()->DoAction(1); - } + Talk(YELL_SKARVALD_SKA_DIEDFIRST); + pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE); + pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0); + return; + } + else + { + Talk(YELL_SKARVALD_DAL_DIED); + dalronn->AI()->DoAction(1); } } - me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true); } + me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true); + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) + case 0: + break; + case EVENT_MATE_DIED: + Talk(YELL_SKARVALD_DAL_DIEDFIRST); + break; + case EVENT_SHARVALD_CHARGE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true)) { - case 0: - break; - case EVENT_MATE_DIED: - Talk(YELL_SKARVALD_DAL_DIEDFIRST); - break; - case EVENT_SHARVALD_CHARGE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true)) - { - DoResetThreatList(); - me->AddThreat(target, 10000.0f); - me->CastSpell(target, SPELL_CHARGE, false); - } - events.Repeat(5s, 10s); - break; - case EVENT_STONE_STRIKE: - if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) - { - me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false); - events.Repeat(5s, 10s); - } - else - { - events.Repeat(3s); - } - break; - case EVENT_ENRAGE: - if (me->GetHealthPct() <= 60) - { - me->CastSpell(me, SPELL_ENRAGE, true); - break; - } - events.Repeat(1s); - break; + DoResetThreatList(); + me->AddThreat(target, 10000.0f); + me->CastSpell(target, SPELL_CHARGE, false); } - DoMeleeAttackIfReady(); + events.Repeat(5s, 10s); + break; + case EVENT_STONE_STRIKE: + if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim())) + { + me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false); + events.Repeat(5s, 10s); + } + else + { + events.Repeat(3s); + } + break; + case EVENT_ENRAGE: + if (me->GetHealthPct() <= 60) + { + me->CastSpell(me, SPELL_ENRAGE, true); + break; + } + events.Repeat(1s); + break; } - }; + DoMeleeAttackIfReady(); + } }; -class boss_dalronn_the_controller : public CreatureScript -{ -public: - boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { } - - CreatureAI* GetAI(Creature* pCreature) const override +struct boss_dalronn_the_controller : public ScriptedAI { - return GetUtgardeKeepAI(pCreature); - } - - struct boss_dalronn_the_controllerAI : public ScriptedAI - { - boss_dalronn_the_controllerAI(Creature* c) : ScriptedAI(c), summons(me) + boss_dalronn_the_controller(Creature* c) : ScriptedAI(c), summons(me) { pInstance = c->GetInstanceScript(); } @@ -397,10 +376,9 @@ public: DoMeleeAttackIfReady(); } }; -}; void AddSC_boss_skarvald_dalronn() { - new boss_skarvald_the_constructor(); - new boss_dalronn_the_controller(); + RegisterUtgardeKeepCreatureAI(boss_skarvald_the_constructor); + RegisterUtgardeKeepCreatureAI(boss_dalronn_the_controller); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index b85a73f23..62263725b 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -23,72 +23,61 @@ #include "SpellScriptLoader.h" #include "Vehicle.h" -class npc_dragonflayer_forge_master : public CreatureScript +struct npc_dragonflayer_forge_master : public ScriptedAI { -public: - npc_dragonflayer_forge_master() : CreatureScript("npc_dragonflayer_forge_master") { } - - CreatureAI* GetAI(Creature* pCreature) const override + npc_dragonflayer_forge_master(Creature* c) : ScriptedAI(c) { - return GetUtgardeKeepAI(pCreature); + pInstance = c->GetInstanceScript(); + + float x = me->GetHomePosition().GetPositionX(); + float y = me->GetHomePosition().GetPositionY(); + if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f) + { + dataId = DATA_FORGE_1; + prevDataId = 0; + } + else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f) + { + dataId = DATA_FORGE_2; + prevDataId = DATA_FORGE_1; + } + else + { + dataId = DATA_FORGE_3; + prevDataId = DATA_FORGE_2; + } } - struct npc_dragonflayer_forge_masterAI : public ScriptedAI + InstanceScript* pInstance; + uint32 dataId; + uint32 prevDataId; + + void Reset() override { - npc_dragonflayer_forge_masterAI(Creature* c) : ScriptedAI(c) + if (pInstance) + pInstance->SetData(dataId, NOT_STARTED); + } + + void JustDied(Unit* /*killer*/) override + { + if (pInstance) + pInstance->SetData(dataId, DONE); + me->SaveRespawnTime(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + if (pInstance) { - pInstance = c->GetInstanceScript(); - - float x = me->GetHomePosition().GetPositionX(); - float y = me->GetHomePosition().GetPositionY(); - if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f) + if (prevDataId && !pInstance->GetData(prevDataId)) { - dataId = DATA_FORGE_1; - prevDataId = 0; - } - else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f) - { - dataId = DATA_FORGE_2; - prevDataId = DATA_FORGE_1; - } - else - { - dataId = DATA_FORGE_3; - prevDataId = DATA_FORGE_2; + EnterEvadeMode(); + return; } + pInstance->SetData(dataId, IN_PROGRESS); } - - InstanceScript* pInstance; - uint32 dataId; - uint32 prevDataId; - - void Reset() override - { - if (pInstance) - pInstance->SetData(dataId, NOT_STARTED); - } - - void JustDied(Unit* /*killer*/) override - { - if (pInstance) - pInstance->SetData(dataId, DONE); - me->SaveRespawnTime(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - if (pInstance) - { - if (prevDataId && !pInstance->GetData(prevDataId)) - { - EnterEvadeMode(); - return; - } - pInstance->SetData(dataId, IN_PROGRESS); - } - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - } - }; + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + } }; enum EnslavedProtoDrake @@ -111,97 +100,86 @@ enum EnslavedProtoDrake const Position protodrakeCheckPos = {206.24f, -190.28f, 200.11f, 0.f}; -class npc_enslaved_proto_drake : public CreatureScript +struct npc_enslaved_proto_drake : public ScriptedAI { -public: - npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { } - - struct npc_enslaved_proto_drakeAI : public ScriptedAI + npc_enslaved_proto_drake(Creature* creature) : ScriptedAI(creature) { - npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature) - { - _setData = false; - } - - void Reset() override - { - _events.Reset(); - _events.ScheduleEvent(EVENT_REND, 2s, 3s); - _events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms); - _events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST) - { - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f); - if (Vehicle* v = me->GetVehicleKit()) - if (Unit* p = v->GetPassenger(0)) - if (Creature* rider = p->ToCreature()) - rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f); - - me->SetCanFly(false); - me->SetDisableGravity(false); - me->SetFacingTo(0.25f); - me->SetImmuneToAll(false); - } - } - - void SetData(uint32 type, uint32 data) override - { - if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f) - { - _setData = true; - me->SetCanFly(true); - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventid = _events.ExecuteEvent()) - { - switch (eventid) - { - case EVENT_REND: - DoCast(SPELL_REND); - _events.ScheduleEvent(EVENT_REND, 15s, 20s); - break; - case EVENT_FLAME_BREATH: - DoCast(SPELL_FLAME_BREATH); - _events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s); - break; - case EVENT_KNOCKAWAY: - DoCast(SPELL_KNOCK_AWAY); - _events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - bool _setData; - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUtgardeKeepAI(creature); + _setData = false; } + + void Reset() override + { + _events.Reset(); + _events.ScheduleEvent(EVENT_REND, 2s, 3s); + _events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms); + _events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST) + { + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f); + if (Vehicle* v = me->GetVehicleKit()) + if (Unit* p = v->GetPassenger(0)) + if (Creature* rider = p->ToCreature()) + rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f); + + me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetFacingTo(0.25f); + me->SetImmuneToAll(false); + } + } + + void SetData(uint32 type, uint32 data) override + { + if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f) + { + _setData = true; + me->SetCanFly(true); + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventid = _events.ExecuteEvent()) + { + switch (eventid) + { + case EVENT_REND: + DoCast(SPELL_REND); + _events.ScheduleEvent(EVENT_REND, 15s, 20s); + break; + case EVENT_FLAME_BREATH: + DoCast(SPELL_FLAME_BREATH); + _events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s); + break; + case EVENT_KNOCKAWAY: + DoCast(SPELL_KNOCK_AWAY); + _events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + +private: + bool _setData; + EventMap _events; }; enum TickingTimeBomb @@ -234,8 +212,8 @@ class spell_ticking_time_bomb_aura : public AuraScript void AddSC_utgarde_keep() { - new npc_dragonflayer_forge_master(); - new npc_enslaved_proto_drake(); + RegisterUtgardeKeepCreatureAI(npc_dragonflayer_forge_master); + RegisterUtgardeKeepCreatureAI(npc_enslaved_proto_drake); RegisterSpellScript(spell_ticking_time_bomb_aura); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h index 23f3bddb1..a2da84257 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h @@ -83,4 +83,6 @@ inline AI* GetUtgardeKeepAI(T* obj) return GetInstanceAI(obj, UtgardeKeepScriptName); } +#define RegisterUtgardeKeepCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUtgardeKeepAI) + #endif