diff --git a/data/sql/updates/pending_db_world/rev_1699988688060367046.sql b/data/sql/updates/pending_db_world/rev_1699988688060367046.sql new file mode 100644 index 000000000..904f476c7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1699988688060367046.sql @@ -0,0 +1,32 @@ +-- Spawns for Razzashi Cobra (11373) +DELETE FROM `creature` WHERE `guid` IN (52323, 52324, 52325, 52326); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(52323, 11373, 0, 0, 309, 0, 0, 1, 1, 0, -12021.2, -1719.73, 39.2625, 0.85, 259200, 0, 0, 15260, 0, 0, 0, 0, 0, '', NULL, 0, NULL), +(52324, 11373, 0, 0, 309, 0, 0, 1, 1, 0, -12029.4, -1714.54, 39.2802, 0.68, 259200, 0, 0, 15260, 0, 0, 0, 0, 0, '', NULL, 0, NULL), +(52325, 11373, 0, 0, 309, 0, 0, 1, 1, 0, -12036.8, -1704.27, 39.9802, 0.45, 259200, 0, 0, 15260, 0, 0, 0, 0, 0, '', NULL, 0, NULL), +(52326, 11373, 0, 0, 309, 0, 0, 1, 1, 0, -12037.7, -1694.2, 39.2746, 0.27, 259200, 0, 0, 15260, 0, 0, 0, 0, 0, '', NULL, 0, NULL); + +-- Remove script from Razzashi Cobra (11373) +UPDATE `creature_template` SET `ScriptName` = '' WHERE (`entry` = 11373); + +-- Update SAI for Razzaishi Cobra (11373) +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 11373) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(11373, 0, 0, 0, 0, 0, 100, 0, 8000, 8000, 15000, 15000, 0, 0, 11, 24097, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Razzashi Cobra - In Combat - Cast \'Poison\''); + +-- High Priest Venoxis (GUID: 49194) and Razzashi Cobra (GUID: 52323-52326) creature formation +DELETE FROM `creature_formations` WHERE `leaderGUID` = 49194; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(49194, 49194, 0, 0, 27, 0, 0), +(49194, 52323, 0, 0, 27, 0, 0), +(49194, 52324, 0, 0, 27, 0, 0), +(49194, 52325, 0, 0, 27, 0, 0), +(49194, 52326, 0, 0, 27, 0, 0); + +-- High Priest Venoxis (GUID: 49194) and Razzashi Cobra (GUID: 52323-52326) linked respawn +DELETE FROM `linked_respawn` WHERE `linkedGuid` = 49194; +INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`) VALUES +(52323, 49194, 0), +(52324, 49194, 0), +(52325, 49194, 0), +(52326, 49194, 0); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp index 6143b32c3..959c50dc1 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp @@ -33,43 +33,25 @@ enum Says enum Spells { - // troll form + // High Priest Venoxis (14507) + // All Phases SPELL_THRASH = 3391, + + // Phase 1 - Troll Form SPELL_DISPEL_MAGIC = 23859, SPELL_RENEW = 23895, SPELL_HOLY_NOVA = 23858, SPELL_HOLY_FIRE = 23860, SPELL_HOLY_WRATH = 23979, - // snake form + + // Transform + SPELL_VENOXIS_TRANSFORM = 23849, + + // Phase 2 - Snake Form SPELL_POISON_CLOUD = 23861, SPELL_VENOM_SPIT = 23862, - - SPELL_PARASITIC_SERPENT = 23865, SPELL_SUMMON_PARASITIC_SERPENT = 23866, - SPELL_PARASITIC_SERPENT_TRIGGER = 23867, - // used when swapping event-stages - SPELL_VENOXIS_TRANSFORM = 23849, // 50% health - shapechange to cobra - SPELL_FRENZY = 8269, // 20% health - frenzy - SPELL_POISON = 24097 -}; - -enum Events -{ - // troll form - EVENT_THRASH = 1, - EVENT_DISPEL_MAGIC = 2, - EVENT_RENEW = 3, - EVENT_HOLY_NOVA = 4, - EVENT_HOLY_FIRE = 5, - EVENT_HOLY_WRATH = 6, - // phase-changing - EVENT_TRANSFORM = 7, - // snake form events - EVENT_POISON_CLOUD = 8, - EVENT_VENOM_SPIT = 9, - EVENT_PARASITIC_SERPENT = 10, - EVENT_FRENZY = 11, - EVENT_POISON + SPELL_FRENZY = 8269, }; enum Phases @@ -80,275 +62,114 @@ enum Phases enum NPCs { - NPC_PARASITIC_SERPENT = 14884, - NPC_RAZZASHI_COBRA = 11373, - BOSS_VENOXIS = 14507 + BOSS_VENOXIS = 14507, + NPC_RAZZASHI_COBRA = 11373, + NPC_PARASITIC_SERPENT = 14884 }; -class boss_venoxis : public CreatureScript +// High Priest Venoxis (14507) +struct boss_venoxis : public BossAI { public: - boss_venoxis() : CreatureScript("boss_venoxis") { } + boss_venoxis(Creature* creature) : BossAI(creature, DATA_VENOXIS) { } - struct boss_venoxisAI : public BossAI + void InitializeAI() override { - boss_venoxisAI(Creature* creature) : BossAI(creature, DATA_VENOXIS) { } - - void Reset() override + scheduler.SetValidator([this] { - _Reset(); - // remove all spells and auras from previous attempts - me->RemoveAllAuras(); - me->SetReactState(REACT_PASSIVE); - // set some internally used variables to their defaults - _inMeleeRange = 0; - _transformed = false; - _frenzied = false; - events.SetPhase(PHASE_ONE); + return !me->HasUnitState(UNIT_STATE_CASTING); + }); - SpawnCobras(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_VENOXIS_DEATH); - me->RemoveAllAuras(); - } - - void SpawnCobras() - { - me->SummonCreature(NPC_RAZZASHI_COBRA, -12021.20f, -1719.73f, 39.34f, 0.85f, TEMPSUMMON_CORPSE_DESPAWN); - me->SummonCreature(NPC_RAZZASHI_COBRA, -12029.40f, -1714.54f, 39.36f, 0.68f, TEMPSUMMON_CORPSE_DESPAWN); - me->SummonCreature(NPC_RAZZASHI_COBRA, -12036.79f, -1704.27f, 40.06f, 0.45f, TEMPSUMMON_CORPSE_DESPAWN); - me->SummonCreature(NPC_RAZZASHI_COBRA, -12037.70f, -1694.20f, 39.35f, 0.27f, TEMPSUMMON_CORPSE_DESPAWN); - } - - void SetCombatCombras() - { - std::list cobraList; - me->GetCreatureListWithEntryInGrid(cobraList, NPC_RAZZASHI_COBRA, 50.0f); - - if (!cobraList.empty()) - { - for (auto& cobras : cobraList) - { - cobras->SetInCombatWithZone(); - } - } - } - - void JustEngagedWith(Unit* /*who*/) override - { - _JustEngagedWith(); - me->SetReactState(REACT_AGGRESSIVE); - // Always running events - events.ScheduleEvent(EVENT_THRASH, 5s); - // Phase one events (regular form) - events.ScheduleEvent(EVENT_HOLY_NOVA, 5s, 15s, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35s, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_HOLY_FIRE, 10s, 20s, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_RENEW, 30s, 0, PHASE_ONE); - events.ScheduleEvent(EVENT_HOLY_WRATH, 15s, 25s, 0, PHASE_ONE); - - events.SetPhase(PHASE_ONE); - - // Set zone in combat - DoZoneInCombat(); - SetCombatCombras(); - } - - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override - { - // check if venoxis is ready to transform - if (!_transformed && !HealthAbovePct(50)) - { - _transformed = true; - // schedule the event that changes our phase - events.ScheduleEvent(EVENT_TRANSFORM, 100ms); - } - // we're losing health, bad, go frenzy - else if (!_frenzied && !HealthAbovePct(20)) - { - _frenzied = true; - events.ScheduleEvent(EVENT_FRENZY, 100ms); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - // return back to main code if we're still casting - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - // thrash is available in all phases - case EVENT_THRASH: - DoCast(me, SPELL_THRASH, true); - events.ScheduleEvent(EVENT_THRASH, 10s, 20s); - break; - - // troll form spells and Actions (first part) - case EVENT_DISPEL_MAGIC: - DoCast(me, SPELL_DISPEL_MAGIC); - events.ScheduleEvent(EVENT_DISPEL_MAGIC, 15s, 20s, 0, PHASE_ONE); - break; - case EVENT_RENEW: - DoCast(me, SPELL_RENEW); - events.ScheduleEvent(EVENT_RENEW, 25s, 30s, 0, PHASE_ONE); - break; - case EVENT_HOLY_WRATH: - if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat)) - DoCast(target, SPELL_HOLY_WRATH); - events.ScheduleEvent(EVENT_HOLY_WRATH, 12s, 22s, 0, PHASE_ONE); - break; - case EVENT_HOLY_FIRE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - DoCast(target, SPELL_HOLY_FIRE); - events.ScheduleEvent(EVENT_HOLY_FIRE, 10s, 24s, 0, PHASE_ONE); - break; - case EVENT_HOLY_NOVA: - DoCastSelf(SPELL_HOLY_NOVA); - events.ScheduleEvent(EVENT_HOLY_NOVA, 10s, 24s, 0, PHASE_ONE); - break; - - // - // snake form spells and Actions - // - - case EVENT_VENOM_SPIT: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - DoCast(target, SPELL_VENOM_SPIT); - events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 15s, 0, PHASE_TWO); - break; - case EVENT_POISON_CLOUD: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - DoCast(target, SPELL_POISON_CLOUD); - events.ScheduleEvent(EVENT_POISON_CLOUD, 15s, 20s, 0, PHASE_TWO); - break; - case EVENT_PARASITIC_SERPENT: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT); - events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15s, 0, PHASE_TWO); - break; - case EVENT_FRENZY: - // frenzy at 20% health - DoCast(me, SPELL_FRENZY, true); - break; - - // - // shape and phase-changing - // - - case EVENT_TRANSFORM: - // shapeshift at 50% health - DoCast(me, SPELL_VENOXIS_TRANSFORM); - Talk(SAY_VENOXIS_TRANSFORM); - DoResetThreatList(); - - // phase two events (snakeform) - events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_CLOUD, 10s, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30s, 0, PHASE_TWO); - - // transformed, start phase two - events.SetPhase(PHASE_TWO); - - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - uint8 _inMeleeRange; - bool _transformed; - bool _frenzied; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI(creature); + Reset(); } -}; -class npc_razzashi_cobra_venoxis : public CreatureScript -{ -public: - npc_razzashi_cobra_venoxis() : CreatureScript("npc_razzashi_cobra_venoxis") {} - - struct npc_razzashi_cobra_venoxis_AI : public ScriptedAI + void Reset() override { - npc_razzashi_cobra_venoxis_AI(Creature* creature) : ScriptedAI(creature) {} + BossAI::Reset(); - EventMap events; + me->RemoveAllAuras(); + me->SetReactState(REACT_PASSIVE); + } - void Reset() - { - events.Reset(); - } - - void JustEngagedWith(Unit*) - { - events.ScheduleEvent(EVENT_POISON, 8s); - - if (Creature* Venoxis = GetVenoxis()) - { - Venoxis->SetInCombatWithZone(); - } - } - - Creature* GetVenoxis() - { - return me->FindNearestCreature(BOSS_VENOXIS, 200.0f, true); - } - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_POISON: - { - me->CastSpell(me->GetVictim(), SPELL_POISON); - events.ScheduleEvent(EVENT_POISON, 15s); - break; - } - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void JustEngagedWith(Unit* /*who*/) override { - return new npc_razzashi_cobra_venoxis_AI(creature); + _JustEngagedWith(); + me->SetReactState(REACT_AGGRESSIVE); + + // Both phases + scheduler.Schedule(8s, [this](TaskContext context) + { + DoCastSelf(SPELL_THRASH, true); + context.Repeat(10s, 20s); + }); + + // + // Phase 1 - Troll Form + // + scheduler.Schedule(5s, 15s, PHASE_ONE, [this](TaskContext context) + { + DoCastSelf(SPELL_HOLY_NOVA); + context.Repeat(10s, 24s); + }).Schedule(35s, PHASE_ONE, [this](TaskContext context) + { + DoCastSelf(SPELL_DISPEL_MAGIC); + context.Repeat(15s, 20s); + }).Schedule(10s, 20s, PHASE_ONE, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_HOLY_FIRE); + context.Repeat(10s, 24s); + }).Schedule(30s, PHASE_ONE, [this](TaskContext context) + { + DoCastSelf(SPELL_RENEW); + context.Repeat(25s, 30s); + }).Schedule(15s, 25s, PHASE_ONE, [this](TaskContext context) + { + DoCastRandomTarget(SPELL_HOLY_WRATH); + context.Repeat(12s, 22s); + }); + + // + // Phase 2 - Snake Form (50% health) + // + ScheduleHealthCheckEvent(50, [&] + { + scheduler.CancelGroup(PHASE_ONE); + + DoCastSelf(SPELL_VENOXIS_TRANSFORM); + Talk(SAY_VENOXIS_TRANSFORM); + DoResetThreatList(); + + scheduler.Schedule(5s, PHASE_TWO, [this](TaskContext context) + { + DoCastSelf(SPELL_VENOM_SPIT); + context.Repeat(5s, 15s); + }).Schedule(10s, PHASE_TWO, [this](TaskContext context) + { + DoCastSelf(SPELL_POISON_CLOUD); + context.Repeat(15s, 20s); + }).Schedule(30s, PHASE_TWO, [this](TaskContext context) + { + DoCastSelf(SPELL_SUMMON_PARASITIC_SERPENT); + context.Repeat(15s); + }); + + // frenzy at 20% health + ScheduleHealthCheckEvent(20, [&] + { + DoCastSelf(SPELL_FRENZY, true); + }); + }); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_VENOXIS_DEATH); + me->RemoveAllAuras(); // removes transform } }; void AddSC_boss_venoxis() { - new boss_venoxis(); - new npc_razzashi_cobra_venoxis(); + RegisterCreatureAI(boss_venoxis); }