Scripts/BWD: initial work on Maloriak encounter

This commit is contained in:
Ovahlord committed 2019-07-31 22:57:58 +02:00
1 parent d849ae131d
commit c1627e6a3e
4 files changed
+406 -8

No files matched your search

@@ -36,7 +36,6 @@ enum BWDDataTypes
DATA_NEFARIANS_END = 5,
/*Events*/
DATA_DEAD_DWARF_SPIRITS,
DATA_ANCIENT_BELL,
DATA_COLUMN_OF_LIGHT,
@@ -62,7 +61,11 @@ enum BWDDataTypes
/*Chimaeron*/
DATA_BILE_O_TRON_800,
DATA_FINKLE_EINHORN,
DATA_LORD_VICTOR_NEFARIUS_CHIMAERON
DATA_LORD_VICTOR_NEFARIUS_CHIMAERON,
/*Maloriak*/
DATA_CAULDRON_TRIGGER,
DATA_CAULDRON
};
enum BWDCreatureIds
@@ -115,6 +118,9 @@ enum BWDCreatureIds
NPC_BILE_O_TRON_800 = 44418,
NPC_LORD_VICTOR_NEFARIUS_CHIMAERON = 48964,
/*Maloriak*/
NPC_CAULDRON_TRIGGER = 41505,
/*Events*/
NPC_SPIRIT_OF_MOLTENFIST = 43125,
NPC_SPIRIT_OF_ANVILRAGE = 43128,
@@ -129,9 +135,10 @@ enum BWDCreatureIds
enum BWDGameObjectIds
{
GO_INNER_CHAMBER_DOOR = 205830,
GO_ANCIENT_BELL = 204276,
GO_ATHENAEUM_DOOR = 208291,
GO_INNER_CHAMBER_DOOR = 205830,
GO_ANCIENT_BELL = 204276,
GO_ATHENAEUM_DOOR = 208291,
GO_DOODAD_BLACKROCKV2_LABROOM_CAULDRON_01 = 203306
};
enum BWDMisc
@@ -0,0 +1,386 @@
/*
* Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/>
*
* 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 "ObjectMgr.h"
#include "ScriptMgr.h"
#include "CommonPredicates.h"
#include "GridNotifiers.h"
#include "PassiveAI.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "blackwing_descent.h"
enum Spells
{
// Maloriak
SPELL_ARCANE_STORM = 77896,
SPELL_REMEDY = 77912,
SPELL_THROW_RED_BOTTLE = 77925,
SPELL_THROW_BLUE_BOTTLE = 77932,
SPELL_THROW_GREEN_BOTTLE = 77937,
SPELL_DRINK_RED_BOTTLE = 88699,
SPELL_DRINK_BLUE_BOTTLE = 88700,
SPELL_DRINK_BLACK_BOTTLE = 92828,
SPELL_FIRE_IMBUED = 78896,
SPELL_FROST_IMBUED = 78895,
SPELL_SHADOW_IMBUED = 92716,
SPELL_SLIME_IMBUED = 92917,
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,
// Cauldron Trigger
SPELL_DEBILITATING_SLIME_CAST = 77602,
SPELL_DEBILITATING_SLIME_KNOCKBACK = 77948,
SPELL_DEBILITATING_SLIME_DEBUFF = 77615,
};
enum Events
{
// Maloriak
EVENT_ARCANE_STORM = 1,
EVENT_REMEDY,
EVENT_RELEASE_ABERRATIONS,
EVENT_FACE_TO_CAULDRON,
EVENT_THROW_VIAL,
EVENT_MOVE_TO_CAULDRON,
EVENT_DRINK_BOTTLE,
EVENT_IMBUED_BUFF,
EVENT_EXPLODE_CAULDRON,
EVENT_ATTACK_PLAYERS,
};
enum Actions
{
ACTION_SCHEDULE_EVENTS_FOR_PHASE = 1
};
enum MovePoints
{
POINT_CAULDRON = 1
};
enum Texts
{
// Maloriak
SAY_AGGRO = 0,
SAY_RED_VIAL = 1,
SAY_ANNOUNCE_RED_VIAL = 2,
SAY_BLUE_VIAL = 3,
SAY_ANNOUNCE_BLUE_VIAL = 4,
SAY_GREEN_VIAL = 5,
SAY_ANNOUNCE_GREEN_VIAL = 6,
SAY_RELEASE_ABERRATIONS = 7,
};
enum Vials
{
VIAL_RED = 0,
VIAL_BLUE = 1,
VIAL_GREEN = 2
};
enum GameObjectCustomAnim
{
CUSTOM_ANIM_RED_CAULDRON = 0,
CUSTOM_ANIM_BLUE_CAULDRON = 1,
CUSTOM_ANIM_GREEN_CAULDRON = 2,
CUSTOM_ANIM_BLACK_CAULDRON = 3
};
Position const CauldronMovePosition = { -106.6782f, -475.4438f, 73.45684f };
struct VialData
{
uint8 SayTextId;
uint8 AnnounceTextId;
uint32 ThrowSpellId;
uint32 DrinkSpellId;
uint32 ImbuedSpellId;
};
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 }},
};
struct boss_maloriak : public BossAI
{
boss_maloriak(Creature* creature) : BossAI(creature, DATA_MALORIAK),
_currentVial(urand(VIAL_RED, VIAL_BLUE)), _usedVialsCount(0) { }
void Reset() override
{
_Reset();
me->MakeInterruptable(false);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 15s + 500ms);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
_EnterEvadeMode();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
summons.DespawnAll();
_DespawnAtEvade();
}
void OnSpellCastInterrupt(SpellInfo const* spell) override
{
switch (spell->Id)
{
case SPELL_ARCANE_STORM:
me->MakeInterruptable(false);
me->m_Events.KillAllEvents(true);
break;
case SPELL_RELEASE_ABERRATIONS:
me->MakeInterruptable(false);
break;
default:
break;
}
}
void OnSuccessfulSpellCast(SpellInfo const* spell) override
{
switch (spell->Id)
{
case SPELL_RELEASE_ABERRATIONS:
Talk(SAY_RELEASE_ABERRATIONS);
me->MakeInterruptable(false);
break;
default:
break;
}
}
void MovementInform(uint32 motionType, uint32 pointId) override
{
if (motionType != POINT_MOTION_TYPE && motionType != EFFECT_MOTION_TYPE)
return;
switch (pointId)
{
case POINT_CAULDRON:
events.ScheduleEvent(EVENT_DRINK_BOTTLE, 1s + 500ms);
break;
default:
break;
}
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_SCHEDULE_EVENTS_FOR_PHASE:
events.ScheduleEvent(EVENT_ATTACK_PLAYERS, _currentVial != VIAL_GREEN ? 1ms : 4s);
if (_currentVial == VIAL_RED || _currentVial == VIAL_BLUE)
{
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);
events.ScheduleEvent(EVENT_ARCANE_STORM, 8s);
events.ScheduleEvent(EVENT_REMEDY, 33s + 500ms);
events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 15s);
}
break;
default:
break;
}
}
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_ARCANE_STORM:
{
me->MakeInterruptable(true);
DoCastSelf(SPELL_ARCANE_STORM);
Creature* maloriak = me;
me->m_Events.AddEventAtOffset([maloriak]() { maloriak->MakeInterruptable(false); }, 6s + 500ms);
events.Repeat(13s + 500ms);
break;
}
case EVENT_REMEDY:
DoCastSelf(SPELL_REMEDY);
break;
case EVENT_RELEASE_ABERRATIONS:
me->MakeInterruptable(true);
DoCastAOE(SPELL_RELEASE_ABERRATIONS);
events.Repeat(24s + 500ms);
break;
case EVENT_FACE_TO_CAULDRON:
events.Reset();
if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER))
{
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
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.Repeat(50s);
events.ScheduleEvent(EVENT_THROW_VIAL, 1s + 300ms);
}
break;
case EVENT_THROW_VIAL:
DoCastSelf(vialData[_currentVial].ThrowSpellId);
Talk(vialData[_currentVial].AnnounceTextId);
events.ScheduleEvent(EVENT_MOVE_TO_CAULDRON, 1s);
break;
case EVENT_MOVE_TO_CAULDRON:
me->GetMotionMaster()->MovePoint(POINT_CAULDRON, CauldronMovePosition);
break;
case EVENT_DRINK_BOTTLE:
DoCastSelf(vialData[_currentVial].DrinkSpellId);
events.ScheduleEvent(EVENT_IMBUED_BUFF, 2s + 500ms);
if (_currentVial == VIAL_GREEN)
events.ScheduleEvent(EVENT_EXPLODE_CAULDRON, 1s);
break;
case EVENT_IMBUED_BUFF:
DoCastSelf(vialData[_currentVial].ImbuedSpellId);
DoAction(ACTION_SCHEDULE_EVENTS_FOR_PHASE);
break;
case EVENT_EXPLODE_CAULDRON:
if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER))
{
cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_CAST);
cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_KNOCKBACK);
}
break;
case EVENT_ATTACK_PLAYERS:
me->SetReactState(REACT_AGGRESSIVE);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
uint8 _currentVial;
uint8 _usedVialsCount;
};
class spell_maloriak_throw_bottle : public SpellScript
{
PrepareSpellScript(spell_maloriak_throw_bottle);
void HandleDummyEffect(SpellEffIndex effIndex)
{
if (Unit* caster = GetCaster())
caster->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void Register() override
{
OnEffectLaunchTarget += SpellEffectFn(spell_maloriak_throw_bottle::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
class spell_maloriak_throw_bottle_triggered : public SpellScript
{
PrepareSpellScript(spell_maloriak_throw_bottle_triggered);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_THROW_RED_BOTTLE_TRIGGERED,
SPELL_THROW_BLUE_BOTTLE_TRIGGERED,
SPELL_THROW_GREEN_BOTTLE_TRIGGERED,
SPELL_THROW_BLACK_BOTTLE_TRIGGERED
});
}
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
{
InstanceScript* instance = GetHitUnit()->GetInstanceScript();
if (!instance)
return;
if (GameObject* cauldron = instance->GetGameObject(DATA_CAULDRON))
{
switch (GetSpellInfo()->Id)
{
case SPELL_THROW_RED_BOTTLE_TRIGGERED:
cauldron->SendCustomAnim(CUSTOM_ANIM_RED_CAULDRON);
break;
case SPELL_THROW_BLUE_BOTTLE_TRIGGERED:
cauldron->SendCustomAnim(CUSTOM_ANIM_BLUE_CAULDRON);
break;
case SPELL_THROW_GREEN_BOTTLE_TRIGGERED:
cauldron->SendCustomAnim(CUSTOM_ANIM_GREEN_CAULDRON);
break;
case SPELL_THROW_BLACK_BOTTLE_TRIGGERED:
cauldron->SendCustomAnim(CUSTOM_ANIM_BLACK_CAULDRON);
break;
default:
break;
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_maloriak_throw_bottle_triggered::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
void AddSC_boss_maloriak()
{
RegisterBlackwingDescentCreatureAI(boss_maloriak);
RegisterSpellScript(spell_maloriak_throw_bottle);
RegisterSpellScript(spell_maloriak_throw_bottle_triggered);
}
@@ -28,6 +28,7 @@ ObjectData const creatureData[] =
{ BOSS_OMNOTRON, DATA_OMNOTRON_DEFENSE_SYSTEM },
{ BOSS_ATRAMEDES, DATA_ATRAMEDES },
{ BOSS_CHIMAERON, DATA_CHIMAERON },
{ BOSS_MALORIAK, DATA_MALORIAK },
{ NPC_ELECTRON, DATA_ELECTRON },
{ NPC_MAGMATRON, DATA_MAGMATRON },
{ NPC_TOXITRON, DATA_TOXITRON },
@@ -39,14 +40,16 @@ ObjectData const creatureData[] =
{ NPC_BILE_O_TRON_800, DATA_BILE_O_TRON_800 },
{ NPC_FINKLE_EINHORN, DATA_FINKLE_EINHORN },
{ NPC_LORD_VICTOR_NEFARIUS_CHIMAERON, DATA_LORD_VICTOR_NEFARIUS_CHIMAERON },
{ NPC_CAULDRON_TRIGGER, DATA_CAULDRON_TRIGGER },
{ 0, 0 } // END
};
ObjectData const gameobjectData[] =
{
{ GO_ANCIENT_BELL, DATA_ANCIENT_BELL },
{ GO_ATHENAEUM_DOOR, DATA_ATHENAEUM_DOOR },
{ 0, 0 } // END
{ GO_ANCIENT_BELL, DATA_ANCIENT_BELL },
{ GO_ATHENAEUM_DOOR, DATA_ATHENAEUM_DOOR },
{ GO_DOODAD_BLACKROCKV2_LABROOM_CAULDRON_01, DATA_CAULDRON },
{ 0, 0 } // END
};
DoorData const doorData[] =
@@ -78,6 +78,7 @@ void AddSC_boss_magmaw();
void AddSC_boss_omnotron_defense_system();
void AddSC_boss_atramedes();
void AddSC_boss_chimaeron();
void AddSC_boss_maloriak();
void AddSC_blackwing_descent();
void AddSC_instance_deadmines(); //Deadmines
void AddSC_boss_glubtok();
@@ -307,6 +308,7 @@ void AddEasternKingdomsScripts()
AddSC_boss_omnotron_defense_system();
AddSC_boss_atramedes();
AddSC_boss_chimaeron();
AddSC_boss_maloriak();
AddSC_blackwing_descent();
AddSC_instance_deadmines(); //Deadmines
AddSC_boss_glubtok();