diff options
| -rw-r--r-- | sql/updates/world/3.3.5/2021_12_01_00_world.sql | 14 | ||||
| -rw-r--r-- | src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp | 243 | 
2 files changed, 140 insertions, 117 deletions
diff --git a/sql/updates/world/3.3.5/2021_12_01_00_world.sql b/sql/updates/world/3.3.5/2021_12_01_00_world.sql new file mode 100644 index 00000000000..b7f7e062ea1 --- /dev/null +++ b/sql/updates/world/3.3.5/2021_12_01_00_world.sql @@ -0,0 +1,14 @@ +-- +UPDATE `creature_template` SET `speed_walk` = 1, `speed_run` = 2.14286, `flags_extra` = `flags_extra`|512 WHERE `entry` = 14517; +UPDATE `creature_template_movement` SET `Flight` = 0 WHERE `CreatureId` = 14517; + +DELETE FROM `creature_text` WHERE `CreatureID` = 14517 AND `GroupID` IN (3,4); +INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(14517,3,0,"%s emits a deafening shriek!",16,0,100,0,0,0,10370,0,"High Priestess Jeklik"), +(14517,4,0,"%s begins to cast a Great Heal!",16,0,100,0,0,0,10494,0,"High Priestess Jeklik"); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 23974; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,23974,0,0,31,0,3,14758,0,0,0,0,"","Group 0: Spell 'Summon Frenzied Bloodseeker Bats' (Effect 0) targets creature 'Zul'Gurub Trigger'"); + +UPDATE `creature_template` SET `speed_walk` = 2, `speed_run` = 2.14286, `BaseAttackTime` = 1000, `ScriptName` = 'npc_frenzied_bloodseeker_bat' WHERE `entry` = 14965; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp index 82134003109..55cd1269c18 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp @@ -20,45 +20,60 @@  #include "ScriptMgr.h"  #include "TemporarySummon.h" -enum Says +enum Texts  {      SAY_AGGRO               = 0, -    SAY_RAIN_FIRE           = 1, -    SAY_DEATH               = 2 +    SAY_CALL_RIDERS         = 1, +    SAY_DEATH               = 2, +    EMOTE_SUMMON_BATS       = 3, +    EMOTE_GREAT_HEAL        = 4  };  enum Spells  { -    SPELL_CHARGE            = 22911, -    SPELL_SONICBURST        = 23918, -    SPELL_SCREECH           = 6605, -    SPELL_SHADOW_WORD_PAIN  = 23952, -    SPELL_MIND_FLAY         = 23953, -    SPELL_CHAIN_MIND_FLAY   = 26044, // Right ID unknown. So disabled -    SPELL_GREATERHEAL       = 23954, -    SPELL_BAT_FORM          = 23966, - -    // Batriders Spell -    SPELL_BOMB              = 40332 // Wrong ID but Magmadars bomb is not working... -}; +    // Intro +    SPELL_GREEN_CHANNELING       = 13540, +    SPELL_BAT_FORM               = 23966, -enum BatIds -{ -    NPC_BLOODSEEKER_BAT     = 11368, -    NPC_FRENZIED_BAT        = 14965 +    // Phase one +    SPELL_PIERCE_ARMOR           = 12097, +    SPELL_BLOOD_LEECH            = 22644, +    SPELL_CHARGE                 = 22911, +    SPELL_SONIC_BURST            = 23918, +    SPELL_SWOOP                  = 23919, +    SPELL_SUMMON_BATS            = 23974, + +    // Phase two +    SPELL_CURSE_OF_BLOOD         = 16098, +    SPELL_PSYCHIC_SCREAM         = 22884, +    SPELL_SHADOW_WORD_PAIN       = 23952, +    SPELL_MIND_FLAY              = 23953, +    SPELL_GREAT_HEAL             = 23954, + +    // Frenzied Bloodseeker Bat +    SPELL_ROOT_SELF              = 23973,   // They spawns with this aura + +    // Gurubashi Bat Rider +    SPELL_LIQUID_FIRE_PERIODIC   = 23968,   // Periodically triggers 23969 +    SPELL_LIQUID_FIRE_DAMAGE     = 23970,   // Assumedly used in script of 23969 +    SPELL_SUMMON_LIQUID_FIRE     = 23971    // Assumedly used in script of 23970  };  enum Events  { -    EVENT_CHARGE_JEKLIK     = 1, +    EVENT_PIERCE_ARMOR      = 1, +    EVENT_BLOOD_LEECH, +    EVENT_CHARGE_JEKLIK,      EVENT_SONIC_BURST, -    EVENT_SCREECH, -    EVENT_SPAWN_BATS, +    EVENT_SWOOP, +    EVENT_SUMMON_BATS, + +    EVENT_CURSE_OF_BLOOD, +    EVENT_PSYCHIC_SCREAM,      EVENT_SHADOW_WORD_PAIN,      EVENT_MIND_FLAY, -    EVENT_CHAIN_MIND_FLAY, -    EVENT_GREATER_HEAL, -    EVENT_SPAWN_FLYING_BATS +    EVENT_GREAT_HEAL, +    EVENT_SPAWN_BAT_RIDER  };  enum Phase @@ -67,44 +82,34 @@ enum Phase      PHASE_TWO               = 2  }; -Position const SpawnBat[6] = -{ -    { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, -    { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, -    { -12293.6220f, -1380.2640f, 144.8304f, 5.483f }, -    { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, -    { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, -    { -12293.6220f, -1380.2640f, 144.8304f, 5.483f } -}; -  struct boss_jeklik : public BossAI  { -    boss_jeklik(Creature* creature) : BossAI(creature, DATA_JEKLIK) { } +    boss_jeklik(Creature* creature) : BossAI(creature, DATA_JEKLIK), _calledRiders(false) { }      void Reset() override      { +        DoCastSelf(SPELL_GREEN_CHANNELING); +        _calledRiders = false;          _Reset();      } -    void JustDied(Unit* /*killer*/) override -    { -        _JustDied(); -        Talk(SAY_DEATH); -    } -      void JustEngagedWith(Unit* who) override      {          BossAI::JustEngagedWith(who);          Talk(SAY_AGGRO);          events.SetPhase(PHASE_ONE); -        events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20s, 0, PHASE_ONE); -        events.ScheduleEvent(EVENT_SONIC_BURST, 8s, 0, PHASE_ONE); -        events.ScheduleEvent(EVENT_SCREECH, 13s, 0, PHASE_ONE); -        events.ScheduleEvent(EVENT_SPAWN_BATS, 60s, 0, PHASE_ONE); +        /// @todo: Intro sequence with movement +        events.ScheduleEvent(EVENT_PIERCE_ARMOR, 10s, 20s, 0, PHASE_ONE); +        events.ScheduleEvent(EVENT_BLOOD_LEECH, 10s, 20s, 0, PHASE_ONE); +        events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 10s, 25s, 0, PHASE_ONE); +        events.ScheduleEvent(EVENT_SONIC_BURST, 10s, 25s, 0, PHASE_ONE); +        events.ScheduleEvent(EVENT_SWOOP, 10s, 15s, 0, PHASE_ONE); +        events.ScheduleEvent(EVENT_SUMMON_BATS, 40s, 0, PHASE_ONE); -        me->SetCanFly(true); -        DoCast(me, SPELL_BAT_FORM); +        me->SetDisableGravity(true); +        me->RemoveAurasDueToSpell(SPELL_GREEN_CHANNELING); +        DoCastSelf(SPELL_BAT_FORM, true);      }      void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override @@ -112,17 +117,36 @@ struct boss_jeklik : public BossAI          if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50))          {              me->RemoveAurasDueToSpell(SPELL_BAT_FORM); -            me->SetCanFly(false); +            me->SetDisableGravity(false);              ResetThreatList();              events.SetPhase(PHASE_TWO); -            events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6s, 0, PHASE_TWO); -            events.ScheduleEvent(EVENT_MIND_FLAY, 11s, 0, PHASE_TWO); -            events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26s, 0, PHASE_TWO); -            events.ScheduleEvent(EVENT_GREATER_HEAL, 50s, 0, PHASE_TWO); -            events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10s, 0, PHASE_TWO); +            events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 10s, 20s, 0, PHASE_TWO); +            events.ScheduleEvent(EVENT_PSYCHIC_SCREAM, 25s, 35s, 0, PHASE_TWO); +            events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 10s, 15s, 0, PHASE_TWO); +            events.ScheduleEvent(EVENT_MIND_FLAY, 10s, 30s, 0, PHASE_TWO); +            events.ScheduleEvent(EVENT_GREAT_HEAL, 25s, 0, PHASE_TWO); +        } + +        if (!_calledRiders && !HealthAbovePct(35)) +        { +            _calledRiders = true; +            Talk(SAY_CALL_RIDERS); +            //events.ScheduleEvent(EVENT_SPAWN_BAT_RIDER, 0s, 0, PHASE_TWO);          }      } +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        summons.DespawnAll(); +        _DespawnAtEvade(); +    } + +    void JustDied(Unit* /*killer*/) override +    { +        _JustDied(); +        Talk(SAY_DEATH); +    } +      void UpdateAI(uint32 diff) override      {          if (!UpdateVictim()) @@ -137,54 +161,61 @@ struct boss_jeklik : public BossAI          {              switch (eventId)              { +                // Phase one +                case EVENT_PIERCE_ARMOR: +                    DoCastVictim(SPELL_PIERCE_ARMOR); +                    events.Repeat(20s, 30s); +                    break; +                case EVENT_BLOOD_LEECH: +                    DoCastVictim(SPELL_BLOOD_LEECH); +                    events.Repeat(10s, 20s); +                    break;                  case EVENT_CHARGE_JEKLIK:                      if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true)) -                    {                          DoCast(target, SPELL_CHARGE); -                        AttackStart(target); -                    } -                    events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 15s, 30s, 0, PHASE_ONE); +                    events.Repeat(15s, 30s);                      break;                  case EVENT_SONIC_BURST: -                    DoCastVictim(SPELL_SONICBURST); -                    events.ScheduleEvent(EVENT_SONIC_BURST, 8s, 13s, 0, PHASE_ONE); +                    DoCastSelf(SPELL_SONIC_BURST); +                    events.Repeat(20s, 30s);                      break; -                case EVENT_SCREECH: -                    DoCastVictim(SPELL_SCREECH); -                    events.ScheduleEvent(EVENT_SCREECH, 18s, 26s, 0, PHASE_ONE); +                case EVENT_SWOOP: +                    DoCastVictim(SPELL_SWOOP); +                    events.Repeat(15s, 20s);                      break; -                case EVENT_SPAWN_BATS: -                    if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true)) -                        for (uint8 i = 0; i < 6; ++i) -                            if (TempSummon* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s)) -                                bat->AI()->AttackStart(target); -                    events.ScheduleEvent(EVENT_SPAWN_BATS, 1min, 0, PHASE_ONE); +                case EVENT_SUMMON_BATS: +                    Talk(EMOTE_SUMMON_BATS); +                    DoCastSelf(SPELL_SUMMON_BATS); +                    events.Repeat(1min); +                    break; +                // Phase two +                case EVENT_CURSE_OF_BLOOD: +                    DoCastSelf(SPELL_CURSE_OF_BLOOD); +                    events.Repeat(25s, 30s); +                    break; +                case EVENT_PSYCHIC_SCREAM: +                    DoCastSelf(SPELL_PSYCHIC_SCREAM); +                    events.Repeat(35s, 45s);                      break;                  case EVENT_SHADOW_WORD_PAIN:                      if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true))                          DoCast(target, SPELL_SHADOW_WORD_PAIN); -                    events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 12s, 18s, 0, PHASE_TWO); +                    events.Repeat(10s, 20s);                      break;                  case EVENT_MIND_FLAY:                      DoCastVictim(SPELL_MIND_FLAY); -                    events.ScheduleEvent(EVENT_MIND_FLAY, 16s, 0, PHASE_TWO); -                    break; -                case EVENT_CHAIN_MIND_FLAY: -                    me->InterruptNonMeleeSpells(false); -                    DoCastVictim(SPELL_CHAIN_MIND_FLAY); -                    events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 15s, 30s, 0, PHASE_TWO); +                    events.Repeat(25s, 40s);                      break; -                case EVENT_GREATER_HEAL: -                    me->InterruptNonMeleeSpells(false); -                    DoCast(me, SPELL_GREATERHEAL); -                    events.ScheduleEvent(EVENT_GREATER_HEAL, 25s, 35s, 0, PHASE_TWO); -                    break; -                case EVENT_SPAWN_FLYING_BATS: -                    if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true)) -                        if (TempSummon* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s)) -                            flyingBat->AI()->AttackStart(target); -                    events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10s, 15s, 0, PHASE_TWO); +                case EVENT_GREAT_HEAL: +                    Talk(EMOTE_GREAT_HEAL); +                    DoCastSelf(SPELL_GREAT_HEAL); +                    events.Repeat(25s);                      break; +                /// @todo: One Gurubashi Bat Rider should be spawned at -12301.7 -1371.29 145.092 4.74729 or -12298 -1368.51 145.398 4.79965 +                /// They're uninteractible, passive and simply flies on paths, throwing bombs. Despawns at path end +//              case EVENT_SPAWN_BAT_RIDER: +//                  events.Repeat(10s); +//                  break;                  default:                      break;              } @@ -195,54 +226,32 @@ struct boss_jeklik : public BossAI          DoMeleeAttackIfReady();      } + +private: +    bool _calledRiders;  }; -// Flying Bat -struct npc_batrider : public ScriptedAI +/// @todo: Intro sequence with movement +struct npc_frenzied_bloodseeker_bat : public ScriptedAI  { -    npc_batrider(Creature* creature) : ScriptedAI(creature) -    { -        Initialize(); -    } - -    void Initialize() -    { -        _bombTimer = 2000; -    } +    npc_frenzied_bloodseeker_bat(Creature* creature) : ScriptedAI(creature) { }      void Reset() override      { -        Initialize(); -        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); +        DoZoneInCombat();      } -    void JustEngagedWith(Unit* /*who*/) override { } - -    void UpdateAI(uint32 diff) override +    void UpdateAI(uint32 /*diff*/) override      {          if (!UpdateVictim())              return; -        if (_bombTimer <= diff) -        { -            if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true)) -            { -                DoCast(target, SPELL_BOMB); -                _bombTimer = 5000; -            } -        } -        else -            _bombTimer -= diff; -          DoMeleeAttackIfReady();      } - -private: -    uint32 _bombTimer;  };  void AddSC_boss_jeklik()  {      RegisterZulGurubCreatureAI(boss_jeklik); -    RegisterZulGurubCreatureAI(npc_batrider); +    RegisterZulGurubCreatureAI(npc_frenzied_bloodseeker_bat);  }  | 
