Start adding missing scripts Part 7
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* 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 3 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game;
|
||||||
|
using Game.AI;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Scripting;
|
||||||
|
|
||||||
|
namespace Scripts.Draenor
|
||||||
|
{
|
||||||
|
// 79243 - Baros Alexston
|
||||||
|
struct MiscConst
|
||||||
|
{
|
||||||
|
// Quest
|
||||||
|
public const uint QuestEstablishYourGarrison = 34586;
|
||||||
|
|
||||||
|
// Gossip
|
||||||
|
public const uint GossipOptionEstablishGarrison = 0;
|
||||||
|
|
||||||
|
// Text
|
||||||
|
public const uint SayStartConstruction = 0;
|
||||||
|
|
||||||
|
// Spells
|
||||||
|
public const uint SpellQuest34586Killcredit = 161033;
|
||||||
|
public const uint SpellCreateGarrisonShadowmoonValleyAlliance = 156020;
|
||||||
|
public const uint SpellDespawnAllSummonsGarrisonIntroOnly = 160938;
|
||||||
|
|
||||||
|
public static Position GarrisonLevelOneCreationPlayerPosition = new Position(1904.58f, 312.906f, 88.9542f, 4.303615f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class npc_baros_alexston : ScriptedAI
|
||||||
|
{
|
||||||
|
public npc_baros_alexston(Creature creature) : base(creature) { }
|
||||||
|
|
||||||
|
public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||||
|
{
|
||||||
|
if (gossipListId == MiscConst.GossipOptionEstablishGarrison)
|
||||||
|
{
|
||||||
|
player.CloseGossipMenu();
|
||||||
|
player.CastSpell(player, MiscConst.SpellQuest34586Killcredit, true);
|
||||||
|
player.CastSpell(player, MiscConst.SpellCreateGarrisonShadowmoonValleyAlliance, true);
|
||||||
|
player.CastSpell(player, MiscConst.SpellDespawnAllSummonsGarrisonIntroOnly, true);
|
||||||
|
player.NearTeleportTo(MiscConst.GarrisonLevelOneCreationPlayerPosition);
|
||||||
|
|
||||||
|
PhasingHandler.OnConditionChange(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnQuestAccept(Player player, Quest quest)
|
||||||
|
{
|
||||||
|
if (quest.Id == MiscConst.QuestEstablishYourGarrison)
|
||||||
|
Talk(MiscConst.SayStartConstruction, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script] // 160938 - Despawn All Summons (Garrison Intro Only)
|
||||||
|
class spell_despawn_all_summons_garrison_intro_only : SpellScript
|
||||||
|
{
|
||||||
|
void HandleScript(uint effIndex)
|
||||||
|
{
|
||||||
|
Creature hitCreature = GetHitCreature();
|
||||||
|
if (hitCreature)
|
||||||
|
{
|
||||||
|
if (hitCreature.GetOwner() == GetCaster())
|
||||||
|
hitCreature.DespawnOrUnsummon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Register()
|
||||||
|
{
|
||||||
|
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,472 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* 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 3 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game.AI;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Maps;
|
||||||
|
using Game.Scripting;
|
||||||
|
using Game.Spells;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Scripts.EasternKingdoms.MagistersTerrace.FelbloodKaelthas
|
||||||
|
{
|
||||||
|
struct TextIds
|
||||||
|
{
|
||||||
|
// Kael'thas Sunstrider
|
||||||
|
public const uint SayIntro1 = 0;
|
||||||
|
public const uint SayIntro2 = 1;
|
||||||
|
public const uint SayGravityLapse1 = 2;
|
||||||
|
public const uint SayGravityLapse2 = 3;
|
||||||
|
public const uint SayPowerFeedback = 4;
|
||||||
|
public const uint SaySummonPhoenix = 5;
|
||||||
|
public const uint SayAnnouncePyroblast = 6;
|
||||||
|
public const uint SayFlameStrike = 7;
|
||||||
|
public const uint SayDeath = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpellIds
|
||||||
|
{
|
||||||
|
// Kael'thas Sunstrider
|
||||||
|
public const uint Fireball = 44189;
|
||||||
|
public const uint GravityLapse = 49887;
|
||||||
|
public const uint HGravityLapse = 44226;
|
||||||
|
public const uint GravityLapseCenterTeleport = 44218;
|
||||||
|
public const uint GravityLapseLeftTeleport = 44219;
|
||||||
|
public const uint GravityLapseFrontLeftTeleport = 44220;
|
||||||
|
public const uint GravityLapseFrontTeleport = 44221;
|
||||||
|
public const uint GravityLapseFrontRightTeleport = 44222;
|
||||||
|
public const uint GravityLapseRightTeleport = 44223;
|
||||||
|
public const uint GravityLapseInitial = 44224;
|
||||||
|
public const uint GravityLapseFly = 44227;
|
||||||
|
public const uint GravityLapseBeamVisualPeriodic = 44251;
|
||||||
|
public const uint SummonArcaneSphere = 44265;
|
||||||
|
public const uint FlameStrike = 46162;
|
||||||
|
public const uint ShockBarrier = 46165;
|
||||||
|
public const uint PowerFeedback = 44233;
|
||||||
|
public const uint HPowerFeedback = 47109;
|
||||||
|
public const uint Pyroblast = 36819;
|
||||||
|
public const uint Phoenix = 44194;
|
||||||
|
public const uint EmoteTalkExclamation = 48348;
|
||||||
|
public const uint EmotePoint = 48349;
|
||||||
|
public const uint EmoteRoar = 48350;
|
||||||
|
public const uint ClearFlight = 44232;
|
||||||
|
public const uint QuiteSuicide = 3617; // Serverside public const uint
|
||||||
|
|
||||||
|
// Flame Strike
|
||||||
|
public const uint FlameStrikeDummy = 44191;
|
||||||
|
public const uint FlameStrikeDamage = 44190;
|
||||||
|
|
||||||
|
// Phoenix
|
||||||
|
public const uint Rebirth = 44196;
|
||||||
|
public const uint Burn = 44197;
|
||||||
|
public const uint EmberBlast = 44199;
|
||||||
|
public const uint SummonPhoenixEgg = 44195; // Serverside public const uint
|
||||||
|
public const uint FullHeal = 17683;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Phase
|
||||||
|
{
|
||||||
|
Intro = 0,
|
||||||
|
One = 1,
|
||||||
|
Two = 2,
|
||||||
|
Outro = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MiscConst
|
||||||
|
{
|
||||||
|
public static uint[] GravityLapseTeleportSpells =
|
||||||
|
{
|
||||||
|
SpellIds.GravityLapseLeftTeleport,
|
||||||
|
SpellIds.GravityLapseFrontLeftTeleport,
|
||||||
|
SpellIds.GravityLapseFrontTeleport,
|
||||||
|
SpellIds.GravityLapseFrontRightTeleport,
|
||||||
|
SpellIds.GravityLapseRightTeleport
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class boss_felblood_kaelthas : BossAI
|
||||||
|
{
|
||||||
|
byte _gravityLapseTargetCount;
|
||||||
|
bool _firstGravityLapse;
|
||||||
|
|
||||||
|
Phase _phase;
|
||||||
|
|
||||||
|
static uint groupFireBall = 1;
|
||||||
|
|
||||||
|
public boss_felblood_kaelthas(Creature creature) : base(creature, DataTypes.KaelthasSunstrider)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
_gravityLapseTargetCount = 0;
|
||||||
|
_firstGravityLapse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustEngagedWith(Unit who)
|
||||||
|
{
|
||||||
|
base.JustEngagedWith(who);
|
||||||
|
_phase = Phase.One;
|
||||||
|
|
||||||
|
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), groupFireBall, task =>
|
||||||
|
{
|
||||||
|
DoCastVictim(SpellIds.Fireball);
|
||||||
|
task.Repeat(TimeSpan.FromSeconds(2.5));
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(44), task =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayFlameStrike);
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 40.0f, true);
|
||||||
|
if (target)
|
||||||
|
DoCast(target, SpellIds.FlameStrike);
|
||||||
|
task.Repeat();
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SaySummonPhoenix);
|
||||||
|
DoCastSelf(SpellIds.Phoenix);
|
||||||
|
task.Repeat(TimeSpan.FromSeconds(45));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (IsHeroic())
|
||||||
|
{
|
||||||
|
_scheduler.Schedule(TimeSpan.FromMinutes(1) + TimeSpan.FromSeconds(1), task =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayAnnouncePyroblast);
|
||||||
|
DoCastSelf(SpellIds.ShockBarrier);
|
||||||
|
task.RescheduleGroup(groupFireBall, TimeSpan.FromSeconds(2.5));
|
||||||
|
task.Schedule(TimeSpan.FromSeconds(2), pyroBlastTask =>
|
||||||
|
{
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 40.0f, true);
|
||||||
|
if (target != null)
|
||||||
|
DoCast(target, SpellIds.Pyroblast);
|
||||||
|
});
|
||||||
|
task.Repeat(TimeSpan.FromMinutes(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
_Reset();
|
||||||
|
Initialize();
|
||||||
|
_phase = Phase.Intro;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustDied(Unit killer)
|
||||||
|
{
|
||||||
|
// No _JustDied() here because otherwise we would reset the events which will trigger the death sequence twice.
|
||||||
|
instance.SetBossState(DataTypes.KaelthasSunstrider, EncounterState.Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void EnterEvadeMode(EvadeReason why)
|
||||||
|
{
|
||||||
|
DoCastAOE(SpellIds.ClearFlight, new CastSpellExtraArgs(true));
|
||||||
|
_EnterEvadeMode();
|
||||||
|
summons.DespawnAll();
|
||||||
|
_DespawnAtEvade();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||||
|
{
|
||||||
|
// Checking for lethal damage first so we trigger the outro phase without triggering phase two in case of oneshot attacks
|
||||||
|
if (damage >= me.GetHealth() && _phase != Phase.Outro)
|
||||||
|
{
|
||||||
|
me.AttackStop();
|
||||||
|
me.SetReactState(ReactStates.Passive);
|
||||||
|
me.InterruptNonMeleeSpells(true);
|
||||||
|
me.RemoveAurasDueToSpell(DungeonMode(SpellIds.PowerFeedback, SpellIds.HPowerFeedback));
|
||||||
|
summons.DespawnAll();
|
||||||
|
DoCastAOE(SpellIds.ClearFlight);
|
||||||
|
Talk(TextIds.SayDeath);
|
||||||
|
|
||||||
|
_phase = Phase.Outro;
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.EmoteTalkExclamation);
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(3.8), task =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.EmotePoint);
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(7.4), task =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.EmoteRoar);
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.EmoteRoar);
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(11), task =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.QuiteSuicide);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase two checks. Skip phase two if we are in the outro already
|
||||||
|
if (me.HealthBelowPctDamaged(50, damage) && _phase != Phase.Two && _phase != Phase.Outro)
|
||||||
|
{
|
||||||
|
_phase = Phase.Two;
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), task =>
|
||||||
|
{
|
||||||
|
Talk(_firstGravityLapse ? TextIds.SayGravityLapse1 : TextIds.SayGravityLapse2);
|
||||||
|
_firstGravityLapse = false;
|
||||||
|
me.SetReactState(ReactStates.Passive);
|
||||||
|
me.AttackStop();
|
||||||
|
me.GetMotionMaster().Clear();
|
||||||
|
task.Schedule(TimeSpan.FromSeconds(1), _ =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.GravityLapseCenterTeleport);
|
||||||
|
task.Schedule(TimeSpan.FromSeconds(1), _ =>
|
||||||
|
{
|
||||||
|
_gravityLapseTargetCount = 0;
|
||||||
|
DoCastAOE(SpellIds.GravityLapseInitial);
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(4), _ =>
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < 3; i++)
|
||||||
|
DoCastSelf(SpellIds.SummonArcaneSphere, new CastSpellExtraArgs(true));
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(5), _ =>
|
||||||
|
{
|
||||||
|
DoCastAOE(SpellIds.GravityLapseBeamVisualPeriodic);
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(35), _ =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayPowerFeedback);
|
||||||
|
DoCastAOE(SpellIds.ClearFlight);
|
||||||
|
DoCastSelf(DungeonMode(SpellIds.PowerFeedback, SpellIds.HPowerFeedback));
|
||||||
|
summons.DespawnEntry(CreatureIds.ArcaneSphere);
|
||||||
|
task.Repeat(TimeSpan.FromSeconds(11));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kael'thas may only kill himself via Quite Suicide
|
||||||
|
if (damage >= me.GetHealth() && attacker != me)
|
||||||
|
damage = (uint)(me.GetHealth() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetData(uint type, uint data)
|
||||||
|
{
|
||||||
|
if (type == DataTypes.KaelthasIntro)
|
||||||
|
{
|
||||||
|
// skip the intro if Kael'thas is engaged already
|
||||||
|
if (_phase != Phase.Intro)
|
||||||
|
return;
|
||||||
|
|
||||||
|
me.SetImmuneToPC(true);
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayIntro1);
|
||||||
|
me.SetEmoteState(Emote.StateTalk);
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(20.6), _ =>
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayIntro2);
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(15) + TimeSpan.FromMilliseconds(500), _ =>
|
||||||
|
{
|
||||||
|
me.SetEmoteState(Emote.OneshotNone);
|
||||||
|
me.SetImmuneToPC(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(15.6), _ => me.HandleEmoteCommand(Emote.OneshotLaughNoSheathe));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SpellHitTarget(WorldObject target, SpellInfo spellInfo)
|
||||||
|
{
|
||||||
|
Unit unitTarget = target.ToUnit();
|
||||||
|
if (!unitTarget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (spellInfo.Id)
|
||||||
|
{
|
||||||
|
case SpellIds.GravityLapseInitial:
|
||||||
|
{
|
||||||
|
DoCast(unitTarget, MiscConst.GravityLapseTeleportSpells[_gravityLapseTargetCount], new CastSpellExtraArgs(true));
|
||||||
|
target.m_Events.AddEventAtOffset(() =>
|
||||||
|
{
|
||||||
|
target.CastSpell(target, DungeonMode(SpellIds.GravityLapse, SpellIds.HGravityLapse));
|
||||||
|
target.CastSpell(target, SpellIds.GravityLapseFly);
|
||||||
|
|
||||||
|
}, TimeSpan.FromMilliseconds(400));
|
||||||
|
_gravityLapseTargetCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SpellIds.ClearFlight:
|
||||||
|
unitTarget.RemoveAurasDueToSpell(SpellIds.GravityLapseFly);
|
||||||
|
unitTarget.RemoveAurasDueToSpell(DungeonMode(SpellIds.GravityLapse, SpellIds.HGravityLapse));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustSummoned(Creature summon)
|
||||||
|
{
|
||||||
|
summons.Summon(summon);
|
||||||
|
|
||||||
|
switch (summon.GetEntry())
|
||||||
|
{
|
||||||
|
case CreatureIds.ArcaneSphere:
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 70.0f, true);
|
||||||
|
if (target)
|
||||||
|
summon.GetMotionMaster().MoveFollow(target, 0.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
case CreatureIds.FlameStrike:
|
||||||
|
summon.CastSpell(summon, SpellIds.FlameStrikeDummy);
|
||||||
|
summon.DespawnOrUnsummon(TimeSpan.FromSeconds(15));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAI(uint diff)
|
||||||
|
{
|
||||||
|
if (!UpdateVictim() && _phase != Phase.Intro)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_scheduler.Update(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class npc_felblood_kaelthas_phoenix : ScriptedAI
|
||||||
|
{
|
||||||
|
InstanceScript _instance;
|
||||||
|
|
||||||
|
bool _isInEgg;
|
||||||
|
ObjectGuid _eggGUID;
|
||||||
|
|
||||||
|
public npc_felblood_kaelthas_phoenix(Creature creature) : base(creature)
|
||||||
|
{
|
||||||
|
_instance = creature.GetInstanceScript();
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
me.SetReactState(ReactStates.Passive);
|
||||||
|
_isInEgg = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void IsSummonedBy(WorldObject summoner)
|
||||||
|
{
|
||||||
|
DoZoneInCombat();
|
||||||
|
DoCastSelf(SpellIds.Burn);
|
||||||
|
DoCastSelf(SpellIds.Rebirth);
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(2), task => me.SetReactState(ReactStates.Aggressive));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustEngagedWith(Unit who) { }
|
||||||
|
|
||||||
|
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||||
|
{
|
||||||
|
if (damage >= me.GetHealth())
|
||||||
|
{
|
||||||
|
if (!_isInEgg)
|
||||||
|
{
|
||||||
|
me.AttackStop();
|
||||||
|
me.SetReactState(ReactStates.Passive);
|
||||||
|
me.RemoveAllAuras();
|
||||||
|
me.SetUnitFlag(UnitFlags.Uninteractible);
|
||||||
|
DoCastSelf(SpellIds.EmberBlast);
|
||||||
|
// DoCastSelf(SpellSummonPhoenixEgg); -- We do a manual summon for now. Feel free to move it to spelleffect_dbc
|
||||||
|
Creature egg = DoSummon(CreatureIds.PhoenixEgg, me.GetPosition(), TimeSpan.FromSeconds(0));
|
||||||
|
if (egg)
|
||||||
|
{
|
||||||
|
Creature kaelthas = _instance.GetCreature(DataTypes.KaelthasSunstrider);
|
||||||
|
if (kaelthas)
|
||||||
|
{
|
||||||
|
kaelthas.GetAI().JustSummoned(egg);
|
||||||
|
_eggGUID = egg.GetGUID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||||
|
{
|
||||||
|
Creature egg = ObjectAccessor.GetCreature(me, _eggGUID);
|
||||||
|
if (egg)
|
||||||
|
egg.DespawnOrUnsummon();
|
||||||
|
|
||||||
|
me.RemoveAllAuras();
|
||||||
|
task.Schedule(TimeSpan.FromSeconds(2), rebirthTask =>
|
||||||
|
{
|
||||||
|
DoCastSelf(SpellIds.Rebirth);
|
||||||
|
rebirthTask.Schedule(TimeSpan.FromSeconds(2), engageTask =>
|
||||||
|
{
|
||||||
|
_isInEgg = false;
|
||||||
|
DoCastSelf(SpellIds.FullHeal);
|
||||||
|
DoCastSelf(SpellIds.Burn);
|
||||||
|
me.RemoveUnitFlag(UnitFlags.Uninteractible);
|
||||||
|
engageTask.Schedule(TimeSpan.FromSeconds(2), task => me.SetReactState(ReactStates.Aggressive));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_isInEgg = true;
|
||||||
|
}
|
||||||
|
damage = (uint)(me.GetHealth() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SummonedCreatureDies(Creature summon, Unit killer)
|
||||||
|
{
|
||||||
|
// Egg has been destroyed within 15 seconds so we lose the phoenix.
|
||||||
|
me.DespawnOrUnsummon();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAI(uint diff)
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script] // 44191 - Flame Strike
|
||||||
|
class spell_felblood_kaelthas_flame_strike : AuraScript
|
||||||
|
{
|
||||||
|
public override bool Validate(SpellInfo spellInfo)
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo(SpellIds.FlameStrikeDamage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||||
|
{
|
||||||
|
Unit target = GetTarget();
|
||||||
|
if (target)
|
||||||
|
target.CastSpell(target, SpellIds.FlameStrikeDamage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Register()
|
||||||
|
{
|
||||||
|
AfterEffectRemove.Add(new EffectApplyHandler(AfterRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* 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 3 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Maps;
|
||||||
|
using Game.Scripting;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Scripts.EasternKingdoms.MagistersTerrace
|
||||||
|
{
|
||||||
|
struct DataTypes
|
||||||
|
{
|
||||||
|
// Encounter states
|
||||||
|
public const uint SelinFireheart = 0;
|
||||||
|
public const uint Vexallus = 1;
|
||||||
|
public const uint PriestessDelrissa = 2;
|
||||||
|
public const uint KaelthasSunstrider = 3;
|
||||||
|
|
||||||
|
// Encounter related
|
||||||
|
public const uint KaelthasIntro = 4;
|
||||||
|
public const uint DelrissaDeathCount = 5;
|
||||||
|
|
||||||
|
// Additional data
|
||||||
|
public const uint Kalecgos = 6;
|
||||||
|
public const uint EscapeOrb = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CreatureIds
|
||||||
|
{
|
||||||
|
// Bosses
|
||||||
|
public const uint KaelthasSunstrider = 24664;
|
||||||
|
public const uint SelinFireheart = 24723;
|
||||||
|
public const uint Vexallus = 24744;
|
||||||
|
public const uint PriestessDelrissa = 24560;
|
||||||
|
|
||||||
|
// Encounter related
|
||||||
|
// Kael'thas Sunstrider
|
||||||
|
public const uint ArcaneSphere = 24708;
|
||||||
|
public const uint FlameStrike = 24666;
|
||||||
|
public const uint Phoenix = 24674;
|
||||||
|
public const uint PhoenixEgg = 24675;
|
||||||
|
|
||||||
|
// Selin Fireheart
|
||||||
|
public const uint FelCrystal = 24722;
|
||||||
|
|
||||||
|
// Event related
|
||||||
|
public const uint Kalecgos = 24844;
|
||||||
|
public const uint HumanKalecgos = 24848;
|
||||||
|
public const uint CoilskarWitch = 24696;
|
||||||
|
public const uint SunbladeWarlock = 24686;
|
||||||
|
public const uint SunbladeMageGuard = 24683;
|
||||||
|
public const uint SisterOfTorment = 24697;
|
||||||
|
public const uint EthereumSmuggler = 24698;
|
||||||
|
public const uint SunbladeBloodKnight = 24684;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GameObjectIds
|
||||||
|
{
|
||||||
|
public const uint AssemblyChamberDoor = 188065;
|
||||||
|
public const uint SunwellRaidGate2 = 187979;
|
||||||
|
public const uint SunwellRaidGate4 = 187770;
|
||||||
|
public const uint SunwellRaidGate5 = 187896;
|
||||||
|
public const uint AsylumDoor = 188064;
|
||||||
|
public const uint EscapeOrb = 188173;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MiscConst
|
||||||
|
{
|
||||||
|
public const uint EventSpawnKalecgos = 16547;
|
||||||
|
|
||||||
|
public const uint SayKalecgosSpawn = 0;
|
||||||
|
|
||||||
|
public const uint PathKalecgosFlight = 248440;
|
||||||
|
|
||||||
|
public static ObjectData[] creatureData =
|
||||||
|
{
|
||||||
|
new ObjectData(CreatureIds.SelinFireheart, DataTypes.SelinFireheart),
|
||||||
|
new ObjectData(CreatureIds.Vexallus, DataTypes.Vexallus),
|
||||||
|
new ObjectData(CreatureIds.PriestessDelrissa, DataTypes.PriestessDelrissa),
|
||||||
|
new ObjectData(CreatureIds.KaelthasSunstrider, DataTypes.KaelthasSunstrider),
|
||||||
|
new ObjectData(CreatureIds.Kalecgos, DataTypes.Kalecgos),
|
||||||
|
new ObjectData(CreatureIds.HumanKalecgos, DataTypes.Kalecgos),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static ObjectData[] gameObjectData =
|
||||||
|
{
|
||||||
|
new ObjectData(GameObjectIds.EscapeOrb, DataTypes.EscapeOrb),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static DoorData[] doorData =
|
||||||
|
{
|
||||||
|
new DoorData(GameObjectIds.SunwellRaidGate2, DataTypes.SelinFireheart, DoorType.Passage),
|
||||||
|
new DoorData(GameObjectIds.AssemblyChamberDoor, DataTypes.SelinFireheart, DoorType.Room),
|
||||||
|
new DoorData(GameObjectIds.SunwellRaidGate5, DataTypes.Vexallus, DoorType.Passage),
|
||||||
|
new DoorData(GameObjectIds.SunwellRaidGate4, DataTypes.PriestessDelrissa, DoorType.Passage),
|
||||||
|
new DoorData(GameObjectIds.AsylumDoor, DataTypes.KaelthasSunstrider, DoorType.Room),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Position KalecgosSpawnPos = new Position(164.3747f, -397.1197f, 2.151798f, 1.66219f);
|
||||||
|
public static Position KaelthasTrashGroupDistanceComparisonPos = new Position(150.0f, 141.0f, -14.4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class instance_magisters_terrace : InstanceMapScript
|
||||||
|
{
|
||||||
|
public instance_magisters_terrace() : base(nameof(instance_magisters_terrace), 585) { }
|
||||||
|
|
||||||
|
class instance_magisters_terrace_InstanceMapScript : InstanceScript
|
||||||
|
{
|
||||||
|
List<ObjectGuid> _kaelthasPreTrashGUIDs = new();
|
||||||
|
byte _delrissaDeathCount;
|
||||||
|
|
||||||
|
public instance_magisters_terrace_InstanceMapScript(InstanceMap map) : base(map)
|
||||||
|
{
|
||||||
|
SetHeaders("MT");
|
||||||
|
SetBossNumber(4);
|
||||||
|
LoadObjectData(MiscConst.creatureData, MiscConst.gameObjectData);
|
||||||
|
LoadDoorData(MiscConst.doorData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override uint GetData(uint type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataTypes.DelrissaDeathCount:
|
||||||
|
return _delrissaDeathCount;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetData(uint type, uint data)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataTypes.DelrissaDeathCount:
|
||||||
|
if (data == (uint)EncounterState.Special)
|
||||||
|
_delrissaDeathCount++;
|
||||||
|
else
|
||||||
|
_delrissaDeathCount = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCreatureCreate(Creature creature)
|
||||||
|
{
|
||||||
|
base.OnCreatureCreate(creature);
|
||||||
|
|
||||||
|
switch (creature.GetEntry())
|
||||||
|
{
|
||||||
|
case CreatureIds.CoilskarWitch:
|
||||||
|
case CreatureIds.SunbladeWarlock:
|
||||||
|
case CreatureIds.SunbladeMageGuard:
|
||||||
|
case CreatureIds.SisterOfTorment:
|
||||||
|
case CreatureIds.EthereumSmuggler:
|
||||||
|
case CreatureIds.SunbladeBloodKnight:
|
||||||
|
if (creature.GetDistance(MiscConst.KaelthasTrashGroupDistanceComparisonPos) < 10.0f)
|
||||||
|
_kaelthasPreTrashGUIDs.Add(creature.GetGUID());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUnitDeath(Unit unit)
|
||||||
|
{
|
||||||
|
if (!unit.IsCreature())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (unit.GetEntry())
|
||||||
|
{
|
||||||
|
case CreatureIds.CoilskarWitch:
|
||||||
|
case CreatureIds.SunbladeWarlock:
|
||||||
|
case CreatureIds.SunbladeMageGuard:
|
||||||
|
case CreatureIds.SisterOfTorment:
|
||||||
|
case CreatureIds.EthereumSmuggler:
|
||||||
|
case CreatureIds.SunbladeBloodKnight:
|
||||||
|
if (_kaelthasPreTrashGUIDs.Contains(unit.GetGUID()))
|
||||||
|
{
|
||||||
|
_kaelthasPreTrashGUIDs.Remove(unit.GetGUID());
|
||||||
|
if (_kaelthasPreTrashGUIDs.Count == 0)
|
||||||
|
{
|
||||||
|
Creature kaelthas = GetCreature(DataTypes.KaelthasSunstrider);
|
||||||
|
if (kaelthas)
|
||||||
|
kaelthas.GetAI().SetData(DataTypes.KaelthasIntro, (uint)EncounterState.InProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnGameObjectCreate(GameObject go)
|
||||||
|
{
|
||||||
|
base.OnGameObjectCreate(go);
|
||||||
|
|
||||||
|
switch (go.GetEntry())
|
||||||
|
{
|
||||||
|
case GameObjectIds.EscapeOrb:
|
||||||
|
if (GetBossState(DataTypes.KaelthasSunstrider) == EncounterState.Done)
|
||||||
|
go.RemoveFlag(GameObjectFlags.NotSelectable);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessEvent(WorldObject obj, uint eventId, WorldObject invoker)
|
||||||
|
{
|
||||||
|
if (eventId == MiscConst.EventSpawnKalecgos)
|
||||||
|
if (!GetCreature(DataTypes.Kalecgos) && _events.Empty())
|
||||||
|
_events.ScheduleEvent(MiscConst.EventSpawnKalecgos, TimeSpan.FromMinutes(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(uint diff)
|
||||||
|
{
|
||||||
|
_events.Update(diff);
|
||||||
|
|
||||||
|
if (_events.ExecuteEvent() == MiscConst.EventSpawnKalecgos)
|
||||||
|
{
|
||||||
|
Creature kalecgos = instance.SummonCreature(CreatureIds.Kalecgos, MiscConst.KalecgosSpawnPos);
|
||||||
|
if (kalecgos)
|
||||||
|
{
|
||||||
|
kalecgos.GetMotionMaster().MovePath(MiscConst.PathKalecgosFlight, false);
|
||||||
|
kalecgos.GetAI().Talk(MiscConst.SayKalecgosSpawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool SetBossState(uint type, EncounterState state)
|
||||||
|
{
|
||||||
|
if (!base.SetBossState(type, state))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataTypes.PriestessDelrissa:
|
||||||
|
if (state == EncounterState.InProgress)
|
||||||
|
_delrissaDeathCount = 0;
|
||||||
|
break;
|
||||||
|
case DataTypes.KaelthasSunstrider:
|
||||||
|
if (state == EncounterState.Done)
|
||||||
|
{
|
||||||
|
GameObject orb = GetGameObject(DataTypes.EscapeOrb);
|
||||||
|
if (orb != null)
|
||||||
|
orb.RemoveFlag(GameObjectFlags.NotSelectable);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||||
|
{
|
||||||
|
return new instance_magisters_terrace_InstanceMapScript(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* 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 3 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game.AI;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Maps;
|
||||||
|
using Game.Scripting;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Scripts.EasternKingdoms.MagistersTerrace.SelinFireheart
|
||||||
|
{
|
||||||
|
struct TextIds
|
||||||
|
{
|
||||||
|
public const uint SayAggro = 0;
|
||||||
|
public const uint SayEnergy = 1;
|
||||||
|
public const uint SayEmpowered = 2;
|
||||||
|
public const uint SayKill = 3;
|
||||||
|
public const uint SayDeath = 4;
|
||||||
|
public const uint EmoteCrystal = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpellIds
|
||||||
|
{
|
||||||
|
// Crystal effect spells
|
||||||
|
public const uint FelCrystalDummy = 44329;
|
||||||
|
public const uint ManaRage = 44320; // This spell triggers 44321, which changes scale and regens mana Requires an entry in spell_script_target
|
||||||
|
|
||||||
|
// Selin's spells
|
||||||
|
public const uint DrainLife = 44294;
|
||||||
|
public const uint FelExplosion = 44314;
|
||||||
|
|
||||||
|
public const uint DrainMana = 46153; // Heroic only
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PhaseIds
|
||||||
|
{
|
||||||
|
public const byte Normal = 1;
|
||||||
|
public const byte Drain = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EventIds
|
||||||
|
{
|
||||||
|
public const uint FelExplosion = 1;
|
||||||
|
public const uint DrainCrystal = 2;
|
||||||
|
public const uint DrainMana = 3;
|
||||||
|
public const uint DrainLife = 4;
|
||||||
|
public const uint Empower = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MiscConst
|
||||||
|
{
|
||||||
|
public const int ActionSwitchPhase = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script] // @todo crystals should really be a Db creature summon group, having them in `creature` like this will cause tons of despawn/respawn bugs
|
||||||
|
class boss_selin_fireheart : BossAI
|
||||||
|
{
|
||||||
|
ObjectGuid CrystalGUID;
|
||||||
|
bool _scheduledEvents;
|
||||||
|
|
||||||
|
public boss_selin_fireheart(Creature creature) : base(creature, DataTypes.SelinFireheart) { }
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
List<Creature> crystals = me.GetCreatureListWithEntryInGrid(CreatureIds.FelCrystal, 250.0f);
|
||||||
|
|
||||||
|
foreach (Creature creature in crystals)
|
||||||
|
creature.Respawn(true);
|
||||||
|
|
||||||
|
_Reset();
|
||||||
|
CrystalGUID.Clear();
|
||||||
|
_scheduledEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DoAction(int action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case MiscConst.ActionSwitchPhase:
|
||||||
|
_events.SetPhase(PhaseIds.Normal);
|
||||||
|
_events.ScheduleEvent(EventIds.FelExplosion, TimeSpan.FromSeconds(2), 0, PhaseIds.Normal);
|
||||||
|
AttackStart(me.GetVictim());
|
||||||
|
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectNearestCrystal()
|
||||||
|
{
|
||||||
|
Creature crystal = me.FindNearestCreature(CreatureIds.FelCrystal, 250.0f);
|
||||||
|
if (crystal)
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayEnergy);
|
||||||
|
Talk(TextIds.EmoteCrystal);
|
||||||
|
|
||||||
|
DoCast(crystal, SpellIds.FelCrystalDummy);
|
||||||
|
CrystalGUID = crystal.GetGUID();
|
||||||
|
|
||||||
|
float x, y, z;
|
||||||
|
crystal.GetClosePoint(out x, out y, out z, me.GetCombatReach(), SharedConst.ContactDistance);
|
||||||
|
|
||||||
|
_events.SetPhase(PhaseIds.Drain);
|
||||||
|
me.SetWalk(false);
|
||||||
|
me.GetMotionMaster().MovePoint(1, x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShatterRemainingCrystals()
|
||||||
|
{
|
||||||
|
List<Creature> crystals = me.GetCreatureListWithEntryInGrid(CreatureIds.FelCrystal, 250.0f);
|
||||||
|
|
||||||
|
foreach (Creature crystal in crystals)
|
||||||
|
crystal.KillSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustEngagedWith(Unit who)
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayAggro);
|
||||||
|
base.JustEngagedWith(who);
|
||||||
|
|
||||||
|
_events.SetPhase(PhaseIds.Normal);
|
||||||
|
_events.ScheduleEvent(EventIds.FelExplosion, TimeSpan.FromMilliseconds(2100), 0, PhaseIds.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void KilledUnit(Unit victim)
|
||||||
|
{
|
||||||
|
if (victim.IsPlayer())
|
||||||
|
Talk(TextIds.SayKill);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||||
|
{
|
||||||
|
if (type == MovementGeneratorType.Point && id == 1)
|
||||||
|
{
|
||||||
|
Unit CrystalChosen = Global.ObjAccessor.GetUnit(me, CrystalGUID);
|
||||||
|
if (CrystalChosen != null && CrystalChosen.IsAlive())
|
||||||
|
{
|
||||||
|
CrystalChosen.RemoveUnitFlag(UnitFlags.Uninteractible);
|
||||||
|
CrystalChosen.CastSpell(me, SpellIds.ManaRage, true);
|
||||||
|
_events.ScheduleEvent(EventIds.Empower, TimeSpan.FromSeconds(10), PhaseIds.Drain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustDied(Unit killer)
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayDeath);
|
||||||
|
_JustDied();
|
||||||
|
|
||||||
|
ShatterRemainingCrystals();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAI(uint diff)
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_events.Update(diff);
|
||||||
|
|
||||||
|
if (me.HasUnitState(UnitState.Casting))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_events.ExecuteEvents(eventId =>
|
||||||
|
{
|
||||||
|
switch (eventId)
|
||||||
|
{
|
||||||
|
case EventIds.FelExplosion:
|
||||||
|
DoCastAOE(SpellIds.FelExplosion);
|
||||||
|
_events.ScheduleEvent(EventIds.FelExplosion, TimeSpan.FromSeconds(2), 0, PhaseIds.Normal);
|
||||||
|
break;
|
||||||
|
case EventIds.DrainCrystal:
|
||||||
|
SelectNearestCrystal();
|
||||||
|
_scheduledEvents = false;
|
||||||
|
break;
|
||||||
|
case EventIds.DrainMana:
|
||||||
|
{
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 45.0f, true);
|
||||||
|
if (target != null)
|
||||||
|
DoCast(target, SpellIds.DrainMana);
|
||||||
|
_events.ScheduleEvent(EventIds.DrainMana, TimeSpan.FromSeconds(10), 0, PhaseIds.Normal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EventIds.DrainLife:
|
||||||
|
{
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 20.0f, true);
|
||||||
|
if (target != null)
|
||||||
|
DoCast(target, SpellIds.DrainLife);
|
||||||
|
_events.ScheduleEvent(EventIds.DrainLife, TimeSpan.FromSeconds(10), 0, PhaseIds.Normal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EventIds.Empower:
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayEmpowered);
|
||||||
|
|
||||||
|
Creature CrystalChosen = ObjectAccessor.GetCreature(me, CrystalGUID);
|
||||||
|
if (CrystalChosen && CrystalChosen.IsAlive())
|
||||||
|
CrystalChosen.KillSelf();
|
||||||
|
|
||||||
|
CrystalGUID.Clear();
|
||||||
|
|
||||||
|
me.GetMotionMaster().Clear();
|
||||||
|
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.HasUnitState(UnitState.Casting))
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (me.GetPowerPct(PowerType.Mana) < 10.0f)
|
||||||
|
{
|
||||||
|
if (_events.IsInPhase(PhaseIds.Normal) && !_scheduledEvents)
|
||||||
|
{
|
||||||
|
_scheduledEvents = true;
|
||||||
|
TimeSpan timer = RandomHelper.RandTime(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7));
|
||||||
|
_events.ScheduleEvent(EventIds.DrainLife, timer, 0, PhaseIds.Normal);
|
||||||
|
|
||||||
|
if (IsHeroic())
|
||||||
|
{
|
||||||
|
_events.ScheduleEvent(EventIds.DrainCrystal, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), 0, PhaseIds.Normal);
|
||||||
|
_events.ScheduleEvent(EventIds.DrainMana, timer + TimeSpan.FromSeconds(5), 0, PhaseIds.Normal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_events.ScheduleEvent(EventIds.DrainCrystal, TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25), 0, PhaseIds.Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class npc_fel_crystal : ScriptedAI
|
||||||
|
{
|
||||||
|
public npc_fel_crystal(Creature creature) : base(creature) { }
|
||||||
|
|
||||||
|
public override void JustDied(Unit killer)
|
||||||
|
{
|
||||||
|
InstanceScript instance = me.GetInstanceScript();
|
||||||
|
if (instance != null)
|
||||||
|
{
|
||||||
|
Creature selin = instance.GetCreature(DataTypes.SelinFireheart);
|
||||||
|
if (selin && selin.IsAlive())
|
||||||
|
selin.GetAI().DoAction(MiscConst.ActionSwitchPhase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* 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 3 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Constants;
|
||||||
|
using Game.AI;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Scripting;
|
||||||
|
using Game.Spells;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Scripts.EasternKingdoms.MagistersTerrace.Vexallus
|
||||||
|
{
|
||||||
|
struct TextIds
|
||||||
|
{
|
||||||
|
public const uint SayAggro = 0;
|
||||||
|
public const uint SayEnergy = 1;
|
||||||
|
public const uint SayOverload = 2;
|
||||||
|
public const uint SayKill = 3;
|
||||||
|
public const uint EmoteDischargeEnergy = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpellIds
|
||||||
|
{
|
||||||
|
public const uint ChainLightning = 44318;
|
||||||
|
public const uint Overload = 44353;
|
||||||
|
public const uint ArcaneShock = 44319;
|
||||||
|
|
||||||
|
public const uint SummonPureEnergy = 44322; // mod scale -10
|
||||||
|
public const uint HSummonPureEnergy1 = 46154; // mod scale -5
|
||||||
|
public const uint HSummonPureEnergy2 = 46159; // mod scale -5
|
||||||
|
|
||||||
|
// NpcPureEnergy
|
||||||
|
public const uint EnergyBolt = 46156;
|
||||||
|
public const uint EnergyFeedback = 44335;
|
||||||
|
public const uint PureEnergyPassive = 44326;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MiscConst
|
||||||
|
{
|
||||||
|
public const uint IntervalModifier = 15;
|
||||||
|
public const uint IntervalSwitch = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class boss_vexallus : BossAI
|
||||||
|
{
|
||||||
|
uint _intervalHealthAmount;
|
||||||
|
bool _enraged;
|
||||||
|
|
||||||
|
public boss_vexallus(Creature creature) : base(creature, DataTypes.Vexallus)
|
||||||
|
{
|
||||||
|
_intervalHealthAmount = 1;
|
||||||
|
_enraged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
_Reset();
|
||||||
|
_intervalHealthAmount = 1;
|
||||||
|
_enraged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void KilledUnit(Unit victim)
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayKill);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustEngagedWith(Unit who)
|
||||||
|
{
|
||||||
|
Talk(TextIds.SayAggro);
|
||||||
|
base.JustEngagedWith(who);
|
||||||
|
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||||
|
{
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true);
|
||||||
|
if (target)
|
||||||
|
DoCast(target, SpellIds.ChainLightning);
|
||||||
|
task.Repeat();
|
||||||
|
});
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||||
|
{
|
||||||
|
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 20.0f, true);
|
||||||
|
if (target)
|
||||||
|
DoCast(target, SpellIds.ArcaneShock);
|
||||||
|
task.Repeat(TimeSpan.FromSeconds(8));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustSummoned(Creature summoned)
|
||||||
|
{
|
||||||
|
Unit temp = SelectTarget(SelectTargetMethod.Random, 0);
|
||||||
|
if (temp)
|
||||||
|
summoned.GetMotionMaster().MoveFollow(temp, 0, 0);
|
||||||
|
|
||||||
|
summons.Summon(summoned);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DamageTaken(Unit who, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||||
|
{
|
||||||
|
if (_enraged)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 85%, 70%, 55%, 40%, 25%
|
||||||
|
if (!HealthAbovePct((int)(100 - MiscConst.IntervalModifier * _intervalHealthAmount)))
|
||||||
|
{
|
||||||
|
// increase amount, unless we're at 10%, then we switch and return
|
||||||
|
if (_intervalHealthAmount == MiscConst.IntervalSwitch)
|
||||||
|
{
|
||||||
|
_enraged = true;
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
_scheduler.Schedule(TimeSpan.FromSeconds(1.2), task =>
|
||||||
|
{
|
||||||
|
DoCastVictim(SpellIds.Overload);
|
||||||
|
task.Repeat(TimeSpan.FromSeconds(2));
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++_intervalHealthAmount;
|
||||||
|
|
||||||
|
Talk(TextIds.SayEnergy);
|
||||||
|
Talk(TextIds.EmoteDischargeEnergy);
|
||||||
|
|
||||||
|
if (IsHeroic())
|
||||||
|
{
|
||||||
|
DoCast(me, SpellIds.HSummonPureEnergy1);
|
||||||
|
DoCast(me, SpellIds.HSummonPureEnergy2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoCast(me, SpellIds.SummonPureEnergy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateAI(uint diff)
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script]
|
||||||
|
class npc_pure_energy : ScriptedAI
|
||||||
|
{
|
||||||
|
public npc_pure_energy(Creature creature) : base(creature)
|
||||||
|
{
|
||||||
|
me.SetDisplayFromModel(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JustDied(Unit killer)
|
||||||
|
{
|
||||||
|
if (killer)
|
||||||
|
killer.CastSpell(killer, SpellIds.EnergyFeedback, true);
|
||||||
|
me.RemoveAurasDueToSpell(SpellIds.PureEnergyPassive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user