initial commit

This commit is contained in:
hondacrx
2017-06-19 17:30:18 -04:00
commit 6e265ea24b
763 changed files with 488824 additions and 0 deletions
@@ -0,0 +1,209 @@
/*
* 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.Scripting;
using System;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.Amanitar
{
struct SpellIds
{
public const uint Bash = 57094; // Victim
public const uint EntanglingRoots = 57095; // Random Victim 100y
public const uint Mini = 57055; // Self
public const uint VenomBoltVolley = 57088; // Random Victim 100y
public const uint HealthyMushroomPotentFungus = 56648; // Killer 3y
public const uint PoisonousMushroomPoisonCloud = 57061; // Self - Duration 8 Sec
public const uint PoisonousMushroomVisualArea = 61566; // Self
public const uint PoisonousMushroomVisualAura = 56741; // Self
public const uint PutridMushroom = 31690; // To Make The Mushrooms Visible
public const uint PowerMushroomVisualAura = 56740;
}
struct CreatureIds
{
public const uint Trigger = 19656;
public const uint HealthyMushroom = 30391;
public const uint PoisonousMushroom = 30435;
}
[Script]
class boss_amanitar : CreatureScript
{
public boss_amanitar() : base("boss_amanitar") { }
class boss_amanitarAI : BossAI
{
public boss_amanitarAI(Creature creature) : base(creature, DataTypes.Amanitar) { }
public override void Reset()
{
_Reset();
me.SetMeleeDamageSchool(SpellSchools.Nature);
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
SpawnAdds();
task.Repeat(TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(9), task =>
{
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.EntanglingRoots, true);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14), task =>
{
DoCastVictim(SpellIds.Bash);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(18), task =>
{
DoCast(SpellIds.Mini);
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), task =>
{
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.VenomBoltVolley, true);
task.Repeat(TimeSpan.FromSeconds(18), TimeSpan.FromSeconds(22));
});
}
public override void JustDied(Unit killer)
{
_JustDied();
instance.DoRemoveAurasDueToSpellOnPlayers(SpellIds.Mini);
}
void SpawnAdds()
{
int u = 0;
for (byte i = 0; i < 30; ++i)
{
Position pos = me.GetRandomNearPosition(30.0f);
pos.posZ = me.GetMap().GetHeight(pos.GetPositionX(), pos.GetPositionY(), MapConst.MaxHeight) + 2.0f;
Creature trigger = me.SummonCreature(CreatureIds.Trigger, pos);
if (trigger)
{
Creature temp1 = trigger.FindNearestCreature(CreatureIds.HealthyMushroom, 4.0f, true);
Creature temp2 = trigger.FindNearestCreature(CreatureIds.PoisonousMushroom, 4.0f, true);
if (temp1 || temp2)
{
trigger.DisappearAndDie();
}
else
{
u = 1 - u;
trigger.DisappearAndDie();
me.SummonCreature(u > 0 ? CreatureIds.PoisonousMushroom : CreatureIds.HealthyMushroom, pos, TempSummonType.TimedOrCorpseDespawn, 60 * Time.InMilliseconds);
}
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_amanitarAI>(creature);
}
}
[Script]
class npc_amanitar_mushrooms : CreatureScript
{
public npc_amanitar_mushrooms() : base("npc_amanitar_mushrooms") { }
class npc_amanitar_mushroomsAI : ScriptedAI
{
public npc_amanitar_mushroomsAI(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
{
if (me.GetEntry() == CreatureIds.PoisonousMushroom)
{
DoCast(me, SpellIds.PoisonousMushroomVisualArea, true);
DoCast(me, SpellIds.PoisonousMushroomPoisonCloud);
}
task.Repeat(TimeSpan.FromSeconds(7));
});
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
DoCast(SpellIds.PutridMushroom);
if (me.GetEntry() == CreatureIds.PoisonousMushroom)
DoCast(SpellIds.PoisonousMushroomVisualAura);
else
DoCast(SpellIds.PowerMushroomVisualAura);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (damage >= me.GetHealth() && me.GetEntry() == CreatureIds.HealthyMushroom)
DoCast(me, SpellIds.HealthyMushroomPotentFungus, true);
}
public override void EnterCombat(Unit who) { }
public override void AttackStart(Unit victim) { }
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_amanitar_mushroomsAI(creature);
}
}
}
@@ -0,0 +1,276 @@
/*
* 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.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.ElderNadox
{
struct SpellIds
{
public const uint BroodPlague = 56130;
public const uint HBroodRage = 59465;
public const uint Enrage = 26662; // Enraged If Too Far Away From Home
public const uint SummonSwarmers = 56119; // 2x 30178 -- 2x Every 10secs
public const uint SummonSwarmGuard = 56120; // 1x 30176
// Adds
public const uint SwarmBuff = 56281;
public const uint Sprint = 56354;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SayEggSac = 3;
public const uint EmoteHatches = 4;
}
struct Misc
{
public const uint DataRespectYourElders = 6;
}
[Script]
class boss_elder_nadox : CreatureScript
{
public boss_elder_nadox() : base("boss_elder_nadox") { }
class boss_elder_nadoxAI : BossAI
{
public boss_elder_nadoxAI(Creature creature) : base(creature, DataTypes.ElderNadox)
{
Initialize();
}
void Initialize()
{
GuardianSummoned = false;
GuardianDied = false;
}
public override void Reset()
{
_Reset();
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
_scheduler.Schedule(TimeSpan.FromSeconds(13), task =>
{
DoCast(SelectTarget(SelectAggroTarget.Random, 0, 100, true), SpellIds.BroodPlague, true);
task.Repeat(TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
/// @todo: summoned by egg
DoCast(me, SpellIds.SummonSwarmers);
if (RandomHelper.URand(1, 3) == 3) // 33% chance of dialog
Talk(TextIds.SayEggSac);
task.Repeat();
});
if (IsHeroic())
{
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCast(SpellIds.HBroodRage);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(50));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
if (me.HasAura(SpellIds.Enrage))
return;
if (me.GetPositionZ() < 24.0f)
DoCast(me, SpellIds.Enrage, true);
task.Repeat();
});
}
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
if (summon.GetEntry() == AKCreatureIds.AhnkaharGuardian)
GuardianDied = true;
}
public override uint GetData(uint type)
{
if (type == Misc.DataRespectYourElders)
return !GuardianDied ? 1 : 0u;
return 0;
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(TextIds.SaySlay);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (!GuardianSummoned && me.HealthBelowPct(50))
{
/// @todo: summoned by egg
Talk(TextIds.EmoteHatches, me);
DoCast(me, SpellIds.SummonSwarmGuard);
GuardianSummoned = true;
}
DoMeleeAttackIfReady();
}
bool GuardianSummoned;
bool GuardianDied;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_elder_nadoxAI>(creature, "instance_ahnkahet");
}
}
[Script]
class npc_ahnkahar_nerubian : CreatureScript
{
public npc_ahnkahar_nerubian() : base("npc_ahnkahar_nerubian") { }
class npc_ahnkahar_nerubianAI : ScriptedAI
{
public npc_ahnkahar_nerubianAI(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(13), task =>
{
DoCast(me, SpellIds.Sprint);
task.Repeat(TimeSpan.FromSeconds(20));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_ahnkahar_nerubianAI(creature);
}
}
// 56159 - Swarm
[Script]
class spell_ahn_kahet_swarm : SpellScriptLoader
{
public spell_ahn_kahet_swarm() : base("spell_ahn_kahet_swarm") { }
class spell_ahn_kahet_swarm_SpellScript : SpellScript
{
public spell_ahn_kahet_swarm_SpellScript()
{
_targetCount = 0;
}
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.SwarmBuff);
}
void CountTargets(List<WorldObject> targets)
{
_targetCount = targets.Count;
}
void HandleDummy(uint effIndex)
{
if (_targetCount != 0)
{ Aura aura = GetCaster().GetAura(SpellIds.SwarmBuff);
if (aura != null)
{
aura.SetStackAmount((byte)_targetCount);
aura.RefreshDuration();
}
else
GetCaster().CastCustomSpell(SpellIds.SwarmBuff, SpellValueMod.AuraStack, _targetCount, GetCaster(), TriggerCastFlags.FullMask);
}
else
GetCaster().RemoveAurasDueToSpell(SpellIds.SwarmBuff);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(CountTargets, 0, Targets.UnitSrcAreaAlly));
OnEffectHit.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
}
int _targetCount;
}
public override SpellScript GetSpellScript()
{
return new spell_ahn_kahet_swarm_SpellScript();
}
}
[Script]
class achievement_respect_your_elders : AchievementCriteriaScript
{
public achievement_respect_your_elders() : base("achievement_respect_your_elders") { }
public override bool OnCheck(Player player, Unit target)
{
return target && target.GetAI().GetData(Misc.DataRespectYourElders) != 0;
}
}
}
@@ -0,0 +1,295 @@
/*
* 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.Collections.Generic;
using System.Linq;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.HeraldVolazj
{
struct SpellIds
{
public const uint Insanity = 57496; //Dummy
public const uint InsanityVisual = 57561;
public const uint InsanityTarget = 57508;
public const uint MindFlay = 57941;
public const uint ShadowBoltVolley = 57942;
public const uint Shiver = 57949;
public const uint ClonePlayer = 57507; //Cast On Player During Insanity
public const uint InsanityPhasing1 = 57508;
public const uint InsanityPhasing2 = 57509;
public const uint InsanityPhasing3 = 57510;
public const uint InsanityPhasing4 = 57511;
public const uint InsanityPhasing5 = 57512;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SayPhase = 3;
}
struct Misc
{
public const uint AchievQuickDemiseStartEvent = 20382;
}
[Script]
class boss_volazj : CreatureScript
{
public boss_volazj() : base("boss_volazj") { }
class boss_volazjAI : ScriptedAI
{
public boss_volazjAI(Creature creature) : base(creature)
{
Summons = new SummonList(me);
Initialize();
instance = creature.GetInstanceScript();
}
void Initialize()
{
uiMindFlayTimer = 8 * Time.InMilliseconds;
uiShadowBoltVolleyTimer = 5 * Time.InMilliseconds;
uiShiverTimer = 15 * Time.InMilliseconds;
// Used for Insanity handling
insanityHandled = 0;
}
// returns the percentage of health after taking the given damage.
uint GetHealthPct(uint damage)
{
if (damage > me.GetHealth())
return 0;
return (uint)(100 * (me.GetHealth() - damage) / me.GetMaxHealth());
}
public override void DamageTaken(Unit pAttacker, ref uint damage)
{
if (me.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable))
damage = 0;
if ((GetHealthPct(0) >= 66 && GetHealthPct(damage) < 66) ||
(GetHealthPct(0) >= 33 && GetHealthPct(damage) < 33))
{
me.InterruptNonMeleeSpells(false);
DoCast(me, SpellIds.Insanity, false);
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.Insanity)
{
// Not good target or too many players
if (target.GetTypeId() != TypeId.Player || insanityHandled > 4)
return;
// First target - start channel visual and set self as unnattackable
if (insanityHandled == 0)
{
// Channel visual
DoCast(me, SpellIds.InsanityVisual, true);
// Unattackable
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
me.SetControlled(true, UnitState.Stunned);
}
// phase the player
target.CastSpell(target, SpellIds.InsanityTarget + insanityHandled, true);
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.InsanityTarget + insanityHandled);
if (spellInfo == null)
return;
// summon twisted party members for this target
var players = me.GetMap().GetPlayers();
foreach (var player in players)
{
if (!player || !player.IsAlive())
continue;
// Summon clone
Unit summon = me.SummonCreature(AKCreatureIds.TwistedVisage, me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetOrientation(), TempSummonType.CorpseDespawn, 0);
if (summon)
{
// clone
player.CastSpell(summon, SpellIds.ClonePlayer, true);
// phase the summon
summon.SetInPhase((uint)spellInfo.GetEffect(0).MiscValueB, true, true);
}
}
++insanityHandled;
}
}
void ResetPlayersPhase()
{
var players = me.GetMap().GetPlayers();
foreach (var player in players)
{
for (uint index = 0; index <= 4; ++index)
player.RemoveAurasDueToSpell(SpellIds.InsanityTarget + index);
}
}
public override void Reset()
{
Initialize();
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.NotStarted);
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievQuickDemiseStartEvent);
// Visible for all players in insanity
me.SetInPhase(169, true, true);
for (uint i = 173; i <= 177; ++i)
me.SetInPhase(i, true, true);
ResetPlayersPhase();
// Cleanup
Summons.DespawnAll();
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
me.SetControlled(false, UnitState.Stunned);
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayAggro);
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.InProgress);
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievQuickDemiseStartEvent);
}
public override void JustSummoned(Creature summon)
{
Summons.Summon(summon);
}
public override void SummonedCreatureDespawn(Creature summon)
{
uint nextPhase = 0;
Summons.Despawn(summon);
// Check if all summons in this phase killed
foreach (var guid in Summons)
{
Creature visage = ObjectAccessor.GetCreature(me, guid);
if (visage)
{
// Not all are dead
if (visage.IsInPhase(summon))
return;
else
{
nextPhase = visage.GetPhases().First();
break;
}
}
}
// Roll Insanity
var players = me.GetMap().GetPlayers();
foreach (var player in players)
{
if (player)
{
for (uint index = 0; index <= 4; ++index)
player.RemoveAurasDueToSpell(SpellIds.InsanityTarget + index);
player.CastSpell(player, SpellIds.InsanityTarget + nextPhase - 173, true);
}
}
}
public override void UpdateAI(uint diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (insanityHandled != 0)
{
if (!Summons.Empty())
return;
insanityHandled = 0;
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
me.SetControlled(false, UnitState.Stunned);
me.RemoveAurasDueToSpell(SpellIds.InsanityVisual);
}
if (uiMindFlayTimer <= diff)
{
DoCastVictim(SpellIds.MindFlay);
uiMindFlayTimer = 20 * Time.InMilliseconds;
} else uiMindFlayTimer -= diff;
if (uiShadowBoltVolleyTimer <= diff)
{
DoCastVictim(SpellIds.ShadowBoltVolley);
uiShadowBoltVolleyTimer = 5 * Time.InMilliseconds;
} else uiShadowBoltVolleyTimer -= diff;
if (uiShiverTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.Shiver);
uiShiverTimer = 15 * Time.InMilliseconds;
} else uiShiverTimer -= diff;
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
instance.SetBossState(DataTypes.HeraldVolazj, EncounterState.Done);
Summons.DespawnAll();
ResetPlayersPhase();
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(TextIds.SaySlay);
}
InstanceScript instance;
uint uiMindFlayTimer;
uint uiShadowBoltVolleyTimer;
uint uiShiverTimer;
uint insanityHandled;
SummonList Summons;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_volazjAI>(creature);
}
}
}
@@ -0,0 +1,602 @@
/*
* 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;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.JedogaShadowseeker
{
struct SpellIds
{
public const uint SphereVisual = 56075;
public const uint GiftOfTheHerald = 56219;
public const uint CycloneStrike = 56855; // Self
public const uint LightningBolt = 56891; // 40y
public const uint Thundershock = 56926; // 30y
public const uint RandomLightningVisual = 56327;
public const uint SacrificeBeam = 56150;
public const uint SacrificeVisual = 56133;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySacrifice1 = 1;
public const uint SaySacrifice2 = 2;
public const uint SaySlay = 3;
public const uint SayDeath = 4;
public const uint SayPreaching = 5;
}
struct Misc
{
public const int ActionInitiateKilled = 1;
public const uint DataVolunteerWork = 2;
public static Position[] JedogaPosition =
{
new Position(372.330994f, -705.278015f, -0.624178f, 5.427970f),
new Position(372.330994f, -705.278015f, -16.179716f, 5.427970f)
};
}
[Script]
class boss_jedoga_shadowseeker : CreatureScript
{
public boss_jedoga_shadowseeker() : base("boss_jedoga_shadowseeker") { }
public class boss_jedoga_shadowseekerAI : ScriptedAI
{
public boss_jedoga_shadowseekerAI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
bFirstTime = true;
bPreDone = false;
}
void Initialize()
{
uiOpFerTimer = RandomHelper.URand(15 * Time.InMilliseconds, 20 * Time.InMilliseconds);
uiCycloneTimer = 3 * Time.InMilliseconds;
uiBoltTimer = 7 * Time.InMilliseconds;
uiThunderTimer = 12 * Time.InMilliseconds;
bOpFerok = false;
bOpFerokFail = false;
bOnGround = false;
bCanDown = false;
volunteerWork = true;
}
public override void Reset()
{
Initialize();
DoCast(SpellIds.RandomLightningVisual);
if (!bFirstTime)
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.Fail);
instance.SetGuidData(DataTypes.PlJedogaTarget, ObjectGuid.Empty);
instance.SetGuidData(DataTypes.AddJedogaVictim, ObjectGuid.Empty);
instance.SetData(DataTypes.JedogaResetInitiands, 0);
MoveUp();
bFirstTime = false;
}
public override void EnterCombat(Unit who)
{
if (instance == null || (who.GetTypeId() == TypeId.Unit && who.GetEntry() == AKCreatureIds.JedogaController))
return;
Talk(TextIds.SayAggro);
me.SetInCombatWithZone();
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.InProgress);
}
public override void AttackStart(Unit who)
{
if (!who || (who.GetTypeId() == TypeId.Unit && who.GetEntry() == AKCreatureIds.JedogaController))
return;
base.AttackStart(who);
}
public override void KilledUnit(Unit Victim)
{
if (!Victim || !Victim.IsTypeId(TypeId.Player))
return;
Talk(TextIds.SaySlay);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
instance.SetBossState(DataTypes.JedogaShadowseeker, EncounterState.Done);
}
public override void DoAction(int action)
{
if (action == Misc.ActionInitiateKilled)
volunteerWork = false;
}
public override uint GetData(uint type)
{
if (type == Misc.DataVolunteerWork)
return volunteerWork ? 1 : 0u;
return 0;
}
public override void MoveInLineOfSight(Unit who)
{
if (instance == null || !who || (who.IsTypeId(TypeId.Unit) && who.GetEntry() == AKCreatureIds.JedogaController))
return;
if (!bPreDone && who.IsTypeId(TypeId.Player) && me.GetDistance(who) < 100.0f)
{
Talk(TextIds.SayPreaching);
bPreDone = true;
}
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress || !bOnGround)
return;
if (!me.GetVictim() && me.CanCreatureAttack(who))
{
float attackRadius = me.GetAttackDistance(who);
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
{
if (!me.GetVictim())
{
who.RemoveAurasByType(AuraType.ModStealth);
AttackStart(who);
}
else
{
who.SetInCombatWith(me);
me.AddThreat(who, 0.0f);
}
}
}
}
void MoveDown()
{
bOpFerokFail = false;
instance.SetData(DataTypes.JedogaTriggerSwitch, 0);
me.GetMotionMaster().MovePoint(1, Misc.JedogaPosition[1]);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
bOnGround = true;
if (UpdateVictim())
{
AttackStart(me.GetVictim());
me.GetMotionMaster().MoveChase(me.GetVictim());
}
else
{
Unit target = Global.ObjAccessor.GetUnit(me, instance.GetGuidData(DataTypes.PlJedogaTarget));
if (target)
{
AttackStart(target);
instance.SetData(DataTypes.JedogaResetInitiands, 0);
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress)
EnterCombat(target);
}
else if (!me.IsInCombat())
EnterEvadeMode();
}
}
void MoveUp()
{
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.AttackStop();
me.RemoveAllAuras();
me.LoadCreaturesAddon();
me.GetMotionMaster().MovePoint(0, Misc.JedogaPosition[0]);
instance.SetData(DataTypes.JedogaTriggerSwitch, 1);
if (instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress)
GetVictimForSacrifice();
bOnGround = false;
uiOpFerTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
}
void GetVictimForSacrifice()
{
ObjectGuid victim = instance.GetGuidData(DataTypes.AddJedogaInitiand);
if (!victim.IsEmpty())
{
Talk(TextIds.SaySacrifice1);
instance.SetGuidData(DataTypes.AddJedogaVictim, victim);
}
else
bCanDown = true;
}
void Sacrifice()
{
Talk(TextIds.SaySacrifice2);
me.InterruptNonMeleeSpells(false);
DoCast(me, SpellIds.GiftOfTheHerald, false);
bOpFerok = false;
bCanDown = true;
}
public override void UpdateAI(uint diff)
{
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress && instance.GetData(DataTypes.AllInitiandDead) != 0)
MoveDown();
if (bOpFerok && !bOnGround && !bCanDown)
Sacrifice();
if (bOpFerokFail && !bOnGround && !bCanDown)
bCanDown = true;
if (bCanDown)
{
MoveDown();
bCanDown = false;
}
if (bOnGround)
{
if (!UpdateVictim())
return;
if (uiCycloneTimer <= diff)
{
DoCast(me, SpellIds.CycloneStrike, false);
uiCycloneTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
}
else uiCycloneTimer -= diff;
if (uiBoltTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
me.CastSpell(target, SpellIds.LightningBolt, false);
uiBoltTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
}
else uiBoltTimer -= diff;
if (uiThunderTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
me.CastSpell(target, SpellIds.Thundershock, false);
uiThunderTimer = RandomHelper.URand(15 * Time.InMilliseconds, 30 * Time.InMilliseconds);
}
else uiThunderTimer -= diff;
if (uiOpFerTimer <= diff)
MoveUp();
else
uiOpFerTimer -= diff;
DoMeleeAttackIfReady();
}
}
InstanceScript instance;
uint uiOpFerTimer;
uint uiCycloneTimer;
uint uiBoltTimer;
uint uiThunderTimer;
bool bPreDone;
public bool bOpFerok;
bool bOnGround;
public bool bOpFerokFail;
bool bCanDown;
bool volunteerWork;
bool bFirstTime;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_jedoga_shadowseekerAI>(creature);
}
}
[Script]
class npc_jedoga_twilight_volunteer : CreatureScript
{
public npc_jedoga_twilight_volunteer() : base("npc_jedoga_initiand") { }
class npc_jedoga_twilight_volunteerAI : ScriptedAI
{
public npc_jedoga_twilight_volunteerAI(Creature creature) : base(creature)
{
Initialize();
instance = creature.GetInstanceScript();
}
void Initialize()
{
bWalking = false;
bCheckTimer = 2 * Time.InMilliseconds;
}
public override void Reset()
{
Initialize();
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress)
{
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
}
else
{
DoCast(me, SpellIds.SphereVisual, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
}
}
public override void JustDied(Unit killer)
{
if (!killer || instance == null)
return;
if (bWalking)
{
Creature boss = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.JedogaShadowseeker));
if (boss)
{
if (!boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().bOpFerok)
boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().bOpFerokFail = true;
if (killer.IsTypeId(TypeId.Player))
boss.GetAI().DoAction(Misc.ActionInitiateKilled);
}
instance.SetGuidData(DataTypes.AddJedogaVictim, ObjectGuid.Empty);
bWalking = false;
}
if (killer.IsTypeId(TypeId.Player))
instance.SetGuidData(DataTypes.PlJedogaTarget, killer.GetGUID());
}
public override void EnterCombat(Unit who) { }
public override void AttackStart(Unit victim)
{
if ((instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress) || !victim)
return;
base.AttackStart(victim);
}
public override void MoveInLineOfSight(Unit who)
{
if ((instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress) || !who)
return;
base.MoveInLineOfSight(who);
}
public override void MovementInform(MovementGeneratorType uiType, uint uiPointId)
{
if (uiType != MovementGeneratorType.Point || instance == null)
return;
switch (uiPointId)
{
case 1:
{
Creature boss = me.GetMap().GetCreature(instance.GetGuidData(DataTypes.JedogaShadowseeker));
if (boss)
{
boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().bOpFerok = true;
boss.GetAI<boss_jedoga_shadowseeker.boss_jedoga_shadowseekerAI>().bOpFerokFail = false;
me.KillSelf();
}
}
break;
}
}
public override void UpdateAI(uint diff)
{
if (bCheckTimer <= diff)
{
if (me.GetGUID() == instance.GetGuidData(DataTypes.AddJedogaVictim) && !bWalking)
{
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
float distance = me.GetDistance(Misc.JedogaPosition[1]);
if (distance < 9.0f)
me.SetSpeedRate(UnitMoveType.Walk, 0.5f);
else if (distance < 15.0f)
me.SetSpeedRate(UnitMoveType.Walk, 0.75f);
else if (distance < 20.0f)
me.SetSpeedRate(UnitMoveType.Walk, 1.0f);
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MovePoint(1, Misc.JedogaPosition[1]);
bWalking = true;
}
if (!bWalking)
{
if (instance.GetBossState(DataTypes.JedogaShadowseeker) != EncounterState.InProgress && me.HasAura(SpellIds.SphereVisual))
{
me.RemoveAurasDueToSpell(SpellIds.SphereVisual);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, false);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
}
if (instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.InProgress && !me.HasAura(SpellIds.SphereVisual))
{
DoCast(me, SpellIds.SphereVisual, false);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Normal, true);
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable | UnitFlags.NonAttackable);
}
}
bCheckTimer = 2 * Time.InMilliseconds;
}
else bCheckTimer -= diff;
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
InstanceScript instance;
uint bCheckTimer;
bool bWalking;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_jedoga_twilight_volunteerAI>(creature);
}
}
[Script]
class npc_jedoga_controller : CreatureScript
{
public npc_jedoga_controller() : base("npc_jedogas_aufseher_trigger") { }
class npc_jedoga_controllerAI : ScriptedAI
{
public npc_jedoga_controllerAI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
bRemoved = false;
bRemoved2 = false;
bCast = false;
bCast2 = false;
SetCombatMovement(false);
}
public override void Reset() { }
public override void EnterCombat(Unit who) { }
public override void AttackStart(Unit victim) { }
public override void MoveInLineOfSight(Unit who) { }
public override void UpdateAI(uint diff)
{
if (!bRemoved && me.GetPositionX() > 440.0f)
{
if (instance.GetBossState(DataTypes.PrinceTaldaram) == EncounterState.Done)
{
me.InterruptNonMeleeSpells(true);
bRemoved = true;
return;
}
if (!bCast)
{
//DoCast(me, JedogaShadowseekerConst.SpellBeamVisualJedogasAufseher1, false);
bCast = true;
}
}
if (!bRemoved2 && me.GetPositionX() < 440.0f)
{
if (!bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) != 0)
{
//DoCast(me, JedogaShadowseekerConst.SpellBeamVisualJedogasAufseher2, false);
bCast2 = true;
}
if (bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) == 0)
{
me.InterruptNonMeleeSpells(true);
bCast2 = false;
}
if (!bRemoved2 && instance.GetBossState(DataTypes.JedogaShadowseeker) == EncounterState.Done)
{
me.InterruptNonMeleeSpells(true);
bRemoved2 = true;
}
}
}
InstanceScript instance;
bool bRemoved;
bool bRemoved2;
bool bCast;
bool bCast2;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_jedoga_controllerAI>(creature);
}
}
[Script]
class achievement_volunteer_work : AchievementCriteriaScript
{
public achievement_volunteer_work() : base("achievement_volunteer_work") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature Jedoga = target.ToCreature();
if (Jedoga)
if (Jedoga.GetAI().GetData(Misc.DataVolunteerWork) != 0)
return true;
return false;
}
}
}
@@ -0,0 +1,476 @@
/*
* 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;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet.PrinceTaldaram
{
struct SpellIds
{
public const uint Bloodthirst = 55968; // Trigger Spell + Add Aura
public const uint ConjureFlameSphere = 55931;
public const uint FlameSphereSummon1 = 55895; // 1x 30106
public const uint FlameSphereSummon2 = 59511; // 1x 31686
public const uint FlameSphereSummon3 = 59512; // 1x 31687
public const uint FlameSphereSpawnEffect = 55891;
public const uint FlameSphereVisual = 55928;
public const uint FlameSpherePeriodic = 55926;
public const uint FlameSphereDeathEffect = 55947;
public const uint EmbraceOfTheVampyr = 55959;
public const uint Vanish = 55964;
public const uint BeamVisual = 60342;
public const uint HoverFall = 60425;
}
struct CreatureIds
{
public const uint FlameSphere1 = 30106;
public const uint FlameSphere2 = 31686;
public const uint FlameSphere3 = 31687;
}
struct TextIds
{
public const uint Say1 = 0;
public const uint SayWarning = 1;
public const uint SayAggro = 2;
public const uint SaySlay = 3;
public const uint SayDeath = 4;
public const uint SayFeed = 5;
public const uint SayVanish = 6;
}
struct Misc
{
public const uint EventConjureFlameSpheres = 1;
public const uint EventBloodthirst = 2;
public const uint EventVanish = 3;
public const uint EventJustVanished = 4;
public const uint EventVanished = 5;
public const uint EventFeeding = 6;
// Flame Sphere
public const uint EventStartMove = 7;
public const uint EventDespawn = 8;
public const uint DataEmbraceDmg = 20000;
public const uint DataEmbraceDmgH = 40000;
public const float DataSphereDistance = 25.0f;
public const float DataSphereAngleOffset = MathFunctions.PI / 2;
public const float DataGroundPositionZ = 11.30809f;
}
[Script]
class boss_prince_taldaram : CreatureScript
{
public boss_prince_taldaram() : base("boss_prince_taldaram") { }
public class boss_prince_taldaramAI : BossAI
{
public boss_prince_taldaramAI(Creature creature) : base(creature, DataTypes.PrinceTaldaram)
{
me.SetDisableGravity(true);
_embraceTakenDamage = 0;
}
public override void Reset()
{
_Reset();
_flameSphereTargetGUID.Clear();
_embraceTargetGUID.Clear();
_embraceTakenDamage = 0;
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
_events.ScheduleEvent(Misc.EventBloodthirst, 10000);
_events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000));
_events.ScheduleEvent(Misc.EventConjureFlameSpheres, 5000);
}
public override void JustSummoned(Creature summon)
{
base.JustSummoned(summon);
switch (summon.GetEntry())
{
case CreatureIds.FlameSphere1:
case CreatureIds.FlameSphere2:
case CreatureIds.FlameSphere3:
summon.GetAI().SetGUID(_flameSphereTargetGUID);
break;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventBloodthirst:
DoCast(me, SpellIds.Bloodthirst);
_events.ScheduleEvent(Misc.EventBloodthirst, 10000);
break;
case Misc.EventConjureFlameSpheres:
// random target?
Unit victim = me.GetVictim();
if (victim)
{
_flameSphereTargetGUID = victim.GetGUID();
DoCast(victim, SpellIds.ConjureFlameSphere);
}
_events.ScheduleEvent(Misc.EventConjureFlameSpheres, 15000);
break;
case Misc.EventVanish:
{
var players = me.GetMap().GetPlayers();
uint targets = 0;
foreach (var player in players)
{
if (player && player.IsAlive())
++targets;
}
if (targets > 2)
{
Talk(TextIds.SayVanish);
DoCast(me, SpellIds.Vanish);
me.SetInCombatState(true); // Prevents the boss from resetting
_events.DelayEvents(500);
_events.ScheduleEvent(Misc.EventJustVanished, 500);
Unit embraceTarget = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (embraceTarget)
_embraceTargetGUID = embraceTarget.GetGUID();
}
_events.ScheduleEvent(Misc.EventVanish, RandomHelper.URand(25000, 35000));
break;
}
case Misc.EventJustVanished:
{
Unit embraceTarget = GetEmbraceTarget();
if (embraceTarget)
{
me.GetMotionMaster().Clear();
me.SetSpeedRate(UnitMoveType.Walk, 2.0f);
me.GetMotionMaster().MoveChase(embraceTarget);
}
_events.ScheduleEvent(Misc.EventVanished, 1300);
}
break;
case Misc.EventVanished:
{
Unit embraceTarget = GetEmbraceTarget();
if (embraceTarget)
DoCast(embraceTarget, SpellIds.EmbraceOfTheVampyr);
Talk(TextIds.SayFeed);
me.GetMotionMaster().Clear();
me.SetSpeedRate(UnitMoveType.Walk, 1.0f);
me.GetMotionMaster().MoveChase(me.GetVictim());
_events.ScheduleEvent(Misc.EventFeeding, 20000);
}
break;
case Misc.EventFeeding:
_embraceTargetGUID.Clear();
break;
default:
break;
}
});
DoMeleeAttackIfReady();
}
public override void DamageTaken(Unit doneBy, ref uint damage)
{
Unit embraceTarget = GetEmbraceTarget();
if (embraceTarget && embraceTarget.IsAlive())
{
_embraceTakenDamage += damage;
if (_embraceTakenDamage > DungeonMode<uint>(Misc.DataEmbraceDmg, Misc.DataEmbraceDmgH))
{
_embraceTargetGUID.Clear();
me.CastStop();
}
}
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
_JustDied();
}
public override void KilledUnit(Unit victim)
{
if (!victim.IsTypeId(TypeId.Player))
return;
if (victim.GetGUID() == _embraceTargetGUID)
_embraceTargetGUID.Clear();
Talk(TextIds.SaySlay);
}
public bool CheckSpheres()
{
for (byte i = 0; i < 2; ++i)
{
if (instance.GetData(DataTypes.Sphere1 + i) == 0)
return false;
}
RemovePrison();
return true;
}
Unit GetEmbraceTarget()
{
if (!_embraceTargetGUID.IsEmpty())
return Global.ObjAccessor.GetUnit(me, _embraceTargetGUID);
return null;
}
void RemovePrison()
{
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
me.RemoveAurasDueToSpell(SpellIds.BeamVisual);
me.SetHomePosition(me.GetPositionX(), me.GetPositionY(), Misc.DataGroundPositionZ, me.GetOrientation());
DoCast(SpellIds.HoverFall);
me.SetDisableGravity(false);
me.GetMotionMaster().MoveLand(0, me.GetHomePosition());
Talk(TextIds.SayWarning);
instance.HandleGameObject(instance.GetGuidData(DataTypes.PrinceTaldaramPlatform), true);
}
ObjectGuid _flameSphereTargetGUID;
ObjectGuid _embraceTargetGUID;
uint _embraceTakenDamage;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_prince_taldaramAI>(creature);
}
}
[Script] // 30106, 31686, 31687 - Flame Sphere
class npc_prince_taldaram_flame_sphere : CreatureScript
{
public npc_prince_taldaram_flame_sphere() : base("npc_prince_taldaram_flame_sphere") { }
class npc_prince_taldaram_flame_sphereAI : ScriptedAI
{
public npc_prince_taldaram_flame_sphereAI(Creature creature) : base(creature)
{
}
public override void Reset()
{
DoCast(me, SpellIds.FlameSphereSpawnEffect, true);
DoCast(me, SpellIds.FlameSphereVisual, true);
_flameSphereTargetGUID.Clear();
_events.Reset();
_events.ScheduleEvent(Misc.EventStartMove, 3 * Time.InMilliseconds);
_events.ScheduleEvent(Misc.EventDespawn, 13 * Time.InMilliseconds);
}
public override void SetGUID(ObjectGuid guid, int id = 0)
{
_flameSphereTargetGUID = guid;
}
public override void EnterCombat(Unit who) { }
public override void MoveInLineOfSight(Unit who) { }
public override void UpdateAI(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventStartMove:
{
DoCast(me, SpellIds.FlameSpherePeriodic, true);
/// @todo: find correct values
float angleOffset = 0.0f;
float distOffset = Misc.DataSphereDistance;
switch (me.GetEntry())
{
case CreatureIds.FlameSphere1:
break;
case CreatureIds.FlameSphere2:
angleOffset = Misc.DataSphereAngleOffset;
break;
case CreatureIds.FlameSphere3:
angleOffset = -Misc.DataSphereAngleOffset;
break;
default:
return;
}
Unit sphereTarget = Global.ObjAccessor.GetUnit(me, _flameSphereTargetGUID);
if (!sphereTarget)
return;
float angle = me.GetAngle(sphereTarget) + angleOffset;
float x = me.GetPositionX() + distOffset * (float)Math.Cos(angle);
float y = me.GetPositionY() + distOffset * (float)Math.Sin(angle);
/// @todo: correct speed
me.GetMotionMaster().MovePoint(0, x, y, me.GetPositionZ());
break;
}
case Misc.EventDespawn:
DoCast(me, SpellIds.FlameSphereDeathEffect, true);
me.DespawnOrUnsummon(1000);
break;
default:
break;
}
});
}
ObjectGuid _flameSphereTargetGUID;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_prince_taldaram_flame_sphereAI(creature);
}
}
[Script] // 193093, 193094 - Ancient Nerubian Device
class go_prince_taldaram_sphere : GameObjectScript
{
public go_prince_taldaram_sphere() : base("go_prince_taldaram_sphere") { }
public override bool OnGossipHello(Player player, GameObject go)
{
InstanceScript instance = go.GetInstanceScript();
if (instance == null)
return false;
Creature PrinceTaldaram = ObjectAccessor.GetCreature(go, instance.GetGuidData(DataTypes.PrinceTaldaram));
if (PrinceTaldaram && PrinceTaldaram.IsAlive())
{
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
go.SetGoState(GameObjectState.Active);
switch (go.GetEntry())
{
case GameObjectIds.Sphere1:
instance.SetData(DataTypes.Sphere1, (uint)EncounterState.InProgress);
PrinceTaldaram.GetAI().Talk(TextIds.Say1);
break;
case GameObjectIds.Sphere2:
instance.SetData(DataTypes.Sphere2, (uint)EncounterState.InProgress);
PrinceTaldaram.GetAI().Talk(TextIds.Say1);
break;
}
PrinceTaldaram.GetAI<boss_prince_taldaram.boss_prince_taldaramAI>().CheckSpheres();
}
return true;
}
}
[Script] // 55931 - Conjure Flame Sphere
class spell_prince_taldaram_conjure_flame_sphere : SpellScriptLoader
{
public spell_prince_taldaram_conjure_flame_sphere() : base("spell_prince_taldaram_conjure_flame_sphere") { }
class spell_prince_taldaram_conjure_flame_sphere_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.FlameSphereSummon1, SpellIds.FlameSphereSummon2, SpellIds.FlameSphereSummon3);
}
void HandleScript(uint effIndex)
{
Unit caster = GetCaster();
caster.CastSpell(caster, SpellIds.FlameSphereSummon1, true);
if (caster.GetMap().IsHeroic())
{
caster.CastSpell(caster, SpellIds.FlameSphereSummon2, true);
caster.CastSpell(caster, SpellIds.FlameSphereSummon3, true);
}
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy));
}
}
public override SpellScript GetSpellScript()
{
return new spell_prince_taldaram_conjure_flame_sphere_SpellScript();
}
}
[Script] // 55895, 59511, 59512 - Flame Sphere Summon
class spell_prince_taldaram_flame_sphere_summon : SpellScriptLoader
{
public spell_prince_taldaram_flame_sphere_summon() : base("spell_prince_taldaram_flame_sphere_summon") { }
class spell_prince_taldaram_flame_sphere_summon_SpellScript : SpellScript
{
void SetDest(ref SpellDestination dest)
{
dest.RelocateOffset(new Position(0.0f, 0.0f, 5.5f, 0.0f));
}
public override void Register()
{
OnDestinationTargetSelect.Add(new DestinationTargetSelectHandler(SetDest, 0, Targets.DestCaster));
}
}
public override SpellScript GetSpellScript()
{
return new spell_prince_taldaram_flame_sphere_summon_SpellScript();
}
}
}
@@ -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.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet
{
[Script]
class instance_ahnkahet : InstanceMapScript
{
public instance_ahnkahet() : base("instance_ahnkahet", 619) { }
class instance_ahnkahet_InstanceScript : InstanceScript
{
public instance_ahnkahet_InstanceScript(Map map) : base(map)
{
SetHeaders("AK");
SetBossNumber(DataTypes.HeraldVolazj + 1);
LoadDoorData(new DoorData(GameObjectIds.PrinceTaldaramGate, DataTypes.PrinceTaldaram, DoorType.Passage));
SwitchTrigger = 0;
SpheresState[0] = 0;
SpheresState[1] = 0;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case AKCreatureIds.ElderNadox:
ElderNadoxGUID = creature.GetGUID();
break;
case AKCreatureIds.PrinceTaldaram:
PrinceTaldaramGUID = creature.GetGUID();
break;
case AKCreatureIds.JedogaShadowseeker:
JedogaShadowseekerGUID = creature.GetGUID();
break;
case AKCreatureIds.Amanitar:
AmanitarGUID = creature.GetGUID();
break;
case AKCreatureIds.HeraldVolazj:
HeraldVolazjGUID = creature.GetGUID();
break;
case AKCreatureIds.Initiand:
InitiandGUIDs.Add(creature.GetGUID());
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.PrinceTaldaramPlatform:
PrinceTaldaramPlatformGUID = go.GetGUID();
if (GetBossState(DataTypes.PrinceTaldaram) == EncounterState.Done)
HandleGameObject(ObjectGuid.Empty, true, go);
break;
case GameObjectIds.Sphere1:
if (SpheresState[0] != 0)
{
go.SetGoState(GameObjectState.Active);
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
else
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
break;
case GameObjectIds.Sphere2:
if (SpheresState[1] != 0)
{
go.SetGoState(GameObjectState.Active);
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
else
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
break;
case GameObjectIds.PrinceTaldaramGate:
AddDoor(go, true);
break;
default:
break;
}
}
public override void OnGameObjectRemove(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.PrinceTaldaramGate:
AddDoor(go, false);
break;
default:
break;
}
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case DataTypes.Sphere1:
case DataTypes.Sphere2:
SpheresState[type - DataTypes.Sphere1] = data;
break;
case DataTypes.JedogaTriggerSwitch:
SwitchTrigger = (byte)data;
break;
case DataTypes.JedogaResetInitiands:
foreach (ObjectGuid guid in InitiandGUIDs)
{
Creature creature = instance.GetCreature(guid);
if (creature)
{
creature.Respawn();
if (!creature.IsInEvadeMode())
creature.GetAI().EnterEvadeMode();
}
}
break;
default:
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case DataTypes.Sphere1:
case DataTypes.Sphere2:
return SpheresState[type - DataTypes.Sphere1];
case DataTypes.AllInitiandDead:
foreach (ObjectGuid guid in InitiandGUIDs)
{
Creature cr = instance.GetCreature(guid);
if (!cr || cr.IsAlive())
return 0;
}
return 1;
case DataTypes.JedogaTriggerSwitch:
return SwitchTrigger;
default:
break;
}
return 0;
}
public override void SetGuidData(uint type, ObjectGuid data)
{
switch (type)
{
case DataTypes.AddJedogaVictim:
JedogaSacrifices = data;
break;
case DataTypes.PlJedogaTarget:
JedogaTarget = data;
break;
default:
break;
}
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataTypes.ElderNadox:
return ElderNadoxGUID;
case DataTypes.PrinceTaldaram:
return PrinceTaldaramGUID;
case DataTypes.JedogaShadowseeker:
return JedogaShadowseekerGUID;
case DataTypes.Amanitar:
return AmanitarGUID;
case DataTypes.HeraldVolazj:
return HeraldVolazjGUID;
case DataTypes.PrinceTaldaramPlatform:
return PrinceTaldaramPlatformGUID;
case DataTypes.AddJedogaInitiand:
{
List<ObjectGuid> vInitiands = new List<ObjectGuid>();
foreach (ObjectGuid guid in InitiandGUIDs)
{
Creature cr = instance.GetCreature(guid);
if (cr && cr.IsAlive())
vInitiands.Add(guid);
}
if (vInitiands.Empty())
return ObjectGuid.Empty;
return vInitiands.PickRandom();
}
case DataTypes.AddJedogaVictim:
return JedogaSacrifices;
case DataTypes.PlJedogaTarget:
return JedogaTarget;
default:
break;
}
return ObjectGuid.Empty;
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case DataTypes.JedogaShadowseeker:
if (state == EncounterState.Done)
{
foreach (ObjectGuid guid in InitiandGUIDs)
{
Creature cr = instance.GetCreature(guid);
if (cr)
cr.DespawnOrUnsummon();
}
}
break;
default:
break;
}
return true;
}
void WriteSaveDataMore(string data)
{
data += SpheresState[0] + ' ' + SpheresState[1];
}
void ReadSaveDataMore(string data)
{
data += SpheresState[0];
data += SpheresState[1];
}
ObjectGuid ElderNadoxGUID;
ObjectGuid PrinceTaldaramGUID;
ObjectGuid JedogaShadowseekerGUID;
ObjectGuid AmanitarGUID;
ObjectGuid HeraldVolazjGUID;
ObjectGuid PrinceTaldaramPlatformGUID;
ObjectGuid JedogaSacrifices;
ObjectGuid JedogaTarget;
List<ObjectGuid> InitiandGUIDs = new List<ObjectGuid>();
uint[] SpheresState = new uint[2];
byte SwitchTrigger;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_ahnkahet_InstanceScript(map);
}
}
struct DataTypes
{
// Encounter States/Boss GUIDs
public const uint ElderNadox = 0;
public const uint PrinceTaldaram = 1;
public const uint JedogaShadowseeker = 2;
public const uint Amanitar = 3;
public const uint HeraldVolazj = 4;
// Additional Data
public const uint Sphere1 = 5;
public const uint Sphere2 = 6;
public const uint PrinceTaldaramPlatform = 7;
public const uint PlJedogaTarget = 8;
public const uint AddJedogaVictim = 9;
public const uint AddJedogaInitiand = 10;
public const uint JedogaTriggerSwitch = 11;
public const uint JedogaResetInitiands = 12;
public const uint AllInitiandDead = 13;
}
struct AKCreatureIds
{
public const uint ElderNadox = 29309;
public const uint PrinceTaldaram = 29308;
public const uint JedogaShadowseeker = 29310;
public const uint Amanitar = 30258;
public const uint HeraldVolazj = 29311;
// Elder Nadox
public const uint AhnkaharGuardian = 30176;
public const uint AhnkaharSwarmer = 30178;
// Jedoga Shadowseeker
public const uint Initiand = 30114;
public const uint JedogaController = 30181;
// Herald Volazj
//public const uint TwistedVisage1 = 30621,
//public const uint TwistedVisage2 = 30622,
//public const uint TwistedVisage3 = 30623,
//public const uint TwistedVisage4 = 30624,
public const uint TwistedVisage = 30625;
}
struct GameObjectIds
{
public const uint PrinceTaldaramGate = 192236;
public const uint PrinceTaldaramPlatform = 193564;
public const uint Sphere1 = 193093;
public const uint Sphere2 = 193094;
}
}
@@ -0,0 +1,722 @@
/*
* 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;
using System.Linq;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.Anubarak
{
struct SpellIds
{
public const uint Emerge = 53500;
public const uint Submerge = 53421;
public const uint ImpaleAura = 53456;
public const uint ImpaleVisual = 53455;
public const uint ImpaleDamage = 53454;
public const uint LeechingSwarm = 53467;
public const uint Pound = 59433;
public const uint PoundDamage = 59432;
public const uint CarrionBeetles = 53520;
public const uint CarrionBeetle = 53521;
public const uint SummonDarter = 53599;
public const uint SummonAssassin = 53609;
public const uint SummonGuardian = 53614;
public const uint SummonVenomancer = 53615;
public const uint Dart = 59349;
public const uint Backstab = 52540;
public const uint AssassinVisual = 53611;
public const uint SunderArmor = 53618;
public const uint PoisonBolt = 53617;
}
struct CreatureIds
{
public const uint WorldTrigger = 22515;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SayLocust = 3;
public const uint SaySubmerge = 4;
public const uint SayIntro = 5;
}
struct EventIds
{
public const uint Pound = 1;
public const uint Impale = 2;
public const uint LeechingSwarm = 3;
public const uint CarrionBeetles = 4;
public const uint Submerge = 5; // Use Event For This So We Don'T Submerge Mid-Cast
public const uint Darter = 6;
public const uint Assassin = 7;
public const uint Guardian = 8;
public const uint Venomancer = 9;
public const uint CloseDoor = 10;
}
struct Misc
{
public const uint AchievGottaGoStartEvent = 20381;
public const byte PhaseEmerge = 1;
public const byte PhaseSubmerge = 2;
public const int GuidTypePet = 0;
public const int GuidTypeImpale = 1;
public const byte SummonGroupWorldTriggerGuardian = 1;
public const int ActionPetDied = 1;
public const int ActionPetEvade = 2;
}
[Script]
class boss_anub_arak : CreatureScript
{
public boss_anub_arak() : base("boss_anub_arak") { }
class boss_anub_arakAI : BossAI
{
public boss_anub_arakAI(Creature creature) : base(creature, ANDataTypes.Anubarak) { }
public override void Reset()
{
base.Reset();
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
_nextSubmerge = 75;
_petCount = 0;
}
public override void EnterCombat(Unit who)
{
base.EnterCombat(who);
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
if (door)
door.SetGoState(GameObjectState.Active); // open door for now
Talk(TextIds.SayAggro);
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
_events.SetPhase(Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CloseDoor, TimeSpan.FromSeconds(5));
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(17), 0, Misc.PhaseEmerge);
// set up world triggers
List<TempSummon> summoned;
me.SummonCreatureGroup(Misc.SummonGroupWorldTriggerGuardian, out summoned);
if (summoned.Empty()) // something went wrong
{
EnterEvadeMode(EvadeReason.Other);
return;
}
_guardianTrigger = summoned.First().GetGUID();
Creature trigger = DoSummon(CreatureIds.WorldTrigger, me.GetPosition(), 0u, TempSummonType.ManualDespawn);
if (trigger)
_assassinTrigger = trigger.GetGUID();
else
{
EnterEvadeMode(EvadeReason.Other);
return;
}
}
public override void EnterEvadeMode(EvadeReason why)
{
summons.DespawnAll();
_DespawnAtEvade();
}
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.CloseDoor:
GameObject door = instance.GetGameObject(ANDataTypes.AnubarakWall);
if (door)
door.SetGoState(GameObjectState.Ready);
break;
case EventIds.Pound:
DoCastVictim(SpellIds.Pound);
_events.Repeat(TimeSpan.FromSeconds(26), TimeSpan.FromSeconds(32));
break;
case EventIds.LeechingSwarm:
Talk(TextIds.SayLocust);
DoCastAOE(SpellIds.LeechingSwarm);
_events.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(28));
break;
case EventIds.CarrionBeetles:
DoCastAOE(SpellIds.CarrionBeetles);
_events.Repeat(TimeSpan.FromSeconds(24), TimeSpan.FromSeconds(27));
break;
case EventIds.Impale:
Creature impaleTarget = ObjectAccessor.GetCreature(me, _impaleTarget);
if (impaleTarget)
DoCast(impaleTarget, SpellIds.ImpaleDamage, true);
break;
case EventIds.Submerge:
Talk(TextIds.SaySubmerge);
DoCastSelf(SpellIds.Submerge);
break;
case EventIds.Darter:
{
List<Creature> triggers = new List<Creature>();
me.GetCreatureListWithEntryInGrid(triggers, CreatureIds.WorldTrigger);
if (!triggers.Empty())
{
var it = triggers.PickRandom();
it.CastSpell(it, SpellIds.SummonDarter, true);
_events.Repeat(TimeSpan.FromSeconds(11));
}
else
EnterEvadeMode(EvadeReason.Other);
break;
}
case EventIds.Assassin:
{
Creature trigger = ObjectAccessor.GetCreature(me, _assassinTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
trigger.CastSpell(trigger, SpellIds.SummonAssassin, true);
if (_assassinCount > 2)
{
_assassinCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_assassinCount = 0;
}
else // something went wrong
EnterEvadeMode(EvadeReason.Other);
break;
}
case EventIds.Guardian:
{
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
trigger.CastSpell(trigger, SpellIds.SummonGuardian, true);
if (_guardianCount > 2)
{
_guardianCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_guardianCount = 0;
}
else
EnterEvadeMode(EvadeReason.Other);
}
break;
case EventIds.Venomancer:
{
Creature trigger = ObjectAccessor.GetCreature(me, _guardianTrigger);
if (trigger)
{
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
trigger.CastSpell(trigger, SpellIds.SummonVenomancer, true);
if (_venomancerCount > 2)
{
_venomancerCount -= 2;
_events.Repeat(TimeSpan.FromSeconds(20));
}
else
_venomancerCount = 0;
}
else
EnterEvadeMode(EvadeReason.Other);
}
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void KilledUnit(Unit victim)
{
if (victim.IsTypeId(TypeId.Player))
Talk(TextIds.SaySlay);
}
public override void SetGUID(ObjectGuid guid, int type)
{
switch (type)
{
case Misc.GuidTypePet:
{
Creature creature = ObjectAccessor.GetCreature(me, guid);
if (creature)
JustSummoned(creature);
else // something has gone horribly wrong
EnterEvadeMode(EvadeReason.Other);
break;
}
case Misc.GuidTypeImpale:
_impaleTarget = guid;
_events.ScheduleEvent(EventIds.Impale, TimeSpan.FromSeconds(4));
break;
}
}
public override void DoAction(int action)
{
switch (action)
{
case Misc.ActionPetDied:
if (_petCount == 0) // underflow check - something has gone horribly wrong
{
EnterEvadeMode(EvadeReason.Other);
return;
}
if (--_petCount == 0) // last pet died, emerge
{
me.RemoveAurasDueToSpell(SpellIds.Submerge);
me.RemoveAurasDueToSpell(SpellIds.ImpaleAura);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
DoCastSelf(SpellIds.Emerge);
_events.SetPhase(Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.Pound, TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.LeechingSwarm, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7), 0, Misc.PhaseEmerge);
_events.ScheduleEvent(EventIds.CarrionBeetles, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), 0, Misc.PhaseEmerge);
}
break;
case Misc.ActionPetEvade:
EnterEvadeMode(EvadeReason.Other);
break;
}
}
public override void DamageTaken(Unit source, ref uint damage)
{
if (me.HasAura(SpellIds.Submerge))
damage = 0;
else
if (_nextSubmerge != 0 && me.HealthBelowPctDamaged((int)_nextSubmerge, damage))
{
_events.CancelEvent(EventIds.Submerge);
_events.ScheduleEvent(EventIds.Submerge, 0, 0, Misc.PhaseEmerge);
_nextSubmerge = _nextSubmerge - 25;
}
}
public override void SpellHit(Unit whose, SpellInfo spell)
{
if (spell.Id == SpellIds.Submerge)
{
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
me.RemoveAurasDueToSpell(SpellIds.LeechingSwarm);
DoCastSelf(SpellIds.ImpaleAura, true);
_events.SetPhase(Misc.PhaseSubmerge);
switch (_nextSubmerge)
{
case 50: // first submerge phase
_assassinCount = 4;
_guardianCount = 2;
_venomancerCount = 0;
break;
case 25: // second submerge phase
_assassinCount = 6;
_guardianCount = 2;
_venomancerCount = 2;
break;
case 0: // third submerge phase
_assassinCount = 6;
_guardianCount = 2;
_venomancerCount = 2;
_events.ScheduleEvent(EventIds.Darter, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
break;
}
_petCount = (uint)(_guardianCount + _venomancerCount);
if (_assassinCount != 0)
_events.ScheduleEvent(EventIds.Assassin, TimeSpan.FromSeconds(0), 0, Misc.PhaseSubmerge);
if (_guardianCount != 0)
_events.ScheduleEvent(EventIds.Guardian, TimeSpan.FromSeconds(4), 0, Misc.PhaseSubmerge);
if (_venomancerCount != 0)
_events.ScheduleEvent(EventIds.Venomancer, TimeSpan.FromSeconds(20), 0, Misc.PhaseSubmerge);
}
}
ObjectGuid _impaleTarget;
uint _nextSubmerge;
uint _petCount;
ObjectGuid _guardianTrigger;
ObjectGuid _assassinTrigger;
byte _assassinCount;
byte _guardianCount;
byte _venomancerCount;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_anub_arakAI>(creature);
}
}
[Script]
class npc_anubarak_pet_template : ScriptedAI
{
public npc_anubarak_pet_template(Creature creature, bool isLarge) : base(creature)
{
_instance = creature.GetInstanceScript();
_isLarge = isLarge;
}
public override void InitializeAI()
{
base.InitializeAI();
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypePet);
else
me.DespawnOrUnsummon();
}
public override void JustDied(Unit killer)
{
base.JustDied(killer);
if (_isLarge)
{
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().DoAction(Misc.ActionPetDied);
}
}
public override void EnterEvadeMode(EvadeReason why)
{
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
anubarak.GetAI().DoAction(Misc.ActionPetEvade);
else
me.DespawnOrUnsummon();
}
protected InstanceScript _instance;
bool _isLarge;
}
[Script]
class npc_anubarak_anub_ar_darter : CreatureScript
{
public npc_anubarak_anub_ar_darter() : base("npc_anubarak_anub_ar_darter") { }
class npc_anubarak_anub_ar_darterAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_darterAI(Creature creature) : base(creature, false) { }
public override void InitializeAI()
{
base.InitializeAI();
DoCastAOE(SpellIds.Dart);
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_darterAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_assassin : CreatureScript
{
public npc_anubarak_anub_ar_assassin() : base("npc_anubarak_anub_ar_assassin") { }
class npc_anubarak_anub_ar_assassinAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_assassinAI(Creature creature) : base(creature, false)
{
_backstabTimer = 6 * Time.InMilliseconds;
}
bool IsInBounds(Position jumpTo, List<AreaBoundary> boundary)
{
if (boundary == null)
return true;
foreach (var it in boundary)
if (!it.IsWithinBoundary(jumpTo))
return false;
return true;
}
Position GetRandomPositionAround(Creature anubarak)
{
float DISTANCE_MIN = 10.0f;
float DISTANCE_MAX = 30.0f;
double angle = RandomHelper.NextDouble() * 2.0 * Math.PI;
return new Position(anubarak.GetPositionX() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Sin(angle)), anubarak.GetPositionY() + (float)(RandomHelper.FRand(DISTANCE_MIN, DISTANCE_MAX) * Math.Cos(angle)), anubarak.GetPositionZ());
}
public override void InitializeAI()
{
base.InitializeAI();
var boundary = _instance.GetBossBoundary(ANDataTypes.Anubarak);
Creature anubarak = _instance.GetCreature(ANDataTypes.Anubarak);
if (anubarak)
{
Position jumpTo;
do
jumpTo = GetRandomPositionAround(anubarak);
while (!IsInBounds(jumpTo, boundary));
me.GetMotionMaster().MoveJump(jumpTo, 40.0f, 40.0f);
DoCastSelf(SpellIds.AssassinVisual, true);
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _backstabTimer)
{
if (me.GetVictim() && me.GetVictim().isInBack(me))
DoCastVictim(SpellIds.Backstab);
_backstabTimer = 6 * Time.InMilliseconds;
}
else
_backstabTimer -= diff;
DoMeleeAttackIfReady();
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (id == EventId.Jump)
{
me.RemoveAurasDueToSpell(SpellIds.AssassinVisual);
DoZoneInCombat();
}
}
uint _backstabTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_assassinAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_guardian : CreatureScript
{
public npc_anubarak_anub_ar_guardian() : base("npc_anubarak_anub_ar_guardian") { }
class npc_anubarak_anub_ar_guardianAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_guardianAI(Creature creature) : base(creature, true)
{
_sunderTimer = 6 * Time.InMilliseconds;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _sunderTimer)
{
DoCastVictim(SpellIds.SunderArmor);
_sunderTimer = 12 * Time.InMilliseconds;
}
else
_sunderTimer -= diff;
DoMeleeAttackIfReady();
}
uint _sunderTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_guardianAI>(creature);
}
}
[Script]
class npc_anubarak_anub_ar_venomancer : CreatureScript
{
public npc_anubarak_anub_ar_venomancer() : base("npc_anubarak_anub_ar_venomancer") { }
class npc_anubarak_anub_ar_venomancerAI : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_venomancerAI(Creature creature) : base(creature, true)
{
_boltTimer = 5 * Time.InMilliseconds;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (diff >= _boltTimer)
{
DoCastVictim(SpellIds.PoisonBolt);
_boltTimer = RandomHelper.URand(2, 3) * Time.InMilliseconds;
}
else
_boltTimer -= diff;
DoMeleeAttackIfReady();
}
uint _boltTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_anub_ar_venomancerAI>(creature);
}
}
[Script]
class npc_anubarak_impale_target : CreatureScript
{
public npc_anubarak_impale_target() : base("npc_anubarak_impale_target") { }
class npc_anubarak_impale_targetAI : NullCreatureAI
{
public npc_anubarak_impale_targetAI(Creature creature) : base(creature) { }
public override void InitializeAI()
{
Creature anubarak = me.GetInstanceScript().GetCreature(ANDataTypes.Anubarak);
if (anubarak)
{
DoCastSelf(SpellIds.ImpaleVisual);
me.DespawnOrUnsummon(TimeSpan.FromSeconds(6));
anubarak.GetAI().SetGUID(me.GetGUID(), Misc.GuidTypeImpale);
}
else
me.DespawnOrUnsummon();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_anubarak_impale_targetAI>(creature);
}
}
[Script]
class spell_anubarak_pound : SpellScriptLoader
{
public spell_anubarak_pound() : base("spell_anubarak_pound") { }
class spell_anubarak_pound_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.PoundDamage);
}
void HandleDummy(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
GetCaster().CastSpell(target, SpellIds.PoundDamage, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ApplyAura));
}
}
public override SpellScript GetSpellScript()
{
return new spell_anubarak_pound_SpellScript();
}
}
[Script]
class spell_anubarak_carrion_beetles : SpellScriptLoader
{
public spell_anubarak_carrion_beetles() : base("spell_anubarak_carrion_beetles") { }
class spell_anubarak_carrion_beetles_AuraScript : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.CarrionBeetle);
}
void HandlePeriodic(AuraEffect eff)
{
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
GetCaster().CastSpell(GetCaster(), SpellIds.CarrionBeetle, true);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
}
}
public override AuraScript GetAuraScript()
{
return new spell_anubarak_carrion_beetles_AuraScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,131 @@
/*
* 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.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub
{
[Script]
class instance_azjol_nerub : InstanceMapScript
{
public instance_azjol_nerub() : base(nameof(instance_azjol_nerub), 601) { }
class instance_azjol_nerub_InstanceScript : InstanceScript
{
public instance_azjol_nerub_InstanceScript(Map map) : base(map)
{
SetHeaders(ANInstanceMisc.DataHeader);
SetBossNumber(ANInstanceMisc.EncounterCount);
LoadBossBoundaries(ANInstanceMisc.boundaries);
LoadDoorData(ANInstanceMisc.doorData);
LoadObjectData(ANInstanceMisc.creatureData, ANInstanceMisc.gameobjectData);
}
public override void OnUnitDeath(Unit who)
{
base.OnUnitDeath(who);
Creature creature = who.ToCreature();
if (!creature || creature.IsCritter() || creature.IsControlledByPlayer())
return;
Creature gatewatcher = GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (gatewatcher)
gatewatcher.GetAI().DoAction(-ANInstanceMisc.ActionGatewatcherGreet);
}
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_azjol_nerub_InstanceScript(map);
}
}
struct ANDataTypes
{
// Encounter States/Boss Guids
public const uint KrikthirTheGatewatcher = 0;
public const uint Hadronox = 1;
public const uint Anubarak = 2;
// Additional Data
public const uint WatcherNarjil = 3;
public const uint WatcherGashra = 4;
public const uint WatcherSilthik = 5;
public const uint AnubarakWall = 6;
}
struct ANCreatureIds
{
public const uint Krikthir = 28684;
public const uint Hadronox = 28921;
public const uint Anubarak = 29120;
public const uint WatcherNarjil = 28729;
public const uint WatcherGashra = 28730;
public const uint WatcherSilthik = 28731;
}
struct ANGameObjectIds
{
public const uint KrikthirDoor = 192395;
public const uint AnubarakDoor1 = 192396;
public const uint AnubarakDoor2 = 192397;
public const uint AnubarakDoor3 = 192398;
}
// These are passed as -action to AI's DoAction to differentiate between them and boss scripts' own actions
struct ANInstanceMisc
{
public const string DataHeader = "AN";
public const uint EncounterCount = 3;
public const int ActionGatewatcherGreet = 1;
public static DoorData[] doorData =
{
new DoorData(ANGameObjectIds.KrikthirDoor, ANDataTypes.KrikthirTheGatewatcher, DoorType.Passage),
new DoorData(ANGameObjectIds.AnubarakDoor1, ANDataTypes.Anubarak, DoorType.Room ),
new DoorData(ANGameObjectIds.AnubarakDoor2, ANDataTypes.Anubarak, DoorType.Room ),
new DoorData(ANGameObjectIds.AnubarakDoor3, ANDataTypes.Anubarak, DoorType.Room )
};
public static ObjectData[] creatureData =
{
new ObjectData(ANCreatureIds.Krikthir, ANDataTypes.KrikthirTheGatewatcher ),
new ObjectData(ANCreatureIds.Hadronox, ANDataTypes.Hadronox ),
new ObjectData(ANCreatureIds.Anubarak, ANDataTypes.Anubarak ),
new ObjectData(ANCreatureIds.WatcherNarjil, ANDataTypes.WatcherGashra ),
new ObjectData(ANCreatureIds.WatcherGashra, ANDataTypes.WatcherSilthik ),
new ObjectData(ANCreatureIds.WatcherSilthik, ANDataTypes.WatcherNarjil )
};
public static ObjectData[] gameobjectData =
{
new ObjectData(ANGameObjectIds.AnubarakDoor3, ANDataTypes.AnubarakWall)
};
public static BossBoundaryEntry[] boundaries =
{
new BossBoundaryEntry(ANDataTypes.KrikthirTheGatewatcher, new RectangleBoundary(400.0f, 580.0f, 623.5f, 810.0f)),
new BossBoundaryEntry(ANDataTypes.Hadronox, new ZRangeBoundary(666.0f, 776.0f)),
new BossBoundaryEntry(ANDataTypes.Anubarak, new CircleBoundary(new Position(550.6178f, 253.5917f), 26.0f))
};
}
}
@@ -0,0 +1,729 @@
/*
* 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 Framework.Dynamic;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheChampion
{
struct TrialOfChampionSpells
{
//Vehicle
public const uint CHARGE = 63010;
public const uint SHIELD_BREAKER = 68504;
public const uint SHIELD = 66482;
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
public const uint MORTAL_STRIKE = 68783;
public const uint MORTAL_STRIKE_H = 68784;
public const uint BLADESTORM = 63784;
public const uint INTERCEPT = 67540;
public const uint ROLLING_THROW = 47115; //not implemented in the AI yet...
// Ambrose Boltspark && Eressea Dawnsinger || Mage
public const uint FIREBALL = 66042;
public const uint FIREBALL_H = 68310;
public const uint BLAST_WAVE = 66044;
public const uint BLAST_WAVE_H = 68312;
public const uint HASTE = 66045;
public const uint POLYMORPH = 66043;
public const uint POLYMORPH_H = 68311;
// Colosos && Runok Wildmane || Shaman
public const uint CHAIN_LIGHTNING = 67529;
public const uint CHAIN_LIGHTNING_H = 68319;
public const uint EARTH_SHIELD = 67530;
public const uint HEALING_WAVE = 67528;
public const uint HEALING_WAVE_H = 68318;
public const uint HEX_OF_MENDING = 67534;
// Jaelyne Evensong && Zul'tore || Hunter
public const uint DISENGAGE = 68340; //not implemented in the AI yet...
public const uint LIGHTNING_ARROWS = 66083;
public const uint MULTI_SHOT = 66081;
public const uint SHOOT = 65868;
public const uint SHOOT_H = 67988;
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
public const uint EVISCERATE = 67709;
public const uint EVISCERATE_H = 68317;
public const uint FAN_OF_KNIVES = 67706;
public const uint POISON_BOTTLE = 67701;
}
/*
struct Point
{
float x, y, z;
}
const Point MovementPoint[] =
{
{746.84f, 623.15f, 411.41f},
{747.96f, 620.29f, 411.09f},
{750.23f, 618.35f, 411.09f}
}
*/
/*
* Generic AI for vehicles used by npcs in ToC, it needs more improvements. *
* Script Complete: 25%. *
*/
[Script]
class generic_vehicleAI_toc5 : CreatureScript
{
public generic_vehicleAI_toc5() : base("generic_vehicleAI_toc5") { }
class generic_vehicleAI_toc5AI : npc_escortAI
{
public generic_vehicleAI_toc5AI(Creature creature) : base(creature)
{
Initialize();
SetDespawnAtEnd(false);
uiWaypointPath = 0;
instance = creature.GetInstanceScript();
}
void Initialize()
{
uiChargeTimer = 5000;
uiShieldBreakerTimer = 8000;
uiBuffTimer = RandomHelper.URand(30000, 60000);
}
public override void Reset()
{
Initialize();
}
public override void SetData(uint uiType, uint uiData)
{
switch (uiType)
{
case 1:
AddWaypoint(0, 747.36f, 634.07f, 411.572f);
AddWaypoint(1, 780.43f, 607.15f, 411.82f);
AddWaypoint(2, 785.99f, 599.41f, 411.92f);
AddWaypoint(3, 778.44f, 601.64f, 411.79f);
uiWaypointPath = 1;
break;
case 2:
AddWaypoint(0, 747.35f, 634.07f, 411.57f);
AddWaypoint(1, 768.72f, 581.01f, 411.92f);
AddWaypoint(2, 763.55f, 590.52f, 411.71f);
uiWaypointPath = 2;
break;
case 3:
AddWaypoint(0, 747.35f, 634.07f, 411.57f);
AddWaypoint(1, 784.02f, 645.33f, 412.39f);
AddWaypoint(2, 775.67f, 641.91f, 411.91f);
uiWaypointPath = 3;
break;
}
if (uiType <= 3)
Start(false, true);
}
public override void WaypointReached(uint waypointId)
{
switch (waypointId)
{
case 2:
if (uiWaypointPath == 3 || uiWaypointPath == 2)
instance.SetData((uint)Data.DATA_MOVEMENT_DONE, instance.GetData((uint)Data.DATA_MOVEMENT_DONE) + 1);
break;
case 3:
instance.SetData((uint)Data.DATA_MOVEMENT_DONE, instance.GetData((uint)Data.DATA_MOVEMENT_DONE) + 1);
break;
}
}
public override void EnterCombat(Unit who)
{
DoCastSpellShield();
}
void DoCastSpellShield()
{
for (byte i = 0; i < 3; ++i)
DoCast(me, TrialOfChampionSpells.SHIELD, true);
}
public override void UpdateAI(uint uiDiff)
{
base.UpdateAI(uiDiff);
if (!UpdateVictim())
return;
if (uiBuffTimer <= uiDiff)
{
if (!me.HasAura(TrialOfChampionSpells.SHIELD))
DoCastSpellShield();
uiBuffTimer = RandomHelper.URand(30000, 45000);
}
else
uiBuffTimer -= uiDiff;
if (uiChargeTimer <= uiDiff)
{
var players = me.GetMap().GetPlayers();
if (!players.Empty())
{
foreach (var player in players)
{
if (player && !player.IsGameMaster() && me.IsInRange(player, 8.0f, 25.0f, false))
{
DoResetThreat();
me.AddThreat(player, 1.0f);
DoCast(player, TrialOfChampionSpells.CHARGE);
break;
}
}
}
uiChargeTimer = 5000;
}
else
uiChargeTimer -= uiDiff;
//dosen't work at all
if (uiShieldBreakerTimer <= uiDiff)
{
Vehicle pVehicle = me.GetVehicleKit();
if (!pVehicle)
return;
Unit pPassenger = pVehicle.GetPassenger(0);
if (pPassenger)
{
var players = me.GetMap().GetPlayers();
if (!players.Empty())
{
foreach (var player in players)
{
if (player && !player.IsGameMaster() && me.IsInRange(player, 10.0f, 30.0f, false))
{
pPassenger.CastSpell(player, TrialOfChampionSpells.SHIELD_BREAKER, true);
break;
}
}
}
}
uiShieldBreakerTimer = 7000;
}
else
uiShieldBreakerTimer -= uiDiff;
DoMeleeAttackIfReady();
}
InstanceScript instance;
uint uiChargeTimer;
uint uiShieldBreakerTimer;
uint uiBuffTimer;
uint uiWaypointPath;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<generic_vehicleAI_toc5AI>(creature);
}
public static void AggroAllPlayers(Creature temp)
{
var PlList = temp.GetMap().GetPlayers();
if (PlList.Empty())
return;
foreach (var player in PlList)
{
if (player)
{
if (player.IsGameMaster())
continue;
if (player.IsAlive())
{
temp.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.ImmuneToPc);
temp.SetReactState(ReactStates.Aggressive);
temp.SetInCombatWith(player);
player.SetInCombatWith(temp);
temp.AddThreat(player, 0.0f);
}
}
}
}
public static bool GrandChampionsOutVehicle(Creature me)
{
InstanceScript instance = me.GetInstanceScript();
if (instance == null)
return false;
Creature pGrandChampion1 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1));
Creature pGrandChampion2 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2));
Creature pGrandChampion3 = ObjectAccessor.GetCreature(me, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3));
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
{
if (pGrandChampion1.m_movementInfo.transport.guid.IsEmpty() &&
pGrandChampion2.m_movementInfo.transport.guid.IsEmpty() &&
pGrandChampion3.m_movementInfo.transport.guid.IsEmpty())
return true;
}
return false;
}
}
abstract class boss_basic_toc5AI : ScriptedAI
{
public boss_basic_toc5AI(Creature creature) : base(creature)
{
Initialize();
instance = creature.GetInstanceScript();
bDone = false;
bHome = false;
uiPhase = 0;
uiPhaseTimer = 0;
me.SetReactState(ReactStates.Passive);
// THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.ImmuneToPc);
}
public abstract void Initialize();
public override void Reset()
{
Initialize();
}
public override void JustReachedHome()
{
base.JustReachedHome();
if (!bHome)
return;
uiPhaseTimer = 15000;
uiPhase = 1;
bHome = false;
}
public override void JustDied(Unit killer)
{
instance.SetData((uint)Data.BOSS_GRAND_CHAMPIONS, (uint)EncounterState.Done);
}
public override void UpdateAI(uint diff)
{
if (!bDone && generic_vehicleAI_toc5.GrandChampionsOutVehicle(me))
{
bDone = true;
if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1))
me.SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
else if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2))
me.SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
else if (me.GetGUID() == instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3))
me.SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
EnterEvadeMode();
bHome = true;
}
if (uiPhaseTimer <= diff)
{
if (uiPhase == 1)
{
generic_vehicleAI_toc5.AggroAllPlayers(me);
uiPhase = 0;
}
}
else
uiPhaseTimer -= diff;
}
public bool InVehicle()
{
return !me.m_movementInfo.transport.guid.IsEmpty();
}
public TaskScheduler NonCombatEvents = new TaskScheduler();
public InstanceScript instance;
public byte uiPhase;
public uint uiPhaseTimer;
bool bDone;
public bool bHome;
}
[Script]
class boss_warrior_toc5 : CreatureScript
{
public boss_warrior_toc5() : base("boss_warrior_toc5") { }
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
class boss_warrior_toc5AI : boss_basic_toc5AI
{
public boss_warrior_toc5AI(Creature creature) : base(creature) { }
public override void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(TrialOfChampionSpells.BLADESTORM);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
{
var players = me.GetMap().GetPlayers();
if (!players.Empty())
{
foreach (var player in players)
{
if (player && !player.IsGameMaster() && me.IsInRange(player, 8.0f, 25.0f, false))
{
DoResetThreat();
me.AddThreat(player, 5.0f);
DoCast(player, TrialOfChampionSpells.INTERCEPT);
break;
}
}
}
task.Repeat(TimeSpan.FromSeconds(7));
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(TrialOfChampionSpells.MORTAL_STRIKE);
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12));
});
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!UpdateVictim() || InVehicle())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_warrior_toc5AI>(creature);
}
}
[Script]
class boss_mage_toc5 : CreatureScript
{
public boss_mage_toc5() : base("boss_mage_toc5") { }
// Ambrose Boltspark && Eressea Dawnsinger || Mage
class boss_mage_toc5AI : boss_basic_toc5AI
{
public boss_mage_toc5AI(Creature creature) : base(creature) { }
public override void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(TrialOfChampionSpells.FIREBALL);
task.Repeat(TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, TrialOfChampionSpells.POLYMORPH);
task.Repeat(TimeSpan.FromSeconds(8));
});
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastAOE(TrialOfChampionSpells.BLAST_WAVE, false);
task.Repeat(TimeSpan.FromSeconds(13));
});
_scheduler.Schedule(TimeSpan.FromSeconds(22), task =>
{
me.InterruptNonMeleeSpells(true);
DoCast(me, TrialOfChampionSpells.HASTE);
task.Repeat(TimeSpan.FromSeconds(22));
});
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!UpdateVictim() || InVehicle())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_mage_toc5AI>(creature);
}
}
[Script]
class boss_shaman_toc5 : CreatureScript
{
public boss_shaman_toc5() : base("boss_shaman_toc5") { }
// Colosos && Runok Wildmane || Shaman
class boss_shaman_toc5AI : boss_basic_toc5AI
{
public boss_shaman_toc5AI(Creature creature) : base(creature) { }
public override void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(16), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, TrialOfChampionSpells.CHAIN_LIGHTNING);
task.Repeat(TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
bool bChance = RandomHelper.randChance(50);
if (!bChance)
{
Unit pFriend = DoSelectLowestHpFriendly(40);
if (pFriend)
DoCast(pFriend, TrialOfChampionSpells.HEALING_WAVE);
}
else
DoCast(me, TrialOfChampionSpells.HEALING_WAVE);
task.Repeat(TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35), task =>
{
DoCast(me, TrialOfChampionSpells.EARTH_SHIELD);
task.Repeat(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25), task =>
{
DoCastVictim(TrialOfChampionSpells.HEX_OF_MENDING, true);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
});
}
public override void EnterCombat(Unit who)
{
DoCast(me, TrialOfChampionSpells.EARTH_SHIELD);
DoCast(who, TrialOfChampionSpells.HEX_OF_MENDING);
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!UpdateVictim() || InVehicle())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_shaman_toc5AI>(creature);
}
}
[Script]
class boss_hunter_toc5 : CreatureScript
{
public boss_hunter_toc5() : base("boss_hunter_toc5") { }
// Jaelyne Evensong && Zul'tore || Hunter
class boss_hunter_toc5AI : boss_basic_toc5AI
{
public boss_hunter_toc5AI(Creature creature) : base(creature) { }
public override void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
{
DoCastAOE(TrialOfChampionSpells.LIGHTNING_ARROWS, false);
task.Repeat(TimeSpan.FromSeconds(7));
});
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
ObjectGuid uiTargetGUID = ObjectGuid.Empty;
Unit target = SelectTarget(SelectAggroTarget.Farthest, 0, 30.0f);
if (target)
{
uiTargetGUID = target.GetGUID();
DoCast(target, TrialOfChampionSpells.SHOOT);
}
bool bShoot = true;
task.Repeat(TimeSpan.FromSeconds(12));
task.Schedule(TimeSpan.FromSeconds(3), task1 =>
{
if (bShoot)
{
me.InterruptNonMeleeSpells(true);
Unit target1 = Global.ObjAccessor.GetUnit(me, uiTargetGUID);
if (target1 && me.IsInRange(target1, 5.0f, 30.0f, false))
{
DoCast(target1, TrialOfChampionSpells.MULTI_SHOT);
}
else
{
var players = me.GetMap().GetPlayers();
if (!players.Empty())
{
foreach (var player in players)
{
if (player && !player.IsGameMaster() && me.IsInRange(player, 5.0f, 30.0f, false))
{
DoCast(player, TrialOfChampionSpells.MULTI_SHOT);
break;
}
}
}
}
bShoot = false;
}
});
});
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!UpdateVictim() || InVehicle())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_hunter_toc5AI>(creature);
}
}
[Script]
class boss_rouge_toc5 : CreatureScript
{
public boss_rouge_toc5() : base("boss_rouge_toc5") { }
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
class boss_rouge_toc5AI : boss_basic_toc5AI
{
public boss_rouge_toc5AI(Creature creature) : base(creature) { }
public override void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(TrialOfChampionSpells.EVISCERATE);
task.Repeat(TimeSpan.FromSeconds(8));
});
_scheduler.Schedule(TimeSpan.FromSeconds(14), task =>
{
DoCastAOE(TrialOfChampionSpells.FAN_OF_KNIVES, false);
task.Repeat(TimeSpan.FromSeconds(14));
});
_scheduler.Schedule(TimeSpan.FromSeconds(19), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, TrialOfChampionSpells.POISON_BOTTLE);
task.Repeat(TimeSpan.FromSeconds(19));
});
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!UpdateVictim() || !me.m_movementInfo.transport.guid.IsEmpty())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_rouge_toc5AI>(creature);
}
}
}
@@ -0,0 +1,333 @@
/*
* 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 Framework.GameMath;
using Framework.IO;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheChampion
{
[Script]
class instance_trial_of_the_champion : InstanceMapScript
{
public instance_trial_of_the_champion() : base("instance_trial_of_the_champion", 650) { }
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_trial_of_the_champion_InstanceMapScript(map);
}
class instance_trial_of_the_champion_InstanceMapScript : InstanceScript
{
public instance_trial_of_the_champion_InstanceMapScript(Map map) : base(map)
{
SetHeaders("TC");
uiMovementDone = 0;
uiGrandChampionsDeaths = 0;
uiArgentSoldierDeaths = 0;
//bDone = false;
}
public override bool IsEncounterInProgress()
{
for (byte i = 0; i < 4; ++i)
{
if (m_auiEncounter[i] == EncounterState.InProgress)
return true;
}
return false;
}
public override void OnCreatureCreate(Creature creature)
{
var players = instance.GetPlayers();
Team TeamInInstance = 0;
if (!players.Empty())
{
Player player = players.First();
if (player)
TeamInInstance = player.GetTeam();
}
switch (creature.GetEntry())
{
// Champions
case VehicleIds.MOKRA_SKILLCRUSHER_MOUNT:
if (TeamInInstance == Team.Horde)
creature.UpdateEntry(VehicleIds.MARSHAL_JACOB_ALERIUS_MOUNT);
break;
case VehicleIds.ERESSEA_DAWNSINGER_MOUNT:
if (TeamInInstance == Team.Horde)
creature.UpdateEntry(VehicleIds.AMBROSE_BOLTSPARK_MOUNT);
break;
case VehicleIds.RUNOK_WILDMANE_MOUNT:
if (TeamInInstance == Team.Horde)
creature.UpdateEntry(VehicleIds.COLOSOS_MOUNT);
break;
case VehicleIds.ZUL_TORE_MOUNT:
if (TeamInInstance == Team.Horde)
creature.UpdateEntry(VehicleIds.EVENSONG_MOUNT);
break;
case VehicleIds.DEATHSTALKER_VESCERI_MOUNT:
if (TeamInInstance == Team.Horde)
creature.UpdateEntry(VehicleIds.LANA_STOUTHAMMER_MOUNT);
break;
// Coliseum Announcer || Just NPC_JAEREN must be spawned.
case CreatureIds.JAEREN:
uiAnnouncerGUID = creature.GetGUID();
if (TeamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.ARELAS);
break;
case VehicleIds.ARGENT_WARHORSE:
case VehicleIds.ARGENT_BATTLEWORG:
VehicleList.Add(creature.GetGUID());
break;
case CreatureIds.EADRIC:
case CreatureIds.PALETRESS:
uiArgentChampionGUID = creature.GetGUID();
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.MAIN_GATE:
uiMainGateGUID = go.GetGUID();
break;
case GameObjectIds.CHAMPIONS_LOOT:
case GameObjectIds.CHAMPIONS_LOOT_H:
uiChampionLootGUID = go.GetGUID();
break;
}
}
public override void SetData(uint uiType, uint uiData)
{
switch (uiType)
{
case (uint)Data.DATA_MOVEMENT_DONE:
uiMovementDone = (ushort)uiData;
if (uiMovementDone == 3)
{
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
if (pAnnouncer)
pAnnouncer.GetAI().SetData((uint)Data.DATA_IN_POSITION, 0);
}
break;
case (uint)Data.BOSS_GRAND_CHAMPIONS:
m_auiEncounter[0] = (EncounterState)uiData;
if (uiData == (uint)EncounterState.InProgress)
{
foreach (var guid in VehicleList)
{
Creature summon = instance.GetCreature(guid);
if (summon)
summon.RemoveFromWorld();
}
}
else if (uiData == (uint)EncounterState.Done)
{
++uiGrandChampionsDeaths;
if (uiGrandChampionsDeaths == 3)
{
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
if (pAnnouncer)
{
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.CHAMPIONS_LOOT_H : GameObjectIds.CHAMPIONS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
}
}
}
break;
case (uint)Data.DATA_ARGENT_SOLDIER_DEFEATED:
uiArgentSoldierDeaths = (byte)uiData;
if (uiArgentSoldierDeaths == 9)
{
Creature pBoss = instance.GetCreature(uiArgentChampionGUID);
if (pBoss)
{
pBoss.GetMotionMaster().MovePoint(0, 746.88f, 618.74f, 411.06f);
pBoss.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
pBoss.SetReactState(ReactStates.Aggressive);
}
}
break;
case (uint)Data.BOSS_ARGENT_CHALLENGE_E:
{
m_auiEncounter[1] = (EncounterState)uiData;
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
if (pAnnouncer)
{
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.EADRIC_LOOT_H : GameObjectIds.EADRIC_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
}
}
break;
case (uint)Data.BOSS_ARGENT_CHALLENGE_P:
{
m_auiEncounter[2] = (EncounterState)uiData;
Creature pAnnouncer = instance.GetCreature(uiAnnouncerGUID);
if (pAnnouncer)
{
pAnnouncer.GetMotionMaster().MovePoint(0, 748.309f, 619.487f, 411.171f);
pAnnouncer.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.PALETRESS_LOOT_H : GameObjectIds.PALETRESS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.WAxis, 90000);
}
}
break;
}
if (uiData == (uint)EncounterState.Done)
SaveToDB();
}
public override uint GetData(uint uiData)
{
switch (uiData)
{
case (uint)Data.BOSS_GRAND_CHAMPIONS:
return (uint)m_auiEncounter[0];
case (uint)Data.BOSS_ARGENT_CHALLENGE_E:
return (uint)m_auiEncounter[1];
case (uint)Data.BOSS_ARGENT_CHALLENGE_P:
return (uint)m_auiEncounter[2];
case (uint)Data.BOSS_BLACK_KNIGHT:
return (uint)m_auiEncounter[3];
case (uint)Data.DATA_MOVEMENT_DONE:
return uiMovementDone;
case (uint)Data.DATA_ARGENT_SOLDIER_DEFEATED:
return uiArgentSoldierDeaths;
}
return 0;
}
public override ObjectGuid GetGuidData(uint uiData)
{
switch (uiData)
{
case (uint)Data64.DATA_ANNOUNCER:
return uiAnnouncerGUID;
case (uint)Data64.DATA_MAIN_GATE:
return uiMainGateGUID;
case (uint)Data64.DATA_GRAND_CHAMPION_1:
return uiGrandChampion1GUID;
case (uint)Data64.DATA_GRAND_CHAMPION_2:
return uiGrandChampion2GUID;
case (uint)Data64.DATA_GRAND_CHAMPION_3:
return uiGrandChampion3GUID;
}
return ObjectGuid.Empty;
}
public override void SetGuidData(uint uiType, ObjectGuid uiData)
{
switch (uiType)
{
case (uint)Data64.DATA_GRAND_CHAMPION_1:
uiGrandChampion1GUID = uiData;
break;
case (uint)Data64.DATA_GRAND_CHAMPION_2:
uiGrandChampion2GUID = uiData;
break;
case (uint)Data64.DATA_GRAND_CHAMPION_3:
uiGrandChampion3GUID = uiData;
break;
}
}
public override string GetSaveData()
{
OUT_SAVE_INST_DATA();
string str_data = string.Format("T C {0} {1} {2} {3} {4} {5}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], m_auiEncounter[3], uiGrandChampionsDeaths, uiMovementDone);
OUT_SAVE_INST_DATA_COMPLETE();
return str_data;
}
public override void Load(string str)
{
if (str.IsEmpty())
{
OUT_LOAD_INST_DATA_FAIL();
return;
}
OUT_LOAD_INST_DATA(str);
StringArguments loadStream = new StringArguments(str);
string dataHead = loadStream.NextString();
if (dataHead[0] == 'T' && dataHead[1] == 'C')
{
for (byte i = 0; i < 4; ++i)
{
m_auiEncounter[i] = (EncounterState)loadStream.NextUInt32();
if (m_auiEncounter[i] == EncounterState.InProgress)
m_auiEncounter[i] = EncounterState.NotStarted;
}
uiGrandChampionsDeaths = loadStream.NextUInt16();
uiMovementDone = loadStream.NextUInt16();
}
else
OUT_LOAD_INST_DATA_FAIL();
OUT_LOAD_INST_DATA_COMPLETE();
}
EncounterState[] m_auiEncounter = new EncounterState[4];
ushort uiMovementDone;
ushort uiGrandChampionsDeaths;
byte uiArgentSoldierDeaths;
ObjectGuid uiAnnouncerGUID;
ObjectGuid uiMainGateGUID;
//ObjectGuid uiGrandChampionVehicle1GUID;
//ObjectGuid uiGrandChampionVehicle2GUID;
//ObjectGuid uiGrandChampionVehicle3GUID;
ObjectGuid uiGrandChampion1GUID;
ObjectGuid uiGrandChampion2GUID;
ObjectGuid uiGrandChampion3GUID;
ObjectGuid uiChampionLootGUID;
ObjectGuid uiArgentChampionGUID;
List<ObjectGuid> VehicleList = new List<ObjectGuid>();
//bool bDone;
}
}
}
@@ -0,0 +1,587 @@
/*
* 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.CrusadersColiseum.TrialOfTheChampion
{
struct TrialOfTheChampionConst
{
public const uint SAY_INTRO_1 = 0;
public const uint SAY_INTRO_2 = 1;
public const uint SAY_INTRO_3 = 2;
public const uint SAY_AGGRO = 3;
public const uint SAY_PHASE_2 = 4;
public const uint SAY_PHASE_3 = 5;
public const uint SAY_KILL_PLAYER = 6;
public const uint SAY_DEATH = 7;
public const string GOSSIP_START_EVENT1 = "I'm ready to start challenge.";
public const string GOSSIP_START_EVENT2 = "I'm ready for the next challenge.";
}
enum Data
{
BOSS_GRAND_CHAMPIONS,
BOSS_ARGENT_CHALLENGE_E,
BOSS_ARGENT_CHALLENGE_P,
BOSS_BLACK_KNIGHT,
DATA_MOVEMENT_DONE,
DATA_LESSER_CHAMPIONS_DEFEATED,
DATA_START,
DATA_IN_POSITION,
DATA_ARGENT_SOLDIER_DEFEATED
};
enum Data64
{
DATA_ANNOUNCER,
DATA_MAIN_GATE,
DATA_GRAND_CHAMPION_VEHICLE_1,
DATA_GRAND_CHAMPION_VEHICLE_2,
DATA_GRAND_CHAMPION_VEHICLE_3,
DATA_GRAND_CHAMPION_1,
DATA_GRAND_CHAMPION_2,
DATA_GRAND_CHAMPION_3
};
struct CreatureIds
{
// Horde Champions
public const uint MOKRA = 35572;
public const uint ERESSEA = 35569;
public const uint RUNOK = 35571;
public const uint ZULTORE = 35570;
public const uint VISCERI = 35617;
// Alliance Champions
public const uint JACOB = 34705;
public const uint AMBROSE = 34702;
public const uint COLOSOS = 34701;
public const uint JAELYNE = 34657;
public const uint LANA = 34703;
public const uint EADRIC = 35119;
public const uint PALETRESS = 34928;
public const uint ARGENT_LIGHWIELDER = 35309;
public const uint ARGENT_MONK = 35305;
public const uint PRIESTESS = 35307;
public const uint BLACK_KNIGHT = 35451;
public const uint RISEN_JAEREN = 35545;
public const uint RISEN_ARELAS = 35564;
public const uint JAEREN = 35004;
public const uint ARELAS = 35005;
}
struct GameObjectIds
{
public const uint MAIN_GATE = 195647;
public const uint CHAMPIONS_LOOT = 195709;
public const uint CHAMPIONS_LOOT_H = 195710;
public const uint EADRIC_LOOT = 195374;
public const uint EADRIC_LOOT_H = 195375;
public const uint PALETRESS_LOOT = 195323;
public const uint PALETRESS_LOOT_H = 195324;
}
struct VehicleIds
{
//Grand Champions Alliance Vehicles
public const uint MARSHAL_JACOB_ALERIUS_MOUNT = 35637;
public const uint AMBROSE_BOLTSPARK_MOUNT = 35633;
public const uint COLOSOS_MOUNT = 35768;
public const uint EVENSONG_MOUNT = 34658;
public const uint LANA_STOUTHAMMER_MOUNT = 35636;
//Faction Champions (ALLIANCE)
public const uint DARNASSIA_NIGHTSABER = 33319;
public const uint EXODAR_ELEKK = 33318;
public const uint STORMWIND_STEED = 33217;
public const uint GNOMEREGAN_MECHANOSTRIDER = 33317;
public const uint IRONFORGE_RAM = 33316;
//Grand Champions Horde Vehicles
public const uint MOKRA_SKILLCRUSHER_MOUNT = 35638;
public const uint ERESSEA_DAWNSINGER_MOUNT = 35635;
public const uint RUNOK_WILDMANE_MOUNT = 35640;
public const uint ZUL_TORE_MOUNT = 35641;
public const uint DEATHSTALKER_VESCERI_MOUNT = 35634;
//Faction Champions (HORDE)
public const uint FORSAKE_WARHORSE = 33324;
public const uint THUNDER_BLUFF_KODO = 33322;
public const uint ORGRIMMAR_WOLF = 33320;
public const uint SILVERMOON_HAWKSTRIDER = 33323;
public const uint DARKSPEAR_RAPTOR = 33321;
public const uint ARGENT_WARHORSE = 35644;
public const uint ARGENT_BATTLEWORG = 36558;
public const uint BLACK_KNIGHT = 35491;
}
[Script]
class npc_announcer_toc5 : CreatureScript
{
public npc_announcer_toc5() : base("npc_announcer_toc5") { }
class npc_announcer_toc5AI : ScriptedAI
{
public npc_announcer_toc5AI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
uiSummonTimes = 0;
uiLesserChampions = 0;
uiFirstBoss = 0;
uiSecondBoss = 0;
uiThirdBoss = 0;
uiArgentChampion = 0;
uiPhase = 0;
uiTimer = 0;
me.SetReactState(ReactStates.Passive);
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
me.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
SetGrandChampionsForEncounter();
SetArgentChampion();
}
void NextStep(uint uiTimerStep, bool bNextStep = true, byte uiPhaseStep = 0)
{
uiTimer = uiTimerStep;
if (bNextStep)
++uiPhase;
else
uiPhase = uiPhaseStep;
}
public override void SetData(uint uiType, uint uiData)
{
switch (uiType)
{
case (uint)Data.DATA_START:
DoSummonGrandChampion(uiFirstBoss);
NextStep(10000, false, 1);
break;
case (uint)Data.DATA_IN_POSITION: //movement EncounterState.Done.
me.GetMotionMaster().MovePoint(1, 735.81f, 661.92f, 412.39f);
GameObject go = ObjectAccessor.GetGameObject(me, instance.GetGuidData((uint)Data64.DATA_MAIN_GATE));
if (go)
instance.HandleGameObject(go.GetGUID(), false);
NextStep(10000, false, 3);
break;
case (uint)Data.DATA_LESSER_CHAMPIONS_DEFEATED:
{
++uiLesserChampions;
List<ObjectGuid> TempList = new List<ObjectGuid>();
if (uiLesserChampions == 3 || uiLesserChampions == 6)
{
switch (uiLesserChampions)
{
case 3:
TempList = Champion2List;
break;
case 6:
TempList = Champion3List;
break;
}
foreach (var guid in TempList)
{
Creature summon = ObjectAccessor.GetCreature(me, guid);
if (summon)
AggroAllPlayers(summon);
}
} else if (uiLesserChampions == 9)
StartGrandChampionsAttack();
break;
}
}
}
void StartGrandChampionsAttack()
{
Creature pGrandChampion1 = ObjectAccessor.GetCreature(me, uiVehicle1GUID);
Creature pGrandChampion2 = ObjectAccessor.GetCreature(me, uiVehicle2GUID);
Creature pGrandChampion3 = ObjectAccessor.GetCreature(me, uiVehicle3GUID);
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
{
AggroAllPlayers(pGrandChampion1);
AggroAllPlayers(pGrandChampion2);
AggroAllPlayers(pGrandChampion3);
}
}
public override void MovementInform(MovementGeneratorType uiType, uint uiPointId)
{
if (uiType != MovementGeneratorType.Point)
return;
if (uiPointId == 1)
me.SetFacingTo(4.714f);
}
void DoSummonGrandChampion(uint uiBoss)
{
++uiSummonTimes;
uint VEHICLE_TO_SUMMON1 = 0;
uint VEHICLE_TO_SUMMON2 = 0;
switch (uiBoss)
{
case 0:
VEHICLE_TO_SUMMON1 = VehicleIds.MOKRA_SKILLCRUSHER_MOUNT;
VEHICLE_TO_SUMMON2 = VehicleIds.ORGRIMMAR_WOLF;
break;
case 1:
VEHICLE_TO_SUMMON1 = VehicleIds.ERESSEA_DAWNSINGER_MOUNT;
VEHICLE_TO_SUMMON2 = VehicleIds.SILVERMOON_HAWKSTRIDER;
break;
case 2:
VEHICLE_TO_SUMMON1 = VehicleIds.RUNOK_WILDMANE_MOUNT;
VEHICLE_TO_SUMMON2 = VehicleIds.THUNDER_BLUFF_KODO;
break;
case 3:
VEHICLE_TO_SUMMON1 = VehicleIds.ZUL_TORE_MOUNT;
VEHICLE_TO_SUMMON2 = VehicleIds.DARKSPEAR_RAPTOR;
break;
case 4:
VEHICLE_TO_SUMMON1 = VehicleIds.DEATHSTALKER_VESCERI_MOUNT;
VEHICLE_TO_SUMMON2 = VehicleIds.FORSAKE_WARHORSE;
break;
default:
return;
}
Creature pBoss = me.SummonCreature(VEHICLE_TO_SUMMON1, SpawnPosition);
if (pBoss)
{
ObjectGuid uiGrandChampionBoss = ObjectGuid.Empty;
Vehicle pVehicle = pBoss.GetVehicleKit();
if (pVehicle)
{
Unit unit = pVehicle.GetPassenger(0);
if (unit)
uiGrandChampionBoss = unit.GetGUID();
}
switch (uiSummonTimes)
{
case 1:
uiVehicle1GUID = pBoss.GetGUID();
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_1, uiVehicle1GUID);
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1, uiGrandChampionBoss);
break;
case 2:
uiVehicle2GUID = pBoss.GetGUID();
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_2, uiVehicle2GUID);
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2, uiGrandChampionBoss);
break;
case 3:
uiVehicle3GUID = pBoss.GetGUID();
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_VEHICLE_3, uiVehicle3GUID);
instance.SetGuidData((uint)Data64.DATA_GRAND_CHAMPION_3, uiGrandChampionBoss);
break;
default:
return;
}
pBoss.GetAI().SetData(uiSummonTimes, 0);
for (byte i = 0; i < 3; ++i)
{
Creature pAdd = me.SummonCreature(VEHICLE_TO_SUMMON2, SpawnPosition, TempSummonType.CorpseDespawn);
if (pAdd)
{
switch (uiSummonTimes)
{
case 1:
Champion1List.Add(pAdd.GetGUID());
break;
case 2:
Champion2List.Add(pAdd.GetGUID());
break;
case 3:
Champion3List.Add(pAdd.GetGUID());
break;
}
switch (i)
{
case 0:
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI);
break;
case 1:
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI / 2);
break;
case 2:
pAdd.GetMotionMaster().MoveFollow(pBoss, 2.0f, MathFunctions.PI / 2 + MathFunctions.PI);
break;
}
}
}
}
}
void DoStartArgentChampionEncounter()
{
me.GetMotionMaster().MovePoint(1, 735.81f, 661.92f, 412.39f);
if (me.SummonCreature(uiArgentChampion, SpawnPosition))
{
for (byte i = 0; i < 3; ++i)
{
Creature lightwielderTrash = me.SummonCreature(CreatureIds.ARGENT_LIGHWIELDER, SpawnPosition);
if (lightwielderTrash)
lightwielderTrash.GetAI().SetData(i, 0);
Creature monkTrash = me.SummonCreature(CreatureIds.ARGENT_MONK, SpawnPosition);
if (monkTrash)
monkTrash.GetAI().SetData(i, 0);
Creature priestessTrash = me.SummonCreature(CreatureIds.PRIESTESS, SpawnPosition);
if (priestessTrash)
priestessTrash.GetAI().SetData(i, 0);
}
}
}
void SetGrandChampionsForEncounter()
{
uiFirstBoss = RandomHelper.URand(0, 4);
while (uiSecondBoss == uiFirstBoss || uiThirdBoss == uiFirstBoss || uiThirdBoss == uiSecondBoss)
{
uiSecondBoss = RandomHelper.URand(0, 4);
uiThirdBoss = RandomHelper.URand(0, 4);
}
}
void SetArgentChampion()
{
byte uiTempBoss = (byte)RandomHelper.URand(0, 1);
switch (uiTempBoss)
{
case 0:
uiArgentChampion = CreatureIds.EADRIC;
break;
case 1:
uiArgentChampion = CreatureIds.PALETRESS;
break;
}
}
public void StartEncounter()
{
me.RemoveFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
if (instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.NotStarted)
{
if (instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.NotStarted && instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.NotStarted)
{
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted)
SetData((uint)Data.DATA_START, 0);
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done)
DoStartArgentChampionEncounter();
}
if ((instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done &&
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.Done) ||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.Done)
me.SummonCreature(VehicleIds.BLACK_KNIGHT, 769.834f, 651.915f, 447.035f, 0);
}
}
void AggroAllPlayers(Creature temp)
{
var PlList = me.GetMap().GetPlayers();
if (PlList.Empty())
return;
foreach (var player in PlList)
{
if (player.IsGameMaster())
continue;
if (player.IsAlive())
{
temp.SetHomePosition(me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
temp.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
temp.SetReactState(ReactStates.Aggressive);
temp.SetInCombatWith(player);
player.SetInCombatWith(temp);
temp.AddThreat(player, 0.0f);
}
}
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (uiTimer <= diff)
{
switch (uiPhase)
{
case 1:
DoSummonGrandChampion(uiSecondBoss);
NextStep(10000, true);
break;
case 2:
DoSummonGrandChampion(uiThirdBoss);
NextStep(0, false);
break;
case 3:
if (!Champion1List.Empty())
{
foreach (var guid in Champion1List)
{
Creature summon = ObjectAccessor.GetCreature(me, guid);
if (summon)
AggroAllPlayers(summon);
}
NextStep(0, false);
}
break;
}
}
else
uiTimer -= diff;
if (!UpdateVictim())
return;
}
public override void JustSummoned(Creature summon)
{
if (instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted)
{
summon.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
summon.SetReactState(ReactStates.Passive);
}
}
public override void SummonedCreatureDespawn(Creature summon)
{
switch (summon.GetEntry())
{
case VehicleIds.DARNASSIA_NIGHTSABER:
case VehicleIds.EXODAR_ELEKK:
case VehicleIds.STORMWIND_STEED:
case VehicleIds.GNOMEREGAN_MECHANOSTRIDER:
case VehicleIds.IRONFORGE_RAM:
case VehicleIds.FORSAKE_WARHORSE:
case VehicleIds.THUNDER_BLUFF_KODO:
case VehicleIds.ORGRIMMAR_WOLF:
case VehicleIds.SILVERMOON_HAWKSTRIDER:
case VehicleIds.DARKSPEAR_RAPTOR:
SetData((uint)Data.DATA_LESSER_CHAMPIONS_DEFEATED, 0);
break;
}
}
InstanceScript instance;
byte uiSummonTimes;
byte uiLesserChampions;
uint uiArgentChampion;
uint uiFirstBoss;
uint uiSecondBoss;
uint uiThirdBoss;
uint uiPhase;
uint uiTimer;
ObjectGuid uiVehicle1GUID;
ObjectGuid uiVehicle2GUID;
ObjectGuid uiVehicle3GUID;
List<ObjectGuid> Champion1List = new List<ObjectGuid>();
List<ObjectGuid> Champion2List = new List<ObjectGuid>();
List<ObjectGuid> Champion3List = new List<ObjectGuid>();
Position SpawnPosition = new Position(746.261f, 657.401f, 411.681f, 4.65f);
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_announcer_toc5AI>(creature);
}
public override bool OnGossipHello(Player player, Creature creature)
{
InstanceScript instance = creature.GetInstanceScript();
if (instance != null &&
((instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.Done &&
instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.Done &&
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.Done) ||
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.Done))
return false;
if (instance != null &&
instance.GetData((uint)Data.BOSS_GRAND_CHAMPIONS) == (uint)EncounterState.NotStarted &&
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_E) == (uint)EncounterState.NotStarted &&
instance.GetData((uint)Data.BOSS_ARGENT_CHALLENGE_P) == (uint)EncounterState.NotStarted &&
instance.GetData((uint)Data.BOSS_BLACK_KNIGHT) == (uint)EncounterState.NotStarted)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, TrialOfTheChampionConst.GOSSIP_START_EVENT1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
else if (instance != null)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, TrialOfTheChampionConst.GOSSIP_START_EVENT2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
player.SEND_GOSSIP_MENU(player.GetGossipTextId(creature), creature.GetGUID());
return true;
}
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
{
player.PlayerTalkClass.ClearMenus();
if (action == eTradeskill.GossipActionInfoDef + 1)
{
player.CLOSE_GOSSIP_MENU();
((npc_announcer_toc5AI)creature.GetAI()).StartEncounter();
}
return true;
}
}
}
@@ -0,0 +1,568 @@
/*
* 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.Collections.Generic;
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheCrusader
{
struct Jaraxxus
{
public const uint SayIntro = 0;
public const uint SayAggro = 1;
public const uint EmoteLegionFlame = 2;
public const uint EmoteNetherPortal = 3;
public const uint SayMistressOfPain = 4;
public const uint EmoteIncinerate = 5;
public const uint SayIncinerate = 6;
public const uint EmoteInfernalEruption = 7;
public const uint SayInfernalEruption = 8;
public const uint SayKillPlayer = 9;
public const uint SayDeath = 10;
public const uint SayBerserk = 11;
public const uint NpcLegionFlame = 34784;
public const uint NpcInfernalVolcano = 34813;
public const uint NpcFelInfernal = 34815; // Immune To All Cc On Heroic (Stuns; Banish; Interrupt; Etc)
public const uint NpcNetherPortal = 34825;
public const uint NpcMistressOfPain = 34826;
public const uint SpellLegionFlame = 66197; // Player Should Run Away From Raid Because He Triggers Legion Flame
public const uint SpellLegionFlameEffect = 66201; // Used By Trigger Npc
public const uint SpellNetherPower = 66228; // +20% Of Spell Damage Per Stack; Stackable Up To 5/10 Times; Must Be Dispelled/Stealed
public const uint SpellFelLighting = 66528; // Jumps To Nearby Targets
public const uint SpellFelFireball = 66532; // Does Heavy Damage To The Tank; Interruptable
public const uint SpellIncinerateFlesh = 66237; // Target Must Be Healed Or Will Trigger Burning Inferno
public const uint SpellBurningInferno = 66242; // Triggered By Incinerate Flesh
public const uint SpellInfernalEruption = 66258; // Summons Infernal Volcano
public const uint SpellInfernalEruptionEffect = 66252; // Summons Felflame Infernal (3 At Normal And Inifinity At Heroic)
public const uint SpellNetherPortal = 66269; // Summons Nether Portal
public const uint SpellNetherPortalEffect = 66263; // Summons Mistress Of Pain (1 At Normal And Infinity At Heroic)
public const uint SpellBerserk = 64238; // Unused
// Mistress Of Pain Spells
public const uint SpellShivanSlash = 67098;
public const uint SpellSpinningStrike = 66283;
public const uint SpellMistressKiss = 66336;
public const uint SpellFelInferno = 67047;
public const uint SpellFelStreak = 66494;
public const int SpellLordHittin = 66326; // Special Effect Preventing More Specific Spells Be Cast On The Same Player Within 10 Seconds
public const uint SpellMistressKissDamageSilence = 66359;
// Lord Jaraxxus
public const uint EventFelFireball = 1;
public const uint EventFelLightning = 2;
public const uint EventIncinerateFlesh = 3;
public const uint EventNetherPower = 4;
public const uint EventLegionFlame = 5;
public const uint EventSummonoNetherPortal = 6;
public const uint EventSummonInfernalEruption = 7;
// Mistress Of Pain
public const uint EventShivanSlash = 8;
public const uint EventSpinningStrike = 9;
public const uint EventMistressKiss = 10;
}
[Script]
class boss_jaraxxus : CreatureScript
{
public
boss_jaraxxus() : base("boss_jaraxxus") { }
class boss_jaraxxusAI : BossAI
{
public boss_jaraxxusAI(Creature creature) : base(creature, DataTypes.BossJaraxxus) { }
public override void Reset()
{
_Reset();
_events.ScheduleEvent(Jaraxxus.EventFelFireball, 5 * Time.InMilliseconds);
_events.ScheduleEvent(Jaraxxus.EventFelLightning, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
_events.ScheduleEvent(Jaraxxus.EventIncinerateFlesh, RandomHelper.URand(20 * Time.InMilliseconds, 25 * Time.InMilliseconds));
_events.ScheduleEvent(Jaraxxus.EventNetherPower, 40 * Time.InMilliseconds);
_events.ScheduleEvent(Jaraxxus.EventLegionFlame, 30 * Time.InMilliseconds);
_events.ScheduleEvent(Jaraxxus.EventSummonoNetherPortal, 20 * Time.InMilliseconds);
_events.ScheduleEvent(Jaraxxus.EventSummonInfernalEruption, 80 * Time.InMilliseconds);
}
public override void JustReachedHome()
{
_JustReachedHome();
instance.SetBossState(DataTypes.BossJaraxxus, EncounterState.Fail);
DoCast(me, Spells.JaraxxusChains);
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
{
Talk(Jaraxxus.SayKillPlayer);
instance.SetData(DataTypes.TributeToImmortalityEligible, 0);
}
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(Jaraxxus.SayDeath);
}
public override void JustSummoned(Creature summoned)
{
summons.Summon(summoned);
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(Jaraxxus.SayAggro);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Jaraxxus.EventFelFireball:
DoCastVictim(Jaraxxus.SpellFelFireball);
_events.ScheduleEvent(Jaraxxus.EventFelFireball, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
return;
case Jaraxxus.EventFelLightning:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true, -Jaraxxus.SpellLordHittin);
if (target)
DoCast(target, Jaraxxus.SpellFelLighting);
_events.ScheduleEvent(Jaraxxus.EventFelLightning, RandomHelper.URand(10 * Time.InMilliseconds, 15 * Time.InMilliseconds));
return;
}
case Jaraxxus.EventIncinerateFlesh:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true, -Jaraxxus.SpellLordHittin);
if (target)
{
Talk(Jaraxxus.EmoteIncinerate, target);
Talk(Jaraxxus.SayIncinerate);
DoCast(target, Jaraxxus.SpellInfernalEruption);
}
_events.ScheduleEvent(Jaraxxus.EventIncinerateFlesh, RandomHelper.URand(20 * Time.InMilliseconds, 25 * Time.InMilliseconds));
return;
}
case Jaraxxus.EventNetherPower:
me.CastCustomSpell(Jaraxxus.SpellNetherPower, SpellValueMod.AuraStack, RaidMode(5, 10, 5, 10), me, true);
_events.ScheduleEvent(Jaraxxus.EventNetherPower, 40 * Time.InMilliseconds);
return;
case Jaraxxus.EventLegionFlame:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true, -Jaraxxus.SpellLordHittin);
if (target)
{
Talk(Jaraxxus.EmoteLegionFlame, target);
DoCast(target, Jaraxxus.SpellLegionFlame);
}
_events.ScheduleEvent(Jaraxxus.EventLegionFlame, 30 * Time.InMilliseconds);
return;
}
case Jaraxxus.EventSummonoNetherPortal:
Talk(Jaraxxus.EmoteNetherPortal);
Talk(Jaraxxus.SayMistressOfPain);
DoCast(Jaraxxus.SpellNetherPortal);
_events.ScheduleEvent(Jaraxxus.EventSummonoNetherPortal, 2 * Time.Minute * Time.InMilliseconds);
return;
case Jaraxxus.EventSummonInfernalEruption:
Talk(Jaraxxus.EmoteInfernalEruption);
Talk(Jaraxxus.SayInfernalEruption);
DoCast(Jaraxxus.SpellInfernalEruption);
_events.ScheduleEvent(Jaraxxus.EventSummonInfernalEruption, 2 * Time.Minute * Time.InMilliseconds);
return;
}
});
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_jaraxxusAI>(creature);
}
}
[Script]
class npc_legion_flame : CreatureScript
{
public npc_legion_flame() : base("npc_legion_flame") { }
class npc_legion_flameAI : ScriptedAI
{
public npc_legion_flameAI(Creature creature) : base(creature)
{
SetCombatMovement(false);
_instance = creature.GetInstanceScript();
}
public override void Reset()
{
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable);
me.SetInCombatWithZone();
DoCast(Jaraxxus.SpellLegionFlameEffect);
}
public override void UpdateAI(uint diff)
{
UpdateVictim();
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
me.DespawnOrUnsummon();
}
InstanceScript _instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_legion_flameAI>(creature);
}
}
[Script]
class npc_infernal_volcano : CreatureScript
{
public npc_infernal_volcano() : base("npc_infernal_volcano") { }
class npc_infernal_volcanoAI : ScriptedAI
{
public npc_infernal_volcanoAI(Creature creature) : base(creature)
{
_summons = new SummonList(me);
SetCombatMovement(false);
}
public override void Reset()
{
me.SetReactState(ReactStates.Passive);
if (!IsHeroic())
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
else
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
_summons.DespawnAll();
}
public override void IsSummonedBy(Unit summoner)
{
DoCast(Jaraxxus.SpellInfernalEruptionEffect);
}
public override void JustSummoned(Creature summoned)
{
_summons.Summon(summoned);
// makes immediate corpse despawn of summoned Felflame Infernals
summoned.SetCorpseDelay(0);
}
public override void JustDied(Unit killer)
{
// used to despawn corpse immediately
me.DespawnOrUnsummon();
}
public override void UpdateAI(uint diff) { }
SummonList _summons;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_infernal_volcanoAI(creature);
}
}
[Script]
class npc_fel_infernal : CreatureScript
{
public npc_fel_infernal() : base("npc_fel_infernal") { }
class npc_fel_infernalAI : ScriptedAI
{
public npc_fel_infernalAI(Creature creature) : base(creature)
{
_instance = creature.GetInstanceScript();
}
public override void Reset()
{
_felStreakTimer = 30 * Time.InMilliseconds;
me.SetInCombatWithZone();
}
public override void UpdateAI(uint diff)
{
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
{
me.DespawnOrUnsummon();
return;
}
if (!UpdateVictim())
return;
if (_felStreakTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
DoCast(target, Jaraxxus.SpellFelStreak);
_felStreakTimer = 30 * Time.InMilliseconds;
}
else
_felStreakTimer -= diff;
DoMeleeAttackIfReady();
}
uint _felStreakTimer;
InstanceScript _instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_fel_infernalAI>(creature);
}
}
[Script]
class npc_nether_portal : CreatureScript
{
public npc_nether_portal() : base("npc_nether_portal") { }
class npc_nether_portalAI : ScriptedAI
{
public npc_nether_portalAI(Creature creature) : base(creature)
{
_summons = new SummonList(me);
}
public override void Reset()
{
me.SetReactState(ReactStates.Passive);
if (!IsHeroic())
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
else
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
_summons.DespawnAll();
}
public override void IsSummonedBy(Unit summoner)
{
DoCast(Jaraxxus.SpellNetherPortalEffect);
}
public override void JustSummoned(Creature summoned)
{
_summons.Summon(summoned);
// makes immediate corpse despawn of summoned Mistress of Pain
summoned.SetCorpseDelay(0);
}
public override void JustDied(Unit killer)
{
// used to despawn corpse immediately
me.DespawnOrUnsummon();
}
public override void UpdateAI(uint diff) { }
SummonList _summons;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_nether_portalAI(creature);
}
}
[Script]
class npc_mistress_of_pain : CreatureScript
{
public npc_mistress_of_pain() : base("npc_mistress_of_pain") { }
class npc_mistress_of_painAI : ScriptedAI
{
public npc_mistress_of_painAI(Creature creature) : base(creature)
{
_instance = creature.GetInstanceScript();
_instance.SetData(DataTypes.MistressOfPainCount, DataTypes.Increase);
}
public override void Reset()
{
_events.ScheduleEvent(Jaraxxus.EventShivanSlash, 30 * Time.InMilliseconds);
_events.ScheduleEvent(Jaraxxus.EventSpinningStrike, 30 * Time.InMilliseconds);
if (IsHeroic())
_events.ScheduleEvent(Jaraxxus.EventMistressKiss, 15 * Time.InMilliseconds);
me.SetInCombatWithZone();
}
public override void JustDied(Unit killer)
{
_instance.SetData(DataTypes.MistressOfPainCount, DataTypes.Decrease);
}
public override void UpdateAI(uint diff)
{
if (_instance.GetBossState(DataTypes.BossJaraxxus) != EncounterState.InProgress)
{
me.DespawnOrUnsummon();
return;
}
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Jaraxxus.EventShivanSlash:
DoCastVictim(Jaraxxus.SpellShivanSlash);
_events.ScheduleEvent(Jaraxxus.EventShivanSlash, 30 * Time.InMilliseconds);
return;
case Jaraxxus.EventSpinningStrike:
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
DoCast(target, Jaraxxus.SpellSpinningStrike);
_events.ScheduleEvent(Jaraxxus.EventSpinningStrike, 30 * Time.InMilliseconds);
return;
case Jaraxxus.EventMistressKiss:
DoCast(me, Jaraxxus.SpellMistressKiss);
_events.ScheduleEvent(Jaraxxus.EventMistressKiss, 30 * Time.InMilliseconds);
return;
default:
break;
}
});
DoMeleeAttackIfReady();
}
InstanceScript _instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_mistress_of_painAI>(creature);
}
}
[Script]
class spell_mistress_kiss : SpellScriptLoader
{
public spell_mistress_kiss() : base("spell_mistress_kiss") { }
class spell_mistress_kiss_AuraScript : AuraScript
{
public override bool Load()
{
return ValidateSpellInfo(Jaraxxus.SpellMistressKissDamageSilence);
}
void HandleDummyTick(AuraEffect aurEff)
{
Unit caster = GetCaster();
Unit target = GetTarget();
if (caster && target)
{
if (target.HasUnitState(UnitState.Casting))
{
caster.CastSpell(target, Jaraxxus.SpellMistressKissDamageSilence, true);
target.RemoveAurasDueToSpell(GetSpellInfo().Id);
}
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleDummyTick, 0, AuraType.PeriodicDummy));
}
}
public override AuraScript GetAuraScript()
{
return new spell_mistress_kiss_AuraScript();
}
}
[Script]
class spell_mistress_kiss_area : SpellScriptLoader
{
public spell_mistress_kiss_area() : base("spell_mistress_kiss_area") { }
class spell_mistress_kiss_area_SpellScript : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
// get a list of players with mana
targets.RemoveAll(unit => unit.IsTypeId(TypeId.Player) && unit.ToPlayer().getPowerType() == PowerType.Mana);
if (targets.Empty())
return;
WorldObject target = targets.PickRandom();
targets.Clear();
targets.Add(target);
}
void HandleScript(uint effIndex)
{
GetCaster().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_mistress_kiss_area_SpellScript();
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,409 @@
/*
* 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.Entities;
using Game.Maps;
namespace Scripts.Northrend.CrusadersColiseum.TrialOfTheCrusader
{
struct DataTypes
{
public const uint BossBeasts = 0;
public const uint BossJaraxxus = 1;
public const uint BossCrusaders = 2;
public const uint BossValkiries = 3;
public const uint BossLichKing = 4; // Not Really A Boss But Oh Well
public const uint BossAnubarak = 5;
public const uint MaxEncounters = 6;
public const uint TypeCounter = 8;
public const uint TypeEvent = 9;
public const uint TypeEventTimer = 101;
public const uint TypeEventNpc = 102;
public const uint TypeNorthrendBeasts = 103;
public const uint SnoboldCount = 301;
public const uint MistressOfPainCount = 302;
public const uint TributeToImmortalityEligible = 303;
public const uint Increase = 501;
public const uint Decrease = 502;
}
struct Spells
{
public const uint WilfredPortal = 68424;
public const uint JaraxxusChains = 67924;
public const uint CorpseTeleport = 69016;
public const uint DestroyFloorKnockup = 68193;
}
struct WorldStateIds
{
public const uint Show = 4390;
public const uint Count = 4389;
}
enum AnnouncerMessages
{
Beasts = 724001,
Jaraxxus = 724002,
Crusaders = 724003,
Valkiries = 724004,
LichKing = 724005,
Anubarak = 724006
}
struct CreatureIds
{
public const uint Barrent = 34816;
public const uint Tirion = 34996;
public const uint TirionFordring = 36095;
public const uint ArgentMage = 36097;
public const uint Fizzlebang = 35458;
public const uint Garrosh = 34995;
public const uint Varian = 34990;
public const uint LichKing = 35877;
public const uint Thrall = 34994;
public const uint Proudmoore = 34992;
public const uint WilfredPortal = 17965;
public const uint Trigger = 35651;
public const uint Icehowl = 34797;
public const uint Gormok = 34796;
public const uint Dreadscale = 34799;
public const uint Acidmaw = 35144;
public const uint Jaraxxus = 34780;
public const uint ChampionsController = 34781;
public const uint AllianceDeathKnight = 34461;
public const uint AllianceDruidBalance = 34460;
public const uint AllianceDruidRestoration = 34469;
public const uint AllianceHunter = 34467;
public const uint AllianceMage = 34468;
public const uint AlliancePaladinHoly = 34465;
public const uint AlliancePaladinRetribution = 34471;
public const uint AlliancePriestDiscipline = 34466;
public const uint AlliancePriestShadow = 34473;
public const uint AllianceRogue = 34472;
public const uint AllianceShamanEnhancement = 34463;
public const uint AllianceShamanRestoration = 34470;
public const uint AllianceWarlock = 34474;
public const uint AllianceWarrior = 34475;
public const uint HordeDeathKnight = 34458;
public const uint HordeDruidBalance = 34451;
public const uint HordeDruidRestoration = 34459;
public const uint HordeHunter = 34448;
public const uint HordeMage = 34449;
public const uint HordePaladinHoly = 34445;
public const uint HordePaladinRetribution = 34456;
public const uint HordePriestDiscipline = 34447;
public const uint HordePriestShadow = 34441;
public const uint HordeRogue = 34454;
public const uint HordeShamanEnhancement = 34455;
public const uint HordeShamanRestoration = 34444;
public const uint HordeWarlock = 34450;
public const uint HordeWarrior = 34453;
public const uint Lightbane = 34497;
public const uint Darkbane = 34496;
public const uint DarkEssence = 34567;
public const uint LightEssence = 34568;
public const uint Anubarak = 34564;
};
struct GameObjectIds
{
public const uint CrusadersCache10 = 195631;
public const uint CrusadersCache25 = 195632;
public const uint CrusadersCache10H = 195633;
public const uint CrusadersCache25H = 195635;
// Tribute Chest (Heroic)
// 10-Man Modes
public const uint TributeChest10h25 = 195668; // 10man 01-24 Attempts
public const uint TributeChest10h45 = 195667; // 10man 25-44 Attempts
public const uint TributeChest10h50 = 195666; // 10man 45-49 Attempts
public const uint TributeChest10h99 = 195665; // 10man 50 Attempts
// 25-Man Modes
public const uint TributeChest25h25 = 195672; // 25man 01-24 Attempts
public const uint TributeChest25h45 = 195671; // 25man 25-44 Attempts
public const uint TributeChest25h50 = 195670; // 25man 45-49 Attempts
public const uint TributeChest25h99 = 195669; // 25man 50 Attempts
public const uint ArgentColiseumFloor = 195527; //20943
public const uint MainGateDoor = 195647;
public const uint EastPortcullis = 195648;
public const uint WebDoor = 195485;
public const uint PortalToDalaran = 195682;
}
struct AchievementData
{
// Northrend Beasts
public const uint UpperBackPain10Player = 11779;
public const uint UpperBackPain10PlayerHeroic = 11802;
public const uint UpperBackPain25Player = 11780;
public const uint UpperBackPain25PlayerHeroic = 11801;
// Lord Jaraxxus
public const uint ThreeSixtyPainSpike10Player = 11838;
public const uint ThreeSixtyPainSpike10PlayerHeroic = 11861;
public const uint ThreeSixtyPainSpike25Player = 11839;
public const uint ThreeSixtyPainSpike25PlayerHeroic = 11862;
// Tribute
public const uint ATributeToSkill10Player = 12344;
public const uint ATributeToSkill25Player = 12338;
public const uint ATributeToMadSkill10Player = 12347;
public const uint ATributeToMadSkill25Player = 12341;
public const uint ATributeToInsanity10Player = 12349;
public const uint ATributeToInsanity25Player = 12343;
public const uint ATributeToImmortalityHorde = 12358;
public const uint ATributeToImmortalityAlliance = 12359;
public const uint ATributeToDedicatedInsanity = 12360;
public const uint RealmFirstGrandCrusader = 12350;
// Dummy Spells - Not Existing In Dbc But We Don'T Need That
public const uint SpellWormsKilledIn10Seconds = 68523;
public const uint SpellChampionsKilledInMinute = 68620;
public const uint SpellDefeatFactionChampions = 68184;
public const uint SpellTraitorKing10 = 68186;
public const uint SpellTraitorKing25 = 68515;
// Timed Events
public const uint EventStartTwinsFight = 21853;
}
struct NorthrendBeasts
{
public const uint GormokInProgress = 1000;
public const uint GormokDone = 1001;
public const uint SnakesInProgress = 2000;
public const uint DreadscaleSubmerged = 2001;
public const uint AcidmawSubmerged = 2002;
public const uint SnakesSpecial = 2003;
public const uint SnakesDone = 2004;
public const uint IcehowlInProgress = 3000;
public const uint IcehowlDone = 3001;
}
struct Texts
{
// Highlord Tirion Fordring - 34996
public const uint Stage_0_01 = 0;
public const uint Stage_0_02 = 1;
public const uint Stage_0_04 = 2;
public const uint Stage_0_05 = 3;
public const uint Stage_0_06 = 4;
public const uint Stage_0_Wipe = 5;
public const uint Stage_1_01 = 6;
public const uint Stage_1_07 = 7;
public const uint Stage_1_08 = 8;
public const uint Stage_1_11 = 9;
public const uint Stage_2_01 = 10;
public const uint Stage_2_03 = 11;
public const uint Stage_2_06 = 12;
public const uint Stage_3_01 = 13;
public const uint Stage_3_02 = 14;
public const uint Stage_4_01 = 15;
public const uint Stage_4_03 = 16;
// Varian Wrynn
public const uint Stage_0_03a = 0;
public const uint Stage_1_10 = 1;
public const uint Stage_2_02a = 2;
public const uint Stage_2_04a = 3;
public const uint Stage_2_05a = 4;
public const uint Stage_3_03a = 5;
// Garrosh
public const uint Stage_0_03h = 0;
public const uint Stage_1_09 = 1;
public const uint Stage_2_02h = 2;
public const uint Stage_2_04h = 3;
public const uint Stage_2_05h = 4;
public const uint Stage_3_03h = 5;
// Wilfred Fizzlebang
public const uint Stage_1_02 = 0;
public const uint Stage_1_03 = 1;
public const uint Stage_1_04 = 2;
public const uint Stage_1_06 = 3;
// Lord Jaraxxus
public const uint Stage_1_05 = 0;
// The Lich King
public const uint Stage_4_02 = 0;
public const uint Stage_4_05 = 1;
public const uint Stage_4_04 = 2;
// Highlord Tirion Fordring - 36095
public const uint Stage_4_06 = 0;
public const uint Stage_4_07 = 1;
}
struct MiscData
{
public const uint DespawnTime = 300000;
public const uint DisplayIdDestroyedFloor = 9060;
public static BossBoundaryEntry[] boundaries =
{
new BossBoundaryEntry(DataTypes.BossBeasts, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
new BossBoundaryEntry(DataTypes.BossJaraxxus, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
new BossBoundaryEntry(DataTypes.BossCrusaders, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
new BossBoundaryEntry(DataTypes.BossValkiries, new CircleBoundary(new Position(563.26f, 139.6f), 75.0)),
new BossBoundaryEntry(DataTypes.BossAnubarak, new EllipseBoundary(new Position(746.0f, 135.0f), 100.0, 75.0))
};
public static _Messages[] _GossipMessage =
{
new _Messages(AnnouncerMessages.Beasts, eTradeskill.GossipActionInfoDef + 1, false, DataTypes.BossBeasts),
new _Messages(AnnouncerMessages.Jaraxxus, eTradeskill.GossipActionInfoDef + 2, false, DataTypes.BossJaraxxus),
new _Messages(AnnouncerMessages.Crusaders, eTradeskill.GossipActionInfoDef + 3, false, DataTypes.BossCrusaders),
new _Messages(AnnouncerMessages.Valkiries, eTradeskill.GossipActionInfoDef + 4, false, DataTypes.BossValkiries),
new _Messages(AnnouncerMessages.LichKing, eTradeskill.GossipActionInfoDef + 5, false, DataTypes.BossAnubarak),
new _Messages(AnnouncerMessages.Anubarak, eTradeskill.GossipActionInfoDef + 6, true, DataTypes.BossAnubarak)
};
public static Position[] ToCSpawnLoc =
{
new Position(563.912f, 261.625f, 394.73f, 4.70437f), // 0 Center
new Position( 575.451f, 261.496f, 394.73f, 4.6541f), // 1 Left
new Position( 549.951f, 261.55f, 394.73f, 4.74835f) // 2 Right
};
public static Position[] ToCCommonLoc =
{
new Position(559.257996f, 90.266197f, 395.122986f, 0), // 0 Barrent
new Position(563.672974f, 139.571f, 393.837006f, 0), // 1 Center
new Position(563.833008f, 187.244995f, 394.5f, 0), // 2 Backdoor
new Position(577.347839f, 195.338888f, 395.14f, 0), // 3 - Right
new Position(550.955933f, 195.338888f, 395.14f, 0), // 4 - Left
new Position(563.833008f, 195.244995f, 394.585561f, 0), // 5 - Center
new Position(573.5f, 180.5f, 395.14f, 0), // 6 Move 0 Right
new Position(553.5f, 180.5f, 395.14f, 0), // 7 Move 0 Left
new Position(573.0f, 170.0f, 395.14f, 0), // 8 Move 1 Right
new Position(555.5f, 170.0f, 395.14f, 0), // 9 Move 1 Left
new Position(563.8f, 216.1f, 395.1f, 0), // 10 Behind the door
new Position(575.042358f, 195.260727f, 395.137146f, 0), // 5
new Position(552.248901f, 195.331955f, 395.132658f, 0), // 6
new Position(573.342285f, 195.515823f, 395.135956f, 0), // 7
new Position(554.239929f, 195.825577f, 395.137909f, 0), // 8
new Position(571.042358f, 195.260727f, 395.137146f, 0), // 9
new Position(556.720581f, 195.015472f, 395.132658f, 0), // 10
new Position(569.534119f, 195.214478f, 395.139526f, 0), // 11
new Position(569.231201f, 195.941071f, 395.139526f, 0), // 12
new Position(558.811610f, 195.985779f, 394.671661f, 0), // 13
new Position(567.641724f, 195.351501f, 394.659943f, 0), // 14
new Position(560.633972f, 195.391708f, 395.137543f, 0), // 15
new Position(565.816956f, 195.477921f, 395.136810f, 0) // 16
};
public static Position[] JaraxxusLoc =
{
new Position(508.104767f, 138.247345f, 395.128052f, 0), // 0 - Fizzlebang start location
new Position(548.610596f, 139.807800f, 394.321838f, 0), // 1 - fizzlebang end
new Position(581.854187f, 138.0f, 394.319f, 0), // 2 - Portal Right
new Position(550.558838f, 138.0f, 394.319f, 0) // 3 - Portal Left
};
public static Position[] FactionChampionLoc =
{
new Position(514.231f, 105.569f, 418.234f, 0), // 0 - Horde Initial Pos 0
new Position(508.334f, 115.377f, 418.234f, 0), // 1 - Horde Initial Pos 1
new Position(506.454f, 126.291f, 418.234f, 0), // 2 - Horde Initial Pos 2
new Position(506.243f, 106.596f, 421.592f, 0), // 3 - Horde Initial Pos 3
new Position(499.885f, 117.717f, 421.557f, 0), // 4 - Horde Initial Pos 4
new Position(613.127f, 100.443f, 419.74f, 0), // 5 - Ally Initial Pos 0
new Position(621.126f, 128.042f, 418.231f, 0), // 6 - Ally Initial Pos 1
new Position(618.829f, 113.606f, 418.232f, 0), // 7 - Ally Initial Pos 2
new Position(625.845f, 112.914f, 421.575f, 0), // 8 - Ally Initial Pos 3
new Position(615.566f, 109.653f, 418.234f, 0), // 9 - Ally Initial Pos 4
new Position(535.469f, 113.012f, 394.66f, 0), // 10 - Horde Final Pos 0
new Position(526.417f, 137.465f, 394.749f, 0), // 11 - Horde Final Pos 1
new Position(528.108f, 111.057f, 395.289f, 0), // 12 - Horde Final Pos 2
new Position(519.92f, 134.285f, 395.289f, 0), // 13 - Horde Final Pos 3
new Position(533.648f, 119.148f, 394.646f, 0), // 14 - Horde Final Pos 4
new Position(531.399f, 125.63f, 394.708f, 0), // 15 - Horde Final Pos 5
new Position(528.958f, 131.47f, 394.73f, 0), // 16 - Horde Final Pos 6
new Position(526.309f, 116.667f, 394.833f, 0), // 17 - Horde Final Pos 7
new Position(524.238f, 122.411f, 394.819f, 0), // 18 - Horde Final Pos 8
new Position(521.901f, 128.488f, 394.832f, 0) // 19 - Horde Final Pos 9
};
public static Position[] TwinValkyrsLoc =
{
new Position(586.060242f, 117.514809f, 394.41f, 0), // 0 - Dark essence 1
new Position(541.602112f, 161.879837f, 394.41f, 0), // 1 - Dark essence 2
new Position(541.021118f, 117.262932f, 394.41f, 0), // 2 - Light essence 1
new Position(586.200562f, 162.145523f, 394.41f, 0) // 3 - Light essence 2
};
public static Position[] LichKingLoc =
{
new Position(563.549f, 152.474f, 394.393f, 0), // 0 - Lich king start
new Position(563.547f, 141.613f, 393.908f, 0) // 1 - Lich king end
};
public static Position[] AnubarakLoc =
{
new Position(787.932556f, 133.289780f, 142.612152f, 0), // 0 - Anub'arak start location
new Position(695.240051f, 137.834824f, 142.200000f, 0), // 1 - Anub'arak move point location
new Position(694.886353f, 102.484665f, 142.119614f, 0), // 3 - Nerub Spawn
new Position(694.500671f, 185.363968f, 142.117905f, 0), // 5 - Nerub Spawn
new Position(731.987244f, 83.3824690f, 142.119614f, 0), // 2 - Nerub Spawn
new Position(740.184509f, 193.443390f, 142.117584f, 0) // 4 - Nerub Spawn
};
public static Position[] EndSpawnLoc =
{
new Position(648.9167f, 131.0208f, 141.6161f, 0), // 0 - Highlord Tirion Fordring
new Position(649.1614f, 142.0399f, 141.3057f, 0), // 1 - Argent Mage
new Position(644.6250f, 149.2743f, 140.6015f, 0) // 2 - Portal to Dalaran
};
}
struct _Messages
{
public _Messages(AnnouncerMessages _msg, uint _id, bool _state, uint _encounter)
{
msgnum = _msg;
id = _id;
state = _state;
encounter = _encounter;
}
public AnnouncerMessages msgnum;
public uint id;
public bool state;
public uint encounter;
}
}
+223
View File
@@ -0,0 +1,223 @@
/*
* 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 Framework.Database;
using Game.AI;
using Game.Entities;
using Game.Mails;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.Northrend
{
struct DalaranConst
{
//Mageguard
public const uint SpellTrespasserA = 54028;
public const uint SpellTrespasserH = 54029;
public const uint SpellSunreaverDisguiseFemale = 70973;
public const uint SpellSunreaverDisguiseMale = 70974;
public const uint SpellSilverConenantDisguiseFemale = 70971;
public const uint SpellSilverConenantDisguiseMale = 70972;
public const int NpcAplleboughA = 29547;
public const int NpcSweetberryH = 29715;
//Minigob
public const int SpellManabonked = 61834;
public const int SpellTeleportVisual = 51347;
public const int SpellImprovedBlink = 61995;
public const int EventSelectTarget = 1;
public const int EventBlink = 2;
public const int EventDespawnVisual = 3;
public const int EventDespawn = 4;
public const int MailMinigobEntry = 264;
public const int MailDeliverDelayMin = 5 * Time.Minute;
public const int MailDeliverDelayMax = 15 * Time.Minute;
}
[Script]
class npc_mageguard_dalaran : CreatureScript
{
public npc_mageguard_dalaran() : base("npc_mageguard_dalaran") { }
class npc_mageguard_dalaranAI : ScriptedAI
{
public npc_mageguard_dalaranAI(Creature creature) : base(creature)
{
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchools.Normal, true);
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
}
public override void Reset() { }
public override void EnterCombat(Unit who) { }
public override void AttackStart(Unit who) { }
public override void MoveInLineOfSight(Unit who)
{
if (!who || !who.IsInWorld || who.GetZoneId() != 4395)
return;
if (!me.IsWithinDist(who, 65.0f, false))
return;
Player player = who.GetCharmerOrOwnerPlayerOrPlayerItself();
if (!player || player.IsGameMaster() || player.IsBeingTeleported() ||
// If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
player.HasAura(DalaranConst.SpellSunreaverDisguiseFemale) || player.HasAura(DalaranConst.SpellSunreaverDisguiseMale) ||
player.HasAura(DalaranConst.SpellSilverConenantDisguiseFemale) || player.HasAura(DalaranConst.SpellSilverConenantDisguiseMale))
return;
switch (me.GetEntry())
{
case 29254:
if (player.GetTeam() == Team.Horde) // Horde unit found in Alliance area
{
if (GetClosestCreatureWithEntry(me, DalaranConst.NpcAplleboughA, 32.0f))
{
if (me.isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
DoCast(who, DalaranConst.SpellTrespasserA); // Teleport the Horde unit out
}
else // In my line of sight, and "indoors"
DoCast(who, DalaranConst.SpellTrespasserA); // Teleport the Horde unit out
}
break;
case 29255:
if (player.GetTeam() == Team.Alliance) // Alliance unit found in Horde area
{
if (GetClosestCreatureWithEntry(me, DalaranConst.NpcSweetberryH, 32.0f))
{
if (me.isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me
DoCast(who, DalaranConst.SpellTrespasserH); // Teleport the Alliance unit out
}
else // In my line of sight, and "indoors"
DoCast(who, DalaranConst.SpellTrespasserH); // Teleport the Alliance unit out
}
break;
}
me.SetOrientation(me.GetHomePosition().GetOrientation());
return;
}
public override void UpdateAI(uint diff) { }
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_mageguard_dalaranAI(creature);
}
}
[Script]
class npc_minigob_manabonk : CreatureScript
{
public npc_minigob_manabonk() : base("npc_minigob_manabonk") { }
class npc_minigob_manabonkAI : ScriptedAI
{
public npc_minigob_manabonkAI(Creature creature) : base(creature)
{
me.setActive(true);
}
public override void Reset()
{
me.SetVisible(false);
_events.ScheduleEvent(DalaranConst.EventSelectTarget, Time.InMilliseconds);
}
Player SelectTargetInDalaran()
{
List<Player> PlayerInDalaranList = new List<Player>();
var players = me.GetMap().GetPlayers();
foreach (var player in players)
{
if (player.GetZoneId() == me.GetZoneId() && !player.IsFlying() && !player.IsMounted() && !player.IsGameMaster())
PlayerInDalaranList.Add(player);
}
if (PlayerInDalaranList.Empty())
return null;
return PlayerInDalaranList.PickRandom();
}
void SendMailToPlayer(Player player)
{
SQLTransaction trans = new SQLTransaction();
uint deliverDelay = RandomHelper.URand(DalaranConst.MailDeliverDelayMin, DalaranConst.MailDeliverDelayMax);
new MailDraft(DalaranConst.MailMinigobEntry, true).SendMailTo(trans, new MailReceiver(player), new MailSender(MailMessageType.Creature, me.GetEntry()), MailCheckMask.None, deliverDelay);
DB.Characters.CommitTransaction(trans);
}
public override void UpdateAI(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case DalaranConst.EventSelectTarget:
me.SetVisible(true);
DoCast(me, DalaranConst.SpellTeleportVisual);
Player player = SelectTargetInDalaran();
if (player)
{
me.NearTeleportTo(player.GetPositionX(), player.GetPositionY(), player.GetPositionZ(), 0.0f);
DoCast(player, DalaranConst.SpellManabonked);
SendMailToPlayer(player);
}
_events.ScheduleEvent(DalaranConst.EventBlink, 3 * Time.InMilliseconds);
break;
case DalaranConst.EventBlink:
{
DoCast(me, DalaranConst.SpellImprovedBlink);
Position pos = me.GetRandomNearPosition(RandomHelper.FRand(15, 40));
me.GetMotionMaster().MovePoint(0, pos.posX, pos.posY, pos.posZ);
_events.ScheduleEvent(DalaranConst.EventDespawn, 3 * Time.InMilliseconds);
_events.ScheduleEvent(DalaranConst.EventDespawnVisual, (uint)(2.5 * Time.InMilliseconds));
break;
}
case DalaranConst.EventDespawnVisual:
DoCast(me, DalaranConst.SpellTeleportVisual);
break;
case DalaranConst.EventDespawn:
me.DespawnOrUnsummon();
break;
default:
break;
}
});
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_minigob_manabonkAI(creature);
}
}
}
@@ -0,0 +1,281 @@
/*
* 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;
namespace Scripts.Northrend.DraktharonKeep.KingDred
{
struct SpellIds
{
public const uint BellowingRoar = 22686; // Fears The Group; Can Be Resisted/Dispelled
public const uint GrievousBite = 48920;
public const uint ManglingSlash = 48873; // Cast On The Current Tank; Adds Debuf
public const uint FearsomeRoar = 48849;
public const uint PiercingSlash = 48878; // Debuff --> Armor Reduced By 75%
public const uint RaptorCall = 59416; // Dummy
public const uint GutRip = 49710;
public const uint Rend = 13738;
}
struct Misc
{
public const int ActionRaptorKilled = 1;
public const uint DataRaptorsKilled = 2;
}
[Script]
class boss_king_dred : CreatureScript
{
public boss_king_dred() : base("boss_king_dred") { }
class boss_king_dredAI : BossAI
{
public boss_king_dredAI(Creature creature) : base(creature, DTKDataTypes.KingDred)
{
Initialize();
}
void Initialize()
{
raptorsKilled = 0;
}
public override void Reset()
{
Initialize();
_Reset();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(33), task =>
{
DoCastAOE(SpellIds.BellowingRoar);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.GrievousBite);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(18.5), task =>
{
DoCastVictim(SpellIds.ManglingSlash);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task =>
{
DoCastAOE(SpellIds.FearsomeRoar);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
{
DoCastVictim(SpellIds.PiercingSlash);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25), task =>
{
DoCastVictim(SpellIds.RaptorCall);
float x, y, z;
me.GetClosePoint(out x, out y, out z, me.GetObjectSize() / 3, 10.0f);
me.SummonCreature(RandomHelper.RAND(DTKCreatureIds.DrakkariGutripper, DTKCreatureIds.DrakkariScytheclaw), x, y, z, 0, TempSummonType.DeadDespawn, 1000);
task.Repeat();
});
}
public override void DoAction(int action)
{
if (action == Misc.ActionRaptorKilled)
++raptorsKilled;
}
public override uint GetData(uint type)
{
if (type == Misc.DataRaptorsKilled)
return raptorsKilled;
return 0;
}
public override void JustDied(Unit killer)
{
_JustDied();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
byte raptorsKilled;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_king_dredAI>(creature);
}
}
[Script]
class npc_drakkari_gutripper : CreatureScript
{
public npc_drakkari_gutripper() : base("npc_drakkari_gutripper") { }
class npc_drakkari_gutripperAI : ScriptedAI
{
public npc_drakkari_gutripperAI(Creature creature) : base(creature)
{
Initialize();
instance = me.GetInstanceScript();
}
void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), task =>
{
DoCastVictim(SpellIds.GutRip, false);
task.Repeat();
});
}
public override void Reset()
{
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
Creature dred = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.KingDred));
if (dred)
dred.GetAI().DoAction(Misc.ActionRaptorKilled);
}
InstanceScript instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_gutripperAI>(creature);
}
}
[Script]
class npc_drakkari_scytheclaw : CreatureScript
{
public npc_drakkari_scytheclaw() : base("npc_drakkari_scytheclaw") { }
class npc_drakkari_scytheclawAI : ScriptedAI
{
public npc_drakkari_scytheclawAI(Creature creature) : base(creature)
{
Initialize();
instance = me.GetInstanceScript();
}
void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15), task =>
{
DoCastVictim(SpellIds.Rend, false);
task.Repeat();
});
}
public override void Reset()
{
_scheduler.CancelAll();
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
Creature dred = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.KingDred));
if (dred)
dred.GetAI().DoAction(Misc.ActionRaptorKilled);
}
InstanceScript instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_scytheclawAI>(creature);
}
}
[Script]
class achievement_king_dred : AchievementCriteriaScript
{
public achievement_king_dred() : base("achievement_king_dred") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature dred = target.ToCreature();
if (dred)
if (dred.GetAI().GetData(Misc.DataRaptorsKilled) >= 6)
return true;
return false;
}
}
}
@@ -0,0 +1,440 @@
/*
* 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;
namespace Scripts.Northrend.DraktharonKeep.Novos
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayKill = 1;
public const uint SayDeath = 2;
public const uint SaySummoningAdds = 3; // Unused
public const uint SayArcaneField = 4;
public const uint EmoteSummoningAdds = 5; // Unused
}
struct SpellIds
{
public const uint BeamChannel = 52106;
public const uint ArcaneField = 47346;
public const uint SummonRisenShadowcaster = 49105;
public const uint SummonFetidTrollCorpse = 49103;
public const uint SummonHulkingCorpse = 49104;
public const uint SummonCrystalHandler = 49179; //not used
public const uint SummonCopyOfMinions = 59933; //not used
public const uint ArcaneBlast = 49198;
public const uint Blizzard = 49034;
public const uint Frostbolt = 49037;
public const uint WrathOfMisery = 50089;
public const uint SummonMinions = 59910;
}
struct Misc
{
public const int ActionResetCrystals = 0;
public const int ActionActivateCrystal = 1;
public const int ActionDeactivate = 2;
public const uint EventAttack = 3;
public const uint EventSummonMinions = 4;
public const uint EventSummonRisenShadowcaster = 5;
public const uint EventSummonFetidTrollCorpse = 6;
public const uint EventSummonHulkingCorpse = 7;
public const uint EventSummonCrystalHandler = 8;
public const uint DataNovosAchiev = 9;
public static SummonerInfo[] summoners =
{
new SummonerInfo(EventSummonRisenShadowcaster, 7),
new SummonerInfo(EventSummonFetidTrollCorpse, 3),
new SummonerInfo(EventSummonHulkingCorpse, 30),
new SummonerInfo(EventSummonCrystalHandler, 15)
};
public struct SummonerInfo
{
public SummonerInfo(uint _eventid, uint _timer)
{
eventId = _eventid;
timer = _timer;
}
public uint eventId;
public uint timer;
}
public static Position[] SummonPositions =
{
new Position(-306.8209f, -703.7687f, 27.2919f, 3.401838f),
new Position(-421.395f, -705.7863f, 28.57594f, 4.830696f),
new Position(-308.1955f, -704.8419f, 27.2919f, 3.010279f),
new Position(-424.1306f, -705.7354f, 28.57594f, 5.325676f)
};
public const float MaxYCoordOhNovosMAX = -771.95f;
}
[Script]
class boss_novos : CreatureScript
{
public boss_novos() : base("boss_novos") { }
class boss_novosAI : BossAI
{
public boss_novosAI(Creature creature) : base(creature, DTKDataTypes.Novos)
{
Initialize();
_bubbled = false;
}
void Initialize()
{
_ohNovos = true;
}
public override void Reset()
{
_Reset();
Initialize();
SetCrystalsStatus(false);
SetSummonerStatus(false);
SetBubbled(false);
}
public override void EnterCombat(Unit victim)
{
_EnterCombat();
Talk(TextIds.SayAggro);
SetCrystalsStatus(true);
SetSummonerStatus(true);
SetBubbled(true);
}
public override void AttackStart(Unit target)
{
if (!target)
return;
if (me.Attack(target, true))
DoStartNoMovement(target);
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(TextIds.SayKill);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || _bubbled)
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventSummonMinions:
DoCast(SpellIds.SummonMinions);
_events.ScheduleEvent(Misc.EventSummonMinions, 15000);
break;
case Misc.EventAttack:
Unit victim = SelectTarget(SelectAggroTarget.Random);
if (victim)
DoCast(victim, RandomHelper.RAND(SpellIds.ArcaneBlast, SpellIds.Blizzard, SpellIds.Frostbolt, SpellIds.WrathOfMisery));
_events.ScheduleEvent(Misc.EventAttack, 3000);
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
}
public override void DoAction(int action)
{
if (action == DTKDataTypes.ActionCrystalHandlerDied)
{
Talk(TextIds.SayArcaneField);
SetSummonerStatus(false);
SetBubbled(false);
_events.ScheduleEvent(Misc.EventAttack, 3000);
if (IsHeroic())
_events.ScheduleEvent(Misc.EventSummonMinions, 15000);
}
}
public override void MoveInLineOfSight(Unit who)
{
base.MoveInLineOfSight(who);
if (!_ohNovos || !who || !who.IsTypeId(TypeId.Player) || who.GetPositionY() > Misc.MaxYCoordOhNovosMAX)
return;
uint entry = who.GetEntry();
if (entry == DTKCreatureIds.HulkingCorpse || entry == DTKCreatureIds.RisenShadowcaster || entry == DTKCreatureIds.FetidTrollCorpse)
_ohNovos = false;
}
public override uint GetData(uint type)
{
return type == Misc.DataNovosAchiev && _ohNovos ? 1 : 0u;
}
public override void JustSummoned(Creature summon)
{
me.Yell(TextIds.SaySummoningAdds, summon);
me.TextEmote(TextIds.EmoteSummoningAdds, summon);
summon.SelectNearestTargetInAttackDistance(50f);
summons.Summon(summon);
}
void SetBubbled(bool state)
{
_bubbled = state;
if (!state)
{
if (me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable))
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
if (me.HasUnitState(UnitState.Casting))
me.CastStop();
}
else
{
if (!me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable))
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
DoCast(SpellIds.ArcaneField);
}
}
void SetSummonerStatus(bool active)
{
for (byte i = 0; i < 4; i++)
{
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.NovosSummoner1 + i);
if (!guid.IsEmpty())
{
Creature crystalChannelTarget = ObjectAccessor.GetCreature(me, guid);
if (crystalChannelTarget)
{
if (active)
crystalChannelTarget.GetAI().SetData(Misc.summoners[i].eventId, Misc.summoners[i].timer);
else
crystalChannelTarget.GetAI().Reset();
}
}
}
}
void SetCrystalsStatus(bool active)
{
for (byte i = 0; i < 4; i++)
{
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.NovosCrystal1 + i);
if (!guid.IsEmpty())
{
GameObject crystal = ObjectAccessor.GetGameObject(me, guid);
if (crystal)
SetCrystalStatus(crystal, active);
}
}
}
void SetCrystalStatus(GameObject crystal, bool active)
{
crystal.SetGoState(active ? GameObjectState.Active : GameObjectState.Ready);
Creature crystalChannelTarget = crystal.FindNearestCreature(DTKCreatureIds.CrystalChannelTarget, 5.0f);
if (crystalChannelTarget)
{
if (active)
crystalChannelTarget.CastSpell(null, SpellIds.BeamChannel);
else if (crystalChannelTarget.HasUnitState(UnitState.Casting))
crystalChannelTarget.CastStop();
}
}
bool _ohNovos;
bool _bubbled;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_novosAI>(creature);
}
}
[Script]
class npc_crystal_channel_target : CreatureScript
{
public npc_crystal_channel_target() : base("npc_crystal_channel_target") { }
class npc_crystal_channel_targetAI : ScriptedAI
{
public npc_crystal_channel_targetAI(Creature creature) : base(creature) { }
public override void Reset()
{
_events.Reset();
_crystalHandlerCount = 0;
}
public override void UpdateAI(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventSummonCrystalHandler:
me.SummonCreature(DTKCreatureIds.CrystalHandler, Misc.SummonPositions[_crystalHandlerCount++]);
if (_crystalHandlerCount < 4)
_events.Repeat(TimeSpan.FromSeconds(15));
break;
case Misc.EventSummonRisenShadowcaster:
DoCast(SpellIds.SummonRisenShadowcaster);
_events.Repeat(TimeSpan.FromSeconds(7));
break;
case Misc.EventSummonFetidTrollCorpse:
DoCast(SpellIds.SummonFetidTrollCorpse);
_events.Repeat(TimeSpan.FromSeconds(3));
break;
case Misc.EventSummonHulkingCorpse:
DoCast(SpellIds.SummonHulkingCorpse);
_events.Repeat(TimeSpan.FromSeconds(30));
break;
}
});
}
public override void SetData(uint id, uint value)
{
_events.ScheduleEvent(id, TimeSpan.FromSeconds(value));
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
if (_crystalHandlerCount < 4)
return;
InstanceScript instance = me.GetInstanceScript();
if (instance != null)
{
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.Novos);
if (!guid.IsEmpty())
{
Creature novos = ObjectAccessor.GetCreature(me, guid);
if (novos)
novos.GetAI().DoAction(DTKDataTypes.ActionCrystalHandlerDied);
}
}
}
public override void JustSummoned(Creature summon)
{
InstanceScript instance = me.GetInstanceScript();
if (instance != null)
{
ObjectGuid guid = instance.GetGuidData(DTKDataTypes.Novos);
if (!guid.IsEmpty())
{
Creature novos = ObjectAccessor.GetCreature(me, guid);
if (novos)
novos.GetAI().JustSummoned(summon);
}
}
if (summon)
summon.GetMotionMaster().MovePath(summon.GetEntry() * 100, false);
}
uint _crystalHandlerCount;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_crystal_channel_targetAI>(creature);
}
}
[Script]
class achievement_oh_novos : AchievementCriteriaScript
{
public achievement_oh_novos() : base("achievement_oh_novos") { }
public override bool OnCheck(Player player, Unit target)
{
return target && target.IsTypeId(TypeId.Unit) && target.ToCreature().GetAI().GetData(Misc.DataNovosAchiev) != 0;
}
}
[Script]
class spell_novos_summon_minions : SpellScriptLoader
{
public spell_novos_summon_minions() : base("spell_novos_summon_minions") { }
class spell_novos_summon_minions_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.SummonCopyOfMinions);
}
void HandleScript(uint effIndex)
{
for (byte i = 0; i < 2; ++i)
GetCaster().CastSpell((Unit)null, SpellIds.SummonCopyOfMinions, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_novos_summon_minions_SpellScript();
}
}
}
@@ -0,0 +1,251 @@
/*
* 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.Scripting;
using Game.Spells;
using System;
namespace Scripts.Northrend.DraktharonKeep.TharonJa
{
struct SpellIds
{
// Skeletal Spells (Phase 1)
public const uint CurseOfLife = 49527;
public const uint RainOfFire = 49518;
public const uint ShadowVolley = 49528;
public const uint DecayFlesh = 49356; // Cast At End Of Phase 1; Starts Phase 2
// Flesh Spells (Phase 2)
public const uint GiftOfTharonJa = 52509;
public const uint ClearGiftOfTharonJa = 53242;
public const uint EyeBeam = 49544;
public const uint LightningBreath = 49537;
public const uint PoisonCloud = 49548;
public const uint ReturnFlesh = 53463; // Channeled Spell Ending Phase Two And Returning To Phase 1. This Ability Will Stun The Party For 6 Seconds.
public const uint AchievementCheck = 61863;
public const uint FleshVisual = 52582;
public const uint Dummy = 49551;
}
struct EventIds
{
public const uint CurseOfLife = 1;
public const uint RainOfFire = 2;
public const uint ShadowVolley = 3;
public const uint EyeBeam = 4;
public const uint LightningBreath = 5;
public const uint PoisonCloud = 6;
public const uint DecayFlesh = 7;
public const uint GoingFlesh = 8;
public const uint ReturnFlesh = 9;
public const uint GoingSkeletal = 10;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayKill = 1;
public const uint SayFlesh = 2;
public const uint SaySkeleton = 3;
public const uint SayDeath = 4;
}
struct Misc
{
public const uint ModelFlesh = 27073;
}
[Script]
class boss_tharon_ja : CreatureScript
{
public boss_tharon_ja() : base("boss_tharon_ja") { }
class boss_tharon_jaAI : BossAI
{
public boss_tharon_jaAI(Creature creature) : base(creature, DTKDataTypes.TharonJa) { }
public override void Reset()
{
_Reset();
me.RestoreDisplayId();
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayAggro);
_EnterCombat();
_events.ScheduleEvent(EventIds.DecayFlesh, TimeSpan.FromSeconds(20));
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(1));
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(TextIds.SayKill);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
DoCastAOE(SpellIds.ClearGiftOfTharonJa, true);
DoCastAOE(SpellIds.AchievementCheck, true);
}
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.CurseOfLife:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.CurseOfLife);
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
}
return;
case EventIds.ShadowVolley:
DoCastVictim(SpellIds.ShadowVolley);
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
return;
case EventIds.RainOfFire:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.RainOfFire);
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
}
return;
case EventIds.LightningBreath:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.LightningBreath);
_events.ScheduleEvent(EventIds.LightningBreath, TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(7));
}
return;
case EventIds.EyeBeam:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.EyeBeam);
_events.ScheduleEvent(EventIds.EyeBeam, TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(6));
}
return;
case EventIds.PoisonCloud:
DoCastAOE(SpellIds.PoisonCloud);
_events.ScheduleEvent(EventIds.PoisonCloud, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(12));
return;
case EventIds.DecayFlesh:
DoCastAOE(SpellIds.DecayFlesh);
_events.ScheduleEvent(EventIds.GoingFlesh, TimeSpan.FromSeconds(6));
return;
case EventIds.GoingFlesh:
Talk(TextIds.SayFlesh);
me.SetDisplayId(Misc.ModelFlesh);
DoCastAOE(SpellIds.GiftOfTharonJa, true);
DoCast(me, SpellIds.FleshVisual, true);
DoCast(me, SpellIds.Dummy, true);
_events.Reset();
_events.ScheduleEvent(EventIds.ReturnFlesh, TimeSpan.FromSeconds(20));
_events.ScheduleEvent(EventIds.LightningBreath, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4));
_events.ScheduleEvent(EventIds.EyeBeam, TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8));
_events.ScheduleEvent(EventIds.PoisonCloud, TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(7));
break;
case EventIds.ReturnFlesh:
DoCastAOE(SpellIds.ReturnFlesh);
_events.ScheduleEvent(EventIds.GoingSkeletal, 6000);
return;
case EventIds.GoingSkeletal:
Talk(TextIds.SaySkeleton);
me.RestoreDisplayId();
DoCastAOE(SpellIds.ClearGiftOfTharonJa, true);
_events.Reset();
_events.ScheduleEvent(EventIds.DecayFlesh, TimeSpan.FromSeconds(20));
_events.ScheduleEvent(EventIds.CurseOfLife, TimeSpan.FromSeconds(1));
_events.ScheduleEvent(EventIds.RainOfFire, TimeSpan.FromSeconds(14), TimeSpan.FromSeconds(18));
_events.ScheduleEvent(EventIds.ShadowVolley, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_tharon_jaAI>(creature);
}
}
[Script]
class spell_tharon_ja_clear_gift_of_tharon_ja : SpellScriptLoader
{
public spell_tharon_ja_clear_gift_of_tharon_ja() : base("spell_tharon_ja_clear_gift_of_tharon_ja") { }
class spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.GiftOfTharonJa);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.RemoveAura(SpellIds.GiftOfTharonJa);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript();
}
}
}
@@ -0,0 +1,335 @@
/*
* 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.Scripting;
using Game.Spells;
using System;
namespace Scripts.Northrend.DraktharonKeep.Trollgore
{
struct SpellIds
{
public const uint InfectedWound = 49637;
public const uint Crush = 49639;
public const uint CorpseExplode = 49555;
public const uint CorpseExplodeDamage = 49618;
public const uint Consume = 49380;
public const uint ConsumeBuff = 49381;
public const uint ConsumeBuffH = 59805;
public const uint SummonInvaderA = 49456;
public const uint SummonInvaderB = 49457;
public const uint SummonInvaderC = 49458; // Can'T Find Any Sniffs
public const uint InvaderTaunt = 49405;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayKill = 1;
public const uint SayConsume = 2;
public const uint SayExplode = 3;
public const uint SayDeath = 4;
}
struct Misc
{
public const uint DataConsumptionJunction = 1;
public const uint PointLanding = 1;
public static Position Landing = new Position(-263.0534f, -660.8658f, 26.50903f, 0.0f);
}
[Script]
class boss_trollgore : CreatureScript
{
public boss_trollgore() : base("boss_trollgore") { }
class boss_trollgoreAI : BossAI
{
public boss_trollgoreAI(Creature creature) : base(creature, DTKDataTypes.Trollgore)
{
Initialize();
}
void Initialize()
{
_consumptionJunction = true;
}
public override void Reset()
{
_Reset();
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
{
Talk(TextIds.SayConsume);
DoCastAOE(SpellIds.Consume);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.Crush);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60), task =>
{
DoCastVictim(SpellIds.InfectedWound);
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
});
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
{
Talk(TextIds.SayExplode);
DoCastAOE(SpellIds.CorpseExplode);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(40), task =>
{
for (byte i = 0; i < 3; ++i)
{
Creature trigger = ObjectAccessor.GetCreature(me, instance.GetGuidData(DTKDataTypes.TrollgoreInvaderSummoner1 + i));
if (trigger)
trigger.CastSpell(trigger, RandomHelper.RAND(SpellIds.SummonInvaderA, SpellIds.SummonInvaderB, SpellIds.SummonInvaderC), true, null, null, me.GetGUID());
}
task.Repeat();
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
if (_consumptionJunction)
{
Aura ConsumeAura = me.GetAura(DungeonMode(SpellIds.ConsumeBuff, SpellIds.ConsumeBuffH));
if (ConsumeAura != null && ConsumeAura.GetStackAmount() > 9)
_consumptionJunction = false;
}
DoMeleeAttackIfReady();
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override uint GetData(uint type)
{
if (type == Misc.DataConsumptionJunction)
return _consumptionJunction ? 1 : 0u;
return 0;
}
public override void KilledUnit(Unit victim)
{
if (victim.IsTypeId(TypeId.Player))
Talk(TextIds.SayKill);
}
public override void JustSummoned(Creature summon)
{
summon.GetMotionMaster().MovePoint(Misc.PointLanding, Misc.Landing);
summons.Summon(summon);
}
bool _consumptionJunction;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_trollgoreAI>(creature);
}
}
[Script]
class npc_drakkari_invader : CreatureScript
{
public npc_drakkari_invader() : base("npc_drakkari_invader") { }
class npc_drakkari_invaderAI : ScriptedAI
{
public npc_drakkari_invaderAI(Creature creature) : base(creature) { }
public override void MovementInform(MovementGeneratorType type, uint pointId)
{
if (type == MovementGeneratorType.Point && pointId == Misc.PointLanding)
{
me.Dismount();
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc);
DoCastAOE(SpellIds.InvaderTaunt);
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_drakkari_invaderAI>(creature);
}
}
[Script] // 49380, 59803 - Consume
class spell_trollgore_consume : SpellScriptLoader
{
public spell_trollgore_consume() : base("spell_trollgore_consume") { }
class spell_trollgore_consume_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.ConsumeBuff);
}
void HandleConsume(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.CastSpell(GetCaster(), SpellIds.ConsumeBuff, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleConsume, 1, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_trollgore_consume_SpellScript();
}
}
[Script] // 49555, 59807 - Corpse Explode
class spell_trollgore_corpse_explode : SpellScriptLoader
{
public spell_trollgore_corpse_explode() : base("spell_trollgore_corpse_explode") { }
class spell_trollgore_corpse_explode_AuraScript : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.CorpseExplodeDamage);
}
void PeriodicTick(AuraEffect aurEff)
{
if (aurEff.GetTickNumber() == 2)
{
Unit caster = GetCaster();
if (caster)
caster.CastSpell(GetTarget(), SpellIds.CorpseExplodeDamage, true, null, aurEff);
}
}
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Creature target = GetTarget().ToCreature();
if (target)
target.DespawnOrUnsummon();
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 0, AuraType.Dummy));
AfterEffectRemove.Add(new EffectApplyHandler(HandleRemove, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
}
}
public override AuraScript GetAuraScript()
{
return new spell_trollgore_corpse_explode_AuraScript();
}
}
[Script] // 49405 - Invader Taunt Trigger
class spell_trollgore_invader_taunt : SpellScriptLoader
{
public spell_trollgore_invader_taunt() : base("spell_trollgore_invader_taunt") { }
class spell_trollgore_invader_taunt_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo((uint)spellInfo.GetEffect(0).CalcValue());
}
void HandleTaunt(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.CastSpell(GetCaster(), (uint)GetEffectValue(), true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleTaunt, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_trollgore_invader_taunt_SpellScript();
}
}
[Script]
class achievement_consumption_junction : AchievementCriteriaScript
{
public achievement_consumption_junction() : base("achievement_consumption_junction")
{
}
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature Trollgore = target.ToCreature();
if (Trollgore)
if (Trollgore.GetAI().GetData(Misc.DataConsumptionJunction) != 0)
return true;
return false;
}
}
}
@@ -0,0 +1,224 @@
/*
* 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 Game.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Northrend.DraktharonKeep
{
struct DTKDataTypes
{
// Encounter States/Boss Guids
public const uint Trollgore = 0;
public const uint Novos = 1;
public const uint KingDred = 2;
public const uint TharonJa = 3;
// Additional Data
//public const uint KingDredAchiev;
public const uint TrollgoreInvaderSummoner1 = 4;
public const uint TrollgoreInvaderSummoner2 = 5;
public const uint TrollgoreInvaderSummoner3 = 6;
public const uint NovosCrystal1 = 7;
public const uint NovosCrystal2 = 8;
public const uint NovosCrystal3 = 9;
public const uint NovosCrystal4 = 10;
public const uint NovosSummoner1 = 11;
public const uint NovosSummoner2 = 12;
public const uint NovosSummoner3 = 13;
public const uint NovosSummoner4 = 14;
public const int ActionCrystalHandlerDied = 15;
}
struct DTKCreatureIds
{
public const uint Trollgore = 26630;
public const uint Novos = 26631;
public const uint KingDred = 27483;
public const uint TharonJa = 26632;
// Trollgore
public const uint DrakkariInvaderA = 27709;
public const uint DrakkariInvaderB = 27753;
public const uint DrakkariInvaderC = 27754;
// Novos
public const uint CrystalChannelTarget = 26712;
public const uint CrystalHandler = 26627;
public const uint HulkingCorpse = 27597;
public const uint FetidTrollCorpse = 27598;
public const uint RisenShadowcaster = 27600;
// King Dred
public const uint DrakkariGutripper = 26641;
public const uint DrakkariScytheclaw = 26628;
public const uint WorldTrigger = 22515;
}
struct DTKGameObjectIds
{
public const uint NovosCrystal1 = 189299;
public const uint NovosCrystal2 = 189300;
public const uint NovosCrystal3 = 189301;
public const uint NovosCrystal4 = 189302;
}
[Script]
class instance_drak_tharon_keep : InstanceMapScript
{
public instance_drak_tharon_keep() : base(nameof(instance_drak_tharon_keep), 600) { }
class instance_drak_tharon_keep_InstanceScript : InstanceScript
{
public instance_drak_tharon_keep_InstanceScript(Map map) : base(map)
{
SetHeaders("DTK");
SetBossNumber(4);
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case DTKCreatureIds.Trollgore:
TrollgoreGUID = creature.GetGUID();
break;
case DTKCreatureIds.Novos:
NovosGUID = creature.GetGUID();
break;
case DTKCreatureIds.KingDred:
KingDredGUID = creature.GetGUID();
break;
case DTKCreatureIds.TharonJa:
TharonJaGUID = creature.GetGUID();
break;
case DTKCreatureIds.WorldTrigger:
InitializeTrollgoreInvaderSummoner(creature);
break;
case DTKCreatureIds.CrystalChannelTarget:
InitializeNovosSummoner(creature);
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case DTKGameObjectIds.NovosCrystal1:
NovosCrystalGUIDs[0] = go.GetGUID();
break;
case DTKGameObjectIds.NovosCrystal2:
NovosCrystalGUIDs[1] = go.GetGUID();
break;
case DTKGameObjectIds.NovosCrystal3:
NovosCrystalGUIDs[2] = go.GetGUID();
break;
case DTKGameObjectIds.NovosCrystal4:
NovosCrystalGUIDs[3] = go.GetGUID();
break;
default:
break;
}
}
void InitializeTrollgoreInvaderSummoner(Creature creature)
{
float y = creature.GetPositionY();
float z = creature.GetPositionZ();
if (z < 50.0f)
return;
if (y < -650.0f && y > -660.0f)
TrollgoreInvaderSummonerGuids[0] = creature.GetGUID();
else if (y < -660.0f && y > -670.0f)
TrollgoreInvaderSummonerGuids[1] = creature.GetGUID();
else if (y < -675.0f && y > -685.0f)
TrollgoreInvaderSummonerGuids[2] = creature.GetGUID();
}
void InitializeNovosSummoner(Creature creature)
{
float x = creature.GetPositionX();
float y = creature.GetPositionY();
float z = creature.GetPositionZ();
if (x < -374.0f && x > -379.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
NovosSummonerGUIDs[0] = creature.GetGUID();
else if (x < -379.0f && x > -385.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
NovosSummonerGUIDs[1] = creature.GetGUID();
else if (x < -374.0f && x > -385.0f && y > -827.0f && y < -820.0f && z < 60.0f && z > 58.0f)
NovosSummonerGUIDs[2] = creature.GetGUID();
else if (x < -338.0f && x > -380.0f && y > -727.0f && y < 721.0f && z < 30.0f && z > 26.0f)
NovosSummonerGUIDs[3] = creature.GetGUID();
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DTKDataTypes.Trollgore:
return TrollgoreGUID;
case DTKDataTypes.Novos:
return NovosGUID;
case DTKDataTypes.KingDred:
return KingDredGUID;
case DTKDataTypes.TharonJa:
return TharonJaGUID;
case DTKDataTypes.TrollgoreInvaderSummoner1:
case DTKDataTypes.TrollgoreInvaderSummoner2:
case DTKDataTypes.TrollgoreInvaderSummoner3:
return TrollgoreInvaderSummonerGuids[type - DTKDataTypes.TrollgoreInvaderSummoner1];
case DTKDataTypes.NovosCrystal1:
case DTKDataTypes.NovosCrystal2:
case DTKDataTypes.NovosCrystal3:
case DTKDataTypes.NovosCrystal4:
return NovosCrystalGUIDs[type - DTKDataTypes.NovosCrystal1];
case DTKDataTypes.NovosSummoner1:
case DTKDataTypes.NovosSummoner2:
case DTKDataTypes.NovosSummoner3:
case DTKDataTypes.NovosSummoner4:
return NovosSummonerGUIDs[type - DTKDataTypes.NovosSummoner1];
}
return ObjectGuid.Empty;
}
ObjectGuid TrollgoreGUID;
ObjectGuid NovosGUID;
ObjectGuid KingDredGUID;
ObjectGuid TharonJaGUID;
ObjectGuid[] TrollgoreInvaderSummonerGuids = new ObjectGuid[3];
ObjectGuid[] NovosCrystalGUIDs = new ObjectGuid[4];
ObjectGuid[] NovosSummonerGUIDs = new ObjectGuid[4];
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_drak_tharon_keep_InstanceScript(map);
}
}
}
@@ -0,0 +1,444 @@
/*
* 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.Gundrak.DrakkariColossus
{
struct TextIds
{
// Drakkari Elemental
public const uint EmoteMojo = 0;
public const uint EmoteActivateAltar = 1;
}
struct SpellIds
{
public const uint Emerge = 54850;
public const uint ElementalSpawnEffect = 54888;
public const uint MojoVolley = 54849;
public const uint SurgeVisual = 54827;
public const uint Merge = 54878;
public const uint MightyBlow = 54719;
public const uint Surge = 54801;
public const uint FreezeAnim = 16245;
public const uint MojoPuddle = 55627;
public const uint MojoWave = 55626;
}
struct Misc
{
public const uint EventMightyBlow = 1;
public const uint EventSurge = 1;
public const int ActionSummonElemental = 1;
public const int ActionFreezeColossus = 2;
public const int ActionUnfreezeColossus = 3;
public const int ActionReturnToColossus = 1;
public const byte ColossusPhaseNormal = 1;
public const byte ColossusPhaseFirstElementalSummon = 2;
public const byte ColossusPhaseSecondElementalSummon = 3;
public const uint DataColossusPhase = 1;
public const uint DataIntroDone = 2;
}
[Script]
class boss_drakkari_colossus : CreatureScript
{
public boss_drakkari_colossus() : base("boss_drakkari_colossus") { }
class boss_drakkari_colossusAI : BossAI
{
public boss_drakkari_colossusAI(Creature creature) : base(creature, GDDataTypes.DrakkariColossus)
{
Initialize();
me.SetReactState(ReactStates.Passive);
introDone = false;
}
void Initialize()
{
phase = Misc.ColossusPhaseNormal;
}
public override void Reset()
{
_Reset();
if (GetData(Misc.DataIntroDone) != 0)
{
me.SetReactState(ReactStates.Aggressive);
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
me.RemoveAura(SpellIds.FreezeAnim);
}
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), task =>
{
DoCastVictim(SpellIds.MightyBlow);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
});
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
me.RemoveAura(SpellIds.FreezeAnim);
}
public override void JustDied(Unit killer)
{
_JustDied();
}
public override void DoAction(int action)
{
switch (action)
{
case Misc.ActionSummonElemental:
DoCast(SpellIds.Emerge);
break;
case Misc.ActionFreezeColossus:
me.GetMotionMaster().Clear();
me.GetMotionMaster().MoveIdle();
me.SetReactState(ReactStates.Passive);
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
DoCast(me, SpellIds.FreezeAnim);
break;
case Misc.ActionUnfreezeColossus:
if (me.GetReactState() == ReactStates.Aggressive)
return;
me.SetReactState(ReactStates.Aggressive);
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
me.RemoveAura(SpellIds.FreezeAnim);
me.SetInCombatWithZone();
if (me.GetVictim())
me.GetMotionMaster().MoveChase(me.GetVictim(), 0, 0);
break;
}
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (me.HasFlag(UnitFields.Flags, UnitFlags.ImmuneToPc))
damage = 0;
if (phase == Misc.ColossusPhaseNormal ||
phase == Misc.ColossusPhaseFirstElementalSummon)
{
if (HealthBelowPct(phase == Misc.ColossusPhaseNormal ? 50 : 5))
{
damage = 0;
phase = (phase == Misc.ColossusPhaseNormal ? Misc.ColossusPhaseFirstElementalSummon : Misc.ColossusPhaseSecondElementalSummon);
DoAction(Misc.ActionFreezeColossus);
DoAction(Misc.ActionSummonElemental);
}
}
}
public override uint GetData(uint data)
{
if (data == Misc.DataColossusPhase)
return phase;
else if (data == Misc.DataIntroDone)
return introDone ? 1 : 0u;
return 0;
}
public override void SetData(uint type, uint data)
{
if (type == Misc.DataIntroDone)
introDone = data != 0;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
if (me.GetReactState() == ReactStates.Aggressive)
DoMeleeAttackIfReady();
}
public override void JustSummoned(Creature summon)
{
summon.SetInCombatWithZone();
if (phase == Misc.ColossusPhaseSecondElementalSummon)
summon.SetHealth(summon.GetMaxHealth() / 2);
}
byte phase;
bool introDone;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_drakkari_colossusAI>(creature);
}
}
[Script]
class boss_drakkari_elemental : CreatureScript
{
public boss_drakkari_elemental() : base("boss_drakkari_elemental") { }
class boss_drakkari_elementalAI : ScriptedAI
{
public boss_drakkari_elementalAI(Creature creature) : base(creature)
{
DoCast(me, SpellIds.ElementalSpawnEffect);
instance = creature.GetInstanceScript();
}
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15), task =>
{
DoCast(SpellIds.SurgeVisual);
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true);
if (target)
DoCast(target, SpellIds.Surge);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
});
me.AddAura(SpellIds.MojoVolley, me);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.EmoteActivateAltar);
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
if (colossus)
killer.Kill(colossus);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
public override void DoAction(int action)
{
switch (action)
{
case Misc.ActionReturnToColossus:
Talk(TextIds.EmoteMojo);
DoCast(SpellIds.SurgeVisual);
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
if (colossus)
// what if the elemental is more than 80 yards from drakkari colossus ?
DoCast(colossus, SpellIds.Merge, true);
break;
}
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (HealthBelowPct(50))
{
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
if (colossus)
{
if (colossus.GetAI().GetData(Misc.DataColossusPhase) == Misc.ColossusPhaseFirstElementalSummon)
{
damage = 0;
// to prevent spell spaming
if (me.HasUnitState(UnitState.Charging))
return;
// not sure about this, the idea of this code is to prevent bug the elemental
// if it is not in a acceptable distance to cast the charge spell.
if (me.GetDistance(colossus) > 80.0f)
{
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
return;
me.GetMotionMaster().MovePoint(0, colossus.GetPositionX(), colossus.GetPositionY(), colossus.GetPositionZ());
return;
}
DoAction(Misc.ActionReturnToColossus);
}
}
}
}
public override void EnterEvadeMode(EvadeReason why)
{
me.DespawnOrUnsummon();
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.Merge)
{
Creature colossus = target.ToCreature();
if (colossus)
{
colossus.GetAI().DoAction(Misc.ActionUnfreezeColossus);
me.DespawnOrUnsummon();
}
}
}
InstanceScript instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_drakkari_elementalAI>(creature);
}
}
[Script]
class npc_living_mojo : CreatureScript
{
public npc_living_mojo() : base("npc_living_mojo") { }
class npc_living_mojoAI : ScriptedAI
{
public npc_living_mojoAI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
}
public override void Reset()
{
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
{
DoCastVictim(SpellIds.MojoWave);
task.Repeat(TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
{
DoCastVictim(SpellIds.MojoPuddle);
task.Repeat(TimeSpan.FromSeconds(18));
});
}
void MoveMojos(Creature boss)
{
List<Creature> mojosList = new List<Creature>();
boss.GetCreatureListWithEntryInGrid(mojosList, me.GetEntry(), 12.0f);
if (!mojosList.Empty())
{
foreach (var mojo in mojosList)
{
if (mojo)
mojo.GetMotionMaster().MovePoint(1, boss.GetHomePosition());
}
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point)
return;
if (id == 1)
{
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
if (colossus)
{
colossus.GetAI().DoAction(Misc.ActionUnfreezeColossus);
if (colossus.GetAI().GetData(Misc.DataIntroDone) == 0)
colossus.GetAI().SetData(Misc.DataIntroDone, 1);
colossus.SetInCombatWithZone();
me.DespawnOrUnsummon();
}
}
}
public override void AttackStart(Unit attacker)
{
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
return;
// we do this checks to see if the creature is one of the creatures that sorround the boss
Creature colossus = instance.GetCreature(GDDataTypes.DrakkariColossus);
if (colossus)
{
Position homePosition = me.GetHomePosition();
float distance = homePosition.GetExactDist(colossus.GetHomePosition());
if (distance < 12.0f)
{
MoveMojos(colossus);
me.SetReactState(ReactStates.Passive);
}
else
base.AttackStart(attacker);
}
}
public override void UpdateAI(uint diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
InstanceScript instance;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_living_mojoAI>(creature);
}
}
}
+128
View File
@@ -0,0 +1,128 @@
/*
* 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.Scripting;
using System;
namespace Scripts.Northrend.Gundrak.EckTheFerocious
{
struct TextIds
{
public const uint EmoteSpawn = 0;
}
struct SpellIds
{
public const uint Berserk = 55816; // Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%.
public const uint Bite = 55813; // Eck bites down hard, inflicting 150% of his normal damage to an enemy.
public const uint Spit = 55814; // Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec.
public const uint Spring1 = 55815; // Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back.
public const uint Spring2 = 55837; // Eck leaps at a distant target.
}
[Script]
class boss_eck : CreatureScript
{
public boss_eck() : base("boss_eck") { }
class boss_eckAI : BossAI
{
public boss_eckAI(Creature creature) : base(creature, GDDataTypes.EckTheFerocious)
{
Initialize();
Talk(TextIds.EmoteSpawn);
}
void Initialize()
{
_berserk = false;
}
public override void Reset()
{
_Reset();
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.Bite);
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
DoCastVictim(SpellIds.Spit);
task.Repeat(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(14));
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 35.0f, true);
if (target)
DoCast(target, RandomHelper.RAND(SpellIds.Spring1, SpellIds.Spring2));
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10));
});
// 60-90 secs according to wowwiki
_scheduler.Schedule(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(90), 1, task =>
{
DoCast(me, SpellIds.Berserk);
_berserk = true;
});
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!_berserk && me.HealthBelowPctDamaged(20, damage))
{
_scheduler.RescheduleGroup(1, TimeSpan.FromSeconds(1));
_berserk = true;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
bool _berserk;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_eckAI>(creature);
}
}
}
@@ -0,0 +1,439 @@
/*
* 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 Framework.IO;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
using System.Text;
namespace Scripts.Northrend.Gundrak
{
struct GDInstanceMisc
{
public const uint TimerStatueActivation = 3500;
public static DoorData[] doorData =
{
new DoorData(GDGameObjectIds.GalDarahDoor1, GDDataTypes.GalDarah, DoorType.Passage),
new DoorData(GDGameObjectIds.GalDarahDoor2, GDDataTypes.GalDarah, DoorType.Passage),
new DoorData(GDGameObjectIds.GalDarahDoor3, GDDataTypes.GalDarah, DoorType.Room),
new DoorData(GDGameObjectIds.EckTheFerociousDoor, GDDataTypes.Moorabi, DoorType.Passage),
new DoorData(GDGameObjectIds.EckTheFerociousDoorBehind, GDDataTypes.EckTheFerocious, DoorType.Passage),
};
public static ObjectData[] creatureData =
{
new ObjectData(GDCreatureIds.DrakkariColossus, GDDataTypes.DrakkariColossus),
};
public static ObjectData[] gameObjectData =
{
new ObjectData(GDGameObjectIds.SladRanAltar, GDDataTypes.SladRanAltar),
new ObjectData(GDGameObjectIds.MoorabiAltar, GDDataTypes.MoorabiAltar),
new ObjectData(GDGameObjectIds.DrakkariColossusAltar, GDDataTypes.DrakkariColossusAltar),
new ObjectData(GDGameObjectIds.SladRanStatue, GDDataTypes.SladRanStatue),
new ObjectData(GDGameObjectIds.MoorabiStatue, GDDataTypes.MoorabiStatue),
new ObjectData(GDGameObjectIds.DrakkariColossusStatue, GDDataTypes.DrakkariColossusStatue),
new ObjectData(GDGameObjectIds.GalDarahStatue, GDDataTypes.GalDarahStatue),
new ObjectData(GDGameObjectIds.Trapdoor, GDDataTypes.Trapdoor),
new ObjectData(GDGameObjectIds.Collision, GDDataTypes.Collision)
};
public static Position EckSpawnPoint = new Position(1643.877930f, 936.278015f, 107.204948f, 0.668432f);
}
struct GDDataTypes
{
// Encounter Ids // Encounter States // Boss Guids
public const uint SladRan = 0;
public const uint DrakkariColossus = 1;
public const uint Moorabi = 2;
public const uint GalDarah = 3;
public const uint EckTheFerocious = 4;
// Additional Objects
public const uint SladRanAltar = 5;
public const uint DrakkariColossusAltar = 6;
public const uint MoorabiAltar = 7;
public const uint SladRanStatue = 8;
public const uint DrakkariColossusStatue = 9;
public const uint MoorabiStatue = 10;
public const uint GalDarahStatue = 11;
public const uint Trapdoor = 12;
public const uint Collision = 13;
public const uint Bridge = 14;
public const uint StatueActivate = 15;
}
struct GDCreatureIds
{
public const uint SladRan = 29304;
public const uint Moorabi = 29305;
public const uint GalDarah = 29306;
public const uint DrakkariColossus = 29307;
public const uint RuinDweller = 29920;
public const uint EckTheFerocious = 29932;
public const uint AltarTrigger = 30298;
}
struct GDGameObjectIds
{
public const uint SladRanAltar = 192518;
public const uint MoorabiAltar = 192519;
public const uint DrakkariColossusAltar = 192520;
public const uint SladRanStatue = 192564;
public const uint MoorabiStatue = 192565;
public const uint GalDarahStatue = 192566;
public const uint DrakkariColossusStatue = 192567;
public const uint EckTheFerociousDoor = 192632;
public const uint EckTheFerociousDoorBehind = 192569;
public const uint GalDarahDoor1 = 193208;
public const uint GalDarahDoor2 = 193209;
public const uint GalDarahDoor3 = 192568;
public const uint Trapdoor = 193188;
public const uint Collision = 192633;
}
struct GDSpellIds
{
public const uint FireBeamMammoth = 57068;
public const uint FireBeamSnake = 57071;
public const uint FireBeamElemental = 57072;
}
[Script]
class instance_gundrak : InstanceMapScript
{
public instance_gundrak() : base(nameof(instance_gundrak), 604) { }
class instance_gundrak_InstanceMapScript : InstanceScript
{
public instance_gundrak_InstanceMapScript(Map map) : base(map)
{
SetHeaders("GD");
SetBossNumber(5);
LoadDoorData(GDInstanceMisc.doorData);
LoadObjectData(GDInstanceMisc.creatureData, GDInstanceMisc.gameObjectData);
SladRanStatueState = GameObjectState.Active;
DrakkariColossusStatueState = GameObjectState.Active;
MoorabiStatueState = GameObjectState.Active;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case GDCreatureIds.RuinDweller:
if (creature.IsAlive())
DwellerGUIDs.Add(creature.GetGUID());
break;
default:
break;
}
base.OnCreatureCreate(creature);
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GDGameObjectIds.SladRanAltar:
if (GetBossState(GDDataTypes.SladRan) == EncounterState.Done)
{
if (SladRanStatueState == GameObjectState.Active)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
else
go.SetGoState(GameObjectState.Active);
}
break;
case GDGameObjectIds.MoorabiAltar:
if (GetBossState(GDDataTypes.Moorabi) == EncounterState.Done)
{
if (MoorabiStatueState == GameObjectState.Active)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
else
go.SetGoState(GameObjectState.Active);
}
break;
case GDGameObjectIds.DrakkariColossusAltar:
if (GetBossState(GDDataTypes.DrakkariColossus) == EncounterState.Done)
{
if (DrakkariColossusStatueState == GameObjectState.Active)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
else
go.SetGoState(GameObjectState.Active);
}
break;
case GDGameObjectIds.SladRanStatue:
go.SetGoState(SladRanStatueState);
break;
case GDGameObjectIds.MoorabiStatue:
go.SetGoState(MoorabiStatueState);
break;
case GDGameObjectIds.GalDarahStatue:
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.ActiveAlternative : GameObjectState.Ready);
break;
case GDGameObjectIds.DrakkariColossusStatue:
go.SetGoState(DrakkariColossusStatueState);
break;
case GDGameObjectIds.EckTheFerociousDoor:
// Don't store door on non-heroic
if (!instance.IsHeroic())
return;
break;
case GDGameObjectIds.Trapdoor:
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Ready : GameObjectState.Active);
break;
case GDGameObjectIds.Collision:
go.SetGoState(CheckRequiredBosses(GDDataTypes.GalDarah) ? GameObjectState.Active : GameObjectState.Ready);
break;
default:
break;
}
base.OnGameObjectCreate(go);
}
public override void OnUnitDeath(Unit unit)
{
if (unit.GetEntry() == GDCreatureIds.RuinDweller)
{
DwellerGUIDs.Remove(unit.GetGUID());
if (DwellerGUIDs.Empty())
unit.SummonCreature(GDCreatureIds.EckTheFerocious, GDInstanceMisc.EckSpawnPoint, TempSummonType.CorpseTimedDespawn, 300 * Time.InMilliseconds);
}
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case GDDataTypes.SladRan:
if (state == EncounterState.Done)
{
GameObject go = GetGameObject(GDDataTypes.SladRanAltar);
if (go)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
case GDDataTypes.DrakkariColossus:
if (state == EncounterState.Done)
{
GameObject go = GetGameObject(GDDataTypes.DrakkariColossusAltar);
if (go)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
case GDDataTypes.Moorabi:
if (state == EncounterState.Done)
{
GameObject go = GetGameObject(GDDataTypes.MoorabiAltar);
if (go)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
default:
break;
}
return true;
}
public override bool CheckRequiredBosses(uint bossId, Player player = null)
{
if (_SkipCheckRequiredBosses(player))
return true;
switch (bossId)
{
case GDDataTypes.EckTheFerocious:
if (!instance.IsHeroic() || GetBossState(GDDataTypes.Moorabi) != EncounterState.Done)
return false;
break;
case GDDataTypes.GalDarah:
if (SladRanStatueState != GameObjectState.ActiveAlternative
|| DrakkariColossusStatueState != GameObjectState.ActiveAlternative
|| MoorabiStatueState != GameObjectState.ActiveAlternative)
return false;
break;
default:
break;
}
return true;
}
bool IsBridgeReady()
{
return SladRanStatueState == GameObjectState.Ready && DrakkariColossusStatueState == GameObjectState.Ready && MoorabiStatueState == GameObjectState.Ready;
}
public override void SetData(uint type, uint data)
{
if (type == GDDataTypes.StatueActivate)
{
switch (data)
{
case GDGameObjectIds.SladRanAltar:
_events.ScheduleEvent(GDDataTypes.SladRanStatue, GDInstanceMisc.TimerStatueActivation);
break;
case GDGameObjectIds.DrakkariColossusAltar:
_events.ScheduleEvent(GDDataTypes.DrakkariColossusStatue, GDInstanceMisc.TimerStatueActivation);
break;
case GDGameObjectIds.MoorabiAltar:
_events.ScheduleEvent(GDDataTypes.MoorabiStatue, GDInstanceMisc.TimerStatueActivation);
break;
default:
break;
}
}
}
public override void WriteSaveDataMore(StringBuilder data)
{
data.AppendFormat("{0} {1} {2} ", (uint)SladRanStatueState, (uint)DrakkariColossusStatueState, (uint)MoorabiStatueState);
}
public override void ReadSaveDataMore(StringArguments data)
{
SladRanStatueState = (GameObjectState)data.NextUInt32();
DrakkariColossusStatueState = (GameObjectState)data.NextUInt32();
MoorabiStatueState = (GameObjectState)data.NextUInt32();
if (IsBridgeReady())
_events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation);
}
void ToggleGameObject(uint type, GameObjectState state)
{
GameObject go = GetGameObject(type);
if (go)
go.SetGoState(state);
switch (type)
{
case GDDataTypes.SladRanStatue:
SladRanStatueState = state;
break;
case GDDataTypes.DrakkariColossusStatue:
DrakkariColossusStatueState = state;
break;
case GDDataTypes.MoorabiStatue:
MoorabiStatueState = state;
break;
default:
break;
}
}
public override void Update(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
uint spellId = 0;
uint altarId = 0;
switch (eventId)
{
case GDDataTypes.SladRanStatue:
spellId = GDSpellIds.FireBeamSnake;
altarId = GDDataTypes.SladRanAltar;
break;
case GDDataTypes.DrakkariColossusStatue:
spellId = GDSpellIds.FireBeamElemental;
altarId = GDDataTypes.DrakkariColossusAltar;
break;
case GDDataTypes.MoorabiStatue:
spellId = GDSpellIds.FireBeamMammoth;
altarId = GDDataTypes.MoorabiAltar;
break;
case GDDataTypes.Bridge:
for (uint type = GDDataTypes.SladRanStatue; type <= GDDataTypes.GalDarahStatue; ++type)
ToggleGameObject(type, GameObjectState.ActiveAlternative);
ToggleGameObject(GDDataTypes.Trapdoor, GameObjectState.Ready);
ToggleGameObject(GDDataTypes.Collision, GameObjectState.Active);
SaveToDB();
return;
default:
return;
}
GameObject altar = GetGameObject(altarId);
if (altar)
{
Creature trigger = altar.FindNearestCreature(GDCreatureIds.AltarTrigger, 10.0f);
if (trigger)
trigger.CastSpell((Unit)null, spellId, true);
}
// eventId equals statueId
ToggleGameObject(eventId, GameObjectState.Ready);
if (IsBridgeReady())
_events.ScheduleEvent(GDDataTypes.Bridge, GDInstanceMisc.TimerStatueActivation);
SaveToDB();
});
}
List<ObjectGuid> DwellerGUIDs = new List<ObjectGuid>();
GameObjectState SladRanStatueState;
GameObjectState DrakkariColossusStatueState;
GameObjectState MoorabiStatueState;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_gundrak_InstanceMapScript(map);
}
}
[Script]
class go_gundrak_altar : GameObjectScript
{
public go_gundrak_altar() : base("go_gundrak_altar") { }
public override bool OnGossipHello(Player player, GameObject go)
{
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
go.SetGoState(GameObjectState.Active);
InstanceScript instance = go.GetInstanceScript();
if (instance != null)
{
instance.SetData(GDDataTypes.StatueActivate, go.GetEntry());
return true;
}
return false;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,733 @@
/*
* 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/>.
*/
namespace Scripts.Northrend.IcecrownCitadel
{
struct IccConst
{
public const uint WeeklyNPCs = 9;
}
struct Bosses
{
public const uint LordMarrowgar = 0;
public const uint LadyDeathwhisper = 1;
public const uint GunshipBattle = 2;
public const uint DeathbringerSaurfang = 3;
public const uint Festergut = 4;
public const uint Rotface = 5;
public const uint ProfessorPutricide = 6;
public const uint BloodPrinceCouncil = 7;
public const uint BloodQueenLanaThel = 8;
public const uint SisterSvalna = 9;
public const uint ValithriaDreamwalker = 10;
public const uint Sindragosa = 11;
public const uint TheLichKing = 12;
public const uint MaxEncounters = 13;
}
struct Texts
{
// Highlord Tirion Fordring (At Light'S Hammer)
public const uint SayTirionIntro1 = 0;
public const uint SayTirionIntro2 = 1;
public const uint SayTirionIntro3 = 2;
public const uint SayTirionIntro4 = 3;
public const uint SayTirionIntroH5 = 4;
public const uint SayTirionIntroA5 = 5;
// The Lich King (At Light'S Hammer)
public const uint SayLkIntro1 = 0;
public const uint SayLkIntro2 = 1;
public const uint SayLkIntro3 = 2;
public const uint SayLkIntro4 = 3;
public const uint SayLkIntro5 = 4;
// Highlord Bolvar Fordragon (At Light'S Hammer)
public const uint SayBolvarIntro1 = 0;
// High Overlord Saurfang (At Light'S Hammer)
public const uint SaySaurfangIntro1 = 15;
public const uint SaySaurfangIntro2 = 16;
public const uint SaySaurfangIntro3 = 17;
public const uint SaySaurfangIntro4 = 18;
// Muradin Bronzebeard (At Light'S Hammer)
public const uint SayMuradinIntro1 = 13;
public const uint SayMuradinIntro2 = 14;
public const uint SayMuradinIntro3 = 15;
// Deathbound Ward
public const uint SayTrapActivate = 0;
// Rotting Frost Giant
public const uint EmoteDeathPlagueWarning = 0;
// Sister Svalna
public const uint SaySvalnaKillCaptain = 1; // Happens When She Kills A Captain
public const uint SaySvalnaKill = 4;
public const uint SaySvalnaCaptainDeath = 5; // Happens When A Captain Resurrected By Her Dies
public const uint SaySvalnaDeath = 6;
public const uint EmoteSvalnaImpale = 7;
public const uint EmoteSvalnaBrokenShield = 8;
public const uint SayCrokIntro1 = 0; // Ready Your Arms; My Argent Brothers. The Vrykul Will Protect The Frost Queen With Their Lives.
public const uint SayArnathIntro2 = 5; // Even Dying Here Beats Spending Another Day Collecting Reagents For That Madman; Finklestein.
public const uint SayCrokIntro3 = 1; // Enough Idle Banter! Our Champions Have Arrived - Support Them As We Push Our Way Through The Hall!
public const uint SaySvalnaEventStart = 0; // You May Have Once Fought Beside Me; Crok; But Now You Are Nothing More Than A Traitor. Come; Your Second Death Approaches!
public const uint SayCrokCombatWp0 = 2; // Draw Them Back To Us; And We'Ll Assist You.
public const uint SayCrokCombatWp1 = 3; // Quickly; Push On!
public const uint SayCrokFinalWp = 4; // Her Reinforcements Will Arrive Shortly; We Must Bring Her Down Quickly!
public const uint SaySvalnaResurrectCaptains = 2; // Foolish Crok. You Brought My Reinforcements With You. Arise; Argent Champions; And Serve The Lich King In Death!
public const uint SayCrokCombatSvalna = 5; // I'Ll Draw Her Attacks. Return Our Brothers To Their Graves; Then Help Me Bring Her Down!
public const uint SaySvalnaAggro = 3; // Come; Scourgebane. I'Ll Show The Master Which Of Us Is Truly Worthy Of The Title Of "Champion"!
public const uint SayCaptainDeath = 0;
public const uint SayCaptainResurrected = 1;
public const uint SayCaptainKill = 2;
public const uint SayCaptainSecondDeath = 3;
public const uint SayCaptainSurviveTalk = 4;
public const uint SayCrokWeakeningGauntlet = 6;
public const uint SayCrokWeakeningSvalna = 7;
public const uint SayCrokDeath = 8;
}
struct InstanceSpells
{
// Rotting Frost Giant
public const uint DeathPlague = 72879;
public const uint DeathPlagueAura = 72865;
public const uint RecentlyInfected = 72884;
public const uint DeathPlagueKill = 72867;
public const uint Stomp = 64652;
public const uint ArcticBreath = 72848;
// Frost Freeze Trap
public const uint ColdflameJets = 70460;
// Alchemist Adrianna
public const uint HarvestBlightSpecimen = 72155;
public const uint HarvestBlightSpecimen25 = 72162;
// Crok Scourgebane
public const uint IceboundArmor = 70714;
public const uint ScourgeStrike = 71488;
public const uint DeathStrike = 71489;
// Sister Svalna
public const uint CaressOfDeath = 70078;
public const uint ImpalingSpearKill = 70196;
public const uint ReviveChampion = 70053;
public const uint Undeath = 70089;
public const uint ImpalingSpear = 71443;
public const uint AetherShield = 71463;
public const uint HurlSpear = 71466;
// Captain Arnath
public const uint DominateMind = 14515;
public const uint FlashHealNormal = 71595;
public const uint PowerWordShieldNormal = 71548;
public const uint SmiteNormal = 71546;
public const uint FlashHealUndead = 71782;
public const uint PowerWordShieldUndead = 71780;
public const uint SmiteUndead = 71778;
public static uint SpellFlashHeal(bool isUndead) { return isUndead ? InstanceSpells.FlashHealUndead : InstanceSpells.FlashHealNormal; }
public static uint SpellPowerWordShield(bool isUndead) { return isUndead ? InstanceSpells.PowerWordShieldUndead : InstanceSpells.PowerWordShieldNormal; }
public static uint SpellSmite(bool isUndead) { return isUndead ? InstanceSpells.SmiteUndead : InstanceSpells.SmiteNormal; }
// Captain Brandon
public const uint CrusaderStrike = 71549;
public const uint DivineShield = 71550;
public const uint JudgementOfCommand = 71551;
public const uint HammerOfBetrayal = 71784;
// Captain Grondel
public const uint Charge = 71553;
public const uint MortalStrike = 71552;
public const uint SunderArmor = 71554;
public const uint Conflagration = 71785;
// Captain Rupert
public const uint FelIronBombNormal = 71592;
public const uint MachineGunNormal = 71594;
public const uint RocketLaunchNormal = 71590;
public const uint FelIronBombUndead = 71787;
public const uint MachineGunUndead = 71788;
public const uint RocketLaunchUndead = 71786;
public static uint SpellFelIronBomb(bool isUndead) { return isUndead ? InstanceSpells.FelIronBombUndead : InstanceSpells.FelIronBombNormal; }
public static uint SpellMachineGun(bool isUndead) { return isUndead ? InstanceSpells.MachineGunUndead : InstanceSpells.MachineGunNormal; }
public static uint SpellRocketLaunch(bool isUndead) { return isUndead ? InstanceSpells.RocketLaunchUndead : InstanceSpells.RocketLaunchNormal; }
// Invisible Stalker (Float; Uninteractible; Largeaoi)
public const uint SoulMissile = 72585;
public const uint Berserk = 26662;
public const uint Berserk2 = 47008;
// Deathbound Ward
public const uint StoneForm = 70733;
// Residue Rendezvous
public const uint OrangeBlightResidue = 72144;
public const uint GreenBlightResidue = 72145;
// The Lich King
public const uint ArthasTeleporterCeremony = 72915;
public const uint FrostmourneTeleportVisual = 73078;
// Shadowmourne questline
public const uint UnsatedCraving = 71168;
public const uint ShadowsFate = 71169;
}
struct EventTypes
{
// Highlord Tirion Fordring (At Light'S Hammer)
// The Lich King (At Light'S Hammer)
// Highlord Bolvar Fordragon (At Light'S Hammer)
// High Overlord Saurfang (At Light'S Hammer)
// Muradin Bronzebeard (At Light'S Hammer)
public const uint TirionIntro2 = 1;
public const uint TirionIntro3 = 2;
public const uint TirionIntro4 = 3;
public const uint TirionIntro5 = 4;
public const uint LkIntro1 = 5;
public const uint TirionIntro6 = 6;
public const uint LkIntro2 = 7;
public const uint LkIntro3 = 8;
public const uint LkIntro4 = 9;
public const uint BolvarIntro1 = 10;
public const uint LkIntro5 = 11;
public const uint SaurfangIntro1 = 12;
public const uint TirionIntroH7 = 13;
public const uint SaurfangIntro2 = 14;
public const uint SaurfangIntro3 = 15;
public const uint SaurfangIntro4 = 16;
public const uint SaurfangRun = 17;
public const uint MuradinIntro1 = 18;
public const uint MuradinIntro2 = 19;
public const uint MuradinIntro3 = 20;
public const uint TirionIntroA7 = 21;
public const uint MuradinIntro4 = 22;
public const uint MuradinIntro5 = 23;
public const uint MuradinRun = 24;
// Rotting Frost Giant
public const uint DeathPlague = 25;
public const uint Stomp = 26;
public const uint ArcticBreath = 27;
// Frost Freeze Trap
public const uint ActivateTrap = 28;
// Crok Scourgebane
public const uint ScourgeStrike = 29;
public const uint DeathStrike = 30;
public const uint HealthCheck = 31;
public const uint CrokIntro3 = 32;
public const uint StartPathing = 33;
// Sister Svalna
public const uint ArnathIntro2 = 34;
public const uint SvalnaStart = 35;
public const uint SvalnaResurrect = 36;
public const uint SvalnaCombat = 37;
public const uint ImpalingSpear = 38;
public const uint AetherShield = 39;
// Captain Arnath
public const uint ArnathFlashHeal = 40;
public const uint ArnathPwShield = 41;
public const uint ArnathSmite = 42;
public const uint ArnathDominateMind = 43;
// Captain Brandon
public const uint BrandonCrusaderStrike = 44;
public const uint BrandonDivineShield = 45;
public const uint BrandonJudgementOfCommand = 46;
public const uint BrandonHammerOfBetrayal = 47;
// Captain Grondel
public const uint GrondelChargeCheck = 48;
public const uint GrondelMortalStrike = 49;
public const uint GrondelSunderArmor = 50;
public const uint GrondelConflagration = 51;
// Captain Rupert
public const uint RupertFelIronBomb = 52;
public const uint RupertMachineGun = 53;
public const uint RupertRocketLaunch = 54;
// Invisible Stalker (Float; Uninteractible; Largeaoi)
public const uint SoulMissile = 55;
}
struct DataTypes
{
// Additional Data
public const uint SaurfangEventNpc = 13;
public const uint BonedAchievement = 14;
public const uint OozeDanceAchievement = 15;
public const uint PutricideTable = 16;
public const uint NauseaAchievement = 17;
public const uint OrbWhispererAchievement = 18;
public const uint PrinceKelesethGuid = 19;
public const uint PrinceTaldaramGuid = 20;
public const uint PrinceValanarGuid = 21;
public const uint BloodPrincesControl = 22;
public const uint SindragosaFrostwyrms = 23;
public const uint Spinestalker = 24;
public const uint Rimefang = 25;
public const uint ColdflameJets = 26;
public const uint TeamInInstance = 27;
public const uint BloodQuickeningState = 28;
public const uint HeroicAttempts = 29;
public const uint CrokScourgebane = 30;
public const uint CaptainArnath = 31;
public const uint CaptainBrandon = 32;
public const uint CaptainGrondel = 33;
public const uint CaptainRupert = 34;
public const uint ValithriaTrigger = 35;
public const uint ValithriaLichKing = 36;
public const uint HighlordTirionFordring = 37;
public const uint ArthasPlatform = 38;
public const uint TerenasMenethil = 39;
public const uint EnemyGunship = 40;
public const uint UpperSpireTeleAct = 41;
}
struct WorldStates
{
public const uint ShowTimer = 4903;
public const uint ExecutionTime = 4904;
public const uint ShowAttempts = 4940;
public const uint AttemptsRemaining = 4941;
public const uint AttemptsMax = 4942;
}
struct CreatureIds
{
// At Light'S Hammer
public const uint HighlordTirionFordringLh = 37119;
public const uint TheLichKingLh = 37181;
public const uint HighlordBolvarFordragonLh = 37183;
public const uint KorKronGeneral = 37189;
public const uint AllianceCommander = 37190;
public const uint Tortunok = 37992; // Druid Armor H
public const uint AlanaMoonstrike = 37999; // Druid Armor A
public const uint GerardoTheSuave = 37993; // Hunter Armor H
public const uint TalanMoonstrike = 37998; // Hunter Armor A
public const uint UvlusBanefire = 38284; // Mage Armor H
public const uint MalfusGrimfrost = 38283; // Mage Armor A
public const uint IkfirusTheVile = 37991; // Rogue Armor H
public const uint Yili = 37997; // Rogue Armor A
public const uint VolGuk = 38841; // Shaman Armor H
public const uint Jedebia = 38840; // Shaman Armor A
public const uint HaraggTheUnseen = 38181; // Warlock Armor H
public const uint NibyTheAlmighty = 38182; // Warlock Armor N
public const uint GarroshHellscream = 39372;
public const uint KingVarianWrynn = 39371;
public const uint DeathboundWard = 37007;
public const uint LadyJainaProudmooreQuest = 38606;
public const uint MuradinBronzaBeardQuest = 38607;
public const uint UtherTheLightBringerQuest = 38608;
public const uint LadySylvanasWindrunnerQuest = 38609;
// Weekly Quests
public const uint InfiltratorMinchar = 38471;
public const uint KorKronLieutenant = 38491;
public const uint SkybreakerLieutenant = 38492;
public const uint RottingFrostGiant10 = 38490;
public const uint RottingFrostGiant25 = 38494;
public const uint AlchemistAdrianna = 38501;
public const uint AlrinTheAgile = 38551;
public const uint InfiltratorMincharBq = 38558;
public const uint MincharBeamStalker = 38557;
public const uint ValithriaDreamwalkerQuest = 38589;
// Lord Marrowgar
public const uint LordMarrowgar = 36612;
public const uint Coldflame = 36672;
public const uint BoneSpike = 36619;
// Lady Deathwhisper
public const uint LadyDeathwhisper = 36855;
public const uint CultFanatic = 37890;
public const uint DeformedFanatic = 38135;
public const uint ReanimatedFanatic = 38009;
public const uint CultAdherent = 37949;
public const uint EmpoweredAdherent = 38136;
public const uint ReanimatedAdherent = 38010;
public const uint VengefulShade = 38222;
// Icecrown Gunship Battle
public const uint MartyrStalkerIGBSaurfang = 38569;
public const uint AllianceGunshipCannon = 36838;
public const uint HordeGunshipCannon = 36839;
public const uint SkybreakerDeckhand = 36970;
public const uint OrgrimsHammerCrew = 36971;
public const uint IGBHighOverlordSaurfang = 36939;
public const uint IGBMuradinBrozebeard = 36948;
public const uint TheSkybreaker = 37540;
public const uint OrgrimsHammer = 37215;
public const uint GunshipHull = 37547;
public const uint TeleportPortal = 37227;
public const uint TeleportExit = 37488;
public const uint SkybreakerSorcerer = 37116;
public const uint SkybreakerRifleman = 36969;
public const uint SkybreakerMortarSoldier = 36978;
public const uint SkybreakerMarine = 36950;
public const uint SkybreakerSergeant = 36961;
public const uint KorKronBattleMage = 37117;
public const uint KorKronAxeThrower = 36968;
public const uint KorKronRocketeer = 36982;
public const uint KorKronReaver = 36957;
public const uint KorKronSergeant = 36960;
public const uint ZafodBoombox = 37184;
public const uint HighCaptainJustinBartlett = 37182;
public const uint SkyReaverKormBlackscar = 37833;
// Deathbringer Saurfang
public const uint DeathbringerSaurfang = 37813;
public const uint BloodBeast = 38508;
public const uint SeJainaProudmoore = 37188; // Se Means Saurfang Event
public const uint SeMuradinBronzebeard = 37200;
public const uint SeKingVarianWrynn = 37879;
public const uint SeHighOverlordSaurfang = 37187;
public const uint SeKorKronReaver = 37920;
public const uint SeSkybreakerMarine = 37830;
public const uint FrostFreezeTrap = 37744;
// Festergut
public const uint Festergut = 36626;
public const uint GasDummy = 36659;
public const uint MalleableOozeStalker = 38556;
// Rotface
public const uint Rotface = 36627;
public const uint OozeSprayStalker = 37986;
public const uint PuddleStalker = 37013;
public const uint UnstableExplosionStalker = 38107;
public const uint VileGasStalker = 38548;
// Professor Putricide
public const uint ProfessorPutricide = 36678;
public const uint AbominationWingMadScientistStalker = 37824;
public const uint GrowingOozePuddle = 37690;
public const uint GasCloud = 37562;
public const uint VolatileOoze = 37697;
public const uint ChokingGasBomb = 38159;
public const uint TearGasTargetStalker = 38317;
public const uint MutatedAbomination10 = 37672;
public const uint MutatedAbomination25 = 38285;
// Blood Prince Council
public const uint PrinceKeleseth = 37972;
public const uint PrinceTaldaram = 37973;
public const uint PrinceValanar = 37970;
public const uint BloodOrbController = 38008;
public const uint FloatingTrigger = 30298;
public const uint DarkNucleus = 38369;
public const uint BallOfFlame = 38332;
public const uint BallOfInfernoFlame = 38451;
public const uint KineticBombTarget = 38458;
public const uint KineticBomb = 38454;
public const uint ShockVortex = 38422;
// Blood-Queen Lana'Thel
public const uint BloodQueenLanaThel = 37955;
// Frostwing Halls Gauntlet Event
public const uint CrokScourgebane = 37129;
public const uint CaptainArnath = 37122;
public const uint CaptainBrandon = 37123;
public const uint CaptainGrondel = 37124;
public const uint CaptainRupert = 37125;
public const uint CaptainArnathUndead = 37491;
public const uint CaptainBrandonUndead = 37493;
public const uint CaptainGrondelUndead = 37494;
public const uint CaptainRupertUndead = 37495;
public const uint YmirjarBattleMaiden = 37132;
public const uint YmirjarDeathbringer = 38125;
public const uint YmirjarFrostbinder = 37127;
public const uint YmirjarHuntress = 37134;
public const uint YmirjarWarlord = 37133;
public const uint SisterSvalna = 37126;
public const uint ImpalingSpear = 38248;
// Valithria Dreamwalker
public const uint ValithriaDreamwalker = 36789;
public const uint GreenDragonCombatTrigger = 38752;
public const uint RisenArchmage = 37868;
public const uint BlazingSkeleton = 36791;
public const uint Suppresser = 37863;
public const uint BlisteringZombie = 37934;
public const uint GluttonousAbomination = 37886;
public const uint ManaVoid = 38068;
public const uint ColumnOfFrost = 37918;
public const uint RotWorm = 37907;
public const uint TheLichKingValithria = 16980;
public const uint DreamPortalPreEffect = 38186;
public const uint NightmarePortalPreEffect = 38429;
public const uint DreamPortal = 37945;
public const uint NightmarePortal = 38430;
// Sindragosa
public const uint Sindragosa = 36853;
public const uint Spinestalker = 37534;
public const uint Rimefang = 37533;
public const uint FrostwardenHandler = 37531;
public const uint FrostwingWhelp = 37532;
public const uint IcyBlast = 38223;
public const uint FrostBomb = 37186;
public const uint IceTomb = 36980;
// The Lich King
public const uint TheLichKing = 36597;
public const uint HighlordTirionFordringLk = 38995;
public const uint TerenasMenethilFrostmourne = 36823;
public const uint SpiritWarden = 36824;
public const uint TerenasMenethilFrostmourneH = 39217;
public const uint ShamblingHorror = 37698;
public const uint DrudgeGhoul = 37695;
public const uint IceSphere = 36633;
public const uint RagingSpirit = 36701;
public const uint Defile = 38757;
public const uint ValkyrShadowguard = 36609;
public const uint VileSpirit = 37799;
public const uint WickedSpirit = 39190;
public const uint StrangulateVehicle = 36598;
public const uint WorldTrigger = 22515;
public const uint WorldTriggerInfiniteAoi = 36171;
public const uint SpiritBomb = 39189;
public const uint FrostmourneTrigger = 38584;
// Generic
public const uint InvisibleStalker = 30298;
}
struct GameObjectIds
{
// ICC Teleporters
public const uint TransporterLichKing = 202223;
public const uint TransporterUpperSpire = 202235;
public const uint TransporterLightsHammer = 202242;
public const uint TransporterRampart = 202243;
public const uint TransporterDeathBringer = 202244;
public const uint TransporterOratory = 202245;
public const uint TransporterSindragosa = 202246;
// Lower Spire Trash
public const uint SpiritAlarm1 = 201814;
public const uint SpiritAlarm2 = 201815;
public const uint SpiritAlarm3 = 201816;
public const uint SpiritAlarm4 = 201817;
// Lord Marrogar
public const uint DoodadIcecrownIcewall02 = 201910;
public const uint LordMarrowgarIcewall = 201911;
public const uint LordMarrowgarSEntrance = 201857;
// Lady Deathwhisper
public const uint OratoryOfTheDamnedEntrance = 201563;
public const uint LadyDeathwhisperElevator = 202220;
// Icecrown Gunship Battle - Horde raid
public const uint OrgrimsHammer_H = 201812;
public const uint TheSkybreaker_H = 201811;
public const uint GunshipArmory_H_10N = 202178;
public const uint GunshipArmory_H_25N = 202180;
public const uint GunshipArmory_H_10H = 202177;
public const uint GunshipArmory_H_25H = 202179;
// Icecrown Gunship Battle - Alliance raid
public const uint OrgrimsHammer_A = 201581;
public const uint TheSkybreaker_A = 201580;
public const uint GunshipArmory_A_10N = 201873;
public const uint GunshipArmory_A_25N = 201874;
public const uint GunshipArmory_A_10H = 201872;
public const uint GunshipArmory_A_25H = 201875;
// Deathbringer Saurfang
public const uint SaurfangSDoor = 201825;
public const uint DeathbringerSCache10n = 202239;
public const uint DeathbringerSCache25n = 202240;
public const uint DeathbringerSCache10h = 202238;
public const uint DeathbringerSCache25h = 202241;
// Professor Putricide
public const uint OrangePlagueMonsterEntrance = 201371;
public const uint GreenPlagueMonsterEntrance = 201370;
public const uint ScientistAirlockDoorCollision = 201612;
public const uint ScientistAirlockDoorOrange = 201613;
public const uint ScientistAirlockDoorGreen = 201614;
public const uint DoodadIcecrownOrangetubes02 = 201617;
public const uint DoodadIcecrownGreentubes02 = 201618;
public const uint ScientistEntrance = 201372;
public const uint DrinkMe = 201584;
public const uint PlagueSigil = 202182;
// Blood Prince Council
public const uint CrimsonHallDoor = 201376;
public const uint BloodElfCouncilDoor = 201378;
public const uint BloodElfCouncilDoorRight = 201377;
// Blood-Queen Lana'Thel
public const uint DoodadIcecrownBloodprinceDoor01 = 201746;
public const uint DoodadIcecrownGrate01 = 201755;
public const uint BloodwingSigil = 202183;
// Valithria Dreamwalker
public const uint GreenDragonBossEntrance = 201375;
public const uint GreenDragonBossExit = 201374;
public const uint DoodadIcecrownRoostportcullis01 = 201380;
public const uint DoodadIcecrownRoostportcullis02 = 201381;
public const uint DoodadIcecrownRoostportcullis03 = 201382;
public const uint DoodadIcecrownRoostportcullis04 = 201383;
public const uint CacheOfTheDreamwalker10n = 201959;
public const uint CacheOfTheDreamwalker25n = 202339;
public const uint CacheOfTheDreamwalker10h = 202338;
public const uint CacheOfTheDreamwalker25h = 202340;
// Sindragosa
public const uint SindragosaEntranceDoor = 201373;
public const uint SindragosaShortcutEntranceDoor = 201369;
public const uint SindragosaShortcutExitDoor = 201379;
public const uint IceWall = 202396;
public const uint IceBlock = 201722;
public const uint SigilOfTheFrostwing = 202181;
// The Lich King
public const uint ArthasPlatform = 202161;
public const uint ArthasPrecipice = 202078;
public const uint DoodadIcecrownThronefrostywind01 = 202188;
public const uint DoodadIcecrownThronefrostyedge01 = 202189;
public const uint DoodadIceshardStanding02 = 202141;
public const uint DoodadIceshardStanding01 = 202142;
public const uint DoodadIceshardStanding03 = 202143;
public const uint DoodadIceshardStanding04 = 202144;
public const uint DoodadIcecrownSnowedgewarning01 = 202190;
public const uint FrozenLavaman = 202436;
public const uint LavamanPillarsChained = 202437;
public const uint LavamanPillarsUnchained = 202438;
}
struct AchievementCriteriaIds
{
// Lord Marrowgar
public const uint Boned10n = 12775;
public const uint Boned25n = 12962;
public const uint Boned10h = 13393;
public const uint Boned25h = 13394;
// Rotface
public const uint DancesWithOozes10 = 12984;
public const uint DancesWithOozes25 = 12966;
public const uint DancesWithOozes10H = 12985;
public const uint DancesWithOozes25H = 12983;
// Professor Putricide
public const uint Nausea10 = 12987;
public const uint Nausea25 = 12968;
public const uint Nausea10H = 12988;
public const uint Nausea25H = 12981;
// Blood Prince Council
public const uint OrbWhisperer10 = 13033;
public const uint OrbWhisperer25 = 12969;
public const uint OrbWhisperer10H = 13034;
public const uint OrbWhisperer25H = 13032;
// Blood-Queen Lana'Thel
public const uint KillLanaThel10m = 13340;
public const uint KillLanaThel25m = 13360;
public const uint OnceBittenTwiceShy10 = 12780;
public const uint OnceBittenTwiceShy25 = 13012;
public const uint OnceBittenTwiceShy10V = 13011;
public const uint OnceBittenTwiceShy25V = 13013;
}
struct WeeklyQuestIds
{
public const uint Deprogramming10 = 24869;
public const uint Deprogramming25 = 24875;
public const uint SecuringTheRamparts10 = 24870;
public const uint SecuringTheRamparts25 = 24877;
public const uint ResidueRendezvous10 = 24873;
public const uint ResidueRendezvous25 = 24878;
public const uint BloodQuickening10 = 24874;
public const uint BloodQuickening25 = 24879;
public const uint RespiteForATornmentedSoul10 = 24872;
public const uint RespiteForATornmentedSoul25 = 24880;
}
struct Actions
{
// Icecrown Gunship Battle
public const int EnemyGunshipTalk = -369390;
public const int ExitShip = -369391;
// Festergut
public const int FestergutCombat = -366260;
public const int FestergutGas = -366261;
public const int FestergutDeath = -366262;
// Rotface
public const int RotfaceCombat = -366270;
public const int RotfaceOoze = -366271;
public const int RotfaceDeath = -366272;
public const int ChangePhase = -366780;
// Blood-Queen Lana'Thel
public const int KillMinchar = -379550;
// Frostwing Halls Gauntlet Event
public const int VrykulDeath = 37129;
// Sindragosa
public const int StartFrostwyrm = -368530;
public const int TriggerAsphyxiation = -368531;
// The Lich King
public const int RestoreLight = -72262;
public const int FrostmourneIntro = -36823;
// Sister Svalna
public const int KillCaptain = 1;
public const int StartGauntlet = 2;
public const int ResurrectCaptains = 3;
public const int CaptainDies = 4;
public const int ResetEvent = 5;
}
struct TeleporterSpells
{
public const uint LIGHT_S_HAMMER_TELEPORT = 70781;
public const uint ORATORY_OF_THE_DAMNED_TELEPORT = 70856;
public const uint RAMPART_OF_SKULLS_TELEPORT = 70857;
public const uint DEATHBRINGER_S_RISE_TELEPORT = 7085;
public const uint UPPER_SPIRE_TELEPORT = 70859;
public const uint FROZEN_THRONE_TELEPORT = 70860;
public const uint SINDRAGOSA_S_LAIR_TELEPORT = 70861;
}
struct AreaIds
{
public const uint IcecrownCitadel = 4812;
public const uint TheFrozenThrone = 4859;
}
}
@@ -0,0 +1,106 @@
/*
* 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.DataStorage;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
namespace Scripts.Northrend.IcecrownCitadel
{
[Script]
class icecrown_citadel_teleport : GameObjectScript
{
public icecrown_citadel_teleport() : base("icecrown_citadel_teleport") { }
public class icecrown_citadel_teleportAI : GameObjectAI
{
public icecrown_citadel_teleportAI(GameObject go) : base(go) { }
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
if (gossipListId >= TeleportSpells.Length)
return false;
player.PlayerTalkClass.ClearMenus();
player.CLOSE_GOSSIP_MENU();
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleportSpells[gossipListId]);
if (spell == null)
return false;
if (player.IsInCombat())
{
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, player.GetMapId(), spell.Id, player.GetMap().GenerateLowGuid(HighGuid.Cast));
Spell.SendCastResult(player, spell, 0, castId, SpellCastResult.AffectingCombat);
return true;
}
return true;
}
}
public override GameObjectAI GetAI(GameObject go)
{
return GetInstanceAI<icecrown_citadel_teleportAI>(go, "instance_icecrown_citadel");
}
public const uint GOSSIP_SENDER_ICC_PORT = 631;
static uint[] TeleportSpells =
{
TeleporterSpells.LIGHT_S_HAMMER_TELEPORT, // 0
TeleporterSpells.ORATORY_OF_THE_DAMNED_TELEPORT, // 1
0, // 2
TeleporterSpells.RAMPART_OF_SKULLS_TELEPORT, // 3
TeleporterSpells.DEATHBRINGER_S_RISE_TELEPORT, // 4
TeleporterSpells.UPPER_SPIRE_TELEPORT, // 5
TeleporterSpells.SINDRAGOSA_S_LAIR_TELEPORT // 6
};
}
[Script]
class at_frozen_throne_teleport : AreaTriggerScript
{
public at_frozen_throne_teleport() : base("at_frozen_throne_teleport") { }
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
{
if (player.IsInCombat())
{
SpellInfo spell = Global.SpellMgr.GetSpellInfo(TeleporterSpells.FROZEN_THRONE_TELEPORT);
if (spell == null)
{
ObjectGuid castId = ObjectGuid.Create(HighGuid.Cast, SpellCastSource.Normal, player.GetMapId(), spell.Id, player.GetMap().GenerateLowGuid(HighGuid.Cast));
Spell.SendCastResult(player, spell, 0, castId, SpellCastResult.AffectingCombat);
}
return true;
}
InstanceScript instance = player.GetInstanceScript();
if (instance != null)
if (instance.GetBossState(Bosses.ProfessorPutricide) == EncounterState.Done &&
instance.GetBossState(Bosses.BloodQueenLanaThel) == EncounterState.Done &&
instance.GetBossState(Bosses.Sindragosa) == EncounterState.Done &&
instance.GetBossState(Bosses.TheLichKing) != EncounterState.InProgress)
player.CastSpell(player, TeleporterSpells.FROZEN_THRONE_TELEPORT, true);
return true;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,734 @@
/*
* 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.Movement;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace Scripts.Northrend.IcecrownCitadel
{
namespace Marrorgar
{
struct Texts
{
public const int SayEnterZone = 0;
public const int SayAggro = 1;
public const int SayBoneStorm = 2;
public const int SayBonespike = 3;
public const int SayKill = 4;
public const int SayDeath = 5;
public const int SayBerserk = 6;
public const int EmoteBoneStorm = 7;
}
struct Spells
{
// Lord Marrowgar
public const uint BoneSlice = 69055;
public const uint BoneStorm = 69076;
public const uint BoneSpikeGraveyard = 69057;
public const uint ColdflameNormal = 69140;
public const uint ColdflameBoneStorm = 72705;
// Bone Spike
public const uint Impaled = 69065;
public const uint RideVehicle = 46598;
// Coldflame
public const uint ColdflamePassive = 69145;
public const uint ColdflameSummon = 69147;
}
struct Misc
{
public static uint[] BoneSpikeSummonId = { 69062, 72669, 72670 };
public const uint EventBoneSpikeGraveyard = 1;
public const uint EventColdflame = 2;
public const uint EventBoneStormBegin = 3;
public const uint EventBoneStormMove = 4;
public const uint EventBoneStormEnd = 5;
public const uint EventEnableBoneSlice = 6;
public const uint EventEnrage = 7;
public const uint EventWarnBoneStorm = 8;
public const uint EventColdflameTrigger = 9;
public const uint EventFailBoned = 10;
public const uint EventGroupSpecial = 1;
public const uint PointTargetBonestormPlayer = 36612631;
public const uint PointTargetColdflame = 36672631;
public const int DataColdflameGuid = 0;
// Manual Marking For Targets Hit By Bone Slice As No Aura Exists For This Purpose
// These Units Are The Tanks In This Encounter
// And Should Be Immune To Bone Spike Graveyard
public const int DataSpikeImmune = 1;
//DataSpikeImmune1; = 2; // Reserved & Used
//DataSpikeImmune2; = 3; // Reserved & Used
public const int ActionClearSpikeImmunities = 1;
public const uint MaxBoneSpikeImmune = 3;
}
class BoneSpikeTargetSelector : ISelector
{
public BoneSpikeTargetSelector(UnitAI ai)
{
_ai = ai;
}
public bool Check(Unit unit)
{
if (!unit.IsTypeId(TypeId.Player))
return false;
if (unit.HasAura(Spells.Impaled))
return false;
// Check if it is one of the tanks soaking Bone Slice
for (int i = 0; i < Misc.MaxBoneSpikeImmune; ++i)
if (unit.GetGUID() == _ai.GetGUID(Misc.DataSpikeImmune + i))
return false;
return true;
}
UnitAI _ai;
}
[Script]
class boss_lord_marrowgar : CreatureScript
{
public boss_lord_marrowgar() : base("boss_lord_marrowgar") { }
public class boss_lord_marrowgarAI : BossAI
{
public boss_lord_marrowgarAI(Creature creature) : base(creature, Bosses.LordMarrowgar)
{
_boneStormDuration = RaidMode<uint>(20000, 30000, 20000, 30000);
_baseSpeed = creature.GetSpeedRate(UnitMoveType.Run);
_coldflameLastPos.Relocate(creature);
_introDone = false;
_boneSlice = false;
}
public override void Reset()
{
_Reset();
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed);
me.RemoveAurasDueToSpell(Spells.BoneStorm);
me.RemoveAurasDueToSpell(InstanceSpells.Berserk);
_events.ScheduleEvent(Misc.EventEnableBoneSlice, 10000);
_events.ScheduleEvent(Misc.EventBoneSpikeGraveyard, 15000, Misc.EventGroupSpecial);
_events.ScheduleEvent(Misc.EventColdflame, 5000, Misc.EventGroupSpecial);
_events.ScheduleEvent(Misc.EventWarnBoneStorm, RandomHelper.URand(45000, 50000));
_events.ScheduleEvent(Misc.EventEnrage, 600000);
_boneSlice = false;
_boneSpikeImmune.Clear();
}
public override void EnterCombat(Unit who)
{
Talk(Texts.SayAggro);
me.setActive(true);
DoZoneInCombat();
instance.SetBossState(Bosses.LordMarrowgar, EncounterState.InProgress);
}
public override void JustDied(Unit killer)
{
Talk(Texts.SayDeath);
_JustDied();
}
public override void JustReachedHome()
{
_JustReachedHome();
instance.SetBossState(Bosses.LordMarrowgar, EncounterState.Fail);
instance.SetData(DataTypes.BonedAchievement, 1); // reset
}
public override void KilledUnit(Unit victim)
{
if (victim.IsTypeId(TypeId.Player))
Talk(Texts.SayKill);
}
public override void MoveInLineOfSight(Unit who)
{
if (!_introDone && me.IsWithinDistInMap(who, 70.0f))
{
Talk(Texts.SayEnterZone);
_introDone = true;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventBoneSpikeGraveyard:
if (IsHeroic() || !me.HasAura(Spells.BoneStorm))
DoCast(me, Spells.BoneSpikeGraveyard);
_events.ScheduleEvent(Misc.EventBoneSpikeGraveyard, RandomHelper.URand(15000, 20000), Misc.EventGroupSpecial);
break;
case Misc.EventColdflame:
_coldflameLastPos.Relocate(me);
_coldflameTarget.Clear();
if (!me.HasAura(Spells.BoneStorm))
DoCastAOE(Spells.ColdflameNormal);
else
DoCast(me, Spells.ColdflameBoneStorm);
_events.ScheduleEvent(Misc.EventColdflame, 5000, Misc.EventGroupSpecial);
break;
case Misc.EventWarnBoneStorm:
_boneSlice = false;
Talk(Texts.SayBoneStorm);
me.FinishSpell(CurrentSpellTypes.Melee, false);
DoCast(me, Spells.BoneStorm);
_events.DelayEvents(3000, Misc.EventGroupSpecial);
_events.ScheduleEvent(Misc.EventBoneStormBegin, 3050);
_events.ScheduleEvent(Misc.EventWarnBoneStorm, RandomHelper.URand(90000, 95000));
break;
case Misc.EventBoneStormBegin:
Aura pStorm = me.GetAura(Spells.BoneStorm);
if (pStorm != null)
pStorm.SetDuration((int)_boneStormDuration);
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed * 3.0f);
Talk(Texts.SayBoneStorm);
_events.ScheduleEvent(Misc.EventBoneStormEnd, _boneStormDuration + 1);
goto case Misc.EventBoneStormMove;
// no break here
case Misc.EventBoneStormMove:
{
_events.ScheduleEvent(Misc.EventBoneStormMove, _boneStormDuration / 3);
Unit unit = SelectTarget(SelectAggroTarget.Random, 0, new NonTankTargetSelector(me));
if (!unit)
unit = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (unit)
me.GetMotionMaster().MovePoint(Misc.PointTargetBonestormPlayer, unit);
break;
}
case Misc.EventBoneStormEnd:
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
me.GetMotionMaster().MovementExpired();
me.GetMotionMaster().MoveChase(me.GetVictim());
me.SetSpeedRate(UnitMoveType.Run, _baseSpeed);
_events.CancelEvent(Misc.EventBoneStormMove);
_events.ScheduleEvent(Misc.EventEnableBoneSlice, 10000);
if (!IsHeroic())
_events.RescheduleEvent(Misc.EventBoneSpikeGraveyard, 15000, Misc.EventGroupSpecial);
break;
case Misc.EventEnableBoneSlice:
_boneSlice = true;
break;
case Misc.EventEnrage:
DoCast(me, Texts.SayBerserk, true);
Talk(Texts.SayBerserk);
break;
}
});
// We should not melee attack when storming
if (me.HasAura(Spells.BoneStorm))
return;
// 10 seconds since encounter start Bone Slice replaces melee attacks
if (_boneSlice && !me.GetCurrentSpell(CurrentSpellTypes.Melee))
DoCastVictim(Spells.BoneSlice);
DoMeleeAttackIfReady();
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point || id != Misc.PointTargetBonestormPlayer)
return;
// lock movement
me.GetMotionMaster().MoveIdle();
}
public Position GetLastColdflamePosition()
{
return _coldflameLastPos;
}
public override ObjectGuid GetGUID(int type = 0)
{
switch (type)
{
case Misc.DataColdflameGuid:
return _coldflameTarget;
case Misc.DataSpikeImmune + 0:
case Misc.DataSpikeImmune + 1:
case Misc.DataSpikeImmune + 2:
{
int index = type - Misc.DataSpikeImmune;
if (index < _boneSpikeImmune.Count)
return _boneSpikeImmune[index];
break;
}
}
return ObjectGuid.Empty;
}
public override void SetGUID(ObjectGuid guid, int type = 0)
{
switch (type)
{
case Misc.DataColdflameGuid:
_coldflameTarget = guid;
break;
case Misc.DataSpikeImmune:
_boneSpikeImmune.Add(guid);
break;
}
}
public override void DoAction(int action)
{
if (action != Misc.ActionClearSpikeImmunities)
return;
_boneSpikeImmune.Clear();
}
Position _coldflameLastPos = new Position();
List<ObjectGuid> _boneSpikeImmune = new List<ObjectGuid>();
ObjectGuid _coldflameTarget;
uint _boneStormDuration;
float _baseSpeed;
bool _introDone;
bool _boneSlice;
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<boss_lord_marrowgarAI>(creature);
}
}
[Script]
class npc_coldflame : CreatureScript
{
public npc_coldflame() : base("npc_coldflame") { }
class npc_coldflameAI : ScriptedAI
{
public npc_coldflameAI(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit owner)
{
if (!owner.IsTypeId(TypeId.Player))
return;
Position pos = new Position();
var marrowgarAI = (boss_lord_marrowgar.boss_lord_marrowgarAI)owner.GetAI();
if (marrowgarAI != null)
pos.Relocate(marrowgarAI.GetLastColdflamePosition());
else
pos.Relocate(owner);
if (owner.HasAura(Spells.BoneStorm))
{
float ang = Position.NormalizeOrientation(pos.GetAngle(me));
me.SetOrientation(ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 5.0f - owner.GetObjectSize(), ang);
}
else
{
Player target = Global.ObjAccessor.GetPlayer(owner, owner.GetAI().GetGUID(Misc.DataColdflameGuid));
if (!target)
{
me.DespawnOrUnsummon();
return;
}
float ang = Position.NormalizeOrientation(pos.GetAngle(target));
me.SetOrientation(ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 15.0f - owner.GetObjectSize(), ang);
}
me.NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
DoCast(Spells.ColdflameSummon);
_events.ScheduleEvent(Misc.EventColdflameTrigger, 500);
}
public override void UpdateAI(uint diff)
{
_events.Update(diff);
if (_events.ExecuteEvent() == Misc.EventColdflameTrigger)
{
Position newPos = me.GetNearPosition(5.0f, 0.0f);
me.NearTeleportTo(newPos.GetPositionX(), newPos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
DoCast(Spells.ColdflameSummon);
_events.ScheduleEvent(Misc.EventColdflameTrigger, 500);
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<npc_coldflameAI>(creature);
}
}
[Script]
class npc_bone_spike : CreatureScript
{
public npc_bone_spike() : base("npc_bone_spike") { }
class npc_bone_spikeAI : ScriptedAI
{
public npc_bone_spikeAI(Creature creature)
: base(creature)
{
_hasTrappedUnit = false;
Contract.Assert(creature.GetVehicleKit());
SetCombatMovement(false);
}
public override void JustDied(Unit killer)
{
TempSummon summ = me.ToTempSummon();
if (summ)
{
Unit trapped = summ.GetSummoner();
if (trapped)
trapped.RemoveAurasDueToSpell(Spells.Impaled);
}
me.DespawnOrUnsummon();
}
public override void KilledUnit(Unit victim)
{
me.DespawnOrUnsummon();
victim.RemoveAurasDueToSpell(Spells.Impaled);
}
public override void IsSummonedBy(Unit summoner)
{
DoCast(summoner, Spells.Impaled);
summoner.CastSpell(me, Spells.RideVehicle, true);
_events.ScheduleEvent(Misc.EventFailBoned, 8000);
_hasTrappedUnit = true;
}
public override void PassengerBoarded(Unit passenger, sbyte seat, bool apply)
{
if (!apply)
return;
// @HACK - Change passenger offset to the one taken directly from sniffs
// Remove this when proper calculations are implemented.
// This fixes healing spiked people
MoveSplineInit init = new MoveSplineInit(passenger);
init.DisableTransportPathTransformations();
init.MoveTo(-0.02206125f, -0.02132235f, 5.514783f, false);
init.Launch();
}
public override void UpdateAI(uint diff)
{
if (!_hasTrappedUnit)
return;
_events.Update(diff);
if (_events.ExecuteEvent() == Misc.EventFailBoned)
{
InstanceScript instance = me.GetInstanceScript();
if (instance != null)
instance.SetData(DataTypes.BonedAchievement, 0);
}
}
bool _hasTrappedUnit;
}
public override CreatureAI GetAI(Creature creature)
{
return InstanceIcecrownCitadel.GetInstanceAI<npc_bone_spikeAI>(creature);
}
}
[Script]
class spell_marrowgar_coldflame : SpellScriptLoader
{
public spell_marrowgar_coldflame() : base("spell_marrowgar_coldflame") { }
class spell_marrowgar_coldflame_SpellScript : SpellScript
{
void SelectTarget(List<WorldObject> targets)
{
targets.Clear();
// select any unit but not the tank (by owners threatlist)
Unit target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 1, -GetCaster().GetObjectSize(), true, -(int)Spells.Impaled);
if (!target)
target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true); // or the tank if its solo
if (!target)
return;
GetCaster().GetAI().SetGUID(target.GetGUID(), Misc.DataColdflameGuid);
targets.Add(target);
}
void HandleScriptEffect(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetCaster().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SelectTarget, 0, Targets.UnitDestAreaEnemy));
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_coldflame_SpellScript();
}
}
[Script]
class spell_marrowgar_coldflame_bonestorm : SpellScriptLoader
{
public spell_marrowgar_coldflame_bonestorm() : base("spell_marrowgar_coldflame_bonestorm") { }
class spell_marrowgar_coldflame_SpellScript : SpellScript
{
void HandleScriptEffect(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
for (byte i = 0; i < 4; ++i)
GetCaster().CastSpell(GetHitUnit(), (uint)(GetEffectValue() + i), true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.ScriptEffect));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_coldflame_SpellScript();
}
}
[Script]
class spell_marrowgar_coldflame_damage : SpellScriptLoader
{
public spell_marrowgar_coldflame_damage() : base("spell_marrowgar_coldflame_damage") { }
class spell_marrowgar_coldflame_damage_AuraScript : AuraScript
{
bool CanBeAppliedOn(Unit target)
{
if (target.HasAura(Spells.Impaled))
return false;
if (target.GetExactDist2d(GetOwner()) > GetSpellInfo().GetEffect(target.GetMap().GetDifficultyID(), 0).CalcRadius())
return false;
Aura aur = target.GetAura(GetId());
if (aur != null)
if (aur.GetOwner() != GetOwner())
return false;
return true;
}
public override void Register()
{
DoCheckAreaTarget.Add(new CheckAreaTargetHandler(CanBeAppliedOn));
}
}
public override AuraScript GetAuraScript()
{
return new spell_marrowgar_coldflame_damage_AuraScript();
}
}
[Script]
class spell_marrowgar_bone_spike_graveyard : SpellScriptLoader
{
public spell_marrowgar_bone_spike_graveyard() : base("spell_marrowgar_bone_spike_graveyard") { }
class spell_marrowgar_bone_spike_graveyard_SpellScript : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(Misc.BoneSpikeSummonId);
}
public override bool Load()
{
return GetCaster().IsTypeId(TypeId.Unit) && GetCaster().IsAIEnabled;
}
SpellCastResult CheckCast()
{
return GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 0, new BoneSpikeTargetSelector(GetCaster().GetAI())) ? SpellCastResult.SpellCastOk : SpellCastResult.NoValidTargets;
}
void HandleSpikes(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
Creature marrowgar = GetCaster().ToCreature();
if (marrowgar)
{
CreatureAI marrowgarAI = marrowgar.GetAI();
byte boneSpikeCount = (byte)(Convert.ToBoolean((int)GetCaster().GetMap().GetSpawnMode() & 1) ? 3 : 1);
List<Unit> targets = marrowgarAI.SelectTargetList(new BoneSpikeTargetSelector(marrowgarAI), boneSpikeCount, SelectAggroTarget.Random);
if (targets.Empty())
return;
uint i = 0;
foreach (var target in targets)
{
target.CastSpell(target, Misc.BoneSpikeSummonId[i], true);
i++;
}
marrowgarAI.Talk(Texts.SayBonespike);
}
}
public override void Register()
{
OnCheckCast.Add(new CheckCastHandler(CheckCast));
OnEffectHitTarget.Add(new EffectHandler(HandleSpikes, 1, SpellEffectName.ApplyAura));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_spike_graveyard_SpellScript();
}
}
[Script]
class spell_marrowgar_bone_storm : SpellScriptLoader
{
public spell_marrowgar_bone_storm() : base("spell_marrowgar_bone_storm") { }
class spell_marrowgar_bone_storm_SpellScript : SpellScript
{
void RecalculateDamage()
{
SetHitDamage((int)(GetHitDamage() / Math.Max(Math.Sqrt(GetHitUnit().GetExactDist2d(GetCaster())), 1.0f)));
}
public override void Register()
{
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_storm_SpellScript();
}
}
[Script]
class spell_marrowgar_bone_slice : SpellScriptLoader
{
public spell_marrowgar_bone_slice() : base("spell_marrowgar_bone_slice") { }
class spell_marrowgar_bone_slice_SpellScript : SpellScript
{
public override bool Load()
{
_targetCount = 0;
return true;
}
void ClearSpikeImmunities()
{
GetCaster().GetAI().DoAction(Misc.ActionClearSpikeImmunities);
}
void CountTargets(List<WorldObject> targets)
{
_targetCount = (uint)Math.Min(targets.Count, GetSpellInfo().MaxAffectedTargets);
}
void SplitDamage()
{
// Mark the unit as hit, even if the spell missed or was dodged/parried
GetCaster().GetAI().SetGUID(GetHitUnit().GetGUID(), Misc.DataSpikeImmune);
if (_targetCount == 0)
return; // This spell can miss all targets
SetHitDamage((int)(GetHitDamage() / _targetCount));
}
public override void Register()
{
BeforeCast.Add(new CastHandler(ClearSpikeImmunities));
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(CountTargets, 0, Targets.UnitDestAreaEnemy));
OnHit.Add(new HitHandler(SplitDamage));
}
uint _targetCount;
}
public override SpellScript GetSpellScript()
{
return new spell_marrowgar_bone_slice_SpellScript();
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
/*
* 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 Game.Entities;
namespace Scripts.Northrend.IcecrownCitadel
{
public class Sindragosa
{
Position RimefangFlyPos = new Position(4413.309f, 2456.421f, 233.3795f, 2.890186f);
Position RimefangLandPos = new Position(4413.309f, 2456.421f, 203.3848f, 2.890186f);
Position SpinestalkerFlyPos = new Position(4418.895f, 2514.233f, 230.4864f, 3.396045f);
Position SpinestalkerLandPos = new Position(4418.895f, 2514.233f, 203.3848f, 3.396045f);
public static Position SindragosaSpawnPos = new Position(4818.700f, 2483.710f, 287.0650f, 3.089233f);
Position SindragosaFlyPos = new Position(4475.190f, 2484.570f, 234.8510f, 3.141593f);
Position SindragosaLandPos = new Position(4419.190f, 2484.570f, 203.3848f, 3.141593f);
Position SindragosaAirPos = new Position(4475.990f, 2484.430f, 247.9340f, 3.141593f);
Position SindragosaAirPosFar = new Position(4525.600f, 2485.150f, 245.0820f, 3.141593f);
Position SindragosaFlyInPos = new Position(4419.190f, 2484.360f, 232.5150f, 3.141593f);
}
}
@@ -0,0 +1,39 @@
/*
* 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 Game.Entities;
namespace Scripts.Northrend.IcecrownCitadel
{
public class TheLichKing
{
Position CenterPosition = new Position(503.6282f, -2124.655f, 840.8569f, 0.0f);
Position TirionIntro = new Position(489.2970f, -2124.840f, 840.8569f, 0.0f);
Position TirionCharge = new Position(482.9019f, -2124.479f, 840.8570f, 0.0f);
Position[] LichKingIntro =
{
new Position(432.0851f, -2123.673f, 864.6582f, 0.0f),
new Position(457.8351f, -2123.423f, 841.1582f, 0.0f),
new Position(465.0730f, -2123.470f, 840.8569f, 0.0f),
};
Position OutroPosition1 = new Position(493.6286f, -2124.569f, 840.8569f, 0.0f);
Position OutroFlying = new Position(508.9897f, -2124.561f, 845.3565f, 0.0f);
public static Position TerenasSpawn = new Position(495.5542f, -2517.012f, 1050.000f, 4.6993f);
Position TerenasSpawnHeroic = new Position(495.7080f, -2523.760f, 1050.000f, 0.0f);
public static Position SpiritWardenSpawn = new Position(495.3406f, -2529.983f, 1050.000f, 1.5592f);
}
}
@@ -0,0 +1,26 @@
/*
* 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 Game.Entities;
namespace Scripts.Northrend.IcecrownCitadel
{
public class ValithriaDreamwalker
{
public static Position ValithriaSpawnPos = new Position(4210.813f, 2484.443f, 364.9558f, 0.01745329f);
}
}
@@ -0,0 +1,63 @@
/*
* 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/>.
*/
namespace Scripts.Northrend.Naxxramas
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayGreet = 1;
public const uint SaySlay = 2;
public const uint EmoteLocust = 3;
public const uint EmoteFrenzy = 0;
public const uint EmoteSpawn = 1;
public const uint EmoteScarab = 2;
}
struct EventIds
{
public const uint Impale = 1; // Cast Impale On A Random Target
public const uint Locust = 2; // Begin Channeling Locust Swarm
public const uint LocustEnds = 3; // Locust Swarm Dissipates
public const uint SpawnGuard = 4; // 10-Man Only - Crypt Guard Has Delayed Spawn; Also Used For The Locust Swarm Crypt Guard In Both Modes
public const uint Scarabs = 5; // Spawn Corpse Scarabs
public const uint Berserk = 6; // Berserk
}
struct SpellIds
{
public const uint Impale = 28783; // 25-Man: 56090
public const uint LocustSwarm = 28785; // 25-Man: 54021
public const uint SummonCorpseScarabsPlr = 29105; // This Spawns 5 Corpse Scarabs On Top Of Player
public const uint SummonCorpseScarabsMob = 28864; // This Spawns 10 Corpse Scarabs On Top Of Dead Guards
public const uint Berserk = 27680;
}
struct Misc
{
public const uint achievTimedStartEvent = 9891;
public const uint PhaseNormal = 1;
public const uint PhaseSwarm = 2;
public const uint SpawnGroupsInitial25M = 1;
public const uint SpawnGroupsSingleSpawn = 2;
}
}
@@ -0,0 +1,29 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Scripts.Northrend.Nexus.EyeOfEternity
{
class BossMalygos
{
}
}
@@ -0,0 +1,351 @@
/*
* 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 Framework.GameMath;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
using System.Linq;
namespace Scripts.Northrend.Nexus.EyeOfEternity
{
struct EyeOfEternityConst
{
public const uint MaxEncounter = 1;
public const uint EventFocusingIris = 20711;
}
struct InstanceData
{
public const uint MalygosEvent = 1;
public const uint VortexHandling = 2;
public const uint PowerSparksHandling = 3;
public const uint RespawnIris = 4;
}
struct InstanceData64
{
public const uint Trigger = 0;
public const uint Malygos = 1;
public const uint Platform = 2;
public const uint AlexstraszaBunnyGUID = 3;
public const uint HeartOfMagicGUID = 4;
public const uint FocusingIrisGUID = 5;
public const uint GiftBoxBunnyGUID = 6;
}
struct InstanceNpcs
{
public const uint Malygos = 28859;
public const uint VortexTrigger = 30090;
public const uint PortalTrigger = 30118;
public const uint PowerSpark = 30084;
public const uint HoverDiskMelee = 30234;
public const uint HoverDiskCaster = 30248;
public const uint ArcaneOverload = 30282;
public const uint WyrmrestSkytalon = 30161;
public const uint Alexstrasza = 32295;
public const uint AlexstraszaBunny = 31253;
public const uint AlexstraszasGift = 32448;
public const uint SurgeOfPower = 30334;
}
struct InstanceGameObjects
{
public const uint NexusRaidPlatform = 193070;
public const uint ExitPortal = 193908;
public const uint FocusingIris10 = 193958;
public const uint FocusingIris25 = 193960;
public const uint AlexstraszaSGift10 = 193905;
public const uint AlexstraszaSGift25 = 193967;
public const uint HeartOfMagic10 = 194158;
public const uint HeartOfMagic25 = 194159;
}
struct InstanceSpells
{
public const uint Vortex4 = 55853; // Damage | Used To Enter To The Vehicle
public const uint Vortex5 = 56263; // Damage | Used To Enter To The Vehicle
public const uint PortalOpened = 61236;
public const uint RideRedDragonTriggered = 56072;
public const uint IrisOpened = 61012; // Visual When Starting Encounter
public const uint SummomRedDragonBuddy = 56070;
}
[Script]
class instance_eye_of_eternity : InstanceMapScript
{
public instance_eye_of_eternity() : base("instance_eye_of_eternity", 616) { }
class instance_eye_of_eternity_InstanceMapScript : InstanceScript
{
public instance_eye_of_eternity_InstanceMapScript(Map map) : base(map)
{
SetHeaders("EOE");
SetBossNumber(EyeOfEternityConst.MaxEncounter);
}
public override void OnPlayerEnter(Player player)
{
if (GetBossState(0) == EncounterState.Done)
player.CastSpell(player, InstanceSpells.SummomRedDragonBuddy, true);
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
if (type == InstanceData.MalygosEvent)
{
if (state == EncounterState.Fail)
{
foreach (var triggerGuid in portalTriggers)
{
Creature trigger = instance.GetCreature(triggerGuid);
if (trigger)
{
// just in case
trigger.RemoveAllAuras();
trigger.GetAI().Reset();
}
}
SpawnGameObject(InstanceGameObjects.ExitPortal, exitPortalPosition);
GameObject platform = instance.GetGameObject(platformGUID);
if (platform)
platform.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Destroyed);
}
else if (state == EncounterState.Done)
SpawnGameObject(InstanceGameObjects.ExitPortal, exitPortalPosition);
}
return true;
}
/// @todo this should be handled in map, maybe add a summon function in map
// There is no other way afaik...
void SpawnGameObject(uint entry, Position pos)
{
GameObject go = new GameObject();
if (go.Create(entry, instance, PhaseMasks.Normal, pos, Quaternion.WAxis, 255, GameObjectState.Ready))
instance.AddToMap(go);
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case InstanceGameObjects.NexusRaidPlatform:
platformGUID = go.GetGUID();
break;
case InstanceGameObjects.FocusingIris10:
case InstanceGameObjects.FocusingIris25:
irisGUID = go.GetGUID();
focusingIrisPosition = go.GetPosition();
break;
case InstanceGameObjects.ExitPortal:
exitPortalGUID = go.GetGUID();
exitPortalPosition = go.GetPosition();
break;
case InstanceGameObjects.HeartOfMagic10:
case InstanceGameObjects.HeartOfMagic25:
heartOfMagicGUID = go.GetGUID();
break;
default:
break;
}
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case InstanceNpcs.VortexTrigger:
vortexTriggers.Add(creature.GetGUID());
break;
case InstanceNpcs.Malygos:
malygosGUID = creature.GetGUID();
break;
case InstanceNpcs.PortalTrigger:
portalTriggers.Add(creature.GetGUID());
break;
case InstanceNpcs.AlexstraszaBunny:
alexstraszaBunnyGUID = creature.GetGUID();
break;
case InstanceNpcs.AlexstraszasGift:
giftBoxBunnyGUID = creature.GetGUID();
break;
}
}
public override void OnUnitDeath(Unit unit)
{
if (!unit.IsTypeId(TypeId.Player))
return;
// Player continues to be moving after death no matter if spline will be cleared along with all movements,
// so on next world tick was all about delay if box will pop or not (when new movement will be registered)
// since in EoE you never stop falling. However root at this precise* moment works,
// it will get cleared on release. If by any chance some lag happen "Reload()" and "RepopMe()" works,
// last test I made now gave me 50/0 of this bug so I can't do more about it.
unit.SetControlled(true, UnitState.Root);
}
public override void ProcessEvent(WorldObject obj, uint eventId)
{
if (eventId == EyeOfEternityConst.EventFocusingIris)
{
Creature alexstraszaBunny = instance.GetCreature(alexstraszaBunnyGUID);
if (alexstraszaBunny)
alexstraszaBunny.CastSpell(alexstraszaBunny, InstanceSpells.IrisOpened);
GameObject iris = instance.GetGameObject(irisGUID);
if (iris)
iris.SetFlag(GameObjectFields.Flags, GameObjectFlags.InUse);
Creature malygos = instance.GetCreature(malygosGUID);
if (malygos)
malygos.GetAI().DoAction(0); // ACTION_LAND_ENCOUNTER_START
GameObject exitPortal = instance.GetGameObject(exitPortalGUID);
if (exitPortal)
exitPortal.Delete();
}
}
void VortexHandling()
{
Creature malygos = instance.GetCreature(malygosGUID);
if (malygos)
{
var threatList = malygos.GetThreatManager().getThreatList();
foreach (var guid in vortexTriggers)
{
if (threatList.Empty())
return;
byte counter = 0;
Creature trigger = instance.GetCreature(guid);
if (trigger)
{
// each trigger have to cast the spell to 5 players.
foreach (var refe in threatList)
{
if (counter >= 5)
break;
Unit target = refe.getTarget();
if (target)
{
Player player = target.ToPlayer();
if (!player || player.IsGameMaster() || player.HasAura(InstanceSpells.Vortex4))
continue;
player.CastSpell(trigger, InstanceSpells.Vortex4, true);
counter++;
}
}
}
}
}
}
void PowerSparksHandling()
{
bool next = (lastPortalGUID == portalTriggers.Last() || !lastPortalGUID.IsEmpty() ? true : false);
foreach (var guid in portalTriggers)
{
if (next)
{
Creature trigger = instance.GetCreature(guid);
if (trigger)
{
lastPortalGUID = trigger.GetGUID();
trigger.CastSpell(trigger, InstanceSpells.PortalOpened, true);
return;
}
}
if (guid == lastPortalGUID)
next = true;
}
}
public override void SetData(uint data, uint value)
{
switch (data)
{
case InstanceData.VortexHandling:
VortexHandling();
break;
case InstanceData.PowerSparksHandling:
PowerSparksHandling();
break;
case InstanceData.RespawnIris:
SpawnGameObject(instance.GetDifficultyID() == Difficulty.Raid10N ? InstanceGameObjects.FocusingIris10 : InstanceGameObjects.FocusingIris25, focusingIrisPosition);
break;
}
}
public override ObjectGuid GetGuidData(uint data)
{
switch (data)
{
case InstanceData64.Trigger:
return vortexTriggers.First();
case InstanceData64.Malygos:
return malygosGUID;
case InstanceData64.Platform:
return platformGUID;
case InstanceData64.AlexstraszaBunnyGUID:
return alexstraszaBunnyGUID;
case InstanceData64.HeartOfMagicGUID:
return heartOfMagicGUID;
case InstanceData64.FocusingIrisGUID:
return irisGUID;
case InstanceData64.GiftBoxBunnyGUID:
return giftBoxBunnyGUID;
}
return ObjectGuid.Empty;
}
List<ObjectGuid> vortexTriggers = new List<ObjectGuid>();
List<ObjectGuid> portalTriggers = new List<ObjectGuid>();
ObjectGuid malygosGUID;
ObjectGuid irisGUID;
ObjectGuid lastPortalGUID;
ObjectGuid platformGUID;
ObjectGuid exitPortalGUID;
ObjectGuid heartOfMagicGUID;
ObjectGuid alexstraszaBunnyGUID;
ObjectGuid giftBoxBunnyGUID;
Position focusingIrisPosition;
Position exitPortalPosition;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_eye_of_eternity_InstanceMapScript(map);
}
}
}
@@ -0,0 +1,291 @@
/*
* 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;
namespace Scripts.Northrend.Nexus.Nexus
{
struct AnomalusConst
{
//Spells
public const uint SpellSpark = 47751;
public const uint SpellSparkHeroic = 57062;
public const uint SpellRiftShield = 47748;
public const uint SpellChargeRift = 47747; // Works Wrong (Affect Players; Not Rifts)
public const uint SpellCreateRift = 47743; // Don'T Work; Using Wa
public const uint SpellArcaneAttraction = 57063; // No Idea; When It'S Used
public const uint SpellChaoticEnergyBurst = 47688;
public const uint SpellChargedChaoticEnergyBurst = 47737;
public const uint SpellArcaneform = 48019; // Chaotic Rift Visual
//Texts
public const uint SayAggro = 0;
public const uint SayDeath = 1;
public const uint SayRift = 2;
public const uint SayShield = 3;
public const uint SayRiftEmote = 4; // Needs To Be Added To Script
public const uint SayShieldEmote = 5; // Needs To Be Added To Script
//Misc
public const uint NpcCrazedManaWraith = 26746;
public const uint NpcChaoticRift = 26918;
public const uint DataChaosTheory = 1;
public static Position[] RiftLocation =
{
new Position(652.64f, -273.70f, -8.75f, 0.0f),
new Position(634.45f, -265.94f, -8.44f, 0.0f),
new Position(620.73f, -281.17f, -9.02f, 0.0f),
new Position(626.10f, -304.67f, -9.44f, 0.0f),
new Position(639.87f, -314.11f, -9.49f, 0.0f),
new Position(651.72f, -297.44f, -9.37f, 0.0f)
};
}
[Script]
class boss_anomalus : CreatureScript
{
public boss_anomalus() : base("boss_anomalus") { }
class boss_anomalusAI : ScriptedAI
{
public boss_anomalusAI(Creature creature) : base(creature)
{
instance = me.GetInstanceScript();
}
void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, AnomalusConst.SpellSpark);
task.Repeat(TimeSpan.FromSeconds(5));
});
Phase = 0;
uiChaoticRiftGUID.Clear();
chaosTheory = true;
}
public override void Reset()
{
Initialize();
instance.SetBossState(DataTypes.Anomalus, EncounterState.NotStarted);
}
public override void EnterCombat(Unit who)
{
Talk(AnomalusConst.SayAggro);
instance.SetBossState(DataTypes.Anomalus, EncounterState.InProgress);
}
public override void JustDied(Unit killer)
{
Talk(AnomalusConst.SayDeath);
instance.SetBossState(DataTypes.Anomalus, EncounterState.Done);
}
public override uint GetData(uint type)
{
if (type == AnomalusConst.DataChaosTheory)
return chaosTheory ? 1 : 0u;
return 0;
}
public override void SummonedCreatureDies(Creature summoned, Unit who)
{
if (summoned.GetEntry() == AnomalusConst.NpcChaoticRift)
chaosTheory = false;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.GetDistance(me.GetHomePosition()) > 60.0f)
{
// Not blizzlike, hack to avoid an exploit
EnterEvadeMode();
return;
}
if (me.HasAura(AnomalusConst.SpellRiftShield))
{
if (!uiChaoticRiftGUID.IsEmpty())
{
Creature Rift = ObjectAccessor.GetCreature(me, uiChaoticRiftGUID);
if (Rift && Rift.IsDead())
{
me.RemoveAurasDueToSpell(AnomalusConst.SpellRiftShield);
uiChaoticRiftGUID.Clear();
}
return;
}
}
else
uiChaoticRiftGUID.Clear();
if ((Phase == 0) && HealthBelowPct(50))
{
Phase = 1;
Talk(AnomalusConst.SayShield);
DoCast(me, AnomalusConst.SpellRiftShield);
Creature Rift = me.SummonCreature(AnomalusConst.NpcChaoticRift, AnomalusConst.RiftLocation[RandomHelper.IRand(0, 5)], TempSummonType.TimedDespawnOOC, 1000);
if (Rift)
{
//DoCast(Rift, SPELL_CHARGE_RIFT);
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
Rift.GetAI().AttackStart(target);
uiChaoticRiftGUID = Rift.GetGUID();
Talk(AnomalusConst.SayRift);
}
}
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
InstanceScript instance;
byte Phase;
ObjectGuid uiChaoticRiftGUID;
bool chaosTheory;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_anomalusAI>(creature);
}
}
[Script]
class npc_chaotic_rift : CreatureScript
{
public npc_chaotic_rift() : base("npc_chaotic_rift") { }
class npc_chaotic_riftAI : ScriptedAI
{
public npc_chaotic_riftAI(Creature creature) : base(creature)
{
Initialize();
instance = me.GetInstanceScript();
SetCombatMovement(false);
}
void Initialize()
{
uiChaoticEnergyBurstTimer = 1000;
uiSummonCrazedManaWraithTimer = 5000;
}
public override void Reset()
{
Initialize();
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
DoCast(me, AnomalusConst.SpellArcaneform, false);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (uiChaoticEnergyBurstTimer <= diff)
{
Creature Anomalus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Anomalus));
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
{
if (Anomalus && Anomalus.HasAura(AnomalusConst.SpellRiftShield))
DoCast(target, AnomalusConst.SpellChargedChaoticEnergyBurst);
else
DoCast(target, AnomalusConst.SpellChaoticEnergyBurst);
}
uiChaoticEnergyBurstTimer = 1000;
}
else
uiChaoticEnergyBurstTimer -= diff;
if (uiSummonCrazedManaWraithTimer <= diff)
{
Creature Wraith = me.SummonCreature(AnomalusConst.NpcCrazedManaWraith, me.GetPositionX() + 1, me.GetPositionY() + 1, me.GetPositionZ(), 0, TempSummonType.TimedDespawnOOC, 1000);
if (Wraith)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
Wraith.GetAI().AttackStart(target);
}
Creature Anomalus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Anomalus));
if (Anomalus && Anomalus.HasAura(AnomalusConst.SpellRiftShield))
uiSummonCrazedManaWraithTimer = 5000;
else
uiSummonCrazedManaWraithTimer = 10000;
}
else
uiSummonCrazedManaWraithTimer -= diff;
}
InstanceScript instance;
uint uiChaoticEnergyBurstTimer;
uint uiSummonCrazedManaWraithTimer;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_chaotic_riftAI>(creature);
}
}
[Script]
class achievement_chaos_theory : AchievementCriteriaScript
{
public achievement_chaos_theory() : base("achievement_chaos_theory")
{
}
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature Anomalus = target.ToCreature();
if (Anomalus)
if (Anomalus.GetAI().GetData(AnomalusConst.DataChaosTheory) != 0)
return true;
return false;
}
}
}
@@ -0,0 +1,277 @@
/*
* 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.Nexus.Nexus
{
struct KeristraszaConst
{
//Spells
public const uint SpellFrozenPrison = 47854;
public const uint SpellTailSweep = 50155;
public const uint SpellCrystalChains = 50997;
public const uint SpellEnrage = 8599;
public const uint SpellCrystalFireBreath = 48096;
public const uint SpellCrystalize = 48179;
public const uint SpellIntenseCold = 48094;
public const uint SpellIntenseColdTriggered = 48095;
//Yells
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayEnrage = 2;
public const uint SayDeath = 3;
public const uint SayCrystalNova = 4;
public const uint SayFrenzy = 5;
//Misc
public const uint DataIntenseCold = 1;
public const uint DataContainmentSpheres = 3;
}
[Script]
class boss_keristrasza : CreatureScript
{
public boss_keristrasza() : base("boss_keristrasza") { }
public class boss_keristraszaAI : BossAI
{
public boss_keristraszaAI(Creature creature) : base(creature, DataTypes.Keristrasza)
{
Initialize();
}
void Initialize()
{
_enrage = false;
//Crystal FireBreath
_scheduler.Schedule(TimeSpan.FromSeconds(14), task =>
{
DoCastVictim(KeristraszaConst.SpellCrystalFireBreath);
task.Repeat(TimeSpan.FromSeconds(14));
});
//CrystalChainsCrystalize
_scheduler.Schedule(TimeSpan.FromSeconds(DungeonMode<uint>(30, 11)), task =>
{
Talk(KeristraszaConst.SayCrystalNova);
if (IsHeroic())
DoCast(me, KeristraszaConst.SpellCrystalize);
else
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, KeristraszaConst.SpellCrystalChains);
}
task.Repeat(TimeSpan.FromSeconds(DungeonMode<uint>(30, 11)));
});
//TailSweep
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCast(me, KeristraszaConst.SpellTailSweep);
task.Repeat(TimeSpan.FromSeconds(5));
});
}
public override void Reset()
{
Initialize();
_intenseColdList.Clear();
me.RemoveFlag(UnitFields.Flags, UnitFlags.Stunned);
RemovePrison(CheckContainmentSpheres());
_Reset();
}
public override void EnterCombat(Unit who)
{
Talk(KeristraszaConst.SayAggro);
DoCastAOE(KeristraszaConst.SpellIntenseCold);
_EnterCombat();
}
public override void JustDied(Unit killer)
{
Talk(KeristraszaConst.SayDeath);
_JustDied();
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(KeristraszaConst.SaySlay);
}
public bool CheckContainmentSpheres(bool removePrison = false)
{
for (uint i = DataTypes.AnomalusContainmetSphere; i < (DataTypes.AnomalusContainmetSphere + KeristraszaConst.DataContainmentSpheres); ++i)
{
GameObject containmentSpheres = ObjectAccessor.GetGameObject(me, instance.GetGuidData(i));
if (!containmentSpheres || containmentSpheres.GetGoState() != GameObjectState.Active)
return false;
}
if (removePrison)
RemovePrison(true);
return true;
}
void RemovePrison(bool remove)
{
if (remove)
{
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
if (me.HasAura(KeristraszaConst.SpellFrozenPrison))
me.RemoveAurasDueToSpell(KeristraszaConst.SpellFrozenPrison);
}
else
{
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
DoCast(me, KeristraszaConst.SpellFrozenPrison, false);
}
}
public override void SetGUID(ObjectGuid guid, int id = 0)
{
if (id == KeristraszaConst.DataIntenseCold)
_intenseColdList.Add(guid);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!_enrage && me.HealthBelowPctDamaged(25, damage))
{
Talk(KeristraszaConst.SayEnrage);
Talk(KeristraszaConst.SayFrenzy);
DoCast(me, KeristraszaConst.SpellEnrage);
_enrage = true;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
bool _enrage;
public List<ObjectGuid> _intenseColdList = new List<ObjectGuid>();
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_keristraszaAI>(creature);
}
}
[Script]
class containment_sphere : GameObjectScript
{
public containment_sphere() : base("containment_sphere") { }
public override bool OnGossipHello(Player player, GameObject go)
{
InstanceScript instance = go.GetInstanceScript();
Creature pKeristrasza = ObjectAccessor.GetCreature(go, instance.GetGuidData(DataTypes.Keristrasza));
if (pKeristrasza && pKeristrasza.IsAlive())
{
// maybe these are hacks :(
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
go.SetGoState(GameObjectState.Active);
((boss_keristrasza.boss_keristraszaAI)pKeristrasza.GetAI()).CheckContainmentSpheres(true);
}
return true;
}
}
[Script]
class spell_intense_cold : SpellScriptLoader
{
public spell_intense_cold() : base("spell_intense_cold") { }
class spell_intense_cold_AuraScript : AuraScript
{
void HandlePeriodicTick(AuraEffect aurEff)
{
if (aurEff.GetBase().GetStackAmount() < 2)
return;
Unit caster = GetCaster();
/// @todo the caster should be boss but not the player
if (!caster || caster.GetAI() == null)
return;
caster.GetAI().SetGUID(GetTarget().GetGUID(), (int)KeristraszaConst.DataIntenseCold);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 1, AuraType.PeriodicDamage));
}
}
public override AuraScript GetAuraScript()
{
return new spell_intense_cold_AuraScript();
}
}
[Script]
class achievement_intense_cold : AchievementCriteriaScript
{
public achievement_intense_cold() : base("achievement_intense_cold") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
var _intenseColdList = ((boss_keristrasza.boss_keristraszaAI)target.ToCreature().GetAI())._intenseColdList;
if (!_intenseColdList.Empty())
{
foreach (var guid in _intenseColdList)
if (player.GetGUID() == guid)
return false;
}
return true;
}
}
}
@@ -0,0 +1,349 @@
/*
* 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;
namespace Scripts.Northrend.Nexus.Nexus
{
struct MagusTelestraConst
{
//Spells
public const uint SpellIceNova = 47772;
public const uint SpellIceNovaH = 56935;
public const uint SpellFirebomb = 47773;
public const uint SpellFirebombH = 56934;
public const uint SpellGravityWell = 47756;
public const uint SpellTelestraBack = 47714;
public const uint SpellFireMagusVisual = 47705;
public const uint SpellFrostMagusVisual = 47706;
public const uint SpellArcaneMagusVisual = 47704;
public const uint SpellWearChristmasHat = 61400;
//Npcs
public const uint NpcFireMagus = 26928;
public const uint NpcFrostMagus = 26930;
public const uint NpcArcaneMagus = 26929;
//Texts
public const uint SayAggro = 0;
public const uint SayKill = 1;
public const uint SayDeath = 2;
public const uint SayMerge = 3;
public const uint SaySplit = 4;
//Misc
public const uint DataSplitPersonality = 1;
public const ushort GameEventWinterVeil = 2;
}
[Script]
class boss_magus_telestra : CreatureScript
{
public boss_magus_telestra() : base("boss_magus_telestra") { }
class boss_magus_telestraAI : ScriptedAI
{
public boss_magus_telestraAI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
bFireMagusDead = false;
bFrostMagusDead = false;
bArcaneMagusDead = false;
uiIsWaitingToAppearTimer = 0;
}
void Initialize()
{
Phase = 0;
uiIceNovaTimer = 7 * Time.InMilliseconds;
uiFireBombTimer = 0;
uiGravityWellTimer = 15 * Time.InMilliseconds;
uiCooldown = 0;
for (byte n = 0; n < 3; ++n)
time[n] = 0;
splitPersonality = 0;
bIsWaitingToAppear = false;
}
public override void Reset()
{
Initialize();
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.NotStarted);
if (IsHeroic() && Global.GameEventMgr.IsActiveEvent(MagusTelestraConst.GameEventWinterVeil) && !me.HasAura(MagusTelestraConst.SpellWearChristmasHat))
me.AddAura(MagusTelestraConst.SpellWearChristmasHat, me);
}
public override void EnterCombat(Unit who)
{
Talk(MagusTelestraConst.SayAggro);
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.InProgress);
}
public override void JustDied(Unit killer)
{
Talk(MagusTelestraConst.SayDeath);
instance.SetBossState(DataTypes.MagusTelestra, EncounterState.Done);
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(MagusTelestraConst.SayKill);
}
public override uint GetData(uint type)
{
if (type == MagusTelestraConst.DataSplitPersonality)
return splitPersonality;
return 0;
}
public override void UpdateAI(uint diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (bIsWaitingToAppear)
{
me.StopMoving();
me.AttackStop();
if (uiIsWaitingToAppearTimer <= diff)
{
me.CastSpell(me, 47714, true);
me.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
bIsWaitingToAppear = false;
InVanish = false;
me.SendAIReaction(AiReaction.Hostile);
}
else
uiIsWaitingToAppearTimer -= diff;
return;
}
if ((Phase == 1) || (Phase == 3))
{
if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead)
{
for (byte n = 0; n < 3; ++n)
time[n] = 0;
me.GetMotionMaster().Clear();
DoCast(me, MagusTelestraConst.SpellTelestraBack);
if (Phase == 1)
Phase = 2;
if (Phase == 3)
Phase = 4;
bIsWaitingToAppear = true;
uiIsWaitingToAppearTimer = 4 * Time.InMilliseconds;
Talk(MagusTelestraConst.SayMerge);
}
else
return;
}
if ((Phase == 0) && HealthBelowPct(50))
{
InVanish = true;
Phase = 1;
me.CastStop();
me.RemoveAllAuras();
me.CastSpell(me, 47710, false);
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
bFireMagusDead = false;
bFrostMagusDead = false;
bArcaneMagusDead = false;
Talk(MagusTelestraConst.SaySplit);
return;
}
if (IsHeroic() && (Phase == 2) && HealthBelowPct(10))
{
InVanish = true;
Phase = 3;
me.CastStop();
me.RemoveAllAuras();
me.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable);
bFireMagusDead = false;
bFrostMagusDead = false;
bArcaneMagusDead = false;
Talk(MagusTelestraConst.SaySplit);
return;
}
if (uiCooldown != 0)
{
if (uiCooldown <= diff)
uiCooldown = 0;
else
{
uiCooldown -= diff;
return;
}
}
if (uiIceNovaTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
{
DoCast(target, MagusTelestraConst.SpellIceNova, false);
uiCooldown = 1500;
}
uiIceNovaTimer = 15 * Time.InMilliseconds;
}
else uiIceNovaTimer -= diff;
if (uiGravityWellTimer <= diff)
{
Unit target = me.GetVictim();
if (target)
{
DoCast(target, MagusTelestraConst.SpellGravityWell);
uiCooldown = 6 * Time.InMilliseconds;
}
uiGravityWellTimer = 15 * Time.InMilliseconds;
}
else uiGravityWellTimer -= diff;
if (uiFireBombTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
{
DoCast(target, MagusTelestraConst.SpellFirebomb, false);
uiCooldown = 2 * Time.InMilliseconds;
}
uiFireBombTimer = 2 * Time.InMilliseconds;
}
else uiFireBombTimer -= diff;
if (!InVanish)
DoMeleeAttackIfReady();
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
if (summon.IsAlive())
return;
switch (summon.GetEntry())
{
case MagusTelestraConst.NpcFireMagus:
bFireMagusDead = true;
break;
case MagusTelestraConst.NpcFrostMagus:
bFrostMagusDead = true;
break;
case MagusTelestraConst.NpcArcaneMagus:
bArcaneMagusDead = true;
break;
}
byte i = 0;
while (time[i] != 0)
++i;
time[i] = Global.WorldMgr.GetGameTime();
if (i == 2 && (time[2] - time[1] < 5) && (time[1] - time[0] < 5))
++splitPersonality;
}
InstanceScript instance;
bool bFireMagusDead;
bool bFrostMagusDead;
bool bArcaneMagusDead;
bool bIsWaitingToAppear;
bool InVanish;
uint uiIsWaitingToAppearTimer;
uint uiIceNovaTimer;
uint uiFireBombTimer;
uint uiGravityWellTimer;
uint uiCooldown;
byte Phase;
byte splitPersonality;
long[] time = new long[3];
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_magus_telestraAI>(creature);
}
}
[Script]
class achievement_split_personality : AchievementCriteriaScript
{
public achievement_split_personality() : base("achievement_split_personality")
{
}
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature Telestra = target.ToCreature();
if (Telestra)
if (Telestra.GetAI().GetData(MagusTelestraConst.DataSplitPersonality) == 2)
return true;
return false;
}
}
[Script]
class spell_gravity_well_effect : SpellScriptLoader
{
public spell_gravity_well_effect() : base("spell_gravity_well_effect") { }
class spell_gravity_well_effect_SpellScript : SpellScript
{
void HandleDummy(uint index)
{
}
public override void Register()
{
}
}
public override SpellScript GetSpellScript()
{
return new spell_gravity_well_effect_SpellScript();
}
}
}
@@ -0,0 +1,113 @@
/*
* 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.Scripting;
using System;
namespace Scripts.Northrend.Nexus.Nexus
{
struct NexusCommandersConst
{
//Spells
public const uint SpellBattleShout = 31403;
public const uint SpellCharge = 60067;
public const uint SpellFrighteningShout = 19134;
public const uint SpellWhirlwind = 38618;
public const uint SpellFrozenPrison = 47543;
//Texts
public const uint SayAggro = 0;
public const uint SayKill = 1;
public const uint SayDeath = 2;
}
[Script]
class boss_nexus_commanders : CreatureScript
{
public boss_nexus_commanders() : base("boss_nexus_commanders") { }
class boss_nexus_commandersAI : BossAI
{
boss_nexus_commandersAI(Creature creature) : base(creature, DataTypes.Commander) { }
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(NexusCommandersConst.SayAggro);
me.RemoveAurasDueToSpell(NexusCommandersConst.SpellFrozenPrison);
DoCast(me, NexusCommandersConst.SpellBattleShout);
//Charge
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, NexusCommandersConst.SpellCharge);
task.Repeat(TimeSpan.FromSeconds(11), TimeSpan.FromSeconds(15));
});
//Whirlwind
_scheduler.Schedule(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(8), task =>
{
DoCast(me, NexusCommandersConst.SpellWhirlwind);
task.Repeat(TimeSpan.FromSeconds(19.5), TimeSpan.FromSeconds(25));
});
//Frightening Shout
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(15), task =>
{
DoCastAOE(NexusCommandersConst.SpellFrighteningShout);
task.Repeat(TimeSpan.FromSeconds(45), TimeSpan.FromSeconds(55));
});
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(NexusCommandersConst.SayDeath);
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(NexusCommandersConst.SayKill);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_nexus_commandersAI>(creature);
}
}
}
@@ -0,0 +1,291 @@
/*
* 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.Scripting;
using Game.Spells;
using System;
namespace Scripts.Northrend.Nexus.Nexus
{
struct OrmorokConst
{
//Spells
public const uint SpellReflection = 47981;
public const uint SpellTrample = 48016;
public const uint SpellFrenzy = 48017;
public const uint SpellSummonCrystallineTangler = 61564;
public const uint SpellCrystalSpikes = 47958;
//Texts
public const uint SayAggro = 1;
public const uint SayDeath = 2;
public const uint SayReflect = 3;
public const uint SayCrystalSpikes = 4;
public const uint SayKill = 5;
public const uint SayFrenzy = 6;
}
[Script]
class boss_ormorok : CreatureScript
{
public boss_ormorok() : base("boss_ormorok") { }
class boss_ormorokAI : BossAI
{
public boss_ormorokAI(Creature creature) : base(creature, DataTypes.Ormorok)
{
Initialize();
}
void Initialize()
{
frenzy = false;
}
public override void Reset()
{
base.Reset();
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
//Crystal Spikes
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
Talk(OrmorokConst.SayCrystalSpikes);
DoCast(OrmorokConst.SpellCrystalSpikes);
task.Repeat(TimeSpan.FromSeconds(12));
});
//Trample
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
DoCast(me, OrmorokConst.SpellTrample);
task.Repeat(TimeSpan.FromSeconds(10));
});
//Spell Reflection
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
Talk(OrmorokConst.SayReflect);
DoCast(me, OrmorokConst.SpellReflection);
task.Repeat(TimeSpan.FromSeconds(30));
});
//Heroic Crystalline Tangler
if (IsHeroic())
{
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, new OrmorokTanglerPredicate(me));
if (target)
DoCast(target, OrmorokConst.SpellSummonCrystallineTangler);
task.Repeat(TimeSpan.FromSeconds(17));
});
}
Talk(OrmorokConst.SayAggro);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!frenzy && HealthBelowPct(25))
{
Talk(OrmorokConst.SayFrenzy);
DoCast(me, OrmorokConst.SpellFrenzy);
frenzy = true;
}
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(OrmorokConst.SayDeath);
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
Talk(OrmorokConst.SayKill);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
bool frenzy;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_ormorokAI>(creature);
}
}
class OrmorokTanglerPredicate : ISelector
{
public OrmorokTanglerPredicate(Unit unit)
{
me = unit;
}
public bool Check(Unit target)
{
return target.GetDistance2d(me) >= 5.0f;
}
Unit me;
}
struct CrystalSpikesConst
{
public const uint NpcCrystalSpikeInitial = 27101;
public const uint NpcCrystalSpikeTrigger = 27079;
public const uint DataCount = 1;
public const uint MaxCount = 5;
public const uint SpellCrystalSpikeDamage = 47944;
public const uint GoCrystalSpikeTrap = 188537;
public static uint[] CrystalSpikeSummon =
{
47936,
47942,
7943
};
}
[Script]
class npc_crystal_spike_trigger : CreatureScript
{
public npc_crystal_spike_trigger() : base("npc_crystal_spike_trigger") { }
class npc_crystal_spike_triggerAI : ScriptedAI
{
public npc_crystal_spike_triggerAI(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit owner)
{
switch (me.GetEntry())
{
case CrystalSpikesConst.NpcCrystalSpikeInitial:
_count = 0;
me.SetFacingToObject(owner);
break;
case CrystalSpikesConst.NpcCrystalSpikeTrigger:
Creature trigger = owner.ToCreature();
if (trigger)
_count = trigger.GetAI().GetData(CrystalSpikesConst.DataCount) + 1;
break;
default:
_count = CrystalSpikesConst.MaxCount;
break;
}
if (me.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
{
GameObject trap = me.FindNearestGameObject(CrystalSpikesConst.GoCrystalSpikeTrap, 1.0f);
if (trap)
trap.Use(me);
}
//Despawn
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
{
if (me.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
{
GameObject trap = me.FindNearestGameObject(CrystalSpikesConst.GoCrystalSpikeTrap, 1.0f);
if (trap)
trap.Delete();
}
me.DespawnOrUnsummon();
});
}
public override uint GetData(uint type)
{
return type == CrystalSpikesConst.DataCount ? _count : 0;
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
uint _count;
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_crystal_spike_triggerAI(creature);
}
}
[Script]
class spell_crystal_spike : SpellScriptLoader
{
public spell_crystal_spike() : base("spell_crystal_spike") { }
class spell_crystal_spike_AuraScript : AuraScript
{
void HandlePeriodic(AuraEffect aurEff)
{
Unit target = GetTarget();
if (target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeInitial || target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeTrigger)
{
Creature trigger = target.ToCreature();
if (trigger)
{
uint spell = target.GetEntry() == CrystalSpikesConst.NpcCrystalSpikeInitial ? CrystalSpikesConst.CrystalSpikeSummon[0] : CrystalSpikesConst.CrystalSpikeSummon[RandomHelper.IRand(0, 2)];
if (trigger.GetAI().GetData(CrystalSpikesConst.DataCount) < CrystalSpikesConst.MaxCount)
trigger.CastSpell(trigger, spell, true);
}
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
}
}
public override AuraScript GetAuraScript()
{
return new spell_crystal_spike_AuraScript();
}
}
}
@@ -0,0 +1,227 @@
/*
* 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.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Northrend.Nexus.Nexus
{
struct DataTypes
{
public const uint Commander = 0;
public const uint MagusTelestra = 1;
public const uint Anomalus = 2;
public const uint Ormorok = 3;
public const uint Keristrasza = 4;
public const uint AnomalusContainmetSphere = 5;
public const uint OrmorokContainmetSphere = 6;
public const uint TelestraContainmetSphere = 7;
}
struct CreatureIds
{
public const uint Anomalus = 26763;
public const uint Keristrasza = 26723;
// Alliance
public const uint AllianceBerserker = 26800;
public const uint AllianceRanger = 26802;
public const uint AllianceCleric = 26805;
public const uint AllianceCommander = 27949;
public const uint CommanderStoutbeard = 26796;
// Horde
public const uint HordeBerserker = 26799;
public const uint HordeRanger = 26801;
public const uint HordeCleric = 26803;
public const uint HordeCommander = 27947;
public const uint CommanderKolurg = 26798;
}
struct GameObjectIds
{
public const uint AnomalusContainmetSphere = 188527;
public const uint OrmoroksContainmetSphere = 188528;
public const uint TelestrasContainmetSphere = 188526;
}
[Script]
class instance_nexus : InstanceMapScript
{
public instance_nexus() : base(nameof(instance_nexus), 576) { }
class instance_nexus_InstanceMapScript : InstanceScript
{
public instance_nexus_InstanceMapScript(Map map) : base(map)
{
SetHeaders("NEX");
SetBossNumber(DataTypes.Keristrasza + 1);
_teamInInstance = 0;
}
public override void OnPlayerEnter(Player player)
{
if (_teamInInstance == 0)
_teamInInstance = player.GetTeam();
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case CreatureIds.Anomalus:
AnomalusGUID = creature.GetGUID();
break;
case CreatureIds.Keristrasza:
KeristraszaGUID = creature.GetGUID();
break;
// Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
case CreatureIds.AllianceBerserker:
if (ServerAllowsTwoSideGroups())
creature.SetFaction(16);
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.HordeBerserker);
break;
case CreatureIds.AllianceRanger:
if (ServerAllowsTwoSideGroups())
creature.SetFaction(16);
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.HordeRanger);
break;
case CreatureIds.AllianceCleric:
if (ServerAllowsTwoSideGroups())
creature.SetFaction(16);
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.HordeCleric);
break;
case CreatureIds.AllianceCommander:
if (ServerAllowsTwoSideGroups())
creature.SetFaction(16);
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.HordeCommander);
break;
case CreatureIds.CommanderStoutbeard:
if (ServerAllowsTwoSideGroups())
creature.SetFaction(16);
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.CommanderKolurg);
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.AnomalusContainmetSphere:
AnomalusContainmentSphere = go.GetGUID();
if (GetBossState(DataTypes.Anomalus) == EncounterState.Done)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
break;
case GameObjectIds.OrmoroksContainmetSphere:
OrmoroksContainmentSphere = go.GetGUID();
if (GetBossState(DataTypes.Ormorok) == EncounterState.Done)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
break;
case GameObjectIds.TelestrasContainmetSphere:
TelestrasContainmentSphere = go.GetGUID();
if (GetBossState(DataTypes.MagusTelestra) == EncounterState.Done)
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
break;
default:
break;
}
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case DataTypes.MagusTelestra:
if (state == EncounterState.Done)
{
GameObject sphere = instance.GetGameObject(TelestrasContainmentSphere);
if (sphere)
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
case DataTypes.Anomalus:
if (state == EncounterState.Done)
{
GameObject sphere = instance.GetGameObject(AnomalusContainmentSphere);
if (sphere)
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
case DataTypes.Ormorok:
if (state == EncounterState.Done)
{
GameObject sphere = instance.GetGameObject(OrmoroksContainmentSphere);
if (sphere)
sphere.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
break;
default:
break;
}
return true;
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataTypes.Anomalus:
return AnomalusGUID;
case DataTypes.Keristrasza:
return KeristraszaGUID;
case DataTypes.AnomalusContainmetSphere:
return AnomalusContainmentSphere;
case DataTypes.OrmorokContainmetSphere:
return OrmoroksContainmentSphere;
case DataTypes.TelestraContainmetSphere:
return TelestrasContainmentSphere;
default:
break;
}
return ObjectGuid.Empty;
}
ObjectGuid AnomalusGUID;
ObjectGuid KeristraszaGUID;
ObjectGuid AnomalusContainmentSphere;
ObjectGuid OrmoroksContainmentSphere;
ObjectGuid TelestrasContainmentSphere;
Team _teamInInstance;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_nexus_InstanceMapScript(map);
}
}
}
@@ -0,0 +1,368 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Entities;
using Game.Scripting;
using Game.Maps;
using Framework.Constants;
using Game.Network.Packets;
using Framework.Dynamic;
namespace Scripts.Northrend.Nexus.Oculus
{
/*
struct DataTypes
{
// Encounter States/Boss GUIDs
public const uint Drakos = 0;
public const uint Varos = 1;
public const uint Urom = 2;
public const uint Eregos = 3;
// GPS System
public const uint Constructs = 4;
}
class instance_oculus : InstanceMapScript
{
public instance_oculus() : base(nameof(instance_oculus), 578) { }
class instance_oculus_InstanceMapScript : InstanceScript
{
public instance_oculus_InstanceMapScript(Map map) : base(map)
{
SetHeaders("OC");
SetBossNumber(DataTypes.Eregos + 1);
LoadDoorData(doorData);
CentrifugueConstructCounter = 0;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case NPC_DRAKOS:
DrakosGUID = creature.GetGUID();
break;
case NPC_VAROS:
VarosGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
creature.SetPhaseMask(1, true);
break;
case NPC_UROM:
UromGUID = creature.GetGUID();
if (GetBossState(DATA_VAROS) == EncounterState.Done)
creature.SetPhaseMask(1, true);
break;
case NPC_EREGOS:
EregosGUID = creature.GetGUID();
if (GetBossState(DATA_UROM) == EncounterState.Done)
creature.SetPhaseMask(1, true);
break;
case NPC_CENTRIFUGE_CONSTRUCT:
if (creature.IsAlive())
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++CentrifugueConstructCounter);
break;
case NPC_BELGARISTRASZ:
BelgaristraszGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
{
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
creature.Relocate(BelgaristraszMove);
}
break;
case NPC_ETERNOS:
EternosGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
{
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
creature.Relocate(EternosMove);
}
break;
case NPC_VERDISA:
VerdisaGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
{
creature.SetFlag(UnitFields.NpcFlags, NPCFlags.Gossip);
creature.Relocate(VerdisaMove);
}
break;
case NPC_GREATER_WHELP:
if (GetBossState(DATA_UROM) == EncounterState.Done)
{
creature.SetPhaseMask(1, true);
GreaterWhelpList.Add(creature.GetGUID());
}
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GO_DRAGON_CAGE_DOOR:
AddDoor(go, true);
break;
case GO_EREGOS_CACHE_N:
case GO_EREGOS_CACHE_H:
EregosCacheGUID = go.GetGUID();
break;
default:
break;
}
}
public override void OnGameObjectRemove(GameObject go)
{
switch (go.GetEntry())
{
case GO_DRAGON_CAGE_DOOR:
AddDoor(go, false);
break;
default:
break;
}
}
public override void OnUnitDeath(Unit unit)
{
Creature creature = unit.ToCreature();
if (!creature)
return;
if (creature.GetEntry() == NPC_CENTRIFUGE_CONSTRUCT)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --CentrifugueConstructCounter);
if (CentrifugueConstructCounter == 0)
{
Creature varos = instance.GetCreature(VarosGUID);
if (varos)
varos.RemoveAllAuras();
}
}
}
public override void FillInitialWorldStates(InitWorldStates packet)
{
if (GetBossState(DATA_DRAKOS) == EncounterState.Done && GetBossState(DATA_VAROS) != EncounterState.Done)
{
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
}
else
{
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
packet.Worldstates.Add(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, 0);
}
}
public override void ProcessEvent(WorldObject Unit, uint eventId)
{
if (eventId != EVENT_CALL_DRAGON)
return;
Creature varos = instance.GetCreature(VarosGUID);
if (varos)
{
Creature drake = varos.SummonCreature(NPC_AZURE_RING_GUARDIAN, varos.GetPositionX(), varos.GetPositionY(), varos.GetPositionZ() + 40);
if (drake)
drake.GetAI().DoAction(ACTION_CALL_DRAGON_EVENT);
}
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case DATA_DRAKOS:
if (state == EncounterState.Done)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
FreeDragons();
Creature varos = instance.GetCreature(VarosGUID);
if (varos)
varos.SetPhaseMask(1, true);
events.ScheduleEvent(EVENT_VAROS_INTRO, 15000);
}
break;
case DATA_VAROS:
if (state == EncounterState.Done)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
Creature urom = instance.GetCreature(UromGUID);
if (urom)
urom.SetPhaseMask(1, true);
}
break;
case DATA_UROM:
if (state == EncounterState.Done)
{
Creature eregos = instance.GetCreature(EregosGUID);
if (eregos)
{
eregos.SetPhaseMask(1, true);
GreaterWhelps();
events.ScheduleEvent(EVENT_EREGOS_INTRO, 5000);
}
}
break;
case DATA_EREGOS:
if (state == EncounterState.Done)
{
GameObject cache = instance.GetGameObject(EregosCacheGUID);
if (cache)
{
cache.SetRespawnTime((int)cache.GetRespawnDelay());
cache.RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
}
break;
}
return true;
}
public override uint GetData(uint type)
{
if (type == DATA_CONSTRUCTS)
{
if (CentrifugueConstructCounter == 0)
return KILL_NO_CONSTRUCT;
else if (CentrifugueConstructCounter == 1)
return KILL_ONE_CONSTRUCT;
else if (CentrifugueConstructCounter > 1)
return KILL_MORE_CONSTRUCT;
}
return KILL_NO_CONSTRUCT;
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DATA_DRAKOS:
return DrakosGUID;
case DATA_VAROS:
return VarosGUID;
case DATA_UROM:
return UromGUID;
case DATA_EREGOS:
return EregosGUID;
default:
break;
}
return ObjectGuid.Empty;
}
void FreeDragons()
{
Creature belgaristrasz = instance.GetCreature(BelgaristraszGUID);
if (belgaristrasz)
{
belgaristrasz.SetWalk(true);
belgaristrasz.GetMotionMaster().MovePoint(POINT_MOVE_OUT, BelgaristraszMove);
}
Creature eternos = instance.GetCreature(EternosGUID);
if (eternos)
{
eternos.SetWalk(true);
eternos.GetMotionMaster().MovePoint(POINT_MOVE_OUT, EternosMove);
}
Creature verdisa = instance.GetCreature(VerdisaGUID);
if (verdisa)
{
verdisa.SetWalk(true);
verdisa.GetMotionMaster().MovePoint(POINT_MOVE_OUT, VerdisaMove);
}
}
public override void Update(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case EVENT_VAROS_INTRO:
Creature varos = instance.GetCreature(VarosGUID);
if (varos)
varos.GetAI().Talk(SAY_VAROS_INTRO_TEXT);
break;
case EVENT_EREGOS_INTRO:
Creature eregos = instance.GetCreature(EregosGUID);
if (eregos)
eregos.GetAI().Talk(SAY_EREGOS_INTRO_TEXT);
break;
default:
break;
}
});
}
void GreaterWhelps()
{
foreach (ObjectGuid guid in GreaterWhelpList)
{
Creature gwhelp = instance.GetCreature(guid);
if (gwhelp)
gwhelp.SetPhaseMask(1, true);
}
}
ObjectGuid DrakosGUID;
ObjectGuid VarosGUID;
ObjectGuid UromGUID;
ObjectGuid EregosGUID;
ObjectGuid BelgaristraszGUID;
ObjectGuid EternosGUID;
ObjectGuid VerdisaGUID;
byte CentrifugueConstructCounter;
ObjectGuid EregosCacheGUID;
List<ObjectGuid> GreaterWhelpList = new List<ObjectGuid>();
EventMap events = new EventMap();
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_oculus_InstanceMapScript(map);
}
}
*/
}
@@ -0,0 +1,30 @@
/*
* 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 Game.Entities;
namespace Scripts.Northrend.Ulduar
{
namespace Algalon
{
class AlgalonTheObserver
{
public static Position AlgalonSummonPos = new Position(1632.531f, -304.8516f, 450.1123f, 1.530165f);
public static Position AlgalonLandPos = new Position(1632.668f, -302.7656f, 417.3211f, 1.530165f);
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+162
View File
@@ -0,0 +1,162 @@
/*
* 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Entities;
using Game.Scripting;
using Game.AI;
using Framework.Constants;
using Game.Spells;
namespace Scripts.Northrend.Ulduar
{
namespace Razorscale
{
/*class boss_razorscale_controller : CreatureScript
{
public boss_razorscale_controller() : base("boss_razorscale_controller") { }
class boss_razorscale_controllerAI : BossAI
{
public boss_razorscale_controllerAI(Creature creature) : base(creature, InstanceData.RazorscaleControl)
{
me.SetDisplayId(me.GetCreatureTemplate().ModelId2);
}
public override void Reset()
{
_Reset();
me.SetReactState(ReactStates.Passive);
}
public override void SpellHit(Unit caster, SpellInfo spell)
{
switch (spell.Id)
{
case SPELL_FLAMED:
GameObject Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_1));
if (Harpoon)
Harpoon.RemoveFromWorld();
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_2));
if (Harpoon)
Harpoon.RemoveFromWorld();
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_3));
if (Harpoon)
Harpoon.RemoveFromWorld();
Harpoon = ObjectAccessor.GetGameObject(me, instance.GetGuidData(GO_RAZOR_HARPOON_4));
if (Harpoon)
Harpoon.RemoveFromWorld();
DoAction(ACTION_HARPOON_BUILD);
DoAction(ACTION_PLACE_BROKEN_HARPOON);
break;
case SPELL_HARPOON_SHOT_1:
case SPELL_HARPOON_SHOT_2:
case SPELL_HARPOON_SHOT_3:
case SPELL_HARPOON_SHOT_4:
DoCast(SPELL_HARPOON_TRIGGER);
break;
}
}
public override void JustDied(Unit killer)
{
_JustDied();
}
public override void DoAction(int action)
{
if (instance.GetBossState(BOSS_RAZORSCALE) != EncounterState.InProgress)
return;
switch (action)
{
case ACTION_HARPOON_BUILD:
events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000);
if (me->GetMap()->GetSpawnMode() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000);
break;
case ACTION_PLACE_BROKEN_HARPOON:
for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
me->SummonGameObject(GO_RAZOR_BROKEN_HARPOON, PosHarpoon[n].GetPositionX(), PosHarpoon[n].GetPositionY(), PosHarpoon[n].GetPositionZ(), 2.286f, 0, 0, 0, 0, 180);
break;
}
}
public override void UpdateAI(uint Diff)
{
_events.Update(Diff);
while (uint eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BUILD_HARPOON_1:
Talk(EMOTE_HARPOON);
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_1, PosHarpoon[0].GetPositionX(), PosHarpoon[0].GetPositionY(), PosHarpoon[0].GetPositionZ(), 4.790f, 0.0f, 0.0f, 0.0f, 0.0f, uint32(me->GetRespawnTime())))
{
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f)) //only nearest broken harpoon
BrokenHarpoon->RemoveFromWorld();
events.ScheduleEvent(EVENT_BUILD_HARPOON_2, 20000);
events.CancelEvent(EVENT_BUILD_HARPOON_1);
}
return;
case EVENT_BUILD_HARPOON_2:
Talk(EMOTE_HARPOON);
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_2, PosHarpoon[1].GetPositionX(), PosHarpoon[1].GetPositionY(), PosHarpoon[1].GetPositionZ(), 4.659f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
{
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
BrokenHarpoon->RemoveFromWorld();
events.CancelEvent(EVENT_BUILD_HARPOON_2);
}
return;
case EVENT_BUILD_HARPOON_3:
Talk(EMOTE_HARPOON);
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_3, PosHarpoon[2].GetPositionX(), PosHarpoon[2].GetPositionY(), PosHarpoon[2].GetPositionZ(), 5.382f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
{
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
BrokenHarpoon->RemoveFromWorld();
events.ScheduleEvent(EVENT_BUILD_HARPOON_4, 20000);
events.CancelEvent(EVENT_BUILD_HARPOON_3);
}
return;
case EVENT_BUILD_HARPOON_4:
Talk(EMOTE_HARPOON);
if (GameObject * Harpoon = me->SummonGameObject(GO_RAZOR_HARPOON_4, PosHarpoon[3].GetPositionX(), PosHarpoon[3].GetPositionY(), PosHarpoon[3].GetPositionZ(), 4.266f, 0, 0, 0, 0, uint32(me->GetRespawnTime())))
{
if (GameObject * BrokenHarpoon = Harpoon->FindNearestGameObject(GO_RAZOR_BROKEN_HARPOON, 5.0f))
BrokenHarpoon->RemoveFromWorld();
events.CancelEvent(EVENT_BUILD_HARPOON_4);
}
return;
}
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<boss_razorscale_controllerAI>(creature);
}
}*/
}
}
+409
View File
@@ -0,0 +1,409 @@
/*
* 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/>.
*/
namespace Scripts.Northrend.Ulduar
{
struct BossIds
{
public const uint MaxEncounter = 17;
public const uint Leviathan = 0;
public const uint Ignis = 1;
public const uint Razorscale = 2;
public const uint Xt002 = 3;
public const uint AssemblyOfIron = 4;
public const uint Kologarn = 5;
public const uint Auriaya = 6;
public const uint Mimiron = 7;
public const uint Hodir = 8;
public const uint Thorim = 9;
public const uint Freya = 10;
public const uint Brightleaf = 11;
public const uint Ironbranch = 12;
public const uint Stonebark = 13;
public const uint Vezax = 14;
public const uint YoggSaron = 15;
public const uint Algalon = 16;
}
struct InstanceCreatureIds
{
// General
public const uint Leviathan = 33113;
public const uint SalvagedDemolisher = 33109;
public const uint SalvagedSiegeEngine = 33060;
public const uint SalvagedChopper = 33062;
public const uint Ignis = 33118;
public const uint Razorscale = 33186;
public const uint RazorscaleController = 33233;
public const uint SteelforgedDeffender = 33236;
public const uint ExpeditionCommander = 33210;
public const uint Xt002 = 33293;
public const uint XtToyPile = 33337;
public const uint Steelbreaker = 32867;
public const uint Molgeim = 32927;
public const uint Brundir = 32857;
public const uint Kologarn = 32930;
public const uint FocusedEyebeam = 33632;
public const uint FocusedEyebeamRight = 33802;
public const uint LeftArm = 32933;
public const uint RightArm = 32934;
public const uint Rubble = 33768;
public const uint Auriaya = 33515;
public const uint Mimiron = 33350;
public const uint Hodir = 32845;
public const uint Thorim = 32865;
public const uint Freya = 32906;
public const uint Vezax = 33271;
public const uint YoggSaron = 33288;
public const uint Algalon = 32871;
//XT002
public const uint XS013Scrapbot = 33343;
// Mimiron
public const uint LeviathanMkII = 33432;
public const uint Vx001 = 33651;
public const uint AerialCommandUnit = 33670;
public const uint AssaultBot = 34057;
public const uint BombBot = 33836;
public const uint JunkBot = 33855;
public const uint EmergencyFireBot = 34147;
public const uint FrostBomb = 34149;
public const uint BurstTarget = 34211;
public const uint Flame = 34363;
public const uint FlameSpread = 34121;
public const uint DBTarget = 33576;
public const uint RocketMimironVisual = 34050;
public const uint WorldTriggerMimiron = 21252;
public const uint Computer = 34143;
// Freya'S Keepers
public const uint Ironbranch = 32913;
public const uint Brightleaf = 32915;
public const uint Stonebark = 32914;
// Hodir'S Helper Npcs
public const uint TorGreycloud = 32941;
public const uint KarGreycloud = 33333;
public const uint EiviNightfeather = 33325;
public const uint EllieNightfeather = 32901;
public const uint SpiritwalkerTara = 33332;
public const uint SpiritwalkerYona = 32950;
public const uint ElementalistMahfuun = 33328;
public const uint ElementalistAvuun = 32900;
public const uint AmiraBlazeweaver = 33331;
public const uint VeeshaBlazeweaver = 32946;
public const uint MissyFlamecuffs = 32893;
public const uint SissyFlamecuffs = 33327;
public const uint BattlePriestEliza = 32948;
public const uint BattlePriestGina = 33330;
public const uint FieldMedicPenny = 32897;
public const uint FieldMedicJessi = 33326;
// Freya'S Trash Npcs
public const uint CorruptedServitor = 33354;
public const uint MisguidedNymph = 33355;
public const uint GuardianLasher = 33430;
public const uint ForestSwarmer = 33431;
public const uint MangroveEnt = 33525;
public const uint IronrootLasher = 33526;
public const uint NaturesBlade = 33527;
public const uint GuardianOfLife = 33528;
// Freya Achievement Trigger
public const uint FreyaAchieveTrigger = 33406;
// Yogg-Saron
public const uint Sara = 33134;
public const uint GuardianOfYoggSaron = 33136;
public const uint HodirObservationRing = 33213;
public const uint FreyaObservationRing = 33241;
public const uint ThorimObservationRing = 33242;
public const uint MimironObservationRing = 33244;
public const uint VoiceOfYoggSaron = 33280;
public const uint OminousCloud = 33292;
public const uint FreyaYs = 33410;
public const uint HodirYs = 33411;
public const uint MimironYs = 33412;
public const uint ThorimYs = 33413;
public const uint SuitOfArmor = 33433;
public const uint KingLlane = 33437;
public const uint TheLichKing = 33441;
public const uint ImmolatedChampion = 33442;
public const uint Ysera = 33495;
public const uint Neltharion = 33523;
public const uint Malygos = 33535;
public const uint DeathRay = 33881;
public const uint DeathOrb = 33882;
public const uint BrainOfYoggSaron = 33890;
public const uint InfluenceTentacle = 33943;
public const uint TurnedChampion = 33962;
public const uint CrusherTentacle = 33966;
public const uint ConstrictorTentacle = 33983;
public const uint CorruptorTentacle = 33985;
public const uint ImmortalGuardian = 33988;
public const uint SanityWell = 33991;
public const uint DescendIntoMadness = 34072;
public const uint MarkedImmortalGuardian = 36064;
// Algalon The Observer
public const uint BrannBronzbeardAlg = 34064;
public const uint Azeroth = 34246;
public const uint LivingConstellation = 33052;
public const uint AlgalonStalker = 33086;
public const uint CollapsingStar = 32955;
public const uint BlackHole = 32953;
public const uint WormHole = 34099;
public const uint AlgalonVoidZoneVisualStalker = 34100;
public const uint AlgalonStalkerAsteroidTarget01 = 33104;
public const uint AlgalonStalkerAsteroidTarget02 = 33105;
public const uint UnleashedDarkMatter = 34097;
}
struct InstanceGameObjectIds
{
// Leviathan
public const uint LeviathanDoor = 194905;
public const uint LeviathanGate = 194630;
// Razorscale
public const uint MoleMachine = 194316;
public const uint RazorHarpoon1 = 194542;
public const uint RazorHarpoon2 = 194541;
public const uint RazorHarpoon3 = 194543;
public const uint RazorHarpoon4 = 194519;
public const uint RazorBrokenHarpoon = 194565;
// Xt-002
public const uint Xt002Door = 194631;
// Assembly Of Iron
public const uint IronCouncilDoor = 194554;
public const uint ArchivumDoor = 194556;
// Kologarn
public const uint KologarnChestHero = 195047;
public const uint KologarnChest = 195046;
public const uint KologarnBridge = 194232;
public const uint KologarnDoor = 194553;
// Hodir
public const uint HodirEntrance = 194442;
public const uint HodirDoor = 194634;
public const uint HodirIceDoor = 194441;
public const uint HodirRareCacheOfWinter = 194200;
public const uint HodirRareCacheOfWinterHero = 194201;
public const uint HodirChestHero = 194308;
public const uint HodirChest = 194307;
// Thorim
public const uint ThorimChestHero = 194315;
public const uint ThorimChest = 194314;
// Mimiron
public const uint MimironTram = 194675;
public const uint MimironElevator = 194749;
public const uint MimironButton = 194739;
public const uint MimironDoor1 = 194774;
public const uint MimironDoor2 = 194775;
public const uint MimironDoor3 = 194776;
public const uint CacheOfInnovation = 194789;
public const uint CacheOfInnovationFirefighter = 194957;
public const uint CacheOfInnovationHero = 194956;
public const uint CacheOfInnovationFirefighterHero = 194958;
// Vezax
public const uint VezaxDoor = 194750;
// Yogg-Saron
public const uint YoggSaronDoor = 194773;
public const uint BrainRoomDoor1 = 194635;
public const uint BrainRoomDoor2 = 194636;
public const uint BrainRoomDoor3 = 194637;
// Algalon The Observer
public const uint CelestialPlanetariumAccess10 = 194628;
public const uint CelestialPlanetariumAccess25 = 194752;
public const uint DoodadUlSigildoor01 = 194767;
public const uint DoodadUlSigildoor02 = 194911;
public const uint DoodadUlSigildoor03 = 194910;
public const uint DoodadUlUniversefloor01 = 194715;
public const uint DoodadUlUniversefloor02 = 194716;
public const uint DoodadUlUniverseglobe01 = 194148;
public const uint DoodadUlUlduarTrapdoor03 = 194253;
public const uint GiftOfTheObserver10 = 194821;
public const uint GiftOfTheObserver25 = 194822;
}
struct InstanceEventIds
{
public const int TowerOfStormDestroyed = 21031;
public const int TowerOfFrostDestroyed = 21032;
public const int TowerOfFlamesDestroyed = 21033;
public const int TowerOfLifeDestroyed = 21030;
public const int ActivateSanityWell = 21432;
public const int HodirsProtectiveGazeProc = 21437;
}
struct LeviathanActions
{
public const int TowerOfStormDestroyed = 1;
public const int TowerOfFrostDestroyed = 2;
public const int TowerOfFlamesDestroyed = 3;
public const int TowerOfLifeDestroyed = 4;
public const int MoveToCenterPosition = 10;
}
struct InstanceCriteriaIds
{
public const uint ConSpeedAtory = 21597;
public const uint Lumberjacked = 21686;
public const uint Disarmed = 21687;
public const uint WaitsDreamingStormwind25 = 10321;
public const uint WaitsDreamingChamber25 = 10322;
public const uint WaitsDreamingIcecrown25 = 10323;
public const uint WaitsDreamingStormwind10 = 10324;
public const uint WaitsDreamingChamber10 = 10325;
public const uint WaitsDreamingIcecrown10 = 10326;
public const uint DriveMeCrazy10 = 10185;
public const uint DriveMeCrazy25 = 10296;
public const uint ThreeLightsInTheDarkness10 = 10410;
public const uint ThreeLightsInTheDarkness25 = 10414;
public const uint TwoLightsInTheDarkness10 = 10388;
public const uint TwoLightsInTheDarkness25 = 10415;
public const uint OneLightInTheDarkness10 = 10409;
public const uint OneLightInTheDarkness25 = 10416;
public const uint AloneInTheDarkness10 = 10412;
public const uint AloneInTheDarkness25 = 10417;
public const uint HeraldOfTitans = 10678;
// Champion Of Ulduar
public const uint ChampionLeviathan10 = 10042;
public const uint ChampionIgnis10 = 10342;
public const uint ChampionRazorscale10 = 10340;
public const uint ChampionXt002_10 = 10341;
public const uint ChampionIronCouncil10 = 10598;
public const uint ChampionKologarn10 = 10348;
public const uint ChampionAuriaya10 = 10351;
public const uint ChampionHodir10 = 10439;
public const uint ChampionThorim10 = 10403;
public const uint ChampionFreya10 = 10582;
public const uint ChampionMimiron10 = 10347;
public const uint ChampionVezax10 = 10349;
public const uint ChampionYoggSaron10 = 10350;
// Conqueror Of Ulduar
public const uint ChampionLeviathan25 = 10352;
public const uint ChampionIgnis25 = 10355;
public const uint ChampionRazorscale25 = 10353;
public const uint ChampionXt002_25 = 10354;
public const uint ChampionIronCouncil25 = 10599;
public const uint ChampionKologarn25 = 10357;
public const uint ChampionAuriaya25 = 10363;
public const uint ChampionHodir25 = 10719;
public const uint ChampionThorim25 = 10404;
public const uint ChampionFreya25 = 10583;
public const uint ChampionMimiron25 = 10361;
public const uint ChampionVezax25 = 10362;
public const uint ChampionYoggSaron25 = 10364;
}
struct InstanceData
{
// Colossus (Leviathan)
public const uint Colossus = 20;
// Razorscale
public const uint ExpeditionCommander = 21;
public const uint RazorscaleControl = 22;
// Xt-002
public const uint ToyPile0 = 23;
public const uint ToyPile1 = 24;
public const uint ToyPile2 = 25;
public const uint ToyPile3 = 26;
// Assembly Of Iron
public const uint Steelbreaker = 27;
public const uint Molgeim = 28;
public const uint Brundir = 29;
// Hodir
public const uint HodirRareCache = 30;
// Mimiron
public const uint LeviathanMKII = 31;
public const uint VX001 = 32;
public const uint AerialCommandUnit = 33;
public const uint Computer = 34;
public const uint MimironWorldTrigger = 35;
public const uint MimironElevator = 36;
public const uint MimironTram = 37;
public const uint MimironButton = 38;
// Yogg-Saron
public const uint VoiceOfYoggSaron = 39;
public const uint Sara = 40;
public const uint BrainOfYoggSaron = 41;
public const uint FreyaYs = 42;
public const uint HodirYs = 43;
public const uint ThorimYs = 44;
public const uint MimironYs = 45;
public const uint Illusion = 46;
public const uint DriveMeCrazy = 47;
public const uint KeepersCount = 48;
// Algalon The Observer
public const uint AlgalonSummonState = 49;
public const uint Sigildoor01 = 50;
public const uint Sigildoor02 = 51;
public const uint Sigildoor03 = 52;
public const uint UniverseFloor01 = 53;
public const uint UniverseFloor02 = 54;
public const uint UniverseGlobe = 55;
public const uint AlgalonTrapdoor = 56;
public const uint BrannBronzebeardAlg = 57;
}
struct InstanceWorldStates
{
public const uint AlgalonDespawnTimer = 4131;
public const uint AlgalonTimerEnabled = 4132;
}
struct InstanceAchievementData
{
// Fl Achievement Boolean
public const uint DataUnbroken = 29052906; // 2905, 2906 Are Achievement Ids,
public const uint MaxHeraldArmorItemlevel = 226;
public const uint MaxHeraldWeaponItemlevel = 232;
}
struct InstanceEvents
{
public const uint EventDespawnAlgalon = 1;
public const uint EventUpdateAlgalonTimer = 2;
public const uint ActionInitAlgalon = 6;
}
struct YoggSaronIllusions
{
public const uint ChamberIllusion = 0;
public const uint IcecrownIllusion = 1;
public const uint StormwindIllusion = 2;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
/*
* 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 Game.Entities;
namespace Scripts.Northrend.Ulduar
{
class YoggSaron
{
public static Position[] ObservationRingKeepersPos =
{
new Position(1945.682f, 33.34201f, 411.4408f, 5.270895f), // Freya
new Position(1945.761f, -81.52171f, 411.4407f, 1.029744f), // Hodir
new Position(2028.822f, -65.73573f, 411.4426f, 2.460914f), // Thorim
new Position(2028.766f, 17.42014f, 411.4446f, 3.857178f), // Mimiron
};
public static Position[] YSKeepersPos =
{
new Position(2036.873f, 25.42513f, 338.4984f, 3.909538f), // Freya
new Position(1939.045f, -90.87457f, 338.5426f, 0.994837f), // Hodir
new Position(1939.148f, 42.49035f, 338.5427f, 5.235988f), // Thorim
new Position(2036.658f, -73.58822f, 338.4985f, 2.460914f), // Mimiron
};
}
}
@@ -0,0 +1,756 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.Scripting;
using Game.Maps;
using Game.WorldEntities;
using Framework.Util;
using Framework.Constants;
using Game.Spells;
using Game;
namespace Scripts.Northrend.VioletHold
{
class instance_violet_hold : InstanceMapScript
{
public instance_violet_hold() : base("instance_violet_hold", 608) { }
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_violet_hold_InstanceMapScript(map);
}
class instance_violet_hold_InstanceMapScript : InstanceScript
{
public instance_violet_hold_InstanceMapScript(Map map) : base(map) { }
public override void Initialize()
{
uiMoragg = 0;
uiErekem = 0;
uiIchoron = 0;
uiLavanthor = 0;
uiXevozz = 0;
uiZuramat = 0;
uiCyanigosa = 0;
uiSinclari = 0;
uiMoraggCell = 0;
uiErekemCell = 0;
uiErekemGuard[0] = 0;
uiErekemGuard[1] = 0;
uiIchoronCell = 0;
uiLavanthorCell = 0;
uiXevozzCell = 0;
uiZuramatCell = 0;
uiMainDoor = 0;
uiTeleportationPortal = 0;
uiSaboteurPortal = 0;
trashMobs.Clear();
uiRemoveNpc = 0;
uiDoorIntegrity = 100;
uiWaveCount = 0;
uiLocation = (byte)RandomHelper.URand(0, 5);
uiFirstBoss = 0;
uiSecondBoss = 0;
uiCountErekemGuards = 0;
uiCountActivationCrystals = 0;
uiCyanigosaEventPhase = 1;
uiActivationTimer = 5000;
uiDoorSpellTimer = 2000;
uiCyanigosaEventTimer = 3 * Time.InMilliseconds;
bActive = false;
bIsDoorSpellCast = false;
bCrystalActivated = false;
defenseless = true;
uiMainEventPhase = EncounterState.NotStarted;
}
public override bool IsEncounterInProgress()
{
for (byte i = 0; i < MAX_ENCOUNTER; ++i)
if ((EncounterState)m_auiEncounter[i] == EncounterState.InProgress)
return true;
return false;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case CREATURE_XEVOZZ:
uiXevozz = creature.GetGUID();
break;
case CREATURE_LAVANTHOR:
uiLavanthor = creature.GetGUID();
break;
case CREATURE_ICHORON:
uiIchoron = creature.GetGUID();
break;
case CREATURE_ZURAMAT:
uiZuramat = creature.GetGUID();
break;
case CREATURE_EREKEM:
uiErekem = creature.GetGUID();
break;
case CREATURE_EREKEM_GUARD:
if (uiCountErekemGuards < 2)
{
uiErekemGuard[uiCountErekemGuards++] = creature.GetGUID();
creature.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
}
break;
case CREATURE_MORAGG:
uiMoragg = creature.GetGUID();
break;
case CREATURE_CYANIGOSA:
uiCyanigosa = creature.GetGUID();
creature.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
break;
case CREATURE_SINCLARI:
uiSinclari = creature.GetGUID();
break;
}
if (creature.GetGUID() == uiFirstBoss || creature.GetGUID() == uiSecondBoss)
{
creature.AllLootRemovedFromCorpse();
creature.RemoveLootMode(1);
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GO_EREKEM_GUARD_1_DOOR:
uiErekemLeftGuardCell = go.GetGUID();
break;
case GO_EREKEM_GUARD_2_DOOR:
uiErekemRightGuardCell = go.GetGUID();
break;
case GO_EREKEM_DOOR:
uiErekemCell = go.GetGUID();
break;
case GO_ZURAMAT_DOOR:
uiZuramatCell = go.GetGUID();
break;
case GO_LAVANTHOR_DOOR:
uiLavanthorCell = go.GetGUID();
break;
case GO_MORAGG_DOOR:
uiMoraggCell = go.GetGUID();
break;
case GO_ICHORON_DOOR:
uiIchoronCell = go.GetGUID();
break;
case GO_XEVOZZ_DOOR:
uiXevozzCell = go.GetGUID();
break;
case GO_MAIN_DOOR:
uiMainDoor = go.GetGUID();
break;
case GO_ACTIVATION_CRYSTAL:
if (uiCountActivationCrystals < 4)
uiActivationCrystal[uiCountActivationCrystals++] = go.GetGUID();
break;
}
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case DATA_1ST_BOSS_EVENT:
UpdateEncounterState(EncounterCreditType.KillCreature, CREATURE_EREKEM, null);
m_auiEncounter[0] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
SaveToDB();
break;
case DATA_2ND_BOSS_EVENT:
UpdateEncounterState(EncounterCreditType.KillCreature, CREATURE_MORAGG, null);
m_auiEncounter[1] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
SaveToDB();
break;
case DATA_CYANIGOSA_EVENT:
m_auiEncounter[2] = (byte)data;
if ((EncounterState)data == EncounterState.Done)
{
SaveToDB();
uiMainEventPhase = EncounterState.EncounterState.Done;
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
pMainDoor.SetGoState(GameObjectState.Active);
}
break;
case DATA_WAVE_COUNT:
uiWaveCount = (byte)data;
bActive = true;
break;
case DATA_REMOVE_NPC:
uiRemoveNpc = (byte)data;
break;
case DATA_PORTAL_LOCATION:
uiLocation = (byte)data;
break;
case DATA_DOOR_INTEGRITY:
uiDoorIntegrity = (byte)data;
defenseless = false;
DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, uiDoorIntegrity);
break;
case DATA_NPC_PRESENCE_AT_DOOR_ADD:
NpcAtDoorCastingList.Add((byte)data);
break;
case DATA_NPC_PRESENCE_AT_DOOR_REMOVE:
if (!NpcAtDoorCastingList.Empty())
NpcAtDoorCastingList.RemoveAt(0);//.pop_back();
break;
case DATA_MAIN_DOOR:
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
{
switch ((GameObjectState)data)
{
case GameObjectState.Active:
case GameObjectState.Ready:
case GameObjectState.ActiveAlternative:
pMainDoor.SetGoState((GameObjectState)data);
break;
}
}
break;
case DATA_START_BOSS_ENCOUNTER:
switch (uiWaveCount)
{
case 6:
StartBossEncounter(uiFirstBoss);
break;
case 12:
StartBossEncounter(uiSecondBoss);
break;
}
break;
case DATA_ACTIVATE_CRYSTAL:
ActivateCrystal();
break;
case DATA_MAIN_EVENT_PHASE:
uiMainEventPhase = (EncounterState)data;
if ((EncounterState)data == EncounterState.InProgress) // Start event
{
if (GameObject mainDoor = instance.GetGameObject(uiMainDoor))
mainDoor.SetGoState(GameObjectState.Ready);
uiWaveCount = 1;
bActive = true;
for (int i = 0; i < 4; ++i)
{
if (GameObject crystal = instance.GetGameObject(uiActivationCrystal[i]))
crystal.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
uiRemoveNpc = 0; // might not have been reset after a wipe on a boss.
}
break;
}
}
public override void SetData64(uint type, ulong data)
{
switch (type)
{
case DATA_ADD_TRASH_MOB:
trashMobs.Add(data);
break;
case DATA_DEL_TRASH_MOB:
trashMobs.Remove(data);
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case DATA_1ST_BOSS_EVENT:
return m_auiEncounter[0];
case DATA_2ND_BOSS_EVENT:
return m_auiEncounter[1];
case DATA_CYANIGOSA_EVENT:
return m_auiEncounter[2];
case DATA_WAVE_COUNT:
return uiWaveCount;
case DATA_REMOVE_NPC:
return uiRemoveNpc;
case DATA_PORTAL_LOCATION:
return uiLocation;
case DATA_DOOR_INTEGRITY:
return uiDoorIntegrity;
case DATA_NPC_PRESENCE_AT_DOOR:
return (uint)NpcAtDoorCastingList.Count;
case DATA_FIRST_BOSS:
return uiFirstBoss;
case DATA_SECOND_BOSS:
return uiSecondBoss;
case DATA_MAIN_EVENT_PHASE:
return (uint)uiMainEventPhase;
case DATA_DEFENSELESS:
return (uint)(defenseless ? 1 : 0);
}
return 0;
}
public override ulong GetData64(uint identifier)
{
switch (identifier)
{
case DATA_MORAGG: return uiMoragg;
case DATA_EREKEM: return uiErekem;
case DATA_EREKEM_GUARD_1: return uiErekemGuard[0];
case DATA_EREKEM_GUARD_2: return uiErekemGuard[1];
case DATA_ICHORON: return uiIchoron;
case DATA_LAVANTHOR: return uiLavanthor;
case DATA_XEVOZZ: return uiXevozz;
case DATA_ZURAMAT: return uiZuramat;
case DATA_CYANIGOSA: return uiCyanigosa;
case DATA_MORAGG_CELL: return uiMoraggCell;
case DATA_EREKEM_CELL: return uiErekemCell;
case DATA_EREKEM_RIGHT_GUARD_CELL: return uiErekemRightGuardCell;
case DATA_EREKEM_LEFT_GUARD_CELL: return uiErekemLeftGuardCell;
case DATA_ICHORON_CELL: return uiIchoronCell;
case DATA_LAVANTHOR_CELL: return uiLavanthorCell;
case DATA_XEVOZZ_CELL: return uiXevozzCell;
case DATA_ZURAMAT_CELL: return uiZuramatCell;
case DATA_MAIN_DOOR: return uiMainDoor;
case DATA_SINCLARI: return uiSinclari;
case DATA_TELEPORTATION_PORTAL: return uiTeleportationPortal;
case DATA_SABOTEUR_PORTAL: return uiSaboteurPortal;
}
return 0;
}
void SpawnPortal()
{
SetData(DATA_PORTAL_LOCATION, (GetData(DATA_PORTAL_LOCATION) + RandomHelper.URand(1, 5)) % 6);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
if (Creature portal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, PortalLocation[GetData(DATA_PORTAL_LOCATION)], TempSummonType.CorpseDespawn))
uiTeleportationPortal = portal.GetGUID();
}
void StartBossEncounter(byte uiBoss, bool bForceRespawn = true)
{
Creature pBoss = null;
switch (uiBoss)
{
case BOSS_MORAGG:
HandleGameObject(uiMoraggCell, bForceRespawn);
pBoss = instance.GetCreature(uiMoragg);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove1);
break;
case BOSS_EREKEM:
HandleGameObject(uiErekemCell, bForceRespawn);
HandleGameObject(uiErekemRightGuardCell, bForceRespawn);
HandleGameObject(uiErekemLeftGuardCell, bForceRespawn);
pBoss = instance.GetCreature(uiErekem);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove2);
if (Creature pGuard1 = instance.GetCreature(uiErekemGuard[0]))
{
if (bForceRespawn)
pGuard1.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
else
pGuard1.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pGuard1.GetMotionMaster().MovePoint(0, BossStartMove21);
}
if (Creature pGuard2 = instance.GetCreature(uiErekemGuard[1]))
{
if (bForceRespawn)
pGuard2.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
else
pGuard2.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pGuard2.GetMotionMaster().MovePoint(0, BossStartMove22);
}
break;
case BOSS_ICHORON:
HandleGameObject(uiIchoronCell, bForceRespawn);
pBoss = instance.GetCreature(uiIchoron);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove3);
break;
case BOSS_LAVANTHOR:
HandleGameObject(uiLavanthorCell, bForceRespawn);
pBoss = instance.GetCreature(uiLavanthor);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove4);
break;
case BOSS_XEVOZZ:
HandleGameObject(uiXevozzCell, bForceRespawn);
pBoss = instance.GetCreature(uiXevozz);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove5);
break;
case BOSS_ZURAMAT:
HandleGameObject(uiZuramatCell, bForceRespawn);
pBoss = instance.GetCreature(uiZuramat);
if (pBoss)
pBoss.GetMotionMaster().MovePoint(0, BossStartMove6);
break;
}
// generic boss state changes
if (pBoss)
{
pBoss.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pBoss.SetReactState(ReactStates.Aggressive);
if (!bForceRespawn)
{
if (pBoss.IsDead())
{
// respawn but avoid to be looted again
pBoss.Respawn();
pBoss.RemoveLootMode(1);
}
pBoss.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
uiWaveCount = 0;
}
}
}
void AddWave()
{
DoUpdateWorldState(WORLD_STATE_VH, 1);
DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, uiWaveCount);
switch (uiWaveCount)
{
case 6:
if (uiFirstBoss == 0)
uiFirstBoss = (byte)RandomHelper.URand(1, 6);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
if (Creature pPortal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TempSummonType.CorpseDespawn))
uiSaboteurPortal = pPortal.GetGUID();
if (Creature pAzureSaboteur = pSinclari.SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TempSummonType.DeadDespawn))
pAzureSaboteur.CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
}
break;
case 12:
if (uiSecondBoss == 0)
do
{
uiSecondBoss = (byte)RandomHelper.URand(1, 6);
} while (uiSecondBoss == uiFirstBoss);
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
if (Creature pPortal = pSinclari.SummonCreature(CREATURE_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TempSummonType.CorpseDespawn))
uiSaboteurPortal = pPortal.GetGUID();
if (Creature pAzureSaboteur = pSinclari.SummonCreature(CREATURE_SABOTEOUR, MiddleRoomLocation, TempSummonType.DeadDespawn))
pAzureSaboteur.CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
}
break;
case 18:
{
Creature pSinclari = instance.GetCreature(uiSinclari);
if (pSinclari)
pSinclari.SummonCreature(CREATURE_CYANIGOSA, CyanigosasSpawnLocation, TempSummonType.DeadDespawn);
break;
}
case 1:
{
if (GameObject pMainDoor = instance.GetGameObject(uiMainDoor))
pMainDoor.SetGoState(GameObjectState.Ready);
DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, 100);
// no break
}
goto default;
default:
SpawnPortal();
break;
}
}
public override string GetSaveData()
{
OUT_SAVE_INST_DATA();
str_data = string.Format("V H {0} {1} {2} {3} {4}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], uiFirstBoss, uiSecondBoss);
OUT_SAVE_INST_DATA_COMPLETE();
return str_data;
}
public override void Load(string str)
{
if (!string.IsNullOrEmpty(str))
{
OUT_LOAD_INST_DATA_FAIL();
return;
}
OUT_LOAD_INST_DATA(str);
StringArguments args = new StringArguments(str);
char dataHead1 = args.NextChar();
char dataHead2 = args.NextChar();
ushort data0 = args.NextUInt16();
ushort data1 = args.NextUInt16();
ushort data2 = args.NextUInt16();
ushort data3 = args.NextUInt16();
ushort data4 = args.NextUInt16();
if (dataHead1 == 'V' && dataHead2 == 'H')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
for (byte i = 0; i < MAX_ENCOUNTER; ++i)
if ((EncounterState)m_auiEncounter[i] == EncounterState.InProgress)
m_auiEncounter[i] = (ushort)EncounterState.NotStarted;
uiFirstBoss = (byte)data3;
uiSecondBoss = (byte)data4;
}
else
OUT_LOAD_INST_DATA_FAIL();
OUT_LOAD_INST_DATA_COMPLETE();
}
bool CheckWipe()
{
var players = instance.GetPlayers();
foreach (var player in players)
{
if (player.IsGameMaster())
continue;
if (player.IsAlive())
return false;
}
return true;
}
public override void Update(uint diff)
{
if (!instance.HavePlayers())
return;
// portals should spawn if other portal is dead and doors are closed
if (bActive && uiMainEventPhase == EncounterState.InProgress)
{
if (uiActivationTimer < diff)
{
AddWave();
bActive = false;
// 1 minute waiting time after each boss fight
uiActivationTimer = (uint)((uiWaveCount == 6 || uiWaveCount == 12) ? 60000 : 5000);
} else uiActivationTimer -= diff;
}
// if main event is in progress and players have wiped then reset instance
if (uiMainEventPhase == EncounterState.InProgress && CheckWipe())
{
SetData(DATA_REMOVE_NPC, 1);
StartBossEncounter(uiFirstBoss, false);
StartBossEncounter(uiSecondBoss, false);
SetData(DATA_MAIN_DOOR, GameObjectState.Active);
SetData(DATA_WAVE_COUNT, 0);
uiMainEventPhase = EncounterState.NotStarted;
for (int i = 0; i < 4; ++i)
{
if (GameObject crystal = instance.GetGameObject(uiActivationCrystal[i]))
crystal.SetFlag(GameObjectFields.Flags, GameObjectFlags.NotSelectable);
}
if (Creature pSinclari = instance.GetCreature(uiSinclari))
{
pSinclari.SetVisible(true);
List<Creature> GuardList = new List<Creature>();
pSinclari.GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
if (!GuardList.Empty())
{
foreach (var pGuard in GuardList)
{
pGuard.SetVisible(true);
pGuard.SetReactState(ReactStates.Aggressive);
pGuard.GetMotionMaster().MovePoint(1, pGuard.GetHomePosition());
}
}
pSinclari.GetMotionMaster().MovePoint(1, pSinclari.GetHomePosition());
pSinclari.RemoveFlag(UnitFields.Flags, UnitFlags.NotSelectable);
}
}
// Cyanigosa is spawned but not tranformed, prefight event
Creature pCyanigosa = instance.GetCreature(uiCyanigosa);
if (pCyanigosa && !pCyanigosa.HasAura(CYANIGOSA_SPELL_TRANSFORM))
{
if (uiCyanigosaEventTimer <= diff)
{
switch (uiCyanigosaEventPhase)
{
case 1:
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
pCyanigosa.GetAI().Talk(CYANIGOSA_SAY_SPAWN);
uiCyanigosaEventTimer = 7 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 2:
pCyanigosa.GetMotionMaster().MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f);
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_BLUE_AURA, false);
uiCyanigosaEventTimer = 7 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 3:
pCyanigosa.RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA);
pCyanigosa.CastSpell(pCyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0);
pCyanigosa.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
pCyanigosa.SetReactState(ReactStates.Aggressive);
uiCyanigosaEventTimer = 2 * Time.InMilliseconds;
++uiCyanigosaEventPhase;
break;
case 4:
uiCyanigosaEventPhase = 0;
break;
}
} else uiCyanigosaEventTimer -= diff;
}
// if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active
if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == EncounterState.InProgress)
{
// if door integrity is > 0 then decrase it's integrity state
if (GetData(DATA_DOOR_INTEGRITY))
{
if (uiDoorSpellTimer < diff)
{
SetData(DATA_DOOR_INTEGRITY, GetData(DATA_DOOR_INTEGRITY) - 1);
uiDoorSpellTimer = 2000;
} else uiDoorSpellTimer -= diff;
}
// else set door state to active (means door will open and group have failed to sustain mob invasion on the door)
else
{
SetData(DATA_MAIN_DOOR, GameObjectState.Active);
uiMainEventPhase = EncounterState.Fail;
}
}
}
void ActivateCrystal()
{
// just to make things easier we'll get the gameobject from the map
GameObject invoker = instance.GetGameObject(uiActivationCrystal[0]);
if (!invoker)
return;
SpellInfo spellInfoLightning = Global.SpellMgr.GetSpellInfo(SPELL_ARCANE_LIGHTNING);
if (spellInfoLightning == null)
return;
// the orb
TempSummon trigger = invoker.SummonCreature(NPC_DEFENSE_SYSTEM, ArcaneSphere, TempSummonType.ManualDespawn, 0);
if (!trigger)
return;
// visuals
trigger.CastSpell(trigger, spellInfoLightning, true, 0, 0, trigger.GetGUID());
// Kill all mobs registered with SetData64(ADD_TRASH_MOB)
foreach (var guid in trashMobs)
{
Creature creature = instance.GetCreature(guid);
if (creature && creature.IsAlive())
trigger.Kill(creature);
}
}
public override void ProcessEvent(WorldObject go, uint uiEventId)
{
switch (uiEventId)
{
case EVENT_ACTIVATE_CRYSTAL:
bCrystalActivated = true; // Activation by player's will throw event signal
ActivateCrystal();
break;
}
}
#region Fields
ulong uiMoragg;
ulong uiErekem;
ulong[] uiErekemGuard = new ulong[2];
ulong uiIchoron;
ulong uiLavanthor;
ulong uiXevozz;
ulong uiZuramat;
ulong uiCyanigosa;
ulong uiSinclari;
ulong uiMoraggCell;
ulong uiErekemCell;
ulong uiErekemLeftGuardCell;
ulong uiErekemRightGuardCell;
ulong uiIchoronCell;
ulong uiLavanthorCell;
ulong uiXevozzCell;
ulong uiZuramatCell;
ulong uiMainDoor;
ulong uiTeleportationPortal;
ulong uiSaboteurPortal;
ulong[] uiActivationCrystal = new ulong[4];
uint uiActivationTimer;
uint uiCyanigosaEventTimer;
uint uiDoorSpellTimer;
List<ulong> trashMobs = new List<ulong>(); // to kill with crystal
byte uiWaveCount;
byte uiLocation;
byte uiFirstBoss;
byte uiSecondBoss;
byte uiRemoveNpc;
byte uiDoorIntegrity;
ushort[] m_auiEncounter = new ushort[MAX_ENCOUNTER];
byte uiCountErekemGuards;
byte uiCountActivationCrystals;
byte uiCyanigosaEventPhase;
EncounterState uiMainEventPhase; // SPECIAL: pre event animations, InProgress: event itself
bool bActive;
bool bWiped;
bool bIsDoorSpellCast;
bool bCrystalActivated;
bool defenseless;
List<byte> NpcAtDoorCastingList = new List<byte>();
string str_data;
#endregion
}
}
}
@@ -0,0 +1,21 @@
/*
* 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/>.
*/
namespace Scripts.Northrend.VioletHold
{
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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.BattleFields;
using Game.Conditions;
using Game.Entities;
using Game.Scripting;
namespace Scripts.Northrend
{
[Script]
class spell_wintergrasp_defender_teleport : SpellScriptLoader
{
public spell_wintergrasp_defender_teleport() : base("spell_wintergrasp_defender_teleport") { }
class spell_wintergrasp_defender_teleport_SpellScript : SpellScript
{
SpellCastResult CheckCast()
{
BattleField wg = Global.BattleFieldMgr.GetBattlefieldByBattleId(1);
if (wg != null)
{
Player target = GetExplTargetUnit().ToPlayer();
if (target)
// check if we are in Wintergrasp at all, SotA uses same teleport spells
if ((target.GetZoneId() == 4197 && target.GetTeamId() != wg.GetDefenderTeam()) || target.HasAura(54643))
return SpellCastResult.BadTargets;
}
return SpellCastResult.SpellCastOk;
}
public override void Register()
{
OnCheckCast.Add(new CheckCastHandler(CheckCast));
}
}
public override SpellScript GetSpellScript()
{
return new spell_wintergrasp_defender_teleport_SpellScript();
}
}
[Script]
class spell_wintergrasp_defender_teleport_trigger : SpellScriptLoader
{
public spell_wintergrasp_defender_teleport_trigger() : base("spell_wintergrasp_defender_teleport_trigger") { }
class spell_wintergrasp_defender_teleport_trigger_SpellScript : SpellScript
{
void HandleDummy(uint effindex)
{
Unit target = GetHitUnit();
if (target)
{
WorldLocation loc = target.GetWorldLocation();
SetExplTargetDest(loc);
}
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
}
}
public override SpellScript GetSpellScript()
{
return new spell_wintergrasp_defender_teleport_trigger_SpellScript();
}
}
[Script]
class condition_is_wintergrasp_horde : ConditionScript
{
public condition_is_wintergrasp_horde() : base("condition_is_wintergrasp_horde") { }
public override bool OnConditionCheck(Condition condition, ConditionSourceInfo sourceInfo)
{
BattleField wintergrasp = Global.BattleFieldMgr.GetBattlefieldByBattleId(BattlefieldIds.WG);
if (wintergrasp.IsEnabled() && wintergrasp.GetDefenderTeam() == TeamId.Horde)
return true;
return false;
}
}
[Script]
class condition_is_wintergrasp_alliance : ConditionScript
{
public condition_is_wintergrasp_alliance() : base("condition_is_wintergrasp_alliance") { }
public override bool OnConditionCheck(Condition condition, ConditionSourceInfo sourceInfo)
{
BattleField wintergrasp = Global.BattleFieldMgr.GetBattlefieldByBattleId(BattlefieldIds.WG);
if (wintergrasp.IsEnabled() && wintergrasp.GetDefenderTeam() == TeamId.Alliance)
return true;
return false;
}
}
}