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); } |
