diff options
5 files changed, 474 insertions, 2 deletions
diff --git a/sql/updates/world/master/2023_04_25_01_world.sql b/sql/updates/world/master/2023_04_25_01_world.sql new file mode 100644 index 00000000000..aa74359ca95 --- /dev/null +++ b/sql/updates/world/master/2023_04_25_01_world.sql @@ -0,0 +1,56 @@ +-- Cragmaw the Infested +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_cragmaw_the_infested' WHERE `entry` = 131817; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_cragmaw_blood_tick' WHERE `entry` = 132051; +UPDATE `creature_template` SET `flags_extra` = 128 WHERE `entry` = 132080; + +UPDATE `creature_template_addon` SET `Emote` = 0, `auras` = '' WHERE `entry` = 131817; + +UPDATE `creature_template` SET `faction`=16, `speed_walk`=5.599999904632568359, `speed_run`=2, `BaseAttackTime`=1500, `unit_flags`=32768, `unit_flags2`=2048, `unit_flags3`=524288 WHERE `entry`=132051; -- Blood Tick +UPDATE `creature_template` SET `faction`=16, `BaseAttackTime`=2000, `unit_flags`=33554432, `unit_flags2`=2048, `unit_flags3`=17301505 WHERE `entry`=132080; -- Blood Tick Larva + +DELETE FROM `creature` WHERE `guid` = 850807; +DELETE FROM `creature_addon` WHERE `guid` = 850807; + +DELETE FROM `creature_template_addon` WHERE `entry` = (132051 /*132051 (Blood Tick) - Blood Burst*/); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES +(132051, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, '278641 260768'); -- 132051 (Blood Tick) - Blood Burst + +-- AreaTrigger +DELETE FROM `areatrigger_template` WHERE (`IsServerSide`=0 AND `Id` IN (17026,17014)); +INSERT INTO `areatrigger_template` (`Id`, `IsServerSide`, `Type`, `Flags`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `VerifiedBuild`) VALUES +(17026, 0, 0, 4, 1.35000002384185791, 1.35000002384185791, 0, 0, 0, 0, 0, 0, 48999), +(17014, 0, 1, 4, 2.5, 2.5, 7.5, 2.5, 2.5, 7.5, 0, 0, 48999); + +DELETE FROM `areatrigger_create_properties` WHERE `Id` IN (12334 /*SpellId : 260411*/, 12319 /*SpellId : 260292*/); +INSERT INTO `areatrigger_create_properties` (`Id`, `AreaTriggerId`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `VerifiedBuild`) VALUES +(12334, 17026, 0, 0, 0, 0, -1, 0, 0, 0, 12000, 0, 1.35000002384185791, 1.35000002384185791, 0, 0, 0, 0, 0, 0, 48999), -- SpellId : 260411 (Summon Larva) +(12319, 17014, 0, 0, 0, 0, -1, 0, 0, 0, 10000, 1, 2.5, 2.5, 7.5, 2.5, 2.5, 7.5, 0, 0, 48999); -- SpellId : 260292 (Charge) + +UPDATE `areatrigger_create_properties` SET `ScriptName` = 'at_cragmaw_destroy_larva' WHERE `Id` = 12334 AND `AreaTriggerId` = 17026; + +DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId` = 17014 AND `IsServerSide` = 0; +INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsServerSide`, `ActionType`, `ActionParam`, `TargetType`) VALUES +(17014, 0, 0, 260312, 2); + +-- Scaling +DELETE FROM `creature_template_scaling` WHERE (`DifficultyID`=23 AND `Entry` IN (132051,132080,140593)); +INSERT INTO `creature_template_scaling` (`Entry`, `DifficultyID`, `LevelScalingDeltaMin`, `LevelScalingDeltaMax`, `ContentTuningID`, `VerifiedBuild`) VALUES +(132051, 23, 0, 0, 502, 48999), +(132080, 23, 0, 0, 502, 48999), +(140593, 23, 2, 2, 502, 48999); + + -- Creature 132080 smart ai +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 132080; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = 132080; +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`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(132080, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 11, 260416, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'OnSummon - Self: Cast spell 260416 with flags triggered on Self'), +(132080, 0, 1, 0, 54, 0, 100, 0, 0, 0, 0, 0, 11, 260411, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'OnSummon - Self: Cast spell 260411 with flags triggered on Self'); + +-- SpellScripts +DELETE FROM `spell_script_names` WHERE `spell_id` IN (271775, 260416, 159474, 278641, 260411); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(271775, 'spell_cragmaw_power_energize_tantrum'), +(260416, 'spell_cragmaw_larva_metamorphosis'), +(159474, 'spell_gen_feign_death_all_flags_uninteractible'), +(278641, 'spell_cragmaw_blood_burst'), +(260411, 'spell_cragmaw_summon_larva'); diff --git a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp b/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp new file mode 100644 index 00000000000..e92f6f8e731 --- /dev/null +++ b/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp @@ -0,0 +1,382 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "AreaTrigger.h" +#include "AreaTriggerAI.h" +#include "CreatureAI.h" +#include "CreatureAIImpl.h" +#include "InstanceScript.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "SpellAuras.h" +#include "SharedDefines.h" +#include "TemporarySummon.h" +#include "underrot.h" + +enum CragmawSpells +{ + // Cragmaw + SPELL_CRAWG_EATING = 279156, + SPELL_POWER_DISPLAY_TANTRUM = 271771, + SPELL_POWER_ENERGIZE_TANTRUM = 271775, + SPELL_CHARGE_SELECTOR = 260292, + SPELL_INDIGESTION = 260793, + SPELL_TANTRUM_INITIAL = 260333, + + // Larva + SPELL_DESTROY_LARVA = 260418, + SPELL_METAMORPHOSIS_2 = 260766, + SPELL_SUMMON_BLOOD_TICK = 260353, + SPELL_SUMMON_BLOOD_TICK_VISUAL = 260496, + + // Blood Tick + SPELL_BLOOD_BURST_DAMAGE = 278637, + SPELL_SERRATED_FANGS = 260455, + + // Fetid Maggot + SPELL_FEIGN_DEATH = 159474 +}; + +enum CragmawEvents +{ + // Cragmaw + EVENT_CHARGE_SELECTOR = 1, + EVENT_INDIGESTION, + EVENT_NORMAL_REQUEUE, + EVENT_CHECK_ENERGY_TANTRUM, + + // Blood Tick + EVENT_SERRATED_FANGS = 1 +}; + +enum CragmawPoints +{ + POINT_TANTRUM_START_RND_MOVEMENT = 0 +}; + +enum CragmawNPC +{ + NPC_FETID_MAGGOT = 130909 +}; + +Position const FetidMaggotSpawn = { 857.864f, 984.981f, 39.231f, 4.68147f }; + +// 131817 - Cragmaw the Infested +struct boss_cragmaw_the_infested : public BossAI +{ + boss_cragmaw_the_infested(Creature* creature) : BossAI(creature, DATA_CRAGMAW_THE_INFESTED) { } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void JustAppeared() override + { + me->SetPowerType(POWER_ENERGY); + DoCast(SPELL_POWER_DISPLAY_TANTRUM); + + if (instance->GetData(DATA_CRAGMAW_CRAWG_EATING)) + return; + + DoCastSelf(SPELL_CRAWG_EATING); + me->SetEmoteState(EMOTE_STATE_EAT); + if (TempSummon* summon = me->SummonCreature(NPC_FETID_MAGGOT, FetidMaggotSpawn)) + { + _fetidMaggotGuid = summon->GetGUID(); + summon->CastSpell(nullptr, SPELL_FEIGN_DEATH, true); + } + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + summons.DespawnAll(); + _EnterEvadeMode(); + _DespawnAtEvade(); + } + + void ScheduleSpells() + { + events.Reset(); + + if (GetDifficulty() == DIFFICULTY_NORMAL) + events.ScheduleEvent(EVENT_NORMAL_REQUEUE, 45s); + + if (urand(0, 1) == 0) + { + events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 9s); + events.ScheduleEvent(EVENT_INDIGESTION, 20s); + events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 33s); + } + else + { + events.ScheduleEvent(EVENT_INDIGESTION, 9s); + events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 21s); + events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 41s); + } + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + instance->SetData(DATA_CRAGMAW_CRAWG_EATING, 1); + ScheduleSpells(); + events.ScheduleEvent(EVENT_CHECK_ENERGY_TANTRUM, 500ms); + + if (Creature* fetidMaggot = ObjectAccessor::GetCreature(*me, _fetidMaggotGuid)) + fetidMaggot->DespawnOrUnsummon(); + + if (IsHeroic() || GetDifficulty() == DIFFICULTY_MYTHIC || GetDifficulty() == DIFFICULTY_MYTHIC_KEYSTONE) + DoCast(SPELL_POWER_ENERGIZE_TANTRUM); + } + + void MovementInform(uint32 /*type*/, uint32 id) override + { + if (id == POINT_TANTRUM_START_RND_MOVEMENT) + me->GetMotionMaster()->MoveRandom(20.0f); + } + + void OnChannelFinished(SpellInfo const* spell) override + { + if (spell->Id == SPELL_TANTRUM_INITIAL) + me->SetReactState(REACT_AGGRESSIVE); + }; + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_CHARGE_SELECTOR: + DoCast(SPELL_CHARGE_SELECTOR); + break; + case EVENT_INDIGESTION: + DoCast(SPELL_INDIGESTION); + break; + case EVENT_NORMAL_REQUEUE: + ScheduleSpells(); + break; + case EVENT_CHECK_ENERGY_TANTRUM: + if (me->GetPower(POWER_ENERGY) >= 100) + { + ScheduleSpells(); + DoCast(SPELL_TANTRUM_INITIAL); + me->SetReactState(REACT_PASSIVE); + me->GetMotionMaster()->MovePoint(POINT_TANTRUM_START_RND_MOVEMENT, me->GetHomePosition()); + } + events.Repeat(500ms); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } +private: + ObjectGuid _fetidMaggotGuid; +}; + +// 132051 - Blood Tick +struct npc_cragmaw_blood_tick : public ScriptedAI +{ + npc_cragmaw_blood_tick(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + Creature* cragmaw = me->GetInstanceScript()->GetCreature(DATA_CRAGMAW_THE_INFESTED); + if (!cragmaw || !cragmaw->IsAIEnabled()) + return; + + cragmaw->AI()->JustSummoned(me); + DoZoneInCombat(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SERRATED_FANGS, 1s); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_STUNNED)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_SERRATED_FANGS: + DoCastVictim(SPELL_SERRATED_FANGS); + _events.ScheduleEvent(EVENT_SERRATED_FANGS, 6s); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } +private: + EventMap _events; +}; + +// 271775 - Tantrum Energy Bar (periodic) +class spell_cragmaw_power_energize_tantrum : public AuraScript +{ + PrepareAuraScript(spell_cragmaw_power_energize_tantrum); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + target->SetPower(POWER_ENERGY, target->GetPower(POWER_ENERGY) + 2); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_cragmaw_power_energize_tantrum::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// 260411 - Summon Larva +class spell_cragmaw_summon_larva : public AuraScript +{ + PrepareAuraScript(spell_cragmaw_summon_larva); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* creature = GetTarget()->ToCreature()) + creature->DespawnOrUnsummon(300ms); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_summon_larva::OnRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 260418 - Destroy Larva +struct at_cragmaw_destroy_larva : AreaTriggerAI +{ + at_cragmaw_destroy_larva(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + at->GetCaster()->CastSpell(nullptr, SPELL_DESTROY_LARVA, true); + } +}; + +// 260416 - Metamorphosis +class spell_cragmaw_larva_metamorphosis : public AuraScript +{ + PrepareAuraScript(spell_cragmaw_larva_metamorphosis); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_SUMMON_BLOOD_TICK, + SPELL_SUMMON_BLOOD_TICK_VISUAL, + SPELL_METAMORPHOSIS_2 + }); + } + + void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // Spell duration is 8s on heroic+ difficulties + if (GetTarget()->GetMap()->GetDifficultyID() != DIFFICULTY_NORMAL) + { + aurEff->GetBase()->SetDuration(8000); + aurEff->GetBase()->SetMaxDuration(8000); + } + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + if (aurEff->GetTickNumber() == aurEff->GetTotalTicks() - 2) + GetTarget()->CastSpell(nullptr, SPELL_METAMORPHOSIS_2, true); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + Unit* target = GetTarget(); + target->CastSpell(nullptr, SPELL_SUMMON_BLOOD_TICK_VISUAL, true); + target->CastSpell(target->GetPosition(), SPELL_SUMMON_BLOOD_TICK, true); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_cragmaw_larva_metamorphosis::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_cragmaw_larva_metamorphosis::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_larva_metamorphosis::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 278641 - Blood Burst +class spell_cragmaw_blood_burst : public AuraScript +{ + PrepareAuraScript(spell_cragmaw_blood_burst); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_BLOOD_BURST_DAMAGE, true); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_blood_burst::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +void AddSC_boss_cragmaw_the_infested() +{ + // Creature + RegisterUnderrotCreatureAI(boss_cragmaw_the_infested); + RegisterUnderrotCreatureAI(npc_cragmaw_blood_tick); + + // Spells + RegisterSpellScript(spell_cragmaw_power_energize_tantrum); + RegisterSpellScript(spell_cragmaw_larva_metamorphosis); + RegisterSpellScript(spell_cragmaw_blood_burst); + RegisterSpellScript(spell_cragmaw_summon_larva); + + // AreaTrigger + RegisterAreaTriggerAI(at_cragmaw_destroy_larva); +} diff --git a/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp b/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp index 7ae5a1ab8ae..f2a6ec616bc 100644 --- a/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp +++ b/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp @@ -22,7 +22,8 @@ BossBoundaryData const boundaries = { - { DATA_ELDER_LEAXA, new CircleBoundary(Position(869.502014f, 1230.199951f), 58.0f) } + { DATA_ELDER_LEAXA, new CircleBoundary(Position(869.502014f, 1230.199951f), 58.0f) }, + { DATA_CRAGMAW_THE_INFESTED, new CircleBoundary(Position(852.797974f, 982.133545f), 90.0f) } }; ObjectData const creatureData[] = @@ -63,7 +64,36 @@ public: LoadDoorData(doorData); LoadBossBoundaries(boundaries); LoadDungeonEncounterData(encounters); + + _cragmawCrawgEating = false; + } + + uint32 GetData(uint32 dataId) const override + { + switch (dataId) + { + case DATA_CRAGMAW_CRAWG_EATING: + return _cragmawCrawgEating ? 1 : 0; + default: + break; + } + return 0; } + + void SetData(uint32 dataId, uint32 /*value*/) override + { + switch (dataId) + { + case DATA_CRAGMAW_CRAWG_EATING: + _cragmawCrawgEating = true; + break; + default: + break; + } + } + + private: + bool _cragmawCrawgEating; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Zandalar/Underrot/underrot.h b/src/server/scripts/Zandalar/Underrot/underrot.h index 315071c906d..77849594584 100644 --- a/src/server/scripts/Zandalar/Underrot/underrot.h +++ b/src/server/scripts/Zandalar/Underrot/underrot.h @@ -31,7 +31,9 @@ enum UnderrotDataTypes DATA_ELDER_LEAXA = 0, DATA_SPORECALLER_ZANCHA, DATA_CRAGMAW_THE_INFESTED, - DATA_UNBOUND_ABOMINATION + DATA_UNBOUND_ABOMINATION, + + DATA_CRAGMAW_CRAWG_EATING }; enum UnderrotCreatureIds diff --git a/src/server/scripts/Zandalar/zandalar_script_loader.cpp b/src/server/scripts/Zandalar/zandalar_script_loader.cpp index 2c0559e0ad8..2822c02be62 100644 --- a/src/server/scripts/Zandalar/zandalar_script_loader.cpp +++ b/src/server/scripts/Zandalar/zandalar_script_loader.cpp @@ -20,6 +20,7 @@ // Underrot void AddSC_instance_underrot(); void AddSC_boss_elder_leaxa(); +void AddSC_boss_cragmaw_the_infested(); // The name of this function should match: // void Add${NameOfDirectory}Scripts() @@ -28,4 +29,5 @@ void AddZandalarScripts() // Underrot AddSC_instance_underrot(); AddSC_boss_elder_leaxa(); + AddSC_boss_cragmaw_the_infested(); } |
