diff --git a/apps/ci/ci-pending.sh b/apps/ci/ci-pending.sh index 77013bcb8..fa3f798d4 100644 --- a/apps/ci/ci-pending.sh +++ b/apps/ci/ci-pending.sh @@ -27,7 +27,7 @@ for i in `find data/sql/updates/pending* -name "*sql" -type f`; do echo "> broadcast_text check - Failed" echo " - DON'T EDIT broadcast_text TABLE UNLESS YOU KNOW WHAT YOU ARE DOING!" echo " - This error can safely be ignored if the changes are approved to be sniffed." -# exit 1 + exit 1 else echo "> broadcast_text check - OK" fi diff --git a/data/sql/updates/db_world/2023_06_08_00.sql b/data/sql/updates/db_world/2023_06_08_00.sql new file mode 100644 index 000000000..b7eed79ee --- /dev/null +++ b/data/sql/updates/db_world/2023_06_08_00.sql @@ -0,0 +1,12 @@ +-- DB update 2023_06_07_04 -> 2023_06_08_00 +-- +DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (8374,15039,33534,12548,33620,15659,38795); +INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`) VALUES +(8374, 8374, 38761), +(15039, 15039, 15616), +(33534, 33534, 38135), +(12548, 12548, 21401), +(33620, 33620, 38137), +(15659, 15659, 15305), +(38795, 38795, 33666); + diff --git a/data/sql/updates/db_world/2023_06_09_00.sql b/data/sql/updates/db_world/2023_06_09_00.sql new file mode 100644 index 000000000..905b4393f --- /dev/null +++ b/data/sql/updates/db_world/2023_06_09_00.sql @@ -0,0 +1,12 @@ +-- DB update 2023_06_08_00 -> 2023_06_09_00 +-- +DELETE FROM `creature_template_movement` WHERE (`CreatureId` IN (18176,18177,18178,18179,19897,19898,19899,19900)); +INSERT INTO `creature_template_movement` (`CreatureId`, `Flight`, `Rooted`) VALUES +(18176, 1, 1), +(18177, 1, 1), +(18178, 1, 1), +(18179, 1, 1), +(19897, 1, 1), +(19898, 1, 1), +(19899, 1, 1), +(19900, 1, 1); diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 8f751fad4..df90051a6 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -1297,18 +1297,6 @@ AllowTickets = 1 DeletedCharacterTicketTrace = 0 -# -# DungeonFinder.OptionsMask -# Description: Dungeon and raid finder system. -# Value is a bitmask consisting of: -# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser -# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser -# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses - -# Default: 5 - -DungeonFinder.OptionsMask = 5 - # # DBC.EnforceItemAttributes # Disallow overriding item attributes stored in DBC files with values from the database @@ -3682,6 +3670,17 @@ Calculate.Gameoject.Zone.Area.Data = 0 Group.Raid.LevelRestriction = 10 +# +# DungeonFinder.OptionsMask +# Description: Dungeon and raid finder system. +# Value is a bitmask consisting of: +# LFG_OPTION_ENABLE_DUNGEON_FINDER = 1, Enable the dungeon finder browser +# LFG_OPTION_ENABLE_RAID_BROWSER = 2, Enable the raid browser +# LFG_OPTION_ENABLE_SEASONAL_BOSSES = 4, Enable seasonal bosses +# Default: 5 + +DungeonFinder.OptionsMask = 5 + # # LFG.Location.All # diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 069b75086..865ca4cdd 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5043,11 +5043,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (caster && target->CanHaveThreatList()) target->AddThreat(caster, 10.0f); break; - case 13139: // net-o-matic - // root to self part of (root_target->charge->root_self sequence - if (caster) - caster->CastSpell(caster, 13138, true, nullptr, this); - break; case 34026: // kill command { Unit* pet = target->GetGuardianPet(); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index 7a9399418..908e42feb 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -126,17 +126,19 @@ public: { boss_dorotheeAI(Creature* creature) : ScriptedAI(creature) { + SetCombatMovement(false); + //this is kinda a big no-no. but it will prevent her from moving to chase targets. she should just cast her spells. in this case, since there is not really something to LOS her with or get out of range this would work. but a more elegant solution would be better Initialize(); instance = creature->GetInstanceScript(); } void Initialize() { - AggroTimer = 500; + AggroTimer = 12000; - WaterBoltTimer = 5000; + WaterBoltTimer = 0; FearTimer = 15000; - SummonTitoTimer = 47500; + SummonTitoTimer = 41000; SummonedTito = false; TitoDied = false; @@ -152,6 +154,7 @@ public: bool SummonedTito; bool TitoDied; + bool IntroDone = false; void Reset() override { @@ -160,8 +163,7 @@ public: void JustEngagedWith(Unit* /*who*/) override { - Talk(SAY_DOROTHEE_AGGRO); - DoZoneInCombat(); + me->SetInCombatWithZone(); } void JustReachedHome() override @@ -175,6 +177,7 @@ public: { Talk(SAY_DOROTHEE_DEATH); SummonCroneIfReady(instance, me); + me->DespawnOrUnsummon(); } void AttackStart(Unit* who) override @@ -186,7 +189,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) return; @@ -194,14 +196,35 @@ public: ScriptedAI::MoveInLineOfSight(who); } + void EnterEvadeMode(EvadeReason reason) override + { + ScriptedAI::EnterEvadeMode(reason); + + if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL); + me->DespawnOrUnsummon(); + } + } + void UpdateAI(uint32 diff) override { + if(!IntroDone) + { + if(!me->IsInEvadeMode()) + { + Talk(SAY_DOROTHEE_AGGRO); + IntroDone = true; + } + } + if (AggroTimer) { if (AggroTimer <= diff) { me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->SetImmuneToPC(false); + me->SetInCombatWithZone(); AggroTimer = 0; } else @@ -214,7 +237,7 @@ public: if (WaterBoltTimer <= diff) { DoCast(SelectTarget(SelectTargetMethod::Random, 0), SPELL_WATERBOLT); - WaterBoltTimer = TitoDied ? 1500 : 5000; + WaterBoltTimer = 1500; } else WaterBoltTimer -= diff; @@ -279,6 +302,7 @@ public: Talk(SAY_DOROTHEE_TITO_DEATH, Dorothee); } } + me->DespawnOrUnsummon(); } void UpdateAI(uint32 diff) override @@ -311,6 +335,136 @@ void boss_dorothee::boss_dorotheeAI::SummonTito() } } +class boss_roar : public CreatureScript +{ +public: + boss_roar() : CreatureScript("boss_roar") { } + + CreatureAI* GetAI(Creature* creature) const override + { + return GetKarazhanAI(creature); + } + + struct boss_roarAI : public ScriptedAI + { + boss_roarAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + InstanceScript* instance; + + uint32 AggroTimer; + uint32 MangleTimer; + uint32 ShredTimer; + uint32 ScreamTimer; + + void Reset() override + { + AggroTimer = 16670; + MangleTimer = 5000; + ShredTimer = 10000; + ScreamTimer = 15000; + } + + void MoveInLineOfSight(Unit* who) override + + { + if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + return; + + ScriptedAI::MoveInLineOfSight(who); + } + + void EnterEvadeMode(EvadeReason reason) override + { + ScriptedAI::EnterEvadeMode(reason); + + if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL); + me->DespawnOrUnsummon(); + } + } + + void AttackStart(Unit* who) override + { + if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) + return; + + ScriptedAI::AttackStart(who); + } + + void JustEngagedWith(Unit* /*who*/) override + { + Talk(SAY_ROAR_AGGRO); + DoZoneInCombat(); + } + + void JustReachedHome() override + { + me->DespawnOrUnsummon(); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_ROAR_DEATH); + SummonCroneIfReady(instance, me); + me->DespawnOrUnsummon(); + } + + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_ROAR_SLAY); + } + + void UpdateAI(uint32 diff) override + { + if (AggroTimer) + { + if (AggroTimer <= diff) + { + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + me->SetImmuneToPC(false); + me->SetInCombatWithZone(); + AggroTimer = 0; + } + else + AggroTimer -= diff; + } + + if (!UpdateVictim()) + return; + + if (MangleTimer <= diff) + { + DoCastVictim(SPELL_MANGLE); + MangleTimer = urand(5000, 8000); + } + else + MangleTimer -= diff; + + if (ShredTimer <= diff) + { + DoCastVictim(SPELL_SHRED); + ShredTimer = urand(10000, 15000); + } + else + ShredTimer -= diff; + + if (ScreamTimer <= diff) + { + DoCastVictim(SPELL_FRIGHTENED_SCREAM); + ScreamTimer = urand(20000, 30000); + } + else + ScreamTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + class boss_strawman : public CreatureScript { public: @@ -336,7 +490,7 @@ public: void Reset() override { - AggroTimer = 11000; + AggroTimer = 26300; BrainBashTimer = 5000; BrainWipeTimer = 7000; } @@ -350,7 +504,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) return; @@ -358,6 +511,16 @@ public: ScriptedAI::MoveInLineOfSight(who); } + void EnterEvadeMode(EvadeReason reason) override + { + ScriptedAI::EnterEvadeMode(reason); + + if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL); + me->DespawnOrUnsummon(); + } + } void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_STRAWMAN_AGGRO); @@ -385,8 +548,8 @@ public: void JustDied(Unit* /*killer*/) override { Talk(SAY_STRAWMAN_DEATH); - SummonCroneIfReady(instance, me); + me->DespawnOrUnsummon(); } void KilledUnit(Unit* /*victim*/) override @@ -402,6 +565,7 @@ public: { me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->SetImmuneToPC(false); + me->SetInCombatWithZone(); AggroTimer = 0; } else @@ -460,7 +624,7 @@ public: void Reset() override { - AggroTimer = 15000; + AggroTimer = 34470; CleaveTimer = 5000; RustTimer = 15000; @@ -487,7 +651,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) return; @@ -495,11 +658,22 @@ public: ScriptedAI::MoveInLineOfSight(who); } + void EnterEvadeMode(EvadeReason reason) override + { + ScriptedAI::EnterEvadeMode(reason); + + if(!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + { + instance->SetBossState(DATA_OPERA_PERFORMANCE, FAIL); + me->DespawnOrUnsummon(); + } + } + void JustDied(Unit* /*killer*/) override { Talk(SAY_TINHEAD_DEATH); - SummonCroneIfReady(instance, me); + me->DespawnOrUnsummon(); } void KilledUnit(Unit* /*victim*/) override @@ -515,6 +689,7 @@ public: { me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->SetImmuneToPC(false); + me->SetInCombatWithZone(); AggroTimer = 0; } else @@ -550,124 +725,6 @@ public: }; }; -class boss_roar : public CreatureScript -{ -public: - boss_roar() : CreatureScript("boss_roar") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetKarazhanAI(creature); - } - - struct boss_roarAI : public ScriptedAI - { - boss_roarAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 AggroTimer; - uint32 MangleTimer; - uint32 ShredTimer; - uint32 ScreamTimer; - - void Reset() override - { - AggroTimer = 20000; - MangleTimer = 5000; - ShredTimer = 10000; - ScreamTimer = 15000; - } - - void MoveInLineOfSight(Unit* who) override - - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - - void AttackStart(Unit* who) override - { - if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::AttackStart(who); - } - - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_ROAR_AGGRO); - DoZoneInCombat(); - } - - void JustReachedHome() override - { - me->DespawnOrUnsummon(); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_ROAR_DEATH); - - SummonCroneIfReady(instance, me); - } - - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_ROAR_SLAY); - } - - void UpdateAI(uint32 diff) override - { - if (AggroTimer) - { - if (AggroTimer <= diff) - { - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - me->SetImmuneToPC(false); - AggroTimer = 0; - } - else - AggroTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (MangleTimer <= diff) - { - DoCastVictim(SPELL_MANGLE); - MangleTimer = urand(5000, 8000); - } - else - MangleTimer -= diff; - - if (ShredTimer <= diff) - { - DoCastVictim(SPELL_SHRED); - ShredTimer = urand(10000, 15000); - } - else - ShredTimer -= diff; - - if (ScreamTimer <= diff) - { - DoCastVictim(SPELL_FRIGHTENED_SCREAM); - ScreamTimer = urand(20000, 30000); - } - else - ScreamTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - class boss_crone : public CreatureScript { public: diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h index 6e76cbe48..750b1e14a 100644 --- a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h @@ -38,4 +38,6 @@ inline AI* GetAuchenaiCryptsAI(T* obj) return GetInstanceAI(obj, ACScriptName); } +#define RegisterAuchenaiCryptsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAuchenaiCryptsAI) + #endif // AUCHENAI_CRYPTS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp index fb65e27f2..546210c2a 100644 --- a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp @@ -19,142 +19,26 @@ #include "ScriptedCreature.h" #include "auchenai_crypts.h" -enum ExarchMaladaar +enum Text { SAY_INTRO = 0, SAY_SUMMON = 1, SAY_AGGRO = 2, SAY_ROAR = 3, SAY_SLAY = 4, - SAY_DEATH = 5, + SAY_DEATH = 5 +}; +enum Spells +{ + // Exarch Maladaar SPELL_RIBBON_OF_SOULS = 32422, SPELL_SOUL_SCREAM = 32421, SPELL_STOLEN_SOUL = 32346, SPELL_STOLEN_SOUL_VISUAL = 32395, SPELL_SUMMON_AVATAR = 32424, - ENTRY_STOLEN_SOUL = 18441, - - EVENT_SPELL_FEAR = 1, - EVENT_SPELL_RIBBON = 2, - EVENT_SPELL_SOUL = 3, - EVENT_CHECK_HEALTH = 4 -}; - -class boss_exarch_maladaar : public CreatureScript -{ -public: - boss_exarch_maladaar() : CreatureScript("boss_exarch_maladaar") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetAuchenaiCryptsAI(creature); - } - - struct boss_exarch_maladaarAI : public ScriptedAI - { - boss_exarch_maladaarAI(Creature* creature) : ScriptedAI(creature) - { - _talked = false; - } - - bool _talked; - EventMap events; - - void Reset() override - { - events.Reset(); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!_talked && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 150.0f)) - { - Talk(SAY_INTRO); - _talked = true; - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void JustEngagedWith(Unit*) override - { - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_SPELL_FEAR, 15000); - events.ScheduleEvent(EVENT_SPELL_RIBBON, 5000); - events.ScheduleEvent(EVENT_SPELL_SOUL, 25000); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 5000); - } - - void KilledUnit(Unit*) override - { - if (urand(0, 1)) - Talk(SAY_SLAY); - } - - void JustDied(Unit*) override - { - Talk(SAY_DEATH); - - //When Exarch Maladar is defeated D'ore appear. - me->SummonCreature(19412, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 600000); - } - - 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 (HealthBelowPct(25)) - { - Talk(SAY_SUMMON); - me->CastSpell(me, SPELL_SUMMON_AVATAR, false); - return; - } - events.RepeatEvent(2000); - break; - case EVENT_SPELL_SOUL: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) - { - Talk(SAY_ROAR); - me->CastSpell(target, SPELL_STOLEN_SOUL, false); - if (Creature* summon = me->SummonCreature(ENTRY_STOLEN_SOUL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) - { - summon->CastSpell(summon, SPELL_STOLEN_SOUL_VISUAL, false); - summon->SetDisplayId(target->GetDisplayId()); - summon->AI()->DoAction(target->getClass()); - summon->AI()->AttackStart(target); - } - } - events.RepeatEvent(urand(25000, 30000)); - break; - case EVENT_SPELL_RIBBON: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - me->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); - events.RepeatEvent(urand(10000, 20000)); - break; - case EVENT_SPELL_FEAR: - me->CastSpell(me, SPELL_SOUL_SCREAM, false); - events.RepeatEvent(urand(15000, 25000)); - break; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -enum stolenSoul -{ + // Stolen Soul SPELL_MOONFIRE = 37328, SPELL_FIREBALL = 37329, SPELL_MIND_FLAY = 37330, @@ -164,99 +48,211 @@ enum stolenSoul SPELL_MORTAL_STRIKE = 37335, SPELL_FREEZING_TRAP = 37368, SPELL_HAMMER_OF_JUSTICE = 37369, - SPELL_PLAGUE_STRIKE = 58839, - - EVENT_STOLEN_SOUL_SPELL = 1, + SPELL_PLAGUE_STRIKE = 58839 }; -class npc_stolen_soul : public CreatureScript +enum Npc { -public: - npc_stolen_soul() : CreatureScript("npc_stolen_soul") { } + ENTRY_STOLEN_SOUL = 18441 +}; - CreatureAI* GetAI(Creature* creature) const override +struct boss_exarch_maladaar : public BossAI +{ + boss_exarch_maladaar(Creature* creature) : BossAI(creature, DATA_EXARCH_MALADAAR) { - return GetAuchenaiCryptsAI(creature); + _talked = false; + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - struct npc_stolen_soulAI : public ScriptedAI + bool _talked; + + void Reset() override { - npc_stolen_soulAI(Creature* creature) : ScriptedAI(creature) {} + _Reset(); + ScheduleHealthCheckEvent(25, [&] { + Talk(SAY_SUMMON); + DoCastSelf(SPELL_SUMMON_AVATAR); + }); + } - uint8 myClass; - EventMap events; - - void Reset() override + void MoveInLineOfSight(Unit* who) override + { + if (!_talked && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 150.0f)) { - myClass = CLASS_WARRIOR; - events.ScheduleEvent(EVENT_STOLEN_SOUL_SPELL, 1000); + _talked = true; + Talk(SAY_INTRO); } + ScriptedAI::MoveInLineOfSight(who); + } - void DoAction(int32 pClass) override + void JustEngagedWith(Unit*) override + { + _JustEngagedWith(); + Talk(SAY_AGGRO); + scheduler.Schedule(15s, [this] (TaskContext context) { - myClass = pClass; - } - - void UpdateAI(uint32 diff) override + DoCastSelf(SPELL_SOUL_SCREAM); + context.Repeat(15s, 25s); + }).Schedule(5s, [this](TaskContext context) { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (events.ExecuteEvent() == EVENT_STOLEN_SOUL_SPELL) + DoCastRandomTarget(SPELL_RIBBON_OF_SOULS); + context.Repeat(10s, 20s); + }).Schedule(25s, [this](TaskContext context) + { + if (Unit * target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) { - switch (myClass) + Talk(SAY_ROAR); + DoCast(target, SPELL_STOLEN_SOUL); + if (Creature* summon = me->SummonCreature(ENTRY_STOLEN_SOUL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000)) { - case CLASS_WARRIOR: - me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false); - events.RepeatEvent(6000); - break; - case CLASS_PALADIN: - me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, false); - events.RepeatEvent(6000); - break; - case CLASS_HUNTER: - me->CastSpell(me->GetVictim(), SPELL_FREEZING_TRAP, false); - events.RepeatEvent(20000); - break; - case CLASS_ROGUE: - me->CastSpell(me->GetVictim(), SPELL_HEMORRHAGE, false); - events.RepeatEvent(10000); - break; - case CLASS_PRIEST: - me->CastSpell(me->GetVictim(), SPELL_MIND_FLAY, false); - events.RepeatEvent(5000); - break; - case CLASS_SHAMAN: - me->CastSpell(me->GetVictim(), SPELL_FROSTSHOCK, false); - events.RepeatEvent(8000); - break; - case CLASS_MAGE: - me->CastSpell(me->GetVictim(), SPELL_FIREBALL, false); - events.RepeatEvent(5000); - break; - case CLASS_WARLOCK: - me->CastSpell(me->GetVictim(), SPELL_CURSE_OF_AGONY, false); - events.RepeatEvent(20000); - break; - case CLASS_DRUID: - me->CastSpell(me->GetVictim(), SPELL_MOONFIRE, false); - events.RepeatEvent(10000); - break; - case CLASS_DEATH_KNIGHT: - me->CastSpell(me->GetVictim(), SPELL_PLAGUE_STRIKE, false); - events.RepeatEvent(6000); - break; + summon->CastSpell(summon, SPELL_STOLEN_SOUL_VISUAL, false); + summon->SetDisplayId(target->GetDisplayId()); + summon->AI()->DoAction(target->getClass()); + summon->AI()->AttackStart(target); } } + context.Repeat(25s, 30s); + }); + } - DoMeleeAttackIfReady(); + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer() && urand(0, 1)) + { + Talk(SAY_SLAY); } - }; + } + + void JustDied(Unit*) override + { + Talk(SAY_DEATH); + me->SummonCreature(19412, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 600000); + _JustDied(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + DoMeleeAttackIfReady(); + } +}; + +struct npc_stolen_soul : public ScriptedAI +{ + npc_stolen_soul(Creature* creature) : ScriptedAI(creature) {} + + uint8 myClass; + + void Reset() override + { + myClass = CLASS_WARRIOR; + _scheduler.Schedule(1s, [this] (TaskContext /*context*/) + { + switch (myClass) + { + case CLASS_WARRIOR: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_MORTAL_STRIKE); + context.Repeat(6s); + }); + break; + case CLASS_PALADIN: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_HAMMER_OF_JUSTICE); + context.Repeat(6s); + }); + break; + case CLASS_HUNTER: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_FREEZING_TRAP); + context.Repeat(20s); + }); + break; + case CLASS_ROGUE: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_HEMORRHAGE); + context.Repeat(10s); + }); + break; + case CLASS_PRIEST: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_MIND_FLAY); + context.Repeat(5s); + }); + break; + case CLASS_SHAMAN: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_FROSTSHOCK); + context.Repeat(8s); + }); + break; + case CLASS_MAGE: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_FIREBALL); + context.Repeat(5s); + }); + break; + case CLASS_WARLOCK: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_CURSE_OF_AGONY); + context.Repeat(20s); + }); + break; + case CLASS_DRUID: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_MOONFIRE); + context.Repeat(10s); + }); + break; + case CLASS_DEATH_KNIGHT: + _scheduler.Schedule(0ms, [this](TaskContext context) + { + DoCastVictim(SPELL_PLAGUE_STRIKE); + context.Repeat(6s); + }); + break; + } + }); + } + + void DoAction(int32 pClass) override + { + myClass = pClass; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff); + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_exarch_maladaar() { - new boss_exarch_maladaar(); - new npc_stolen_soul(); + RegisterAuchenaiCryptsCreatureAI(boss_exarch_maladaar); + RegisterAuchenaiCryptsCreatureAI(npc_stolen_soul); } diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp index 80aee8195..06c96b7cf 100644 --- a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp @@ -22,220 +22,222 @@ #include "SpellScript.h" #include "auchenai_crypts.h" -enum eShirrak +enum Spells { - SPELL_INHIBIT_MAGIC = 32264, - SPELL_ATTRACT_MAGIC = 32265, - SPELL_CARNIVOROUS_BITE_N = 36383, - SPELL_CARNIVOROUS_BITE_H = 39382, + SPELL_INHIBIT_MAGIC = 32264, + SPELL_ATTRACT_MAGIC = 32265, + SPELL_CARNIVOROUS_BITE = 36383, + SPELL_FIERY_BLAST = 32302, + SPELL_FOCUS_FIRE_VISUAL = 32286, + SPELL_FOCUS_CAST = 32300, - SPELL_FIERY_BLAST_N = 32302, - SPELL_FIERY_BLAST_H = 38382, - SPELL_FOCUS_FIRE_VISUAL = 32286, - SPELL_FOCUS_CAST = 32300, - - EVENT_SPELL_INHIBIT_MAGIC = 1, - EVENT_SPELL_ATTRACT_MAGIC = 2, - EVENT_SPELL_CARNIVOROUS = 3, - EVENT_SPELL_FOCUS_FIRE = 4, - EVENT_SPELL_FOCUS_FIRE_2 = 5, - EVENT_SPELL_FOCUS_FIRE_3 = 6, - - ENTRY_FOCUS_FIRE = 18374, - - EMOTE_FOCUSED = 0 + SPELL_POSSESS_INSTANT = 32830, + SPELL_POSSESS_CHANNELED = 33401 }; -class boss_shirrak_the_dead_watcher : public CreatureScript +enum Misc { -public: - boss_shirrak_the_dead_watcher() : CreatureScript("boss_shirrak_the_dead_watcher") { } + ENTRY_FOCUS_FIRE = 18374, + EMOTE_FOCUSED = 0 +}; - CreatureAI* GetAI(Creature* creature) const override +struct boss_shirrak_the_dead_watcher : public BossAI +{ + boss_shirrak_the_dead_watcher(Creature* creature) : BossAI(creature, DATA_SHIRRAK_THE_DEAD_WATCHER) { - return GetAuchenaiCryptsAI(creature); + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - struct boss_shirrak_the_dead_watcherAI : public ScriptedAI + ObjectGuid focusGUID; + + void EnterEvadeMode(EvadeReason why) override { - boss_shirrak_the_dead_watcherAI(Creature* creature) : ScriptedAI(creature) + me->SetControlled(false, UNIT_STATE_ROOT); + CreatureAI::EnterEvadeMode(why); + } + + void Reset() override + { + _Reset(); + focusGUID.Clear(); + me->SetControlled(false, UNIT_STATE_ROOT); + } + + void JustEngagedWith(Unit*) override + { + _JustEngagedWith(); + scheduler.Schedule(1ms, [this] (TaskContext context) { - } - - EventMap events; - ObjectGuid focusGUID; - - void EnterEvadeMode(EvadeReason why) override - { - me->SetControlled(false, UNIT_STATE_ROOT); - ScriptedAI::EnterEvadeMode(why); - } - - void Reset() override - { - events.Reset(); - focusGUID.Clear(); - me->SetControlled(false, UNIT_STATE_ROOT); - } - - void JustEngagedWith(Unit*) override - { - events.ScheduleEvent(EVENT_SPELL_INHIBIT_MAGIC, 0); - events.ScheduleEvent(EVENT_SPELL_ATTRACT_MAGIC, 28000); - events.ScheduleEvent(EVENT_SPELL_CARNIVOROUS, 10000); - events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE, 17000); - } - - void JustSummoned(Creature* summon) override - { - summon->CastSpell(summon, SPELL_FOCUS_FIRE_VISUAL, true); - } - - void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_FOCUS_CAST) - target->CastSpell(target, DUNGEON_MODE(SPELL_FIERY_BLAST_N, SPELL_FIERY_BLAST_H), false); - } - - uint8 getStackCount(float dist) - { - if (dist < 15) - return 4; - if (dist < 25) - return 3; - if (dist < 35) - return 2; - return 1; - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - uint32 eventId = events.ExecuteEvent(); - - if (eventId == EVENT_SPELL_INHIBIT_MAGIC) + Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { - Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* player = i->GetSource()) + if (Player* player = i->GetSource()) + { + float dist = me->GetDistance(player); + if (player->IsAlive() && dist < 45.0f) { - float dist = me->GetDistance(player); - if (player->IsAlive() && dist < 45.0f) + Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC); + if (!aura) { - Aura* aura = player->GetAura(SPELL_INHIBIT_MAGIC); - if (!aura) - aura = me->AddAura(SPELL_INHIBIT_MAGIC, player); - else - aura->RefreshDuration(); - - if (aura) - aura->SetStackAmount(getStackCount(dist)); + aura = me->AddAura(SPELL_INHIBIT_MAGIC, player); } else - player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC); + { + aura->RefreshDuration(); + } + + if (aura) + { + aura->SetStackAmount(getStackCount(dist)); + } } - events.RepeatEvent(3000); - return; - } - - if (!UpdateVictim()) - return; - - switch (eventId) - { - case EVENT_SPELL_ATTRACT_MAGIC: - me->CastSpell(me, SPELL_ATTRACT_MAGIC, false); - events.RepeatEvent(30000); - events.RescheduleEvent(EVENT_SPELL_CARNIVOROUS, 1500); - break; - case EVENT_SPELL_CARNIVOROUS: - me->CastSpell(me, DUNGEON_MODE(SPELL_CARNIVOROUS_BITE_N, SPELL_CARNIVOROUS_BITE_H), false); - events.RepeatEvent(10000); - break; - case EVENT_SPELL_FOCUS_FIRE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true)) + else { - if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000)) - focusGUID = cr->GetGUID(); - Talk(EMOTE_FOCUSED, target); + player->RemoveAurasDueToSpell(SPELL_INHIBIT_MAGIC); } - events.RepeatEvent(urand(15000, 20000)); - events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3000); - events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 3500); - events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_2, 4000); - events.ScheduleEvent(EVENT_SPELL_FOCUS_FIRE_3, 5000); - me->SetControlled(true, UNIT_STATE_ROOT); - break; - case EVENT_SPELL_FOCUS_FIRE_2: - if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID)) - me->CastSpell(flare, SPELL_FOCUS_CAST, true); - break; - case EVENT_SPELL_FOCUS_FIRE_3: - me->SetControlled(false, UNIT_STATE_ROOT); - break; + } } + context.Repeat(3s); + }).Schedule(28s, [this](TaskContext context) + { + DoCastSelf(SPELL_ATTRACT_MAGIC); + context.Repeat(30s); + scheduler.Schedule(1500ms, [this](TaskContext context) + { + DoCastSelf(SPELL_CARNIVOROUS_BITE); + context.Repeat(10s); + }); + }).Schedule(10s, [this](TaskContext context) + { + DoCastSelf(SPELL_CARNIVOROUS_BITE); + context.Repeat(10s); + }).Schedule(17s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true)) + { + if (Creature* cr = me->SummonCreature(ENTRY_FOCUS_FIRE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 7000)) + { + focusGUID = cr->GetGUID(); + } + Talk(EMOTE_FOCUSED, target); + } + context.Repeat(15s, 20s); + scheduler.Schedule(3s, [this](TaskContext /*context*/) + { + if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID)) + { + me->CastSpell(flare, SPELL_FOCUS_CAST, true); + } + }).Schedule(3500ms, [this](TaskContext /*context*/) + { + if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID)) + { + me->CastSpell(flare, SPELL_FOCUS_CAST, true); + } + }).Schedule(4s, [this](TaskContext /*context*/) + { + if (Unit* flare = ObjectAccessor::GetCreature(*me, focusGUID)) + { + me->CastSpell(flare, SPELL_FOCUS_CAST, true); + } + }).Schedule(5s, [this](TaskContext /*context*/) + { + me->SetControlled(false, UNIT_STATE_ROOT); + }); + me->SetControlled(true, UNIT_STATE_ROOT); + }); + } - DoMeleeAttackIfReady(); + void JustSummoned(Creature* summon) override + { + summon->CastSpell(summon, SPELL_FOCUS_FIRE_VISUAL, true); + } + + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_FOCUS_CAST) + { + target->CastSpell(target, SPELL_FIERY_BLAST, false); } - }; + } + + uint8 getStackCount(float dist) + { + if (dist < 15) + return 4; + if (dist < 25) + return 3; + if (dist < 35) + return 2; + return 1; + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } }; -class spell_auchenai_possess : public SpellScriptLoader +class spell_auchenai_possess : public AuraScript { -public: - spell_auchenai_possess() : SpellScriptLoader("spell_auchenai_possess") { } + PrepareAuraScript(spell_auchenai_possess); - class spell_auchenai_possess_AuraScript : public AuraScript + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - PrepareAuraScript(spell_auchenai_possess_AuraScript); - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + } + + if (Unit* caster = GetCaster()) + { + if (Unit* target = GetTarget()) { - return; - } - - if (Unit* caster = GetCaster()) - if (Unit* target = GetTarget()) - caster->CastSpell(target, 32830 /*POSSESS*/, true); - } - - void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) - { - isPeriodic = true; - amplitude = 2000; - } - - void Update(AuraEffect* /*effect*/) - { - // Xinef: Charm is removed when target is at or below 50%hp - if (Unit* owner = GetUnitOwner()) - if (owner->GetHealthPct() <= 50) - SetDuration(0); - } - - void Register() override - { - // Base channel - if (m_scriptSpellId == 33401) - OnEffectRemove += AuraEffectRemoveFn(spell_auchenai_possess_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - else - { - DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_auchenai_possess_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_CHARM); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_auchenai_possess_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_CHARM); + caster->CastSpell(target, SPELL_POSSESS_INSTANT, true); } } - }; + } - AuraScript* GetAuraScript() const override + void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) { - return new spell_auchenai_possess_AuraScript(); + isPeriodic = true; + amplitude = 2000; + } + + void Update(AuraEffect* /*effect*/) + { + if (Unit* owner = GetUnitOwner()) + { + if (owner->GetHealthPct() <= 50) + { + SetDuration(0); + } + } + } + + void Register() override + { + if (m_scriptSpellId == SPELL_POSSESS_CHANNELED) + { + OnEffectRemove += AuraEffectRemoveFn(spell_auchenai_possess::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + else + { + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_auchenai_possess::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_CHARM); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_auchenai_possess::Update, EFFECT_0, SPELL_AURA_MOD_CHARM); + } } }; void AddSC_boss_shirrak_the_dead_watcher() { - new boss_shirrak_the_dead_watcher(); - new spell_auchenai_possess(); + RegisterAuchenaiCryptsCreatureAI(boss_shirrak_the_dead_watcher); + RegisterSpellScript(spell_auchenai_possess); } diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp index d11429398..9552279b8 100644 --- a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp @@ -20,220 +20,185 @@ #include "ScriptedCreature.h" #include "mana_tombs.h" -enum ePrince +enum Text { SAY_INTRO = 0, SAY_AGGRO = 1, SAY_SLAY = 2, SAY_SUMMON = 3, - SAY_DEAD = 4, + SAY_DEAD = 4 +}; +enum Spells +{ + // Shaffar SPELL_BLINK = 34605, SPELL_FROSTBOLT = 32364, SPELL_FIREBALL = 32363, SPELL_FROSTNOVA = 32365, - - SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON + SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON SPELL_ETHEREAL_BEACON_VISUAL = 32368, - NPC_BEACON = 18431, - NPC_SHAFFAR = 18344, - - EVENT_SPELL_BEACON = 1, - EVENT_SPELL_FR_FI = 2, - EVENT_SPELL_FROST_NOVA = 3, - EVENT_SPELL_BLINK = 4, + // Yor + SPELL_DOUBLE_BREATH = 38361, + SPELL_STOMP = 36405 }; -class boss_nexusprince_shaffar : public CreatureScript +enum Npc { -public: - boss_nexusprince_shaffar() : CreatureScript("boss_nexusprince_shaffar") { } + NPC_BEACON = 18431 +}; - CreatureAI* GetAI(Creature* creature) const override +struct boss_nexusprince_shaffar : public BossAI +{ + boss_nexusprince_shaffar(Creature* creature) : BossAI(creature, DATA_NEXUSPRINCE_SHAFFAR), summons(me) { - return GetManaTombsAI(creature); + HasTaunted = false; + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } - struct boss_nexusprince_shaffarAI : public ScriptedAI + SummonList summons; + bool HasTaunted; + + void Reset() override { - boss_nexusprince_shaffarAI(Creature* creature) : ScriptedAI(creature), summons(me) - { - HasTaunted = false; - } - - EventMap events; - SummonList summons; - bool HasTaunted; - - void Reset() override - { - float dist = 8.0f; - float posX, posY, posZ, angle; - me->GetHomePosition(posX, posY, posZ, angle); - - summons.DespawnAll(); - events.Reset(); - me->SummonCreature(NPC_BEACON, posX - dist, posY - dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); - me->SummonCreature(NPC_BEACON, posX - dist, posY + dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); - me->SummonCreature(NPC_BEACON, posX + dist, posY, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!HasTaunted && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 100.0f)) - { - Talk(SAY_INTRO); - HasTaunted = true; - } - } - - void JustEngagedWith(Unit*) override - { - Talk(SAY_AGGRO); - - me->SetInCombatWithZone(); - summons.DoZoneInCombat(); - - events.ScheduleEvent(EVENT_SPELL_BEACON, 10000); - events.ScheduleEvent(EVENT_SPELL_FR_FI, 4000); - events.ScheduleEvent(EVENT_SPELL_FROST_NOVA, 15000); - } - - void JustSummoned(Creature* summon) override - { - if (me->IsInCombat() && summon->GetEntry() == NPC_BEACON) - { - summon->CastSpell(summon, SPELL_ETHEREAL_BEACON_VISUAL, false); - if (Unit* target = SelectTargetFromPlayerList(50.0f)) - summon->AI()->AttackStart(target); - } - - summons.Summon(summon); - } - - void SummonedCreatureDespawn(Creature* summon) override - { - summons.Despawn(summon); - } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEAD); - summons.DespawnAll(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_FROST_NOVA: - me->CastSpell(me, SPELL_FROSTNOVA, false); - events.RepeatEvent(urand(16000, 23000)); - events.DelayEvents(1500); - events.ScheduleEvent(EVENT_SPELL_BLINK, 1500); - break; - case EVENT_SPELL_FR_FI: - me->CastSpell(me->GetVictim(), RAND(SPELL_FROSTBOLT, SPELL_FIREBALL), false); - events.RepeatEvent(urand(3000, 4000)); - break; - case EVENT_SPELL_BLINK: - me->CastSpell(me, SPELL_BLINK, false); - events.RescheduleEvent(EVENT_SPELL_FR_FI, 0); - break; - case EVENT_SPELL_BEACON: - if (!urand(0, 3)) - Talk(SAY_SUMMON); - - me->CastSpell(me, SPELL_ETHEREAL_BEACON, true); - events.RepeatEvent(10000); - break; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -enum Yor -{ - SPELL_DOUBLE_BREATH = 38361, - SPELL_STOMP = 36405, - - EVENT_DOUBLE_BREATH = 1, - EVENT_STOMP = 2 -}; - -class npc_yor : public CreatureScript -{ -public: - npc_yor() : CreatureScript("npc_yor") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetManaTombsAI(creature); + _Reset(); + float dist = 8.0f; + float posX, posY, posZ, angle; + me->GetHomePosition(posX, posY, posZ, angle); + summons.DespawnAll(); + me->SummonCreature(NPC_BEACON, posX - dist, posY - dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); + me->SummonCreature(NPC_BEACON, posX - dist, posY + dist, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); + me->SummonCreature(NPC_BEACON, posX + dist, posY, posZ, angle, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000); } - struct npc_yorAI : public ScriptedAI + void MoveInLineOfSight(Unit* who) override { - npc_yorAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override { } - - void JustEngagedWith(Unit* /*who*/) override + if (!HasTaunted && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 100.0f)) { - events.ScheduleEvent(EVENT_DOUBLE_BREATH, urand(26500, 30500)); - events.ScheduleEvent(EVENT_STOMP, urand(12000, 18000)); + HasTaunted = true; + Talk(SAY_INTRO); } + } - void UpdateAI(uint32 diff) override + void JustEngagedWith(Unit*) override + { + _JustEngagedWith(); + Talk(SAY_AGGRO); + summons.DoZoneInCombat(); + scheduler.Schedule(10s, [this](TaskContext context) { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) + if (!urand(0, 3)) { - return; + Talk(SAY_SUMMON); } - - while (uint32 eventId = events.ExecuteEvent()) + DoCastSelf(SPELL_ETHEREAL_BEACON, true); + context.Repeat(10s); + }).Schedule(4s, [this](TaskContext context) + { + DoCastVictim(RAND(SPELL_FROSTBOLT, SPELL_FIREBALL)); + context.Repeat(3s, 4s); + }).Schedule(15s, [this](TaskContext context) + { + DoCastSelf(SPELL_FROSTNOVA); + context.Repeat(16s, 23s); + scheduler.DelayAll(1500ms); + scheduler.Schedule(1500ms, [this](TaskContext /*context*/) { - switch (eventId) - { - case EVENT_DOUBLE_BREATH: - if (me->IsWithinDist(me->GetVictim(), ATTACK_DISTANCE)) - DoCastVictim(SPELL_DOUBLE_BREATH); - events.ScheduleEvent(EVENT_DOUBLE_BREATH, urand(10000, 20000)); - break; - case EVENT_STOMP: - DoCastAOE(SPELL_STOMP); - events.ScheduleEvent(EVENT_STOMP, urand(14000, 24000)); - break; - } + DoCastSelf(SPELL_BLINK); + }); + }); + } + + void JustSummoned(Creature* summon) override + { + if (me->IsInCombat() && summon->GetEntry() == NPC_BEACON) + { + summon->CastSpell(summon, SPELL_ETHEREAL_BEACON_VISUAL, false); + if (Unit* target = SelectTargetFromPlayerList(50.0f)) + { + summon->AI()->AttackStart(target); } - DoMeleeAttackIfReady(); } - private: - EventMap events; - }; + summons.Summon(summon); + } + + void SummonedCreatureDespawn(Creature* summon) override + { + summons.Despawn(summon); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + { + Talk(SAY_SLAY); + } + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEAD); + summons.DespawnAll(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + DoMeleeAttackIfReady(); + } +}; + +struct npc_yor : public ScriptedAI +{ + npc_yor(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override { } + + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(25500ms, 30500ms, [this](TaskContext context) + { + if (me->IsWithinDist(me->GetVictim(), ATTACK_DISTANCE)) + { + DoCastVictim(SPELL_DOUBLE_BREATH); + } + context.Repeat(10s, 20s); + }).Schedule(12s, 18s, [this](TaskContext context) + { + DoCastAOE(SPELL_STOMP); + context.Repeat(14s, 24s); + }); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_nexusprince_shaffar() { - new boss_nexusprince_shaffar(); - new npc_yor(); + RegisterManaTombsCreatureAI(boss_nexusprince_shaffar); + RegisterManaTombsCreatureAI(npc_yor); } diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_tavarok.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_tavarok.cpp index ce0c30e62..e06751164 100644 --- a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_tavarok.cpp +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_tavarok.cpp @@ -23,8 +23,7 @@ enum Spells { SPELL_EARTHQUAKE = 33919, SPELL_CRYSTAL_PRISON = 32361, - SPELL_ARCING_SMASH_N = 8374, - SPELL_ARCING_SMASH_H = 38761 + SPELL_ARCING_SMASH = 8374 }; struct boss_tavarok : public BossAI @@ -45,7 +44,6 @@ struct boss_tavarok : public BossAI void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); - scheduler.Schedule(10s, 14200ms, [this](TaskContext context) { DoCastSelf(SPELL_EARTHQUAKE); @@ -56,7 +54,7 @@ struct boss_tavarok : public BossAI context.Repeat(15s, 22s); }).Schedule(5900ms, [this](TaskContext context) { - DoCastVictim(DUNGEON_MODE(SPELL_ARCING_SMASH_N, SPELL_ARCING_SMASH_H)); + DoCastVictim(SPELL_ARCING_SMASH); context.Repeat(8s, 12s); }); } @@ -66,12 +64,10 @@ struct boss_tavarok : public BossAI _JustDied(); } - void KilledUnit(Unit* /*victim*/) override - { - } + void KilledUnit(Unit* /*victim*/) override {} }; void AddSC_boss_tavarok() { RegisterManaTombsCreatureAI(boss_tavarok); -} \ No newline at end of file +} diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp index 32ffb66d3..5b854ecf6 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp @@ -20,23 +20,25 @@ #include "SpellScript.h" #include "sethekk_halls.h" -enum Anzu +enum Text { SAY_ANZU_INTRO1 = 0, SAY_ANZU_INTRO2 = 1, - SAY_SUMMON = 2, + SAY_SUMMON = 2 +}; +enum Spells +{ SPELL_PARALYZING_SCREECH = 40184, SPELL_SPELL_BOMB = 40303, SPELL_CYCLONE = 40321, SPELL_BANISH_SELF = 42354, - SPELL_SHADOWFORM = 40973, + SPELL_SHADOWFORM = 40973 +}; - EVENT_SPELL_SCREECH = 1, - EVENT_SPELL_BOMB = 2, - EVENT_SPELL_CYCLONE = 3, - EVENT_ANZU_HEALTH1 = 4, - EVENT_ANZU_HEALTH2 = 5 +enum Npc +{ + NPC_BROOD_OF_ANZU = 23132 }; struct boss_anzu : public BossAI @@ -46,6 +48,10 @@ struct boss_anzu : public BossAI talkTimer = 1; me->ReplaceAllUnitFlags(UNIT_FLAG_NON_ATTACKABLE); me->AddAura(SPELL_SHADOWFORM, me); + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); } uint32 talkTimer; @@ -55,18 +61,45 @@ struct boss_anzu : public BossAI summons.Despawn(summon); summons.RemoveNotExisting(); if (summons.empty()) + { me->RemoveAurasDueToSpell(SPELL_BANISH_SELF); + } + } + + void Reset() override + { + _Reset(); + ScheduleHealthCheckEvent({ 66, 33 }, [&] { + SummonBroods(); + scheduler.DelayAll(10s); + }); } void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); - events.Reset(); - events.ScheduleEvent(EVENT_SPELL_SCREECH, 14000); - events.ScheduleEvent(EVENT_SPELL_BOMB, 5000); - events.ScheduleEvent(EVENT_SPELL_CYCLONE, 8000); - events.ScheduleEvent(EVENT_ANZU_HEALTH1, 2000); - events.ScheduleEvent(EVENT_ANZU_HEALTH2, 2001); + scheduler.Schedule(14s, [this](TaskContext context) + { + DoCastSelf(SPELL_PARALYZING_SCREECH); + context.Repeat(23s); + scheduler.DelayAll(3s); + }).Schedule(5s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) + { + DoCast(target, SPELL_SPELL_BOMB); + } + context.Repeat(16s, 24500ms); + scheduler.DelayAll(3s); + }).Schedule(8s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true)) + { + DoCast(target, SPELL_CYCLONE); + } + context.Repeat(22s, 27s); + scheduler.DelayAll(3s); + }); } void SummonBroods() @@ -74,7 +107,9 @@ struct boss_anzu : public BossAI Talk(SAY_SUMMON); me->CastSpell(me, SPELL_BANISH_SELF, true); for (uint8 i = 0; i < 5; ++i) - me->SummonCreature(23132 /*NPC_BROOD_OF_ANZU*/, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + { + me->SummonCreature(NPC_BROOD_OF_ANZU, me->GetPositionX() + 20 * cos((float)i), me->GetPositionY() + 20 * std::sin((float)i), me->GetPositionZ() + 25.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + } } void UpdateAI(uint32 diff) override @@ -99,49 +134,10 @@ struct boss_anzu : public BossAI if (!UpdateVictim()) return; - events.Update(diff); + scheduler.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED)) return; - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_SCREECH: - me->CastSpell(me, SPELL_PARALYZING_SCREECH, false); - events.RepeatEvent(23000); - events.DelayEvents(3000); - break; - case EVENT_SPELL_BOMB: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true)) - me->CastSpell(target, SPELL_SPELL_BOMB, false); - events.RepeatEvent(urand(16000, 24500)); - events.DelayEvents(3000); - break; - case EVENT_SPELL_CYCLONE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45.0f, true)) - me->CastSpell(target, SPELL_CYCLONE, false); - events.RepeatEvent(urand(22000, 27000)); - events.DelayEvents(3000); - break; - case EVENT_ANZU_HEALTH1: - if (me->HealthBelowPct(66)) - { - SummonBroods(); - events.DelayEvents(10000); - return; - } - events.RepeatEvent(1000); - break; - case EVENT_ANZU_HEALTH2: - if (me->HealthBelowPct(33)) - { - SummonBroods(); - events.DelayEvents(10000); - return; - } - events.RepeatEvent(1000); - break; - } - DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp index 45267f342..3ee4ea9fc 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp @@ -19,24 +19,6 @@ #include "ScriptedCreature.h" #include "sethekk_halls.h" -enum Spells -{ - SPELL_FLAME_SHOCK_N = 15039, - SPELL_FLAME_SHOCK_H = 15616, - SPELL_ARCANE_SHOCK_N = 33534, - SPELL_ARCANE_SHOCK_H = 38135, - SPELL_FROST_SHOCK_N = 12548, - SPELL_FROST_SHOCK_H = 21401, - SPELL_SHADOW_SHOCK_N = 33620, - SPELL_SHADOW_SHOCK_H = 38137, - SPELL_CHAIN_LIGHTNING_N = 15659, - SPELL_CHAIN_LIGHTNING_H = 15305, - SPELL_SUMMON_ARC_ELE = 33538, - SPELL_SUMMON_FIRE_ELE = 33537, - SPELL_SUMMON_FROST_ELE = 33539, - SPELL_SUMMON_SHADOW_ELE = 33540 -}; - enum Text { SAY_SUMMON = 0, @@ -45,6 +27,19 @@ enum Text SAY_DEATH = 3 }; +enum Spells +{ + SPELL_FLAME_SHOCK = 15039, + SPELL_ARCANE_SHOCK = 33534, + SPELL_FROST_SHOCK = 12548, + SPELL_SHADOW_SHOCK = 33620, + SPELL_CHAIN_LIGHTNING = 15659, + SPELL_SUMMON_ARC_ELE = 33538, + SPELL_SUMMON_FIRE_ELE = 33537, + SPELL_SUMMON_FROST_ELE = 33539, + SPELL_SUMMON_SHADOW_ELE = 33540 +}; + struct boss_darkweaver_syth : public BossAI { boss_darkweaver_syth(Creature* creature) : BossAI(creature, DATA_DARKWEAVER_SYTH) @@ -58,7 +53,6 @@ struct boss_darkweaver_syth : public BossAI void Reset() override { _Reset(); - ScheduleHealthCheckEvent({90, 50, 10}, [&] { Talk(SAY_SUMMON); DoCastSelf(SPELL_SUMMON_ARC_ELE); @@ -72,26 +66,25 @@ struct boss_darkweaver_syth : public BossAI { _JustEngagedWith(); Talk(SAY_AGGRO); - scheduler.Schedule(2s, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_FLAME_SHOCK_N, SPELL_FLAME_SHOCK_H)); + DoCastRandomTarget(SPELL_FLAME_SHOCK); context.Repeat(10s, 15s); }).Schedule(4s, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_ARCANE_SHOCK_N, SPELL_ARCANE_SHOCK_H)); + DoCastRandomTarget(SPELL_ARCANE_SHOCK); context.Repeat(10s, 15s); }).Schedule(6s, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_FROST_SHOCK_N, SPELL_FROST_SHOCK_H)); + DoCastRandomTarget(SPELL_FROST_SHOCK); context.Repeat(10s, 15s); }).Schedule(8s, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_SHADOW_SHOCK_N, SPELL_SHADOW_SHOCK_H)); + DoCastRandomTarget(SPELL_SHADOW_SHOCK); context.Repeat(10s, 15s); }).Schedule(15s, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_CHAIN_LIGHTNING_N, SPELL_CHAIN_LIGHTNING_H)); + DoCastRandomTarget(SPELL_CHAIN_LIGHTNING); context.Repeat(10s, 15s); }); } @@ -99,17 +92,19 @@ struct boss_darkweaver_syth : public BossAI void JustDied(Unit* /*killer*/) override { _JustDied(); - Talk(SAY_DEATH); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - Talk(SAY_SLAY); + if (victim->GetTypeId() == TYPEID_PLAYER) + { + Talk(SAY_SLAY); + } } }; void AddSC_boss_darkweaver_syth() { RegisterSethekkHallsCreatureAI(boss_darkweaver_syth); -} \ No newline at end of file +} diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp index cc4540ab1..54ee89e29 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp @@ -20,13 +20,13 @@ #include "SpellScript.h" #include "sethekk_halls.h" -enum TailonkingIkiss +enum Text { SAY_INTRO = 0, SAY_AGGRO = 1, SAY_SLAY = 2, SAY_DEATH = 3, - EMOTE_ARCANE_EXP = 4, + EMOTE_ARCANE_EXP = 4 }; enum Spells @@ -38,7 +38,7 @@ enum Spells SPELL_SLOW = 35032, SPELL_POLYMORPH = 38245, SPELL_ARCANE_VOLLEY = 35059, - SPELL_ARCANE_EXPLOSION = 38197, + SPELL_ARCANE_EXPLOSION = 38197 }; struct boss_talon_king_ikiss : public BossAI @@ -55,14 +55,12 @@ struct boss_talon_king_ikiss : public BossAI { _Reset(); _spoken = false; - ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] { me->InterruptNonMeleeSpells(false); DoCastAOE(SPELL_BLINK); DoCastSelf(SPELL_ARCANE_BUBBLE, true); Talk(EMOTE_ARCANE_EXP); - - scheduler.Schedule(1s, [this](TaskContext) + scheduler.Schedule(1s, [this](TaskContext /*context*/) { DoCastAOE(SPELL_ARCANE_EXPLOSION); }).Schedule(6500ms, [this](TaskContext /*context*/) @@ -72,7 +70,7 @@ struct boss_talon_king_ikiss : public BossAI }); ScheduleHealthCheckEvent(20, [&] { - DoCast(me, SPELL_MANA_SHIELD); + DoCastSelf(SPELL_MANA_SHIELD); }); } @@ -89,7 +87,6 @@ struct boss_talon_king_ikiss : public BossAI Talk(SAY_INTRO); _spoken = true; } - ScriptedAI::MoveInLineOfSight(who); } @@ -97,7 +94,6 @@ struct boss_talon_king_ikiss : public BossAI { _JustEngagedWith(); Talk(SAY_AGGRO); - scheduler.Schedule(5s, [this](TaskContext context) { DoCastAOE(SPELL_ARCANE_VOLLEY); @@ -114,7 +110,6 @@ struct boss_talon_king_ikiss : public BossAI } context.Repeat(15s, 17500ms); }); - if (IsHeroic()) { scheduler.Schedule(15s, 25s, [this](TaskContext context) @@ -129,17 +124,18 @@ struct boss_talon_king_ikiss : public BossAI { _JustDied(); Talk(SAY_DEATH); - if (GameObject* coffer = instance->GetGameObject(DATA_GO_TALON_KING_COFFER)) { coffer->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE | GO_FLAG_INTERACT_COND); } } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - if (urand(0, 1)) + if (victim->IsPlayer() && urand(0, 1)) + { Talk(SAY_SLAY); + } } private: diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp index be9060b3c..f54b9ad81 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp @@ -19,23 +19,25 @@ #include "ScriptedCreature.h" #include "shadow_labyrinth.h" -enum eEnums +enum Text { SAY_INTRO = 0, SAY_AGGRO = 1, SAY_HELP = 2, SAY_SLAY = 3, - SAY_DEATH = 4, + SAY_DEATH = 4 +}; +enum Spells +{ SPELL_BANISH = 30231, SPELL_CORROSIVE_ACID = 33551, SPELL_FEAR = 33547, - SPELL_ENRAGE = 34970, - - EVENT_SPELL_CORROSIVE = 1, - EVENT_SPELL_FEAR = 2, - EVENT_SPELL_ENRAGE = 3, + SPELL_ENRAGE = 34970 +}; +enum Misc +{ PATH_ID_START = 1873100, PATH_ID_PATHING = 1873101, @@ -81,7 +83,6 @@ struct boss_ambassador_hellmaw : public BossAI { return; } - me->RemoveAurasDueToSpell(SPELL_BANISH); Talk(SAY_INTRO); DoPlaySoundToSet(me, SOUND_INTRO); @@ -96,9 +97,7 @@ struct boss_ambassador_hellmaw : public BossAI { return; } - Talk(SAY_AGGRO); - scheduler.Schedule(23050ms, 30350ms, [this](TaskContext context) { DoCastVictim(SPELL_CORROSIVE_ACID); @@ -111,12 +110,11 @@ struct boss_ambassador_hellmaw : public BossAI if (IsHeroic()) { - scheduler.Schedule(3min, [this](TaskContext) + scheduler.Schedule(3min, [this](TaskContext /*context*/) { DoCastSelf(SPELL_ENRAGE, true); }); } - _JustEngagedWith(); } @@ -126,7 +124,6 @@ struct boss_ambassador_hellmaw : public BossAI { return; } - ScriptedAI::MoveInLineOfSight(who); } @@ -136,7 +133,6 @@ struct boss_ambassador_hellmaw : public BossAI { return; } - ScriptedAI::AttackStart(who); } @@ -188,7 +184,7 @@ struct boss_ambassador_hellmaw : public BossAI return; } - //Make sure our attack is ready and we aren't currently casting before checking distance + // Make sure our attack is ready and we aren't currently casting before checking distance if (me->isAttackReady()) { // xinef: prevent base and off attack in same time, delay attack at 0.2 sec @@ -199,7 +195,6 @@ struct boss_ambassador_hellmaw : public BossAI me->setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY); } } - me->AttackerStateUpdate(victim, BASE_ATTACK, false, ignoreCasting); me->resetAttackTimer(); } @@ -211,7 +206,6 @@ struct boss_ambassador_hellmaw : public BossAI { me->setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY); } - me->AttackerStateUpdate(victim, OFF_ATTACK, false, ignoreCasting); me->resetAttackTimer(OFF_ATTACK); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp index fb285f7d5..f4b0edeb7 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp @@ -19,32 +19,38 @@ #include "ScriptedCreature.h" #include "shadow_labyrinth.h" -enum BlackheartTheInciter +enum Text { - SPELL_INCITE_CHAOS = 33676, - SPELL_INCITE_CHAOS_B = 33684, //debuff applied to each member of party - SPELL_CHARGE = 33709, - SPELL_WAR_STOMP = 33707, - SPELL_LAUGHTER = 33722, - SAY_INTRO = 0, SAY_AGGRO = 1, SAY_SLAY = 2, SAY_HELP = 3, - SAY_DEATH = 4, + SAY_DEATH = 4 +}; - EVENT_SPELL_INCITE = 1, - EVENT_INCITE_WAIT = 2, - EVENT_SPELL_CHARGE = 3, - EVENT_SPELL_KNOCKBACK = 4, - EVENT_SPELL_WAR_STOMP = 5, +enum Spells +{ + SPELL_INCITE_CHAOS = 33676, + SPELL_INCITE_CHAOS_B = 33684, // debuff applied to each player + SPELL_CHARGE = 33709, + SPELL_WAR_STOMP = 33707, + SPELL_LAUGHTER = 33722 +}; - NPC_INCITE_TRIGGER = 19300 +enum Npc +{ + NPC_INCITE_TRIGGER = 19300 }; struct boss_blackheart_the_inciter : public BossAI { - boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { } + boss_blackheart_the_inciter(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } bool InciteChaos; @@ -72,12 +78,48 @@ struct boss_blackheart_the_inciter : public BossAI void JustEngagedWith(Unit* /*who*/) override { Talk(SAY_AGGRO); - me->CallForHelp(100.0f); - events.ScheduleEvent(EVENT_SPELL_INCITE, 24000); - events.ScheduleEvent(EVENT_INCITE_WAIT, 15000); - events.ScheduleEvent(EVENT_SPELL_CHARGE, urand(30000, 50000)); - events.ScheduleEvent(EVENT_SPELL_WAR_STOMP, urand(16950, 26350)); _JustEngagedWith(); + me->CallForHelp(100.0f); + scheduler.Schedule(24s, [this](TaskContext context) + { + DoCastAOE(SPELL_INCITE_CHAOS); + DoCastSelf(SPELL_LAUGHTER, true); + uint32 inciteTriggerID = NPC_INCITE_TRIGGER; + std::list t_list = me->GetThreatMgr().GetThreatList(); + for (std::list::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr) + { + Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); + if (target && target->IsPlayer()) + { + if (Creature* inciteTrigger = me->SummonCreature(inciteTriggerID++, *target, TEMPSUMMON_TIMED_DESPAWN, 15 * IN_MILLISECONDS)) + { + inciteTrigger->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + } + } + } + DoResetThreatList(); + me->SetImmuneToPC(true); + InciteChaos = true; + scheduler.DelayAll(15s); + context.Repeat(50s, 70s); + scheduler.Schedule(15s, [this](TaskContext /*context*/) + { + me->SetImmuneToPC(false); + InciteChaos = false; + }); + }).Schedule(15s, [this](TaskContext /*context*/) + { + me->SetImmuneToPC(false); + InciteChaos = false; + }).Schedule(30s, 50s, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_CHARGE); + context.Repeat(30s, 50s); + }).Schedule(16950ms, 26350ms, [this](TaskContext context) + { + DoCastAOE(SPELL_WAR_STOMP); + context.Repeat(16950ms, 26350ms); + }); } void EnterEvadeMode(EvadeReason why) override @@ -91,55 +133,9 @@ struct boss_blackheart_the_inciter : public BossAI void UpdateAI(uint32 diff) override { if (!UpdateVictim() && !InciteChaos) - { return; - } - - events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_INCITE_WAIT: - me->SetImmuneToPC(false); - InciteChaos = false; - break; - case EVENT_SPELL_INCITE: - { - DoCastAOE(SPELL_INCITE_CHAOS); - DoCastSelf(SPELL_LAUGHTER, true); - - uint32 inciteTriggerID = NPC_INCITE_TRIGGER; - std::list t_list = me->GetThreatMgr().GetThreatList(); - for (std::list::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr) - { - Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); - - if (target && target->IsPlayer()) - { - if (Creature* inciteTrigger = me->SummonCreature(inciteTriggerID++, *target, TEMPSUMMON_TIMED_DESPAWN, 15 * IN_MILLISECONDS)) - { - inciteTrigger->CastSpell(target, SPELL_INCITE_CHAOS_B, true); - } - } - } - - DoResetThreatList(); - me->SetImmuneToPC(true); - InciteChaos = true; - events.DelayEvents(15000); - events.RepeatEvent(urand(50000, 70000)); - events.ScheduleEvent(EVENT_INCITE_WAIT, 15000); - break; - } - case EVENT_SPELL_CHARGE: - DoCastRandomTarget(SPELL_CHARGE); - events.RepeatEvent(urand(30000, 50000)); - break; - case EVENT_SPELL_WAR_STOMP: - DoCastAOE(SPELL_WAR_STOMP); - events.RepeatEvent(urand(16950, 26350)); - break; - } + scheduler.Update(diff); if (InciteChaos) return; diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp index bb7769ed2..b6eb11830 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -20,47 +20,52 @@ #include "ScriptedCreature.h" #include "shadow_labyrinth.h" -enum GrandmasterVorpil +enum Text { SAY_INTRO = 0, SAY_AGGRO = 1, SAY_HELP = 2, SAY_SLAY = 3, - SAY_DEATH = 4, + SAY_DEATH = 4 +}; +enum Spells +{ + // Vorpil SPELL_RAIN_OF_FIRE = 33617, - SPELL_DRAW_SHADOWS = 33563, SPELL_SHADOWBOLT_VOLLEY = 33841, SPELL_BANISH = 38791, - NPC_VOID_TRAVELER = 19226, + // Void Traveler SPELL_SACRIFICE = 33587, SPELL_SHADOW_NOVA = 33846, SPELL_EMPOWERING_SHADOWS = 33783, - NPC_VOID_PORTAL = 19224, - SPELL_VOID_PORTAL_VISUAL = 33569, + SPELL_VOID_PORTAL_VISUAL = 33569 +}; + +enum Npc +{ + NPC_VOID_TRAVELER = 19226, + NPC_VOID_PORTAL = 19224 }; float VorpilPosition[3] = {-253.548f, -263.646f, 17.0864f}; -//x, y, z, and orientation +// x, y, z, and orientation float VoidPortalCoords[5][4] = { - {-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, //portal A 33566 - {-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, //portal B 33614 - {-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, //portal C 33615 - {-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, //portal D 33567 - {-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} //portal E 33616 + {-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, // portal A 33566 + {-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, // portal B 33614 + {-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, // portal C 33615 + {-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, // portal D 33567 + {-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} // portal E 33616 }; struct boss_grandmaster_vorpil : public BossAI { - boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL) - { - sayIntro = false; - } + boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL), sayIntro(false) {} bool sayIntro, sayHelp; @@ -111,7 +116,6 @@ struct boss_grandmaster_vorpil : public BossAI default: return 4800ms; } - return 1s; } @@ -146,7 +150,6 @@ struct boss_grandmaster_vorpil : public BossAI { Talk(SAY_AGGRO); summonPortals(); - scheduler.Schedule(9700ms, 20s, [this](TaskContext context) { DoCastAOE(SPELL_SHADOWBOLT_VOLLEY); diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index eb153fb78..5bdf88224 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -20,10 +20,8 @@ #include "SpellInfo.h" #include "shadow_labyrinth.h" -enum Murmur +enum Spells { - EMOTE_SONIC_BOOM = 0, - SPELL_SUPPRESSION = 33332, SPELL_SHOCKWAVE = 33686, SPELL_SHOCKWAVE_SERVERSIDE = 33673, @@ -34,12 +32,14 @@ enum Murmur SPELL_MURMUR_WRATH_AOE = 33329, SPELL_MURMUR_WRATH = 33331, - SPELL_SONIC_BOOM_CAST_N = 33923, - SPELL_SONIC_BOOM_CAST_H = 38796, - SPELL_SONIC_BOOM_EFFECT_N = 38795, - SPELL_SONIC_BOOM_EFFECT_H = 33666, - SPELL_MURMURS_TOUCH_N = 33711, - SPELL_MURMURS_TOUCH_H = 38794, + SPELL_SONIC_BOOM_CAST = 33923, + SPELL_SONIC_BOOM_EFFECT = 38795, + SPELL_MURMURS_TOUCH = 33711 +}; + +enum Misc +{ + EMOTE_SONIC_BOOM = 0, GROUP_RESONANCE = 1, GROUP_OOC_CAST = 2, @@ -47,7 +47,7 @@ enum Murmur GUID_MURMUR_NPCS = 1 }; -enum Creatures +enum Npc { NPC_CABAL_SPELLBINDER = 18639 }; @@ -57,7 +57,6 @@ struct boss_murmur : public BossAI boss_murmur(Creature* creature) : BossAI(creature, DATA_MURMUR) { SetCombatMovement(false); - scheduler.SetValidator([this] { return !me->HasUnitState(UNIT_STATE_CASTING); @@ -75,7 +74,6 @@ struct boss_murmur : public BossAI void CastSupressionOOC() { me->m_Events.CancelEventGroup(GROUP_OOC_CAST); - me->m_Events.AddEventAtOffset([this] { if (me->FindNearestCreature(NPC_CABAL_SPELLBINDER, 35.0f)) { @@ -106,13 +104,11 @@ struct boss_murmur : public BossAI { return true; } - if (Unit* victimTarget = victim->GetVictim()) { return victimTarget != me; } } - return true; } @@ -133,23 +129,21 @@ struct boss_murmur : public BossAI { return; } - _JustEngagedWith(); - scheduler.Schedule(28s, [this](TaskContext context) { Talk(EMOTE_SONIC_BOOM); - DoCastAOE(DUNGEON_MODE(SPELL_SONIC_BOOM_CAST_N, SPELL_SONIC_BOOM_CAST_H)); + DoCastAOE(SPELL_SONIC_BOOM_CAST); scheduler.Schedule(1500ms, [this](TaskContext) { - DoCastAOE(DUNGEON_MODE(SPELL_SONIC_BOOM_EFFECT_N, SPELL_SONIC_BOOM_EFFECT_H), true); + DoCastAOE(SPELL_SONIC_BOOM_EFFECT, true); }); context.Repeat(34s, 40s); }).Schedule(14600ms, 25500ms, [this](TaskContext context) { - DoCastRandomTarget(DUNGEON_MODE(SPELL_MURMURS_TOUCH_N, SPELL_MURMURS_TOUCH_H)); + DoCastRandomTarget(SPELL_MURMURS_TOUCH); context.Repeat(14600ms, 25500ms); }).Schedule(15s, 30s, [this](TaskContext context) { @@ -177,7 +171,6 @@ struct boss_murmur : public BossAI }); } } - context.Repeat(); }); @@ -193,7 +186,6 @@ struct boss_murmur : public BossAI context.Repeat(3650ms, 9150ms); }); } - me->m_Events.CancelEventGroup(GROUP_OOC_CAST); } };