Ported .Net Core commits:

hondacrx:
- Initial commit: Switch to .Net Core 2.0
- Fix build and removed not needed files
Fabi:
- Updated solution platforms.
- Changed folder structure.
- Change library target framework to netstandard2.0.
- Updated solution platforms again...
- Removed windows specific kernel32 function usage (Ctrl-C handler).
This commit is contained in:
Fabian
2017-10-26 17:23:44 +02:00
parent 227702e19c
commit a3dc7b3f48
844 changed files with 26064 additions and 1824 deletions
@@ -0,0 +1,334 @@
/*
* Copyright (C) 2012-2017 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;
using System.Collections.Generic;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.Bronjahm
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SaySoulStorm = 3;
public const uint SayCorruptSoul = 4;
}
struct SpellIds
{
public const uint MagicSBane = 68793;
public const uint ShadowBolt = 70043;
public const uint CorruptSoul = 68839;
public const uint ConsumeSoul = 68861;
public const uint Teleport = 68988;
public const uint Fear = 68950;
public const uint Soulstorm = 68872;
public const uint SoulstormChannel = 69008; // Pre-Fight
public const uint SoulstormVisual = 68870; // Pre-Cast Soulstorm
public const uint PurpleBanishVisual = 68862; // Used By Soul Fragment (Aura)
}
struct EventIds
{
public const uint MagicBane = 1;
public const uint ShadowBolt = 2;
public const uint CorruptSoul = 3;
public const uint Soulstorm = 4;
public const uint Fear = 5;
}
struct Misc
{
public const uint DataSoulPower = 1;
public const byte Phase1 = 1;
public const byte Phase2 = 2;
public static uint[] SoulstormVisualSpells =
{
68904,
68886,
68905,
68896,
68906,
68897,
68907,
68898
};
}
[Script]
class boss_bronjahm : BossAI
{
public boss_bronjahm(Creature creature) : base(creature, DataType.Bronjahm)
{
DoCast(me, SpellIds.SoulstormChannel, true);
}
public override void Reset()
{
_Reset();
_events.SetPhase(Misc.Phase1);
_events.ScheduleEvent(EventIds.ShadowBolt, 2000);
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
}
public override void JustReachedHome()
{
_JustReachedHome();
DoCast(me, SpellIds.SoulstormChannel, true);
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
me.RemoveAurasDueToSpell(SpellIds.SoulstormChannel);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void KilledUnit(Unit who)
{
if (who.GetTypeId() == TypeId.Player)
Talk(TextIds.SaySlay);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (_events.IsInPhase(Misc.Phase1) && !HealthAbovePct(30))
{
_events.SetPhase(Misc.Phase2);
DoCast(me, SpellIds.Teleport);
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16), 0, Misc.Phase2);
_events.ScheduleEvent(EventIds.Soulstorm, 100, 0, Misc.Phase2);
}
}
public override void JustSummoned(Creature summon)
{
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment)
{
summons.Summon(summon);
summon.SetReactState(ReactStates.Passive);
summon.GetMotionMaster().MoveFollow(me, me.GetObjectSize(), 0.0f);
summon.CastSpell(summon, SpellIds.PurpleBanishVisual, true);
}
}
public override uint GetData(uint type)
{
if (type == Misc.DataSoulPower)
{
uint count = 0;
foreach (ObjectGuid guid in summons)
{
Creature summon = ObjectAccessor.GetCreature(me, guid);
if (summon)
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment && summon.IsAlive())
++count;
}
return count;
}
return 0;
}
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.MagicBane:
DoCastAOE(SpellIds.MagicSBane);
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
break;
case EventIds.ShadowBolt:
if (_events.IsInPhase(Misc.Phase2))
{
DoCastVictim(SpellIds.ShadowBolt);
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(2));
}
else
{
if (!me.IsWithinMeleeRange(me.GetVictim()))
DoCastVictim(SpellIds.ShadowBolt);
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(2));
}
break;
case EventIds.CorruptSoul:
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true);
if (target)
{
Talk(TextIds.SayCorruptSoul);
DoCast(target, SpellIds.CorruptSoul);
}
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
break;
case EventIds.Soulstorm:
Talk(TextIds.SaySoulStorm);
me.CastSpell(me, SpellIds.SoulstormVisual, true);
me.CastSpell(me, SpellIds.Soulstorm, false);
break;
case EventIds.Fear:
me.CastCustomSpell(SpellIds.Fear, SpellValueMod.MaxTargets, 1, null, false);
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), 0, Misc.Phase2);
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
if (!_events.IsInPhase(Misc.Phase2))
DoMeleeAttackIfReady();
}
}
[Script]
class npc_corrupted_soul_fragment : ScriptedAI
{
public npc_corrupted_soul_fragment(Creature creature) : base(creature)
{
instance = me.GetInstanceScript();
}
public override void IsSummonedBy(Unit summoner)
{
Creature bronjahm = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataType.Bronjahm));
if (bronjahm)
bronjahm.GetAI().JustSummoned(me);
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Follow)
return;
if (instance.GetGuidData(DataType.Bronjahm).GetCounter() != id)
return;
me.CastSpell((Unit)null, SpellIds.ConsumeSoul, true);
me.DespawnOrUnsummon();
}
InstanceScript instance;
}
[Script]
class spell_bronjahm_magic_bane : SpellScript
{
void RecalculateDamage()
{
if (GetHitUnit().getPowerType() != PowerType.Mana)
return;
int maxDamage = GetCaster().GetMap().IsHeroic() ? 15000 : 10000;
int newDamage = GetHitDamage() + (GetHitUnit().GetMaxPower(PowerType.Mana) / 2);
SetHitDamage(Math.Min(maxDamage, newDamage));
}
public override void Register()
{
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
[Script]
class spell_bronjahm_consume_soul : SpellScript
{
void HandleScript(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_bronjahm_soulstorm_visual : AuraScript
{
void HandlePeriodicTick(AuraEffect aurEff)
{
PreventDefaultAction();
GetTarget().CastSpell(GetTarget(), Misc.SoulstormVisualSpells[aurEff.GetTickNumber() % 8], true);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicDummy));
}
}
[Script]
class spell_bronjahm_soulstorm_targeting : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
Unit caster = GetCaster();
targets.RemoveAll(target =>
{
return caster.GetExactDist2d(target) <= 10.0f;
});
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, SpellConst.EffectAll, Targets.UnitDestAreaEnemy));
}
}
[Script]
class achievement_bronjahm_soul_power : AchievementCriteriaScript
{
public achievement_bronjahm_soul_power() : base("achievement_bronjahm_soul_power") { }
public override bool OnCheck(Player source, Unit target)
{
return target && target.GetAI().GetData(Misc.DataSoulPower) >= 4;
}
}
}
@@ -0,0 +1,414 @@
using System;
using System.Collections.Generic;
using Game.Entities;
using Framework.Constants;
using Game.Scripting;
using Game.AI;
using Game.Spells;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.DevourerOfSouls
{
struct TextIds
{
public const uint SayFaceAggro = 0;
public const byte SayFaceAngerSlay = 1;
public const byte SayFaceSorrowSlay = 2;
public const byte SayFaceDesireSlay = 3;
public const uint SayFaceDeath = 4;
public const uint EmoteMirroredSoul = 5;
public const uint EmoteUnleashSoul = 6;
public const uint SayFaceUnleashSoul = 7;
public const uint EmoteWailingSoul = 8;
public const uint SayFaceWailingSoul = 9;
public const uint SayJainaOutro = 0;
public const uint SaySylvanasOutro = 0;
}
struct SpellIds
{
public const uint PhantomBlast = 68982;
public const uint MirroredSoulProcAura = 69023;
public const uint MirroredSoulDamage = 69034;
public const uint MirroredSoulTargetSelector = 69048;
public const uint MirroredSoulBuff = 69051;
public const uint WellOfSouls = 68820;
public const uint UnleashedSouls = 68939;
public const uint WailingSoulsStarting = 68912; // Initial Spell Cast At Begining Of Wailing Souls Phase
public const uint WailingSoulsBeam = 68875; // The Beam Visual
public const uint WailingSouls = 68873; // The Actual Spell
// 68871; 68873; 68875; 68876; 68899; 68912; 70324;
// 68899 Trigger 68871
}
struct ModelIds
{
public const uint Anger = 30148;
public const uint Sorrow = 30149;
public const uint Desire = 30150;
}
struct Misc
{
public const uint DataThreeFaced = 1;
public static outroPosition[] outroPositions =
{
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5590.47f, 2427.79f, 705.935f, 0.802851f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5593.59f, 2428.34f, 705.935f, 0.977384f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2429.31f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2421.12f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.43f, 2426.53f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.55f, 2418.36f, 705.935f, 1.15192f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5598, 2429.14f, 705.935f, 1.0472f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5594.04f, 2424.87f, 705.935f, 1.15192f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5597.89f, 2421.54f, 705.935f, 0.610865f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5598.57f, 2434.62f, 705.935f, 1.13446f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5585.46f, 2417.99f, 705.935f, 1.06465f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5605.81f, 2428.42f, 705.935f, 0.820305f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5591.61f, 2412.66f, 705.935f, 0.925025f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5593.9f, 2410.64f, 705.935f, 0.872665f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5586.76f, 2416.73f, 705.935f, 0.942478f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5592.23f, 2419.14f, 705.935f, 0.855211f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5594.61f, 2416.87f, 705.935f, 0.907571f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5589.77f, 2421.03f, 705.935f, 0.855211f)),
new outroPosition(CreatureIds.Koreln, CreatureIds.Loralen, new Position(5602.58f, 2435.95f, 705.935f, 0.959931f)),
new outroPosition(CreatureIds.Elandra, CreatureIds.Kalira, new Position(5606.13f, 2433.16f, 705.935f, 0.785398f)),
new outroPosition(CreatureIds.JainaPart2, CreatureIds.SylvanasPart2, new Position(5606.12f, 2436.6f, 705.935f, 0.890118f)),
};
public static Position CrucibleSummonPos = new Position(5672.294f, 2520.686f, 713.4386f, 0.9599311f);
}
struct outroPosition
{
public outroPosition(uint allianceEntry, uint hordeEntry, Position movePosition)
{
Entry = new uint[2];
Entry[0] = allianceEntry;
Entry[1] = hordeEntry;
MovePosition = movePosition;
}
public uint[] Entry;
public Position MovePosition;
}
[Script]
class boss_devourer_of_souls : BossAI
{
public boss_devourer_of_souls(Creature creature) : base(creature, DataType.DevourerOfSouls)
{
Initialize();
beamAngle = 0.0f;
beamAngleDiff = 0.0f;
wailingSoulTick = 0;
}
void Initialize()
{
threeFaced = true;
}
public override void Reset()
{
_Reset();
me.SetControlled(false, UnitState.Root);
me.SetDisplayId(ModelIds.Anger);
me.SetReactState(ReactStates.Aggressive);
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayFaceAggro);
if (!me.FindNearestCreature(CreatureIds.CrucibleOfSouls, 60)) // Prevent double spawn
me.GetMap().SummonCreature(CreatureIds.CrucibleOfSouls, Misc.CrucibleSummonPos);
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.PhantomBlast);
task.Repeat(TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
DoCastAOE(SpellIds.MirroredSoulTargetSelector);
Talk(TextIds.EmoteMirroredSoul);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.WellOfSouls);
task.Repeat(TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.UnleashedSouls);
me.SetDisplayId(ModelIds.Sorrow);
Talk(TextIds.SayFaceUnleashSoul);
Talk(TextIds.EmoteUnleashSoul);
task.Repeat(TimeSpan.FromSeconds(30));
task.Schedule(TimeSpan.FromSeconds(5), () => me.SetDisplayId(ModelIds.Anger));
});
_scheduler.Schedule(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), task =>
{
me.SetDisplayId(ModelIds.Desire);
Talk(TextIds.SayFaceWailingSoul);
Talk(TextIds.EmoteWailingSoul);
DoCast(me, SpellIds.WailingSoulsStarting);
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
{
me.SetFacingToObject(target);
DoCast(me, SpellIds.WailingSoulsBeam);
}
beamAngle = me.GetOrientation();
beamAngleDiff = (float)Math.PI / 30.0f; // PI/2 in 15 sec = PI/30 per tick
if (RandomHelper.RAND(true, false))
beamAngleDiff = -beamAngleDiff;
me.InterruptNonMeleeSpells(false);
me.SetReactState(ReactStates.Passive);
//Remove any target
me.SetTarget(ObjectGuid.Empty);
me.GetMotionMaster().Clear();
me.SetControlled(true, UnitState.Root);
wailingSoulTick = 15;
_scheduler.DelayAll(TimeSpan.FromSeconds(18)); // no other events during wailing souls
// first one after 3 secs.
_scheduler.Schedule(TimeSpan.FromSeconds(3), tickTask =>
{
beamAngle += beamAngleDiff;
me.SetFacingTo(beamAngle, true);
me.StopMoving();
DoCast(me, SpellIds.WailingSouls);
if (--wailingSoulTick != 0)
tickTask.Repeat(TimeSpan.FromSeconds(1));
else
{
me.SetReactState(ReactStates.Aggressive);
me.SetDisplayId(ModelIds.Anger);
me.SetControlled(false, UnitState.Root);
me.GetMotionMaster().MoveChase(me.GetVictim());
task.Repeat(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70));
}
});
});
}
public override void KilledUnit(Unit victim)
{
if (victim.GetTypeId() != TypeId.Player)
return;
byte textId = 0;
switch (me.GetDisplayId())
{
case ModelIds.Anger:
textId = TextIds.SayFaceAngerSlay;
break;
case ModelIds.Sorrow:
textId = TextIds.SayFaceSorrowSlay;
break;
case ModelIds.Desire:
textId = TextIds.SayFaceDesireSlay;
break;
default:
break;
}
if (textId != 0)
Talk(textId);
}
public override void JustDied(Unit killer)
{
_JustDied();
Position spawnPoint = new Position(5618.139f, 2451.873f, 705.854f, 0);
Talk(TextIds.SayFaceDeath);
int entryIndex;
if (instance.GetData(DataType.TeamInInstance) == (uint)Team.Alliance)
entryIndex = 0;
else
entryIndex = 1;
for (var i = 0; Misc.outroPositions[i].Entry[entryIndex] != 0; ++i)
{
Creature summon = me.SummonCreature(Misc.outroPositions[i].Entry[entryIndex], spawnPoint, TempSummonType.DeadDespawn);
if (summon)
{
summon.GetMotionMaster().MovePoint(0, Misc.outroPositions[i].MovePosition);
if (summon.GetEntry() == CreatureIds.JainaPart2)
summon.GetAI().Talk(TextIds.SayJainaOutro);
else if (summon.GetEntry() == CreatureIds.SylvanasPart2)
summon.GetAI().Talk(TextIds.SaySylvanasOutro);
}
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.PhantomBlast)
threeFaced = false;
}
public override uint GetData(uint type)
{
if (type == Misc.DataThreeFaced)
return threeFaced ? 1 : 0u;
return 0;
}
public override void UpdateAI(uint diff)
{
// Return since we have no target
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
bool threeFaced;
// wailing soul event
float beamAngle;
float beamAngleDiff;
sbyte wailingSoulTick;
}
[Script] // 69051 - Mirrored Soul
class spell_devourer_of_souls_mirrored_soul : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulProcAura);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.CastSpell(GetCaster(), SpellIds.MirroredSoulProcAura, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script] // 69023 - Mirrored Soul (Proc)
class spell_devourer_of_souls_mirrored_soul_proc : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulDamage);
}
bool CheckProc(ProcEventInfo eventInfo)
{
return GetCaster() && GetCaster().IsAlive();
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
DamageInfo damageInfo = eventInfo.GetDamageInfo();
if (damageInfo == null || damageInfo.GetDamage() == 0)
return;
int damage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), 45);
GetTarget().CastCustomSpell(SpellIds.MirroredSoulDamage, SpellValueMod.BasePoint0, damage, GetCaster(), true);
}
public override void Register()
{
DoCheckProc.Add(new CheckProcHandler(CheckProc));
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
}
}
[Script] // 69048 - Mirrored Soul (Target Selector)
class spell_devourer_of_souls_mirrored_soul_target_selector : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulBuff);
}
void FilterTargets(List<WorldObject> targets)
{
if (targets.Empty())
return;
WorldObject target = targets.SelectRandom();
targets.Clear();
targets.Add(target);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
GetCaster().CastSpell(target, SpellIds.MirroredSoulBuff, false);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEntry));
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class achievement_three_faced : AchievementCriteriaScript
{
public achievement_three_faced() : base("achievement_three_faced") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature devourer = target.ToCreature();
if (devourer)
if (devourer.GetAI().GetData(Misc.DataThreeFaced) != 0)
return true;
return false;
}
}
}
@@ -0,0 +1,380 @@
/*
* Copyright (C) 2012-2017 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.Collections.Generic;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls
{
struct DataType
{
// Encounter states and GUIDs
public const uint Bronjahm = 0;
public const uint DevourerOfSouls = 1;
// Additional Data
public const uint TeamInInstance = 2;
}
struct CreatureIds
{
public const uint Bronjahm = 36497;
public const uint Devourer = 36502;
public const uint CorruptedSoulFragment = 36535;
public const uint SylvanasPart1 = 37596;
public const uint SylvanasPart2 = 38161;
public const uint JainaPart1 = 37597;
public const uint JainaPart2 = 38160;
public const uint Kalira = 37583;
public const uint Elandra = 37774;
public const uint Loralen = 37779;
public const uint Koreln = 37582;
public const uint Champion1Horde = 37584;
public const uint Champion2Horde = 37587;
public const uint Champion3Horde = 37588;
public const uint Champion1Alliance = 37496;
public const uint Champion2Alliance = 37497;
public const uint CrucibleOfSouls = 37094;
}
struct EventIds
{
public const uint None = 0;
// Jaina/Sylvanas Intro
public const uint Intro1 = 1;
public const uint Intro2 = 2;
public const uint Intro3 = 3;
public const uint Intro4 = 4;
public const uint Intro5 = 5;
public const uint Intro6 = 6;
public const uint Intro7 = 7;
public const uint Intro8 = 8;
}
struct TextIds
{
public const uint SayJainaIntro1 = 0;
public const uint SayJainaIntro2 = 1;
public const uint SayJainaIntro3 = 2;
public const uint SayJainaIntro4 = 3;
public const uint SayJainaIntro5 = 4;
public const uint SayJainaIntro6 = 5;
public const uint SayJainaIntro7 = 6;
public const uint SayJainaIntro8 = 7;
public const uint SaySylvanasIntro1 = 0;
public const uint SaySylvanasIntro2 = 1;
public const uint SaySylvanasIntro3 = 2;
public const uint SaySylvanasIntro4 = 3;
public const uint SaySylvanasIntro5 = 4;
public const uint SaySylvanasIntro6 = 5;
}
struct Misc
{
public const uint MenuIdJaina = 10943;
public const uint MenuIdSylvanas = 10971;
public const uint GossipOptionId = 0;
}
enum Phase
{
Normal,
Intro,
}
[Script]
class instance_forge_of_souls : InstanceMapScript
{
public instance_forge_of_souls() : base(nameof(instance_forge_of_souls), 632) { }
class instance_forge_of_souls_InstanceScript : InstanceScript
{
public instance_forge_of_souls_InstanceScript(Map map) : base(map)
{
SetHeaders("FOS");
SetBossNumber(2);
teamInInstance = 0;
}
public override void OnPlayerEnter(Player player)
{
if (teamInInstance == 0)
teamInInstance = player.GetTeam();
}
public override void OnCreatureCreate(Creature creature)
{
if (teamInInstance == 0)
{
var players = instance.GetPlayers();
if (!players.Empty())
{
Player player = players[0];
if (player)
teamInInstance = player.GetTeam();
}
}
switch (creature.GetEntry())
{
case CreatureIds.Bronjahm:
bronjahm = creature.GetGUID();
break;
case CreatureIds.Devourer:
devourerOfSouls = creature.GetGUID();
break;
case CreatureIds.SylvanasPart1:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart1);
break;
case CreatureIds.Loralen:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Elandra);
break;
case CreatureIds.Kalira:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Koreln);
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case DataType.TeamInInstance:
return (uint)teamInInstance;
default:
break;
}
return 0;
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataType.Bronjahm:
return bronjahm;
case DataType.DevourerOfSouls:
return devourerOfSouls;
default:
break;
}
return ObjectGuid.Empty;
}
ObjectGuid bronjahm;
ObjectGuid devourerOfSouls;
Team teamInInstance;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_forge_of_souls_InstanceScript(map);
}
}
[Script]
class npc_sylvanas_fos : ScriptedAI
{
public npc_sylvanas_fos(Creature creature) : base(creature)
{
Initialize();
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
}
void Initialize()
{
phase = Phase.Normal;
}
public override void Reset()
{
_events.Reset();
Initialize();
}
public override void sGossipSelect(Player player, uint menuId, uint gossipListId)
{
if (menuId == Misc.MenuIdSylvanas && gossipListId == Misc.GossipOptionId)
{
player.CLOSE_GOSSIP_MENU();
phase = Phase.Intro;
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
_events.Reset();
_events.ScheduleEvent(EventIds.Intro1, 1000);
}
}
public override void UpdateAI(uint diff)
{
if (phase == Phase.Intro)
{
_events.Update(diff);
switch (_events.ExecuteEvent())
{
case EventIds.Intro1:
Talk(TextIds.SaySylvanasIntro1);
_events.ScheduleEvent(EventIds.Intro2, 11500);
break;
case EventIds.Intro2:
Talk(TextIds.SaySylvanasIntro2);
_events.ScheduleEvent(EventIds.Intro3, 10500);
break;
case EventIds.Intro3:
Talk(TextIds.SaySylvanasIntro3);
_events.ScheduleEvent(EventIds.Intro4, 9500);
break;
case EventIds.Intro4:
Talk(TextIds.SaySylvanasIntro4);
_events.ScheduleEvent(EventIds.Intro5, 10500);
break;
case EventIds.Intro5:
Talk(TextIds.SaySylvanasIntro5);
_events.ScheduleEvent(EventIds.Intro6, 9500);
break;
case EventIds.Intro6:
Talk(TextIds.SaySylvanasIntro6);
// End of Intro
phase = Phase.Normal;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
_events.Update(diff);
DoMeleeAttackIfReady();
}
Phase phase;
}
[Script]
class npc_jaina_fos : ScriptedAI
{
public npc_jaina_fos(Creature creature) : base(creature)
{
Initialize();
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
}
void Initialize()
{
phase = Phase.Normal;
}
public override void Reset()
{
_events.Reset();
Initialize();
}
public override void sGossipSelect(Player player, uint menuId, uint gossipListId)
{
if (menuId == Misc.MenuIdJaina && gossipListId == Misc.GossipOptionId)
{
player.CLOSE_GOSSIP_MENU();
phase = Phase.Intro;
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
_events.Reset();
_events.ScheduleEvent(EventIds.Intro1, 1000);
}
}
public override void UpdateAI(uint diff)
{
if (phase == Phase.Intro)
{
_events.Update(diff);
switch (_events.ExecuteEvent())
{
case EventIds.Intro1:
Talk(TextIds.SayJainaIntro1);
_events.ScheduleEvent(EventIds.Intro2, 8000);
break;
case EventIds.Intro2:
Talk(TextIds.SayJainaIntro2);
_events.ScheduleEvent(EventIds.Intro3, 8500);
break;
case EventIds.Intro3:
Talk(TextIds.SayJainaIntro3);
_events.ScheduleEvent(EventIds.Intro4, 8000);
break;
case EventIds.Intro4:
Talk(TextIds.SayJainaIntro4);
_events.ScheduleEvent(EventIds.Intro5, 10000);
break;
case EventIds.Intro5:
Talk(TextIds.SayJainaIntro5);
_events.ScheduleEvent(EventIds.Intro6, 8000);
break;
case EventIds.Intro6:
Talk(TextIds.SayJainaIntro6);
_events.ScheduleEvent(EventIds.Intro7, 12000);
break;
case EventIds.Intro7:
Talk(TextIds.SayJainaIntro7);
_events.ScheduleEvent(EventIds.Intro8, 8000);
break;
case EventIds.Intro8:
Talk(TextIds.SayJainaIntro8);
// End of Intro
phase = Phase.Normal;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
_events.Update(diff);
DoMeleeAttackIfReady();
}
Phase phase;
}
}
@@ -0,0 +1,305 @@
using System;
using System.Collections.Generic;
using Game.AI;
using Game.Entities;
using Framework.Constants;
using Game.Spells;
using Game.Scripting;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossForgemasterGarfrost
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayPhase2 = 1;
public const uint SayPhase3 = 2;
public const uint SayDeath = 3;
public const uint SaySlay = 4;
public const uint SayThrowSaronite = 5;
public const uint SayCastDeepFreeze = 6;
public const uint SayTyrannusDeath = 0;
}
struct SpellIds
{
public const uint Permafrost = 70326;
public const uint ThrowSaronite = 68788;
public const uint ThunderingStomp = 68771;
public const uint ChillingWave = 68778;
public const uint DeepFreeze = 70381;
public const uint ForgeMace = 68785;
public const uint ForgeBlade = 68774;
public const uint PermafrostAura = 68786;
}
struct Misc
{
public const byte PhaseOne = 1;
public const byte PhaseTwo = 2;
public const byte PhaseThree = 3;
public const int EquipIdSword = 49345;
public const int EquipIdMace = 49344;
public const uint AchievDoesntGoToEleven = 0;
public const uint PointForge = 0;
public static Position northForgePos = new Position(722.5643f, -234.1615f, 527.182f, 2.16421f);
public static Position southForgePos = new Position(639.257f, -210.1198f, 529.015f, 0.523599f);
}
struct Events
{
public const uint ThrowSaronite = 1;
public const uint ChillingWave = 2;
public const uint DeepFreeze = 3;
public const uint ForgeJump = 4;
public const uint ResumeAttack = 5;
}
[Script]
class boss_garfrost : BossAI
{
public boss_garfrost(Creature creature) : base(creature, DataTypes.Garfrost) { }
public override void Reset()
{
_Reset();
_events.SetPhase(Misc.PhaseOne);
SetEquipmentSlots(true);
_permafrostStack = 0;
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
DoCast(me, SpellIds.Permafrost);
me.CallForHelp(70.0f);
_events.ScheduleEvent(Events.ThrowSaronite, 7000);
}
public override void KilledUnit(Unit victim)
{
if (victim.IsPlayer())
Talk(TextIds.SaySlay);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
me.RemoveAllGameObjects();
Creature tyrannus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Tyrannus));
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusDeath);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (_events.IsInPhase(Misc.PhaseOne) && !HealthAbovePct(66))
{
_events.SetPhase(Misc.PhaseTwo);
Talk(TextIds.SayPhase2);
_events.DelayEvents(8000);
DoCast(me, SpellIds.ThunderingStomp);
_events.ScheduleEvent(Events.ForgeJump, 1500);
return;
}
if (_events.IsInPhase(Misc.PhaseTwo) && !HealthAbovePct(33))
{
_events.SetPhase(Misc.PhaseThree);
Talk(TextIds.SayPhase3);
_events.DelayEvents(8000);
DoCast(me, SpellIds.ThunderingStomp);
_events.ScheduleEvent(Events.ForgeJump, 1500);
return;
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Effect || id != Misc.PointForge)
return;
if (_events.IsInPhase(Misc.PhaseTwo))
{
DoCast(me, SpellIds.ForgeBlade);
SetEquipmentSlots(false, Misc.EquipIdSword);
}
if (_events.IsInPhase(Misc.PhaseThree))
{
me.RemoveAurasDueToSpell(SpellIds.ForgeBlade);
DoCast(me, SpellIds.ForgeMace);
SetEquipmentSlots(false, Misc.EquipIdMace);
}
_events.ScheduleEvent(Events.ResumeAttack, 5000);
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.PermafrostAura)
{
Aura aura = target.GetAura(SpellIds.PermafrostAura);
if (aura != null)
_permafrostStack = Math.Max(_permafrostStack, aura.GetStackAmount());
}
}
public override uint GetData(uint type)
{
return _permafrostStack;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.ThrowSaronite:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
Talk(TextIds.SayThrowSaronite, target);
DoCast(target, SpellIds.ThrowSaronite);
}
_events.ScheduleEvent(Events.ThrowSaronite, TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20));
}
break;
case Events.ChillingWave:
DoCast(me, SpellIds.ChillingWave);
_events.ScheduleEvent(Events.ChillingWave, 40000, 0, Misc.PhaseTwo);
break;
case Events.DeepFreeze:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
Talk(TextIds.SayCastDeepFreeze, target);
DoCast(target, SpellIds.DeepFreeze);
}
_events.ScheduleEvent(Events.DeepFreeze, 35000, 0, Misc.PhaseThree);
}
break;
case Events.ForgeJump:
me.AttackStop();
if (_events.IsInPhase(Misc.PhaseTwo))
me.GetMotionMaster().MoveJump(Misc.northForgePos, 25.0f, 15.0f, Misc.PointForge);
else if (_events.IsInPhase(Misc.PhaseThree))
me.GetMotionMaster().MoveJump(Misc.southForgePos, 25.0f, 15.0f, Misc.PointForge);
break;
case Events.ResumeAttack:
if (_events.IsInPhase(Misc.PhaseTwo))
_events.ScheduleEvent(Events.ChillingWave, 5000, 0, Misc.PhaseTwo);
else if (_events.IsInPhase(Misc.PhaseThree))
_events.ScheduleEvent(Events.DeepFreeze, 10000, 0, Misc.PhaseThree);
AttackStart(me.GetVictim());
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
uint _permafrostStack;
}
[Script]
class spell_garfrost_permafrost : SpellScript
{
public spell_garfrost_permafrost()
{
prevented = false;
}
void PreventHitByLoS(SpellMissInfo missInfo)
{
if (missInfo != SpellMissInfo.None)
return;
Unit target = GetHitUnit();
if (target)
{
Unit caster = GetCaster();
//Temporary Line of Sight Check
List<GameObject> blockList = new List<GameObject>();
caster.GetGameObjectListWithEntryInGrid(blockList, GameObjectIds.SaroniteRock, 100.0f);
if (!blockList.Empty())
{
foreach (var obj in blockList)
{
if (!obj.IsInvisibleDueToDespawn())
{
if (obj.IsInBetween(caster, target, 4.0f))
{
prevented = true;
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, true);
PreventHitDefaultEffect(0);
PreventHitDefaultEffect(1);
PreventHitDefaultEffect(2);
PreventHitDamage();
break;
}
}
}
}
}
}
void RestoreImmunity()
{
Unit target = GetHitUnit();
if (target)
{
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, false);
if (prevented)
PreventHitAura();
}
}
public override void Register()
{
BeforeHit.Add(new BeforeHitHandler(PreventHitByLoS));
AfterHit.Add(new HitHandler(RestoreImmunity));
}
bool prevented;
}
[Script]
class achievement_doesnt_go_to_eleven : AchievementCriteriaScript
{
public achievement_doesnt_go_to_eleven() : base("achievement_doesnt_go_to_eleven") { }
public override bool OnCheck(Player source, Unit target)
{
if (target)
{
Creature garfrost = target.ToCreature();
if (garfrost)
if (garfrost.GetAI().GetData(Misc.AchievDoesntGoToEleven) <= 10)
return true;
}
return false;
}
}
}
@@ -0,0 +1,674 @@
using System;
using Game.Entities;
using Game.Scripting;
using Game.AI;
using Framework.Constants;
using Game.Maps;
using Game.Spells;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossKrickAndIck
{
struct SpellIds
{
public const uint MightyKick = 69021; //Ick'S Spell
public const uint ShadowBolt = 69028; //Krick'S Spell
public const uint ToxicWaste = 69024; //Krick'S Spell
public const uint ExplosiveBarrageKrick = 69012; //Special Spell 1
public const uint ExplosiveBarrageIck = 69263; //Special Spell 1
public const uint PoisonNova = 68989; //Special Spell 2
public const uint Pursuit = 68987; //Special Spell 3
public const uint ExplosiveBarrageSummon = 69015;
public const uint ExplodingOrb = 69017; //Visual On Exploding Orb
public const uint AutoGrow = 69020; //Grow Effect On Exploding Orb
public const uint HastyGrow = 44851; //Need To Check Growing Stacks
public const uint ExplosiveBarrageDamage = 69019; //Damage Done By Orb While Exploding
public const uint Strangulating = 69413; //Krick'S Selfcast In Intro
public const uint Suicide = 7;
public const uint KrickKillCredit = 71308;
public const uint NecromanticPower = 69753;
}
struct TextIds
{
// Krick
public const uint SayKrickAggro = 0;
public const uint SayKrickSlay = 1;
public const uint SayKrickBarrage1 = 2;
public const uint SayKrickBarrage2 = 3;
public const uint SayKrickPoisonNova = 4;
public const uint SayKrickChase = 5;
public const uint SayKrickOutro1 = 6;
public const uint SayKrickOutro3 = 7;
public const uint SayKrickOutro5 = 8;
public const uint SayKrickOutro8 = 9;
// Ick
public const uint SayIckPoisonNova = 0;
public const uint SayIckChase1 = 1;
// Outro
public const uint SayJaynaOutro2 = 0;
public const uint SayJaynaOutro4 = 1;
public const uint SayJaynaOutro10 = 2;
public const uint SaySylvanasOutro2 = 0;
public const uint SaySylvanasOutro4 = 1;
public const uint SaySylvanasOutro10 = 2;
public const uint SayTyrannusOutro7 = 1;
public const uint SayTyrannusOutro9 = 2;
}
struct Events
{
public const uint MightyKick = 1;
public const uint ShadowBolt = 2;
public const uint ToxicWaste = 3;
public const uint Special = 4; //Special Spell Selection (One Of Event 5; 6 Or 7)
public const uint Pursuit = 5;
public const uint PoisonNova = 6;
public const uint ExplosiveBarrage = 7;
// Krick Outro
public const uint Outro1 = 8;
public const uint Outro2 = 9;
public const uint Outro3 = 10;
public const uint Outro4 = 11;
public const uint Outro5 = 12;
public const uint Outro6 = 13;
public const uint Outro7 = 14;
public const uint Outro8 = 15;
public const uint Outro9 = 16;
public const uint Outro10 = 17;
public const uint Outro11 = 18;
public const uint Outro12 = 19;
public const uint Outro13 = 20;
public const uint OutroEnd = 21;
}
enum KrickPhase
{
Combat = 1,
Outro = 2
}
struct Misc
{
public const int ActionOutro = 1;
public const uint PointKrickIntro = 364770;
public const uint PointKrickDeath = 364771;
public static Position[] outroPos =
{
new Position(828.9342f, 118.6247f, 509.5190f, 0.0000000f), // Krick's Outro Position
new Position( 841.0100f, 196.2450f, 573.9640f, 0.2046099f), // Scourgelord Tyrannus Outro Position (Tele to...)
new Position( 777.2274f, 119.5521f, 510.0363f, 6.0562930f), // Sylvanas / Jaine Outro Spawn Position (NPC_SYLVANAS_PART1)
new Position(823.3984f, 114.4907f, 509.4899f, 0.0000000f), // Sylvanas / Jaine Outro Move Position (1)
new Position( 835.5887f, 139.4345f, 530.9526f, 0.0000000f), // Tyrannus fly down Position (not sniffed)
new Position( 828.9342f, 118.6247f, 514.5190f, 0.0000000f), // Krick's Choke Position
new Position(828.9342f, 118.6247f, 509.4958f, 0.0000000f), // Kirck's Death Position
new Position(914.4820f, 143.1602f, 633.3624f, 0.0000000f) // Tyrannus fly up (not sniffed)
};
}
[Script]
class boss_ick : BossAI
{
public boss_ick(Creature creature) : base(creature, DataTypes.Ick)
{
_tempThreat = 0;
}
public override void Reset()
{
_events.Reset();
instance.SetBossState(DataTypes.Ick, EncounterState.NotStarted);
}
Creature GetKrick()
{
return ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Krick));
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickAggro);
_events.ScheduleEvent(Events.MightyKick, 20000);
_events.ScheduleEvent(Events.ToxicWaste, 5000);
_events.ScheduleEvent(Events.ShadowBolt, 10000);
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
}
public override void EnterEvadeMode(EvadeReason why)
{
me.GetMotionMaster().Clear();
base.EnterEvadeMode(why);
}
public override void JustDied(Unit killer)
{
Creature krick = GetKrick();
if (krick)
{
Vehicle vehicle = me.GetVehicleKit();
if (vehicle)
vehicle.RemoveAllPassengers();
if (krick.IsAIEnabled)
krick.GetAI().DoAction(Misc.ActionOutro);
}
instance.SetBossState(DataTypes.Ick, EncounterState.Done);
}
public void SetTempThreat(float threat)
{
_tempThreat = threat;
}
public void _ResetThreat(Unit target)
{
DoModifyThreatPercent(target, -100);
me.AddThreat(target, _tempThreat);
}
public override void UpdateAI(uint diff)
{
if (!me.IsInCombat())
return;
if (!me.GetVictim() && me.GetThreatManager().isThreatListEmpty())
{
EnterEvadeMode(EvadeReason.NoHostiles);
return;
}
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.ToxicWaste:
{
Creature krick = GetKrick();
if (krick)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
krick.CastSpell(target, SpellIds.ToxicWaste);
_events.ScheduleEvent(Events.ToxicWaste, TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(10));
}
}
break;
case Events.ShadowBolt:
{
Creature krick = GetKrick();
if (krick)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1);
if (target)
krick.CastSpell(target, SpellIds.ShadowBolt);
_events.ScheduleEvent(Events.ShadowBolt, 15000);
}
}
return;
case Events.MightyKick:
DoCastVictim(SpellIds.MightyKick);
_events.ScheduleEvent(Events.MightyKick, 25000);
return;
case Events.Special:
//select one of these three special _events
_events.ScheduleEvent(RandomHelper.RAND(Events.ExplosiveBarrage, Events.PoisonNova, Events.Pursuit), 1000);
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(28));
break;
case Events.ExplosiveBarrage:
{
Creature krick = GetKrick();
if (krick)
{
krick.GetAI().Talk(TextIds.SayKrickBarrage1);
krick.GetAI().Talk(TextIds.SayKrickBarrage2);
krick.CastSpell(krick, SpellIds.ExplosiveBarrageKrick, true);
DoCast(me, SpellIds.ExplosiveBarrageIck);
}
_events.DelayEvents(20000);
}
break;
case Events.PoisonNova:
{
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickPoisonNova);
Talk(TextIds.SayIckPoisonNova);
DoCast(me, SpellIds.PoisonNova);
}
break;
case Events.Pursuit:
{
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickChase);
DoCast(me, SpellIds.Pursuit);
}
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
float _tempThreat;
}
[Script]
class boss_krick : ScriptedAI
{
public boss_krick(Creature creature) : base(creature)
{
_instanceScript = creature.GetInstanceScript();
_summons = new SummonList(creature);
Initialize();
}
void Initialize()
{
_phase = KrickPhase.Combat;
_outroNpcGUID.Clear();
_tyrannusGUID.Clear();
}
public override void Reset()
{
_events.Reset();
Initialize();
me.SetReactState(ReactStates.Passive);
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
}
Creature GetIck()
{
return ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.Ick));
}
public override void KilledUnit(Unit victim)
{
if (victim.IsPlayer())
Talk(TextIds.SayKrickSlay);
}
public override void JustSummoned(Creature summon)
{
_summons.Summon(summon);
if (summon.GetEntry() == CreatureIds.ExplodingOrb)
{
summon.CastSpell(summon, SpellIds.ExplodingOrb, true);
summon.CastSpell(summon, SpellIds.AutoGrow, true);
}
}
public override void DoAction(int actionId)
{
if (actionId == Misc.ActionOutro)
{
Creature tyrannusPtr = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannusPtr)
tyrannusPtr.NearTeleportTo(Misc.outroPos[1].GetPositionX(), Misc.outroPos[1].GetPositionY(), Misc.outroPos[1].GetPositionZ(), Misc.outroPos[1].GetOrientation());
else
tyrannusPtr = me.SummonCreature(CreatureIds.TyrannusEvents, Misc.outroPos[1], TempSummonType.ManualDespawn);
tyrannusPtr.SetCanFly(true);
me.GetMotionMaster().MovePoint(Misc.PointKrickIntro, Misc.outroPos[0].GetPositionX(), Misc.outroPos[0].GetPositionY(), Misc.outroPos[0].GetPositionZ());
tyrannusPtr.SetFacingToObject(me);
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point || id != Misc.PointKrickIntro)
return;
Talk(TextIds.SayKrickOutro1);
_phase = KrickPhase.Outro;
_events.Reset();
_events.ScheduleEvent(Events.Outro1, 1000);
}
public override void UpdateAI(uint diff)
{
if (_phase != KrickPhase.Outro)
return;
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.Outro1:
{
Creature temp = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.JainaSylvanas1));
if (temp)
temp.DespawnOrUnsummon();
Creature jainaOrSylvanas = null;
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas = me.SummonCreature(CreatureIds.JainaPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
else
jainaOrSylvanas = me.SummonCreature(CreatureIds.SylvanasPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
if (jainaOrSylvanas)
{
jainaOrSylvanas.GetMotionMaster().MovePoint(0, Misc.outroPos[3]);
_outroNpcGUID = jainaOrSylvanas.GetGUID();
}
_events.ScheduleEvent(Events.Outro2, 6000);
break;
}
case Events.Outro2:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
jainaOrSylvanas.SetFacingToObject(me);
me.SetFacingToObject(jainaOrSylvanas);
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro2);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro2);
}
_events.ScheduleEvent(Events.Outro3, 5000);
}
break;
case Events.Outro3:
Talk(TextIds.SayKrickOutro3);
_events.ScheduleEvent(Events.Outro4, 18000);
break;
case Events.Outro4:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro4);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro4);
}
_events.ScheduleEvent(Events.Outro5, 5000);
}
break;
case Events.Outro5:
Talk(TextIds.SayKrickOutro5);
_events.ScheduleEvent(Events.Outro6, 1000);
break;
case Events.Outro6:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannus)
{
tyrannus.SetSpeedRate(UnitMoveType.Flight, 3.5f);
tyrannus.GetMotionMaster().MovePoint(1, Misc.outroPos[4]);
_tyrannusGUID = tyrannus.GetGUID();
}
_events.ScheduleEvent(Events.Outro7, 5000);
}
break;
case Events.Outro7:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro7);
_events.ScheduleEvent(Events.Outro8, 5000);
}
break;
case Events.Outro8:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me.AddUnitMovementFlag(MovementFlag.Flying);
me.GetMotionMaster().MovePoint(0, Misc.outroPos[5]);
DoCast(me, SpellIds.Strangulating);
_events.ScheduleEvent(Events.Outro9, 2000);
break;
case Events.Outro9:
{
Talk(TextIds.SayKrickOutro8);
/// @todo Tyrannus starts killing Krick.
// there shall be some visual spell effect
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.CastSpell(me, SpellIds.NecromanticPower, true); //not sure if it's the right spell :/
_events.ScheduleEvent(Events.Outro10, 1000);
}
break;
case Events.Outro10:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me.RemoveUnitMovementFlag(MovementFlag.Flying);
me.AddUnitMovementFlag(MovementFlag.FallingFar);
me.GetMotionMaster().MovePoint(0, Misc.outroPos[6]);
_events.ScheduleEvent(Events.Outro11, 2000);
break;
case Events.Outro11:
DoCast(me, SpellIds.KrickKillCredit); // don't really know if we need it
me.SetStandState(UnitStandStateType.Dead);
me.SetHealth(0);
_events.ScheduleEvent(Events.Outro12, 3000);
break;
case Events.Outro12:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro9);
_events.ScheduleEvent(Events.Outro13, 2000);
}
break;
case Events.Outro13:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro10);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro10);
}
// End of OUTRO. for now...
_events.ScheduleEvent(Events.OutroEnd, 3000);
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetMotionMaster().MovePoint(0, Misc.outroPos[7]);
}
break;
case Events.OutroEnd:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.DespawnOrUnsummon();
me.DisappearAndDie();
}
break;
default:
break;
}
});
}
InstanceScript _instanceScript;
SummonList _summons;
KrickPhase _phase;
ObjectGuid _outroNpcGUID;
ObjectGuid _tyrannusGUID;
}
[Script]
class spell_krick_explosive_barrage : AuraScript
{
void HandlePeriodicTick(AuraEffect aurEff)
{
PreventDefaultAction();
Unit caster = GetCaster();
if (caster)
{
if (caster.IsCreature())
{
var players = caster.GetMap().GetPlayers();
foreach (var player in players)
{
if (player)
if (player.IsWithinDist(caster, 60.0f)) // don't know correct range
caster.CastSpell(player, SpellIds.ExplosiveBarrageSummon, true);
}
}
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicTriggerSpell));
}
}
[Script]
class spell_ick_explosive_barrage : AuraScript
{
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
if (caster.IsCreature())
caster.GetMotionMaster().MoveIdle();
}
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
{
if (caster.IsCreature())
{
caster.GetMotionMaster().Clear();
caster.GetMotionMaster().MoveChase(caster.GetVictim());
}
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_exploding_orb_hasty_grow : AuraScript
{
void OnStackChange(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetStackAmount() == 15)
{
Unit target = GetTarget(); // store target because aura gets removed
target.CastSpell(target, SpellIds.ExplosiveBarrageDamage, false);
target.RemoveAurasDueToSpell(SpellIds.HastyGrow);
target.RemoveAurasDueToSpell(SpellIds.AutoGrow);
target.RemoveAurasDueToSpell(SpellIds.ExplodingOrb);
Creature creature = target.ToCreature();
if (creature)
creature.DespawnOrUnsummon();
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(OnStackChange, 0, AuraType.ModScale, AuraEffectHandleModes.Reapply));
}
}
[Script]
class spell_krick_pursuit : SpellScript
{
void HandleScriptEffect(uint effIndex)
{
if (GetCaster())
{
Creature ick = GetCaster().ToCreature();
if (ick)
{
Unit target = ick.GetAI().SelectTarget(SelectAggroTarget.Random, 0, 200.0f, true);
if (target)
{
ick.GetAI().Talk(TextIds.SayIckChase1, target);
ick.AddAura(GetSpellInfo().Id, target);
ick.GetAI<boss_ick>().SetTempThreat(ick.GetThreatManager().getThreat(target));
ick.AddThreat(target, GetEffectValue());
target.AddThreat(ick, GetEffectValue());
}
}
}
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_krick_pursuit_AuraScript : AuraScript
{
void HandleExtraEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
{
Creature creCaster = caster.ToCreature();
if (creCaster)
creCaster.GetAI<boss_ick>()._ResetThreat(GetTarget());
}
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(HandleExtraEffect, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_krick_pursuit_confusion : AuraScript
{
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, true);
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, true);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, false);
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, false);
}
public override void Register()
{
OnEffectApply.Add(new EffectApplyHandler(OnApply, 2, AuraType.Linked, AuraEffectHandleModes.Real));
OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 2, AuraType.Linked, AuraEffectHandleModes.Real));
}
}
}
@@ -0,0 +1,344 @@
using System.Collections.Generic;
using Game.Entities;
using Game.Scripting;
using Game.Maps;
using Framework.Constants;
using Framework.Dynamic;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
{
struct Misc
{
// positions for Martin Victus (37591) and Gorkun Ironskull (37592)
public static Position SlaveLeaderPos = new Position(689.7158f, -104.8736f, 513.7360f, 0.0f);
// position for Jaina and Sylvanas
public static Position EventLeaderPos2 = new Position(1054.368f, 107.14620f, 628.4467f, 0.0f);
public static DoorData[] Doors =
{
new DoorData(GameObjectIds.IceWall, DataTypes.Garfrost, DoorType.Passage),
new DoorData(GameObjectIds.IceWall, DataTypes.Ick, DoorType.Passage),
new DoorData(GameObjectIds.HallsOfReflectionPortcullis, DataTypes.Tyrannus, DoorType.Passage),
};
}
class instance_pit_of_saron : InstanceMapScript
{
public instance_pit_of_saron() : base(nameof(instance_pit_of_saron), 658) { }
class instance_pit_of_saron_InstanceScript : InstanceScript
{
public instance_pit_of_saron_InstanceScript(Map map) : base(map)
{
SetHeaders("POS");
SetBossNumber(3);
LoadDoorData(Misc.Doors);
_teamInInstance = 0;
_cavernActive = 0;
_shardsHit = 0;
}
public override void OnPlayerEnter(Player player)
{
if (_teamInInstance == 0)
_teamInInstance = player.GetTeam();
}
public override void OnCreatureCreate(Creature creature)
{
if (_teamInInstance == 0)
{
var players = instance.GetPlayers();
if (!players.Empty())
{
Player player = players[0];
if (player)
_teamInInstance = player.GetTeam();
}
}
switch (creature.GetEntry())
{
case CreatureIds.Garfrost:
_garfrostGUID = creature.GetGUID();
break;
case CreatureIds.Krick:
_krickGUID = creature.GetGUID();
break;
case CreatureIds.Ick:
_ickGUID = creature.GetGUID();
break;
case CreatureIds.Tyrannus:
_tyrannusGUID = creature.GetGUID();
break;
case CreatureIds.Rimefang:
_rimefangGUID = creature.GetGUID();
break;
case CreatureIds.TyrannusEvents:
_tyrannusEventGUID = creature.GetGUID();
break;
case CreatureIds.SylvanasPart1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart1);
_jainaOrSylvanas1GUID = creature.GetGUID();
break;
case CreatureIds.SylvanasPart2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart2);
_jainaOrSylvanas2GUID = creature.GetGUID();
break;
case CreatureIds.Kilara:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Elandra);
break;
case CreatureIds.Koralen:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Korlaen);
break;
case CreatureIds.Champion1Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion1Alliance);
break;
case CreatureIds.Champion2Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion2Alliance);
break;
case CreatureIds.Champion3Horde: // No 3rd set for Alliance?
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion2Alliance);
break;
case CreatureIds.HordeSlave1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave1);
break;
case CreatureIds.HordeSlave2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave2);
break;
case CreatureIds.HordeSlave3:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave3);
break;
case CreatureIds.HordeSlave4:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave4);
break;
case CreatureIds.FreedSlave1Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave1Alliance);
break;
case CreatureIds.FreedSlave2Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave2Alliance);
break;
case CreatureIds.FreedSlave3Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave3Alliance);
break;
case CreatureIds.RescuedSlaveHorde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.RescuedSlaveAlliance);
break;
case CreatureIds.MartinVictus1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.MartinVictus1);
break;
case CreatureIds.MartinVictus2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.MartinVictus2);
break;
case CreatureIds.CavernEventTrigger:
_cavernstriggersVector.Add(creature.GetGUID());
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.IceWall:
case GameObjectIds.HallsOfReflectionPortcullis:
AddDoor(go, true);
break;
}
}
public override void OnGameObjectRemove(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.IceWall:
case GameObjectIds.HallsOfReflectionPortcullis:
AddDoor(go, false);
break;
}
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case DataTypes.Garfrost:
if (state == EncounterState.Done)
{
Creature summoner = instance.GetCreature(_garfrostGUID);
if (summoner)
{
if (_teamInInstance == Team.Alliance)
summoner.SummonCreature(CreatureIds.MartinVictus1, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
else
summoner.SummonCreature(CreatureIds.GorkunIronskull2, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
}
}
break;
case DataTypes.Tyrannus:
if (state == EncounterState.Done)
{
Creature summoner = instance.GetCreature(_tyrannusGUID);
if (summoner)
{
if (_teamInInstance == Team.Alliance)
summoner.SummonCreature(CreatureIds.JainaPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
else
summoner.SummonCreature(CreatureIds.SylvanasPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
}
}
break;
default:
break;
}
return true;
}
public override uint GetData(uint type)
{
switch (type)
{
case DataTypes.TeamInInstance:
return (uint)_teamInInstance;
case DataTypes.IceShardsHit:
return _shardsHit;
case DataTypes.CavernActive:
return _cavernActive;
default:
break;
}
return 0;
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case DataTypes.IceShardsHit:
_shardsHit = (byte)data;
break;
case DataTypes.CavernActive:
if (data != 0)
{
_cavernActive = (byte)data;
HandleCavernEventTrigger(true);
}
else
HandleCavernEventTrigger(false);
break;
default:
break;
}
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataTypes.Garfrost:
return _garfrostGUID;
case DataTypes.Krick:
return _krickGUID;
case DataTypes.Ick:
return _ickGUID;
case DataTypes.Tyrannus:
return _tyrannusGUID;
case DataTypes.Rimefang:
return _rimefangGUID;
case DataTypes.TyrannusEvent:
return _tyrannusEventGUID;
case DataTypes.JainaSylvanas1:
return _jainaOrSylvanas1GUID;
case DataTypes.JainaSylvanas2:
return _jainaOrSylvanas2GUID;
default:
break;
}
return ObjectGuid.Empty;
}
void HandleCavernEventTrigger(bool activate)
{
foreach (ObjectGuid guid in _cavernstriggersVector)
{
Creature trigger = instance.GetCreature(guid);
if (trigger)
{
if (activate)
trigger.m_Events.AddEvent(new ScheduledIcicleSummons(trigger), trigger.m_Events.CalculateTime(1000));
else
trigger.m_Events.KillAllEvents(false);
}
}
}
ObjectGuid _garfrostGUID;
ObjectGuid _krickGUID;
ObjectGuid _ickGUID;
ObjectGuid _tyrannusGUID;
ObjectGuid _rimefangGUID;
ObjectGuid _tyrannusEventGUID;
ObjectGuid _jainaOrSylvanas1GUID;
ObjectGuid _jainaOrSylvanas2GUID;
List<ObjectGuid> _cavernstriggersVector = new List<ObjectGuid>();
Team _teamInInstance;
byte _shardsHit;
byte _cavernActive;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_pit_of_saron_InstanceScript(map);
}
}
class ScheduledIcicleSummons : BasicEvent
{
public ScheduledIcicleSummons(Creature trigger)
{
_trigger = trigger;
}
public override bool Execute(ulong time, uint diff)
{
if (RandomHelper.randChance(12))
{
_trigger.CastSpell(_trigger, SpellIds.IcicleSummon, true);
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(20000, 35000)));
}
else
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(1000, 20000)));
return true;
}
Creature _trigger;
}
}
@@ -0,0 +1,330 @@
using System;
using Game.Entities;
using Game.AI;
using Game.Spells;
using Game.DataStorage;
using Game.Scripting;
using Framework.Constants;
using Game.Maps;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
{
struct TextIds
{
public const uint SayTyrannusCavernEntrance = 3;
}
struct DataTypes
{
// Encounter States And Guids
public const uint Garfrost = 0;
public const uint Ick = 1;
public const uint Tyrannus = 2;
// Guids
public const uint Rimefang = 3;
public const uint Krick = 4;
public const uint JainaSylvanas1 = 5; // Guid Of Either Jaina Or Sylvanas Part 1; Depending On Team; As It'S The Same Spawn.
public const uint JainaSylvanas2 = 6; // Guid Of Either Jaina Or Sylvanas Part 2; Depending On Team; As It'S The Same Spawn.
public const uint TyrannusEvent = 7;
public const uint TeamInInstance = 8;
public const uint IceShardsHit = 9;
public const uint CavernActive = 10;
}
struct CreatureIds
{
public const uint Garfrost = 36494;
public const uint Krick = 36477;
public const uint Ick = 36476;
public const uint Tyrannus = 36658;
public const uint Rimefang = 36661;
public const uint TyrannusEvents = 36794;
public const uint SylvanasPart1 = 36990;
public const uint SylvanasPart2 = 38189;
public const uint JainaPart1 = 36993;
public const uint JainaPart2 = 38188;
public const uint Kilara = 37583;
public const uint Elandra = 37774;
public const uint Koralen = 37779;
public const uint Korlaen = 37582;
public const uint Champion1Horde = 37584;
public const uint Champion2Horde = 37587;
public const uint Champion3Horde = 37588;
public const uint Champion1Alliance = 37496;
public const uint Champion2Alliance = 37497;
public const uint HordeSlave1 = 36770;
public const uint HordeSlave2 = 36771;
public const uint HordeSlave3 = 36772;
public const uint HordeSlave4 = 36773;
public const uint AllianceSlave1 = 36764;
public const uint AllianceSlave2 = 36765;
public const uint AllianceSlave3 = 36766;
public const uint AllianceSlave4 = 36767;
public const uint FreedSlave1Alliance = 37575;
public const uint FreedSlave2Alliance = 37572;
public const uint FreedSlave3Alliance = 37576;
public const uint FreedSlave1Horde = 37579;
public const uint FreedSlave2Horde = 37578;
public const uint FreedSlave3Horde = 37577;
public const uint RescuedSlaveAlliance = 36888;
public const uint RescuedSlaveHorde = 36889;
public const uint MartinVictus1 = 37591;
public const uint MartinVictus2 = 37580;
public const uint GorkunIronskull1 = 37581;
public const uint GorkunIronskull2 = 37592;
public const uint ForgemasterStalker = 36495;
public const uint ExplodingOrb = 36610;
public const uint YmirjarDeathbringer = 36892;
public const uint IcyBlast = 36731;
public const uint CavernEventTrigger = 32780;
}
struct GameObjectIds
{
public const uint SaroniteRock = 196485;
public const uint IceWall = 201885;
public const uint HallsOfReflectionPortcullis = 201848;
}
struct SpellIds
{
public const uint IcicleSummon = 69424;
public const uint IcicleFallTrigger = 69426;
public const uint IcicleFallVisual = 69428;
public const uint AchievDontLookUpCredit = 72845;
public const uint Fireball = 69583; //Ymirjar Flamebearer
public const uint Hellfire = 69586;
public const uint TacticalBlink = 69584;
public const uint FrostBreath = 69527; //Iceborn Proto-Drake
public const uint LeapingFaceMaul = 69504; // Geist Ambusher
}
[Script]
class npc_ymirjar_flamebearer : ScriptedAI
{
public npc_ymirjar_flamebearer(Creature creature) : base(creature)
{
}
public override void Reset()
{
_scheduler.CancelAll();
}
public override void EnterCombat(Unit who)
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.Fireball);
task.Repeat(TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.TacticalBlink);
DoCast(me, SpellIds.Hellfire);
task.Repeat(TimeSpan.FromSeconds(12));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_iceborn_protodrake : ScriptedAI
{
public npc_iceborn_protodrake(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
Vehicle vehicle = me.GetVehicleKit();
if (vehicle)
vehicle.RemoveAllPassengers();
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.FrostBreath);
task.Repeat(TimeSpan.FromSeconds(10));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
[Script]
class npc_geist_ambusher : ScriptedAI
{
public npc_geist_ambusher(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
if (who.GetTypeId() != TypeId.Player)
return;
// the max range is determined by aggro range
if (me.GetDistance(who) > 5.0f)
DoCast(who, SpellIds.LeapingFaceMaul);
_scheduler.Schedule(TimeSpan.FromSeconds(9), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 5.0f, true);
if (target)
DoCast(target, SpellIds.LeapingFaceMaul);
task.Repeat(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(14));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
[Script]
class spell_trash_npc_glacial_strike : AuraScript
{
void PeriodicTick(AuraEffect aurEff)
{
if (GetTarget().IsFullHealth())
{
GetTarget().RemoveAura(GetId(), ObjectGuid.Empty, 0, AuraRemoveMode.EnemySpell);
PreventDefaultAction();
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 2, AuraType.PeriodicDamagePercent));
}
}
[Script]
class npc_pit_of_saron_icicle : PassiveAI
{
public npc_pit_of_saron_icicle(Creature creature) : base(creature)
{
me.SetDisplayId(me.GetCreatureTemplate().ModelId1);
}
public override void IsSummonedBy(Unit summoner)
{
_summonerGUID = summoner.GetGUID();
_scheduler.Schedule(TimeSpan.FromMilliseconds(3650), task =>
{
DoCastSelf(SpellIds.IcicleFallTrigger, true);
DoCastSelf(SpellIds.IcicleFallVisual);
Unit caster = Global.ObjAccessor.GetUnit(me, _summonerGUID);
if (caster)
caster.RemoveDynObject(SpellIds.IcicleSummon);
});
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
ObjectGuid _summonerGUID;
}
[Script]
class spell_pos_ice_shards : SpellScript
{
void HandleScriptEffect(uint effIndex)
{
if (GetHitPlayer())
GetCaster().GetInstanceScript().SetData(DataTypes.CavernActive, 1);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.SchoolDamage));
}
}
[Script]
class at_pit_cavern_entrance : AreaTriggerScript
{
public at_pit_cavern_entrance() : base("at_pit_cavern_entrance") { }
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
{
if (!entered)
return true;
InstanceScript instance = player.GetInstanceScript();
if (instance != null)
{
if (instance.GetData(DataTypes.CavernActive) != 0)
return true;
instance.SetData(DataTypes.CavernActive, 1);
Creature tyrannus = ObjectAccessor.GetCreature(player, instance.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusCavernEntrance);
}
return true;
}
}
[Script]
class at_pit_cavern_end : AreaTriggerScript
{
public at_pit_cavern_end() : base("at_pit_cavern_end") { }
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
{
if (!entered)
return true;
InstanceScript instance = player.GetInstanceScript();
if (instance != null)
{
instance.SetData(DataTypes.CavernActive, 0);
if (instance.GetData(DataTypes.IceShardsHit) == 0)
instance.DoUpdateCriteria(CriteriaTypes.BeSpellTarget, SpellIds.AchievDontLookUpCredit, 0, player);
}
return true;
}
}
}