aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2021_12_01_00_world.sql14
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp243
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);
}