From a13601bbc5be675a13b307d75e235497d2a25b32 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Fri, 9 Jun 2023 03:40:24 +0200 Subject: [PATCH] fix(Scripts/Karazhan): Opera Wizard of Oz fight correct start timers for combat as well fixing restart of the event (#16303) --- .../EasternKingdoms/Karazhan/bosses_opera.cpp | 319 +++++++++++------- 1 file changed, 188 insertions(+), 131 deletions(-) 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: