aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2022-02-17 22:40:28 +0200
committerGitHub <noreply@github.com>2022-02-17 22:40:28 +0200
commita19c9660b4be0e7d1bf75e98f93d1bffe5c1566b (patch)
treebd42b23d7b4242a3f227d656b83146497d8696fe
parentcb8b06e836f2e4fa988caf564fdfa5c735419bfb (diff)
Scripts/SL: Update Grandmaster Vorpil (#27765)
Closes #23801
-rw-r--r--sql/updates/world/3.3.5/2022_02_17_00_world.sql42
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp306
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp19
3 files changed, 198 insertions, 169 deletions
diff --git a/sql/updates/world/3.3.5/2022_02_17_00_world.sql b/sql/updates/world/3.3.5/2022_02_17_00_world.sql
new file mode 100644
index 00000000000..f3ab22426f6
--- /dev/null
+++ b/sql/updates/world/3.3.5/2022_02_17_00_world.sql
@@ -0,0 +1,42 @@
+-- Portals / Voidwalkers
+UPDATE `spell_target_position` SET `PositionZ` = 17.0863, `Orientation` = 3.121871, `VerifiedBuild` = 0 WHERE `ID` = 33582;
+UPDATE `spell_target_position` SET `Orientation` = 1.360249 WHERE `ID` = 33583;
+UPDATE `spell_target_position` SET `Orientation` = 5.580167 WHERE `ID` = 33584;
+UPDATE `spell_target_position` SET `Orientation` = 0.047734 WHERE `ID` = 33585;
+UPDATE `spell_target_position` SET `Orientation` = 6.012834 WHERE `ID` = 33586;
+
+-- Draw Shadows
+DELETE FROM `spell_target_position` WHERE `ID` = 33558;
+INSERT INTO `spell_target_position` (`ID`,`EffectIndex`,`MapID`,`PositionX`,`PositionY`,`PositionZ`,`Orientation`,`VerifiedBuild`) VALUES
+(33558,0,555,-253.54771,-263.64563,17.169674,3.054326,0),
+(33558,1,555,-253.54771,-263.64563,17.169674,3.054326,0);
+
+-- Empowering Shadows
+UPDATE `conditions` SET `ConditionValue2` = 18732 WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 39364;
+
+-- Evade / Death spells
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (33568,33618);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,1,33568,0,0,31,0,3,19224,0,0,0,0,"","Group 0: Spell 'Despawn Void Portals' (Effect 0) targets creature 'Void Portal'"),
+(13,1,33568,0,1,31,0,3,19427,0,0,0,0,"","Group 1: Spell 'Despawn Void Portals' (Effect 0) targets creature 'Voidwalker Summoner'"),
+(13,1,33618,0,0,31,0,3,19226,0,0,0,0,"","Group 0: Spell 'Great Sacrifice' (Effect 0) targets creature 'Void Traveler'");
+
+DELETE FROM `spell_script_names` WHERE `spell_id` = 33568 AND `ScriptName` = 'spell_gen_despawn_target';
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(33568,'spell_gen_despawn_target');
+
+--
+UPDATE `creature_template` SET `ScriptName` = 'npc_voidwalker_summoner' WHERE `entry` = 19427;
+UPDATE `creature_template` SET `ScriptName` = 'npc_void_traveler' WHERE `entry` = 19226;
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 18732;
+INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
+(18732,0,0,"Come to my aid! Heed your master now!",14,0,100,0,0,10523,17867,0,"Grandmaster Vorpil SAY_HELP"),
+(18732,1,0,"I'll make an offering of your blood!",14,0,100,0,0,10524,17868,0,"Grandmaster Vorpil SAY_AGGRO1"),
+(18732,1,1,"You'll be a fine example for the others!",14,0,100,0,0,10525,17869,0,"Grandmaster Vorpil SAY_AGGRO2"),
+(18732,1,2,"Good, a worthy sacrifice!",14,0,100,0,0,10526,17870,0,"Grandmaster Vorpil SAY_AGGRO3"),
+(18732,2,0,"I serve with pride.",14,0,100,0,0,10527,17871,0,"Grandmaster Vorpil SAY_SLAY1"),
+(18732,2,1,"Your death is for the greater cause...",14,0,100,0,0,10528,17872,0,"Grandmaster Vorpil SAY_SLAY2"),
+(18732,3,0,"I give my life... gladly.",14,0,100,0,0,10529,17873,0,"Grandmaster Vorpil SAY_DEATH"),
+(18732,4,0,"The darkness in your souls draws you ever closer...",14,0,100,0,0,0,16302,0,"Grandmaster Vorpil SAY_DRAW"),
+(18732,5,0,"Fools.",14,0,100,0,0,0,16330,0,"Grandmaster Vorpil SAY_WIPE");
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
index 154b464c95a..0604e9e62db 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
@@ -15,109 +15,88 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
-Name: Boss_Grandmaster_Vorpil
-%Complete: 100
-Category: Auchindoun, Shadow Labyrinth
-*/
-
#include "ScriptMgr.h"
#include "InstanceScript.h"
-#include "Map.h"
#include "MotionMaster.h"
#include "ObjectAccessor.h"
-#include "Player.h"
#include "ScriptedCreature.h"
#include "shadow_labyrinth.h"
-#include "TemporarySummon.h"
-enum GrandmasterVorpil
+enum Texts
{
- SAY_INTRO = 0,
- SAY_AGGRO = 1,
- SAY_HELP = 2,
- SAY_SLAY = 3,
- SAY_DEATH = 4,
-
- SPELL_RAIN_OF_FIRE = 33617,
- H_SPELL_RAIN_OF_FIRE = 39363,
-
- SPELL_DRAW_SHADOWS = 33563,
- SPELL_SHADOWBOLT_VOLLEY = 33841,
- SPELL_BANISH = 38791,
-
- NPC_VOID_TRAVELER = 19226,
- SPELL_SUMMON_VOID_TRAVELER_A = 33582,
- SPELL_SUMMON_VOID_TRAVELER_B = 33583,
- SPELL_SUMMON_VOID_TRAVELER_C = 33584,
- SPELL_SUMMON_VOID_TRAVELER_D = 33585,
- SPELL_SUMMON_VOID_TRAVELER_E = 33586,
-
- SPELL_SACRIFICE = 33587,
- SPELL_SHADOW_NOVA = 33846,
- SPELL_EMPOWERING_SHADOWS = 33783,
-
- NPC_VOID_PORTAL = 19224,
- SPELL_SUMMON_PORTAL = 33566,
- SPELL_VOID_PORTAL_VISUAL = 33569
+ SAY_HELP = 0,
+ SAY_AGGRO = 1,
+ SAY_SLAY = 2,
+ SAY_DEATH = 3,
+ SAY_DRAW = 4,
+ SAY_WIPE = 5
};
-Position const VorpilPosition = { -252.8820f, -264.3030f, 17.1f, 0.0f };
-
-float VoidPortalCoords[5][3] =
+enum Spells
{
- {-283.5894f, -239.5718f, 12.7f},
- {-306.5853f, -258.4539f, 12.7f},
- {-295.8789f, -269.0899f, 12.7f},
- {-209.3401f, -262.7564f, 17.1f},
- {-261.4533f, -297.3298f, 17.1f}
+ SPELL_SHADOWBOLT_VOLLEY = 33841,
+ SPELL_BANISH = 38791,
+ SPELL_DRAW_SHADOWS = 33563,
+ SPELL_RAIN_OF_FIRE = 33617,
+
+ SPELL_SUMMON_VOID_PORTAL_A = 33566,
+ SPELL_SUMMON_VOID_PORTAL_B = 33614,
+ SPELL_SUMMON_VOID_PORTAL_C = 33615,
+ SPELL_SUMMON_VOID_PORTAL_D = 33567,
+ SPELL_SUMMON_VOID_PORTAL_E = 33616,
+ SPELL_SUMMON_VOID_SUMMONER = 33927,
+
+ SPELL_DESPAWN_VOID_PORTALS = 33568,
+ SPELL_GREAT_SACRIFICE = 33618,
+
+ // Voidwalker Summoner
+ SPELL_SUMMON_VOIDWALKER_A = 33582,
+ SPELL_SUMMON_VOIDWALKER_B = 33583,
+ SPELL_SUMMON_VOIDWALKER_C = 33584,
+ SPELL_SUMMON_VOIDWALKER_D = 33585,
+ SPELL_SUMMON_VOIDWALKER_E = 33586,
+
+ // Void Traveler
+ SPELL_SACRIFICE = 33587,
+ SPELL_SHADOW_NOVA = 33846,
+ SPELL_EMPOWERING_SHADOWS = 33783,
+ SPELL_INSTAKILL_SELF = 29878
};
enum Events
{
- EVENT_SHADOWBOLT_VOLLEY = 1,
- EVENT_BANISH = 2,
- EVENT_DRAW_SHADOWS = 3,
- EVENT_SUMMON_TRAVELER = 4
+ EVENT_HELP = 1,
+ EVENT_SHADOWBOLT_VOLLEY,
+ EVENT_BANISH,
+ EVENT_DRAW_SHADOWS,
+ EVENT_RAIN_OF_FIRE
};
-struct boss_grandmaster_vorpil : public BossAI
+std::array<uint32, 5> const VoidwalkerSummonSpells =
{
- boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL)
- {
- Initialize();
- _intro = false;
- }
-
- void Initialize()
- {
- _helpYell = false;
- }
+ SPELL_SUMMON_VOIDWALKER_A, SPELL_SUMMON_VOIDWALKER_B, SPELL_SUMMON_VOIDWALKER_C, SPELL_SUMMON_VOIDWALKER_D, SPELL_SUMMON_VOIDWALKER_E
+};
- void Reset() override
- {
- _Reset();
- Initialize();
- }
+struct boss_grandmaster_vorpil : public BossAI
+{
+ boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL) { }
- void SummonPortals()
+ void JustEngagedWith(Unit* who) override
{
- for (uint8 i = 0; i < 5; ++i)
- if (Creature* portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 50min))
- portal->CastSpell(portal, SPELL_VOID_PORTAL_VISUAL, true);
-
- events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5s);
- }
+ BossAI::JustEngagedWith(who);
+ events.ScheduleEvent(EVENT_HELP, 6s);
+ events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 10s, 15s);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_BANISH, 10s, 20s);
+ events.ScheduleEvent(EVENT_DRAW_SHADOWS, 35s, 45s);
- void spawnVoidTraveler()
- {
- uint8 pos = urand(0, 4);
- me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5s);
- if (!_helpYell)
- {
- Talk(SAY_HELP);
- _helpYell = true;
- }
+ Talk(SAY_AGGRO);
+ DoCastSelf(SPELL_SUMMON_VOID_PORTAL_A);
+ DoCastSelf(SPELL_SUMMON_VOID_PORTAL_B);
+ DoCastSelf(SPELL_SUMMON_VOID_PORTAL_C);
+ DoCastSelf(SPELL_SUMMON_VOID_PORTAL_D);
+ DoCastSelf(SPELL_SUMMON_VOID_PORTAL_E);
+ DoCastSelf(SPELL_SUMMON_VOID_SUMMONER);
}
void KilledUnit(Unit* who) override
@@ -126,34 +105,23 @@ struct boss_grandmaster_vorpil : public BossAI
Talk(SAY_SLAY);
}
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
+ // Despawn is handled by spells, don't store anything
+ void JustSummoned(Creature* /*summon*/) override { }
- void JustEngagedWith(Unit* who) override
+ void EnterEvadeMode(EvadeReason why) override
{
- BossAI::JustEngagedWith(who);
- events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 7s, 14s);
- if (IsHeroic())
- events.ScheduleEvent(EVENT_BANISH, 15s);
- events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45s);
- events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90s);
-
- Talk(SAY_AGGRO);
- SummonPortals();
+ Talk(SAY_WIPE);
+ DoCastSelf(SPELL_DESPAWN_VOID_PORTALS, true);
+ DoCastSelf(SPELL_GREAT_SACRIFICE, true);
+ ScriptedAI::EnterEvadeMode(why);
}
- void MoveInLineOfSight(Unit* who) override
+ void JustDied(Unit* /*killer*/) override
{
- BossAI::MoveInLineOfSight(who);
-
- if (!_intro && me->IsWithinLOSInMap(who) && me->IsWithinDistInMap(who, 100) && me->IsValidAttackTarget(who))
- {
- Talk(SAY_INTRO);
- _intro = true;
- }
+ _JustDied();
+ Talk(SAY_DEATH);
+ DoCastSelf(SPELL_DESPAWN_VOID_PORTALS, true);
+ DoCastSelf(SPELL_GREAT_SACRIFICE, true);
}
void UpdateAI(uint32 diff) override
@@ -170,36 +138,27 @@ struct boss_grandmaster_vorpil : public BossAI
{
switch (eventId)
{
+ case EVENT_HELP:
+ Talk(SAY_HELP);
+ break;
case EVENT_SHADOWBOLT_VOLLEY:
- DoCast(me, SPELL_SHADOWBOLT_VOLLEY);
- events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 15s, 30s);
+ DoCastSelf(SPELL_SHADOWBOLT_VOLLEY);
+ events.Repeat(10s, 25s);
break;
case EVENT_BANISH:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, false))
- DoCast(target, SPELL_BANISH);
- events.ScheduleEvent(EVENT_BANISH, 15s);
+ DoCast(target, SPELL_BANISH);
+ events.Repeat(20s, 30s);
break;
case EVENT_DRAW_SHADOWS:
- {
- Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->GetSource())
- if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH))
- i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT);
-
- me->UpdatePosition(VorpilPosition);
- DoCast(me, SPELL_DRAW_SHADOWS, true);
- DoCast(me, SPELL_RAIN_OF_FIRE);
- events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6s);
- events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30s);
- break;
- }
- case EVENT_SUMMON_TRAVELER:
- spawnVoidTraveler();
- events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10s);
- // enrage at 20%
- if (HealthBelowPct(20))
- events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5s);
+ if (roll_chance_i(50))
+ Talk(SAY_DRAW);
+ DoCastSelf(SPELL_DRAW_SHADOWS);
+ events.Repeat(35s, 45s);
+ events.ScheduleEvent(EVENT_RAIN_OF_FIRE, 1s);
+ break;
+ case EVENT_RAIN_OF_FIRE:
+ DoCastSelf(SPELL_RAIN_OF_FIRE);
break;
}
@@ -209,70 +168,79 @@ struct boss_grandmaster_vorpil : public BossAI
DoMeleeAttackIfReady();
}
-
- private:
- bool _intro;
- bool _helpYell;
};
-struct npc_voidtraveler : public ScriptedAI
+struct npc_voidwalker_summoner : public ScriptedAI
{
- npc_voidtraveler(Creature* creature) : ScriptedAI(creature)
+ npc_voidwalker_summoner(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
{
- Initialize();
- _instance = creature->GetInstanceScript();
+ _scheduler.Schedule(10s, [this](TaskContext task)
+ {
+ DoCastSelf(Trinity::Containers::SelectRandomContainerElement(VoidwalkerSummonSpells));
+ task.Repeat(10s, 15s);
+ });
}
- void Initialize()
+ void UpdateAI(uint32 diff) override
{
- _moveTimer = 0;
- _sacrificed = false;
+ _scheduler.Update(diff);
}
- void Reset() override
+private:
+ TaskScheduler _scheduler;
+};
+
+struct npc_void_traveler : public ScriptedAI
+{
+ npc_void_traveler(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void InitializeAI() override
{
- Initialize();
+ me->SetReactState(REACT_PASSIVE);
}
- void JustEngagedWith(Unit* /*who*/) override { }
-
- void UpdateAI(uint32 diff) override
+ // This part needs more work
+ void JustAppeared() override
{
- if (_moveTimer <= diff)
- {
- Creature* Vorpil = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_GRANDMASTER_VORPIL));
- if (!Vorpil)
- return;
+ if (Creature* vorpil = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_GRANDMASTER_VORPIL)))
+ me->GetMotionMaster()->MoveFollow(vorpil, 0, 0);
- if (_sacrificed)
- {
- DoCastAOE(SPELL_EMPOWERING_SHADOWS, true);
- DoCast(me, SPELL_SHADOW_NOVA, true);
- me->KillSelf();
- return;
- }
- me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0);
- if (me->IsWithinDist(Vorpil, 3))
+ _scheduler.Schedule(500ms, [this](TaskContext task)
+ {
+ if (Creature* vorpil = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_GRANDMASTER_VORPIL)))
{
- DoCast(me, SPELL_SACRIFICE, false);
- _sacrificed = true;
- _moveTimer = 500;
- return;
+ if (me->IsWithinDist(vorpil, 3))
+ {
+ DoCastSelf(SPELL_SACRIFICE);
+
+ task.Schedule(1s, [this](TaskContext /*task*/)
+ {
+ DoCastSelf(SPELL_EMPOWERING_SHADOWS);
+ DoCastSelf(SPELL_SHADOW_NOVA);
+ DoCastSelf(SPELL_INSTAKILL_SELF);
+ });
+ }
+ else
+ task.Repeat();
}
- _moveTimer = 1000;
- }
- else
- _moveTimer -= diff;
+ });
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
}
private:
+ TaskScheduler _scheduler;
InstanceScript* _instance;
- uint32 _moveTimer;
- bool _sacrificed;
};
void AddSC_boss_grandmaster_vorpil()
{
RegisterShadowLabyrinthCreatureAI(boss_grandmaster_vorpil);
- RegisterShadowLabyrinthCreatureAI(npc_voidtraveler);
+ RegisterShadowLabyrinthCreatureAI(npc_voidwalker_summoner);
+ RegisterShadowLabyrinthCreatureAI(npc_void_traveler);
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 20723bfdff3..7b7b1121bbd 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -1405,6 +1405,7 @@ class spell_gen_despawn_aura : public AuraScript
}
};
+/// @todo: migrate spells to spell_gen_despawn_target, then remove this
class spell_gen_despawn_self : public SpellScript
{
PrepareSpellScript(spell_gen_despawn_self);
@@ -1426,6 +1427,23 @@ class spell_gen_despawn_self : public SpellScript
}
};
+class spell_gen_despawn_target : public SpellScript
+{
+ PrepareSpellScript(spell_gen_despawn_target);
+
+ void HandleDespawn(SpellEffIndex /*effIndex*/)
+ {
+ if (GetEffectInfo().IsEffect(SPELL_EFFECT_DUMMY) || GetEffectInfo().IsEffect(SPELL_EFFECT_SCRIPT_EFFECT))
+ if (Creature* target = GetHitCreature())
+ target->DespawnOrUnsummon();
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_target::HandleDespawn, EFFECT_ALL, SPELL_EFFECT_ANY);
+ }
+};
+
enum DivineStormSpell
{
SPELL_DIVINE_STORM = 53385,
@@ -4568,6 +4586,7 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_defend);
RegisterSpellScript(spell_gen_despawn_aura);
RegisterSpellScript(spell_gen_despawn_self);
+ RegisterSpellScript(spell_gen_despawn_target);
RegisterSpellScript(spell_gen_divine_storm_cd_reset);
RegisterSpellScript(spell_gen_ds_flush_knockback);
RegisterSpellScript(spell_gen_dungeon_credit);