Added more Scripts

This commit is contained in:
hondacrx
2017-10-02 12:55:53 -04:00
parent 340aac5659
commit f43ab8cd82
8 changed files with 1821 additions and 7 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_fragmentAI : ScriptedAI
{
public npc_corrupted_soul_fragmentAI(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,417 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
}
}