diff --git a/sql/updates/world/master/2026_04_03_00_world.sql b/sql/updates/world/master/2026_04_03_00_world.sql new file mode 100644 index 0000000000..2c244f05d8 --- /dev/null +++ b/sql/updates/world/master/2026_04_03_00_world.sql @@ -0,0 +1,98 @@ +-- Instance +DELETE FROM `instance_template` WHERE `map`=2651; +INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES +(2651, 0, 'instance_darkflame_cleft'); + +-- Areatriggers +DELETE FROM `areatrigger_create_properties` WHERE (`IsCustom`=0 AND `Id` IN (29999, 29904, 29906)); +INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES +(29999, 0, 33619, 0, 4, 0, 0, 0, 0, -1, 0, 82, NULL, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 'at_the_candle_king_cursed_wax', 59679), -- Spell: 421648 (Cursed Wax) +(29904, 0, 33535, 0, 6, 0, 69049, 0, 0, -1, 0, 0, NULL, 60000, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 'at_the_candle_king_molten_wax', 59679), -- Spell: 420691 (Molten Wax) +(29906, 0, 33535, 0, 6, 0, 69050, 0, 0, -1, 0, 0, NULL, 45000, 0, 0, 1.5, 1.5, 0, 0, 0, 0, 0, 0, 'at_the_candle_king_molten_wax', 59679); -- Spell: 420963 (Molten Wax) + +DELETE FROM `areatrigger_template` WHERE (`IsCustom`=0 AND `Id` IN (33535, 33619)); +INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `VerifiedBuild`) VALUES +(33535, 0, 59679), +(33619, 0, 59679); + +-- Custom AT +DELETE FROM `areatrigger` WHERE `SpawnId`=888888; +INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES +(888888, 888888, 1, 2651, '1,2,8,23', 119.2231, -154.7091, 73.8308, 3.152349, 0, 0, 0, '', 'Darkflame Cleft - The Candle King encounter - Candlelight', 66192); + +DELETE FROM `areatrigger_create_properties` WHERE `Id`=888888 AND `IsCustom`=1; +INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `SpeedIsTime`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES +(888888, 1, 888888, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 0, 1, 32, 50, 5, 32, 50, 5, 0, 0, 'at_the_candle_king_candlelight', 0); + +DELETE FROM `areatrigger_template` WHERE `Id`=888888 AND `IsCustom`=1; +INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `ActionSetId`, `ActionSetFlags`, `VerifiedBuild`) VALUES +(888888, 1, 1, 0, 0, 0); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (421153, 421156, 420919); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 421153, 0, 0, 51, 0, 5, 209603, 0, '', 0, 0, 0, '', 'Spell \'Candleburn\' can only hit \'Wax Statue\''), +(13, 1, 421156, 0, 0, 51, 0, 5, 209791, 0, '', 0, 0, 0, '', 'Spell \'Candleburn\' can only hit \'Wax Chunk\''), +(13, 1, 420919, 0, 0, 51, 0, 6, 0, 0, '', 0, 0, 0, '', 'Spell \'Eerie Molds\' can only hit player'); + +-- Spells +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_the_candle_king_throw_darkflame_selector', 'spell_the_candle_king_throw_darkflame_missile', 'spell_the_candle_king_eerie_molds_clone_summoner', 'spell_the_candle_king_eerie_molds_selector', 'spell_the_candle_king_cursed_wax', 'spell_the_candle_king_darkflame_pickaxe_selector', +'spell_the_candle_king_darkflame_pickaxe_cast'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(420677, 'spell_the_candle_king_eerie_molds_clone_summoner'), +(420659, 'spell_the_candle_king_eerie_molds_selector'), +(422079, 'spell_the_candle_king_cursed_wax'), +(421274, 'spell_the_candle_king_darkflame_pickaxe_selector'), +(421277, 'spell_the_candle_king_darkflame_pickaxe_cast'), +(420696, 'spell_the_candle_king_throw_darkflame_selector'), +(421250, 'spell_the_candle_king_throw_darkflame_missile'); + +-- Creature +DELETE FROM `creature_template_addon` WHERE `entry` IN (209791, 209603); +INSERT INTO `creature_template_addon` (`entry`, `PathId`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES +(209791, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, ''), -- 209791 (Wax Chunk) +(209603, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, ''); -- 209603 (Wax Statue) + +DELETE FROM `creature_template_difficulty` WHERE (`DifficultyID`=23 AND `Entry` IN (208745, 209791, 209603)); +INSERT INTO `creature_template_difficulty` (`Entry`, `DifficultyID`, `LevelScalingDeltaMin`, `LevelScalingDeltaMax`, `ContentTuningID`, `StaticFlags1`, `StaticFlags2`, `StaticFlags3`, `StaticFlags4`, `StaticFlags5`, `StaticFlags6`, `StaticFlags7`, `StaticFlags8`, `VerifiedBuild`) VALUES +(208745, 23, 2, 2, 1279, 0x10000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 59679), -- 208745 (The Candle King) - CanSwim +(209791, 23, 0, 0, 1279, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 59679), -- 209791 (Wax Chunk) - +(209603, 23, 0, 0, 1279, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 59679); -- 209603 (Wax Statue) - + +UPDATE `creature_template_difficulty` SET `HealthScalingExpansion`=10 WHERE (`Entry`=209791 AND `DifficultyID`=0); -- Wax Chunk +UPDATE `creature_template_difficulty` SET `HealthScalingExpansion`=10 WHERE (`Entry`=209603 AND `DifficultyID`=0); -- Wax Statue + +UPDATE `creature_template` SET `ScriptName` = 'boss_the_candle_king' WHERE `entry`=208745; +UPDATE `creature_template` SET `faction`=35, `speed_walk`=0.400000005960464477, `speed_run`=0.142857149243354797, `BaseAttackTime`=1500, `unit_flags`=0x2000300, `unit_flags3`=0x1080001, `AIName`='SmartAI' WHERE `entry`=209791; -- Wax Chunk +UPDATE `creature_template` SET `faction`=35, `speed_walk`=0.400000005960464477, `speed_run`=0.142857149243354797, `BaseAttackTime`=1500, `unit_flags`=0x2000300, `unit_flags3`=0x1080001, `AIName`='SmartAI' WHERE `entry`=209603; -- Wax Statue + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID`=208745; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(208745, 0, 0, 'You. No. Take. CANDLE!', 14, 0, 100, 0, 0, 247825, 262503, 0, 'The Candle King'), +(208745, 1, 0, 'I mold you now!', 14, 0, 33, 0, 0, 247831, 262509, 0, 'The Candle King'), +(208745, 1, 1, 'I make you candle!', 14, 0, 33, 0, 0, 247829, 262507, 0, 'The Candle King'), +(208745, 1, 2, 'Wax and ruin!', 14, 0, 33, 0, 0, 247830, 262508, 0, 'The Candle King'), +(208745, 2, 0, '|TInterface\\Icons\\INV_Shadowflames_Wave:20|t%s targets you with |cFFFF0000|Hspell:421282|h[Darkflame Pickaxe]|h|r!', 42, 0, 100, 0, 0, 0, 0, 0, 'The Candle King'), -- Unknown broadcast_text +(208745, 3, 0, 'This why I king and you dead.', 14, 0, 100, 0, 0, 247832, 262510, 0, 'The Candle King'), +(208745, 4, 0, 'You die!', 14, 0, 33, 0, 0, 247826, 262504, 0, 'The Candle King'), +(208745, 4, 1, 'Snuffed out!', 14, 0, 33, 0, 0, 247827, 262505, 0, 'The Candle King'), +(208745, 4, 2, 'Weaklings!', 14, 0, 33, 0, 0, 247828, 262506, 0, 'The Candle King'), +(208745, 5, 0, 'But I... the king...', 14, 0, 100, 0, 0, 28232, 262511, 0, 'The Candle King'); + +-- SAI +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (209603, 209791) AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `Difficulties`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param_string`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `action_param7`, `action_param_string`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_param_string`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(209603, 0, 0, 1, '', 11, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420677, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Respawn - Cast \'Eerie Molds\''), +(209603, 0, 1, 2, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420918, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Linked - Cast \'Eerie Molds\''), +(209603, 0, 2, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 426011, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Linked - Cast \'Eerie Molds\''), +(209603, 0, 3, 0, '8,23', 11, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 421648, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue (Difficulties Mythic and M+) - On Respawn - Cast \'Cursed Wax\''), +(209603, 0, 4, 5, '', 8, 0, 100, 0, 421153, 0, 0, 0, 0, '', 28, 420918, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Spellhit - Remove Aura \'Eerie Molds\''), +(209603, 0, 5, 6, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420959, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Linked - Cast \'Molten Wax\''), +(209603, 0, 6, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420691, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Linked - Cast \'Molten Wax\''), +(209603, 0, 7, 0, '8,23', 8, 0, 100, 0, 421153, 0, 0, 0, 0, '', 28, 421648, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue (Difficulties Mythic and M+) - On Spellhit - Remove Aura \'Cursed Wax\''), +(209603, 0, 8, 9, '', 8, 0, 100, 0, 421283, 0, 0, 0, 0, '', 11, 420939, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Spellhit - Cast \'Rupture\''), +(209603, 0, 9, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 41, 1000, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Statue - On Linked - Despawn after 1 second'), +(209791, 0, 0, 0, '', 11, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420932, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Chunk - On Respawn - Cast \'Wax Chunk\''), +(209791, 0, 1, 2, '', 8, 0, 100, 0, 421156, 0, 0, 0, 0, '', 11, 420963, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Chunk - On Spellhit - Cast \'Molten Wax\''), +(209791, 0, 2, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 11, 420959, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Wax Chunk - On Linked - Cast \'Molten Wax\''); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4c6fab2c0d..4188177476 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -5103,6 +5103,31 @@ void SpellMgr::LoadSpellInfoCorrections() // ENDOF JADE FOREST SPELLS // + // + // DARKFLAME CLEFT SPELLS + // + + // Darkflame Pickaxe + ApplySpellFix({ 421277 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT; + }); + + // Throw Darkflame + ApplySpellFix({ 420696 }, [](SpellInfo* spellInfo) + { + spellInfo->Attributes |= SPELL_ATTR0_AURA_IS_DEBUFF; + }); + + // Throw Darkflame + ApplySpellFix({ 421250 }, [](SpellInfo* spellInfo) + { + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(165); // 7s + }); + + // ENDOF DARKFLAME CLEFT SPELLS + // + // Earthquake ApplySpellFix({ 61882 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/KhazAlgar/DarkflameCleft/boss_the_candle_king.cpp b/src/server/scripts/KhazAlgar/DarkflameCleft/boss_the_candle_king.cpp new file mode 100644 index 0000000000..0683a7d347 --- /dev/null +++ b/src/server/scripts/KhazAlgar/DarkflameCleft/boss_the_candle_king.cpp @@ -0,0 +1,529 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AreaTrigger.h" +#include "AreaTriggerAI.h" +#include "Creature.h" +#include "GridNotifiersImpl.h" +#include "InstanceScript.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuras.h" +#include "SpellHistory.h" +#include "SpellMgr.h" +#include "SpellScript.h" +#include "darkflame_cleft.h" + +enum TheCandleKingSpells +{ + SPELL_CURSED_WAX = 421648, + SPELL_CURSED_WAX_DUMMY = 422079, + SPELL_CURSED_WAX_STUN = 421653, + SPELL_CURSED_WAX_VISUAL = 422088, // Unk purpose + SPELL_DARKFLAME_PICKAXE_SELECTOR = 421274, + SPELL_DARKFLAME_PICKAXE_CAST = 421277, + SPELL_DARKFLAME_PICKAXE_MARKER = 422648, + SPELL_DARKFLAME_PICKAXE_DAMAGE = 421282, + SPELL_DARKFLAME_PICKAXE_VISUAL = 421283, + SPELL_DARKLIGHT = 426152, + SPELL_DARKLIGHT_DEBUFF = 426127, + SPELL_CANDLELIGHT = 426125, + SPELL_EERIE_MOLDS_CLONE_SUMMONER = 420676, + SPELL_EERIE_MOLDS_SELECTOR = 420659, + SPELL_EERIE_MOLDS_SUMMON = 420665, + SPELL_MOLTEN_WAX_AT = 420691, + SPELL_MOLTEN_WAX_DAMAGE = 421067, + SPELL_PARANOID_MIND = 426145, + SPELL_THROW_DARKFLAME_SELECTOR = 420696, + SPELL_THROW_DARKFLAME_MARKER = 421250, + SPELL_THROW_DARKFLAME_MISSILE = 421145 +}; + +enum TheCandleKingTexts +{ + SAY_AGGRO = 0, + SAY_EERIE_MOLDS = 1, + SAY_PICKAXE_WARNING = 2, + SAY_WIPE = 3, + SAY_KILL = 4, + SAY_DEATH = 5 +}; + +enum TheCandleKingEvents +{ + EVENT_EERIE_MOLDS = 1, + EVENT_PARANOID_MIND, + EVENT_DARKFLAME_PICKAXE, + EVENT_THROW_DARKFLAME +}; + +enum TheCandleKingMisc +{ + NPC_WAX_STATUE = 209603, + NPC_WAX_CHUNK = 209791, +}; + +// 208745 - The Candle King +struct boss_the_candle_king : public BossAI +{ + boss_the_candle_king(Creature* creature) : BossAI(creature, DATA_THE_CANDLE_KING) { } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->SetBossState(DATA_THE_CANDLE_KING, DONE); + + RemoveWaxStatues(); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->SetBossState(DATA_THE_CANDLE_KING, FAIL); + + Talk(SAY_WIPE); + + _EnterEvadeMode(); + _DespawnAtEvade(); + RemoveWaxStatues(); + } + + void RemoveWaxStatues() + { + std::list waxStatues; + GetCreatureListWithEntryInGrid(waxStatues, me, NPC_WAX_STATUE, 200.0f); + GetCreatureListWithEntryInGrid(waxStatues, me, NPC_WAX_CHUNK, 200.0f); + + for (Creature* waxStatue : waxStatues) + waxStatue->DespawnOrUnsummon(); + } + + void KilledUnit(Unit* victim) override + { + if (!victim->IsPlayer()) + return; + + Talk(SAY_KILL); + } + + void OnSpellStart(SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_EERIE_MOLDS_SELECTOR) + Talk(SAY_EERIE_MOLDS); + } + + void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override + { + if (!target->IsPlayer()) + return; + + if (spellInfo->Id == SPELL_DARKFLAME_PICKAXE_SELECTOR) + Talk(SAY_PICKAXE_WARNING, target); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + instance->SetBossState(DATA_THE_CANDLE_KING, IN_PROGRESS); + + Talk(SAY_AGGRO); + + DoCastSelf(SPELL_DARKLIGHT); + + events.ScheduleEvent(EVENT_EERIE_MOLDS, 6s); + events.ScheduleEvent(EVENT_PARANOID_MIND, 10500ms); + events.ScheduleEvent(EVENT_DARKFLAME_PICKAXE, 13200ms); + events.ScheduleEvent(EVENT_THROW_DARKFLAME, 19300ms); + } + + Milliseconds GetCooldownOfSpell(uint32 spellId) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetDifficulty()); + if (!spellInfo) + return 0ms; + + return me->GetSpellHistory()->GetRemainingCooldown(spellInfo); + } + + bool TryCastSpellIfReady(uint32 spellId) + { + Milliseconds cd = GetCooldownOfSpell(spellId); + if (cd == 0ms) + { + DoCastSelf(spellId); + return true; + } + + events.Repeat(cd); + return false; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_EERIE_MOLDS: + { + if (TryCastSpellIfReady(SPELL_EERIE_MOLDS_SELECTOR)) + events.Repeat(IsMythic() ? 23100ms : 31500ms); + break; + } + case EVENT_PARANOID_MIND: + { + if (TryCastSpellIfReady(SPELL_PARANOID_MIND)) + events.Repeat(IsMythic() ? 10900ms : 20600ms); + break; + } + case EVENT_DARKFLAME_PICKAXE: + { + if (TryCastSpellIfReady(SPELL_DARKFLAME_PICKAXE_SELECTOR)) + events.Repeat(IsMythic() ? 23100ms : 17s); + break; + } + case EVENT_THROW_DARKFLAME: + { + if (TryCastSpellIfReady(SPELL_THROW_DARKFLAME_SELECTOR)) + events.Repeat(IsMythic() ? 24300ms : 17s); + break; + } + default: + break; + } + } + } +}; + +// 420677 - Eerie Molds +class spell_the_candle_king_eerie_molds_clone_summoner : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_EERIE_MOLDS_CLONE_SUMMONER }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), SPELL_EERIE_MOLDS_CLONE_SUMMONER, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_eerie_molds_clone_summoner::HandleHit, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +// 420659 - Eerie Molds +class spell_the_candle_king_eerie_molds_selector : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_EERIE_MOLDS_SUMMON }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) const + { + Unit* target = GetHitUnit(); + target->CastSpell(target, SPELL_EERIE_MOLDS_SUMMON, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_eerie_molds_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 420696 - Throw Darkflame +class spell_the_candle_king_throw_darkflame_selector : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_THROW_DARKFLAME_MARKER }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) const + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_THROW_DARKFLAME_MARKER, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_throw_darkflame_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; + +// 421250 - Throw Darkflame +class spell_the_candle_king_throw_darkflame_missile : public AuraScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_THROW_DARKFLAME_MISSILE }); + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_THROW_DARKFLAME_MISSILE, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringAura = aurEff + }); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_the_candle_king_throw_darkflame_missile::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 422079 - Cursed Wax +class spell_the_candle_king_cursed_wax : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CURSED_WAX_STUN }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) const + { + Unit* target = GetHitUnit(); + target->CastSpell(target, SPELL_CURSED_WAX_STUN, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_cursed_wax::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 421274 - Darkflame Pickaxe +class spell_the_candle_king_darkflame_pickaxe_selector : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DARKFLAME_PICKAXE_CAST, SPELL_DARKFLAME_PICKAXE_MARKER }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) const + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + CastSpellExtraArgs args; + args.SetTriggerFlags(TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + args.SetTriggeringSpell(GetSpell()); + + caster->CastSpell(target, SPELL_DARKFLAME_PICKAXE_CAST, args); + caster->CastSpell(target, SPELL_DARKFLAME_PICKAXE_MARKER, args); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_darkflame_pickaxe_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +class DarkflamePickaxeDamageEvent : public BasicEvent +{ +public: + explicit DarkflamePickaxeDamageEvent(Unit* caster, ObjectGuid const& targetGUID, ObjectGuid const& originalCastId) : _caster(caster), _targetGUID(targetGUID), _originalCastId(originalCastId) { } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + if (Unit* target = ObjectAccessor::GetUnit(*_caster, _targetGUID)) + { + _caster->CastSpell(target, SPELL_DARKFLAME_PICKAXE_DAMAGE, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .OriginalCastId = _originalCastId + }); + } + return true; + } + +private: + Unit* _caster; + ObjectGuid _targetGUID; + ObjectGuid _originalCastId; +}; + +// 421277 - Darkflame Pickaxe +class spell_the_candle_king_darkflame_pickaxe_cast : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DARKFLAME_PICKAXE_VISUAL, SPELL_DARKFLAME_PICKAXE_DAMAGE }); + } + + void ClearTarget(WorldObject*& target) + { + target = nullptr; + } + + void FilterTargets(std::list& targets) + { + static constexpr uint8 MAX_TARGETS = 1; + + if (targets.size() <= MAX_TARGETS) + return; + + targets.remove_if([](WorldObject* target) -> bool + { + Unit* unit = target->ToUnit(); + if (!unit) + return true; + + return (!unit->IsPlayer() && unit->GetEntry() != NPC_WAX_STATUE) || !unit->HasAura(SPELL_MOLTEN_WAX_AT); + }); + + auto closestTargetItr = std::ranges::min_element(targets, std::ranges::less(), [caster = GetCaster()](WorldObject const* obj) + { + return caster->GetExactDist2dSq(obj->GetPosition()); + }); + + if (closestTargetItr == targets.end()) + return; + + WorldObject* closestTarget = *closestTargetItr; + targets.clear(); + targets.push_back(closestTarget); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) const + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + CastSpellExtraArgs args; + args.SetTriggerFlags(TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + args.SetTriggeringSpell(GetSpell()); + + caster->CastSpell(target, SPELL_DARKFLAME_PICKAXE_VISUAL, CastSpellExtraArgsInit{ + .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, + .TriggeringSpell = GetSpell() + }); + caster->m_Events.AddEventAtOffset(new DarkflamePickaxeDamageEvent(caster, target->GetGUID(), GetSpell()->m_castId), 300ms); + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_the_candle_king_darkflame_pickaxe_cast::ClearTarget, EFFECT_0, TARGET_UNIT_TARGET_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_candle_king_darkflame_pickaxe_cast::FilterTargets, EFFECT_0, TARGET_UNIT_RECT_CASTER); + OnEffectHitTarget += SpellEffectFn(spell_the_candle_king_darkflame_pickaxe_cast::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 421648 - Cursed Wax +// Id - 29999 +struct at_the_candle_king_cursed_wax : AreaTriggerAI +{ + using AreaTriggerAI::AreaTriggerAI; + + void OnUnitEnter(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + Unit* caster = at->GetCaster(); + if (!caster) + return; + + caster->CastSpell(unit, SPELL_CURSED_WAX_VISUAL, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + caster->CastSpell(unit, SPELL_CURSED_WAX_DUMMY, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + } +}; + +// 420691 - Molten Wax and 420963 - Molten Wax +// Ids: 29904, 29906 +struct at_the_candle_king_molten_wax : public AreaTriggerAI +{ + using AreaTriggerAI::AreaTriggerAI; + + void OnUnitEnter(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + unit->CastSpell(unit, SPELL_MOLTEN_WAX_DAMAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + } + + void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override + { + unit->RemoveAurasDueToSpell(SPELL_MOLTEN_WAX_DAMAGE); + } +}; + +// Id - XXXX (change on merge) +struct at_the_candle_king_candlelight : AreaTriggerAI +{ + using AreaTriggerAI::AreaTriggerAI; + + void OnUnitEnter(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + unit->CastSpell(unit, SPELL_CANDLELIGHT, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); + unit->RemoveAurasDueToSpell(SPELL_DARKLIGHT_DEBUFF); + } + + void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override + { + unit->RemoveAurasDueToSpell(SPELL_CANDLELIGHT); + } +}; + +void AddSC_boss_the_candle_king() +{ + RegisterDarkflameCleftCreatureAI(boss_the_candle_king); + + RegisterSpellScript(spell_the_candle_king_eerie_molds_clone_summoner); + RegisterSpellScript(spell_the_candle_king_eerie_molds_selector); + RegisterSpellScript(spell_the_candle_king_throw_darkflame_selector); + RegisterSpellScript(spell_the_candle_king_throw_darkflame_missile); + RegisterSpellScript(spell_the_candle_king_cursed_wax); + RegisterSpellScript(spell_the_candle_king_darkflame_pickaxe_selector); + RegisterSpellScript(spell_the_candle_king_darkflame_pickaxe_cast); + + RegisterAreaTriggerAI(at_the_candle_king_cursed_wax); + RegisterAreaTriggerAI(at_the_candle_king_molten_wax); + RegisterAreaTriggerAI(at_the_candle_king_candlelight); +} diff --git a/src/server/scripts/KhazAlgar/DarkflameCleft/darkflame_cleft.h b/src/server/scripts/KhazAlgar/DarkflameCleft/darkflame_cleft.h new file mode 100644 index 0000000000..98c66c7f43 --- /dev/null +++ b/src/server/scripts/KhazAlgar/DarkflameCleft/darkflame_cleft.h @@ -0,0 +1,54 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef DEF_DARKFLAME_CLEFT_H_ +#define DEF_DARKFLAME_CLEFT_H_ + +#include "CreatureAIImpl.h" + +#define DCScriptName "instance_darkflame_cleft" +#define DataHeader "DarkflameCleft" + +uint32 const EncounterCount = 4; + +enum DarkflameCleftDataTypes +{ + // Encounters + DATA_OL_WAXBEARD = 0, + DATA_BLAZIKON = 1, + DATA_THE_CANDLE_KING = 2, + DATA_THE_DARKNESS = 3 +}; + +enum DarkflameCleftCreatureIds +{ + // Bosses + BOSS_OL_WAXBEARD = 210149, + BOSS_BLAZIKON = 208743, + BOSS_THE_CANDLE_KING = 208745, + BOSS_THE_DARKNESS = 210797 +}; + +template +inline AI* GetDarkflameCleftAI(T* obj) +{ + return GetInstanceAI(obj, DCScriptName); +} + +#define RegisterDarkflameCleftCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetDarkflameCleftAI) + +#endif diff --git a/src/server/scripts/KhazAlgar/DarkflameCleft/instance_darkflame_cleft.cpp b/src/server/scripts/KhazAlgar/DarkflameCleft/instance_darkflame_cleft.cpp new file mode 100644 index 0000000000..bed74fb6c9 --- /dev/null +++ b/src/server/scripts/KhazAlgar/DarkflameCleft/instance_darkflame_cleft.cpp @@ -0,0 +1,70 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AreaBoundary.h" +#include "InstanceScript.h" +#include "ScriptMgr.h" +#include "darkflame_cleft.h" + +BossBoundaryData const boundaries = +{ + { DATA_THE_CANDLE_KING, new ZRangeBoundary(59.20f, 90.0f) } +}; + +static constexpr ObjectData creatureData[] = +{ + { DATA_OL_WAXBEARD, BOSS_OL_WAXBEARD }, + { DATA_BLAZIKON, BOSS_BLAZIKON }, + { DATA_THE_CANDLE_KING, BOSS_THE_CANDLE_KING }, + { DATA_THE_DARKNESS, BOSS_THE_DARKNESS } +}; + +static constexpr DungeonEncounterData const encounters[] = +{ + { DATA_OL_WAXBEARD, {{ 2829 }} }, + { DATA_BLAZIKON, {{ 2826 }} }, + { DATA_THE_CANDLE_KING, {{ 2787 }} }, + { DATA_THE_DARKNESS, {{ 2788 }} } +}; + +class instance_darkflame_cleft : public InstanceMapScript +{ +public: + instance_darkflame_cleft() : InstanceMapScript(DCScriptName, 2651) { } + + struct instance_darkflame_cleft_InstanceMapScript: public InstanceScript + { + instance_darkflame_cleft_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadObjectData(creatureData, {}); + LoadBossBoundaries(boundaries); + LoadDungeonEncounterData(encounters); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_darkflame_cleft_InstanceMapScript(map); + } +}; + +void AddSC_instance_darkflame_cleft() +{ + new instance_darkflame_cleft(); +} diff --git a/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp index 117ff91ef2..602efceafb 100644 --- a/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp +++ b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp @@ -39,6 +39,10 @@ void AddSC_boss_ulgrax_the_devourer(); void AddSC_instance_city_of_threads(); void AddSC_boss_orator_krix_vizk(); +// Darkflame Cleft +void AddSC_instance_darkflame_cleft(); +void AddSC_boss_the_candle_king(); + // The name of this function should match: // void Add${NameOfDirectory}Scripts() void AddKhazAlgarScripts() @@ -64,4 +68,8 @@ void AddKhazAlgarScripts() // City of Threads AddSC_instance_city_of_threads(); AddSC_boss_orator_krix_vizk(); + + // Darkflame Cleft + AddSC_instance_darkflame_cleft(); + AddSC_boss_the_candle_king(); }