mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 10:26:28 +01:00
Scripts/BWD: implement heroic difficulty mechanics and finish Maloriak Encounter implementation
This commit is contained in:
@@ -65,7 +65,8 @@ enum BWDDataTypes
|
||||
|
||||
/*Maloriak*/
|
||||
DATA_CAULDRON_TRIGGER,
|
||||
DATA_CAULDRON
|
||||
DATA_CAULDRON,
|
||||
DATA_LORD_VICTOR_NEFARIUS_MALORIAK
|
||||
};
|
||||
|
||||
enum BWDCreatureIds
|
||||
@@ -123,6 +124,9 @@ enum BWDCreatureIds
|
||||
NPC_ABERRATION = 41440,
|
||||
NPC_PRIME_SUBJECT = 41841,
|
||||
NPC_FLASH_FREEZE = 41576,
|
||||
NPC_ABSOLUTE_ZERO = 41961,
|
||||
NPC_LORD_VICTOR_NEFARIUS_MALORIAK = 49799,
|
||||
NPC_VILE_SWILL = 49811,
|
||||
|
||||
/*Events*/
|
||||
NPC_SPIRIT_OF_MOLTENFIST = 43125,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "CommonPredicates.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
@@ -44,12 +45,20 @@ enum Spells
|
||||
SPELL_THROW_RED_BOTTLE_TRIGGERED = 77928,
|
||||
SPELL_THROW_BLUE_BOTTLE_TRIGGERED = 77934,
|
||||
SPELL_THROW_GREEN_BOTTLE_TRIGGERED = 77938,
|
||||
SPELL_THROW_BLACK_BOTTLE_TRIGGERED = 92837,
|
||||
SPELL_RELEASE_ABERRATIONS = 77569,
|
||||
SPELL_RELEASE_ALL_MINIONS = 77991,
|
||||
SPELL_SCORCHING_BLAST = 77679,
|
||||
SPELL_BITING_CHILL = 77760,
|
||||
SPELL_FLASH_FREEZE_TARGETING = 97693,
|
||||
SPELL_DRINK_ALL_BOTTLES = 95662,
|
||||
SPELL_UNSTABLE_MIX = 95663,
|
||||
SPELL_MAGMA_JETS_SCRIPT_EFFECT = 93022,
|
||||
SPELL_MAGMA_JETS_SUMMON = 78194,
|
||||
SPELL_ACID_NOVA = 78225,
|
||||
SPELL_ABSOLUTE_ZERO = 78223,
|
||||
SPELL_ENGULFING_DARKNESS = 92754,
|
||||
SPELL_VILE_SWILL = 92720,
|
||||
SPELL_VILE_SWILL_SUMMON = 92724,
|
||||
|
||||
// Cauldron Trigger
|
||||
SPELL_DEBILITATING_SLIME_CAST = 77602,
|
||||
@@ -64,6 +73,23 @@ enum Spells
|
||||
SPELL_DROWNED_STATE = 77564,
|
||||
SPELL_GROWTH_CATALYST = 77987,
|
||||
|
||||
// Magma Jet
|
||||
SPELL_MAGMA_JETS_SUMMON_FIRE = 78094,
|
||||
SPELL_MAGMA_JETS_ERUPTION = 78095,
|
||||
|
||||
// Absolute Zero
|
||||
SPELL_ABSOLUTE_ZERO_TRANSFORM = 78201,
|
||||
SPELL_ABSOLUTE_ZERO_EXPLOSION = 78208,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
SPELL_TELEPORT_VISUAL_ONLY = 41232,
|
||||
SPELL_THROW_BLACK_BOTTLE = 92831,
|
||||
SPELL_THROW_BLACK_BOTTLE_TRIGGERED = 92837,
|
||||
SPELL_MASTER_ADVENTURER_AWARD = 89798,
|
||||
|
||||
// Vile Swill
|
||||
SPELL_DARK_SLUDGE = 92929,
|
||||
|
||||
// Player
|
||||
SPELL_FLASH_FREEZE_SUMMON = 77711,
|
||||
SPELL_FLASH_FREEZE_DUMMY = 77716,
|
||||
@@ -91,24 +117,61 @@ enum Events
|
||||
EVENT_SCORCHING_BLAST,
|
||||
EVENT_BITING_CHILL,
|
||||
EVENT_FLASH_FREEZE,
|
||||
EVENT_ENTER_PHASE_TWO,
|
||||
EVENT_DRINK_ALL_BOTTLES,
|
||||
EVENT_UNSTABLE_MIX,
|
||||
EVENT_MAGMA_JETS,
|
||||
EVENT_ACID_NOVA,
|
||||
EVENT_ABSOLUTE_ZERO,
|
||||
EVENT_MOVE_AWAY_FROM_CAULDRON,
|
||||
EVENT_ENGULFING_DARKNESS,
|
||||
EVENT_VILE_SWILL,
|
||||
|
||||
// Experiments
|
||||
EVENT_LEAP_OUT_OF_CHAMBER,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
EVENT_MOCK_MALORIAK,
|
||||
EVENT_THROW_BLACK_BOTTLE,
|
||||
EVENT_LAND,
|
||||
EVENT_SAY_MALORIAK_DEAD,
|
||||
EVENT_MASTER_ADVENTURER_AWARD,
|
||||
EVENT_TELEPORT_AWAY,
|
||||
|
||||
// Vile Swill
|
||||
EVENT_DARK_SLUDGE
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
// Maloriak
|
||||
ACTION_SCHEDULE_EVENTS_FOR_PHASE = 1,
|
||||
ACTION_RELEASE_EXPERIMENT = 1
|
||||
|
||||
// Experiments
|
||||
ACTION_RELEASE_EXPERIMENT = 1,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
ACTION_THROW_BLACK_BOTTLE = 1,
|
||||
ACTION_MALORIAK_DEAD = 2
|
||||
};
|
||||
|
||||
enum MovePoints
|
||||
{
|
||||
// Maloriak
|
||||
POINT_NONE = 0,
|
||||
POINT_CAULDRON = 1,
|
||||
|
||||
// Experiments
|
||||
POINT_GROUND = 1
|
||||
POINT_GROUND = 1,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
POINT_LAND = 1
|
||||
};
|
||||
|
||||
enum Texts
|
||||
@@ -122,13 +185,23 @@ enum Texts
|
||||
SAY_GREEN_VIAL = 5,
|
||||
SAY_ANNOUNCE_GREEN_VIAL = 6,
|
||||
SAY_RELEASE_ABERRATIONS = 7,
|
||||
SAY_RELEASE_ALL_MINIONS = 8,
|
||||
SAY_SLAY = 9,
|
||||
SAY_DEATH = 10,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
SAY_MOCK_MALORIAK = 0,
|
||||
SAY_THROW_BLACK_BOTTLE = 1,
|
||||
SAY_ANNOUNCE_BLACK_VIAL = 2,
|
||||
SAY_MALORIAK_DEAD = 3
|
||||
};
|
||||
|
||||
enum Vials
|
||||
{
|
||||
VIAL_RED = 0,
|
||||
VIAL_BLUE = 1,
|
||||
VIAL_GREEN = 2
|
||||
VIAL_GREEN = 2,
|
||||
VIAL_BLACK = 3
|
||||
};
|
||||
|
||||
enum GameObjectCustomAnim
|
||||
@@ -139,7 +212,9 @@ enum GameObjectCustomAnim
|
||||
CUSTOM_ANIM_BLACK_CAULDRON = 3
|
||||
};
|
||||
|
||||
Position const CauldronMovePosition = { -106.6782f, -475.4438f, 73.45684f };
|
||||
Position const CauldronMovePosition = { -106.6782f, -475.4438f, 73.45684f };
|
||||
Position const LordVictorNefariusSummonPosition = { -105.9514f, -494.0278f, 89.33157f, 1.605703f };
|
||||
Position const LordVictorNefariusLandPosition = { -105.9514f, -494.0278f, 73.44659f };
|
||||
|
||||
struct VialData
|
||||
{
|
||||
@@ -152,21 +227,24 @@ struct VialData
|
||||
|
||||
enum Misc
|
||||
{
|
||||
SUMMON_GROUP_EXPERIMENTS = 0,
|
||||
SPAWN_GROUP_GROWTH_CHAMBERS = 401
|
||||
SUMMON_GROUP_EXPERIMENTS = 0,
|
||||
SPAWN_GROUP_GROWTH_CHAMBERS = 401,
|
||||
AI_ANIM_KIT_ID_LORD_VICTOR_NEFARIUS = 1173,
|
||||
TITLE_ADVENTURER_AWARD = 188
|
||||
};
|
||||
|
||||
std::unordered_map<uint8, VialData> vialData =
|
||||
{
|
||||
{ VIAL_RED, { SAY_RED_VIAL, SAY_ANNOUNCE_RED_VIAL, SPELL_THROW_RED_BOTTLE, SPELL_DRINK_RED_BOTTLE, SPELL_FIRE_IMBUED }},
|
||||
{ VIAL_BLUE, { SAY_BLUE_VIAL, SAY_ANNOUNCE_BLUE_VIAL, SPELL_THROW_BLUE_BOTTLE, SPELL_DRINK_BLUE_BOTTLE, SPELL_FROST_IMBUED }},
|
||||
{ VIAL_GREEN, { SAY_GREEN_VIAL, SAY_ANNOUNCE_GREEN_VIAL, SPELL_THROW_GREEN_BOTTLE, 0, SPELL_SLIME_IMBUED }},
|
||||
{ VIAL_RED, { SAY_RED_VIAL, SAY_ANNOUNCE_RED_VIAL, SPELL_THROW_RED_BOTTLE, SPELL_DRINK_RED_BOTTLE, SPELL_FIRE_IMBUED }},
|
||||
{ VIAL_BLUE, { SAY_BLUE_VIAL, SAY_ANNOUNCE_BLUE_VIAL, SPELL_THROW_BLUE_BOTTLE, SPELL_DRINK_BLUE_BOTTLE, SPELL_FROST_IMBUED }},
|
||||
{ VIAL_GREEN, { SAY_GREEN_VIAL, SAY_ANNOUNCE_GREEN_VIAL, SPELL_THROW_GREEN_BOTTLE, 0, SPELL_SLIME_IMBUED }},
|
||||
{ VIAL_BLACK, { 0, 0, 0, SPELL_DRINK_BLACK_BOTTLE, SPELL_SHADOW_IMBUED }},
|
||||
};
|
||||
|
||||
struct boss_maloriak : public BossAI
|
||||
{
|
||||
boss_maloriak(Creature* creature) : BossAI(creature, DATA_MALORIAK),
|
||||
_currentVial(urand(VIAL_RED, VIAL_BLUE)), _usedVialsCount(0), _releasedAberrationsCount(0) { }
|
||||
_currentVial(0), _usedVialsCount(0), _vialsPerCycle(IsHeroic() ? 3 : 2), _releasedAberrationsCount(0) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -185,23 +263,56 @@ struct boss_maloriak : public BossAI
|
||||
_JustEngagedWith();
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
|
||||
events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 15s + 500ms);
|
||||
events.SetPhase(PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 15s + 500ms, 0, PHASE_ONE);
|
||||
|
||||
if (IsHeroic())
|
||||
DoSummon(NPC_LORD_VICTOR_NEFARIUS_MALORIAK, LordVictorNefariusSummonPosition, 0, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
_EnterEvadeMode();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
if (Creature* nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK))
|
||||
nefarius->DespawnOrUnsummon();
|
||||
CleanupEncounter();
|
||||
_DespawnAtEvade();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
// Talk(SAY_DEATH);
|
||||
Talk(SAY_DEATH);
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
CleanupEncounter();
|
||||
_JustDied();
|
||||
|
||||
if (Creature * nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK))
|
||||
if (nefarius->IsAIEnabled)
|
||||
nefarius->AI()->DoAction(ACTION_MALORIAK_DEAD);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY, victim);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
case NPC_LORD_VICTOR_NEFARIUS_MALORIAK:
|
||||
break;
|
||||
case NPC_ABSOLUTE_ZERO:
|
||||
summon->GetMotionMaster()->MoveRandom(10.0f);
|
||||
summon->CastSpell(summon, SPELL_ABSOLUTE_ZERO_TRANSFORM);
|
||||
summons.Summon(summon);
|
||||
break;
|
||||
default:
|
||||
summons.Summon(summon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnSpellCastInterrupt(SpellInfo const* spell) override
|
||||
@@ -253,42 +364,57 @@ struct boss_maloriak : public BossAI
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_SCHEDULE_EVENTS_FOR_PHASE:
|
||||
events.ScheduleEvent(EVENT_ATTACK_PLAYERS, _currentVial != VIAL_GREEN ? 1ms : 4s);
|
||||
if (_currentVial != VIAL_BLACK)
|
||||
events.ScheduleEvent(EVENT_ATTACK_PLAYERS, _currentVial != VIAL_GREEN ? 1ms : 4s);
|
||||
events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, _currentVial == VIAL_BLACK ? 1min + 30s : 40s, 0, PHASE_ONE);
|
||||
|
||||
if (_currentVial == VIAL_RED || _currentVial == VIAL_BLUE)
|
||||
switch (_currentVial)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ARCANE_STORM, 14s + 500ms);
|
||||
events.ScheduleEvent(EVENT_REMEDY, 21s + 500ms);
|
||||
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 11s);
|
||||
}
|
||||
else if (_currentVial == VIAL_GREEN)
|
||||
{
|
||||
if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER))
|
||||
cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_DEBUFF);
|
||||
case VIAL_RED:
|
||||
events.ScheduleEvent(EVENT_ARCANE_STORM, 15s + 500ms, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_REMEDY, 20s + 500ms, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 11s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_CONSUMING_FLAMES, 7s, 8s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SCORCHING_BLAST, 19s, 22s, 0, PHASE_ONE);
|
||||
break;
|
||||
case VIAL_BLUE:
|
||||
events.ScheduleEvent(EVENT_ARCANE_STORM, 6s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_REMEDY, 21s + 500ms, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 14s + 500ms, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_BITING_CHILL, 13s, 14s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_FLASH_FREEZE, 17s, 0, PHASE_ONE);
|
||||
break;
|
||||
case VIAL_GREEN:
|
||||
if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER))
|
||||
cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_DEBUFF);
|
||||
|
||||
events.ScheduleEvent(EVENT_ARCANE_STORM, 8s);
|
||||
events.ScheduleEvent(EVENT_REMEDY, 33s + 500ms);
|
||||
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 15s);
|
||||
events.ScheduleEvent(EVENT_ARCANE_STORM, 5s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_REMEDY, 7s + 500ms, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 9s, 0, PHASE_ONE);
|
||||
break;
|
||||
case VIAL_BLACK:
|
||||
me->GetMotionMaster()->MovePoint(POINT_NONE, me->GetHomePosition());
|
||||
events.ScheduleEvent(EVENT_VILE_SWILL, 2s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_ENGULFING_DARKNESS, 8s, 0, PHASE_ONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_currentVial == VIAL_RED)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CONSUMING_FLAMES, 7s + 500ms);
|
||||
events.ScheduleEvent(EVENT_SCORCHING_BLAST, 22s);
|
||||
}
|
||||
else if (_currentVial == VIAL_BLUE)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_BITING_CHILL, 13s + 500ms);
|
||||
events.ScheduleEvent(EVENT_FLASH_FREEZE, 22s);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 40s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(25, damage) && !events.IsInPhase(PHASE_TWO))
|
||||
{
|
||||
events.SetPhase(PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_ENTER_PHASE_TWO, 1ms, 0, PHASE_TWO);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
@@ -309,18 +435,19 @@ struct boss_maloriak : public BossAI
|
||||
DoCastSelf(SPELL_ARCANE_STORM);
|
||||
Creature* maloriak = me;
|
||||
me->m_Events.AddEventAtOffset([maloriak]() { maloriak->MakeInterruptable(false); }, 6s + 500ms);
|
||||
events.Repeat(13s + 500ms);
|
||||
events.Repeat(15s + 500ms, 17s);
|
||||
break;
|
||||
}
|
||||
case EVENT_REMEDY:
|
||||
DoCastSelf(SPELL_REMEDY);
|
||||
events.Repeat(24s);
|
||||
break;
|
||||
case EVENT_RELEASE_ABERRATIONS:
|
||||
if (_releasedAberrationsCount < 6)
|
||||
{
|
||||
me->MakeInterruptable(true);
|
||||
DoCastAOE(SPELL_RELEASE_ABERRATIONS);
|
||||
events.Repeat(24s + 500ms);
|
||||
events.Repeat(17s, 18s);
|
||||
_releasedAberrationsCount++;
|
||||
}
|
||||
break;
|
||||
@@ -330,17 +457,37 @@ struct boss_maloriak : public BossAI
|
||||
{
|
||||
me->AttackStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->ClearUnitState(UNIT_STATE_ROOT);
|
||||
me->SetFacingToObject(cauldron);
|
||||
|
||||
_currentVial = _usedVialsCount < 2 ? _currentVial == VIAL_BLUE ? VIAL_RED : VIAL_BLUE : VIAL_GREEN;
|
||||
Talk(vialData[_currentVial].SayTextId);
|
||||
_usedVialsCount = _usedVialsCount < 2 ? _usedVialsCount + 1 : 0;
|
||||
events.ScheduleEvent(EVENT_THROW_VIAL, 1s + 300ms);
|
||||
if (!_usedVialsCount && IsHeroic())
|
||||
_currentVial = VIAL_BLACK;
|
||||
else
|
||||
{
|
||||
if ((_currentVial == VIAL_BLACK || _currentVial == VIAL_GREEN) && _usedVialsCount < _vialsPerCycle)
|
||||
_currentVial = urand(VIAL_RED, VIAL_BLUE);
|
||||
else if (_usedVialsCount == _vialsPerCycle)
|
||||
_currentVial = VIAL_GREEN;
|
||||
else
|
||||
_currentVial = _currentVial == VIAL_BLUE ? VIAL_RED : VIAL_BLUE;
|
||||
}
|
||||
|
||||
if (_currentVial != VIAL_BLACK)
|
||||
Talk(vialData[_currentVial].SayTextId);
|
||||
else if (Creature * nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK))
|
||||
if (nefarius->IsAIEnabled)
|
||||
nefarius->AI()->DoAction(ACTION_THROW_BLACK_BOTTLE);
|
||||
|
||||
_usedVialsCount = _usedVialsCount < _vialsPerCycle ? _usedVialsCount + 1 : 0;
|
||||
events.ScheduleEvent(EVENT_THROW_VIAL, 1s + 300ms, 0, PHASE_ONE);
|
||||
}
|
||||
break;
|
||||
case EVENT_THROW_VIAL:
|
||||
DoCastSelf(vialData[_currentVial].ThrowSpellId);
|
||||
Talk(vialData[_currentVial].AnnounceTextId);
|
||||
if (_currentVial != VIAL_BLACK)
|
||||
{
|
||||
DoCastSelf(vialData[_currentVial].ThrowSpellId);
|
||||
Talk(vialData[_currentVial].AnnounceTextId);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_CAULDRON, 1s);
|
||||
break;
|
||||
case EVENT_MOVE_TO_CAULDRON:
|
||||
@@ -370,7 +517,7 @@ struct boss_maloriak : public BossAI
|
||||
case EVENT_CONSUMING_FLAMES:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
||||
DoCast(target, SPELL_CONSUMING_FLAMES);
|
||||
events.Repeat(17s);
|
||||
events.Repeat(14s + 500ms);
|
||||
break;
|
||||
case EVENT_SCORCHING_BLAST:
|
||||
DoCastSelf(SPELL_SCORCHING_BLAST);
|
||||
@@ -383,7 +530,54 @@ struct boss_maloriak : public BossAI
|
||||
break;
|
||||
case EVENT_FLASH_FREEZE:
|
||||
DoCastAOE(SPELL_FLASH_FREEZE_TARGETING);
|
||||
events.Repeat(17s);
|
||||
events.Repeat(19s);
|
||||
break;
|
||||
case EVENT_ENTER_PHASE_TWO:
|
||||
me->AttackStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Talk(SAY_RELEASE_ALL_MINIONS);
|
||||
DoCastSelf(SPELL_RELEASE_ALL_MINIONS);
|
||||
events.ScheduleEvent(EVENT_DRINK_ALL_BOTTLES, 5s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_DRINK_ALL_BOTTLES:
|
||||
for (uint8 i = 0; i < VIAL_BLACK; i++)
|
||||
me->RemoveAurasDueToSpell(vialData[i].ImbuedSpellId);
|
||||
|
||||
DoCastSelf(SPELL_DRINK_ALL_BOTTLES);
|
||||
events.ScheduleEvent(EVENT_UNSTABLE_MIX, 2s + 300ms, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_UNSTABLE_MIX:
|
||||
DoCastSelf(SPELL_UNSTABLE_MIX);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.ScheduleEvent(EVENT_MAGMA_JETS, 3s + 500ms, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_ACID_NOVA, 8s + 400ms, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_ABSOLUTE_ZERO, 8s + 400ms, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_MAGMA_JETS:
|
||||
//DoCastAOE(SPELL_MAGMA_JETS_SCRIPT_EFFECT); // seems like an old changed mechanic spell. No purpose atm.
|
||||
DoCastSelf(SPELL_MAGMA_JETS_SUMMON);
|
||||
events.Repeat(6s);
|
||||
break;
|
||||
case EVENT_ACID_NOVA:
|
||||
DoCastAOE(SPELL_ACID_NOVA);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
case EVENT_ABSOLUTE_ZERO:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
||||
DoCast(target, SPELL_ABSOLUTE_ZERO);
|
||||
events.Repeat(7s);
|
||||
break;
|
||||
case EVENT_ENGULFING_DARKNESS:
|
||||
if (me->GetReactState() == REACT_PASSIVE)
|
||||
{
|
||||
me->AddUnitState(UNIT_STATE_ROOT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
DoCastSelf(SPELL_ENGULFING_DARKNESS);
|
||||
events.Repeat(12s + 500ms);
|
||||
break;
|
||||
case EVENT_VILE_SWILL:
|
||||
DoCastSelf(SPELL_VILE_SWILL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -395,6 +589,7 @@ struct boss_maloriak : public BossAI
|
||||
private:
|
||||
uint8 _currentVial;
|
||||
uint8 _usedVialsCount;
|
||||
uint8 _vialsPerCycle;
|
||||
uint8 _releasedAberrationsCount;
|
||||
|
||||
void CleanupEncounter()
|
||||
@@ -413,6 +608,7 @@ struct npc_maloriak_flash_freeze : public NullCreatureAI
|
||||
|
||||
void JustAppeared() override
|
||||
{
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, sSpellMgr->GetSpellIdForDifficulty(SPELL_GROWTH_CATALYST, me), true);
|
||||
DoCastSelf(SPELL_FLASH_FREEZE_VISUAL);
|
||||
Creature* creature = me;
|
||||
me->m_Events.AddEventAtOffset([creature]() { creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); }, 1s);
|
||||
@@ -544,6 +740,145 @@ private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
struct npc_maloriak_magma_jet : public NullCreatureAI
|
||||
{
|
||||
npc_maloriak_magma_jet(Creature* creature) : NullCreatureAI(creature) { }
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->CastSpell(summon, SPELL_MAGMA_JETS_ERUPTION);
|
||||
summon->DespawnOrUnsummon(30s);
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_maloriak_lord_victor_nefarius : public NullCreatureAI
|
||||
{
|
||||
npc_maloriak_lord_victor_nefarius(Creature* creature) : NullCreatureAI(creature) { }
|
||||
|
||||
void JustAppeared() override
|
||||
{
|
||||
me->SetHover(true);
|
||||
DoCastSelf(SPELL_TELEPORT_VISUAL_ONLY);
|
||||
_events.ScheduleEvent(EVENT_MOCK_MALORIAK, 7s + 200ms);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 motionType, uint32 pointId) override
|
||||
{
|
||||
if (motionType != POINT_MOTION_TYPE && motionType != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (pointId)
|
||||
{
|
||||
case POINT_LAND:
|
||||
me->SetDisableGravity(false);
|
||||
me->SetHover(false);
|
||||
_events.ScheduleEvent(EVENT_SAY_MALORIAK_DEAD, 2s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_THROW_BLACK_BOTTLE:
|
||||
Talk(SAY_THROW_BLACK_BOTTLE);
|
||||
_events.ScheduleEvent(EVENT_THROW_BLACK_BOTTLE, 2s + 400ms);
|
||||
break;
|
||||
case ACTION_MALORIAK_DEAD:
|
||||
me->SetAIAnimKitId(AI_ANIM_KIT_ID_LORD_VICTOR_NEFARIUS);
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_LAND, 3s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MOCK_MALORIAK:
|
||||
Talk(SAY_MOCK_MALORIAK);
|
||||
break;
|
||||
case EVENT_THROW_BLACK_BOTTLE:
|
||||
Talk(SAY_ANNOUNCE_BLACK_VIAL);
|
||||
DoCastAOE(SPELL_THROW_BLACK_BOTTLE, true);
|
||||
break;
|
||||
case EVENT_LAND:
|
||||
me->GetMotionMaster()->MoveLand(POINT_LAND, LordVictorNefariusLandPosition);
|
||||
break;
|
||||
case EVENT_SAY_MALORIAK_DEAD:
|
||||
Talk(SAY_MALORIAK_DEAD);
|
||||
_events.ScheduleEvent(EVENT_MASTER_ADVENTURER_AWARD, 7s);
|
||||
break;
|
||||
case EVENT_MASTER_ADVENTURER_AWARD:
|
||||
DoCastAOE(SPELL_MASTER_ADVENTURER_AWARD);
|
||||
_events.ScheduleEvent(EVENT_TELEPORT_AWAY, 2s + 500ms);
|
||||
break;
|
||||
case EVENT_TELEPORT_AWAY:
|
||||
DoCastSelf(SPELL_TELEPORT_VISUAL_ONLY);
|
||||
me->DespawnOrUnsummon(1s + 200ms);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
struct npc_maloriak_vile_swill : public ScriptedAI
|
||||
{
|
||||
npc_maloriak_vile_swill(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void JustAppeared() override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
_events.ScheduleEvent(EVENT_DARK_SLUDGE, 6s);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->DespawnOrUnsummon(5s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DARK_SLUDGE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
||||
DoCast(target, SPELL_DARK_SLUDGE);
|
||||
_events.Repeat(6s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
class spell_maloriak_throw_bottle : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_maloriak_throw_bottle);
|
||||
@@ -763,15 +1098,174 @@ class spell_maloriak_release_experiments : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_maloriak_magma_jets_periodic : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_maloriak_magma_jets_periodic);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_MAGMA_JETS_SUMMON_FIRE });
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit* target = GetTarget();
|
||||
|
||||
uint8 ticks = aurEff->GetTickNumber();
|
||||
float dist = 3.0f * ticks;
|
||||
float x = target->GetPositionX() + cos(target->GetOrientation()) * dist;
|
||||
float y = target->GetPositionY() + sin(target->GetOrientation()) * dist;
|
||||
float z = target->GetMapHeight(x, y, target->GetPositionZ() + 5.0f);
|
||||
if (target->IsWithinLOS(x, y, z))
|
||||
target->CastSpell(x, y, z, SPELL_MAGMA_JETS_SUMMON_FIRE, true);
|
||||
else
|
||||
Remove();
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_maloriak_magma_jets_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_maloriak_absolute_zero : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_maloriak_absolute_zero);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_ABSOLUTE_ZERO_EXPLOSION });
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
caster->RemoveAllAuras();
|
||||
caster->CastSpell(caster, SPELL_ABSOLUTE_ZERO_EXPLOSION);
|
||||
if (Creature * creature = caster->ToCreature())
|
||||
creature->DespawnOrUnsummon(3s);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_maloriak_absolute_zero::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_maloriak_vile_swill: public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_maloriak_vile_swill);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_VILE_SWILL_SUMMON });
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit* target = GetTarget();
|
||||
Position const destination = target->GetRandomPoint(target->GetPosition(), 11.0f);
|
||||
target->CastSpell(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ(), SPELL_VILE_SWILL_SUMMON, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_maloriak_vile_swill::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_maloriak_vile_swill_summon: public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_maloriak_vile_swill_summon);
|
||||
|
||||
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
int32 summonSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell;
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
target->m_Events.AddEventAtOffset([target, summonSpellId]()
|
||||
{
|
||||
target->CastSpell(target, summonSpellId, true);
|
||||
target->SetObjectScale(0.1f);
|
||||
target->m_Events.AddEventAtOffset([target]()
|
||||
{
|
||||
target->RemoveAllAuras();
|
||||
target->DespawnOrUnsummon(4s + 300ms);
|
||||
}, 1s + 200ms);
|
||||
}, 2s);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_maloriak_vile_swill_summon::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_maloriak_master_adventurer_award : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_maloriak_master_adventurer_award);
|
||||
|
||||
void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Player* player = GetTarget()->ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(TITLE_ADVENTURER_AWARD);
|
||||
if (!titleInfo)
|
||||
return;
|
||||
|
||||
player->SetTitle(titleInfo);
|
||||
player->SetUInt32Value(PLAYER_CHOSEN_TITLE, titleInfo->bit_index);
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Player* player = GetTarget()->ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(TITLE_ADVENTURER_AWARD);
|
||||
if (!titleInfo)
|
||||
return;
|
||||
|
||||
player->SetTitle(titleInfo, false);
|
||||
|
||||
if (!player->HasTitle(player->GetInt32Value(PLAYER_CHOSEN_TITLE)))
|
||||
player->SetUInt32Value(PLAYER_CHOSEN_TITLE, 0);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_maloriak_master_adventurer_award::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_maloriak_master_adventurer_award::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_maloriak()
|
||||
{
|
||||
RegisterBlackwingDescentCreatureAI(boss_maloriak);
|
||||
RegisterBlackwingDescentCreatureAI(npc_maloriak_flash_freeze);
|
||||
RegisterBlackwingDescentCreatureAI(npc_maloriak_experiment);
|
||||
RegisterBlackwingDescentCreatureAI(npc_maloriak_magma_jet);
|
||||
RegisterBlackwingDescentCreatureAI(npc_maloriak_lord_victor_nefarius);
|
||||
RegisterBlackwingDescentCreatureAI(npc_maloriak_vile_swill);
|
||||
RegisterSpellScript(spell_maloriak_throw_bottle);
|
||||
RegisterSpellScript(spell_maloriak_throw_bottle_triggered);
|
||||
RegisterAuraScript(spell_maloriak_consuming_flames);
|
||||
RegisterSpellScript(spell_maloriak_flash_freeze_targeting);
|
||||
RegisterSpellScript(spell_maloriak_flash_freeze_dummy);
|
||||
RegisterSpellScript(spell_maloriak_release_experiments);
|
||||
RegisterAuraScript(spell_maloriak_magma_jets_periodic);
|
||||
RegisterSpellScript(spell_maloriak_absolute_zero);
|
||||
RegisterAuraScript(spell_maloriak_vile_swill);
|
||||
RegisterAuraScript(spell_maloriak_vile_swill_summon);
|
||||
RegisterAuraScript(spell_maloriak_master_adventurer_award);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ ObjectData const creatureData[] =
|
||||
{ NPC_FINKLE_EINHORN, DATA_FINKLE_EINHORN },
|
||||
{ NPC_LORD_VICTOR_NEFARIUS_CHIMAERON, DATA_LORD_VICTOR_NEFARIUS_CHIMAERON },
|
||||
{ NPC_CAULDRON_TRIGGER, DATA_CAULDRON_TRIGGER },
|
||||
{ NPC_LORD_VICTOR_NEFARIUS_MALORIAK, DATA_LORD_VICTOR_NEFARIUS_MALORIAK },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
@@ -164,6 +165,7 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
atramedes->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_FLASH_FREEZE:
|
||||
case NPC_VILE_SWILL:
|
||||
if (Creature * maloriak = GetCreature(DATA_MALORIAK))
|
||||
maloriak->AI()->JustSummoned(creature);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user