aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp382
-rw-r--r--src/server/scripts/Zandalar/Underrot/instance_underrot.cpp32
-rw-r--r--src/server/scripts/Zandalar/Underrot/underrot.h4
-rw-r--r--src/server/scripts/Zandalar/zandalar_script_loader.cpp2
4 files changed, 418 insertions, 2 deletions
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();
}