From 60c8dc17bcf1504196c2e3442442391a63c855fd Mon Sep 17 00:00:00 2001 From: offl <11556157+offl@users.noreply.github.com> Date: Sat, 16 Aug 2025 15:35:22 +0300 Subject: Scripts/AQ40: Rewrite Fankriss (#31200) --- sql/updates/world/3.3.5/2025_08_16_01_world.sql | 32 +++ src/server/game/Spells/SpellMgr.cpp | 4 +- .../Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp | 297 ++++++++++----------- 3 files changed, 170 insertions(+), 163 deletions(-) create mode 100644 sql/updates/world/3.3.5/2025_08_16_01_world.sql diff --git a/sql/updates/world/3.3.5/2025_08_16_01_world.sql b/sql/updates/world/3.3.5/2025_08_16_01_world.sql new file mode 100644 index 00000000000..d6a1e422a25 --- /dev/null +++ b/sql/updates/world/3.3.5/2025_08_16_01_world.sql @@ -0,0 +1,32 @@ +-- +DELETE FROM `spell_target_position` WHERE `ID` IN (518,25831,25832,26630,26631,26632,720,731,1121); +INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES +(518,0,531,-8028.5,1050.9,-54,0,0), +(25831,0,531,-8158.03,1139.3,-83.95,0,0), +(25832,0,531,-8029.25,1237.78,-85.2285,0,0), +(720,0,531,-8043.6,1254.1,-84.3,0,0), +(731,0,531,-8003,1222.9,-82.1,0,0), +(1121,0,531,-8022.3,1149,-89.1,0,0), +(26630,0,531,-8043.6,1254.1,-84.2167,0,0), +(26631,0,531,-8003,1222.9,-82.0167,0,0), +(26632,0,531,-8022.3,1149,-89.0167,0,0); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15962; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (15630,15962) AND `source_type` = 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`,`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 +(15630,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On AI Initialize - Set Corpse Delay"), +(15630,0,1,0,11,0,100,0,0,0,0,0,0,38,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On Spawn - Set In Combat With Zone"), +(15630,0,2,0,60,0,100,1,20000,20000,0,0,0,11,26662,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On Update - Cast 'Berserk'"), + +(15962,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Vekniss Hatchling - On AI Initialize - Set Corpse Delay"), +(15962,0,1,0,11,0,100,0,0,0,0,0,0,38,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Vekniss Hatchling - On Spawn - Set In Combat With Zone"); + +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_fankriss_entangle'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(720, 'spell_fankriss_entangle'), +(731, 'spell_fankriss_entangle'), +(1121, 'spell_fankriss_entangle'); + +UPDATE `creature_template` SET `speed_run` = 2.14285714286 WHERE `entry` = 15510; +UPDATE `creature_template` SET `speed_run` = 1.71428571429 WHERE `entry` = 15630; +UPDATE `creature_template` SET `speed_run` = 1.42857142857 WHERE `entry` = 15962; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 5dd878fdddb..154faee4783 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3173,7 +3173,9 @@ void SpellMgr::LoadSpellInfoCorrections() ApplySpellFix({ 42818, // Headless Horseman - Wisp Flight Port 42821, // Headless Horseman - Wisp Flight Missile - 17678 // Despawn Spectral Combatants + 17678, // Despawn Spectral Combatants + 720, // Entangle + 731 // Entangle }, [](SpellInfo* spellInfo) { spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp index d13b84e3719..4625edb8525 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp @@ -15,202 +15,175 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Fankriss -SD%Complete: 100 -SDComment: sound not implemented -SDCategory: Temple of Ahn'Qiraj -EndScriptData */ +/* + * Timers requires to be revisited + */ #include "ScriptMgr.h" +#include "Containers.h" #include "ScriptedCreature.h" +#include "SpellInfo.h" +#include "SpellScript.h" #include "temple_of_ahnqiraj.h" -#include "TemporarySummon.h" -#define SOUND_SENTENCE_YOU 8588 -#define SOUND_SERVE_TO 8589 -#define SOUND_LAWS 8590 -#define SOUND_TRESPASS 8591 -#define SOUND_WILL_BE 8592 - -enum Spells +enum FankrissSpells { - SPELL_MORTAL_WOUND = 28467, - SPELL_ROOT = 28858, + SPELL_MORTAL_WOUND = 25646, + + SPELL_SUMMON_WORM_1 = 518, + SPELL_SUMMON_WORM_2 = 25831, + SPELL_SUMMON_WORM_3 = 25832, - // Enrage for his spawns - SPELL_ENRAGE = 28798 + SPELL_ENTANGLE_1 = 720, + SPELL_ENTANGLE_2 = 731, + SPELL_ENTANGLE_3 = 1121, + + SPELL_SPAWN_HATCHLING_1 = 26630, + SPELL_SPAWN_HATCHLING_2 = 26631, + SPELL_SPAWN_HATCHLING_3 = 26632 +}; + +enum FankrissEvents +{ + EVENT_MORTAL_WOUND = 1, + EVENT_SUMMON_WORM, + EVENT_ENTANGLE }; -class boss_fankriss : public CreatureScript +// 15510 - Fankriss the Unyielding +struct boss_fankriss : public BossAI { -public: - boss_fankriss() : CreatureScript("boss_fankriss") { } + boss_fankriss(Creature* creature) : BossAI(creature, DATA_FRANKRIS), _wormsSpawnPerWave(0), _entanglePerWave(0) { } - CreatureAI* GetAI(Creature* creature) const override + std::vector SummonWormSpells = { SPELL_SUMMON_WORM_1, SPELL_SUMMON_WORM_2, SPELL_SUMMON_WORM_3 }; + std::vector EntangleSpells = { SPELL_ENTANGLE_1, SPELL_ENTANGLE_2, SPELL_ENTANGLE_3 }; + + void Reset() override { - return GetAQ40AI(creature); + _Reset(); + _wormsSpawnPerWave = urand(1, 3); + Trinity::Containers::RandomShuffle(SummonWormSpells); + _entanglePerWave = urand(1, 3); + Trinity::Containers::RandomShuffle(EntangleSpells); } - struct boss_fankrissAI : public BossAI + void JustEngagedWith(Unit* who) override { - boss_fankrissAI(Creature* creature) : BossAI(creature, DATA_FRANKRIS) - { - Initialize(); - } + BossAI::JustEngagedWith(who); - void Initialize() - { - MortalWound_Timer = urand(10000, 15000); - SpawnHatchlings_Timer = urand(6000, 12000); - SpawnSpawns_Timer = urand(15000, 45000); - } - - uint32 MortalWound_Timer; - uint32 SpawnHatchlings_Timer; - uint32 SpawnSpawns_Timer; + events.ScheduleEvent(EVENT_MORTAL_WOUND, 2s, 6s); + events.ScheduleEvent(EVENT_SUMMON_WORM, 30s, 50s); + events.ScheduleEvent(EVENT_ENTANGLE, 15s, 20s); + } - void Reset() override - { - Initialize(); - _Reset(); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void SummonSpawn(Unit* victim) - { - if (!victim) - return; + events.Update(diff); - int Rand = 10 + (rand32() % 10); - float RandX = 0.f; - float RandY = 0.f; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - switch (rand32() % 2) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - case 0: RandX = 0.0f - Rand; break; - case 1: RandX = 0.0f + Rand; break; - } + case EVENT_MORTAL_WOUND: + DoCastVictim(SPELL_MORTAL_WOUND); + events.Repeat(4s, 12s); + break; + case EVENT_SUMMON_WORM: + { + DoCastSelf(SummonWormSpells[_wormsSpawnPerWave - 1]); - Rand = 10 + (rand32() % 10); - switch (rand32() % 2) - { - case 0: RandY = 0.0f - Rand; break; - case 1: RandY = 0.0f + Rand; break; - } - Rand = 0; - Creature* Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s); - if (Spawn) - Spawn->AI()->AttackStart(victim); - } + --_wormsSpawnPerWave; - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; + if (!_wormsSpawnPerWave) + { + _wormsSpawnPerWave = urand(1, 3); + Trinity::Containers::RandomShuffle(SummonWormSpells); + events.Repeat(20s, 70s); + } + else + events.Repeat(5s, 20s); + break; + } + case EVENT_ENTANGLE: + { + Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true); - //MortalWound_Timer - if (MortalWound_Timer <= diff) - { - DoCastVictim(SPELL_MORTAL_WOUND); - MortalWound_Timer = urand(10000, 20000); - } else MortalWound_Timer -= diff; + if (!target) + target = me->GetVictim(); - //Summon 1-3 Spawns of Fankriss at random time. - if (SpawnSpawns_Timer <= diff) - { - switch (urand(0, 2)) - { - case 0: - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - break; - case 1: - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - break; - case 2: - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0)); - break; - } - SpawnSpawns_Timer = urand(30000, 60000); - } else SpawnSpawns_Timer -= diff; + if (target) + DoCast(target, EntangleSpells[_entanglePerWave - 1]); - // Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer. - //We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot. - if (HealthAbovePct(3)) - { - if (SpawnHatchlings_Timer <= diff) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) + --_entanglePerWave; + + if (!_entanglePerWave) { - DoCast(target, SPELL_ROOT); - - if (GetThreat(target)) - ModifyThreatByPercent(target, -100); - - Creature* Hatchling = nullptr; - switch (urand(0, 2)) - { - case 0: - DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - break; - case 1: - DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f); - Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - break; - case 2: - DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f); - Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); - if (Hatchling) - Hatchling->AI()->AttackStart(target); - break; - } + _entanglePerWave = urand(1, 3); + Trinity::Containers::RandomShuffle(EntangleSpells); + events.Repeat(25s, 55s); } - SpawnHatchlings_Timer = urand(45000, 60000); - } else SpawnHatchlings_Timer -= diff; + else + events.Repeat(5s, 10s); + break; + } + default: + break; } - DoMeleeAttackIfReady(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } + +private: + uint8 _wormsSpawnPerWave; + uint8 _entanglePerWave; +}; + +// 720, 731, 1121 - Entangle +class spell_fankriss_entangle : public SpellScript +{ + PrepareSpellScript(spell_fankriss_entangle); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SPAWN_HATCHLING_1, SPELL_SPAWN_HATCHLING_2, SPELL_SPAWN_HATCHLING_3 }); + } + + void HandleAfterCast() + { + switch (GetSpellInfo()->Id) + { + case SPELL_ENTANGLE_1: + GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_1, true); + break; + case SPELL_ENTANGLE_2: + GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_2, true); + break; + case SPELL_ENTANGLE_3: + GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_3, true); + break; + default: + break; } - }; + } + void Register() override + { + AfterCast += SpellCastFn(spell_fankriss_entangle::HandleAfterCast); + } }; void AddSC_boss_fankriss() { - new boss_fankriss(); + RegisterAQ40CreatureAI(boss_fankriss); + RegisterSpellScript(spell_fankriss_entangle); } -- cgit v1.2.3