Scripts/Underrot: Implement Cragmaw the Infested encounter (#28934)

This commit is contained in:
Naddley
2023-04-25 23:41:51 +02:00
committed by GitHub
parent 1e11f51375
commit 5df71e9b14
5 changed files with 474 additions and 2 deletions

View File

@@ -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');

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}