Removed all instance scripts so we can have script project back and spells will work again.

This commit is contained in:
hondacrx
2020-12-07 15:29:06 -05:00
parent a702e070f3
commit 900362a7d7
104 changed files with 2273 additions and 41604 deletions
@@ -1,204 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Scripts.EasternKingdoms.Deadmines
{
/*class instance_deadmines : InstanceMapScript
{
public instance_deadmines() : base("instance_deadmines", 36)
{
}
class instance_deadmines_InstanceMapScript : InstanceScript
{
public instance_deadmines_InstanceMapScript(Map map) : base(map)
{
SetHeaders(DataHeader);
State = CANNON_NOT_USED;
CannonBlast_Timer = 0;
PiratesDelay_Timer = 0;
}
public override void Initialize()
{
}
public override void Update(uint diff)
{
if (IronCladDoorGUID.IsEmpty() || DefiasCannonGUID.IsEmpty() || DoorLeverGUID.IsEmpty())
return;
GameObject pIronCladDoor = instance.GetGameObject(IronCladDoorGUID);
if (!pIronCladDoor)
return;
switch (State)
{
case CANNON_GUNPOWDER_USED:
CannonBlast_Timer = DATA_CANNON_BLAST_TIMER;
// it's a hack - Mr. Smite should do that but his too far away
//pIronCladDoor.SetName("Mr. Smite");
//pIronCladDoor.MonsterYell(SAY_MR_SMITE_ALARM1, LANG_UNIVERSAL, NULL);
pIronCladDoor.PlayDirectSound(SOUND_MR_SMITE_ALARM1);
State = CANNON_BLAST_INITIATED;
break;
case CANNON_BLAST_INITIATED:
PiratesDelay_Timer = DATA_PIRATES_DELAY_TIMER;
if (CannonBlast_Timer <= diff)
{
SummonCreatures();
GameObject pDefiasCannon = instance.GetGameObject(DefiasCannonGUID);
if (pDefiasCannon)
{
pDefiasCannon.SetGoState(GO_STATE_ACTIVE);
pDefiasCannon.PlayDirectSound(SOUND_CANNONFIRE);
}
pIronCladDoor.SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
pIronCladDoor.PlayDirectSound(SOUND_DESTROYDOOR);
GameObject pDoorLever = instance.GetGameObject(DoorLeverGUID);
if (pDoorLever)
pDoorLever.SetUInt32Value(GAMEOBJECT_FLAGS, 4);
//pIronCladDoor.MonsterYell(SAY_MR_SMITE_ALARM2, LANG_UNIVERSAL, NULL);
pIronCladDoor.PlayDirectSound(SOUND_MR_SMITE_ALARM2);
State = PIRATES_ATTACK;
}
else CannonBlast_Timer -= diff;
break;
case PIRATES_ATTACK:
if (PiratesDelay_Timer <= diff)
{
MoveCreaturesInside();
State = EVENT_DONE;
}
else PiratesDelay_Timer -= diff;
break;
}
}
void SummonCreatures()
{
GameObject pIronCladDoor = instance.GetGameObject(IronCladDoorGUID);
if (pIronCladDoor)
{
Creature DefiasPirate1 = pIronCladDoor.SummonCreature(657, pIronCladDoor.GetPositionX() - 2, pIronCladDoor.GetPositionY() - 7, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
Creature DefiasPirate2 = pIronCladDoor.SummonCreature(657, pIronCladDoor.GetPositionX() + 3, pIronCladDoor.GetPositionY() - 6, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
Creature DefiasCompanion = pIronCladDoor.SummonCreature(3450, pIronCladDoor.GetPositionX() + 2, pIronCladDoor.GetPositionY() - 6, pIronCladDoor.GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
DefiasPirate1GUID = DefiasPirate1.GetGUID();
DefiasPirate2GUID = DefiasPirate2.GetGUID();
DefiasCompanionGUID = DefiasCompanion.GetGUID();
}
}
void MoveCreaturesInside()
{
if (DefiasPirate1GUID.IsEmpty() || DefiasPirate2GUID.IsEmpty() || DefiasCompanionGUID.IsEmpty())
return;
Creature pDefiasPirate1 = instance.GetCreature(DefiasPirate1GUID);
Creature pDefiasPirate2 = instance.GetCreature(DefiasPirate2GUID);
Creature pDefiasCompanion = instance.GetCreature(DefiasCompanionGUID);
if (!pDefiasPirate1 || !pDefiasPirate2 || !pDefiasCompanion)
return;
MoveCreatureInside(pDefiasPirate1);
MoveCreatureInside(pDefiasPirate2);
MoveCreatureInside(pDefiasCompanion);
}
void MoveCreatureInside(Creature creature)
{
creature.SetWalk(false);
creature.GetMotionMaster().MovePoint(0, -102.7f, -655.9f, creature.GetPositionZ());
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GO_FACTORY_DOOR: FactoryDoorGUID = go.GetGUID(); break;
case GO_IRONCLAD_DOOR: IronCladDoorGUID = go.GetGUID(); break;
case GO_DEFIAS_CANNON: DefiasCannonGUID = go.GetGUID(); break;
case GO_DOOR_LEVER: DoorLeverGUID = go.GetGUID(); break;
case GO_MR_SMITE_CHEST: uiSmiteChestGUID = go.GetGUID(); break;
}
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case EVENT_STATE:
if (!DefiasCannonGUID.IsEmpty() && !IronCladDoorGUID.IsEmpty())
State = data;
break;
case EVENT_RHAHKZOR:
if (data == DONE)
{
GameObject go = instance.GetGameObject(FactoryDoorGUID);
if (go)
go.SetGoState(GO_STATE_ACTIVE);
}
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case EVENT_STATE:
return State;
}
return 0;
}
public override ObjectGuid GetGuidData(uint data)
{
switch (data)
{
case DATA_SMITE_CHEST:
return uiSmiteChestGUID;
}
return ObjectGuid::Empty;
}
ObjectGuid FactoryDoorGUID;
ObjectGuid IronCladDoorGUID;
ObjectGuid DefiasCannonGUID;
ObjectGuid DoorLeverGUID;
ObjectGuid DefiasPirate1GUID;
ObjectGuid DefiasPirate2GUID;
ObjectGuid DefiasCompanionGUID;
uint State;
uint CannonBlast_Timer;
uint PiratesDelay_Timer;
ObjectGuid uiSmiteChestGUID;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_deadmines_InstanceMapScript(map);
}
}*/
}
@@ -1,373 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.EasternKingdoms.Karazhan.Midnight
{
struct Misc
{
public const uint MountedDisplayid = 16040;
//Attumen (@Todo Use The Summoning Spell Instead Of Creature Id. It Works; But Is Not Convenient For Us)
public const uint SummonAttumen = 15550;
}
struct TextIds
{
public const uint SayKill = 0;
public const uint SayRandom = 1;
public const uint SayDisarmed = 2;
public const uint SayMidnightKill = 3;
public const uint SayAppear = 4;
public const uint SayMount = 5;
public const uint SayDeath = 3;
// Midnight
public const uint EmoteCallAttumen = 0;
public const uint EmoteMountUp = 1;
}
struct SpellIds
{
public const uint Shadowcleave = 29832;
public const uint IntangiblePresence = 29833;
public const uint SpawnSmoke = 10389;
public const uint Charge = 29847;
// Midnight
public const uint Knockdown = 29711;
public const uint SummonAttumen = 29714;
public const uint Mount = 29770;
public const uint SummonAttumenMounted = 29799;
}
enum Phases
{
None,
AttumenEngages,
Mounted
}
[Script]
public class boss_attumen : BossAI
{
public boss_attumen(Creature creature) : base(creature, DataTypes.Attumen)
{
Initialize();
}
void Initialize()
{
_midnightGUID.Clear();
_phase = Phases.None;
}
public override void Reset()
{
Initialize();
base.Reset();
}
public override void EnterEvadeMode(EvadeReason why)
{
Creature midnight = ObjectAccessor.GetCreature(me, _midnightGUID);
if (midnight != null)
_DespawnAtEvade(10, midnight);
me.DespawnOrUnsummon();
}
public override void ScheduleTasks()
{
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25), task =>
{
DoCastVictim(SpellIds.Shadowcleave);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(45), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target != null)
DoCast(target, SpellIds.IntangiblePresence);
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(45));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(60), task =>
{
Talk(TextIds.SayRandom);
task.Repeat(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(60));
});
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
// Attumen does not die until he mounts Midnight, let health fall to 1 and prevent further damage.
if (damage >= me.GetHealth() && _phase != Phases.Mounted)
damage = (uint)(me.GetHealth() - 1);
if (_phase == Phases.AttumenEngages && me.HealthBelowPctDamaged(25, damage))
{
_phase = Phases.None;
Creature midnight = ObjectAccessor.GetCreature(me, _midnightGUID);
if (midnight != null)
midnight.GetAI().DoCastAOE(SpellIds.Mount, true);
}
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayKill);
}
public override void JustSummoned(Creature summon)
{
if (summon.GetEntry() == CreatureIds.AttumenMounted)
{
Creature midnight = ObjectAccessor.GetCreature(me, _midnightGUID);
if (midnight != null)
{
if (midnight.GetHealth() > me.GetHealth())
summon.SetHealth(midnight.GetHealth());
else
summon.SetHealth(me.GetHealth());
summon.GetAI().DoZoneInCombat();
summon.GetAI().SetGUID(_midnightGUID, (int)CreatureIds.Midnight);
}
}
base.JustSummoned(summon);
}
public override void IsSummonedBy(Unit summoner)
{
if (summoner.GetEntry() == CreatureIds.Midnight)
_phase = Phases.AttumenEngages;
if (summoner.GetEntry() == CreatureIds.AttumenUnmounted)
{
_phase = Phases.Mounted;
DoCastSelf(SpellIds.SpawnSmoke);
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25), task =>
{
Unit target = null;
var t_list = me.GetThreatManager().GetThreatList();
List<Unit> target_list = new List<Unit>();
foreach (var itr in t_list)
{
target = Global.ObjAccessor.GetUnit(me, itr.GetUnitGuid());
if (target && !target.IsWithinDist(me, 8.00f, false) && target.IsWithinDist(me, 25.0f, false))
target_list.Add(target);
target = null;
}
if (!target_list.Empty())
target = target_list.SelectRandom();
DoCast(target, SpellIds.Charge);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), task =>
{
DoCastVictim(SpellIds.Knockdown);
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
});
}
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
Unit midnight = Global.ObjAccessor.GetUnit(me, _midnightGUID);
if (midnight)
midnight.KillSelf();
base.JustDied(killer);
}
public override void SetGUID(ObjectGuid guid, int id = 0)
{
if (id == CreatureIds.Midnight)
_midnightGUID = guid;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() && _phase != Phases.None)
return;
_scheduler.Update(diff, DoMeleeAttackIfReady);
}
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Mechanic == Mechanics.Disarm)
Talk(TextIds.SayDisarmed);
if (spell.Id == SpellIds.Mount)
{
Creature midnight = ObjectAccessor.GetCreature(me, _midnightGUID);
if (midnight != null)
{
_phase = Phases.None;
_scheduler.CancelAll();
midnight.AttackStop();
midnight.RemoveAllAttackers();
midnight.SetReactState(ReactStates.Passive);
midnight.GetMotionMaster().MoveChase(me);
midnight.GetAI().Talk(TextIds.EmoteMountUp);
me.AttackStop();
me.RemoveAllAttackers();
me.SetReactState(ReactStates.Passive);
me.GetMotionMaster().MoveChase(midnight);
Talk(TextIds.SayMount);
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
{
Creature midnight1 = ObjectAccessor.GetCreature(me, _midnightGUID);
if (midnight1 != null)
{
if (me.IsWithinMeleeRange(midnight1))
{
DoCastAOE(SpellIds.SummonAttumenMounted);
me.SetVisible(false);
midnight1.SetVisible(false);
}
else
{
midnight1.GetMotionMaster().MoveChase(me);
me.GetMotionMaster().MoveChase(midnight1);
task.Repeat(TimeSpan.FromSeconds(3));
}
}
});
}
}
}
ObjectGuid _midnightGUID;
Phases _phase;
}
[Script]
public class boss_midnight : BossAI
{
public boss_midnight(Creature creature) : base(creature, DataTypes.Attumen)
{
Initialize();
}
void Initialize()
{
_phase = Phases.None;
}
public override void Reset()
{
Initialize();
base.Reset();
me.SetVisible(true);
me.SetReactState(ReactStates.Defensive);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
// Midnight never dies, let health fall to 1 and prevent further damage.
if (damage >= me.GetHealth())
damage = (uint)(me.GetHealth() - 1);
if (_phase == Phases.None && me.HealthBelowPctDamaged(95, damage))
{
_phase = Phases.AttumenEngages;
Talk(TextIds.EmoteCallAttumen);
DoCastAOE(SpellIds.SummonAttumen);
}
else if (_phase == Phases.AttumenEngages && me.HealthBelowPctDamaged(25, damage))
{
_phase = Phases.Mounted;
DoCastAOE(SpellIds.Mount, true);
}
}
public override void JustSummoned(Creature summon)
{
if (summon.GetEntry() == CreatureIds.AttumenUnmounted)
{
_attumenGUID = summon.GetGUID();
summon.GetAI().SetGUID(me.GetGUID(), (int)CreatureIds.Midnight);
summon.GetAI().AttackStart(me.GetVictim());
summon.GetAI().Talk(TextIds.SayAppear);
}
base.JustSummoned(summon);
}
public override void EnterCombat(Unit who)
{
base.EnterCombat(who);
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25), task =>
{
DoCastVictim(SpellIds.Knockdown);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25));
});
}
public override void EnterEvadeMode(EvadeReason why = EvadeReason.Other)
{
base._DespawnAtEvade(10);
}
public override void KilledUnit(Unit victim)
{
if (_phase == Phases.AttumenEngages)
{
Unit unit = Global.ObjAccessor.GetUnit(me, _attumenGUID);
if (unit != null)
Talk(TextIds.SayMidnightKill, unit);
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || _phase == Phases.Mounted)
return;
_scheduler.Update(diff, DoMeleeAttackIfReady);
}
ObjectGuid _attumenGUID;
Phases _phase;
}
}
@@ -1,169 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.EasternKingdoms.Karazhan.Curator
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySummon = 1;
public const uint SayEvocate = 2;
public const uint SayEnrage = 3;
public const uint SayKill = 4;
public const uint SayDeath = 5;
}
struct SpellIds
{
public const uint HatefulBolt = 30383;
public const uint Evocation = 30254;
public const uint ArcaneInfusion = 30403;
public const uint Berserk = 26662;
public const uint SummonAstralFlareNE = 30236;
public const uint SummonAstralFlareNW = 30239;
public const uint SummonAstralFlareSE = 30240;
public const uint SummonAstralFlareSW = 30241;
}
struct EventIds
{
public const uint HatefulBolt = 1;
public const uint SummonAstralFlare = 2;
public const uint ArcaneInfusion = 3;
public const uint Berserk = 4;
}
[Script]
class boss_curator : BossAI
{
public boss_curator(Creature creature) : base(creature, DataTypes.Curator) { }
public override void Reset()
{
_Reset();
_infused = false;
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Arcane, true);
}
public override void KilledUnit(Unit victim)
{
if (victim.GetTypeId() == TypeId.Player)
Talk(TextIds.SayKill);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void EnterCombat(Unit victim)
{
_EnterCombat();
Talk(TextIds.SayAggro);
_events.ScheduleEvent(EventIds.HatefulBolt, TimeSpan.FromSeconds(12));
_events.ScheduleEvent(EventIds.SummonAstralFlare, TimeSpan.FromSeconds(10));
_events.ScheduleEvent(EventIds.Berserk, TimeSpan.FromMinutes(12));
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(15) && !_infused)
{
_infused = true;
_events.ScheduleEvent(EventIds.ArcaneInfusion, TimeSpan.FromMilliseconds(1));
_events.CancelEvent(EventIds.SummonAstralFlare);
}
}
public override void ExecuteEvent(uint eventId)
{
switch (eventId)
{
case EventIds.HatefulBolt:
Unit target = SelectTarget(SelectAggroTarget.MaxThreat, 1);
if (target != null)
DoCast(target, SpellIds.HatefulBolt);
_events.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(15));
break;
case EventIds.ArcaneInfusion:
DoCastSelf(SpellIds.ArcaneInfusion, true);
break;
case EventIds.SummonAstralFlare:
if (RandomHelper.randChance(50))
Talk(TextIds.SaySummon);
DoCastSelf(RandomHelper.RAND(SpellIds.SummonAstralFlareNE, SpellIds.SummonAstralFlareNW, SpellIds.SummonAstralFlareSE, SpellIds.SummonAstralFlareSW), true);
int mana = me.GetMaxPower(PowerType.Mana) / 10;
if (mana != 0)
{
me.ModifyPower(PowerType.Mana, -mana);
if (me.GetPower(PowerType.Mana) * 100 / me.GetMaxPower(PowerType.Mana) < 10)
{
Talk(TextIds.SayEvocate);
me.InterruptNonMeleeSpells(false);
DoCastSelf(SpellIds.Evocation);
}
}
_events.Repeat(TimeSpan.FromSeconds(10));
break;
case EventIds.Berserk:
Talk(TextIds.SayEnrage);
DoCastSelf(SpellIds.Berserk, true);
break;
default:
break;
}
}
bool _infused;
}
[Script]
class npc_curator_astral_flareAI : ScriptedAI
{
public npc_curator_astral_flareAI(Creature creature) : base(creature)
{
me.SetReactState(ReactStates.Passive);
}
public override void Reset()
{
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
{
me.SetReactState(ReactStates.Aggressive);
me.RemoveUnitFlag(UnitFlags.NotSelectable);
DoZoneInCombat();
});
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
}
}
@@ -1,477 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.EasternKingdoms.Karazhan
{
struct karazhanConst
{
public const uint MaxEncounter = 12;
public static Dialogue[] OzDialogue =
{
new Dialogue(0, 6000),
new Dialogue(1, 18000),
new Dialogue(2, 9000),
new Dialogue(3, 15000)
};
public static Dialogue[] HoodDialogue =
{
new Dialogue(4, 6000),
new Dialogue(5, 10000),
new Dialogue(6, 14000),
new Dialogue(7, 15000)
};
public static Dialogue[] RAJDialogue =
{
new Dialogue(8, 5000),
new Dialogue(9, 7000),
new Dialogue(10, 14000),
new Dialogue(11, 14000)
};
// Entries and spawn locations for creatures in Oz event
public static float[][] Spawns =
{
new float[] { 17535, -10896}, // Dorothee
new float[] { 17546, -10891}, // Roar
new float[] { 17547, -10884}, // Tinhead
new float[] { 17543, -10902}, // Strawman
new float[] { 17603, -10892}, // Grandmother
new float[] { 17534, -10900}, // Julianne
};
public static float SPAWN_Z = 90.5f;
public static float SPAWN_Y = -1758f;
public static float SPAWN_O = 4.738f;
public static string SAY_READY = "Splendid, I'm going to get the audience ready. Break a leg!";
public static string SAY_OZ_INTRO1 = "Finally, everything is in place. Are you ready for your big stage debut?";
public static string OZ_GOSSIP1 = "I'm not an actor.";
public static string SAY_OZ_INTRO2 = "Don't worry, you'll be fine. You look like a natural!";
public static string OZ_GOSSIP2 = "Ok, I'll give it a try, then.";
public static string SAY_RAJ_INTRO1 = "The romantic plays are really tough, but you'll do better this time. You have TALENT. Ready?";
public static string RAJ_GOSSIP1 = "I've never been more ready.";
public static string OZ_GM_GOSSIP1 = "[GM] Change event to EVENT_OZ";
public static string OZ_GM_GOSSIP2 = "[GM] Change event to EVENT_HOOD";
public static string OZ_GM_GOSSIP3 = "[GM] Change event to EVENT_RAJ";
// Barnes
public const uint SpellSpotlight = 25824;
public const uint SpellTuxedo = 32616;
// Berthold
public const uint SpellTeleport = 39567;
// Image of Medivh
public const uint SpellFireBall = 30967;
public const uint SpellUberFireball = 30971;
public const uint SpellConflagrationBlast = 30977;
public const uint SpellManaShield = 31635;
public const uint NpcArcanagos = 17652;
public const uint NpcSpotlight = 19525;
public static Position[] OptionalSpawn =
{
new Position(-10960.981445f, -1940.138428f, 46.178097f, 4.12f), // Hyakiss the Lurker
new Position(-10945.769531f, -2040.153320f, 49.474438f, 0.077f), // Shadikith the Glider
new Position(-10899.903320f, -2085.573730f, 49.474449f, 1.38f) // Rokad the Ravager
};
public const uint OptionalBossRequiredDeathCount = 50;
}
struct Dialogue
{
public Dialogue(int textid, uint timer)
{
TextId = textid;
Timer = timer;
}
public int TextId;
public uint Timer;
}
struct DataTypes
{
public const uint Attumen = 1;
public const uint Moroes = 2;
public const uint MaidenOfVirtue = 3;
public const uint OptionalBoss = 4;
public const uint OperaPerformance = 5;
public const uint Curator = 6;
public const uint Aran = 7;
public const uint Terestian = 8;
public const uint Netherspite = 9;
public const uint Chess = 10;
public const uint Malchezzar = 11;
public const uint Nightbane = 12;
public const uint OperaOzDeathcount = 14;
public const uint Kilrek = 15;
public const uint GoCurtains = 18;
public const uint GoStagedoorleft = 19;
public const uint GoStagedoorright = 20;
public const uint GoLibraryDoor = 21;
public const uint GoMassiveDoor = 22;
public const uint GoNetherDoor = 23;
public const uint GoGameDoor = 24;
public const uint GoGameExitDoor = 25;
public const uint ImageOfMedivh = 26;
public const uint MastersTerraceDoor1 = 27;
public const uint MastersTerraceDoor2 = 28;
public const uint GoSideEntranceDoor = 29;
public const uint GoBlackenedUrn = 30;
}
struct OperaEvents
{
public const uint Oz = 1;
public const uint Hood = 2;
public const uint RAJ = 3;
}
struct CreatureIds
{
public const uint HyakissTheLurker = 16179;
public const uint RokadTheRavager = 16181;
public const uint ShadikithTheGlider = 16180;
public const uint TerestianIllhoof = 15688;
public const uint Moroes = 15687;
public const uint Nightbane = 17225;
public const uint AttumenUnmounted = 15550;
public const uint AttumenMounted = 16152;
public const uint Midnight = 16151;
// Trash
public const uint ColdmistWidow = 16171;
public const uint ColdmistStalker = 16170;
public const uint Shadowbat = 16173;
public const uint VampiricShadowbat = 16175;
public const uint GreaterShadowbat = 16174;
public const uint PhaseHound = 16178;
public const uint Dreadbeast = 16177;
public const uint Shadowbeast = 16176;
public const uint Kilrek = 17229;
}
struct GameObjectIds
{
public const uint StageCurtain = 183932;
public const uint StageDoorLeft = 184278;
public const uint StageDoorRight = 184279;
public const uint PrivateLibraryDoor = 184517;
public const uint MassiveDoor = 185521;
public const uint GamesmanHallDoor = 184276;
public const uint GamesmanHallExitDoor = 184277;
public const uint NetherspaceDoor = 185134;
public const uint MastersTerraceDoor = 184274;
public const uint MastersTerraceDoor2 = 184280;
public const uint SideEntranceDoor = 184275;
public const uint DustCoveredChest = 185119;
public const uint BlackenedUrn = 194092;
}
[Script]
public class instance_karazhan : InstanceMapScript
{
public instance_karazhan() : base("instance_karazhan", 532) { }
public class instance_karazhan_InstanceMapScript : InstanceScript
{
public instance_karazhan_InstanceMapScript(InstanceMap map) : base(map)
{
SetHeaders("KZ");
SetBossNumber(karazhanConst.MaxEncounter);
// 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered.
OperaEvent = RandomHelper.URand(1, 3);
OzDeathCount = 0;
OptionalBossCount = 0;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case CreatureIds.Kilrek:
KilrekGUID = creature.GetGUID();
break;
case CreatureIds.TerestianIllhoof:
TerestianGUID = creature.GetGUID();
break;
case CreatureIds.Moroes:
MoroesGUID = creature.GetGUID();
break;
case CreatureIds.Nightbane:
NightbaneGUID = creature.GetGUID();
break;
}
}
public override void OnUnitDeath(Unit unit)
{
Creature creature = unit.ToCreature();
if (creature == null)
return;
switch (creature.GetEntry())
{
case CreatureIds.ColdmistWidow:
case CreatureIds.ColdmistStalker:
case CreatureIds.Shadowbat:
case CreatureIds.VampiricShadowbat:
case CreatureIds.GreaterShadowbat:
case CreatureIds.PhaseHound:
case CreatureIds.Dreadbeast:
case CreatureIds.Shadowbeast:
if (GetBossState(DataTypes.OptionalBoss) == EncounterState.ToBeDecided)
{
++OptionalBossCount;
if (OptionalBossCount == karazhanConst.OptionalBossRequiredDeathCount)
{
switch (RandomHelper.URand(CreatureIds.HyakissTheLurker, CreatureIds.RokadTheRavager))
{
case CreatureIds.HyakissTheLurker:
instance.SummonCreature(CreatureIds.HyakissTheLurker, karazhanConst.OptionalSpawn[0]);
break;
case CreatureIds.ShadikithTheGlider:
instance.SummonCreature(CreatureIds.ShadikithTheGlider, karazhanConst.OptionalSpawn[1]);
break;
case CreatureIds.RokadTheRavager:
instance.SummonCreature(CreatureIds.RokadTheRavager, karazhanConst.OptionalSpawn[2]);
break;
}
}
}
break;
default:
break;
}
}
public override void SetData(uint type, uint uiData)
{
switch (type)
{
case DataTypes.OperaOzDeathcount:
if (uiData == (uint)EncounterState.Special)
++OzDeathCount;
else if (uiData == (uint)EncounterState.InProgress)
OzDeathCount = 0;
break;
}
}
public override bool SetBossState(uint id, EncounterState state)
{
if (!base.SetBossState(id, state))
return false;
switch (id)
{
case DataTypes.OperaPerformance:
if (state == EncounterState.Done)
{
HandleGameObject(StageDoorLeftGUID, true);
HandleGameObject(StageDoorRightGUID, true);
GameObject sideEntrance = instance.GetGameObject(SideEntranceDoor);
if (sideEntrance != null)
sideEntrance.RemoveFlag(GameObjectFlags.Locked);
UpdateEncounterStateForKilledCreature(16812, null);
}
break;
case DataTypes.Chess:
if (state == EncounterState.Done)
DoRespawnGameObject(DustCoveredChest, Time.Day);
break;
default:
break;
}
return true;
}
public override void SetGuidData(uint identifier, ObjectGuid data)
{
if (identifier == DataTypes.ImageOfMedivh)
ImageGUID = data;
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.StageCurtain:
CurtainGUID = go.GetGUID();
break;
case GameObjectIds.StageDoorLeft:
StageDoorLeftGUID = go.GetGUID();
if (GetBossState(DataTypes.OperaPerformance) == EncounterState.Done)
go.SetGoState(GameObjectState.Active);
break;
case GameObjectIds.StageDoorRight:
StageDoorRightGUID = go.GetGUID();
if (GetBossState(DataTypes.OperaPerformance) == EncounterState.Done)
go.SetGoState(GameObjectState.Active);
break;
case GameObjectIds.PrivateLibraryDoor:
LibraryDoor = go.GetGUID();
break;
case GameObjectIds.MassiveDoor:
MassiveDoor = go.GetGUID();
break;
case GameObjectIds.GamesmanHallDoor:
GamesmansDoor = go.GetGUID();
break;
case GameObjectIds.GamesmanHallExitDoor:
GamesmansExitDoor = go.GetGUID();
break;
case GameObjectIds.NetherspaceDoor:
NetherspaceDoor = go.GetGUID();
break;
case GameObjectIds.MastersTerraceDoor:
MastersTerraceDoor[0] = go.GetGUID();
break;
case GameObjectIds.MastersTerraceDoor2:
MastersTerraceDoor[1] = go.GetGUID();
break;
case GameObjectIds.SideEntranceDoor:
SideEntranceDoor = go.GetGUID();
if (GetBossState(DataTypes.OperaPerformance) == EncounterState.Done)
go.AddFlag(GameObjectFlags.Locked);
else
go.RemoveFlag(GameObjectFlags.Locked);
break;
case GameObjectIds.DustCoveredChest:
DustCoveredChest = go.GetGUID();
break;
case GameObjectIds.BlackenedUrn:
BlackenedUrnGUID = go.GetGUID();
break;
}
switch (OperaEvent)
{
// @todo Set Object visibilities for Opera based on performance
case OperaEvents.Oz:
break;
case OperaEvents.Hood:
break;
case OperaEvents.RAJ:
break;
}
}
public override uint GetData(uint uiData)
{
switch (uiData)
{
case DataTypes.OperaPerformance:
return OperaEvent;
case DataTypes.OperaOzDeathcount:
return OzDeathCount;
}
return 0;
}
public override ObjectGuid GetGuidData(uint uiData)
{
switch (uiData)
{
case DataTypes.Kilrek:
return KilrekGUID;
case DataTypes.Terestian:
return TerestianGUID;
case DataTypes.Moroes:
return MoroesGUID;
case DataTypes.Nightbane:
return NightbaneGUID;
case DataTypes.GoStagedoorleft:
return StageDoorLeftGUID;
case DataTypes.GoStagedoorright:
return StageDoorRightGUID;
case DataTypes.GoCurtains:
return CurtainGUID;
case DataTypes.GoLibraryDoor:
return LibraryDoor;
case DataTypes.GoMassiveDoor:
return MassiveDoor;
case DataTypes.GoSideEntranceDoor:
return SideEntranceDoor;
case DataTypes.GoGameDoor:
return GamesmansDoor;
case DataTypes.GoGameExitDoor:
return GamesmansExitDoor;
case DataTypes.GoNetherDoor:
return NetherspaceDoor;
case DataTypes.MastersTerraceDoor1:
return MastersTerraceDoor[0];
case DataTypes.MastersTerraceDoor2:
return MastersTerraceDoor[1];
case DataTypes.ImageOfMedivh:
return ImageGUID;
case DataTypes.GoBlackenedUrn:
return BlackenedUrnGUID;
}
return ObjectGuid.Empty;
}
uint OperaEvent;
uint OzDeathCount;
uint OptionalBossCount;
ObjectGuid CurtainGUID;
ObjectGuid StageDoorLeftGUID;
ObjectGuid StageDoorRightGUID;
ObjectGuid KilrekGUID;
ObjectGuid TerestianGUID;
ObjectGuid MoroesGUID;
ObjectGuid NightbaneGUID;
ObjectGuid LibraryDoor; // Door at Shade of Aran
ObjectGuid MassiveDoor; // Door at Netherspite
ObjectGuid SideEntranceDoor; // Side Entrance
ObjectGuid GamesmansDoor; // Door before Chess
ObjectGuid GamesmansExitDoor; // Door after Chess
ObjectGuid NetherspaceDoor; // Door at Malchezaar
ObjectGuid[] MastersTerraceDoor = new ObjectGuid[2];
ObjectGuid ImageGUID;
ObjectGuid DustCoveredChest;
ObjectGuid BlackenedUrnGUID;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_karazhan_InstanceMapScript(map);
}
}
}
@@ -1,725 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.EasternKingdoms.Karazhan.Moroes
{
struct Misc
{
public static Position[] Locations =
{
new Position(-10991.0f, -1884.33f, 81.73f, 0.614315f),
new Position(-10989.4f, -1885.88f, 81.73f, 0.904913f),
new Position(-10978.1f, -1887.07f, 81.73f, 2.035550f),
new Position(-10975.9f, -1885.81f, 81.73f, 2.253890f),
};
public static uint[] Adds =
{
17007,
19872,
19873,
19874,
19875,
19876,
};
}
struct TextIds
{
public const uint Aggro = 0;
public const uint Special = 1;
public const uint Kill = 2;
public const uint Death = 3;
}
struct SpellIds
{
public const uint Vanish = 29448;
public const uint Garrote = 37066;
public const uint Blind = 34694;
public const uint Gouge = 29425;
public const uint Frenzy = 37023;
// Adds
public const uint Manaburn = 29405;
public const uint Mindfly = 29570;
public const uint Swpain = 34441;
public const uint Shadowform = 29406;
public const uint Hammerofjustice = 13005;
public const uint Judgementofcommand = 29386;
public const uint Sealofcommand = 29385;
public const uint Dispelmagic = 15090;
public const uint Greaterheal = 29564;
public const uint Holyfire = 29563;
public const uint Pwshield = 29408;
public const uint Cleanse = 29380;
public const uint Greaterblessofmight = 29381;
public const uint Holylight = 29562;
public const uint Divineshield = 41367;
public const uint Hamstring = 9080;
public const uint Mortalstrike = 29572;
public const uint Whirlwind = 29573;
public const uint Disarm = 8379;
public const uint Heroicstrike = 29567;
public const uint Shieldbash = 11972;
public const uint Shieldwall = 29390;
}
[Script]
public class boss_moroes : ScriptedAI
{
public boss_moroes(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
}
public override void Reset()
{
Vanish_Timer = 30000;
Blind_Timer = 35000;
Gouge_Timer = 23000;
Wait_Timer = 0;
CheckAdds_Timer = 5000;
Enrage = false;
InVanish = false;
if (me.IsAlive())
SpawnAdds();
instance.SetBossState(DataTypes.Moroes, EncounterState.NotStarted);
}
void StartEvent()
{
instance.SetBossState(DataTypes.Moroes, EncounterState.InProgress);
DoZoneInCombat();
}
public override void EnterCombat(Unit who)
{
StartEvent();
Talk(TextIds.Aggro);
AddsAttack();
DoZoneInCombat();
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.Kill);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.Death);
instance.SetBossState(DataTypes.Moroes, EncounterState.Done);
DeSpawnAdds();
//remove aura from spell Garrote when Moroes dies
instance.DoRemoveAurasDueToSpellOnPlayers(SpellIds.Garrote);
}
void SpawnAdds()
{
DeSpawnAdds();
if (isAddlistEmpty())
{
List<uint> AddList = new List<uint>();
for (byte i = 0; i < 6; ++i)
AddList.Add(Misc.Adds[i]);
AddList.RandomResize(4);
byte c = 0;
for (var i = 0; i != AddList.Count && c < 4; ++i, ++c)
{
uint entry = AddList[i];
Creature creature = me.SummonCreature(entry, Misc.Locations[c], TempSummonType.CorpseTimedDespawn, 10000);
if (creature)
{
AddGUID[c] = creature.GetGUID();
AddId[c] = entry;
}
}
}
else
{
for (byte i = 0; i < 4; ++i)
{
Creature creature = me.SummonCreature(AddId[i], Misc.Locations[i], TempSummonType.CorpseTimedDespawn, 10000);
if (creature)
AddGUID[i] = creature.GetGUID();
}
}
}
bool isAddlistEmpty()
{
for (byte i = 0; i < 4; ++i)
if (AddId[i] == 0)
return true;
return false;
}
void DeSpawnAdds()
{
for (byte i = 0; i < 4; ++i)
{
if (!AddGUID[i].IsEmpty())
{
Creature temp = ObjectAccessor.GetCreature(me, AddGUID[i]);
if (temp)
temp.DespawnOrUnsummon();
}
}
}
void AddsAttack()
{
for (byte i = 0; i < 4; ++i)
{
if (!AddGUID[i].IsEmpty())
{
Creature temp = ObjectAccessor.GetCreature((me), AddGUID[i]);
if (temp && temp.IsAlive())
{
temp.GetAI().AttackStart(me.GetVictim());
DoZoneInCombat(temp);
}
else
EnterEvadeMode();
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (instance.GetData(DataTypes.Moroes) == 0)
{
EnterEvadeMode();
return;
}
if (!Enrage && HealthBelowPct(30))
{
DoCast(me, SpellIds.Frenzy);
Enrage = true;
}
if (CheckAdds_Timer <= diff)
{
for (byte i = 0; i < 4; ++i)
{
if (!AddGUID[i].IsEmpty())
{
Creature temp = ObjectAccessor.GetCreature((me), AddGUID[i]);
if (temp && temp.IsAlive())
if (!temp.GetVictim())
temp.GetAI().AttackStart(me.GetVictim());
}
}
CheckAdds_Timer = 5000;
}
else CheckAdds_Timer -= diff;
if (!Enrage)
{
//Cast Vanish, then Garrote random victim
if (Vanish_Timer <= diff)
{
DoCast(me, SpellIds.Vanish);
InVanish = true;
Vanish_Timer = 30000;
Wait_Timer = 5000;
}
else Vanish_Timer -= diff;
if (Gouge_Timer <= diff)
{
DoCastVictim(SpellIds.Gouge);
Gouge_Timer = 40000;
}
else Gouge_Timer -= diff;
if (Blind_Timer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.MinDistance, 0, 0.0f, true, false);
if (target != null)
DoCast(target, SpellIds.Blind);
Blind_Timer = 40000;
}
else
Blind_Timer -= diff;
}
if (InVanish)
{
if (Wait_Timer <= diff)
{
Talk(TextIds.Special);
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
target.CastSpell(target, SpellIds.Garrote, true);
InVanish = false;
}
else
Wait_Timer -= diff;
}
if (!InVanish)
DoMeleeAttackIfReady();
}
InstanceScript instance;
public ObjectGuid[] AddGUID = new ObjectGuid[4];
uint Vanish_Timer;
uint Blind_Timer;
uint Gouge_Timer;
uint Wait_Timer;
uint CheckAdds_Timer;
uint[] AddId = new uint[4];
bool InVanish;
bool Enrage;
}
class boss_moroes_guestAI : ScriptedAI
{
public boss_moroes_guestAI(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
}
public override void Reset()
{
instance.SetBossState(DataTypes.Moroes, EncounterState.NotStarted);
}
public void AcquireGUID()
{
Creature Moroes = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Moroes));
if (Moroes)
{
for (byte i = 0; i < 4; ++i)
{
ObjectGuid GUID = ((boss_moroes)Moroes.GetAI()).AddGUID[i];
if (!GUID.IsEmpty())
GuestGUID[i] = GUID;
}
}
}
public Unit SelectGuestTarget()
{
ObjectGuid TempGUID = GuestGUID[RandomHelper.Rand32() % 4];
if (!TempGUID.IsEmpty())
{
Unit unit = Global.ObjAccessor.GetUnit(me, TempGUID);
if (unit && unit.IsAlive())
return unit;
}
return me;
}
public override void UpdateAI(uint diff)
{
if (instance.GetData(DataTypes.Moroes) == 0)
EnterEvadeMode();
DoMeleeAttackIfReady();
}
InstanceScript instance;
ObjectGuid[] GuestGUID = new ObjectGuid[4];
}
[Script]
class boss_baroness_dorothea_millstipe : boss_moroes_guestAI
{
//Shadow Priest
public boss_baroness_dorothea_millstipe(Creature creature) : base(creature) { }
uint ManaBurn_Timer;
uint MindFlay_Timer;
uint ShadowWordPain_Timer;
public override void Reset()
{
ManaBurn_Timer = 7000;
MindFlay_Timer = 1000;
ShadowWordPain_Timer = 6000;
DoCast(me, SpellIds.Shadowform, true);
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (MindFlay_Timer <= diff)
{
DoCastVictim(SpellIds.Mindfly);
MindFlay_Timer = 12000; // 3 sec channeled
}
else MindFlay_Timer -= diff;
if (ManaBurn_Timer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
if (target.GetPowerType() == PowerType.Mana)
DoCast(target, SpellIds.Manaburn);
ManaBurn_Timer = 5000; // 3 sec cast
}
else ManaBurn_Timer -= diff;
if (ShadowWordPain_Timer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
{
DoCast(target, SpellIds.Swpain);
ShadowWordPain_Timer = 7000;
}
}
else ShadowWordPain_Timer -= diff;
}
}
[Script]
class boss_baron_rafe_dreuger : boss_moroes_guestAI
{
//Retr Pally
public boss_baron_rafe_dreuger(Creature creature) : base(creature) { }
uint HammerOfJustice_Timer;
uint SealOfCommand_Timer;
uint JudgementOfCommand_Timer;
public override void Reset()
{
HammerOfJustice_Timer = 1000;
SealOfCommand_Timer = 7000;
JudgementOfCommand_Timer = SealOfCommand_Timer + 29000;
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (SealOfCommand_Timer <= diff)
{
DoCast(me, SpellIds.Sealofcommand);
SealOfCommand_Timer = 32000;
JudgementOfCommand_Timer = 29000;
}
else SealOfCommand_Timer -= diff;
if (JudgementOfCommand_Timer <= diff)
{
DoCastVictim(SpellIds.Judgementofcommand);
JudgementOfCommand_Timer = SealOfCommand_Timer + 29000;
}
else JudgementOfCommand_Timer -= diff;
if (HammerOfJustice_Timer <= diff)
{
DoCastVictim(SpellIds.Hammerofjustice);
HammerOfJustice_Timer = 12000;
}
else HammerOfJustice_Timer -= diff;
}
}
[Script]
class boss_lady_catriona_von_indi : boss_moroes_guestAI
{
//Holy Priest
public boss_lady_catriona_von_indi(Creature creature) : base(creature) { }
uint DispelMagic_Timer;
uint GreaterHeal_Timer;
uint HolyFire_Timer;
uint PowerWordShield_Timer;
public override void Reset()
{
DispelMagic_Timer = 11000;
GreaterHeal_Timer = 1500;
HolyFire_Timer = 5000;
PowerWordShield_Timer = 1000;
AcquireGUID();
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (PowerWordShield_Timer <= diff)
{
DoCast(me, SpellIds.Pwshield);
PowerWordShield_Timer = 15000;
}
else PowerWordShield_Timer -= diff;
if (GreaterHeal_Timer <= diff)
{
Unit target = SelectGuestTarget();
DoCast(target, SpellIds.Greaterheal);
GreaterHeal_Timer = 17000;
}
else GreaterHeal_Timer -= diff;
if (HolyFire_Timer <= diff)
{
DoCastVictim(SpellIds.Holyfire);
HolyFire_Timer = 22000;
}
else HolyFire_Timer -= diff;
if (DispelMagic_Timer <= diff)
{
Unit target = RandomHelper.RAND(SelectGuestTarget(), SelectTarget(SelectAggroTarget.Random, 0, 100, true));
if (target)
DoCast(target, SpellIds.Dispelmagic);
DispelMagic_Timer = 25000;
}
else DispelMagic_Timer -= diff;
}
}
[Script]
class boss_lady_keira_berrybuck : boss_moroes_guestAI
{
//Holy Pally
public boss_lady_keira_berrybuck(Creature creature) : base(creature) { }
uint Cleanse_Timer;
uint GreaterBless_Timer;
uint HolyLight_Timer;
uint DivineShield_Timer;
public override void Reset()
{
Cleanse_Timer = 13000;
GreaterBless_Timer = 1000;
HolyLight_Timer = 7000;
DivineShield_Timer = 31000;
AcquireGUID();
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (DivineShield_Timer <= diff)
{
DoCast(me, SpellIds.Divineshield);
DivineShield_Timer = 31000;
}
else DivineShield_Timer -= diff;
if (HolyLight_Timer <= diff)
{
Unit target = SelectGuestTarget();
DoCast(target, SpellIds.Holylight);
HolyLight_Timer = 10000;
}
else HolyLight_Timer -= diff;
if (GreaterBless_Timer <= diff)
{
Unit target = SelectGuestTarget();
DoCast(target, SpellIds.Greaterblessofmight);
GreaterBless_Timer = 50000;
}
else GreaterBless_Timer -= diff;
if (Cleanse_Timer <= diff)
{
Unit target = SelectGuestTarget();
DoCast(target, SpellIds.Cleanse);
Cleanse_Timer = 10000;
}
else Cleanse_Timer -= diff;
}
}
[Script]
class boss_lord_robin_daris : boss_moroes_guestAI
{
//Arms Warr
public boss_lord_robin_daris(Creature creature) : base(creature) { }
uint Hamstring_Timer;
uint MortalStrike_Timer;
uint WhirlWind_Timer;
public override void Reset()
{
Hamstring_Timer = 7000;
MortalStrike_Timer = 10000;
WhirlWind_Timer = 21000;
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (Hamstring_Timer <= diff)
{
DoCastVictim(SpellIds.Hamstring);
Hamstring_Timer = 12000;
}
else Hamstring_Timer -= diff;
if (MortalStrike_Timer <= diff)
{
DoCastVictim(SpellIds.Mortalstrike);
MortalStrike_Timer = 18000;
}
else MortalStrike_Timer -= diff;
if (WhirlWind_Timer <= diff)
{
DoCast(me, SpellIds.Whirlwind);
WhirlWind_Timer = 21000;
}
else WhirlWind_Timer -= diff;
}
}
[Script]
class boss_lord_crispin_ference : boss_moroes_guestAI
{
//Arms Warr
public boss_lord_crispin_ference(Creature creature) : base(creature) { }
uint Disarm_Timer;
uint HeroicStrike_Timer;
uint ShieldBash_Timer;
uint ShieldWall_Timer;
public override void Reset()
{
Disarm_Timer = 6000;
HeroicStrike_Timer = 10000;
ShieldBash_Timer = 8000;
ShieldWall_Timer = 4000;
base.Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
base.UpdateAI(diff);
if (Disarm_Timer <= diff)
{
DoCastVictim(SpellIds.Disarm);
Disarm_Timer = 12000;
}
else Disarm_Timer -= diff;
if (HeroicStrike_Timer <= diff)
{
DoCastVictim(SpellIds.Heroicstrike);
HeroicStrike_Timer = 10000;
}
else HeroicStrike_Timer -= diff;
if (ShieldBash_Timer <= diff)
{
DoCastVictim(SpellIds.Shieldbash);
ShieldBash_Timer = 13000;
}
else ShieldBash_Timer -= diff;
if (ShieldWall_Timer <= diff)
{
DoCast(me, SpellIds.Shieldwall);
ShieldWall_Timer = 21000;
}
else ShieldWall_Timer -= diff;
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,133 +0,0 @@
using System;
using Game.Entities;
using Game.AI;
using Game.Scripting;
using Framework.Constants;
namespace Scripts.EasternKingdoms.TheStockade
{
struct TextIds
{
public const uint SayPull = 0; // Forest Just Setback!
public const uint SayEnrage = 1; // Areatriggermessage: Hogger Enrages!
public const uint SayDeath = 2; // Yiipe!
public const uint SayWarden1 = 0; // Yell - This Ends Here; Hogger!
public const uint SayWarden2 = 1; // Say - He'S...He'S Dead?
public const uint SayWarden3 = 2; // Say - It'S Simply Too Good To Be True. You Couldn'T Have Killed Him So Easily!
}
struct SpellIds
{
public const uint ViciousSlice = 86604;
public const uint MaddeningCall = 86620;
public const uint Enrage = 86736;
}
struct Events
{
public const uint SayWarden1 = 1;
public const uint SayWarden2 = 2;
public const uint SayWarden3 = 3;
}
[Script]
class boss_hogger : BossAI
{
public boss_hogger(Creature creature) : base(creature, DataTypes.Hogger) { }
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayPull);
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4), task =>
{
DoCastVictim(SpellIds.ViciousSlice);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), task =>
{
DoCast(SpellIds.MaddeningCall);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
});
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
_JustDied();
me.SummonCreature(CreatureIds.WardenThelwater, Misc.WardenThelwaterPos);
}
public override void JustSummoned(Creature summon)
{
base.JustSummoned(summon);
if (summon.GetEntry() == CreatureIds.WardenThelwater)
summon.GetMotionMaster().MovePoint(0, Misc.WardenThelwaterMovePos);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (me.HealthBelowPctDamaged(30, damage) && !_hasEnraged)
{
_hasEnraged = true;
Talk(TextIds.SayEnrage);
DoCastSelf(SpellIds.Enrage);
}
}
bool _hasEnraged;
}
[Script]
class npc_warden_thelwater : ScriptedAI
{
public npc_warden_thelwater(Creature creature) : base(creature) { }
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type == MovementGeneratorType.Point && id == 0)
_events.ScheduleEvent(Events.SayWarden1, TimeSpan.FromSeconds(1));
}
public override void UpdateAI(uint diff)
{
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.SayWarden1:
Talk(TextIds.SayWarden1);
_events.ScheduleEvent(Events.SayWarden2, TimeSpan.FromSeconds(4));
break;
case Events.SayWarden2:
Talk(TextIds.SayWarden2);
_events.ScheduleEvent(Events.SayWarden3, TimeSpan.FromSeconds(3));
break;
case Events.SayWarden3:
Talk(TextIds.SayWarden3);
break;
}
});
}
}
}
@@ -1,50 +0,0 @@
using Game.Maps;
using Game.Scripting;
using Game.Entities;
namespace Scripts.EasternKingdoms.TheStockade
{
struct Misc
{
public static Position WardenThelwaterMovePos = new Position(152.019f, 106.198f, -35.1896f, 1.082104f);
public static Position WardenThelwaterPos = new Position(138.369f, 78.2932f, -33.85627f, 1.082104f);
}
struct DataTypes
{
public const uint RandolphMoloch = 0;
public const uint LordOverheat = 1;
public const uint Hogger = 2;
}
struct CreatureIds
{
public const uint RandolphMoloch = 46383;
public const uint LordOverheat = 46264;
public const uint Hogger = 46254;
public const uint WardenThelwater = 46409;
public const uint MortimerMoloch = 46482;
}
[Script]
class instance_the_stockade : InstanceMapScript
{
public instance_the_stockade() : base("instance_the_stockade", 34) { }
class instance_the_stockade_InstanceMapScript : InstanceScript
{
public instance_the_stockade_InstanceMapScript(InstanceMap map) : base(map)
{
SetHeaders("SS");
SetBossNumber(3);
}
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_the_stockade_InstanceMapScript(map);
}
}
}
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Game.Maps;
using Game.Scripting;
namespace Scripts.Kalimdor
{
[Script]
public class instance_ragefire_chasm : InstanceMapScript
{
public instance_ragefire_chasm() : base("instance_ragefire_chasm", 389) { }
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new RagefireChasmInstanceMapScript(map);
}
class RagefireChasmInstanceMapScript : InstanceScript
{
public RagefireChasmInstanceMapScript(InstanceMap map) : base(map) { }
}
}
}
-366
View File
@@ -1,366 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Kalimdor.ZoneAshenvale
{
struct CreatureIds
{
//RuulSnowhoof
public const uint ThistlefurUrsa = 3921;
public const uint ThistlefurTotemic = 3922;
public const uint ThistlefurPathfinder = 3926;
//Muglash
public const uint WrathRider = 3713;
public const uint WrathSorceress = 3717;
public const uint WrathRazortail = 3712;
public const uint WrathPriestess = 3944;
public const uint WrathMyrmidon = 3711;
public const uint WrathSeawitch = 3715;
public const uint Vorsha = 12940;
public const uint Muglash = 12717;
}
struct GameObjectIds
{
//RuulSnowhoof
public const uint Cage = 178147;
//Muglash
public const uint NagaBrazier = 178247;
//KingoftheFoulweald
public const uint Banner = 178205;
}
struct QuestIds
{
//RuulSnowhoof
public const uint FreedomToRuul = 6482;
//Muglash
public const uint Vorsha = 6641;
}
struct TextIds
{
//Muglash
public const uint SayMugStart1 = 0;
public const uint SayMugStart2 = 1;
public const uint SayMugBrazier = 2;
public const uint SayMugBrazierWait = 3;
public const uint SayMugOnGuard = 4;
public const uint SayMugRest = 5;
public const uint SayMugDone = 6;
public const uint SayMugGratitude = 7;
public const uint SayMugPatrol = 8;
public const uint SayMugReturn = 9;
}
struct Misc
{
//RuulSnowhoof
public const uint FactionQuest = 113;
public static Position[] RuulSnowhoofSummonsCoord =
{
new Position(3449.218018f, -587.825073f, 174.978867f, 4.714445f),
new Position(3446.384521f, -587.830872f, 175.186279f, 4.714445f),
new Position(3444.218994f, -587.835327f, 175.380600f, 4.714445f),
new Position(3508.344482f, -492.024261f, 186.929031f, 4.145029f),
new Position(3506.265625f, -490.531006f, 186.740128f, 4.239277f),
new Position(3503.682373f, -489.393799f, 186.629684f, 4.349232f)
};
//Muglash
public static Position[] FirstNagaCoord =
{
new Position(3603.504150f, 1122.631104f, 1.635f, 0.0f), // rider
new Position(3589.293945f, 1148.664063f, 5.565f, 0.0f), // sorceress
new Position(3609.925537f, 1168.759521f, -1.168f, 0.0f) // razortail
};
public static Position[] SecondNagaCoord =
{
new Position(3609.925537f, 1168.759521f, -1.168f, 0.0f), // witch
new Position(3645.652100f, 1139.425415f, 1.322f, 0.0f), // priest
new Position(3583.602051f, 1128.405762f, 2.347f, 0.0f) // myrmidon
};
public static Position VorshaCoord = new Position(3633.056885f, 1172.924072f, -5.388f, 0.0f);
}
[Script]
class npc_ruul_snowhoof : EscortAI
{
public npc_ruul_snowhoof(Creature creature) : base(creature) { }
public override void Reset()
{
GameObject cage = me.FindNearestGameObject(GameObjectIds.Cage, 20);
if (cage)
cage.SetGoState(GameObjectState.Ready);
}
public override void EnterCombat(Unit who) { }
public override void JustSummoned(Creature summoned)
{
summoned.GetAI().AttackStart(me);
}
public override void QuestAccept(Player player, Quest quest)
{
if (quest.Id == QuestIds.FreedomToRuul)
{
me.SetFaction(Misc.FactionQuest);
Start(true, false, player.GetGUID());
}
}
public override void WaypointReached(uint waypointId, uint pathId)
{
Player player = GetPlayerForEscort();
if (!player)
return;
switch (waypointId)
{
case 0:
me.SetStandState(UnitStandStateType.Stand);
GameObject cage = me.FindNearestGameObject(GameObjectIds.Cage, 20);
if (cage)
cage.SetGoState(GameObjectState.Active);
break;
case 13:
me.SummonCreature(CreatureIds.ThistlefurTotemic, Misc.RuulSnowhoofSummonsCoord[0], TempSummonType.DeadDespawn, 60000);
me.SummonCreature(CreatureIds.ThistlefurUrsa, Misc.RuulSnowhoofSummonsCoord[1], TempSummonType.DeadDespawn, 60000);
me.SummonCreature(CreatureIds.ThistlefurPathfinder, Misc.RuulSnowhoofSummonsCoord[2], TempSummonType.DeadDespawn, 60000);
break;
case 19:
me.SummonCreature(CreatureIds.ThistlefurTotemic, Misc.RuulSnowhoofSummonsCoord[3], TempSummonType.DeadDespawn, 60000);
me.SummonCreature(CreatureIds.ThistlefurUrsa, Misc.RuulSnowhoofSummonsCoord[4], TempSummonType.DeadDespawn, 60000);
me.SummonCreature(CreatureIds.ThistlefurPathfinder, Misc.RuulSnowhoofSummonsCoord[5], TempSummonType.DeadDespawn, 60000);
break;
case 21:
player.GroupEventHappens(QuestIds.FreedomToRuul, me);
break;
}
}
}
[Script]
public class npc_muglash : EscortAI
{
public npc_muglash(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
eventTimer = 10000;
waveId = 0;
_isBrazierExtinguished = false;
}
public override void Reset()
{
Initialize();
}
public override void EnterCombat(Unit who)
{
Player player = GetPlayerForEscort();
if (player)
{
if (HasEscortState(EscortState.Paused))
{
if (Convert.ToBoolean(RandomHelper.URand(0, 1)))
Talk(TextIds.SayMugOnGuard, player);
return;
}
}
}
public override void JustDied(Unit killer)
{
if (HasEscortState(EscortState.Escorting))
{
Player player = GetPlayerForEscort();
if (player)
player.FailQuest(QuestIds.Vorsha);
}
}
public override void JustSummoned(Creature summoned)
{
summoned.GetAI().AttackStart(me);
}
public override void QuestAccept(Player player, Quest quest)
{
if (quest.Id == QuestIds.Vorsha)
{
Talk(TextIds.SayMugStart1);
me.SetFaction(Misc.FactionQuest);
Start(true, false, player.GetGUID());
}
}
public override void WaypointReached(uint waypointId, uint pathId)
{
Player player = GetPlayerForEscort();
if (player)
{
switch (waypointId)
{
case 0:
Talk(TextIds.SayMugStart2, player);
break;
case 24:
Talk(TextIds.SayMugBrazier, player);
GameObject go = GetClosestGameObjectWithEntry(me, GameObjectIds.NagaBrazier, SharedConst.InteractionDistance * 2);
if (go)
{
go.RemoveFlag(GameObjectFlags.NotSelectable);
SetEscortPaused(true);
}
break;
case 25:
Talk(TextIds.SayMugGratitude);
player.GroupEventHappens(QuestIds.Vorsha, me);
break;
case 26:
Talk(TextIds.SayMugPatrol);
break;
case 27:
Talk(TextIds.SayMugReturn);
break;
}
}
}
void DoWaveSummon()
{
switch (waveId)
{
case 1:
me.SummonCreature(CreatureIds.WrathRider, Misc.FirstNagaCoord[0], TempSummonType.TimedDespawnOOC, 60000);
me.SummonCreature(CreatureIds.WrathSorceress, Misc.FirstNagaCoord[1], TempSummonType.TimedDespawnOOC, 60000);
me.SummonCreature(CreatureIds.WrathRazortail, Misc.FirstNagaCoord[2], TempSummonType.TimedDespawnOOC, 60000);
break;
case 2:
me.SummonCreature(CreatureIds.WrathPriestess, Misc.SecondNagaCoord[0], TempSummonType.TimedDespawnOOC, 60000);
me.SummonCreature(CreatureIds.WrathMyrmidon, Misc.SecondNagaCoord[1], TempSummonType.TimedDespawnOOC, 60000);
me.SummonCreature(CreatureIds.WrathSeawitch, Misc.SecondNagaCoord[2], TempSummonType.TimedDespawnOOC, 60000);
break;
case 3:
me.SummonCreature(CreatureIds.Vorsha, Misc.VorshaCoord, TempSummonType.TimedDespawnOOC, 60000);
break;
case 4:
SetEscortPaused(false);
Talk(TextIds.SayMugDone);
break;
}
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (!me.GetVictim())
{
if (HasEscortState(EscortState.Paused) && _isBrazierExtinguished)
{
if (eventTimer < diff)
{
++waveId;
DoWaveSummon();
eventTimer = 10000;
}
else
eventTimer -= diff;
}
return;
}
DoMeleeAttackIfReady();
}
uint eventTimer;
byte waveId;
public bool _isBrazierExtinguished { get; set; }
}
[Script]
class go_naga_brazier : GameObjectScript
{
public go_naga_brazier() : base("go_naga_brazier") { }
class go_naga_brazierAI : GameObjectAI
{
public go_naga_brazierAI(GameObject go) : base(go) { }
public override bool GossipHello(Player player)
{
Creature creature = ScriptedAI.GetClosestCreatureWithEntry(me, CreatureIds.Muglash, SharedConst.InteractionDistance * 2);
if (creature)
{
npc_muglash pEscortAI = creature.GetAI<npc_muglash>();
if (pEscortAI != null)
{
creature.GetAI().Talk(TextIds.SayMugBrazierWait);
pEscortAI._isBrazierExtinguished = true;
return false;
}
}
return true;
}
}
public override GameObjectAI GetAI(GameObject go)
{
return new go_naga_brazierAI(go);
}
}
[Script]
class spell_destroy_karangs_banner : SpellScript
{
void HandleAfterCast()
{
GameObject banner = GetCaster().FindNearestGameObject(GameObjectIds.Banner, GetSpellInfo().GetMaxRange(true));
if (banner)
banner.Delete();
}
public override void Register()
{
AfterCast.Add(new CastHandler(HandleAfterCast));
}
}
}
-131
View File
@@ -1,131 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.Dynamic;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.Kalimdor
{
[Script]
class npc_lazy_peon : NullCreatureAI
{
public npc_lazy_peon(Creature creature) : base(creature) { }
public override void InitializeAI()
{
me.SetWalk(true);
scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(120000), task =>
{
GameObject Lumberpile = me.FindNearestGameObject(GoLumberpile, 20);
if (Lumberpile)
me.GetMotionMaster().MovePoint(1, Lumberpile.GetPositionX() - 1, Lumberpile.GetPositionY(), Lumberpile.GetPositionZ());
task.Repeat();
});
scheduler.Schedule(TimeSpan.FromMilliseconds(300000), task =>
{
me.HandleEmoteCommand(Emote.StateNone);
me.GetMotionMaster().MovePoint(2, me.GetHomePosition());
task.Repeat();
});
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
switch (id)
{
case 1:
me.HandleEmoteCommand(Emote.StateWorkChopwood);
break;
case 2:
DoCast(me, SpellBuffSleep);
break;
}
}
public override void SpellHit(Unit caster, SpellInfo spell)
{
if (spell.Id != SpellAwakenPeon)
return;
Player player = caster.ToPlayer();
if (player && player.GetQuestStatus(QuestLazyPeons) == QuestStatus.Incomplete)
{
player.KilledMonsterCredit(me.GetEntry(), me.GetGUID());
Talk(SaySpellHit, caster);
me.RemoveAllAuras();
GameObject Lumberpile = me.FindNearestGameObject(GoLumberpile, 20);
if (Lumberpile)
me.GetMotionMaster().MovePoint(1, Lumberpile.GetPositionX() - 1, Lumberpile.GetPositionY(), Lumberpile.GetPositionZ());
}
}
public override void UpdateAI(uint diff)
{
scheduler.Update(diff);
//if (!UpdateVictim())
//return;
//DoMeleeAttackIfReady();
}
const int QuestLazyPeons = 37446;
const int GoLumberpile = 175784;
const uint SpellBuffSleep = 17743;
const int SpellAwakenPeon = 19938;
const int SaySpellHit = 0;
TaskScheduler scheduler = new TaskScheduler();
}
[Script]
class spell_voodoo : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellBrew, SpellGhostly, SpellHex1, SpellHex2, SpellHex3, SpellGrow, SpellLaunch);
}
void HandleDummy(uint effIndex)
{
uint spellid = RandomHelper.RAND(SpellBrew, SpellGhostly, RandomHelper.RAND(SpellHex1, SpellHex2, SpellHex3), SpellGrow, SpellLaunch);
Unit target = GetHitUnit();
if (target)
GetCaster().CastSpell(target, spellid, false);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.Dummy));
}
const uint SpellBrew = 16712; // Special Brew
const uint SpellGhostly = 16713; // Ghostly
const uint SpellHex1 = 16707; // Hex
const uint SpellHex2 = 16708; // Hex
const uint SpellHex3 = 16709; // Hex
const uint SpellGrow = 16711; // Grow
const uint SpellLaunch = 16716; // Launch (Whee!)
}
}
@@ -1,185 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using 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 : BossAI
{
public boss_amanitar(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);
me.UpdateGroundPositionZ(pos.GetPositionX(), pos.GetPositionY(), ref pos.posZ);
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)
{
u = 1 - u;
me.SummonCreature(u > 0 ? CreatureIds.PoisonousMushroom : CreatureIds.HealthyMushroom, pos, TempSummonType.TimedOrCorpseDespawn, 60 * Time.InMilliseconds);
}
trigger.DespawnOrUnsummon();
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_amanitar_mushrooms : ScriptedAI
{
public npc_amanitar_mushrooms(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.SetDisplayFromModel(1);
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;
}
}
}
@@ -1,247 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
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 : BossAI
{
public boss_elder_nadox(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;
}
[Script]
class npc_ahnkahar_nerubian : ScriptedAI
{
public npc_ahnkahar_nerubian(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();
}
}
// 56159 - Swarm
[Script]
class spell_ahn_kahet_swarm : SpellScript
{
public spell_ahn_kahet_swarm()
{
_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;
}
[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;
}
}
}
@@ -1,289 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System.Collections.Generic;
using System.Linq;
using Game;
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 : ScriptedAI
{
public boss_volazj(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.HasUnitFlag(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.AddUnitFlag(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, GetDifficulty());
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
PhasingHandler.AddPhase(summon, (uint)spellInfo.GetEffect(0).MiscValueB, 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
for (uint i = 173; i <= 177; ++i)
PhasingHandler.AddPhase(me, i, false);
PhasingHandler.AddPhase(me, 169, true);
ResetPlayersPhase();
// Cleanup
Summons.DespawnAll();
me.RemoveUnitFlag(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.GetPhaseShift().GetPhases().First().Key;
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.RemoveUnitFlag(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;
}
}
@@ -1,569 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
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 BeamVisualJedogasAufseher1 = 60342;
public const uint BeamVisualJedogasAufseher2 = 56312;
}
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]
public class boss_jedoga_shadowseeker : ScriptedAI
{
public boss_jedoga_shadowseeker(Creature creature) : base(creature)
{
Initialize();
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();
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);
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.RemoveUnitFlag(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.AddUnitFlag(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;
}
[Script]
class npc_jedoga_initiand : ScriptedAI
{
public npc_jedoga_initiand(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.RemoveUnitFlag(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.AddUnitFlag(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>().bOpFerok)
boss.GetAI<boss_jedoga_shadowseeker>().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>().bOpFerok = true;
boss.GetAI<boss_jedoga_shadowseeker>().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.RemoveUnitFlag(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.RemoveUnitFlag(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.AddUnitFlag(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;
}
[Script]
class npc_jedogas_aufseher_trigger : ScriptedAI
{
public npc_jedogas_aufseher_trigger(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, SpellIds.BeamVisualJedogasAufseher1, false);
bCast = true;
}
}
if (!bRemoved2 && me.GetPositionX() < 440.0f)
{
if (!bCast2 && instance.GetData(DataTypes.JedogaTriggerSwitch) != 0)
{
DoCast(me, SpellIds.BeamVisualJedogasAufseher2, 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;
}
[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;
}
}
}
@@ -1,447 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.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]
public class boss_prince_taldaram : BossAI
{
public boss_prince_taldaram(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.RemoveUnitFlag(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;
}
[Script] // 30106, 31686, 31687 - Flame Sphere
class npc_prince_taldaram_flame_sphere : ScriptedAI
{
public npc_prince_taldaram_flame_sphere(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;
}
[Script] // 193093, 193094 - Ancient Nerubian Device
class go_prince_taldaram_sphere : GameObjectScript
{
public go_prince_taldaram_sphere() : base("go_prince_taldaram_sphere") { }
class go_prince_taldaram_sphereAI : GameObjectAI
{
public go_prince_taldaram_sphereAI(GameObject go) : base(go)
{
instance = go.GetInstanceScript();
}
public override bool GossipHello(Player player)
{
Creature PrinceTaldaram = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.PrinceTaldaram));
if (PrinceTaldaram && PrinceTaldaram.IsAlive())
{
me.AddFlag(GameObjectFlags.NotSelectable);
me.SetGoState(GameObjectState.Active);
switch (me.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>().CheckSpheres();
}
return true;
}
InstanceScript instance;
}
public override GameObjectAI GetAI(GameObject go)
{
return GetInstanceAI<go_prince_taldaram_sphereAI>(go);
}
}
[Script] // 55931 - Conjure Flame Sphere
class spell_prince_taldaram_conjure_flame_sphere : 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));
}
}
[Script] // 55895, 59511, 59512 - Flame Sphere Summon
class spell_prince_taldaram_flame_sphere_summon : 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));
}
}
}
@@ -1,334 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.Northrend.AzjolNerub.Ahnkahet
{
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;
}
[Script]
class instance_ahnkahet : InstanceMapScript
{
public instance_ahnkahet() : base("instance_ahnkahet", 619) { }
class instance_ahnkahet_InstanceScript : InstanceScript
{
public instance_ahnkahet_InstanceScript(InstanceMap 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.AddFlag(GameObjectFlags.NotSelectable);
}
else
go.RemoveFlag(GameObjectFlags.NotSelectable);
break;
case GameObjectIds.Sphere2:
if (SpheresState[1] != 0)
{
go.SetGoState(GameObjectState.Active);
go.AddFlag(GameObjectFlags.NotSelectable);
}
else
go.RemoveFlag(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.SelectRandom();
}
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);
}
}
}
@@ -1,639 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
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 : BossAI
{
public boss_anub_arak(Creature creature) : base(creature, ANDataTypes.Anubarak) { }
public override void Reset()
{
base.Reset();
me.RemoveUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable);
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievGottaGoStartEvent);
_nextSubmerge = 75;
_petCount = 0;
}
public override bool CanAIAttack(Unit victim) { return true; } // do not check boundary here
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
GameObject door2 = instance.GetGameObject(ANDataTypes.AnubarakWall2);
if (door2)
door2.SetGoState(GameObjectState.Active);
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);
GameObject door2 = instance.GetGameObject(ANDataTypes.AnubarakWall2);
if (door2)
door2.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.SelectRandom();
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.RemoveUnitFlag(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.AddUnitFlag(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;
}
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 : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_darter(Creature creature) : base(creature, false) { }
public override void InitializeAI()
{
base.InitializeAI();
DoCastAOE(SpellIds.Dart);
}
}
[Script]
class npc_anubarak_anub_ar_assassin : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_assassin(Creature creature) : base(creature, false)
{
_backstabTimer = 6 * Time.InMilliseconds;
}
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(boundary, jumpTo));
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;
}
[Script]
class npc_anubarak_anub_ar_guardian : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_guardian(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;
}
[Script]
class npc_anubarak_anub_ar_venomancer : npc_anubarak_pet_template
{
public npc_anubarak_anub_ar_venomancer(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;
}
[Script]
class npc_anubarak_impale_target : NullCreatureAI
{
public npc_anubarak_impale_target(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();
}
}
[Script]
class spell_anubarak_pound : 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));
}
}
[Script]
class spell_anubarak_carrion_beetles : 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));
}
}
}
@@ -1,864 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.KrikthirTheGatewatcher
{
struct SpellIds
{
// Krik'Thir The Gatewatcher
public const uint SubbossAggroTrigger = 52343;
public const uint Swarm = 52440;
public const uint MindFlay = 52586;
public const uint CurseOfFatigue = 52592;
public const uint Frenzy = 28747;
// Watchers - Shared
public const uint WebWrap = 52086;
public const uint WebWrapWrapped = 52087;
public const uint InfectedBite = 52469;
// Watcher Gashra
public const uint Enrage = 52470;
// Watcher Narjil
public const uint BlindingWebs = 52524;
// Watcher Silthik
public const uint PoisonSpray = 52493;
// Anub'Ar Warrior
public const uint Cleave = 49806;
public const uint Strike = 52532;
// Anub'Ar Skirmisher
public const uint Charge = 52538;
public const uint Backstab = 52540;
public const uint FixtateTrigger = 52536;
public const uint FixtateTriggered = 52537;
// Anub'Ar Shadowcaster
public const uint ShadowBolt = 52534;
public const uint ShadowNova = 52535;
// Skittering Infector
public const uint AcidSplash = 52446;
}
struct Misc
{
public const uint DataPetGroup = 0;
// Krik'thir the Gatewatcher
public const uint EventSendGroup = 1;
public const uint EventSwarm = 2;
public const uint EventMindFlay = 3;
public const uint EventFrenzy = 4;
}
struct ActionIds
{
public const int GashraDied = 0;
public const int NarjilDied = 1;
public const int SilthikDied = 2;
public const int WatcherEngaged = 3;
public const int PetEngaged = 4;
public const int PetEvade = 5;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SaySwarm = 3;
public const uint SayPrefight = 4;
public const uint SaySendGroup = 5;
}
[Script]
class boss_krik_thir : BossAI
{
public boss_krik_thir(Creature creature) : base(creature, ANDataTypes.KrikthirTheGatewatcher) { }
void SummonAdds()
{
if (instance.GetBossState(ANDataTypes.KrikthirTheGatewatcher) == EncounterState.Done)
return;
for (byte i = 1; i <= 3; ++i)
{
List<TempSummon> summons;
me.SummonCreatureGroup(i, out summons);
foreach (TempSummon summon in summons)
summon.GetAI().SetData(Misc.DataPetGroup, i);
}
}
public override void Reset()
{
base.Reset();
_hadFrenzy = false;
_petsInCombat = false;
_watchersActive = 0;
me.SetReactState(ReactStates.Passive);
}
public override void InitializeAI()
{
base.InitializeAI();
SummonAdds();
}
public override void JustAppeared()
{
base.JustAppeared();
SummonAdds();
}
public override void KilledUnit(Unit victim)
{
if (victim.IsTypeId(TypeId.Player))
Talk(TextIds.SaySlay);
}
public override void JustDied(Unit killer)
{
summons.Clear();
base.JustDied(killer);
Talk(TextIds.SayDeath);
}
public override void EnterCombat(Unit who)
{
_petsInCombat = false;
me.SetReactState(ReactStates.Aggressive);
summons.DoZoneInCombat();
_events.CancelEvent(Misc.EventSendGroup);
_events.ScheduleEvent(Misc.EventSwarm, TimeSpan.FromSeconds(5));
_events.ScheduleEvent(Misc.EventMindFlay, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3));
base.EnterCombat(who);
}
public override void MoveInLineOfSight(Unit who)
{
if (!me.HasReactState(ReactStates.Passive))
{
base.MoveInLineOfSight(who);
return;
}
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
EnterCombat(who);
}
public override void EnterEvadeMode(EvadeReason why)
{
summons.DespawnAll();
_DespawnAtEvade();
}
public override void DoAction(int action)
{
switch (action)
{
case -ANInstanceMisc.ActionGatewatcherGreet:
if (instance.GetData(ANDataTypes.GatewatcherGreet) == 0 && me.IsAlive() && !me.IsInCombat() && !_petsInCombat)
{
instance.SetData(ANDataTypes.GatewatcherGreet, 1);
Talk(TextIds.SayPrefight);
}
break;
case ActionIds.GashraDied:
case ActionIds.NarjilDied:
case ActionIds.SilthikDied:
if (_watchersActive == 0) // something is wrong
{
EnterEvadeMode(EvadeReason.Other);
return;
}
if ((--_watchersActive) == 0) // if there are no watchers currently in combat...
_events.RescheduleEvent(Misc.EventSendGroup, TimeSpan.FromSeconds(5)); // ...send the next watcher after the targets sooner
break;
case ActionIds.WatcherEngaged:
++_watchersActive;
break;
case ActionIds.PetEngaged:
if (_petsInCombat || me.IsInCombat())
break;
_petsInCombat = true;
Talk(TextIds.SayAggro);
_events.ScheduleEvent(Misc.EventSendGroup, TimeSpan.FromSeconds(70));
break;
case ActionIds.PetEvade:
EnterEvadeMode(EvadeReason.Other);
break;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() && !_petsInCombat)
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
if (me.HealthBelowPct(10) && !_hadFrenzy)
{
_hadFrenzy = true;
_events.ScheduleEvent(Misc.EventFrenzy, TimeSpan.FromSeconds(1));
}
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Misc.EventSendGroup:
DoCastAOE(SpellIds.SubbossAggroTrigger, true);
_events.Repeat(TimeSpan.FromSeconds(70));
break;
case Misc.EventSwarm:
DoCastAOE(SpellIds.Swarm);
Talk(TextIds.SaySwarm);
break;
case Misc.EventMindFlay:
DoCastVictim(SpellIds.MindFlay);
_events.Repeat(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(11));
break;
case Misc.EventFrenzy:
DoCastSelf(SpellIds.Frenzy);
DoCastAOE(SpellIds.CurseOfFatigue);
_events.Repeat(TimeSpan.FromSeconds(15));
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
public override void SpellHit(Unit whose, SpellInfo spell)
{
if (spell.Id == SpellIds.SubbossAggroTrigger)
DoZoneInCombat();
}
public override void SpellHitTarget(Unit who, SpellInfo spell)
{
if (spell.Id == SpellIds.SubbossAggroTrigger)
Talk(TextIds.SaySendGroup);
}
bool _hadFrenzy;
bool _petsInCombat;
byte _watchersActive;
}
class npc_gatewatcher_petAI : ScriptedAI
{
public npc_gatewatcher_petAI(Creature creature, bool isWatcher) : base(creature)
{
_instance = creature.GetInstanceScript();
_isWatcher = isWatcher;
}
public virtual void _EnterCombat() { }
public override void EnterCombat(Unit who)
{
if (_isWatcher)
{
_isWatcher = false;
TempSummon meSummon = me.ToTempSummon();
if (meSummon)
{
Creature summoner = meSummon.GetSummonerCreatureBase();
if (summoner)
summoner.GetAI().DoAction(ActionIds.WatcherEngaged);
}
}
if (me.HasReactState(ReactStates.Passive))
{
List<Creature> others = new List<Creature>();
me.GetCreatureListWithEntryInGrid(others, 0, 40.0f);
foreach (Creature other in others)
{
if (other.GetAI().GetData(Misc.DataPetGroup) == _petGroup)
{
other.SetReactState(ReactStates.Aggressive);
other.GetAI().AttackStart(who);
}
}
TempSummon meSummon = me.ToTempSummon();
if (meSummon)
{
Creature summoner = meSummon.GetSummonerCreatureBase();
if (summoner)
summoner.GetAI().DoAction(ActionIds.PetEngaged);
}
}
_EnterCombat();
base.EnterCombat(who);
}
public override void SetData(uint data, uint value)
{
if (data == Misc.DataPetGroup)
{
_petGroup = value;
me.SetReactState(_petGroup != 0 ? ReactStates.Passive : ReactStates.Aggressive);
}
}
public override uint GetData(uint data)
{
if (data == Misc.DataPetGroup)
return _petGroup;
return 0;
}
public override void MoveInLineOfSight(Unit who)
{
if (!me.HasReactState(ReactStates.Passive))
{
base.MoveInLineOfSight(who);
return;
}
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
EnterCombat(who);
}
public override void SpellHit(Unit whose, SpellInfo spell)
{
if (spell.Id == SpellIds.SubbossAggroTrigger)
DoZoneInCombat();
}
public override void EnterEvadeMode(EvadeReason why)
{
TempSummon meSummon = me.ToTempSummon();
if (meSummon)
{
Creature summoner = meSummon.GetSummonerCreatureBase();
if (summoner)
summoner.GetAI().DoAction(ActionIds.PetEvade);
else
me.DespawnOrUnsummon();
return;
}
base.EnterEvadeMode(why);
}
protected InstanceScript _instance;
uint _petGroup;
bool _isWatcher;
}
[Script]
class npc_watcher_gashra : npc_gatewatcher_petAI
{
public npc_watcher_gashra(Creature creature) : base(creature, true)
{
me.SetReactState(ReactStates.Passive);
}
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
{
DoCastSelf(SpellIds.Enrage);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(19), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f);
if (target)
DoCast(target, SpellIds.WebWrap);
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
{
DoCastVictim(SpellIds.InfectedBite);
task.Repeat(TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(27));
});
}
public override void JustDied(Unit killer)
{
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (krikthir && krikthir.IsAlive())
krikthir.GetAI().DoAction(ActionIds.GashraDied);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_watcher_narjil : npc_gatewatcher_petAI
{
public npc_watcher_narjil(Creature creature) : base(creature, true) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(18), task =>
{
DoCastVictim(SpellIds.BlindingWebs);
task.Repeat(TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(27));
});
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
DoCast(target, SpellIds.WebWrap);
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
{
DoCastVictim(SpellIds.InfectedBite);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
});
}
public override void JustDied(Unit killer)
{
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (krikthir && krikthir.IsAlive())
krikthir.GetAI().DoAction(ActionIds.NarjilDied);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_watcher_silthik : npc_gatewatcher_petAI
{
public npc_watcher_silthik(Creature creature) : base(creature, true) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.PoisonSpray);
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(11), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
DoCast(target, SpellIds.WebWrap);
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(17));
});
_scheduler.Schedule(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.InfectedBite);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(24));
});
}
public override void JustDied(Unit killer)
{
Creature krikthir = _instance.GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (krikthir && krikthir.IsAlive())
krikthir.GetAI().DoAction(ActionIds.SilthikDied);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_anub_ar_warrior : npc_gatewatcher_petAI
{
public npc_anub_ar_warrior(Creature creature) : base(creature, false) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9), task =>
{
DoCastVictim(SpellIds.Cleave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), task =>
{
DoCastVictim(SpellIds.Strike);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_anub_ar_skirmisher : npc_gatewatcher_petAI
{
public npc_anub_ar_skirmisher(Creature creature) : base(creature, false) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(8), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.Charge);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9), task =>
{
if (me.GetVictim() && me.GetVictim().IsInBack(me))
DoCastVictim(SpellIds.Backstab);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(13));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.Charge && target)
DoCast(target, SpellIds.FixtateTrigger);
}
}
[Script]
class npc_anub_ar_shadowcaster : npc_gatewatcher_petAI
{
public npc_anub_ar_shadowcaster(Creature creature) : base(creature, false) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void _EnterCombat()
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f, true);
if (target)
DoCast(target, SpellIds.ShadowBolt);
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4));
});
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14), task =>
{
DoCastVictim(SpellIds.ShadowNova);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_skittering_swarmer : ScriptedAI
{
public npc_skittering_swarmer(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
Creature gatewatcher = me.GetInstanceScript().GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (gatewatcher)
{
Unit target = gatewatcher.GetAttackerForHelper();
if (target)
AttackStart(target);
gatewatcher.GetAI().JustSummoned(me);
}
}
}
[Script]
class npc_skittering_infector : ScriptedAI
{
public npc_skittering_infector(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
Creature gatewatcher = me.GetInstanceScript().GetCreature(ANDataTypes.KrikthirTheGatewatcher);
if (gatewatcher)
{
Unit target = gatewatcher.GetAttackerForHelper();
if (target)
AttackStart(target);
gatewatcher.GetAI().JustSummoned(me);
}
}
public override void JustDied(Unit killer)
{
DoCastAOE(SpellIds.AcidSplash);
base.JustDied(killer);
}
}
[Script]
class npc_gatewatcher_web_wrap : NullCreatureAI
{
public npc_gatewatcher_web_wrap(Creature creature) : base(creature) { }
public override void JustDied(Unit killer)
{
TempSummon meSummon = me.ToTempSummon();
if (meSummon)
{
Unit summoner = meSummon.GetSummoner();
if (summoner)
summoner.RemoveAurasDueToSpell(SpellIds.WebWrapWrapped);
}
}
}
[Script]
class spell_gatewatcher_subboss_trigger : SpellScript
{
void HandleTargets(List<WorldObject> targetList)
{
// Remove any Watchers that are already in combat
for (var i = 0; i < targetList.Count; ++i)
{
Creature creature = targetList[i].ToCreature();
if (creature)
if (creature.IsAlive() && !creature.IsInCombat())
continue;
targetList.RemoveAt(i);
}
// Default to Krik'thir himself if he isn't engaged
WorldObject target = null;
if (GetCaster() && !GetCaster().IsInCombat())
target = GetCaster();
// Unless there are Watchers that aren't engaged yet
if (!targetList.Empty())
{
// If there are, pick one of them at random
target = targetList.SelectRandom();
}
// And hit only that one
targetList.Clear();
if (target)
targetList.Add(target);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(HandleTargets, 0, Targets.UnitSrcAreaEntry));
}
}
[Script]
class spell_anub_ar_skirmisher_fixtate : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.FixtateTriggered);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.CastSpell(GetCaster(), SpellIds.FixtateTriggered, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_gatewatcher_web_wrap : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.WebWrapWrapped);
}
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Expire)
return;
Unit target = GetTarget();
if (target)
target.CastSpell(target, SpellIds.WebWrapWrapped, true);
}
public override void Register()
{
OnEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.ModRoot, AuraEffectHandleModes.Real));
}
}
[Script]
class achievement_watch_him_die : AchievementCriteriaScript
{
public achievement_watch_him_die() : base("achievement_watch_him_die") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
InstanceScript instance = target.GetInstanceScript();
if (instance == null)
return false;
foreach (uint watcherData in new[] { ANDataTypes.WatcherGashra, ANDataTypes.WatcherNarjil, ANDataTypes.WatcherSilthik })
{
Creature watcher = instance.GetCreature(watcherData);
if (watcher)
if (watcher.IsAlive())
continue;
return false;
}
return true;
}
}
}
@@ -1,943 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Combat;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub.Nadronox
{
struct SpellIds
{
// Hadronox
public const uint WebFrontDoors = 53177;
public const uint WebSideDoors = 53185;
public const uint LeechPoison = 53030;
public const uint LeechPoisonHeal = 53800;
public const uint AcidCloud = 53400;
public const uint WebGrab = 57731;
public const uint PierceArmor = 53418;
// Anub'Ar Opponent Summoning Spells
public const uint SummonChampionPeriodic = 53035;
public const uint SummonCryptFiendPeriodic = 53037;
public const uint SummonNecromancerPeriodic = 53036;
public const uint SummonChampionTop = 53064;
public const uint SummonCryptFiendTop = 53065;
public const uint SummonNecromancerTop = 53066;
public const uint SummonChampionBottom = 53090;
public const uint SummonCryptFiendBottom = 53091;
public const uint SummonNecromancerBottom = 53092;
// Anub'Ar Crusher
public const uint Smash = 53318;
public const uint Frenzy = 53801;
// Anub'Ar Foes - Shared
public const uint Taunt = 53798;
// Anub'Ar Champion
public const uint Rend = 59343;
public const uint Pummel = 59344;
// Anub'Ar Crypt Guard
public const uint CrushingWebs = 59347;
public const uint InfectedWound = 59348;
// Anub'Ar Necromancer
public const uint ShadowBolt = 53333;
public const uint AnimateBones1 = 53334;
public const uint AnimateBones2 = 53336;
}
enum SummonGroups
{
Crusher1 = 1,
Crusher2 = 2,
Crusher3 = 3
}
struct ActionIds
{
public const int HadronoxMove = 1;
public const int CrusherEngaged = 2;
public const int PackWalk = 3;
}
struct Data
{
public const uint CrusherPackId = 1;
public const uint HadronoxEnteredCombat = 2;
public const uint HadronoxWebbedDoors = 3;
}
struct CreatureIds
{
public const uint Crusher = 28922;
public const uint WorldtriggerLarge = 23472;
}
struct TextIds
{
public const uint SayCrusherAggro = 1;
public const uint EmoteCrusherFrenzy = 2;
public const uint EmoteHadronoxMove = 1;
}
// Movement IDs used by the permanently spawning Anub'ar opponents - they are done in sequence, as one finishes, the next one starts
enum MovementIds
{
None = 0,
Outside,
Downstairs,
Downstairs2,
Hadronox, // this one might have us take a detour to avoid pathfinding "through" the floor...
HadronoxReal // while this one will always make us movechase
}
struct Misc
{
public static Position[] hadronoxStep =
{
new Position(515.5848f, 544.2007f, 673.6272f),
new Position(562.191f , 514.068f , 696.4448f),
new Position(610.3828f, 518.6407f, 695.9385f),
new Position(530.42f , 560.003f, 733.0308f)
};
public static Position[] crusherWaypoints =
{
new Position(529.6913f, 547.1257f, 731.9155f, 4.799650f),
new Position(517.51f , 561.439f , 734.0306f, 4.520403f),
new Position(543.414f , 551.728f , 732.0522f, 3.996804f)
};
public static Position[] championWaypoints =
{
new Position(539.2076f, 549.7539f, 732.8668f, 4.55531f),
new Position(527.3098f, 559.5197f, 732.9407f, 4.742493f),
new Position()
};
public static Position[] cryptFiendWaypoints =
{
new Position(520.3911f, 548.7895f, 732.0118f, 5.0091f),
new Position(),
new Position(550.9611f, 545.1674f, 731.9031f, 3.996804f)
};
public static Position[] necromancerWaypoints =
{
new Position(),
new Position(507.6937f, 563.3471f, 734.8986f, 4.520403f),
new Position(535.1049f, 552.8961f, 732.8441f, 3.996804f),
};
public static Position[] initialMoves =
{
new Position(485.314606f, 611.418640f, 771.428406f),
new Position(575.760437f, 611.516418f, 771.427368f),
new Position(588.930725f, 598.233276f, 739.142151f)
};
public static Position[] downstairsMoves =
{
new Position(513.574341f, 587.022156f, 736.229065f),
new Position(537.920410f, 580.436157f, 732.796692f),
new Position(601.289246f, 583.259644f, 725.443054f),
};
public static Position[] downstairsMoves2 =
{
new Position(571.498718f, 576.978333f, 727.582947f),
new Position(571.498718f, 576.978333f, 727.582947f),
new Position()
};
}
[Script]
class boss_hadronox : BossAI
{
public boss_hadronox(Creature creature) : base(creature, ANDataTypes.Hadronox) { }
bool IsInCombatWithPlayer()
{
List<HostileReference> refs = me.GetThreatManager().GetThreatList();
foreach (HostileReference hostileRef in refs)
{
Unit target = hostileRef.GetTarget();
if (target)
if (target.IsControlledByPlayer())
return true;
}
return false;
}
void SetStep(byte step)
{
if (_lastPlayerCombatState)
return;
_step = step;
me.SetHomePosition(Misc.hadronoxStep[step]);
me.GetMotionMaster().Clear();
me.AttackStop();
SetCombatMovement(false);
me.GetMotionMaster().MovePoint(0, Misc.hadronoxStep[step]);
}
void SummonCrusherPack(SummonGroups group)
{
List<TempSummon> summoned;
me.SummonCreatureGroup((byte)group, out summoned);
foreach (TempSummon summon in summoned)
{
summon.GetAI().SetData(Data.CrusherPackId, (uint)group);
summon.GetAI().DoAction(ActionIds.PackWalk);
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point)
return;
SetCombatMovement(true);
AttackStart(me.GetVictim());
if (_step < Misc.hadronoxStep.Length - 1)
return;
DoCastAOE(SpellIds.WebFrontDoors);
DoCastAOE(SpellIds.WebSideDoors);
_doorsWebbed = true;
DoZoneInCombat();
}
public override uint GetData(uint data)
{
if (data == Data.HadronoxEnteredCombat)
return _enteredCombat ? 1 : 0u;
if (data == Data.HadronoxWebbedDoors)
return _doorsWebbed ? 1 : 0u;
return 0;
}
public override bool CanAIAttack(Unit target)
{
// Prevent Hadronox from going too far from her current home position
if (!target.IsControlledByPlayer() && target.GetDistance(me.GetHomePosition()) > 20.0f)
return false;
return base.CanAIAttack(target);
}
public override void EnterCombat(Unit who)
{
_scheduler.CancelAll();
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(7), task =>
{
DoCastAOE(SpellIds.LeechPoison);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(9));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(13), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100.0f);
if (target)
DoCast(target, SpellIds.AcidCloud);
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(23));
});
_scheduler.Schedule(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(19), task =>
{
DoCastAOE(SpellIds.WebGrab);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(7), task =>
{
DoCastVictim(SpellIds.PierceArmor);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
{
if (IsInCombatWithPlayer() != _lastPlayerCombatState)
{
_lastPlayerCombatState = !_lastPlayerCombatState;
if (_lastPlayerCombatState) // we are now in combat with players
{
if (!instance.CheckRequiredBosses(ANDataTypes.Hadronox))
{
EnterEvadeMode(EvadeReason.SequenceBreak);
return;
}
// cancel current point movement if engaged by players
if (me.GetMotionMaster().GetCurrentMovementGeneratorType() == MovementGeneratorType.Point)
{
me.GetMotionMaster().Clear();
SetCombatMovement(true);
AttackStart(me.GetVictim());
}
}
else // we are no longer in combat with players - reset the encounter
EnterEvadeMode(EvadeReason.NoHostiles);
}
task.Repeat(TimeSpan.FromSeconds(1));
});
me.SetActive(true);
}
public override void DoAction(int action)
{
switch (action)
{
case ActionIds.CrusherEngaged:
if (_enteredCombat)
break;
instance.SetBossState(ANDataTypes.Hadronox, EncounterState.InProgress);
_enteredCombat = true;
SummonCrusherPack(SummonGroups.Crusher2);
SummonCrusherPack(SummonGroups.Crusher3);
break;
case ActionIds.HadronoxMove:
if (_step < Misc.hadronoxStep.Length - 1)
{
SetStep((byte)(_step + 1));
Talk(TextIds.EmoteHadronoxMove);
}
break;
}
}
public override void EnterEvadeMode(EvadeReason why)
{
List<Creature> triggers = new List<Creature>();
me.GetCreatureListWithEntryInGrid(triggers, CreatureIds.WorldtriggerLarge);
foreach (Creature trigger in triggers)
{
if (trigger.HasAura(SpellIds.SummonChampionPeriodic) || trigger.HasAura(SpellIds.WebFrontDoors) || trigger.HasAura(SpellIds.WebSideDoors))
_DespawnAtEvade(25, trigger);
}
_DespawnAtEvade(25);
summons.DespawnAll();
foreach (ObjectGuid gNerubian in _anubar)
{
Creature nerubian = ObjectAccessor.GetCreature(me, gNerubian);
if (nerubian)
nerubian.DespawnOrUnsummon();
}
}
public override void SetGUID(ObjectGuid guid, int what)
{
_anubar.Add(guid);
}
public void Initialize()
{
me.SetBoundingRadius(9.0f);
me.SetCombatReach(9.0f);
_enteredCombat = false;
_doorsWebbed = false;
_lastPlayerCombatState = false;
SetStep(0);
SetCombatMovement(true);
SummonCrusherPack(SummonGroups.Crusher1);
}
public override void InitializeAI()
{
base.InitializeAI();
if (me.IsAlive())
Initialize();
}
public override void JustAppeared()
{
base.JustAppeared();
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
// Safeguard to prevent Hadronox dying to NPCs
public override void DamageTaken(Unit who, ref uint damage)
{
if (!who.IsControlledByPlayer() && me.HealthBelowPct(70))
{
if (me.HealthBelowPctDamaged(5, damage))
damage = 0;
else
damage *= (uint)((me.GetHealthPct() - 5.0f) / 65.0f);
}
}
public override void JustSummoned(Creature summon)
{
summons.Summon(summon);
// Do not enter combat with zone
}
bool _enteredCombat; // has a player entered combat with the first crusher pack? (talk and spawn two more packs)
bool _doorsWebbed; // obvious - have we reached the top and webbed the doors shut? (trigger for hadronox denied achievement)
bool _lastPlayerCombatState; // was there a player in our threat list the last time we checked (we check every second)
byte _step;
List<ObjectGuid> _anubar = new List<ObjectGuid>();
}
class npc_hadronox_crusherPackAI : ScriptedAI
{
public npc_hadronox_crusherPackAI(Creature creature, Position[] positions) : base(creature)
{
_instance = creature.GetInstanceScript();
_positions = positions;
_myPack = 0;
_doFacing = false;
}
public override void DoAction(int action)
{
if (action == ActionIds.PackWalk)
{
switch (_myPack)
{
case SummonGroups.Crusher1:
case SummonGroups.Crusher2:
case SummonGroups.Crusher3:
me.GetMotionMaster().MovePoint(ActionIds.PackWalk, _positions[_myPack - SummonGroups.Crusher1]);
break;
default:
break;
}
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type == MovementGeneratorType.Point && id == ActionIds.PackWalk)
_doFacing = true;
}
public override void EnterEvadeMode(EvadeReason why)
{
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
if (hadronox)
hadronox.GetAI().EnterEvadeMode(EvadeReason.Other);
}
public override uint GetData(uint data)
{
if (data == Data.CrusherPackId)
return (uint)_myPack;
return 0;
}
public override void SetData(uint data, uint value)
{
if (data == Data.CrusherPackId)
{
_myPack = (SummonGroups)value;
me.SetReactState(_myPack != 0 ? ReactStates.Passive : ReactStates.Aggressive);
}
}
public override void EnterCombat(Unit who)
{
if (me.HasReactState(ReactStates.Passive))
{
List<Creature> others = new List<Creature>();
me.GetCreatureListWithEntryInGrid(others, 0, 40.0f);
foreach (Creature other in others)
{
if (other.GetAI().GetData(Data.CrusherPackId) == (uint)_myPack)
{
other.SetReactState(ReactStates.Aggressive);
other.GetAI().AttackStart(who);
}
}
}
_EnterCombat();
base.EnterCombat(who);
}
public virtual void _EnterCombat() { }
public override void MoveInLineOfSight(Unit who)
{
if (!me.HasReactState(ReactStates.Passive))
{
base.MoveInLineOfSight(who);
return;
}
if (me.CanStartAttack(who, false) && me.IsWithinDistInMap(who, me.GetAttackDistance(who) + me.m_CombatDistance))
EnterCombat(who);
}
public override void UpdateAI(uint diff)
{
if (_doFacing)
{
_doFacing = false;
me.SetFacingTo(_positions[_myPack - SummonGroups.Crusher1].GetOrientation());
}
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
protected InstanceScript _instance;
Position[] _positions;
protected SummonGroups _myPack;
bool _doFacing;
}
[Script]
class npc_anub_ar_crusher : npc_hadronox_crusherPackAI
{
public npc_anub_ar_crusher(Creature creature) : base(creature, Misc.crusherWaypoints) { }
public override void _EnterCombat()
{
_scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.Smash);
task.Repeat(TimeSpan.FromSeconds(13), TimeSpan.FromSeconds(21));
});
if (_myPack != SummonGroups.Crusher1)
return;
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
if (hadronox)
{
if (hadronox.GetAI().GetData(Data.HadronoxEnteredCombat) != 0)
return;
hadronox.GetAI().DoAction(ActionIds.CrusherEngaged);
}
Talk(TextIds.SayCrusherAggro);
}
public override void DamageTaken(Unit source, ref uint damage)
{
if (_hadFrenzy || !me.HealthBelowPctDamaged(25, damage))
return;
_hadFrenzy = true;
Talk(TextIds.EmoteCrusherFrenzy);
DoCastSelf(SpellIds.Frenzy);
}
public override void JustDied(Unit killer)
{
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
if (hadronox)
hadronox.GetAI().DoAction(ActionIds.HadronoxMove);
base.JustDied(killer);
}
bool _hadFrenzy;
}
[Script]
class npc_anub_ar_crusher_champion : npc_hadronox_crusherPackAI
{
public npc_anub_ar_crusher_champion(Creature creature) : base(creature, Misc.championWaypoints) { }
public override void _EnterCombat()
{
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(SpellIds.Rend);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.Pummel);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(17));
});
}
}
[Script]
class npc_anub_ar_crusher_crypt_fiend : npc_hadronox_crusherPackAI
{
public npc_anub_ar_crusher_crypt_fiend(Creature creature) : base(creature, Misc.cryptFiendWaypoints) { }
public override void _EnterCombat()
{
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(SpellIds.CrushingWebs);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.InfectedWound);
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(25));
});
}
}
[Script]
class npc_anub_ar_crusher_necromancer : npc_hadronox_crusherPackAI
{
public npc_anub_ar_crusher_necromancer(Creature creature) : base(creature, Misc.necromancerWaypoints) { }
public override void _EnterCombat()
{
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), task =>
{
DoCastVictim(SpellIds.ShadowBolt);
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(37), TimeSpan.FromSeconds(45), task =>
{
DoCastVictim(RandomHelper.URand(0, 1) != 0 ? SpellIds.AnimateBones2 : SpellIds.AnimateBones1);
task.Repeat(TimeSpan.FromSeconds(35), TimeSpan.FromSeconds(50));
});
}
}
class npc_hadronox_foeAI : ScriptedAI
{
public npc_hadronox_foeAI(Creature creature) : base(creature)
{
_instance = creature.GetInstanceScript();
_nextMovement = MovementIds.Outside;
_mySpawn = 0;
}
public override void InitializeAI()
{
base.InitializeAI();
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
if (hadronox)
hadronox.GetAI().SetGUID(me.GetGUID());
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type == MovementGeneratorType.Point)
_nextMovement = (MovementIds)(id + 1);
}
public override void EnterEvadeMode(EvadeReason why)
{
me.DespawnOrUnsummon();
}
public override void UpdateAI(uint diff)
{
if (_nextMovement != 0)
{
switch (_nextMovement)
{
case MovementIds.Outside:
{
float dist = float.PositiveInfinity;
for (byte spawn = 0; spawn < Misc.initialMoves.Length; ++spawn)
{
float thisDist = Misc.initialMoves[spawn].GetExactDistSq(me);
if (thisDist < dist)
{
_mySpawn = spawn;
dist = thisDist;
}
}
me.GetMotionMaster().MovePoint((uint)MovementIds.Outside, Misc.initialMoves[_mySpawn], false); // do not pathfind here, we have to pass through a "wall" of webbing
break;
}
case MovementIds.Downstairs:
me.GetMotionMaster().MovePoint((uint)MovementIds.Downstairs, Misc.downstairsMoves[_mySpawn]);
break;
case MovementIds.Downstairs2:
if (Misc.downstairsMoves2[_mySpawn].GetPositionX() > 0.0f) // might be unset for this spawn - if yes, skip
{
me.GetMotionMaster().MovePoint((uint)MovementIds.Downstairs2, Misc.downstairsMoves2[_mySpawn]);
break;
}
goto case MovementIds.Hadronox;
// intentional missing break
case MovementIds.Hadronox:
case MovementIds.HadronoxReal:
{
float zCutoff = 702.0f;
Creature hadronox = _instance.GetCreature(ANDataTypes.Hadronox);
if (hadronox && hadronox.IsAlive())
{
if (_nextMovement != MovementIds.HadronoxReal)
{
if (hadronox.GetPositionZ() < zCutoff)
{
me.GetMotionMaster().MovePoint((uint)MovementIds.Hadronox, Misc.hadronoxStep[2]);
break;
}
}
AttackStart(hadronox);
}
break;
}
default:
break;
}
_nextMovement = MovementIds.None;
}
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
InstanceScript _instance;
MovementIds _nextMovement;
byte _mySpawn;
}
[Script]
class npc_anub_ar_champion : npc_hadronox_foeAI
{
public npc_anub_ar_champion(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(SpellIds.Rend);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.Pummel);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(17));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
{
DoCastVictim(SpellIds.Taunt);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
});
}
}
[Script]
class npc_anub_ar_crypt_fiend : npc_hadronox_foeAI
{
public npc_anub_ar_crypt_fiend(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
_scheduler.Schedule(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(SpellIds.CrushingWebs);
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.InfectedWound);
task.Repeat(TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
{
DoCastVictim(SpellIds.Taunt);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
});
}
}
[Script]
class npc_anub_ar_necromancer : npc_hadronox_foeAI
{
public npc_anub_ar_necromancer(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(4), task =>
{
DoCastVictim(SpellIds.ShadowBolt);
task.Repeat(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(37), TimeSpan.FromSeconds(45), task =>
{
DoCastVictim(RandomHelper.URand(0, 1) != 0 ? SpellIds.AnimateBones2 : SpellIds.AnimateBones1);
task.Repeat(TimeSpan.FromSeconds(35), TimeSpan.FromSeconds(50));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50), task =>
{
DoCastVictim(SpellIds.Taunt);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(50));
});
}
}
[Script("spell_hadronox_periodic_summon_champion", SpellIds.SummonChampionTop, SpellIds.SummonChampionBottom)]
[Script("spell_hadronox_periodic_summon_crypt_fiend", SpellIds.SummonCryptFiendTop, SpellIds.SummonCryptFiendBottom)]
[Script("spell_hadronox_periodic_summon_necromancer", SpellIds.SummonNecromancerTop, SpellIds.SummonNecromancerBottom)]
class spell_hadronox_periodic_summon_template : AuraScript
{
public spell_hadronox_periodic_summon_template(uint topSpellId, uint bottomSpellId)
{
_topSpellId = topSpellId;
_bottomSpellId = bottomSpellId;
}
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(_topSpellId, _bottomSpellId);
}
void HandleApply(AuraEffect eff, AuraEffectHandleModes mode)
{
AuraEffect effect = GetAura().GetEffect(0);
if (effect != null)
effect.SetPeriodicTimer(RandomHelper.IRand(2, 17) * Time.InMilliseconds);
}
void HandlePeriodic(AuraEffect eff)
{
Unit caster = GetCaster();
if (!caster)
return;
InstanceScript instance = caster.GetInstanceScript();
if (instance == null)
return;
if (instance.GetBossState(ANDataTypes.Hadronox) == EncounterState.Done)
GetAura().Remove();
else
{
if (caster.GetPositionZ() >= 750.0f)
caster.CastSpell(caster, _topSpellId, true);
else
caster.CastSpell(caster, _bottomSpellId, true);
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(HandleApply, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodic, 0, AuraType.PeriodicDummy));
}
uint _topSpellId;
uint _bottomSpellId;
}
[Script]
class spell_hadronox_leeching_poison : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.LeechPoisonHeal);
}
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() != AuraRemoveMode.Death)
return;
if (GetTarget().IsGuardian())
return;
Unit caster = GetCaster();
if (caster)
caster.CastSpell(caster, SpellIds.LeechPoisonHeal, true);
}
public override void Register()
{
OnEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.PeriodicLeech, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_hadronox_web_doors : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.SummonChampionPeriodic, SpellIds.SummonCryptFiendPeriodic, SpellIds.SummonNecromancerPeriodic);
}
void HandleDummy(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
{
target.RemoveAurasDueToSpell(SpellIds.SummonChampionPeriodic);
target.RemoveAurasDueToSpell(SpellIds.SummonCryptFiendPeriodic);
target.RemoveAurasDueToSpell(SpellIds.SummonNecromancerPeriodic);
}
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleDummy, 0, SpellEffectName.ApplyAura));
}
}
[Script]
class achievement_hadronox_denied : AchievementCriteriaScript
{
public achievement_hadronox_denied() : base("achievement_hadronox_denied") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature cTarget = target.ToCreature();
if (cTarget)
if (cTarget.GetAI().GetData(Data.HadronoxWebbedDoors) == 0)
return true;
return false;
}
}
}
@@ -1,170 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Northrend.AzjolNerub.AzjolNerub
{
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;
public const uint AnubarakWall2 = 7;
public const uint GatewatcherGreet = 8;
}
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.AnubarakDoor1, ANDataTypes.AnubarakWall),
new ObjectData(ANGameObjectIds.AnubarakDoor3, ANDataTypes.AnubarakWall2)
};
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))
};
}
[Script]
class instance_azjol_nerub : InstanceMapScript
{
public instance_azjol_nerub() : base(nameof(instance_azjol_nerub), 601) { }
class instance_azjol_nerub_InstanceScript : InstanceScript
{
uint _gateWatcherGreet;
public instance_azjol_nerub_InstanceScript(InstanceMap 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 bool CheckRequiredBosses(uint bossId, Player player)
{
if (_SkipCheckRequiredBosses(player))
return true;
if (bossId > ANDataTypes.KrikthirTheGatewatcher && GetBossState(ANDataTypes.KrikthirTheGatewatcher) != EncounterState.Done)
return false;
return true;
}
public override uint GetData(uint dataId)
{
switch (dataId)
{
case ANDataTypes.GatewatcherGreet:
return _gateWatcherGreet;
default:
return 0;
}
}
public override void SetData(uint dataId, uint value)
{
switch (dataId)
{
case ANDataTypes.GatewatcherGreet:
_gateWatcherGreet = value;
break;
default:
break;
}
}
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_azjol_nerub_InstanceScript(map);
}
}
}
@@ -1,650 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using 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;
}
[Script]
class generic_vehicleAI_toc5 : EscortAI
{
public generic_vehicleAI_toc5(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, uint pathId)
{
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))
{
ResetThreatList();
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;
}
abstract class boss_basic_toc5AI : ScriptedAI
{
protected 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.AddUnitFlag(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 && 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)
{
AggroAllPlayers(me);
uiPhase = 0;
}
}
else
uiPhaseTimer -= diff;
}
public bool InVehicle()
{
return !me.m_movementInfo.transport.guid.IsEmpty();
}
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.RemoveUnitFlag(UnitFlags.NonAttackable | UnitFlags.ImmuneToPc);
temp.SetReactState(ReactStates.Aggressive);
temp.SetInCombatWith(player);
player.SetInCombatWith(temp);
temp.GetThreatManager().AddThreat(player, 0.0f);
}
}
}
}
bool GrandChampionsOutVehicle(Creature creature)
{
InstanceScript instance = creature.GetInstanceScript();
if (instance == null)
return false;
Creature pGrandChampion1 = ObjectAccessor.GetCreature(creature, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_1));
Creature pGrandChampion2 = ObjectAccessor.GetCreature(creature, instance.GetGuidData((uint)Data64.DATA_GRAND_CHAMPION_2));
Creature pGrandChampion3 = ObjectAccessor.GetCreature(creature, 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;
}
public TaskScheduler NonCombatEvents = new TaskScheduler();
public InstanceScript instance;
public byte uiPhase;
public uint uiPhaseTimer;
bool bDone;
public bool bHome;
}
[Script]
// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
class boss_warrior_toc5 : boss_basic_toc5AI
{
public boss_warrior_toc5(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))
{
ResetThreatList();
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();
}
}
[Script]
// Ambrose Boltspark && Eressea Dawnsinger || Mage
class boss_mage_toc5 : boss_basic_toc5AI
{
public boss_mage_toc5(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();
}
}
[Script]
// Colosos && Runok Wildmane || Shaman
class boss_shaman_toc5 : boss_basic_toc5AI
{
public boss_shaman_toc5(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();
}
}
[Script]
// Jaelyne Evensong && Zul'tore || Hunter
class boss_hunter_toc5 : boss_basic_toc5AI
{
public boss_hunter_toc5(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.MaxDistance, 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 uiTarget = Global.ObjAccessor.GetUnit(me, uiTargetGUID);
if (uiTarget && me.IsInRange(uiTarget, 5.0f, 30.0f, false))
{
DoCast(uiTarget, 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();
}
}
[Script]
// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
class boss_rouge_toc5 : boss_basic_toc5AI
{
public boss_rouge_toc5(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();
}
}
}
@@ -1,334 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using 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) { }
class instance_trial_of_the_champion_InstanceMapScript : InstanceScript
{
public instance_trial_of_the_champion_InstanceMapScript(InstanceMap 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.AddNpcFlag(NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.CHAMPIONS_LOOT_H : GameObjectIds.CHAMPIONS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.fromEulerAnglesZYX(1.42f, 0.0f, 0.0f), 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.RemoveUnitFlag(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.AddNpcFlag(NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.EADRIC_LOOT_H : GameObjectIds.EADRIC_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.fromEulerAnglesZYX(1.42f, 0.0f, 0.0f), 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.AddNpcFlag(NPCFlags.Gossip);
pAnnouncer.SummonGameObject(instance.IsHeroic() ? GameObjectIds.PALETRESS_LOOT_H : GameObjectIds.PALETRESS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, Quaternion.fromEulerAnglesZYX(1.42f, 0.0f, 0.0f), 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 =
$"T C {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;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_trial_of_the_champion_InstanceMapScript(map);
}
}
}
@@ -1,585 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.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.AddUnitFlag(UnitFlags.NonAttackable);
me.AddNpcFlag(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.RemoveNpcFlag(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.RemoveUnitFlag(UnitFlags.NonAttackable);
temp.SetReactState(ReactStates.Aggressive);
temp.SetInCombatWith(player);
player.SetInCombatWith(temp);
AddThreat(player, 0.0f, temp);
}
}
}
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.AddUnitFlag(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;
}
}
public override bool GossipHello(Player player)
{
if (((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.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);
SendGossipMenuFor(player, player.GetGossipTextId(me), me.GetGUID());
return true;
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId);
ClearGossipMenuFor(player);
if (action == eTradeskill.GossipActionInfoDef + 1)
{
CloseGossipMenuFor(player);
StartEncounter();
}
return true;
}
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);
}
}
}
@@ -1,487 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System.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 : BossAI
{
public boss_jaraxxus(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.AddUnitFlag(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, 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, 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, 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();
}
}
[Script]
class npc_legion_flame : ScriptedAI
{
public npc_legion_flame(Creature creature) : base(creature)
{
SetCombatMovement(false);
_instance = creature.GetInstanceScript();
}
public override void Reset()
{
me.AddUnitFlag(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;
}
[Script]
class npc_infernal_volcano : ScriptedAI
{
public npc_infernal_volcano(Creature creature) : base(creature)
{
_summons = new SummonList(me);
SetCombatMovement(false);
}
public override void Reset()
{
me.SetReactState(ReactStates.Passive);
if (!IsHeroic())
me.AddUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
else
me.RemoveUnitFlag(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;
}
[Script]
class npc_fel_infernal : ScriptedAI
{
public npc_fel_infernal(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;
}
[Script]
class npc_nether_portal : ScriptedAI
{
public npc_nether_portal(Creature creature) : base(creature)
{
_summons = new SummonList(me);
}
public override void Reset()
{
me.SetReactState(ReactStates.Passive);
if (!IsHeroic())
me.AddUnitFlag(UnitFlags.NonAttackable | UnitFlags.NotSelectable | UnitFlags.Pacified);
else
me.RemoveUnitFlag(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;
}
[Script]
class npc_mistress_of_pain : ScriptedAI
{
public npc_mistress_of_pain(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;
}
[Script]
class spell_mistress_kiss : 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));
}
}
[Script]
class spell_mistress_kiss_area : 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.SelectRandom();
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));
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,409 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Maps;
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 Counter = 8;
public const uint Event = 9;
public const uint EventTimer = 101;
public const uint EventNpc = 102;
public const uint NorthrendBeasts = 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
}
public 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;
}
}
-203
View File
@@ -1,203 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using 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 : ScriptedAI
{
public npc_mageguard_dalaran(Creature creature) : base(creature)
{
creature.AddUnitFlag(UnitFlags.NonAttackable);
creature.ApplySpellImmune(0, SpellImmunity.Damage, (uint)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) { }
}
[Script]
class npc_minigob_manabonk : ScriptedAI
{
public npc_minigob_manabonk(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.SelectRandom();
}
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;
}
});
}
}
}
@@ -1,251 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
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 : BossAI
{
public boss_king_dred(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.GetCombatReach() / 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;
}
[Script]
class npc_drakkari_gutripper : ScriptedAI
{
public npc_drakkari_gutripper(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;
}
[Script]
class npc_drakkari_scytheclaw : ScriptedAI
{
public npc_drakkari_scytheclaw(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;
}
[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;
}
}
}
@@ -1,410 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.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 : BossAI
{
public boss_novos(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.HasUnitFlag(UnitFlags.NonAttackable))
me.RemoveUnitFlag(UnitFlags.NonAttackable);
if (me.HasUnitState(UnitState.Casting))
me.CastStop();
}
else
{
if (!me.HasUnitFlag(UnitFlags.NonAttackable))
me.AddUnitFlag(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;
}
[Script]
class npc_crystal_channel_target : ScriptedAI
{
public npc_crystal_channel_target(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;
}
[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 : 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));
}
}
}
@@ -1,231 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.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 : BossAI
{
public boss_tharon_ja(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();
}
}
[Script]
class spell_tharon_ja_clear_gift_of_tharon_ja : 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));
}
}
}
@@ -1,283 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.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 : BossAI
{
public boss_trollgore(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;
}
[Script]
class npc_drakkari_invader : ScriptedAI
{
public npc_drakkari_invader(Creature creature) : base(creature) { }
public override void MovementInform(MovementGeneratorType type, uint pointId)
{
if (type == MovementGeneratorType.Point && pointId == Misc.PointLanding)
{
me.Dismount();
me.RemoveUnitFlag(UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc);
DoCastAOE(SpellIds.InvaderTaunt);
}
}
}
[Script] // 49380, 59803 - Consume
class spell_trollgore_consume : 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));
}
}
[Script] // 49555, 59807 - Corpse Explode
class spell_trollgore_corpse_explode : 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));
}
}
[Script] // 49405 - Invader Taunt Trigger
class spell_trollgore_invader_taunt : 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));
}
}
[Script]
class achievement_consumption_junction : AchievementCriteriaScript
{
public achievement_consumption_junction() : base("achievement_consumption_junction") { }
public override bool OnCheck(Player source, Unit target)
{
if (!target)
return false;
Creature Trollgore = target.ToCreature();
if (Trollgore)
if (Trollgore.GetAI().GetData(Misc.DataConsumptionJunction) != 0)
return true;
return false;
}
}
}
@@ -1,224 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using 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(InstanceMap 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);
}
}
}
@@ -1,331 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.Bronjahm
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SaySlay = 1;
public const uint SayDeath = 2;
public const uint SaySoulStorm = 3;
public const uint SayCorruptSoul = 4;
}
struct SpellIds
{
public const uint MagicSBane = 68793;
public const uint ShadowBolt = 70043;
public const uint CorruptSoul = 68839;
public const uint ConsumeSoul = 68861;
public const uint Teleport = 68988;
public const uint Fear = 68950;
public const uint Soulstorm = 68872;
public const uint SoulstormChannel = 69008; // Pre-Fight
public const uint SoulstormVisual = 68870; // Pre-Cast Soulstorm
public const uint PurpleBanishVisual = 68862; // Used By Soul Fragment (Aura)
}
struct EventIds
{
public const uint MagicBane = 1;
public const uint ShadowBolt = 2;
public const uint CorruptSoul = 3;
public const uint Soulstorm = 4;
public const uint Fear = 5;
}
struct Misc
{
public const uint DataSoulPower = 1;
public const byte Phase1 = 1;
public const byte Phase2 = 2;
public static uint[] SoulstormVisualSpells =
{
68904,
68886,
68905,
68896,
68906,
68897,
68907,
68898
};
}
[Script]
class boss_bronjahm : BossAI
{
public boss_bronjahm(Creature creature) : base(creature, DataType.Bronjahm)
{
DoCast(me, SpellIds.SoulstormChannel, true);
}
public override void Reset()
{
_Reset();
_events.SetPhase(Misc.Phase1);
_events.ScheduleEvent(EventIds.ShadowBolt, 2000);
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
}
public override void JustReachedHome()
{
_JustReachedHome();
DoCast(me, SpellIds.SoulstormChannel, true);
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
me.RemoveAurasDueToSpell(SpellIds.SoulstormChannel);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
}
public override void KilledUnit(Unit who)
{
if (who.GetTypeId() == TypeId.Player)
Talk(TextIds.SaySlay);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (_events.IsInPhase(Misc.Phase1) && !HealthAbovePct(30))
{
_events.SetPhase(Misc.Phase2);
DoCast(me, SpellIds.Teleport);
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16), 0, Misc.Phase2);
_events.ScheduleEvent(EventIds.Soulstorm, 100, 0, Misc.Phase2);
}
}
public override void JustSummoned(Creature summon)
{
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment)
{
summons.Summon(summon);
summon.SetReactState(ReactStates.Passive);
summon.GetMotionMaster().MoveFollow(me, me.GetCombatReach(), 0.0f);
summon.CastSpell(summon, SpellIds.PurpleBanishVisual, true);
}
}
public override uint GetData(uint type)
{
if (type == Misc.DataSoulPower)
{
uint count = 0;
foreach (ObjectGuid guid in summons)
{
Creature summon = ObjectAccessor.GetCreature(me, guid);
if (summon)
if (summon.GetEntry() == CreatureIds.CorruptedSoulFragment && summon.IsAlive())
++count;
}
return count;
}
return 0;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case EventIds.MagicBane:
DoCastAOE(SpellIds.MagicSBane);
_events.ScheduleEvent(EventIds.MagicBane, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(20));
break;
case EventIds.ShadowBolt:
if (_events.IsInPhase(Misc.Phase2))
{
DoCastVictim(SpellIds.ShadowBolt);
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(2));
}
else
{
if (!me.IsWithinMeleeRange(me.GetVictim()))
DoCastVictim(SpellIds.ShadowBolt);
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromMilliseconds(2));
}
break;
case EventIds.CorruptSoul:
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 0.0f, true);
if (target)
{
Talk(TextIds.SayCorruptSoul);
DoCast(target, SpellIds.CorruptSoul);
}
_events.ScheduleEvent(EventIds.CorruptSoul, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35), 0, Misc.Phase1);
break;
case EventIds.Soulstorm:
Talk(TextIds.SaySoulStorm);
me.CastSpell(me, SpellIds.SoulstormVisual, true);
me.CastSpell(me, SpellIds.Soulstorm, false);
break;
case EventIds.Fear:
me.CastCustomSpell(SpellIds.Fear, SpellValueMod.MaxTargets, 1, null, false);
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12), 0, Misc.Phase2);
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
if (!_events.IsInPhase(Misc.Phase2))
DoMeleeAttackIfReady();
}
}
[Script]
class npc_corrupted_soul_fragment : ScriptedAI
{
public npc_corrupted_soul_fragment(Creature creature) : base(creature)
{
instance = me.GetInstanceScript();
}
public override void IsSummonedBy(Unit summoner)
{
Creature bronjahm = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataType.Bronjahm));
if (bronjahm)
bronjahm.GetAI().JustSummoned(me);
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Follow)
return;
if (instance.GetGuidData(DataType.Bronjahm).GetCounter() != id)
return;
me.CastSpell((Unit)null, SpellIds.ConsumeSoul, true);
me.DespawnOrUnsummon();
}
InstanceScript instance;
}
[Script]
class spell_bronjahm_magic_bane : SpellScript
{
void RecalculateDamage()
{
if (GetHitUnit().GetPowerType() != PowerType.Mana)
return;
int maxDamage = GetCaster().GetMap().IsHeroic() ? 15000 : 10000;
int newDamage = GetHitDamage() + (GetHitUnit().GetMaxPower(PowerType.Mana) / 2);
SetHitDamage(Math.Min(maxDamage, newDamage));
}
public override void Register()
{
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
[Script]
class spell_bronjahm_consume_soul : SpellScript
{
void HandleScript(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_bronjahm_soulstorm_visual : AuraScript
{
void HandlePeriodicTick(AuraEffect aurEff)
{
PreventDefaultAction();
GetTarget().CastSpell(GetTarget(), Misc.SoulstormVisualSpells[aurEff.GetTickNumber() % 8], true);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicDummy));
}
}
[Script]
class spell_bronjahm_soulstorm_targeting : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
Unit caster = GetCaster();
targets.RemoveAll(target => caster.GetExactDist2d(target) <= 10.0f);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, SpellConst.EffectAll, Targets.UnitDestAreaEnemy));
}
}
[Script]
class achievement_bronjahm_soul_power : AchievementCriteriaScript
{
public achievement_bronjahm_soul_power() : base("achievement_bronjahm_soul_power") { }
public override bool OnCheck(Player source, Unit target)
{
return target && target.GetAI().GetData(Misc.DataSoulPower) >= 4;
}
}
}
@@ -1,414 +0,0 @@
using System;
using System.Collections.Generic;
using Game.Entities;
using Framework.Constants;
using Game.Scripting;
using Game.AI;
using Game.Spells;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.DevourerOfSouls
{
struct TextIds
{
public const uint SayFaceAggro = 0;
public const byte SayFaceAngerSlay = 1;
public const byte SayFaceSorrowSlay = 2;
public const byte SayFaceDesireSlay = 3;
public const uint SayFaceDeath = 4;
public const uint EmoteMirroredSoul = 5;
public const uint EmoteUnleashSoul = 6;
public const uint SayFaceUnleashSoul = 7;
public const uint EmoteWailingSoul = 8;
public const uint SayFaceWailingSoul = 9;
public const uint SayJainaOutro = 0;
public const uint SaySylvanasOutro = 0;
}
struct SpellIds
{
public const uint PhantomBlast = 68982;
public const uint MirroredSoulProcAura = 69023;
public const uint MirroredSoulDamage = 69034;
public const uint MirroredSoulTargetSelector = 69048;
public const uint MirroredSoulBuff = 69051;
public const uint WellOfSouls = 68820;
public const uint UnleashedSouls = 68939;
public const uint WailingSoulsStarting = 68912; // Initial Spell Cast At Begining Of Wailing Souls Phase
public const uint WailingSoulsBeam = 68875; // The Beam Visual
public const uint WailingSouls = 68873; // The Actual Spell
// 68871; 68873; 68875; 68876; 68899; 68912; 70324;
// 68899 Trigger 68871
}
struct ModelIds
{
public const uint Anger = 30148;
public const uint Sorrow = 30149;
public const uint Desire = 30150;
}
struct Misc
{
public const uint DataThreeFaced = 1;
public static outroPosition[] outroPositions =
{
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5590.47f, 2427.79f, 705.935f, 0.802851f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5593.59f, 2428.34f, 705.935f, 0.977384f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2429.31f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5600.81f, 2421.12f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.43f, 2426.53f, 705.935f, 0.890118f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5601.55f, 2418.36f, 705.935f, 1.15192f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5598, 2429.14f, 705.935f, 1.0472f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5594.04f, 2424.87f, 705.935f, 1.15192f)),
new outroPosition(CreatureIds.Champion1Alliance, CreatureIds.Champion1Horde, new Position(5597.89f, 2421.54f, 705.935f, 0.610865f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5598.57f, 2434.62f, 705.935f, 1.13446f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5585.46f, 2417.99f, 705.935f, 1.06465f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5605.81f, 2428.42f, 705.935f, 0.820305f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5591.61f, 2412.66f, 705.935f, 0.925025f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5593.9f, 2410.64f, 705.935f, 0.872665f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion2Horde, new Position(5586.76f, 2416.73f, 705.935f, 0.942478f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5592.23f, 2419.14f, 705.935f, 0.855211f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5594.61f, 2416.87f, 705.935f, 0.907571f)),
new outroPosition(CreatureIds.Champion2Alliance, CreatureIds.Champion3Horde, new Position(5589.77f, 2421.03f, 705.935f, 0.855211f)),
new outroPosition(CreatureIds.Koreln, CreatureIds.Loralen, new Position(5602.58f, 2435.95f, 705.935f, 0.959931f)),
new outroPosition(CreatureIds.Elandra, CreatureIds.Kalira, new Position(5606.13f, 2433.16f, 705.935f, 0.785398f)),
new outroPosition(CreatureIds.JainaPart2, CreatureIds.SylvanasPart2, new Position(5606.12f, 2436.6f, 705.935f, 0.890118f)),
};
public static Position CrucibleSummonPos = new Position(5672.294f, 2520.686f, 713.4386f, 0.9599311f);
}
struct outroPosition
{
public outroPosition(uint allianceEntry, uint hordeEntry, Position movePosition)
{
Entry = new uint[2];
Entry[0] = allianceEntry;
Entry[1] = hordeEntry;
MovePosition = movePosition;
}
public uint[] Entry;
public Position MovePosition;
}
[Script]
class boss_devourer_of_souls : BossAI
{
public boss_devourer_of_souls(Creature creature) : base(creature, DataType.DevourerOfSouls)
{
Initialize();
beamAngle = 0.0f;
beamAngleDiff = 0.0f;
wailingSoulTick = 0;
}
void Initialize()
{
threeFaced = true;
}
public override void Reset()
{
_Reset();
me.SetControlled(false, UnitState.Root);
me.SetDisplayId(ModelIds.Anger);
me.SetReactState(ReactStates.Aggressive);
Initialize();
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayFaceAggro);
if (!me.FindNearestCreature(CreatureIds.CrucibleOfSouls, 60)) // Prevent double spawn
me.GetMap().SummonCreature(CreatureIds.CrucibleOfSouls, Misc.CrucibleSummonPos);
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.PhantomBlast);
task.Repeat(TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
DoCastAOE(SpellIds.MirroredSoulTargetSelector);
Talk(TextIds.EmoteMirroredSoul);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.WellOfSouls);
task.Repeat(TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.UnleashedSouls);
me.SetDisplayId(ModelIds.Sorrow);
Talk(TextIds.SayFaceUnleashSoul);
Talk(TextIds.EmoteUnleashSoul);
task.Repeat(TimeSpan.FromSeconds(30));
task.Schedule(TimeSpan.FromSeconds(5), () => me.SetDisplayId(ModelIds.Anger));
});
_scheduler.Schedule(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), task =>
{
me.SetDisplayId(ModelIds.Desire);
Talk(TextIds.SayFaceWailingSoul);
Talk(TextIds.EmoteWailingSoul);
DoCast(me, SpellIds.WailingSoulsStarting);
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
{
me.SetFacingToObject(target);
DoCast(me, SpellIds.WailingSoulsBeam);
}
beamAngle = me.GetOrientation();
beamAngleDiff = (float)Math.PI / 30.0f; // PI/2 in 15 sec = PI/30 per tick
if (RandomHelper.RAND(true, false))
beamAngleDiff = -beamAngleDiff;
me.InterruptNonMeleeSpells(false);
me.SetReactState(ReactStates.Passive);
//Remove any target
me.SetTarget(ObjectGuid.Empty);
me.GetMotionMaster().Clear();
me.SetControlled(true, UnitState.Root);
wailingSoulTick = 15;
_scheduler.DelayAll(TimeSpan.FromSeconds(18)); // no other events during wailing souls
// first one after 3 secs.
_scheduler.Schedule(TimeSpan.FromSeconds(3), tickTask =>
{
beamAngle += beamAngleDiff;
me.SetFacingTo(beamAngle);
me.StopMoving();
DoCast(me, SpellIds.WailingSouls);
if (--wailingSoulTick != 0)
tickTask.Repeat(TimeSpan.FromSeconds(1));
else
{
me.SetReactState(ReactStates.Aggressive);
me.SetDisplayId(ModelIds.Anger);
me.SetControlled(false, UnitState.Root);
me.GetMotionMaster().MoveChase(me.GetVictim());
task.Repeat(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70));
}
});
});
}
public override void KilledUnit(Unit victim)
{
if (victim.GetTypeId() != TypeId.Player)
return;
byte textId = 0;
switch (me.GetDisplayId())
{
case ModelIds.Anger:
textId = TextIds.SayFaceAngerSlay;
break;
case ModelIds.Sorrow:
textId = TextIds.SayFaceSorrowSlay;
break;
case ModelIds.Desire:
textId = TextIds.SayFaceDesireSlay;
break;
default:
break;
}
if (textId != 0)
Talk(textId);
}
public override void JustDied(Unit killer)
{
_JustDied();
Position spawnPoint = new Position(5618.139f, 2451.873f, 705.854f, 0);
Talk(TextIds.SayFaceDeath);
int entryIndex;
if (instance.GetData(DataType.TeamInInstance) == (uint)Team.Alliance)
entryIndex = 0;
else
entryIndex = 1;
for (var i = 0; Misc.outroPositions[i].Entry[entryIndex] != 0; ++i)
{
Creature summon = me.SummonCreature(Misc.outroPositions[i].Entry[entryIndex], spawnPoint, TempSummonType.DeadDespawn);
if (summon)
{
summon.GetMotionMaster().MovePoint(0, Misc.outroPositions[i].MovePosition);
if (summon.GetEntry() == CreatureIds.JainaPart2)
summon.GetAI().Talk(TextIds.SayJainaOutro);
else if (summon.GetEntry() == CreatureIds.SylvanasPart2)
summon.GetAI().Talk(TextIds.SaySylvanasOutro);
}
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.PhantomBlast)
threeFaced = false;
}
public override uint GetData(uint type)
{
if (type == Misc.DataThreeFaced)
return threeFaced ? 1 : 0u;
return 0;
}
public override void UpdateAI(uint diff)
{
// Return since we have no target
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
bool threeFaced;
// wailing soul event
float beamAngle;
float beamAngleDiff;
sbyte wailingSoulTick;
}
[Script] // 69051 - Mirrored Soul
class spell_devourer_of_souls_mirrored_soul : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulProcAura);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
target.CastSpell(GetCaster(), SpellIds.MirroredSoulProcAura, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script] // 69023 - Mirrored Soul (Proc)
class spell_devourer_of_souls_mirrored_soul_proc : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulDamage);
}
bool CheckProc(ProcEventInfo eventInfo)
{
return GetCaster() && GetCaster().IsAlive();
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
DamageInfo damageInfo = eventInfo.GetDamageInfo();
if (damageInfo == null || damageInfo.GetDamage() == 0)
return;
int damage = (int)MathFunctions.CalculatePct(damageInfo.GetDamage(), 45);
GetTarget().CastCustomSpell(SpellIds.MirroredSoulDamage, SpellValueMod.BasePoint0, damage, GetCaster(), true);
}
public override void Register()
{
DoCheckProc.Add(new CheckProcHandler(CheckProc));
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.ProcTriggerSpell));
}
}
[Script] // 69048 - Mirrored Soul (Target Selector)
class spell_devourer_of_souls_mirrored_soul_target_selector : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MirroredSoulBuff);
}
void FilterTargets(List<WorldObject> targets)
{
if (targets.Empty())
return;
WorldObject target = targets.SelectRandom();
targets.Clear();
targets.Add(target);
}
void HandleScript(uint effIndex)
{
Unit target = GetHitUnit();
if (target)
GetCaster().CastSpell(target, SpellIds.MirroredSoulBuff, false);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEntry));
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class achievement_three_faced : AchievementCriteriaScript
{
public achievement_three_faced() : base("achievement_three_faced") { }
public override bool OnCheck(Player player, Unit target)
{
if (!target)
return false;
Creature devourer = target.ToCreature();
if (devourer)
if (devourer.GetAI().GetData(Misc.DataThreeFaced) != 0)
return true;
return false;
}
}
}
@@ -1,382 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls
{
struct DataType
{
// Encounter states and GUIDs
public const uint Bronjahm = 0;
public const uint DevourerOfSouls = 1;
// Additional Data
public const uint TeamInInstance = 2;
}
struct CreatureIds
{
public const uint Bronjahm = 36497;
public const uint Devourer = 36502;
public const uint CorruptedSoulFragment = 36535;
public const uint SylvanasPart1 = 37596;
public const uint SylvanasPart2 = 38161;
public const uint JainaPart1 = 37597;
public const uint JainaPart2 = 38160;
public const uint Kalira = 37583;
public const uint Elandra = 37774;
public const uint Loralen = 37779;
public const uint Koreln = 37582;
public const uint Champion1Horde = 37584;
public const uint Champion2Horde = 37587;
public const uint Champion3Horde = 37588;
public const uint Champion1Alliance = 37496;
public const uint Champion2Alliance = 37497;
public const uint CrucibleOfSouls = 37094;
}
struct EventIds
{
public const uint None = 0;
// Jaina/Sylvanas Intro
public const uint Intro1 = 1;
public const uint Intro2 = 2;
public const uint Intro3 = 3;
public const uint Intro4 = 4;
public const uint Intro5 = 5;
public const uint Intro6 = 6;
public const uint Intro7 = 7;
public const uint Intro8 = 8;
}
struct TextIds
{
public const uint SayJainaIntro1 = 0;
public const uint SayJainaIntro2 = 1;
public const uint SayJainaIntro3 = 2;
public const uint SayJainaIntro4 = 3;
public const uint SayJainaIntro5 = 4;
public const uint SayJainaIntro6 = 5;
public const uint SayJainaIntro7 = 6;
public const uint SayJainaIntro8 = 7;
public const uint SaySylvanasIntro1 = 0;
public const uint SaySylvanasIntro2 = 1;
public const uint SaySylvanasIntro3 = 2;
public const uint SaySylvanasIntro4 = 3;
public const uint SaySylvanasIntro5 = 4;
public const uint SaySylvanasIntro6 = 5;
}
struct Misc
{
public const uint MenuIdJaina = 10943;
public const uint MenuIdSylvanas = 10971;
public const uint GossipOptionId = 0;
}
enum Phase
{
Normal,
Intro,
}
[Script]
class instance_forge_of_souls : InstanceMapScript
{
public instance_forge_of_souls() : base(nameof(instance_forge_of_souls), 632) { }
class instance_forge_of_souls_InstanceScript : InstanceScript
{
public instance_forge_of_souls_InstanceScript(InstanceMap map) : base(map)
{
SetHeaders("FOS");
SetBossNumber(2);
teamInInstance = 0;
}
public override void OnPlayerEnter(Player player)
{
if (teamInInstance == 0)
teamInInstance = player.GetTeam();
}
public override void OnCreatureCreate(Creature creature)
{
if (teamInInstance == 0)
{
var players = instance.GetPlayers();
if (!players.Empty())
{
Player player = players[0];
if (player)
teamInInstance = player.GetTeam();
}
}
switch (creature.GetEntry())
{
case CreatureIds.Bronjahm:
bronjahm = creature.GetGUID();
break;
case CreatureIds.Devourer:
devourerOfSouls = creature.GetGUID();
break;
case CreatureIds.SylvanasPart1:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart1);
break;
case CreatureIds.Loralen:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Elandra);
break;
case CreatureIds.Kalira:
if (teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Koreln);
break;
}
}
public override uint GetData(uint type)
{
switch (type)
{
case DataType.TeamInInstance:
return (uint)teamInInstance;
default:
break;
}
return 0;
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataType.Bronjahm:
return bronjahm;
case DataType.DevourerOfSouls:
return devourerOfSouls;
default:
break;
}
return ObjectGuid.Empty;
}
ObjectGuid bronjahm;
ObjectGuid devourerOfSouls;
Team teamInInstance;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_forge_of_souls_InstanceScript(map);
}
}
[Script]
class npc_sylvanas_fos : ScriptedAI
{
public npc_sylvanas_fos(Creature creature) : base(creature)
{
Initialize();
me.AddNpcFlag(NPCFlags.Gossip);
}
void Initialize()
{
phase = Phase.Normal;
}
public override void Reset()
{
_events.Reset();
Initialize();
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
if (menuId == Misc.MenuIdSylvanas && gossipListId == Misc.GossipOptionId)
{
player.CLOSE_GOSSIP_MENU();
phase = Phase.Intro;
me.RemoveNpcFlag(NPCFlags.Gossip);
_events.Reset();
_events.ScheduleEvent(EventIds.Intro1, 1000);
}
return false;
}
public override void UpdateAI(uint diff)
{
if (phase == Phase.Intro)
{
_events.Update(diff);
switch (_events.ExecuteEvent())
{
case EventIds.Intro1:
Talk(TextIds.SaySylvanasIntro1);
_events.ScheduleEvent(EventIds.Intro2, 11500);
break;
case EventIds.Intro2:
Talk(TextIds.SaySylvanasIntro2);
_events.ScheduleEvent(EventIds.Intro3, 10500);
break;
case EventIds.Intro3:
Talk(TextIds.SaySylvanasIntro3);
_events.ScheduleEvent(EventIds.Intro4, 9500);
break;
case EventIds.Intro4:
Talk(TextIds.SaySylvanasIntro4);
_events.ScheduleEvent(EventIds.Intro5, 10500);
break;
case EventIds.Intro5:
Talk(TextIds.SaySylvanasIntro5);
_events.ScheduleEvent(EventIds.Intro6, 9500);
break;
case EventIds.Intro6:
Talk(TextIds.SaySylvanasIntro6);
// End of Intro
phase = Phase.Normal;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
_events.Update(diff);
DoMeleeAttackIfReady();
}
Phase phase;
}
[Script]
class npc_jaina_fos : ScriptedAI
{
public npc_jaina_fos(Creature creature) : base(creature)
{
Initialize();
me.AddNpcFlag(NPCFlags.Gossip);
}
void Initialize()
{
phase = Phase.Normal;
}
public override void Reset()
{
_events.Reset();
Initialize();
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
if (menuId == Misc.MenuIdJaina && gossipListId == Misc.GossipOptionId)
{
player.CLOSE_GOSSIP_MENU();
phase = Phase.Intro;
me.RemoveNpcFlag(NPCFlags.Gossip);
_events.Reset();
_events.ScheduleEvent(EventIds.Intro1, 1000);
}
return false;
}
public override void UpdateAI(uint diff)
{
if (phase == Phase.Intro)
{
_events.Update(diff);
switch (_events.ExecuteEvent())
{
case EventIds.Intro1:
Talk(TextIds.SayJainaIntro1);
_events.ScheduleEvent(EventIds.Intro2, 8000);
break;
case EventIds.Intro2:
Talk(TextIds.SayJainaIntro2);
_events.ScheduleEvent(EventIds.Intro3, 8500);
break;
case EventIds.Intro3:
Talk(TextIds.SayJainaIntro3);
_events.ScheduleEvent(EventIds.Intro4, 8000);
break;
case EventIds.Intro4:
Talk(TextIds.SayJainaIntro4);
_events.ScheduleEvent(EventIds.Intro5, 10000);
break;
case EventIds.Intro5:
Talk(TextIds.SayJainaIntro5);
_events.ScheduleEvent(EventIds.Intro6, 8000);
break;
case EventIds.Intro6:
Talk(TextIds.SayJainaIntro6);
_events.ScheduleEvent(EventIds.Intro7, 12000);
break;
case EventIds.Intro7:
Talk(TextIds.SayJainaIntro7);
_events.ScheduleEvent(EventIds.Intro8, 8000);
break;
case EventIds.Intro8:
Talk(TextIds.SayJainaIntro8);
// End of Intro
phase = Phase.Normal;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
_events.Update(diff);
DoMeleeAttackIfReady();
}
Phase phase;
}
}
@@ -1,305 +0,0 @@
using System;
using System.Collections.Generic;
using Game.AI;
using Game.Entities;
using Framework.Constants;
using Game.Spells;
using Game.Scripting;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossForgemasterGarfrost
{
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayPhase2 = 1;
public const uint SayPhase3 = 2;
public const uint SayDeath = 3;
public const uint SaySlay = 4;
public const uint SayThrowSaronite = 5;
public const uint SayCastDeepFreeze = 6;
public const uint SayTyrannusDeath = 0;
}
struct SpellIds
{
public const uint Permafrost = 70326;
public const uint ThrowSaronite = 68788;
public const uint ThunderingStomp = 68771;
public const uint ChillingWave = 68778;
public const uint DeepFreeze = 70381;
public const uint ForgeMace = 68785;
public const uint ForgeBlade = 68774;
public const uint PermafrostAura = 68786;
}
struct Misc
{
public const byte PhaseOne = 1;
public const byte PhaseTwo = 2;
public const byte PhaseThree = 3;
public const int EquipIdSword = 49345;
public const int EquipIdMace = 49344;
public const uint AchievDoesntGoToEleven = 0;
public const uint PointForge = 0;
public static Position northForgePos = new Position(722.5643f, -234.1615f, 527.182f, 2.16421f);
public static Position southForgePos = new Position(639.257f, -210.1198f, 529.015f, 0.523599f);
}
struct Events
{
public const uint ThrowSaronite = 1;
public const uint ChillingWave = 2;
public const uint DeepFreeze = 3;
public const uint ForgeJump = 4;
public const uint ResumeAttack = 5;
}
[Script]
class boss_garfrost : BossAI
{
public boss_garfrost(Creature creature) : base(creature, DataTypes.Garfrost) { }
public override void Reset()
{
_Reset();
_events.SetPhase(Misc.PhaseOne);
SetEquipmentSlots(true);
_permafrostStack = 0;
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Talk(TextIds.SayAggro);
DoCast(me, SpellIds.Permafrost);
me.CallForHelp(70.0f);
_events.ScheduleEvent(Events.ThrowSaronite, 7000);
}
public override void KilledUnit(Unit victim)
{
if (victim.IsPlayer())
Talk(TextIds.SaySlay);
}
public override void JustDied(Unit killer)
{
_JustDied();
Talk(TextIds.SayDeath);
me.RemoveAllGameObjects();
Creature tyrannus = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Tyrannus));
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusDeath);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (_events.IsInPhase(Misc.PhaseOne) && !HealthAbovePct(66))
{
_events.SetPhase(Misc.PhaseTwo);
Talk(TextIds.SayPhase2);
_events.DelayEvents(8000);
DoCast(me, SpellIds.ThunderingStomp);
_events.ScheduleEvent(Events.ForgeJump, 1500);
return;
}
if (_events.IsInPhase(Misc.PhaseTwo) && !HealthAbovePct(33))
{
_events.SetPhase(Misc.PhaseThree);
Talk(TextIds.SayPhase3);
_events.DelayEvents(8000);
DoCast(me, SpellIds.ThunderingStomp);
_events.ScheduleEvent(Events.ForgeJump, 1500);
return;
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Effect || id != Misc.PointForge)
return;
if (_events.IsInPhase(Misc.PhaseTwo))
{
DoCast(me, SpellIds.ForgeBlade);
SetEquipmentSlots(false, Misc.EquipIdSword);
}
if (_events.IsInPhase(Misc.PhaseThree))
{
me.RemoveAurasDueToSpell(SpellIds.ForgeBlade);
DoCast(me, SpellIds.ForgeMace);
SetEquipmentSlots(false, Misc.EquipIdMace);
}
_events.ScheduleEvent(Events.ResumeAttack, 5000);
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.PermafrostAura)
{
Aura aura = target.GetAura(SpellIds.PermafrostAura);
if (aura != null)
_permafrostStack = Math.Max(_permafrostStack, aura.GetStackAmount());
}
}
public override uint GetData(uint type)
{
return _permafrostStack;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.ThrowSaronite:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
Talk(TextIds.SayThrowSaronite, target);
DoCast(target, SpellIds.ThrowSaronite);
}
_events.ScheduleEvent(Events.ThrowSaronite, TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20));
}
break;
case Events.ChillingWave:
DoCast(me, SpellIds.ChillingWave);
_events.ScheduleEvent(Events.ChillingWave, 40000, 0, Misc.PhaseTwo);
break;
case Events.DeepFreeze:
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
Talk(TextIds.SayCastDeepFreeze, target);
DoCast(target, SpellIds.DeepFreeze);
}
_events.ScheduleEvent(Events.DeepFreeze, 35000, 0, Misc.PhaseThree);
}
break;
case Events.ForgeJump:
me.AttackStop();
if (_events.IsInPhase(Misc.PhaseTwo))
me.GetMotionMaster().MoveJump(Misc.northForgePos, 25.0f, 15.0f, Misc.PointForge);
else if (_events.IsInPhase(Misc.PhaseThree))
me.GetMotionMaster().MoveJump(Misc.southForgePos, 25.0f, 15.0f, Misc.PointForge);
break;
case Events.ResumeAttack:
if (_events.IsInPhase(Misc.PhaseTwo))
_events.ScheduleEvent(Events.ChillingWave, 5000, 0, Misc.PhaseTwo);
else if (_events.IsInPhase(Misc.PhaseThree))
_events.ScheduleEvent(Events.DeepFreeze, 10000, 0, Misc.PhaseThree);
AttackStart(me.GetVictim());
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
uint _permafrostStack;
}
[Script]
class spell_garfrost_permafrost : SpellScript
{
public spell_garfrost_permafrost()
{
prevented = false;
}
void PreventHitByLoS(SpellMissInfo missInfo)
{
if (missInfo != SpellMissInfo.None)
return;
Unit target = GetHitUnit();
if (target)
{
Unit caster = GetCaster();
//Temporary Line of Sight Check
List<GameObject> blockList = new List<GameObject>();
caster.GetGameObjectListWithEntryInGrid(blockList, GameObjectIds.SaroniteRock, 100.0f);
if (!blockList.Empty())
{
foreach (var obj in blockList)
{
if (!obj.IsInvisibleDueToDespawn())
{
if (obj.IsInBetween(caster, target, 4.0f))
{
prevented = true;
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, true);
PreventHitDefaultEffect(0);
PreventHitDefaultEffect(1);
PreventHitDefaultEffect(2);
PreventHitDamage();
break;
}
}
}
}
}
}
void RestoreImmunity()
{
Unit target = GetHitUnit();
if (target)
{
target.ApplySpellImmune(GetSpellInfo().Id, SpellImmunity.Id, GetSpellInfo().Id, false);
if (prevented)
PreventHitAura();
}
}
public override void Register()
{
BeforeHit.Add(new BeforeHitHandler(PreventHitByLoS));
AfterHit.Add(new HitHandler(RestoreImmunity));
}
bool prevented;
}
[Script]
class achievement_doesnt_go_to_eleven : AchievementCriteriaScript
{
public achievement_doesnt_go_to_eleven() : base("achievement_doesnt_go_to_eleven") { }
public override bool OnCheck(Player source, Unit target)
{
if (target)
{
Creature garfrost = target.ToCreature();
if (garfrost)
if (garfrost.GetAI().GetData(Misc.AchievDoesntGoToEleven) <= 10)
return true;
}
return false;
}
}
}
@@ -1,674 +0,0 @@
using System;
using Game.Entities;
using Game.Scripting;
using Game.AI;
using Framework.Constants;
using Game.Maps;
using Game.Spells;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron.BossKrickAndIck
{
struct SpellIds
{
public const uint MightyKick = 69021; //Ick'S Spell
public const uint ShadowBolt = 69028; //Krick'S Spell
public const uint ToxicWaste = 69024; //Krick'S Spell
public const uint ExplosiveBarrageKrick = 69012; //Special Spell 1
public const uint ExplosiveBarrageIck = 69263; //Special Spell 1
public const uint PoisonNova = 68989; //Special Spell 2
public const uint Pursuit = 68987; //Special Spell 3
public const uint ExplosiveBarrageSummon = 69015;
public const uint ExplodingOrb = 69017; //Visual On Exploding Orb
public const uint AutoGrow = 69020; //Grow Effect On Exploding Orb
public const uint HastyGrow = 44851; //Need To Check Growing Stacks
public const uint ExplosiveBarrageDamage = 69019; //Damage Done By Orb While Exploding
public const uint Strangulating = 69413; //Krick'S Selfcast In Intro
public const uint Suicide = 7;
public const uint KrickKillCredit = 71308;
public const uint NecromanticPower = 69753;
}
struct TextIds
{
// Krick
public const uint SayKrickAggro = 0;
public const uint SayKrickSlay = 1;
public const uint SayKrickBarrage1 = 2;
public const uint SayKrickBarrage2 = 3;
public const uint SayKrickPoisonNova = 4;
public const uint SayKrickChase = 5;
public const uint SayKrickOutro1 = 6;
public const uint SayKrickOutro3 = 7;
public const uint SayKrickOutro5 = 8;
public const uint SayKrickOutro8 = 9;
// Ick
public const uint SayIckPoisonNova = 0;
public const uint SayIckChase1 = 1;
// Outro
public const uint SayJaynaOutro2 = 0;
public const uint SayJaynaOutro4 = 1;
public const uint SayJaynaOutro10 = 2;
public const uint SaySylvanasOutro2 = 0;
public const uint SaySylvanasOutro4 = 1;
public const uint SaySylvanasOutro10 = 2;
public const uint SayTyrannusOutro7 = 1;
public const uint SayTyrannusOutro9 = 2;
}
struct Events
{
public const uint MightyKick = 1;
public const uint ShadowBolt = 2;
public const uint ToxicWaste = 3;
public const uint Special = 4; //Special Spell Selection (One Of Event 5; 6 Or 7)
public const uint Pursuit = 5;
public const uint PoisonNova = 6;
public const uint ExplosiveBarrage = 7;
// Krick Outro
public const uint Outro1 = 8;
public const uint Outro2 = 9;
public const uint Outro3 = 10;
public const uint Outro4 = 11;
public const uint Outro5 = 12;
public const uint Outro6 = 13;
public const uint Outro7 = 14;
public const uint Outro8 = 15;
public const uint Outro9 = 16;
public const uint Outro10 = 17;
public const uint Outro11 = 18;
public const uint Outro12 = 19;
public const uint Outro13 = 20;
public const uint OutroEnd = 21;
}
enum KrickPhase
{
Combat = 1,
Outro = 2
}
struct Misc
{
public const int ActionOutro = 1;
public const uint PointKrickIntro = 364770;
public const uint PointKrickDeath = 364771;
public static Position[] outroPos =
{
new Position(828.9342f, 118.6247f, 509.5190f, 0.0000000f), // Krick's Outro Position
new Position( 841.0100f, 196.2450f, 573.9640f, 0.2046099f), // Scourgelord Tyrannus Outro Position (Tele to...)
new Position( 777.2274f, 119.5521f, 510.0363f, 6.0562930f), // Sylvanas / Jaine Outro Spawn Position (NPC_SYLVANAS_PART1)
new Position(823.3984f, 114.4907f, 509.4899f, 0.0000000f), // Sylvanas / Jaine Outro Move Position (1)
new Position( 835.5887f, 139.4345f, 530.9526f, 0.0000000f), // Tyrannus fly down Position (not sniffed)
new Position( 828.9342f, 118.6247f, 514.5190f, 0.0000000f), // Krick's Choke Position
new Position(828.9342f, 118.6247f, 509.4958f, 0.0000000f), // Kirck's Death Position
new Position(914.4820f, 143.1602f, 633.3624f, 0.0000000f) // Tyrannus fly up (not sniffed)
};
}
[Script]
class boss_ick : BossAI
{
public boss_ick(Creature creature) : base(creature, DataTypes.Ick)
{
_tempThreat = 0;
}
public override void Reset()
{
_events.Reset();
instance.SetBossState(DataTypes.Ick, EncounterState.NotStarted);
}
Creature GetKrick()
{
return ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Krick));
}
public override void EnterCombat(Unit who)
{
_EnterCombat();
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickAggro);
_events.ScheduleEvent(Events.MightyKick, 20000);
_events.ScheduleEvent(Events.ToxicWaste, 5000);
_events.ScheduleEvent(Events.ShadowBolt, 10000);
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
}
public override void EnterEvadeMode(EvadeReason why)
{
me.GetMotionMaster().Clear();
base.EnterEvadeMode(why);
}
public override void JustDied(Unit killer)
{
Creature krick = GetKrick();
if (krick)
{
Vehicle vehicle = me.GetVehicleKit();
if (vehicle)
vehicle.RemoveAllPassengers();
if (krick.IsAIEnabled)
krick.GetAI().DoAction(Misc.ActionOutro);
}
instance.SetBossState(DataTypes.Ick, EncounterState.Done);
}
public void SetTempThreat(float threat)
{
_tempThreat = threat;
}
public void _ResetThreat(Unit target)
{
ModifyThreatByPercent(target, -100);
AddThreat(target, _tempThreat);
}
public override void UpdateAI(uint diff)
{
if (!me.IsInCombat())
return;
if (!me.GetVictim() && me.GetThreatManager().IsThreatListEmpty())
{
EnterEvadeMode(EvadeReason.NoHostiles);
return;
}
_events.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.ToxicWaste:
{
Creature krick = GetKrick();
if (krick)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
krick.CastSpell(target, SpellIds.ToxicWaste);
_events.ScheduleEvent(Events.ToxicWaste, TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(10));
}
}
break;
case Events.ShadowBolt:
{
Creature krick = GetKrick();
if (krick)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1);
if (target)
krick.CastSpell(target, SpellIds.ShadowBolt);
_events.ScheduleEvent(Events.ShadowBolt, 15000);
}
}
return;
case Events.MightyKick:
DoCastVictim(SpellIds.MightyKick);
_events.ScheduleEvent(Events.MightyKick, 25000);
return;
case Events.Special:
//select one of these three special _events
_events.ScheduleEvent(RandomHelper.RAND(Events.ExplosiveBarrage, Events.PoisonNova, Events.Pursuit), 1000);
_events.ScheduleEvent(Events.Special, TimeSpan.FromSeconds(23), TimeSpan.FromSeconds(28));
break;
case Events.ExplosiveBarrage:
{
Creature krick = GetKrick();
if (krick)
{
krick.GetAI().Talk(TextIds.SayKrickBarrage1);
krick.GetAI().Talk(TextIds.SayKrickBarrage2);
krick.CastSpell(krick, SpellIds.ExplosiveBarrageKrick, true);
DoCast(me, SpellIds.ExplosiveBarrageIck);
}
_events.DelayEvents(20000);
}
break;
case Events.PoisonNova:
{
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickPoisonNova);
Talk(TextIds.SayIckPoisonNova);
DoCast(me, SpellIds.PoisonNova);
}
break;
case Events.Pursuit:
{
Creature krick = GetKrick();
if (krick)
krick.GetAI().Talk(TextIds.SayKrickChase);
DoCast(me, SpellIds.Pursuit);
}
break;
default:
break;
}
if (me.HasUnitState(UnitState.Casting))
return;
});
DoMeleeAttackIfReady();
}
float _tempThreat;
}
[Script]
class boss_krick : ScriptedAI
{
public boss_krick(Creature creature) : base(creature)
{
_instanceScript = creature.GetInstanceScript();
_summons = new SummonList(creature);
Initialize();
}
void Initialize()
{
_phase = KrickPhase.Combat;
_outroNpcGUID.Clear();
_tyrannusGUID.Clear();
}
public override void Reset()
{
_events.Reset();
Initialize();
me.SetReactState(ReactStates.Passive);
me.AddUnitFlag(UnitFlags.NonAttackable);
}
Creature GetIck()
{
return ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.Ick));
}
public override void KilledUnit(Unit victim)
{
if (victim.IsPlayer())
Talk(TextIds.SayKrickSlay);
}
public override void JustSummoned(Creature summon)
{
_summons.Summon(summon);
if (summon.GetEntry() == CreatureIds.ExplodingOrb)
{
summon.CastSpell(summon, SpellIds.ExplodingOrb, true);
summon.CastSpell(summon, SpellIds.AutoGrow, true);
}
}
public override void DoAction(int actionId)
{
if (actionId == Misc.ActionOutro)
{
Creature tyrannusPtr = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannusPtr)
tyrannusPtr.NearTeleportTo(Misc.outroPos[1].GetPositionX(), Misc.outroPos[1].GetPositionY(), Misc.outroPos[1].GetPositionZ(), Misc.outroPos[1].GetOrientation());
else
tyrannusPtr = me.SummonCreature(CreatureIds.TyrannusEvents, Misc.outroPos[1], TempSummonType.ManualDespawn);
tyrannusPtr.SetCanFly(true);
me.GetMotionMaster().MovePoint(Misc.PointKrickIntro, Misc.outroPos[0].GetPositionX(), Misc.outroPos[0].GetPositionY(), Misc.outroPos[0].GetPositionZ());
tyrannusPtr.SetFacingToObject(me);
}
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point || id != Misc.PointKrickIntro)
return;
Talk(TextIds.SayKrickOutro1);
_phase = KrickPhase.Outro;
_events.Reset();
_events.ScheduleEvent(Events.Outro1, 1000);
}
public override void UpdateAI(uint diff)
{
if (_phase != KrickPhase.Outro)
return;
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case Events.Outro1:
{
Creature temp = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.JainaSylvanas1));
if (temp)
temp.DespawnOrUnsummon();
Creature jainaOrSylvanas = null;
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas = me.SummonCreature(CreatureIds.JainaPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
else
jainaOrSylvanas = me.SummonCreature(CreatureIds.SylvanasPart1, Misc.outroPos[2], TempSummonType.ManualDespawn);
if (jainaOrSylvanas)
{
jainaOrSylvanas.GetMotionMaster().MovePoint(0, Misc.outroPos[3]);
_outroNpcGUID = jainaOrSylvanas.GetGUID();
}
_events.ScheduleEvent(Events.Outro2, 6000);
break;
}
case Events.Outro2:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
jainaOrSylvanas.SetFacingToObject(me);
me.SetFacingToObject(jainaOrSylvanas);
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro2);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro2);
}
_events.ScheduleEvent(Events.Outro3, 5000);
}
break;
case Events.Outro3:
Talk(TextIds.SayKrickOutro3);
_events.ScheduleEvent(Events.Outro4, 18000);
break;
case Events.Outro4:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro4);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro4);
}
_events.ScheduleEvent(Events.Outro5, 5000);
}
break;
case Events.Outro5:
Talk(TextIds.SayKrickOutro5);
_events.ScheduleEvent(Events.Outro6, 1000);
break;
case Events.Outro6:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _instanceScript.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannus)
{
tyrannus.SetSpeedRate(UnitMoveType.Flight, 3.5f);
tyrannus.GetMotionMaster().MovePoint(1, Misc.outroPos[4]);
_tyrannusGUID = tyrannus.GetGUID();
}
_events.ScheduleEvent(Events.Outro7, 5000);
}
break;
case Events.Outro7:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro7);
_events.ScheduleEvent(Events.Outro8, 5000);
}
break;
case Events.Outro8:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me.AddUnitMovementFlag(MovementFlag.Flying);
me.GetMotionMaster().MovePoint(0, Misc.outroPos[5]);
DoCast(me, SpellIds.Strangulating);
_events.ScheduleEvent(Events.Outro9, 2000);
break;
case Events.Outro9:
{
Talk(TextIds.SayKrickOutro8);
// @todo Tyrannus starts killing Krick.
// there shall be some visual spell effect
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.CastSpell(me, SpellIds.NecromanticPower, true); //not sure if it's the right spell :/
_events.ScheduleEvent(Events.Outro10, 1000);
}
break;
case Events.Outro10:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me.RemoveUnitMovementFlag(MovementFlag.Flying);
me.AddUnitMovementFlag(MovementFlag.FallingFar);
me.GetMotionMaster().MovePoint(0, Misc.outroPos[6]);
_events.ScheduleEvent(Events.Outro11, 2000);
break;
case Events.Outro11:
DoCast(me, SpellIds.KrickKillCredit); // don't really know if we need it
me.SetStandState(UnitStandStateType.Dead);
me.SetHealth(0);
_events.ScheduleEvent(Events.Outro12, 3000);
break;
case Events.Outro12:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusOutro9);
_events.ScheduleEvent(Events.Outro13, 2000);
}
break;
case Events.Outro13:
{
Creature jainaOrSylvanas = ObjectAccessor.GetCreature(me, _outroNpcGUID);
if (jainaOrSylvanas)
{
if (_instanceScript.GetData(DataTypes.TeamInInstance) == (uint)Team.Alliance)
jainaOrSylvanas.GetAI().Talk(TextIds.SayJaynaOutro10);
else
jainaOrSylvanas.GetAI().Talk(TextIds.SaySylvanasOutro10);
}
// End of OUTRO. for now...
_events.ScheduleEvent(Events.OutroEnd, 3000);
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.GetMotionMaster().MovePoint(0, Misc.outroPos[7]);
}
break;
case Events.OutroEnd:
{
Creature tyrannus = ObjectAccessor.GetCreature(me, _tyrannusGUID);
if (tyrannus)
tyrannus.DespawnOrUnsummon();
me.DisappearAndDie();
}
break;
default:
break;
}
});
}
InstanceScript _instanceScript;
SummonList _summons;
KrickPhase _phase;
ObjectGuid _outroNpcGUID;
ObjectGuid _tyrannusGUID;
}
[Script]
class spell_krick_explosive_barrage : AuraScript
{
void HandlePeriodicTick(AuraEffect aurEff)
{
PreventDefaultAction();
Unit caster = GetCaster();
if (caster)
{
if (caster.IsCreature())
{
var players = caster.GetMap().GetPlayers();
foreach (var player in players)
{
if (player)
if (player.IsWithinDist(caster, 60.0f)) // don't know correct range
caster.CastSpell(player, SpellIds.ExplosiveBarrageSummon, true);
}
}
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandlePeriodicTick, 0, AuraType.PeriodicTriggerSpell));
}
}
[Script]
class spell_ick_explosive_barrage : AuraScript
{
void HandleEffectApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
if (caster.IsCreature())
caster.GetMotionMaster().MoveIdle();
}
void HandleEffectRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
{
if (caster.IsCreature())
{
caster.GetMotionMaster().Clear();
caster.GetMotionMaster().MoveChase(caster.GetVictim());
}
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(HandleEffectApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
AfterEffectRemove.Add(new EffectApplyHandler(HandleEffectRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_exploding_orb_hasty_grow : AuraScript
{
void OnStackChange(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetStackAmount() == 15)
{
Unit target = GetTarget(); // store target because aura gets removed
target.CastSpell(target, SpellIds.ExplosiveBarrageDamage, false);
target.RemoveAurasDueToSpell(SpellIds.HastyGrow);
target.RemoveAurasDueToSpell(SpellIds.AutoGrow);
target.RemoveAurasDueToSpell(SpellIds.ExplodingOrb);
Creature creature = target.ToCreature();
if (creature)
creature.DespawnOrUnsummon();
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(OnStackChange, 0, AuraType.ModScale, AuraEffectHandleModes.Reapply));
}
}
[Script]
class spell_krick_pursuit : SpellScript
{
void HandleScriptEffect(uint effIndex)
{
if (GetCaster())
{
Creature ick = GetCaster().ToCreature();
if (ick)
{
Unit target = ick.GetAI().SelectTarget(SelectAggroTarget.Random, 0, 200.0f, true);
if (target)
{
ick.GetAI().Talk(TextIds.SayIckChase1, target);
ick.AddAura(GetSpellInfo().Id, target);
ick.GetAI<boss_ick>().SetTempThreat(ick.GetThreatManager().GetThreat(target));
ick.GetThreatManager().AddThreat(target, GetEffectValue(), GetSpellInfo(), true, true);
target.GetThreatManager().AddThreat(ick, GetEffectValue(), GetSpellInfo(), true, true);
}
}
}
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_krick_pursuit_AuraScript : AuraScript
{
void HandleExtraEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
{
Creature creCaster = caster.ToCreature();
if (creCaster)
creCaster.GetAI<boss_ick>()._ResetThreat(GetTarget());
}
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(HandleExtraEffect, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_krick_pursuit_confusion : AuraScript
{
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, true);
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, true);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().ApplySpellImmune(0, SpellImmunity.State, AuraType.ModTaunt, false);
GetTarget().ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, false);
}
public override void Register()
{
OnEffectApply.Add(new EffectApplyHandler(OnApply, 2, AuraType.Linked, AuraEffectHandleModes.Real));
OnEffectRemove.Add(new EffectApplyHandler(OnRemove, 2, AuraType.Linked, AuraEffectHandleModes.Real));
}
}
}
@@ -1,345 +0,0 @@
using System.Collections.Generic;
using Game.Entities;
using Game.Scripting;
using Game.Maps;
using Framework.Constants;
using Framework.Dynamic;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
{
struct Misc
{
// positions for Martin Victus (37591) and Gorkun Ironskull (37592)
public static Position SlaveLeaderPos = new Position(689.7158f, -104.8736f, 513.7360f, 0.0f);
// position for Jaina and Sylvanas
public static Position EventLeaderPos2 = new Position(1054.368f, 107.14620f, 628.4467f, 0.0f);
public static DoorData[] Doors =
{
new DoorData(GameObjectIds.IceWall, DataTypes.Garfrost, DoorType.Passage),
new DoorData(GameObjectIds.IceWall, DataTypes.Ick, DoorType.Passage),
new DoorData(GameObjectIds.HallsOfReflectionPortcullis, DataTypes.Tyrannus, DoorType.Passage),
};
}
[Script]
class instance_pit_of_saron : InstanceMapScript
{
public instance_pit_of_saron() : base(nameof(instance_pit_of_saron), 658) { }
class instance_pit_of_saron_InstanceScript : InstanceScript
{
public instance_pit_of_saron_InstanceScript(InstanceMap map) : base(map)
{
SetHeaders("POS");
SetBossNumber(3);
LoadDoorData(Misc.Doors);
_teamInInstance = 0;
_cavernActive = 0;
_shardsHit = 0;
}
public override void OnPlayerEnter(Player player)
{
if (_teamInInstance == 0)
_teamInInstance = player.GetTeam();
}
public override void OnCreatureCreate(Creature creature)
{
if (_teamInInstance == 0)
{
var players = instance.GetPlayers();
if (!players.Empty())
{
Player player = players[0];
if (player)
_teamInInstance = player.GetTeam();
}
}
switch (creature.GetEntry())
{
case CreatureIds.Garfrost:
_garfrostGUID = creature.GetGUID();
break;
case CreatureIds.Krick:
_krickGUID = creature.GetGUID();
break;
case CreatureIds.Ick:
_ickGUID = creature.GetGUID();
break;
case CreatureIds.Tyrannus:
_tyrannusGUID = creature.GetGUID();
break;
case CreatureIds.Rimefang:
_rimefangGUID = creature.GetGUID();
break;
case CreatureIds.TyrannusEvents:
_tyrannusEventGUID = creature.GetGUID();
break;
case CreatureIds.SylvanasPart1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart1);
_jainaOrSylvanas1GUID = creature.GetGUID();
break;
case CreatureIds.SylvanasPart2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.JainaPart2);
_jainaOrSylvanas2GUID = creature.GetGUID();
break;
case CreatureIds.Kilara:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Elandra);
break;
case CreatureIds.Koralen:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Korlaen);
break;
case CreatureIds.Champion1Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion1Alliance);
break;
case CreatureIds.Champion2Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion2Alliance);
break;
case CreatureIds.Champion3Horde: // No 3rd set for Alliance?
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.Champion2Alliance);
break;
case CreatureIds.HordeSlave1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave1);
break;
case CreatureIds.HordeSlave2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave2);
break;
case CreatureIds.HordeSlave3:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave3);
break;
case CreatureIds.HordeSlave4:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.AllianceSlave4);
break;
case CreatureIds.FreedSlave1Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave1Alliance);
break;
case CreatureIds.FreedSlave2Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave2Alliance);
break;
case CreatureIds.FreedSlave3Horde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.FreedSlave3Alliance);
break;
case CreatureIds.RescuedSlaveHorde:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.RescuedSlaveAlliance);
break;
case CreatureIds.MartinVictus1:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.MartinVictus1);
break;
case CreatureIds.MartinVictus2:
if (_teamInInstance == Team.Alliance)
creature.UpdateEntry(CreatureIds.MartinVictus2);
break;
case CreatureIds.CavernEventTrigger:
_cavernstriggersVector.Add(creature.GetGUID());
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.IceWall:
case GameObjectIds.HallsOfReflectionPortcullis:
AddDoor(go, true);
break;
}
}
public override void OnGameObjectRemove(GameObject go)
{
switch (go.GetEntry())
{
case GameObjectIds.IceWall:
case GameObjectIds.HallsOfReflectionPortcullis:
AddDoor(go, false);
break;
}
}
public override bool SetBossState(uint type, EncounterState state)
{
if (!base.SetBossState(type, state))
return false;
switch (type)
{
case DataTypes.Garfrost:
if (state == EncounterState.Done)
{
Creature summoner = instance.GetCreature(_garfrostGUID);
if (summoner)
{
if (_teamInInstance == Team.Alliance)
summoner.SummonCreature(CreatureIds.MartinVictus1, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
else
summoner.SummonCreature(CreatureIds.GorkunIronskull2, Misc.SlaveLeaderPos, TempSummonType.ManualDespawn);
}
}
break;
case DataTypes.Tyrannus:
if (state == EncounterState.Done)
{
Creature summoner = instance.GetCreature(_tyrannusGUID);
if (summoner)
{
if (_teamInInstance == Team.Alliance)
summoner.SummonCreature(CreatureIds.JainaPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
else
summoner.SummonCreature(CreatureIds.SylvanasPart2, Misc.EventLeaderPos2, TempSummonType.ManualDespawn);
}
}
break;
default:
break;
}
return true;
}
public override uint GetData(uint type)
{
switch (type)
{
case DataTypes.TeamInInstance:
return (uint)_teamInInstance;
case DataTypes.IceShardsHit:
return _shardsHit;
case DataTypes.CavernActive:
return _cavernActive;
default:
break;
}
return 0;
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case DataTypes.IceShardsHit:
_shardsHit = (byte)data;
break;
case DataTypes.CavernActive:
if (data != 0)
{
_cavernActive = (byte)data;
HandleCavernEventTrigger(true);
}
else
HandleCavernEventTrigger(false);
break;
default:
break;
}
}
public override ObjectGuid GetGuidData(uint type)
{
switch (type)
{
case DataTypes.Garfrost:
return _garfrostGUID;
case DataTypes.Krick:
return _krickGUID;
case DataTypes.Ick:
return _ickGUID;
case DataTypes.Tyrannus:
return _tyrannusGUID;
case DataTypes.Rimefang:
return _rimefangGUID;
case DataTypes.TyrannusEvent:
return _tyrannusEventGUID;
case DataTypes.JainaSylvanas1:
return _jainaOrSylvanas1GUID;
case DataTypes.JainaSylvanas2:
return _jainaOrSylvanas2GUID;
default:
break;
}
return ObjectGuid.Empty;
}
void HandleCavernEventTrigger(bool activate)
{
foreach (ObjectGuid guid in _cavernstriggersVector)
{
Creature trigger = instance.GetCreature(guid);
if (trigger)
{
if (activate)
trigger.m_Events.AddEvent(new ScheduledIcicleSummons(trigger), trigger.m_Events.CalculateTime(1000));
else
trigger.m_Events.KillAllEvents(false);
}
}
}
ObjectGuid _garfrostGUID;
ObjectGuid _krickGUID;
ObjectGuid _ickGUID;
ObjectGuid _tyrannusGUID;
ObjectGuid _rimefangGUID;
ObjectGuid _tyrannusEventGUID;
ObjectGuid _jainaOrSylvanas1GUID;
ObjectGuid _jainaOrSylvanas2GUID;
List<ObjectGuid> _cavernstriggersVector = new List<ObjectGuid>();
Team _teamInInstance;
byte _shardsHit;
byte _cavernActive;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_pit_of_saron_InstanceScript(map);
}
}
class ScheduledIcicleSummons : BasicEvent
{
public ScheduledIcicleSummons(Creature trigger)
{
_trigger = trigger;
}
public override bool Execute(ulong time, uint diff)
{
if (RandomHelper.randChance(12))
{
_trigger.CastSpell(_trigger, SpellIds.IcicleSummon, true);
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(20000, 35000)));
}
else
_trigger.m_Events.AddEvent(new ScheduledIcicleSummons(_trigger), _trigger.m_Events.CalculateTime(RandomHelper.URand(1000, 20000)));
return true;
}
Creature _trigger;
}
}
@@ -1,330 +0,0 @@
using System;
using Game.Entities;
using Game.AI;
using Game.Spells;
using Game.DataStorage;
using Game.Scripting;
using Framework.Constants;
using Game.Maps;
namespace Scripts.Northrend.FrozenHalls.PitOfSaron
{
struct TextIds
{
public const uint SayTyrannusCavernEntrance = 3;
}
struct DataTypes
{
// Encounter States And Guids
public const uint Garfrost = 0;
public const uint Ick = 1;
public const uint Tyrannus = 2;
// Guids
public const uint Rimefang = 3;
public const uint Krick = 4;
public const uint JainaSylvanas1 = 5; // Guid Of Either Jaina Or Sylvanas Part 1; Depending On Team; As It'S The Same Spawn.
public const uint JainaSylvanas2 = 6; // Guid Of Either Jaina Or Sylvanas Part 2; Depending On Team; As It'S The Same Spawn.
public const uint TyrannusEvent = 7;
public const uint TeamInInstance = 8;
public const uint IceShardsHit = 9;
public const uint CavernActive = 10;
}
struct CreatureIds
{
public const uint Garfrost = 36494;
public const uint Krick = 36477;
public const uint Ick = 36476;
public const uint Tyrannus = 36658;
public const uint Rimefang = 36661;
public const uint TyrannusEvents = 36794;
public const uint SylvanasPart1 = 36990;
public const uint SylvanasPart2 = 38189;
public const uint JainaPart1 = 36993;
public const uint JainaPart2 = 38188;
public const uint Kilara = 37583;
public const uint Elandra = 37774;
public const uint Koralen = 37779;
public const uint Korlaen = 37582;
public const uint Champion1Horde = 37584;
public const uint Champion2Horde = 37587;
public const uint Champion3Horde = 37588;
public const uint Champion1Alliance = 37496;
public const uint Champion2Alliance = 37497;
public const uint HordeSlave1 = 36770;
public const uint HordeSlave2 = 36771;
public const uint HordeSlave3 = 36772;
public const uint HordeSlave4 = 36773;
public const uint AllianceSlave1 = 36764;
public const uint AllianceSlave2 = 36765;
public const uint AllianceSlave3 = 36766;
public const uint AllianceSlave4 = 36767;
public const uint FreedSlave1Alliance = 37575;
public const uint FreedSlave2Alliance = 37572;
public const uint FreedSlave3Alliance = 37576;
public const uint FreedSlave1Horde = 37579;
public const uint FreedSlave2Horde = 37578;
public const uint FreedSlave3Horde = 37577;
public const uint RescuedSlaveAlliance = 36888;
public const uint RescuedSlaveHorde = 36889;
public const uint MartinVictus1 = 37591;
public const uint MartinVictus2 = 37580;
public const uint GorkunIronskull1 = 37581;
public const uint GorkunIronskull2 = 37592;
public const uint ForgemasterStalker = 36495;
public const uint ExplodingOrb = 36610;
public const uint YmirjarDeathbringer = 36892;
public const uint IcyBlast = 36731;
public const uint CavernEventTrigger = 32780;
}
struct GameObjectIds
{
public const uint SaroniteRock = 196485;
public const uint IceWall = 201885;
public const uint HallsOfReflectionPortcullis = 201848;
}
struct SpellIds
{
public const uint IcicleSummon = 69424;
public const uint IcicleFallTrigger = 69426;
public const uint IcicleFallVisual = 69428;
public const uint AchievDontLookUpCredit = 72845;
public const uint Fireball = 69583; //Ymirjar Flamebearer
public const uint Hellfire = 69586;
public const uint TacticalBlink = 69584;
public const uint FrostBreath = 69527; //Iceborn Proto-Drake
public const uint LeapingFaceMaul = 69504; // Geist Ambusher
}
[Script]
class npc_ymirjar_flamebearer : ScriptedAI
{
public npc_ymirjar_flamebearer(Creature creature) : base(creature)
{
}
public override void Reset()
{
_scheduler.CancelAll();
}
public override void EnterCombat(Unit who)
{
_scheduler.SetValidator(() => !me.HasUnitState(UnitState.Casting));
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.Fireball);
task.Repeat(TimeSpan.FromSeconds(5));
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.TacticalBlink);
DoCast(me, SpellIds.Hellfire);
task.Repeat(TimeSpan.FromSeconds(12));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
[Script]
class npc_iceborn_protodrake : ScriptedAI
{
public npc_iceborn_protodrake(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
Vehicle vehicle = me.GetVehicleKit();
if (vehicle)
vehicle.RemoveAllPassengers();
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
DoCastVictim(SpellIds.FrostBreath);
task.Repeat(TimeSpan.FromSeconds(10));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
[Script]
class npc_geist_ambusher : ScriptedAI
{
public npc_geist_ambusher(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who)
{
if (who.GetTypeId() != TypeId.Player)
return;
// the max range is determined by aggro range
if (me.GetDistance(who) > 5.0f)
DoCast(who, SpellIds.LeapingFaceMaul);
_scheduler.Schedule(TimeSpan.FromSeconds(9), task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 5.0f, true);
if (target)
DoCast(target, SpellIds.LeapingFaceMaul);
task.Repeat(TimeSpan.FromSeconds(9), TimeSpan.FromSeconds(14));
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
[Script]
class spell_trash_npc_glacial_strike : AuraScript
{
void PeriodicTick(AuraEffect aurEff)
{
if (GetTarget().IsFullHealth())
{
GetTarget().RemoveAura(GetId(), ObjectGuid.Empty, 0, AuraRemoveMode.EnemySpell);
PreventDefaultAction();
}
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(PeriodicTick, 2, AuraType.PeriodicDamagePercent));
}
}
[Script]
class npc_pit_of_saron_icicle : PassiveAI
{
public npc_pit_of_saron_icicle(Creature creature) : base(creature)
{
me.SetDisplayFromModel(0);
}
public override void IsSummonedBy(Unit summoner)
{
_summonerGUID = summoner.GetGUID();
_scheduler.Schedule(TimeSpan.FromMilliseconds(3650), task =>
{
DoCastSelf(SpellIds.IcicleFallTrigger, true);
DoCastSelf(SpellIds.IcicleFallVisual);
Unit caster = Global.ObjAccessor.GetUnit(me, _summonerGUID);
if (caster)
caster.RemoveDynObject(SpellIds.IcicleSummon);
});
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
ObjectGuid _summonerGUID;
}
[Script]
class spell_pos_ice_shards : SpellScript
{
void HandleScriptEffect(uint effIndex)
{
if (GetHitPlayer())
GetCaster().GetInstanceScript().SetData(DataTypes.CavernActive, 1);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScriptEffect, 0, SpellEffectName.SchoolDamage));
}
}
[Script]
class at_pit_cavern_entrance : AreaTriggerScript
{
public at_pit_cavern_entrance() : base("at_pit_cavern_entrance") { }
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
{
if (!entered)
return true;
InstanceScript instance = player.GetInstanceScript();
if (instance != null)
{
if (instance.GetData(DataTypes.CavernActive) != 0)
return true;
instance.SetData(DataTypes.CavernActive, 1);
Creature tyrannus = ObjectAccessor.GetCreature(player, instance.GetGuidData(DataTypes.TyrannusEvent));
if (tyrannus)
tyrannus.GetAI().Talk(TextIds.SayTyrannusCavernEntrance);
}
return true;
}
}
[Script]
class at_pit_cavern_end : AreaTriggerScript
{
public at_pit_cavern_end() : base("at_pit_cavern_end") { }
public override bool OnTrigger(Player player, AreaTriggerRecord areaTrigger, bool entered)
{
if (!entered)
return true;
InstanceScript instance = player.GetInstanceScript();
if (instance != null)
{
instance.SetData(DataTypes.CavernActive, 0);
if (instance.GetData(DataTypes.IceShardsHit) == 0)
instance.DoUpdateCriteria(CriteriaTypes.BeSpellTarget, SpellIds.AchievDontLookUpCredit, 0, player);
}
return true;
}
}
}
@@ -1,414 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
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 : BossAI
{
public boss_drakkari_colossus(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.RemoveUnitFlag(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.AddUnitFlag(UnitFlags.ImmuneToPc);
DoCast(me, SpellIds.FreezeAnim);
break;
case Misc.ActionUnfreezeColossus:
if (me.GetReactState() == ReactStates.Aggressive)
return;
me.SetReactState(ReactStates.Aggressive);
me.RemoveUnitFlag(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.HasUnitFlag(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;
}
[Script]
class boss_drakkari_elemental : ScriptedAI
{
public boss_drakkari_elemental(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;
}
[Script]
class npc_living_mojo : ScriptedAI
{
public npc_living_mojo(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;
}
}
-118
View File
@@ -1,118 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using 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 : BossAI
{
public boss_eck(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;
}
}
@@ -1,449 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.IO;
using Game.AI;
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(InstanceMap 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(GameObjectFlags.NotSelectable);
else
go.SetGoState(GameObjectState.Active);
}
break;
case GDGameObjectIds.MoorabiAltar:
if (GetBossState(GDDataTypes.Moorabi) == EncounterState.Done)
{
if (MoorabiStatueState == GameObjectState.Active)
go.RemoveFlag(GameObjectFlags.NotSelectable);
else
go.SetGoState(GameObjectState.Active);
}
break;
case GDGameObjectIds.DrakkariColossusAltar:
if (GetBossState(GDDataTypes.DrakkariColossus) == EncounterState.Done)
{
if (DrakkariColossusStatueState == GameObjectState.Active)
go.RemoveFlag(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(GameObjectFlags.NotSelectable);
}
break;
case GDDataTypes.DrakkariColossus:
if (state == EncounterState.Done)
{
GameObject go = GetGameObject(GDDataTypes.DrakkariColossusAltar);
if (go)
go.RemoveFlag(GameObjectFlags.NotSelectable);
}
break;
case GDDataTypes.Moorabi:
if (state == EncounterState.Done)
{
GameObject go = GetGameObject(GDDataTypes.MoorabiAltar);
if (go)
go.RemoveFlag(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") { }
class go_gundrak_altarAI : GameObjectAI
{
public go_gundrak_altarAI(GameObject go) : base(go)
{
instance = go.GetInstanceScript();
}
public override bool GossipHello(Player player)
{
me.AddFlag(GameObjectFlags.NotSelectable);
me.SetGoState(GameObjectState.Active);
instance.SetData(GDDataTypes.StatueActivate, me.GetEntry());
return true;
}
InstanceScript instance;
}
public override GameObjectAI GetAI(GameObject go)
{
return GetInstanceAI<go_gundrak_altarAI>(go);
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,734 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
public const uint DivineSurge = 71465;
// 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 ? FlashHealUndead : FlashHealNormal; }
public static uint SpellPowerWordShield(bool isUndead) { return isUndead ? PowerWordShieldUndead : PowerWordShieldNormal; }
public static uint SpellSmite(bool isUndead) { return isUndead ? SmiteUndead : 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 ? FelIronBombUndead : FelIronBombNormal; }
public static uint SpellMachineGun(bool isUndead) { return isUndead ? MachineGunUndead : MachineGunNormal; }
public static uint SpellRocketLaunch(bool isUndead) { return isUndead ? RocketLaunchUndead : 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;
}
}
@@ -1,106 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.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], Difficulty.None);
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);
}
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, Difficulty.None);
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
@@ -1,656 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Movement;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
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 SpellIds
{
// 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(SpellIds.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]
public class boss_lord_marrowgar : BossAI
{
public boss_lord_marrowgar(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(SpellIds.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(SpellIds.BoneStorm))
DoCast(me, SpellIds.BoneSpikeGraveyard);
_events.ScheduleEvent(Misc.EventBoneSpikeGraveyard, RandomHelper.URand(15000, 20000), Misc.EventGroupSpecial);
break;
case Misc.EventColdflame:
_coldflameLastPos.Relocate(me);
_coldflameTarget.Clear();
if (!me.HasAura(SpellIds.BoneStorm))
DoCastAOE(SpellIds.ColdflameNormal);
else
DoCast(me, SpellIds.ColdflameBoneStorm);
_events.ScheduleEvent(Misc.EventColdflame, 5000, Misc.EventGroupSpecial);
break;
case Misc.EventWarnBoneStorm:
_boneSlice = false;
Talk(Texts.SayBoneStorm);
me.FinishSpell(CurrentSpellTypes.Melee, false);
DoCast(me, SpellIds.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(SpellIds.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(SpellIds.BoneStorm))
return;
// 10 seconds since encounter start Bone Slice replaces melee attacks
if (_boneSlice && !me.GetCurrentSpell(CurrentSpellTypes.Melee))
DoCastVictim(SpellIds.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;
}
[Script]
class npc_coldflame : ScriptedAI
{
public npc_coldflame(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)owner.GetAI();
if (marrowgarAI != null)
pos.Relocate(marrowgarAI.GetLastColdflamePosition());
else
pos.Relocate(owner);
if (owner.HasAura(SpellIds.BoneStorm))
{
float ang = Position.NormalizeOrientation(pos.GetAngle(me));
me.SetOrientation(ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 5.0f - owner.GetCombatReach(), 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.GetCombatReach(), ang);
}
me.NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
DoCast(SpellIds.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(SpellIds.ColdflameSummon);
_events.ScheduleEvent(Misc.EventColdflameTrigger, 500);
}
}
}
[Script]
class npc_bone_spike : ScriptedAI
{
public npc_bone_spike(Creature creature) : base(creature)
{
_hasTrappedUnit = false;
Cypher.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(SpellIds.Impaled);
}
me.DespawnOrUnsummon();
}
public override void KilledUnit(Unit victim)
{
me.DespawnOrUnsummon();
victim.RemoveAurasDueToSpell(SpellIds.Impaled);
}
public override void IsSummonedBy(Unit summoner)
{
DoCast(summoner, SpellIds.Impaled);
summoner.CastSpell(me, SpellIds.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;
}
[Script]
class spell_marrowgar_coldflame : SpellScript
{
void SelectTarget(List<WorldObject> targets)
{
targets.Clear();
// select any unit but not the tank
Unit target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 1, -GetCaster().GetCombatReach(), true, false, -(int)SpellIds.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));
}
}
[Script]
class spell_marrowgar_coldflame_bonestorm : 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));
}
}
[Script]
class spell_marrowgar_coldflame_damage : AuraScript
{
bool CanBeAppliedOn(Unit target)
{
if (target.HasAura(SpellIds.Impaled))
return false;
SpellEffectInfo effect = GetSpellInfo().GetEffect(0);
if (effect != null)
if (target.GetExactDist2d(GetOwner()) > effect.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));
}
}
[Script]
class spell_marrowgar_bone_spike_graveyard : 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().GetDifficultyID() & 1) ? 3 : 1);
List<Unit> targets = marrowgarAI.SelectTargetList(boneSpikeCount, SelectAggroTarget.Random, 1, new BoneSpikeTargetSelector(marrowgarAI));
if (targets.Empty())
return;
uint i = 0;
foreach (var target in targets)
{
target.CastSpell(target, Misc.BoneSpikeSummonId[i], true);
if (!target.IsAlive()) // make sure we don't get any stuck spikes on dead targets
{
Aura aura = target.GetAura(SpellIds.Impaled);
if (aura != null)
{
Creature spike = ObjectAccessor.GetCreature(target, aura.GetCasterGUID());
if (spike != null)
spike.DespawnOrUnsummon();
aura.Remove();
}
}
i++;
}
marrowgarAI.Talk(Texts.SayBonespike);
}
}
public override void Register()
{
OnCheckCast.Add(new CheckCastHandler(CheckCast));
OnEffectHitTarget.Add(new EffectHandler(HandleSpikes, 1, SpellEffectName.ApplyAura));
}
}
[Script]
class spell_marrowgar_bone_storm : SpellScript
{
void RecalculateDamage()
{
SetHitDamage((int)(GetHitDamage() / Math.Max(Math.Sqrt(GetHitUnit().GetExactDist2d(GetCaster())), 1.0f)));
}
public override void Register()
{
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
[Script]
class spell_marrowgar_bone_slice : 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;
}
}
}
@@ -1,35 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using 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);
}
}
@@ -1,39 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using 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);
}
}
@@ -1,26 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Game.Entities;
namespace Scripts.Northrend.IcecrownCitadel
{
public class ValithriaDreamwalker
{
public static Position ValithriaSpawnPos = new Position(4210.813f, 2484.443f, 364.9558f, 0.01745329f);
}
}
@@ -1,63 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
}
}
@@ -1,24 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Scripts.Northrend.Nexus.EyeOfEternity
{
class BossMalygos
{
}
}
@@ -1,351 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using 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(InstanceMap 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(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 = GameObject.CreateGameObject(entry, instance, pos, Quaternion.fromEulerAnglesZYX(pos.GetOrientation(), 0.0f, 0.0f), 255, GameObjectState.Ready);
if (go)
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.AddFlag(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);
}
}
}
@@ -1,271 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
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 : ScriptedAI
{
public boss_anomalus(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;
}
[Script]
class npc_chaotic_rift : ScriptedAI
{
public npc_chaotic_rift(Creature creature) : base(creature)
{
Initialize();
instance = me.GetInstanceScript();
SetCombatMovement(false);
}
void Initialize()
{
uiChaoticEnergyBurstTimer = 1000;
uiSummonCrazedManaWraithTimer = 5000;
}
public override void Reset()
{
Initialize();
me.SetDisplayFromModel(1);
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;
}
[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;
}
}
}
@@ -1,269 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
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]
public class boss_keristrasza : BossAI
{
public boss_keristrasza(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.RemoveUnitFlag(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.RemoveUnitFlag(UnitFlags.ImmuneToPc);
me.RemoveUnitFlag(UnitFlags.NonAttackable);
if (me.HasAura(KeristraszaConst.SpellFrozenPrison))
me.RemoveAurasDueToSpell(KeristraszaConst.SpellFrozenPrison);
}
else
{
me.AddUnitFlag(UnitFlags.ImmuneToPc);
me.AddUnitFlag(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>();
}
[Script]
class containment_sphere : GameObjectScript
{
public containment_sphere() : base("containment_sphere") { }
class containment_sphereAI : GameObjectAI
{
public containment_sphereAI(GameObject go) : base(go)
{
instance = go.GetInstanceScript();
}
public override bool GossipHello(Player player)
{
Creature pKeristrasza = ObjectAccessor.GetCreature(me, instance.GetGuidData(DataTypes.Keristrasza));
if (pKeristrasza && pKeristrasza.IsAlive())
{
// maybe these are hacks :(
me.AddFlag(GameObjectFlags.NotSelectable);
me.SetGoState(GameObjectState.Active);
((boss_keristrasza)pKeristrasza.GetAI()).CheckContainmentSpheres(true);
}
return true;
}
InstanceScript instance;
}
public override GameObjectAI GetAI(GameObject go)
{
return GetInstanceAI<containment_sphereAI>(go);
}
}
[Script]
class spell_intense_cold : 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));
}
}
[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)target.ToCreature().GetAI())._intenseColdList;
if (!_intenseColdList.Empty())
{
foreach (var guid in _intenseColdList)
if (player.GetGUID() == guid)
return false;
}
return true;
}
}
}
@@ -1,314 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
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 : ScriptedAI
{
public boss_magus_telestra(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.RemoveUnitFlag(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.RemoveUnitFlag(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.AddUnitFlag(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.AddUnitFlag(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] = GameTime.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];
}
[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;
}
}
}
@@ -1,103 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using 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 : BossAI
{
boss_nexus_commanders(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();
}
}
}
@@ -1,261 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
namespace Scripts.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 : BossAI
{
public boss_ormorok(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;
}
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 : ScriptedAI
{
public npc_crystal_spike_trigger(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;
}
[Script]
class spell_crystal_spike : 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));
}
}
}
@@ -1,227 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
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(InstanceMap 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(GameObjectFlags.NotSelectable);
break;
case GameObjectIds.OrmoroksContainmetSphere:
OrmoroksContainmentSphere = go.GetGUID();
if (GetBossState(DataTypes.Ormorok) == EncounterState.Done)
go.RemoveFlag(GameObjectFlags.NotSelectable);
break;
case GameObjectIds.TelestrasContainmetSphere:
TelestrasContainmentSphere = go.GetGUID();
if (GetBossState(DataTypes.MagusTelestra) == EncounterState.Done)
go.RemoveFlag(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(GameObjectFlags.NotSelectable);
}
break;
case DataTypes.Anomalus:
if (state == EncounterState.Done)
{
GameObject sphere = instance.GetGameObject(AnomalusContainmentSphere);
if (sphere)
sphere.RemoveFlag(GameObjectFlags.NotSelectable);
}
break;
case DataTypes.Ormorok:
if (state == EncounterState.Done)
{
GameObject sphere = instance.GetGameObject(OrmoroksContainmentSphere);
if (sphere)
sphere.RemoveFlag(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);
}
}
}
@@ -1,352 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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.AddNpcFlag(NPCFlags.Gossip);
creature.Relocate(BelgaristraszMove);
}
break;
case NPC_ETERNOS:
EternosGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
{
creature.AddNpcFlag(NPCFlags.Gossip);
creature.Relocate(EternosMove);
}
break;
case NPC_VERDISA:
VerdisaGUID = creature.GetGUID();
if (GetBossState(DATA_DRAKOS) == EncounterState.Done)
{
creature.AddNpcFlag(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();
}
*/
}
@@ -1,30 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using 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
@@ -1,148 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Scripts.Northrend.Ulduar
{
namespace Razorscale
{
/*class boss_razorscale_controller : BossAI
{
public boss_razorscale_controller(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 Get(Creature creature)
{
return GetInstanceAI<boss_razorscale_controllerAI>(creature);
}
}*/
}
}
@@ -1,415 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
// Misc
public const uint BrannBronzebeardIntro = 58;
public const uint LoreKeeperOfNorgannon = 59;
public const uint Dellorah = 60;
public const uint BronzebeardRadio = 61;
}
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
-883
View File
@@ -1,883 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.Dynamic;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
using Game.Networking.Packets;
namespace Scripts.Northrend.Ulduar.Xt002
{
struct SpellIds
{
public const uint TympanicTantrum = 62776;
public const uint SearingLight = 63018;
public const uint SummonLifeSpark = 64210;
public const uint SummonVoidZone = 64203;
public const uint GravityBomb = 63024;
public const uint Heartbreak = 65737;
// Cast By 33337 At Heartbreak:
public const uint RechargePummeler = 62831; // Summons 33344
public const uint RechargeScrapbot = 62828; // Summons 33343
public const uint RechargeBoombot = 62835; // Summons 33346
// Cast By 33329 On 33337 (Visual?)
public const uint EnergyOrb = 62790; // Triggers 62826 - Needs Spellscript For Periodic Tick To Cast One Of The Random Spells Above
public const uint HeartHealToFull = 17683;
public const uint HeartOverload = 62789;
public const uint HeartLightningTether = 64799; // Cast On Self?
public const uint Enrage = 26662;
public const uint Stand = 37752;
public const uint Submerge = 37751;
//------------------Void Zone--------------------
public const uint VoidZone = 64203;
public const uint Consumption = 64208;
// Life Spark
public const uint ArcanePowerState = 49411;
public const uint StaticCharged = 64227;
public const uint Shock = 64230;
//----------------Xt-002 Heart-------------------
public const uint ExposedHeart = 63849;
public const uint HeartRideVehicle = 63852;
public const uint RideVehicleExposed = 63313; //Heart Exposed
//---------------Xm-024 Pummeller----------------
public const uint ArcingSmash = 8374;
public const uint Trample = 5568;
public const uint Uppercut = 10966;
// Scrabot:
public const uint ScrapbotRideVehicle = 47020;
public const uint ScrapRepair = 62832;
public const uint Suicide = 7;
//------------------Boombot-----------------------
public const uint AuraBoombot = 65032;
public const uint Boom = 62834;
// Achievement-Related Spells
public const uint AchievementCreditNerfScrapbots = 65037;
}
struct XT002Data
{
public const uint TransferedHealth = 0;
public const uint HardMode = 1;
public const uint HealthRecovered = 2;
public const uint GravityBombCasualty = 3;
}
struct Texts
{
public const uint Aggro = 0;
public const uint HeartOpened = 1;
public const uint HeartClosed = 2;
public const uint TympanicTantrum = 3;
public const uint Slay = 4;
public const uint Berserk = 5;
public const uint Death = 6;
public const uint Summon = 7;
public const uint EmoteHeartOpened = 8;
public const uint EmoteHeartClosed = 9;
public const uint EmoteTympanicTantrum = 10;
public const uint EmoteScrapbot = 11;
}
struct Misc
{
public const uint PhaseOneGroup = 1;
public const int ActionHardMode = 1;
public const uint AchievMustDeconstructFaster = 21027;
public const sbyte SeatHeartNormal = 0;
public const sbyte SeatHeartExposed = 1;
}
[Script]
class boss_xt002 : BossAI
{
public boss_xt002(Creature creature) : base(creature, BossIds.Xt002)
{
Initialize();
_transferHealth = 0;
}
void Initialize()
{
_healthRecovered = false;
_gravityBombCasualty = false;
_hardMode = false;
_heartExposed = 0;
}
public override void Reset()
{
_Reset();
me.RemoveUnitFlag(UnitFlags.NotSelectable);
me.SetReactState(ReactStates.Aggressive);
DoCastSelf(SpellIds.Stand);
Initialize();
instance.DoStopCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievMustDeconstructFaster);
}
public override void EnterEvadeMode(EvadeReason why)
{
summons.DespawnAll();
_DespawnAtEvade();
}
public override void EnterCombat(Unit who)
{
Talk(Texts.Aggro);
_EnterCombat();
//Enrage
_scheduler.Schedule(TimeSpan.FromMinutes(10), task =>
{
Talk(Texts.Berserk);
DoCastSelf(SpellIds.Enrage);
});
//Gavity Bomb
_scheduler.Schedule(TimeSpan.FromSeconds(20), Misc.PhaseOneGroup, task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.GravityBomb);
task.Repeat(TimeSpan.FromSeconds(20));
});
//Searing Light
_scheduler.Schedule(TimeSpan.FromSeconds(20), Misc.PhaseOneGroup, task =>
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (target)
DoCast(target, SpellIds.SearingLight);
task.Repeat(TimeSpan.FromSeconds(20));
});
//Tympanic Tantrum
_scheduler.Schedule(TimeSpan.FromSeconds(30), Misc.PhaseOneGroup, task =>
{
Talk(Texts.TympanicTantrum);
Talk(Texts.EmoteTympanicTantrum);
DoCast(SpellIds.TympanicTantrum);
task.Repeat(TimeSpan.FromSeconds(30));
});
instance.DoStartCriteriaTimer(CriteriaTimedTypes.Event, Misc.AchievMustDeconstructFaster);
}
public override void DoAction(int action)
{
switch (action)
{
case Misc.ActionHardMode:
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), task =>
{
SetPhaseOne(true);
});
break;
}
}
public override void KilledUnit(Unit who)
{
if (who.GetTypeId() == TypeId.Player)
Talk(Texts.Slay);
}
public override void JustDied(Unit killer)
{
Talk(Texts.Death);
_JustDied();
me.RemoveUnitFlag(UnitFlags.NotSelectable);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!_hardMode && !me.HasReactState(ReactStates.Passive) && !HealthAbovePct(100 - 25 * (_heartExposed + 1)))
ExposeHeart();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (!me.HasReactState(ReactStates.Passive))
DoMeleeAttackIfReady();
}
public override void PassengerBoarded(Unit who, sbyte seatId, bool apply)
{
if (apply && who.GetEntry() == InstanceCreatureIds.XS013Scrapbot)
{
// Need this so we can properly determine when to expose heart again in damagetaken hook
if (me.GetHealthPct() > (25 * (4 - _heartExposed)))
++_heartExposed;
Talk(Texts.EmoteScrapbot);
DoCast(who, SpellIds.ScrapRepair, true);
_healthRecovered = true;
}
if (apply && seatId == Misc.SeatHeartExposed)
who.CastSpell(who, SpellIds.ExposedHeart); // Channeled
}
public override uint GetData(uint type)
{
switch (type)
{
case XT002Data.HardMode:
return _hardMode ? 1 : 0u;
case XT002Data.HealthRecovered:
return _healthRecovered ? 1 : 0u;
case XT002Data.GravityBombCasualty:
return _gravityBombCasualty ? 1 : 0u;
}
return 0;
}
public override void SetData(uint type, uint data)
{
switch (type)
{
case XT002Data.TransferedHealth:
_transferHealth = data;
break;
case XT002Data.GravityBombCasualty:
_gravityBombCasualty = (data > 0) ? true : false;
break;
}
}
void ExposeHeart()
{
Talk(Texts.HeartOpened);
Talk(Texts.EmoteHeartOpened);
DoCastSelf(SpellIds.Submerge); // WIll make creature untargetable
me.AttackStop();
me.SetReactState(ReactStates.Passive);
Unit heart = me.GetVehicleKit() ? me.GetVehicleKit().GetPassenger(Misc.SeatHeartNormal) : null;
if (heart)
{
heart.CastSpell(heart, SpellIds.HeartOverload);
heart.CastSpell(me, SpellIds.HeartLightningTether);
heart.CastSpell(heart, SpellIds.HeartHealToFull, true);
heart.CastSpell(me, SpellIds.RideVehicleExposed, true);
heart.RemoveUnitFlag(UnitFlags.NotSelectable);
heart.AddUnitFlag(UnitFlags.Unk29);
}
_scheduler.DelayGroup(Misc.PhaseOneGroup, TimeSpan.FromSeconds(30));
// Start "end of phase 2 timer"
_scheduler.Schedule(TimeSpan.FromSeconds(30), task => { SetPhaseOne(false); });
_heartExposed++;
}
void SetPhaseOne(bool isHardMode)
{
if (isHardMode)
{
me.SetFullHealth();
DoCastSelf(SpellIds.Heartbreak, true);
me.AddLootMode(LootModes.HardMode1);
_hardMode = true;
}
Talk(Texts.HeartClosed);
Talk(Texts.EmoteHeartClosed);
me.RemoveUnitFlag(UnitFlags.NotSelectable);
me.SetReactState(ReactStates.Aggressive);
DoCastSelf(SpellIds.Stand);
//_events.RescheduleEvent(EVENT_SEARING_LIGHT, TIMER_SEARING_LIGHT / 2);
//_events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
//_events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, RandomHelper.URand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));
Unit heart = me.GetVehicleKit() ? me.GetVehicleKit().GetPassenger(Misc.SeatHeartExposed) : null;
if (!heart)
return;
heart.CastSpell(me, SpellIds.HeartRideVehicle, true);
heart.AddUnitFlag(UnitFlags.NotSelectable);
heart.RemoveUnitFlag(UnitFlags.Unk29);
heart.RemoveAurasDueToSpell(SpellIds.ExposedHeart);
if (!_hardMode)
{
if (_transferHealth == 0)
_transferHealth = (uint)(heart.GetMaxHealth() - heart.GetHealth());
if (_transferHealth >= me.GetHealth())
_transferHealth = (uint)me.GetHealth() - 1;
me.ModifyHealth(-(int)_transferHealth);
me.LowerPlayerDamageReq(_transferHealth);
}
}
// Achievement related
bool _healthRecovered; // Did a scrapbot recover XT-002's health during the encounter?
bool _hardMode; // Are we in hard mode? Or: was the heart killed during phase 2?
bool _gravityBombCasualty; // Did someone die because of Gravity Bomb damage?
byte _heartExposed;
uint _transferHealth;
}
[Script]
class npc_xt002_heart : NullCreatureAI
{
public npc_xt002_heart(Creature creature) : base(creature)
{
_instance = creature.GetInstanceScript();
}
public override void JustDied(Unit killer)
{
Creature xt002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
if (xt002)
{
xt002.GetAI().SetData(XT002Data.TransferedHealth, (uint)me.GetHealth());
xt002.GetAI().DoAction(Misc.ActionHardMode);
}
}
InstanceScript _instance;
}
[Script]
class npc_scrapbot : ScriptedAI
{
public npc_scrapbot(Creature creature) : base(creature)
{
_instance = me.GetInstanceScript();
}
public override void Reset()
{
me.SetReactState(ReactStates.Passive);
Creature pXT002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
if (pXT002)
me.GetMotionMaster().MoveFollow(pXT002, 0.0f, 0.0f);
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
ObjectGuid guid = _instance.GetGuidData(BossIds.Xt002);
if (type == MovementGeneratorType.Follow && id == guid.GetCounter())
{
Creature xt002 = ObjectAccessor.GetCreature(me, guid);
if (xt002)
{
if (me.IsWithinMeleeRange(xt002))
{
DoCast(xt002, SpellIds.ScrapbotRideVehicle);
// Unapply vehicle aura again
xt002.RemoveAurasDueToSpell(SpellIds.ScrapbotRideVehicle);
me.DespawnOrUnsummon();
}
}
}
}
InstanceScript _instance;
}
[Script]
class npc_pummeller : ScriptedAI
{
public npc_pummeller(Creature creature) : base(creature)
{
Initialize();
_instance = creature.GetInstanceScript();
}
void Initialize()
{
_scheduler.SetValidator(() => me.IsWithinMeleeRange(me.GetVictim()));
//Arcing Smash
_scheduler.Schedule(TimeSpan.FromSeconds(27), task =>
{
DoCastVictim(SpellIds.ArcingSmash);
task.Repeat(TimeSpan.FromSeconds(27));
});
//Trample
_scheduler.Schedule(TimeSpan.FromSeconds(22), task =>
{
DoCastVictim(SpellIds.Trample);
task.Repeat(TimeSpan.FromSeconds(22));
});
//Uppercut
_scheduler.Schedule(TimeSpan.FromSeconds(17), task =>
{
DoCastVictim(SpellIds.Uppercut);
task.Repeat(TimeSpan.FromSeconds(17));
});
}
public override void Reset()
{
Initialize();
Creature xt002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
if (xt002)
{
Position pos = xt002.GetPosition();
me.GetMotionMaster().MovePoint(0, pos);
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
InstanceScript _instance;
}
class BoomEvent : BasicEvent
{
public BoomEvent(Creature me)
{
_me = me;
}
public override bool Execute(ulong time, uint diff)
{
// This hack is here because we suspect our implementation of spell effect execution on targets
// is done in the wrong order. We suspect that 0 needs to be applied on all targets,
// then 1, etc - instead of applying each effect on target1, then target2, etc.
// The above situation causes the visual for this spell to be bugged, so we remove the instakill
// effect and implement a script hack for that.
_me.CastSpell(_me, SpellIds.Boom, false);
return true;
}
Creature _me;
}
[Script]
class npc_boombot : ScriptedAI
{
public npc_boombot(Creature creature) : base(creature)
{
Initialize();
_instance = creature.GetInstanceScript();
}
void Initialize()
{
_boomed = false;
}
public override void Reset()
{
Initialize();
DoCast(SpellIds.AuraBoombot); // For achievement
// @todo proper waypoints?
Creature pXT002 = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.Xt002));
if (pXT002)
me.GetMotionMaster().MoveFollow(pXT002, 0.0f, 0.0f);
}
public override void DamageTaken(Unit who, ref uint damage)
{
if (damage >= (me.GetHealth() - me.GetMaxHealth() * 0.5f) && !_boomed)
{
_boomed = true; // Prevent recursive calls
SpellInstakillLog instakill = new SpellInstakillLog();
instakill.Caster = me.GetGUID();
instakill.Target = me.GetGUID();
instakill.SpellID = SpellIds.Boom;
me.SendMessageToSet(instakill, false);
me.DealDamage(me, (uint)me.GetHealth(), null, DamageEffectType.NoDamage, SpellSchoolMask.Normal, null, false);
damage = 0;
// Visual only seems to work if the instant kill event is delayed or the spell itself is delayed
// Casting done from player and caster source has the same targetinfo flags,
// so that can't be the issue
// See BoomEvent class
// Schedule 1s delayed
me.m_Events.AddEvent(new BoomEvent(me), me.m_Events.CalculateTime(1 * Time.InMilliseconds));
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
// No melee attack
}
InstanceScript _instance;
bool _boomed;
}
[Script]
class npc_life_spark : ScriptedAI
{
public npc_life_spark(Creature creature) : base(creature) { }
void Initialize()
{
_scheduler.Schedule(TimeSpan.FromMilliseconds(1), task =>
{
DoCastVictim(SpellIds.Shock);
task.Repeat(TimeSpan.FromSeconds(12));
});
}
public override void Reset()
{
DoCastSelf(SpellIds.ArcanePowerState);
_scheduler.CancelAll();
}
public override void EnterCombat(Unit victim)
{
DoCastSelf(SpellIds.StaticCharged);
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.Shock);
task.Repeat();
});
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_scheduler.Update(diff, DoMeleeAttackIfReady);
}
}
[Script]
class npc_xt_void_zone : PassiveAI
{
public npc_xt_void_zone(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.Schedule(TimeSpan.FromSeconds(1), consumption =>
{
DoCastSelf(SpellIds.Consumption);
consumption.Repeat();
});
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
}
[Script]
class spell_xt002_searing_light_spawn_life_spark : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.SummonLifeSpark);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Player player = GetOwner().ToPlayer();
if (player)
{
Unit xt002 = GetCaster();
if (xt002)
if (xt002.HasAura((uint)aurEff.GetAmount())) // Heartbreak aura indicating hard mode
xt002.CastSpell(player, SpellIds.SummonLifeSpark, true);
}
}
public override void Register()
{
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_xt002_gravity_bomb_aura : AuraScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.SummonVoidZone);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Player player = GetOwner().ToPlayer();
if (player)
{
Unit xt002 = GetCaster();
if (xt002)
if (xt002.HasAura((uint)aurEff.GetAmount())) // Heartbreak aura indicating hard mode
xt002.CastSpell(player, SpellIds.SummonVoidZone, true);
}
}
void OnPeriodic(AuraEffect aurEff)
{
Unit xt002 = GetCaster();
if (!xt002)
return;
Unit owner = GetOwner().ToUnit();
if (!owner)
return;
if ((uint)aurEff.GetAmount() >= owner.GetHealth())
if (xt002.GetAI() != null)
xt002.GetAI().SetData(XT002Data.GravityBombCasualty, 1);
}
public override void Register()
{
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 2, AuraType.PeriodicDamage));
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
}
}
[Script]
class spell_xt002_gravity_bomb_damage : SpellScript
{
void HandleScript(uint eff)
{
Unit caster = GetCaster();
if (!caster)
return;
if ((uint)GetHitDamage() >= GetHitUnit().GetHealth())
if (caster.GetAI() != null)
caster.GetAI().SetData(XT002Data.GravityBombCasualty, 1);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.SchoolDamage));
}
}
[Script]
class spell_xt002_heart_overload_periodic : SpellScript
{
public override bool Validate(SpellInfo spell)
{
return ValidateSpellInfo(SpellIds.EnergyOrb, SpellIds.RechargeBoombot, SpellIds.RechargePummeler, SpellIds.RechargeScrapbot);
}
void HandleScript(uint effIndex)
{
Unit caster = GetCaster();
if (caster)
{
InstanceScript instance = caster.GetInstanceScript();
if (instance != null)
{
Unit toyPile = Global.ObjAccessor.GetUnit(caster, instance.GetGuidData(InstanceData.ToyPile0 + RandomHelper.URand(0, 3)));
if (toyPile)
{
caster.CastSpell(toyPile, SpellIds.EnergyOrb, true);
// This should probably be incorporated in a dummy effect handler, but I've had trouble getting the correct target
// Weighed randomization (approximation)
uint[] spells = { SpellIds.RechargeScrapbot, SpellIds.RechargeScrapbot, SpellIds.RechargeScrapbot, SpellIds.RechargePummeler, SpellIds.RechargeBoombot };
for (byte i = 0; i < 5; ++i)
{
uint spellId = spells[RandomHelper.IRand(0, 4)];
toyPile.CastSpell(toyPile, spellId, true, null, null, instance.GetGuidData(BossIds.Xt002));
}
}
}
Creature creatureBase = caster.GetVehicleCreatureBase();
if (creatureBase)
creatureBase.GetAI().Talk(Texts.Summon);
}
}
public override void Register()
{
OnEffectHit.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy));
}
}
[Script]
class spell_xt002_tympanic_tantrum : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(new PlayerOrPetCheck());
}
void RecalculateDamage()
{
SetHitDamage((int)GetHitUnit().CountPctFromMaxHealth(GetHitDamage()));
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 1, Targets.UnitSrcAreaEnemy));
OnHit.Add(new HitHandler(RecalculateDamage));
}
}
[Script]
class spell_xt002_submerged : SpellScript
{
void HandleScript(uint eff)
{
Creature target = GetHitCreature();
if (!target)
return;
target.AddUnitFlag(UnitFlags.NotSelectable);
target.SetStandState(UnitStandStateType.Submerged);
}
public override void Register()
{
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script]
class spell_xt002_321_boombot_aura : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.AchievementCreditNerfScrapbots);
}
bool CheckProc(ProcEventInfo eventInfo)
{
if (eventInfo.GetActionTarget().GetEntry() != InstanceCreatureIds.XS013Scrapbot)
return false;
return true;
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
InstanceScript instance = eventInfo.GetActor().GetInstanceScript();
if (instance == null)
return;
instance.DoCastSpellOnPlayers(SpellIds.AchievementCreditNerfScrapbots);
}
public override void Register()
{
DoCheckProc.Add(new CheckProcHandler(CheckProc));
OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy));
}
}
[Script]
class achievement_nerf_engineering : AchievementCriteriaScript
{
public achievement_nerf_engineering() : base("achievement_nerf_engineering") { }
public override bool OnCheck(Player source, Unit target)
{
if (!target || target.GetAI() == null)
return false;
return target.GetAI().GetData(XT002Data.HealthRecovered) == 0;
}
}
[Script]
class achievement_heartbreaker : AchievementCriteriaScript
{
public achievement_heartbreaker() : base("achievement_heartbreaker") { }
public override bool OnCheck(Player source, Unit target)
{
if (!target || target.GetAI() == null)
return false;
return target.GetAI().GetData(XT002Data.HardMode) != 0;
}
}
[Script]
class achievement_nerf_gravity_bombs : AchievementCriteriaScript
{
public achievement_nerf_gravity_bombs() : base("achievement_nerf_gravity_bombs") { }
public override bool OnCheck(Player source, Unit target)
{
if (!target || target.GetAI() == null)
return false;
return target.GetAI().GetData(XT002Data.GravityBombCasualty) == 0;
}
}
}
@@ -1,39 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using 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
};
}
}
@@ -1,21 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Scripts.Northrend.VioletHold
{
}
-96
View File
@@ -1,96 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.BattleFields;
using Game.Conditions;
using Game.Entities;
using Game.Scripting;
namespace Scripts.Northrend
{
[Script]
class spell_wintergrasp_defender_teleport : 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));
}
}
[Script]
class spell_wintergrasp_defender_teleport_trigger : 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));
}
}
[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;
}
}
}
@@ -1,301 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game;
using Game.AI;
using Game.Entities;
using Game.Scripting;
namespace Scripts.Outlands
{
struct Aeranas
{
public const uint SaySummon = 0;
public const uint SayFree = 1;
public const uint FactionHostile = 16;
public const uint FactionFriendly = 35;
public const uint SpellEncelopingWinds = 15535;
public const uint SpellShock = 12553;
}
[Script]
class npc_aeranas : ScriptedAI
{
public npc_aeranas(Creature creature) : base(creature) { }
public override void Reset()
{
faction_Timer = 8000;
envelopingWinds_Timer = 9000;
shock_Timer = 5000;
me.RemoveNpcFlag(NPCFlags.QuestGiver);
me.SetFaction(Aeranas.FactionFriendly);
Talk(Aeranas.SaySummon);
}
public override void UpdateAI(uint diff)
{
if (faction_Timer != 0)
{
if (faction_Timer <= diff)
{
me.SetFaction(Aeranas.FactionHostile);
faction_Timer = 0;
}
else
faction_Timer -= diff;
}
if (!UpdateVictim())
return;
if (HealthBelowPct(30))
{
me.SetFaction(Aeranas.FactionFriendly);
me.AddNpcFlag(NPCFlags.QuestGiver);
me.RemoveAllAuras();
me.GetThreatManager().ClearAllThreat();
me.CombatStop(true);
Talk(Aeranas.SayFree);
return;
}
if (shock_Timer <= diff)
{
DoCastVictim(Aeranas.SpellShock);
shock_Timer = 10000;
}
else
shock_Timer -= diff;
if (envelopingWinds_Timer <= diff)
{
DoCastVictim(Aeranas.SpellEncelopingWinds);
envelopingWinds_Timer = 25000;
}
else
envelopingWinds_Timer -= diff;
DoMeleeAttackIfReady();
}
uint faction_Timer;
uint envelopingWinds_Timer;
uint shock_Timer;
}
struct AncestralWolf
{
public const uint EmoteWoldLiftHead = 0;
public const uint EmoteWolfHowl = 1;
public const uint SayWolfWelcome = 2;
public const uint SpellAncestralWoldBuff = 29981;
public const uint NpcRyga = 17123;
}
[Script]
class npc_ancestral_wolf : EscortAI
{
public npc_ancestral_wolf(Creature creature) : base(creature)
{
if (creature.GetOwner() && creature.GetOwner().IsTypeId(TypeId.Player))
Start(false, false, creature.GetOwner().GetGUID());
else
Log.outError(LogFilter.Scripts, "Scripts: npc_ancestral_wolf can not obtain owner or owner is not a player.");
creature.SetSpeed(UnitMoveType.Walk, 1.5f);
Reset();
}
public override void Reset()
{
ryga = null;
DoCast(me, AncestralWolf.SpellAncestralWoldBuff, true);
}
public override void MoveInLineOfSight(Unit who)
{
if (!ryga && who.GetEntry() == AncestralWolf.NpcRyga && me.IsWithinDistInMap(who, 15.0f))
{
Creature temp = who.ToCreature();
if (temp)
ryga = temp;
}
base.MoveInLineOfSight(who);
}
public override void WaypointReached(uint waypointId, uint pathId)
{
switch (waypointId)
{
case 0:
Talk(AncestralWolf.EmoteWoldLiftHead);
break;
case 2:
Talk(AncestralWolf.EmoteWolfHowl);
break;
case 50:
if (ryga && ryga.IsAlive() && !ryga.IsInCombat())
ryga.GetAI().Talk(AncestralWolf.SayWolfWelcome);
break;
}
}
Creature ryga;
}
[Script]
class npc_wounded_blood_elf : EscortAI
{
public npc_wounded_blood_elf(Creature creature) : base(creature) { }
public override void Reset() { }
public override void EnterCombat(Unit who)
{
if (HasEscortState(EscortState.Escorting))
Talk(SAY_ELF_AGGRO);
}
public override void JustSummoned(Creature summoned)
{
summoned.GetAI().AttackStart(me);
}
public override void QuestAccept(Player player, Quest quest)
{
if (quest.Id == QUEST_ROAD_TO_FALCON_WATCH)
{
me.SetFaction(FACTION_FALCON_WATCH_QUEST);
Start(true, false, player.GetGUID());
}
}
public override void WaypointReached(uint waypointId, uint pathId)
{
Player player = GetPlayerForEscort();
if (!player)
return;
switch (waypointId)
{
case 0:
Talk(SAY_ELF_START, player);
break;
case 9:
Talk(SAY_ELF_SUMMON1, player);
// Spawn two Haal'eshi Talonguard
DoSpawnCreature(NPC_HAALESHI_TALONGUARD, -15, -15, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
DoSpawnCreature(NPC_HAALESHI_TALONGUARD, -17, -17, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
break;
case 13:
Talk(SAY_ELF_RESTING, player);
break;
case 14:
Talk(SAY_ELF_SUMMON2, player);
// Spawn two Haal'eshi Windwalker
DoSpawnCreature(NPC_HAALESHI_WINDWALKER, -15, -15, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
DoSpawnCreature(NPC_HAALESHI_WINDWALKER, -17, -17, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
break;
case 27:
Talk(SAY_ELF_COMPLETE, player);
// Award quest credit
player.GroupEventHappens(QUEST_ROAD_TO_FALCON_WATCH, me);
break;
}
}
const uint SAY_ELF_START = 0;
const uint SAY_ELF_SUMMON1 = 1;
const uint SAY_ELF_RESTING = 2;
const uint SAY_ELF_SUMMON2 = 3;
const uint SAY_ELF_COMPLETE = 4;
const uint SAY_ELF_AGGRO = 5;
const uint QUEST_ROAD_TO_FALCON_WATCH = 9375;
const uint NPC_HAALESHI_WINDWALKER = 16966;
const uint NPC_HAALESHI_TALONGUARD = 16967;
const uint FACTION_FALCON_WATCH_QUEST = 775;
}
[Script]
class npc_fel_guard_hound : ScriptedAI
{
public npc_fel_guard_hound(Creature creature) : base(creature) { }
public override void Reset()
{
checkTimer = 5000; //check for creature every 5 sec
helboarGUID.Clear();
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point || id != 1)
return;
Creature helboar = me.GetMap().GetCreature(helboarGUID);
if (helboar)
{
helboar.RemoveCorpse();
DoCast(SPELL_SUMMON_POO);
Player owner = me.GetCharmerOrOwnerPlayerOrPlayerItself();
if (owner)
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
}
}
public override void UpdateAI(uint diff)
{
if (checkTimer <= diff)
{
Creature helboar = me.FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false);
if (helboar)
{
if (helboar.GetGUID() != helboarGUID && me.GetMotionMaster().GetCurrentMovementGeneratorType() != MovementGeneratorType.Point && !me.FindCurrentSpellBySpellId(SPELL_SUMMON_POO))
{
helboarGUID = helboar.GetGUID();
me.GetMotionMaster().MovePoint(1, helboar.GetPositionX(), helboar.GetPositionY(), helboar.GetPositionZ());
}
}
checkTimer = 5000;
}
else checkTimer -= diff;
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
uint checkTimer;
ObjectGuid helboarGUID;
const uint SPELL_SUMMON_POO = 37688;
const uint NPC_DERANGED_HELBOAR = 16863;
}
}
-354
View File
@@ -1,354 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.Outlands
{
[Script]
class npcs_ashyen_and_keleth : CreatureScript
{
public npcs_ashyen_and_keleth() : base("npcs_ashyen_and_keleth") { }
class npcs_ashyen_and_kelethAI : ScriptedAI
{
public npcs_ashyen_and_kelethAI(Creature creature) : base(creature) { }
public override bool GossipHello(Player player)
{
if (player.GetReputationRank(942) > ReputationRank.Neutral)
{
if (me.GetEntry() == NPC_ASHYEN)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_BLESS_ASH, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
if (me.GetEntry() == NPC_KELETH)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_BLESS_KEL, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
}
player.SEND_GOSSIP_MENU(player.GetGossipTextId(me), me.GetGUID());
return true;
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId);
player.PlayerTalkClass.ClearMenus();
if (action == eTradeskill.GossipActionInfoDef + 1)
{
me.SetPowerType(PowerType.Mana);
me.SetMaxPower(PowerType.Mana, 200); //set a "fake" mana value, we can't depend on database doing it in this case
me.SetPower(PowerType.Mana, 200);
if (me.GetEntry() == NPC_ASHYEN) //check which Creature we are dealing with
{
uint spell = 0;
switch (player.GetReputationRank(942))
{ //mark of lore
case ReputationRank.Friendly:
spell = SPELL_BLESS_ASH_FRI;
break;
case ReputationRank.Honored:
spell = SPELL_BLESS_ASH_HON;
break;
case ReputationRank.Revered:
spell = SPELL_BLESS_ASH_REV;
break;
case ReputationRank.Exalted:
spell = SPELL_BLESS_ASH_EXA;
break;
default:
break;
}
if (spell != 0)
{
DoCast(player, spell, true);
me.GetAI().Talk(GOSSIP_REWARD_BLESS);
}
}
if (me.GetEntry() == NPC_KELETH)
{
uint spell = 0;
switch (player.GetReputationRank(942)) //mark of war
{
case ReputationRank.Friendly:
spell = SPELL_BLESS_KEL_FRI;
break;
case ReputationRank.Honored:
spell = SPELL_BLESS_KEL_HON;
break;
case ReputationRank.Revered:
spell = SPELL_BLESS_KEL_REV;
break;
case ReputationRank.Exalted:
spell = SPELL_BLESS_KEL_EXA;
break;
default:
break;
}
if (spell != 0)
{
DoCast(player, spell, true);
me.GetAI().Talk(GOSSIP_REWARD_BLESS);
}
}
player.CLOSE_GOSSIP_MENU();
player.TalkedToCreature(me.GetEntry(), me.GetGUID());
}
return true;
}
const uint GOSSIP_REWARD_BLESS = 0;
const uint NPC_ASHYEN = 17900;
const uint NPC_KELETH = 17901;
const uint SPELL_BLESS_ASH_EXA = 31815;
const uint SPELL_BLESS_ASH_REV = 31811;
const uint SPELL_BLESS_ASH_HON = 31810;
const uint SPELL_BLESS_ASH_FRI = 31808;
const uint SPELL_BLESS_KEL_EXA = 31814;
const uint SPELL_BLESS_KEL_REV = 31813;
const uint SPELL_BLESS_KEL_HON = 31812;
const uint SPELL_BLESS_KEL_FRI = 31807;
const string GOSSIP_ITEM_BLESS_ASH = "Grant me your mark, wise ancient.";
const string GOSSIP_ITEM_BLESS_KEL = "Grant me your mark, mighty ancient.";
}
public override CreatureAI GetAI(Creature creature)
{
return new npcs_ashyen_and_kelethAI(creature);
}
}
[Script]
class npc_cooshcoosh : CreatureScript
{
public npc_cooshcoosh() : base("npc_cooshcoosh") { }
class npc_cooshcooshAI : ScriptedAI
{
public npc_cooshcooshAI(Creature creature) : base(creature)
{
m_uiNormFaction = creature.GetFaction();
}
uint m_uiNormFaction;
public override void Reset()
{
_events.ScheduleEvent(Event_LightningBolt, 2000);
if (me.GetFaction() != m_uiNormFaction)
me.SetFaction(m_uiNormFaction);
}
public override void EnterCombat(Unit who) { }
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
_events.ExecuteEvents(id =>
{
DoCastVictim(SPELL_LIGHTNING_BOLT);
_events.ScheduleEvent(Event_LightningBolt, 5000);
});
DoMeleeAttackIfReady();
}
public override bool GossipHello(Player player)
{
if (player.GetQuestStatus(QUEST_CRACK_SKULLS) == QuestStatus.Incomplete)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_COOSH, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef);
player.SEND_GOSSIP_MENU(9441, me.GetGUID());
return true;
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId);
player.PlayerTalkClass.ClearMenus();
if (action == eTradeskill.GossipActionInfoDef)
{
player.CLOSE_GOSSIP_MENU();
me.SetFaction(FACTION_HOSTILE_CO);
me.GetAI().AttackStart(player);
}
return true;
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_cooshcooshAI(creature);
}
const uint SPELL_LIGHTNING_BOLT = 9532;
const uint QUEST_CRACK_SKULLS = 10009;
const uint FACTION_HOSTILE_CO = 45;
const int Event_LightningBolt = 1;
const string GOSSIP_COOSH = "You owe Sim'salabim money. Hand them over or die!";
}
[Script]
class npc_elder_kuruti : CreatureScript
{
public npc_elder_kuruti() : base("npc_elder_kuruti") { }
class npc_elder_kurutiAI : ScriptedAI
{
public npc_elder_kurutiAI(Creature creature) : base(creature) { }
public override bool GossipHello(Player player)
{
if (player.GetQuestStatus(9803) == QuestStatus.Incomplete)
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef);
player.SEND_GOSSIP_MENU(9226, me.GetGUID());
return true;
}
public override bool GossipSelect(Player player, uint menuId, uint gossipListId)
{
uint action = player.PlayerTalkClass.GetGossipOptionAction(gossipListId);
player.PlayerTalkClass.ClearMenus();
switch (action)
{
case eTradeskill.GossipActionInfoDef:
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
player.SEND_GOSSIP_MENU(9227, me.GetGUID());
break;
case eTradeskill.GossipActionInfoDef + 1:
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, GOSSIP_ITEM_KUR3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2);
player.SEND_GOSSIP_MENU(9229, me.GetGUID());
break;
case eTradeskill.GossipActionInfoDef + 2:
{
if (!player.HasItemCount(24573))
{
List<ItemPosCount> dest = new List<ItemPosCount>();
uint itemId = 24573;
uint temp;
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, 1, out temp);
if (msg == InventoryResult.Ok)
{
player.StoreNewItem(dest, itemId, true);
}
else
player.SendEquipError(msg, null, null, itemId);
}
player.SEND_GOSSIP_MENU(9231, me.GetGUID());
break;
}
}
return true;
}
const string GOSSIP_ITEM_KUR1 = "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies.";
const string GOSSIP_ITEM_KUR2 = "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you.";
const string GOSSIP_ITEM_KUR3 = "I will tell them. Farewell, elder.";
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_elder_kurutiAI(creature);
}
}
[Script]
class npc_kayra_longmane : CreatureScript
{
public npc_kayra_longmane() : base("npc_kayra_longmane") { }
class npc_kayra_longmaneAI : EscortAI
{
public npc_kayra_longmaneAI(Creature creature) : base(creature) { }
public override void Reset() { }
public override void WaypointReached(uint waypointId, uint pathId)
{
Player player = GetPlayerForEscort();
if (!player)
return;
switch (waypointId)
{
case 4:
Talk(SAY_AMBUSH1, player);
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
break;
case 5:
Talk(SAY_PROGRESS, player);
SetRun();
break;
case 16:
Talk(SAY_AMBUSH2, player);
DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
break;
case 17:
SetRun(false);
break;
case 25:
Talk(SAY_END, player);
player.GroupEventHappens(QUEST_ESCAPE_FROM, me);
break;
}
}
public override void QuestAccept(Player player, Quest quest)
{
if (quest.Id == QUEST_ESCAPE_FROM)
{
Talk(SAY_START, player);
Start(false, false, player.GetGUID());
}
}
}
public override CreatureAI GetAI(Creature creature)
{
return new npc_kayra_longmaneAI(creature);
}
const uint SAY_START = 0;
const uint SAY_AMBUSH1 = 1;
const uint SAY_PROGRESS = 2;
const uint SAY_AMBUSH2 = 3;
const uint SAY_END = 4;
const uint QUEST_ESCAPE_FROM = 9752;
const uint NPC_SLAVEBINDER = 18042;
}
}
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Pets
{
[Script]
class npc_pet_dk_ebon_gargoyle : CasterAI
{
public npc_pet_dk_ebon_gargoyle(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
ObjectGuid ownerGuid = me.GetOwnerGUID();
if (ownerGuid.IsEmpty())
return;
// Find victim of Summon Gargoyle spell
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 30.0f);
foreach (var iter in targets)
{
if (iter.GetAura(SpellSummonGargoyle1, ownerGuid) != null)
{
me.Attack(iter, false);
break;
}
}
}
public override void JustDied(Unit killer)
{
// Stop Feeding Gargoyle when it dies
Unit owner = me.GetOwner();
if (owner)
owner.RemoveAurasDueToSpell(SpellSummonGargoyle2);
}
// Fly away when dismissed
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Id != SpellDismissGargoyle || !me.IsAlive())
return;
Unit owner = me.GetOwner();
if (!owner || owner != source)
return;
// Stop Fighting
me.AddUnitFlag(UnitFlags.NonAttackable);
// Sanctuary
me.CastSpell(me, SpellSanctuary, true);
me.SetReactState(ReactStates.Passive);
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
// Fly Away
me.SetCanFly(true);
me.SetSpeedRate(UnitMoveType.Flight, 0.75f);
me.SetSpeedRate(UnitMoveType.Run, 0.75f);
float x = me.GetPositionX() + 20 * (float)Math.Cos(me.GetOrientation());
float y = me.GetPositionY() + 20 * (float)Math.Sin(me.GetOrientation());
float z = me.GetPositionZ() + 40;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MovePoint(0, x, y, z);
// Despawn as soon as possible
me.DespawnOrUnsummon(4 * Time.InMilliseconds);
}
const uint SpellSummonGargoyle1 = 49206;
const uint SpellSummonGargoyle2 = 50514;
const uint SpellDismissGargoyle = 50515;
const uint SpellSanctuary = 54661;
}
[Script]
class npc_pet_dk_guardian : AggressorAI
{
public npc_pet_dk_guardian(Creature creature) : base(creature) { }
public override bool CanAIAttack(Unit target)
{
if (!target)
return false;
Unit owner = me.GetOwner();
if (owner && !target.IsInCombatWith(owner))
return false;
return base.CanAIAttack(target);
}
}
}
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Pets
{
namespace DeathKnight
{
struct SpellIds
{
public const uint SummonGargoyle1 = 49206;
public const uint SummonGargoyle2 = 50514;
public const uint DismissGargoyle = 50515;
public const uint Sanctuary = 54661;
}
[Script]
class npc_pet_dk_ebon_gargoyle : CasterAI
{
public npc_pet_dk_ebon_gargoyle(Creature creature) : base(creature) { }
public override void InitializeAI()
{
base.InitializeAI();
ObjectGuid ownerGuid = me.GetOwnerGUID();
if (ownerGuid.IsEmpty())
return;
// Find victim of Summon Gargoyle spell
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 30.0f);
foreach (var iter in targets)
{
if (iter.GetAura(SpellIds.SummonGargoyle1, ownerGuid) != null)
{
me.Attack(iter, false);
break;
}
}
}
public override void JustDied(Unit killer)
{
// Stop Feeding Gargoyle when it dies
Unit owner = me.GetOwner();
if (owner)
owner.RemoveAurasDueToSpell(SpellIds.SummonGargoyle2);
}
// Fly away when dismissed
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Id != SpellIds.DismissGargoyle || !me.IsAlive())
return;
Unit owner = me.GetOwner();
if (!owner || owner != source)
return;
// Stop Fighting
me.AddUnitFlag(UnitFlags.NonAttackable);
// Sanctuary
me.CastSpell(me, SpellIds.Sanctuary, true);
me.SetReactState(ReactStates.Passive);
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
// Fly Away
me.SetCanFly(true);
me.SetSpeedRate(UnitMoveType.Flight, 0.75f);
me.SetSpeedRate(UnitMoveType.Run, 0.75f);
float x = me.GetPositionX() + 20 * (float)Math.Cos(me.GetOrientation());
float y = me.GetPositionY() + 20 * (float)Math.Sin(me.GetOrientation());
float z = me.GetPositionZ() + 40;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MovePoint(0, x, y, z);
// Despawn as soon as possible
me.DespawnOrUnsummon(4 * Time.InMilliseconds);
}
}
[Script]
class npc_pet_dk_guardian : AggressorAI
{
public npc_pet_dk_guardian(Creature creature) : base(creature) { }
public override bool CanAIAttack(Unit target)
{
if (!target)
return false;
Unit owner = me.GetOwner();
if (owner && !target.IsInCombatWith(owner))
return false;
return base.CanAIAttack(target);
}
}
}
}
+51 -41
View File
@@ -22,54 +22,64 @@ using Game.Scripting;
namespace Scripts.Pets
{
[Script]
class npc_pet_gen_mojo : ScriptedAI
namespace Generic
{
public npc_pet_gen_mojo(Creature creature) : base(creature) { }
public override void Reset()
struct SpellIds
{
_victimGUID.Clear();
Unit owner = me.GetOwner();
if (owner)
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
public const uint FeelingFroggy = 43906;
public const uint SeductionVisual = 43919;
}
public override void EnterCombat(Unit who) { }
public override void UpdateAI(uint diff) { }
public override void ReceiveEmote(Player player, TextEmotes emote)
struct TextIds
{
me.HandleEmoteCommand((Emote)emote);
Unit owner = me.GetOwner();
if (emote != TextEmotes.Kiss || !owner || !owner.IsTypeId(TypeId.Player) ||
owner.ToPlayer().GetTeam() != player.GetTeam())
{
return;
}
Talk(SayMojo, player);
if (!_victimGUID.IsEmpty())
{
Player victim = Global.ObjAccessor.GetPlayer(me, _victimGUID);
if (victim)
victim.RemoveAura(SpellFeelingFroggy);
}
_victimGUID = player.GetGUID();
DoCast(player, SpellFeelingFroggy, true);
DoCast(me, SpellSeductionVisual, true);
me.GetMotionMaster().MoveFollow(player, 0.0f, 0.0f);
public const uint SayMojo = 0;
}
ObjectGuid _victimGUID;
[Script]
class npc_pet_gen_mojo : ScriptedAI
{
public npc_pet_gen_mojo(Creature creature) : base(creature) { }
const uint SayMojo = 0;
const uint SpellFeelingFroggy = 43906;
const uint SpellSeductionVisual = 43919;
public override void Reset()
{
_victimGUID.Clear();
Unit owner = me.GetOwner();
if (owner)
me.GetMotionMaster().MoveFollow(owner, 0.0f, 0.0f);
}
public override void EnterCombat(Unit who) { }
public override void UpdateAI(uint diff) { }
public override void ReceiveEmote(Player player, TextEmotes emote)
{
me.HandleEmoteCommand((Emote)emote);
Unit owner = me.GetOwner();
if (emote != TextEmotes.Kiss || !owner || !owner.IsTypeId(TypeId.Player) ||
owner.ToPlayer().GetTeam() != player.GetTeam())
{
return;
}
Talk(TextIds.SayMojo, player);
if (!_victimGUID.IsEmpty())
{
Player victim = Global.ObjAccessor.GetPlayer(me, _victimGUID);
if (victim)
victim.RemoveAura(SpellIds.FeelingFroggy);
}
_victimGUID = player.GetGUID();
DoCast(player, SpellIds.FeelingFroggy, true);
DoCast(me, SpellIds.SeductionVisual, true);
me.GetMotionMaster().MoveFollow(player, 0.0f, 0.0f);
}
ObjectGuid _victimGUID;
}
}
}
+81 -71
View File
@@ -22,96 +22,106 @@ using Game.Scripting;
namespace Scripts.Pets
{
[Script]
class npc_pet_hunter_snake_trap : ScriptedAI
namespace Hunter
{
public npc_pet_hunter_snake_trap(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who) { }
public override void Reset()
struct SpellIds
{
_spellTimer = 0;
public const uint CripplingPoison = 30981; // Viper
public const uint DeadlyPoisonPassive = 34657; // Venomous Snake
public const uint MindNumbingPoison = 25810; // Viper
CreatureTemplate Info = me.GetCreatureTemplate();
_isViper = Info.Entry == NpcViper ? true : false;
me.SetMaxHealth((uint)(107 * (me.GetLevel() - 40) * 0.025f));
// Add delta to make them not all hit the same time
uint delta = (RandomHelper.Rand32() % 7) * 100;
me.SetBaseAttackTime(WeaponAttackType.BaseAttack, Info.BaseAttackTime + delta);
//me.SetStatFloatValue(UnitFields.RangedAttackPower, (float)Info.AttackPower);
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
if (!me.GetVictim() && me.IsSummon())
{
Unit owner = me.ToTempSummon().GetSummoner();
if (owner)
if (owner.GetAttackerForHelper())
AttackStart(owner.GetAttackerForHelper());
}
if (!_isViper)
DoCast(me, SpellDeadlyPoisonPassive, true);
}
// Redefined for random target selection:
public override void MoveInLineOfSight(Unit who)
struct CreatureIds
{
if (!me.GetVictim() && me.CanCreatureAttack(who))
{
if (me.GetDistanceZ(who) > SharedConst.CreatureAttackRangeZ)
return;
public const int Viper = 19921;
}
float attackRadius = me.GetAttackDistance(who);
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
[Script]
class npc_pet_hunter_snake_trap : ScriptedAI
{
public npc_pet_hunter_snake_trap(Creature creature) : base(creature) { }
public override void EnterCombat(Unit who) { }
public override void Reset()
{
_spellTimer = 0;
CreatureTemplate Info = me.GetCreatureTemplate();
_isViper = Info.Entry == CreatureIds.Viper ? true : false;
me.SetMaxHealth((uint)(107 * (me.GetLevel() - 40) * 0.025f));
// Add delta to make them not all hit the same time
uint delta = (RandomHelper.Rand32() % 7) * 100;
me.SetBaseAttackTime(WeaponAttackType.BaseAttack, Info.BaseAttackTime + delta);
//me.SetStatFloatValue(UnitFields.RangedAttackPower, (float)Info.AttackPower);
// Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
if (!me.GetVictim() && me.IsSummon())
{
if ((RandomHelper.Rand32() % 5) == 0)
Unit owner = me.ToTempSummon().GetSummoner();
if (owner)
if (owner.GetAttackerForHelper())
AttackStart(owner.GetAttackerForHelper());
}
if (!_isViper)
DoCast(me, SpellIds.DeadlyPoisonPassive, true);
}
// Redefined for random target selection:
public override void MoveInLineOfSight(Unit who)
{
if (!me.GetVictim() && me.CanCreatureAttack(who))
{
if (me.GetDistanceZ(who) > SharedConst.CreatureAttackRangeZ)
return;
float attackRadius = me.GetAttackDistance(who);
if (me.IsWithinDistInMap(who, attackRadius) && me.IsWithinLOSInMap(who))
{
me.SetAttackTimer(WeaponAttackType.BaseAttack, (RandomHelper.Rand32() % 10) * 100);
_spellTimer = (RandomHelper.Rand32() % 10) * 100;
AttackStart(who);
if ((RandomHelper.Rand32() % 5) == 0)
{
me.SetAttackTimer(WeaponAttackType.BaseAttack, (RandomHelper.Rand32() % 10) * 100);
_spellTimer = (RandomHelper.Rand32() % 10) * 100;
AttackStart(who);
}
}
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || !me.GetVictim())
return;
if (me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
public override void UpdateAI(uint diff)
{
me.InterruptNonMeleeSpells(false);
return;
}
if (!UpdateVictim() || !me.GetVictim())
return;
//Viper
if (_isViper)
{
if (_spellTimer <= diff)
if (me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
if (RandomHelper.IRand(0, 2) == 0) //33% chance to cast
DoCastVictim(RandomHelper.RAND(SpellMindNumbingPoison, SpellCripplingPoison));
_spellTimer = 3000;
me.InterruptNonMeleeSpells(false);
return;
}
else
_spellTimer -= diff;
//Viper
if (_isViper)
{
if (_spellTimer <= diff)
{
if (RandomHelper.IRand(0, 2) == 0) //33% chance to cast
DoCastVictim(RandomHelper.RAND(SpellIds.MindNumbingPoison, SpellIds.CripplingPoison));
_spellTimer = 3000;
}
else
_spellTimer -= diff;
}
DoMeleeAttackIfReady();
}
DoMeleeAttackIfReady();
bool _isViper;
uint _spellTimer;
}
bool _isViper;
uint _spellTimer;
const uint SpellCripplingPoison = 30981; // Viper
const uint SpellDeadlyPoisonPassive = 34657; // Venomous Snake
const uint SpellMindNumbingPoison = 25810; // Viper
const int NpcViper = 19921;
}
}
+190 -179
View File
@@ -21,221 +21,232 @@ using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
using System;
namespace Scripts.Pets
{
struct PetMageConst
namespace Mage
{
public const uint SpellCloneMe = 45204;
public const uint SpellMastersThreatList = 58838;
public const uint SpellMageFrostBolt = 59638;
public const uint SpellMageFireBlast = 59637;
public const uint TimerMirrorImageInit = 0;
public const uint TimerMirrorImageFrostBolt = 4000;
public const uint TimerMirrorImageFireBlast = 6000;
}
[Script]
class npc_pet_mage_mirror_image : CasterAI
{
public npc_pet_mage_mirror_image(Creature creature) : base(creature) { }
void Init()
struct SpellIds
{
Unit owner = me.GetCharmerOrOwner();
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
Unit highestThreatUnit = null;
float highestThreat = 0.0f;
Unit nearestPlayer = null;
foreach (var unit in targets)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
// Take first found unit
if (!highestThreatUnit && !unit.IsTypeId(TypeId.Player))
{
highestThreatUnit = unit;
continue;
}
if (!nearestPlayer && unit.IsTypeId(TypeId.Player))
{
nearestPlayer = unit;
continue;
}
// else compare best fit unit with current unit
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
{
// Check if best fit hostile unit hs lower threat than this current unit
if (highestThreat < reference.GetThreat())
{
// If so, update best fit unit
highestThreat = reference.GetThreat();
highestThreatUnit = unit;
break;
}
}
}
// In case no unit with threat was found so far, always check for nearest unit (only for players)
if (unit.IsTypeId(TypeId.Player))
{
// If this player is closer than the previous one, update it
if (me.GetDistance(unit.GetPosition()) < me.GetDistance(nearestPlayer.GetPosition()))
nearestPlayer = unit;
}
}
}
// Prioritize units with threat referenced to owner
if (highestThreat > 0.0f && highestThreatUnit)
me.Attack(highestThreatUnit, false);
// If there is no such target, try to attack nearest hostile unit if such exists
else if (nearestPlayer)
me.Attack(nearestPlayer, false);
public const uint CloneMe = 45204;
public const uint MastersThreatList = 58838;
public const uint MageFrostBolt = 59638;
public const uint MageFireBlast = 59637;
}
bool IsInThreatList(Unit target)
struct MiscConst
{
Unit owner = me.GetCharmerOrOwner();
public const uint TimerMirrorImageInit = 0;
public const uint TimerMirrorImageFrostBolt = 4000;
public const uint TimerMirrorImageFireBlast = 6000;
}
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
[Script]
class npc_pet_mage_mirror_image : CasterAI
{
public npc_pet_mage_mirror_image(Creature creature) : base(creature) { }
foreach (var unit in targets)
void Init()
{
if (unit == target)
Unit owner = me.GetCharmerOrOwner();
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
Unit highestThreatUnit = null;
float highestThreat = 0.0f;
Unit nearestPlayer = null;
foreach (var unit in targets)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
// Take first found unit
if (!highestThreatUnit && !unit.IsTypeId(TypeId.Player))
{
highestThreatUnit = unit;
continue;
}
if (!nearestPlayer && unit.IsTypeId(TypeId.Player))
{
nearestPlayer = unit;
continue;
}
// else compare best fit unit with current unit
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
return true;
{
// Check if best fit hostile unit hs lower threat than this current unit
if (highestThreat < reference.GetThreat())
{
// If so, update best fit unit
highestThreat = reference.GetThreat();
highestThreatUnit = unit;
break;
}
}
}
// In case no unit with threat was found so far, always check for nearest unit (only for players)
if (unit.IsTypeId(TypeId.Player))
{
// If this player is closer than the previous one, update it
if (me.GetDistance(unit.GetPosition()) < me.GetDistance(nearestPlayer.GetPosition()))
nearestPlayer = unit;
}
}
}
}
return false;
}
public override void InitializeAI()
{
base.InitializeAI();
Unit owner = me.GetOwner();
if (!owner)
return;
// here mirror image casts on summoner spell (not present in client dbc) 49866
// here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
// Clone Me!
owner.CastSpell(me, PetMageConst.SpellCloneMe, false);
}
public override void EnterCombat(Unit victim)
{
if (me.GetVictim() && !me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.CastSpell(victim, PetMageConst.SpellMageFireBlast, false);
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageInit);
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
}
else
EnterEvadeMode(EvadeReason.Other);
}
public override void Reset()
{
_events.Reset();
}
public override void UpdateAI(uint diff)
{
Unit owner = me.GetCharmerOrOwner();
if (!owner)
return;
Unit target = owner.GetAttackerForHelper();
_events.Update(diff);
// prevent CC interrupts by images
if (me.GetVictim() && me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.InterruptNonMeleeSpells(false);
return;
// Prioritize units with threat referenced to owner
if (highestThreat > 0.0f && highestThreatUnit)
me.Attack(highestThreatUnit, false);
// If there is no such target, try to attack nearest hostile unit if such exists
else if (nearestPlayer)
me.Attack(nearestPlayer, false);
}
if (me.HasUnitState(UnitState.Casting))
return;
// assign target if image doesnt have any or the target is not actual
if (!target || me.GetVictim() != target)
bool IsInThreatList(Unit target)
{
Unit ownerTarget = null;
Player owner1 = me.GetCharmerOrOwner().ToPlayer();
if (owner1)
ownerTarget = owner1.GetSelectedUnit();
Unit owner = me.GetCharmerOrOwner();
// recognize which victim will be choosen
if (ownerTarget && ownerTarget.IsTypeId(TypeId.Player))
List<Unit> targets = new List<Unit>();
var u_check = new AnyUnfriendlyUnitInObjectRangeCheck(me, me, 30.0f);
var searcher = new UnitListSearcher(me, targets, u_check);
Cell.VisitAllObjects(me, searcher, 40.0f);
foreach (var unit in targets)
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
if (unit == target)
{
// Consider only units without CC
if (!unit.HasBreakableByDamageCrowdControlAura(unit))
{
var triggers = unit.GetThreatManager().GetThreatList();
foreach (var reference in triggers)
{
// Try to find threat referenced to owner
if (reference.GetTarget() == owner)
return true;
}
}
}
}
else if (ownerTarget && !ownerTarget.IsTypeId(TypeId.Player) && IsInThreatList(ownerTarget))
return false;
}
public override void InitializeAI()
{
base.InitializeAI();
Unit owner = me.GetOwner();
if (!owner)
return;
// here mirror image casts on summoner spell (not present in client dbc) 49866
// here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
// Clone Me!
owner.CastSpell(me, SpellIds.CloneMe, false);
}
public override void EnterCombat(Unit victim)
{
if (me.GetVictim() && !me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
me.CastSpell(victim, SpellIds.MageFireBlast, false);
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.MageFrostBolt);
task.Repeat(TimeSpan.FromSeconds(4));
});
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
{
DoCastVictim(SpellIds.MageFireBlast);
task.Repeat();
});
}
else
Init();
EnterEvadeMode(EvadeReason.Other);
}
_events.ExecuteEvents(spellId =>
public override void Reset()
{
if (spellId == PetMageConst.SpellMageFrostBolt)
{
_events.ScheduleEvent(PetMageConst.SpellMageFrostBolt, PetMageConst.TimerMirrorImageFrostBolt);
DoCastVictim(spellId);
}
else if (spellId == PetMageConst.SpellMageFireBlast)
{
DoCastVictim(spellId);
_events.ScheduleEvent(PetMageConst.SpellMageFireBlast, PetMageConst.TimerMirrorImageFireBlast);
}
});
}
// Do not reload Creature templates on evade mode enter - prevent visual lost
public override void EnterEvadeMode(EvadeReason why)
{
if (me.IsInEvadeMode() || !me.IsAlive())
return;
Unit owner = me.GetCharmerOrOwner();
me.CombatStop(true);
if (owner && !me.HasUnitState(UnitState.Follow))
{
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, me.GetFollowAngle(), MovementSlot.Active);
_scheduler.CancelAll();
}
public override void UpdateAI(uint diff)
{
Unit owner = me.GetCharmerOrOwner();
if (!owner)
return;
Unit target = owner.GetAttackerForHelper();
_scheduler.Update(diff);
// prevent CC interrupts by images
if (me.GetVictim() && me.GetVictim().HasBreakableByDamageCrowdControlAura(me))
{
me.InterruptNonMeleeSpells(false);
return;
}
if (me.HasUnitState(UnitState.Casting))
return;
// assign target if image doesnt have any or the target is not actual
if (!target || me.GetVictim() != target)
{
Unit ownerTarget = null;
Player owner1 = me.GetCharmerOrOwner().ToPlayer();
if (owner1)
ownerTarget = owner1.GetSelectedUnit();
// recognize which victim will be choosen
if (ownerTarget && ownerTarget.IsTypeId(TypeId.Player))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
}
else if (ownerTarget && !ownerTarget.IsTypeId(TypeId.Player) && IsInThreatList(ownerTarget))
{
if (!ownerTarget.HasBreakableByDamageCrowdControlAura(ownerTarget))
me.Attack(ownerTarget, false);
}
else
Init();
}
_events.ExecuteEvents(eventId =>
{
if (eventId == SpellIds.MageFrostBolt)
{
}
else if (eventId == SpellIds.MageFireBlast)
{
}
});
}
// Do not reload Creature templates on evade mode enter - prevent visual lost
public override void EnterEvadeMode(EvadeReason why)
{
if (me.IsInEvadeMode() || !me.IsAlive())
return;
Unit owner = me.GetCharmerOrOwner();
me.CombatStop(true);
if (owner && !me.HasUnitState(UnitState.Follow))
{
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveFollow(owner, SharedConst.PetFollowDist, me.GetFollowAngle(), MovementSlot.Active);
}
Init();
}
Init();
}
}
}
+30 -27
View File
@@ -20,43 +20,46 @@ using Game.AI;
using Game.Entities;
using Game.Scripting;
namespace Scripts.Pets.Priest
namespace Scripts.Pets
{
struct SpellIds
namespace Priest
{
public const uint GlyphOfShadowFiend = 58228;
public const uint ShadowFiendDeath = 57989;
public const uint LightWellCharges = 59907;
}
[Script]
class npc_pet_pri_lightwell : PassiveAI
{
public npc_pet_pri_lightwell(Creature creature) : base(creature)
struct SpellIds
{
DoCast(creature, SpellIds.LightWellCharges, false);
public const uint GlyphOfShadowFiend = 58228;
public const uint ShadowFiendDeath = 57989;
public const uint LightWellCharges = 59907;
}
public override void EnterEvadeMode(EvadeReason why)
[Script]
class npc_pet_pri_lightwell : PassiveAI
{
if (!me.IsAlive())
return;
public npc_pet_pri_lightwell(Creature creature) : base(creature)
{
DoCast(creature, SpellIds.LightWellCharges, false);
}
me.GetThreatManager().ClearAllThreat();
me.CombatStop(true);
me.ResetPlayerDamageReq();
public override void EnterEvadeMode(EvadeReason why)
{
if (!me.IsAlive())
return;
me.GetThreatManager().ClearAllThreat();
me.CombatStop(true);
me.ResetPlayerDamageReq();
}
}
}
[Script]
class npc_pet_pri_shadowfiend : PetAI
{
public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
[Script]
class npc_pet_pri_shadowfiend : PetAI
{
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
DoCastAOE(SpellIds.ShadowFiendDeath);
public npc_pet_pri_shadowfiend(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
if (summoner.HasAura(SpellIds.GlyphOfShadowFiend))
DoCastAOE(SpellIds.ShadowFiendDeath);
}
}
}
}
+67 -73
View File
@@ -19,95 +19,89 @@ using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Pets
{
[Script]
class npc_pet_shaman_earth_elemental : ScriptedAI
namespace Shaman
{
public npc_pet_shaman_earth_elemental(Creature creature) : base(creature) { }
public override void Reset()
struct SpellIds
{
_events.Reset();
_events.ScheduleEvent(EventAngeredEarth, 0);
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
//npc_pet_shaman_earth_elemental
public const uint AngeredEarth = 36213;
//npc_pet_shaman_fire_elemental
public const uint FireBlast = 57984;
public const uint FireNova = 12470;
public const uint FireShield = 13376;
}
public override void UpdateAI(uint diff)
[Script]
class npc_pet_shaman_earth_elemental : ScriptedAI
{
if (!UpdateVictim())
return;
public npc_pet_shaman_earth_elemental(Creature creature) : base(creature) { }
_events.Update(diff);
if (_events.ExecuteEvent() == EventAngeredEarth)
public override void Reset()
{
DoCastVictim(SpellAngeredEarth);
_events.ScheduleEvent(EventAngeredEarth, RandomHelper.URand(5000, 20000));
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.AngeredEarth);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Nature, true);
}
DoMeleeAttackIfReady();
}
const int EventAngeredEarth = 1;
const uint SpellAngeredEarth = 36213;
}
[Script]
public class npc_pet_shaman_fire_elemental : ScriptedAI
{
public npc_pet_shaman_fire_elemental(Creature creature) : base(creature) { }
public override void Reset()
{
_events.Reset();
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
_events.ScheduleEvent(EventFireShield, 0);
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Fire, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_events.Update(diff);
_events.ExecuteEvents(eventId =>
public override void UpdateAI(uint diff)
{
switch (eventId)
{
case EventFireNova:
DoCastVictim(SpellFireNova);
_events.ScheduleEvent(EventFireNova, RandomHelper.URand(5000, 20000));
break;
case EventFireShield:
DoCastVictim(SpellFireShield);
_events.ScheduleEvent(EventFireShield, 2000);
break;
case EventFireBlast:
DoCastVictim(SpellFireBlast);
_events.ScheduleEvent(EventFireBlast, RandomHelper.URand(5000, 20000));
break;
default:
break;
}
});
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
}
const int EventFireNova = 1;
const int EventFireShield = 2;
const int EventFireBlast = 3;
[Script]
public class npc_pet_shaman_fire_elemental : ScriptedAI
{
public npc_pet_shaman_fire_elemental(Creature creature) : base(creature) { }
const uint SpellFireBlast = 57984;
const uint SpellFireNova = 12470;
const uint SpellFireShield = 13376;
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.FireNova);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.FireShield);
task.Repeat(TimeSpan.FromSeconds(2));
});
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
{
DoCastVictim(SpellIds.FireBlast);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20));
});
me.ApplySpellImmune(0, SpellImmunity.School, SpellSchoolMask.Fire, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (me.HasUnitState(UnitState.Casting))
return;
DoMeleeAttackIfReady();
}
}
}
}
+2 -2
View File
@@ -300,7 +300,7 @@ namespace Scripts.Spells.DeathKnight
}
[Script]
class spell_dk_death_and_decay_AuraScript: AuraScript
class spell_dk_death_and_decay_AuraScript : AuraScript
{
void HandleDummyTick(AuraEffect aurEff)
{
@@ -429,7 +429,7 @@ namespace Scripts.Spells.DeathKnight
void HandleHeal(uint effIndex)
{
Unit caster = GetCaster();
//TODO: heal = std::min(10% health, 20% of all damage taken in last 5 seconds)
//TODO: heal = Math.Min(10% health, 20% of all damage taken in last 5 seconds)
int heal = (int)MathFunctions.CalculatePct(caster.GetMaxHealth(), GetSpellInfo().GetEffect(4).CalcValue());
caster.CastCustomSpell(SpellIds.DeathStrikeHeal, SpellValueMod.BasePoint0, heal, caster, true);
+6 -6
View File
@@ -742,7 +742,7 @@ namespace Scripts.Spells.Druid
void AfterRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
// No need to check remove mode, it's safe for auras to remove each other in AfterRemove hook.
// No need to check Remove mode, it's safe for auras to Remove each other in AfterRemove hook.
GetTarget().RemoveAura(SpellIds.FormStag);
GetTarget().RemoveAura(SpellIds.FormAquatic);
GetTarget().RemoveAura(SpellIds.FormFlight);
@@ -782,7 +782,7 @@ namespace Scripts.Spells.Druid
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
// If it stays 0, it removes Travel Form dummy in AfterRemove.
// If it stays 0, it Removes Travel Form dummy in AfterRemove.
triggeredSpellId = 0;
// We should only handle aura interrupts.
@@ -798,7 +798,7 @@ namespace Scripts.Spells.Druid
else if (CheckLocationForForm(SpellIds.FormStag) == SpellCastResult.SpellCastOk) // Stag form
triggeredSpellId = SpellIds.FormStag;
// If chosen form is current aura, just don't remove it.
// If chosen form is current aura, just don't Remove it.
if (triggeredSpellId == m_scriptSpellId)
PreventDefaultAction();
}
@@ -809,7 +809,7 @@ namespace Scripts.Spells.Druid
if (triggeredSpellId != 0) // Apply new form
player.AddAura(triggeredSpellId, player);
else // If not set, simply remove Travel Form dummy
else // If not set, simply Remove Travel Form dummy
player.RemoveAura(SpellIds.TravelForm);
}
@@ -1004,8 +1004,8 @@ namespace Scripts.Spells.Druid
{
public override bool Validate(SpellInfo spellInfo)
{
SpellEffectInfo effect2 = spellInfo.GetEffect(2);
if (effect2 == null || effect2.IsEffect() || effect2.CalcValue() <= 0)
SpellEffectInfo effectInfo = spellInfo.GetEffect(2);
if (effectInfo == null || effectInfo.IsEffect() || effectInfo.CalcValue() <= 0)
return false;
return true;
}
+9 -158
View File
@@ -140,8 +140,8 @@ namespace Scripts.Spells.Generic
public const uint Damage45k = 64591;
public const uint ChargingEffect8k5 = 63661;
public const uint ChargingEffect20k1 = 68284;
public const uint ChargingEffect20k2 = 68501;
public const uint Charging20k1 = 68284;
public const uint Charging20k2 = 68501;
public const uint ChargingEffect45k1 = 62563;
public const uint ChargingEffect45k2 = 66481;
@@ -269,7 +269,7 @@ namespace Scripts.Spells.Generic
public const uint MarkOfKazrogalHellfire = 189512;
public const uint MarkOfKazrogalDamageHellfire = 189515;
// Auraprocremovespells
// AuraprocRemovespells
public const uint FaceRage = 99947;
public const uint ImpatientMind = 187213;
}
@@ -1184,7 +1184,7 @@ namespace Scripts.Spells.Generic
if (spell.GetEffect(2).ApplyAuraName == AuraType.ModDamagePercentTaken)
OnEffectRemove.Add(new EffectApplyHandler(RemoveDummyFromDriver, 2, AuraType.ModDamagePercentTaken, AuraEffectHandleModes.Real));
// Defend spells cast by players (add/remove visuals)
// Defend spells cast by players (add/Remove visuals)
if (spell.GetEffect(1).ApplyAuraName == AuraType.Dummy)
{
AfterEffectApply.Add(new EffectApplyHandler(RefreshVisualShields, 1, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask));
@@ -1550,7 +1550,7 @@ namespace Scripts.Spells.Generic
switch (GetSpellInfo().Id)
{
case SpellIds.TriggerTrialChampion:
spellId = SpellIds.ChargingEffect20k1;
spellId = SpellIds.Charging20k1;
break;
case SpellIds.TriggerFactionMounts:
spellId = SpellIds.ChargingEffect8k5;
@@ -1608,8 +1608,8 @@ namespace Scripts.Spells.Generic
case SpellIds.ChargingEffect8k5:
spellId = SpellIds.Damage8k5;
break;
case SpellIds.ChargingEffect20k1:
case SpellIds.ChargingEffect20k2:
case SpellIds.Charging20k1:
case SpellIds.Charging20k2:
spellId = SpellIds.Damage20k;
break;
case SpellIds.ChargingEffect45k1:
@@ -1662,7 +1662,7 @@ namespace Scripts.Spells.Generic
// triggered spells are 28703 to 28707
// Note: some sources say, that there was the possibility of
// receiving a debuff. However, this seems to be removed by a patch.
// receiving a debuff. However, this seems to be Removed by a patch.
// don't overwrite an existing aura
for (byte i = 0; i < 5; ++i)
@@ -1762,155 +1762,6 @@ namespace Scripts.Spells.Generic
}
}
[Script]
class spell_gen_on_tournament_mount : AuraScript
{
uint _pennantSpellId;
public override bool Load()
{
_pennantSpellId = 0;
return GetCaster() && GetCaster().IsTypeId(TypeId.Player);
}
void HandleApplyEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
{
Unit vehicle = caster.GetVehicleBase();
if (vehicle)
{
_pennantSpellId = GetPennatSpellId(caster.ToPlayer(), vehicle);
caster.CastSpell(caster, _pennantSpellId, true);
}
}
}
void HandleRemoveEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Unit caster = GetCaster();
if (caster)
caster.RemoveAurasDueToSpell(_pennantSpellId);
}
uint GetPennatSpellId(Player player, Unit mount)
{
switch (mount.GetEntry())
{
case CreatureIds.ArgentSteedAspirant:
case CreatureIds.StormwindSteed:
{
if (player.HasAchieved(AchievementIds.ChampionStormwind))
return SpellIds.StormwindChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfStormwind) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfStormwind))
return SpellIds.StormwindValiant;
else
return SpellIds.StormwindAspirant;
}
case CreatureIds.GnomereganMechanostrider:
{
if (player.HasAchieved(AchievementIds.ChampionGnomeregan))
return SpellIds.GnomereganChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfGnomeregan) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfGnomeregan))
return SpellIds.GnomereganValiant;
else
return SpellIds.GnomereganAspirant;
}
case CreatureIds.DarkSpearRaptor:
{
if (player.HasAchieved(AchievementIds.ChampionSenJin))
return SpellIds.SenjinChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfSenJin) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfSenJin))
return SpellIds.SenjinValiant;
else
return SpellIds.SenjinAspirant;
}
case CreatureIds.ArgentHawkstriderAspirant:
case CreatureIds.SilvermoonHawkstrider:
{
if (player.HasAchieved(AchievementIds.ChampionSilvermoon))
return SpellIds.SilvermoonChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfSilvermoon) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfSilvermoon))
return SpellIds.SilvermoonValiant;
else
return SpellIds.SilvermoonAspirant;
}
case CreatureIds.DarnassianNightsaber:
{
if (player.HasAchieved(AchievementIds.ChampionDarnassus))
return SpellIds.DarnassusChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfDarnassus) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfDarnassus))
return SpellIds.DarnassusValiant;
else
return SpellIds.DarnassusAspirant;
}
case CreatureIds.ExodarElekk:
{
if (player.HasAchieved(AchievementIds.ChampionTheExodar))
return SpellIds.ExodarChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfTheExodar) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfTheExodar))
return SpellIds.ExodarValiant;
else
return SpellIds.ExodarAspirant;
}
case CreatureIds.IronforgeRam:
{
if (player.HasAchieved(AchievementIds.ChampionIronforge))
return SpellIds.IronforgeChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfIronforge) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfIronforge))
return SpellIds.IronforgeValiant;
else
return SpellIds.IronforgeAspirant;
}
case CreatureIds.ForsakenWarhorse:
{
if (player.HasAchieved(AchievementIds.ChampionUndercity))
return SpellIds.UndercityChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfUndercity) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfUndercity))
return SpellIds.UndercityValiant;
else
return SpellIds.UndercityAspirant;
}
case CreatureIds.OrgrimmarWolf:
{
if (player.HasAchieved(AchievementIds.ChampionOrgrimmar))
return SpellIds.OrgrimmarChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfOrgrimmar) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfOrgrimmar))
return SpellIds.OrgrimmarValiant;
else
return SpellIds.OrgrimmarAspirant;
}
case CreatureIds.ThunderBluffKodo:
{
if (player.HasAchieved(AchievementIds.ChampionThunderBluff))
return SpellIds.ThunderbluffChampion;
else if (player.GetQuestRewardStatus(QuestIds.ValiantOfThunderBluff) || player.GetQuestRewardStatus(QuestIds.A_ValiantOfThunderBluff))
return SpellIds.ThunderbluffValiant;
else
return SpellIds.ThunderbluffAspirant;
}
case CreatureIds.ArgentWarhorse:
{
if (player.HasAchieved(AchievementIds.ChampionAlliance) || player.HasAchieved(AchievementIds.ChampionHorde))
return player.GetClass() == Class.Deathknight ? SpellIds.EbonbladeChampion : SpellIds.ArgentcrusadeChampion;
else if (player.HasAchieved(AchievementIds.ArgentValor))
return player.GetClass() == Class.Deathknight ? SpellIds.EbonbladeValiant : SpellIds.ArgentcrusadeValiant;
else
return player.GetClass() == Class.Deathknight ? SpellIds.EbonbladeAspirant : SpellIds.ArgentcrusadeAspirant;
}
default:
return 0;
}
}
public override void Register()
{
AfterEffectApply.Add(new EffectApplyHandler(HandleApplyEffect, 0, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask));
OnEffectRemove.Add(new EffectApplyHandler(HandleRemoveEffect, 0, AuraType.Dummy, AuraEffectHandleModes.RealOrReapplyMask));
}
}
[Script]
class spell_gen_oracle_wolvar_reputation : SpellScript
{
@@ -2875,7 +2726,7 @@ namespace Scripts.Spells.Generic
player.InterruptNonMeleeSpells(true);
player.AddUnitFlag(UnitFlags.NonAttackable);
// if player class = hunter || warlock remove pet if alive
// if player class = hunter || warlock Remove pet if alive
if ((player.GetClass() == Class.Hunter) || (player.GetClass() == Class.Warlock))
{
Pet pet = player.GetPet();
+2 -5
View File
@@ -159,9 +159,6 @@ namespace Scripts.Spells.Holiday
{
public const uint RibbonPole = 181605;
}
[Script] // 45102 Romantic Picnic
class spell_love_is_in_the_air_romantic_picnic : AuraScript
{
@@ -178,7 +175,7 @@ namespace Scripts.Spells.Holiday
Unit target = GetTarget();
Unit caster = GetCaster();
// If our player is no longer sit, remove all auras
// If our player is no longer sit, Remove all auras
if (target.GetStandState() != UnitStandStateType.Sit)
{
target.RemoveAura(SpellIds.RomanticPicnicAchiev);
@@ -756,7 +753,7 @@ namespace Scripts.Spells.Holiday
{
Unit target = GetTarget();
// check if aura needs to be removed
// check if aura needs to be Removed
if (!target.FindNearestGameObject(GameobjectIds.RibbonPole, 8.0f) || !target.HasUnitState(UnitState.Casting))
{
target.InterruptNonMeleeSpells(false);
+2 -2
View File
@@ -300,7 +300,7 @@ namespace Scripts.Spells.Hunter
{
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Default || GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Interrupt)
return;
if (!GetTarget().HasAura(SpellIds.MisdirectionProc))
GetTarget().ResetRedirectThreat();
}
@@ -524,7 +524,7 @@ namespace Scripts.Spells.Hunter
void HandleDummy(uint effIndex)
{
Player caster = GetCaster().ToPlayer();
// break Auto Shot and autohit
// break auto Shot and varhit
caster.InterruptSpell(CurrentSpellTypes.AutoRepeat);
caster.AttackStop();
caster.SendAttackSwingCancelAttack();
+23 -23
View File
@@ -368,7 +368,7 @@ namespace Scripts.Spells.Items
public const uint UnstablePowerAuraStack = 24659;
public const uint RestlessStrengthAuraStack = 24662;
// Auraprocremovespells
// AuraprocRemovespells
public const uint TalismanOfAscendance = 28200;
public const uint JomGabbar = 29602;
public const uint BattleTrance = 45040;
@@ -655,27 +655,27 @@ namespace Scripts.Spells.Items
//CLASS_NONE
new uint[] { },
//CLASS_WARRIOR
new uint[] { SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
//CLASS_PALADIN
new uint[]{ SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_HUNTER
new uint[]{ SpellIds.Delusional, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Delusional, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_ROGUE
new uint[]{ SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
//CLASS_PRIEST
new uint[]{ SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_DEATH_KNIGHT
new uint[]{ SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.MartyrComplex },
//CLASS_SHAMAN
new uint[] { SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_MAGE
new uint[]{ SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_WARLOCK
new uint[]{ SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
new uint[] {SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia },
//CLASS_UNK
new uint[]{ },
//CLASS_DRUID
new uint[]{ SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia }
new uint[] {SpellIds.Sociopath, SpellIds.Delusional, SpellIds.Kleptomania, SpellIds.Megalomania, SpellIds.Paranoia, SpellIds.Manic, SpellIds.Narcissism, SpellIds.MartyrComplex, SpellIds.Dementia }
};
PreventDefaultAction();
@@ -820,19 +820,19 @@ namespace Scripts.Spells.Items
//CLASS_NONE
new uint[] { },
//CLASS_WARRIOR
new uint[] { _strengthSpellId, _criticalSpellId, _hasteSpellId },
new uint[] {_strengthSpellId, _criticalSpellId, _hasteSpellId },
//CLASS_PALADIN
new uint[] { _strengthSpellId, _criticalSpellId, _hasteSpellId },
//CLASS_HUNTER
new uint[] { _agilitySpellId, _criticalSpellId, _apSpellId },
new uint[] {_agilitySpellId, _criticalSpellId, _apSpellId },
//CLASS_ROGUE
new uint[] { _agilitySpellId, _hasteSpellId, _apSpellId },
new uint[] {_agilitySpellId, _hasteSpellId, _apSpellId },
//CLASS_PRIEST
new uint[] { },
//CLASS_DEATH_KNIGHT
new uint[] { _strengthSpellId, _criticalSpellId, _hasteSpellId },
new uint[] {_strengthSpellId, _criticalSpellId, _hasteSpellId },
//CLASS_SHAMAN
new uint[] { _agilitySpellId, _hasteSpellId, _apSpellId },
new uint[] {_agilitySpellId, _hasteSpellId, _apSpellId },
//CLASS_MAGE
new uint[] { },
//CLASS_WARLOCK
@@ -840,7 +840,7 @@ namespace Scripts.Spells.Items
//CLASS_UNK
new uint[] { },
//CLASS_DRUID
new uint[] { _strengthSpellId, _agilitySpellId, _hasteSpellId }
new uint[] {_strengthSpellId, _agilitySpellId, _hasteSpellId }
};
PreventDefaultAction();
@@ -1984,7 +1984,7 @@ namespace Scripts.Spells.Items
Player target = GetHitPlayer();
if (target)
{
uint[] items = { ItemIds.HeartCandy1, ItemIds.HeartCandy2, ItemIds.HeartCandy3, ItemIds.HeartCandy4, ItemIds.HeartCandy5, ItemIds.HeartCandy6, ItemIds.HeartCandy7, ItemIds.HeartCandy8 };
uint[] items = new uint[] { ItemIds.HeartCandy1, ItemIds.HeartCandy2, ItemIds.HeartCandy3, ItemIds.HeartCandy4, ItemIds.HeartCandy5, ItemIds.HeartCandy6, ItemIds.HeartCandy7, ItemIds.HeartCandy8 };
target.AddItem(items[RandomHelper.IRand(0, 7)], 1);
}
}
@@ -2112,7 +2112,7 @@ namespace Scripts.Spells.Items
uint sound_id = RandomHelper.RAND(SoundIds.Ashbringer1, SoundIds.Ashbringer2, SoundIds.Ashbringer3, SoundIds.Ashbringer4, SoundIds.Ashbringer5, SoundIds.Ashbringer6,
SoundIds.Ashbringer7, SoundIds.Ashbringer8, SoundIds.Ashbringer9, SoundIds.Ashbringer10, SoundIds.Ashbringer11, SoundIds.Ashbringer12);
// Ashbringers effect (spellID 28441) retriggers every 5 seconds, with a chance of making it say one of the above 12 sounds
// Ashbringers effect (SpellIds.ID 28441) retriggers every 5 seconds, with a chance of making it say one of the above 12 sounds
if (RandomHelper.URand(0, 60) < 1)
player.PlayDirectSound(sound_id, player);
}
@@ -2557,7 +2557,7 @@ namespace Scripts.Spells.Items
float lastZ = MapConst.InvalidHeight;
}
[Script]
class spell_item_teach_language : SpellScript
{
@@ -2972,7 +2972,7 @@ namespace Scripts.Spells.Items
if (dummy == null || dummy.GetStackAmount() < aurEff.GetAmount())
return;
// if right amount, remove the aura and cast real trigger
// if right amount, Remove the aura and cast real trigger
caster.RemoveAurasDueToSpell(_stackSpell);
Unit target = eventInfo.GetActionTarget();
if (target)
@@ -3392,7 +3392,7 @@ namespace Scripts.Spells.Items
}
[Script]// 45051 - Mad Alchemist's Potion (34440)
class mad_alchemists_potion_SpellScript : SpellScript
class spell_item_mad_alchemists_potion : SpellScript
{
void SecondaryEffect()
{
@@ -3461,7 +3461,7 @@ namespace Scripts.Spells.Items
}
[Script]// 53750 - Crazy Alchemist's Potion (40077)
class crazy_alchemists_potion_SpellScript : SpellScript
class spell_item_crazy_alchemists_potion : SpellScript
{
void SecondaryEffect()
{
+6 -6
View File
@@ -138,8 +138,8 @@ namespace Scripts.Spells.Mage
void HandleAbsorb(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount)
{
AuraEffect effect1 = GetEffect(1);
if (effect1 == null || !GetTargetApplication().HasEffect(1) ||
AuraEffect effectInfo = GetEffect(1);
if (effectInfo == null || !GetTargetApplication().HasEffect(1) ||
dmgInfo.GetDamage() < GetTarget().GetHealth() ||
dmgInfo.GetDamage() > GetTarget().GetMaxHealth() * 2 ||
GetTarget().HasAura(SpellIds.Cauterized))
@@ -148,7 +148,7 @@ namespace Scripts.Spells.Mage
return;
}
GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effect1.GetAmount()));
GetTarget().SetHealth(GetTarget().CountPctFromMaxHealth(effectInfo.GetAmount()));
GetTarget().CastSpell(GetTarget(), GetSpellInfo().GetEffect(2).TriggerSpell, TriggerCastFlags.FullMask);
GetTarget().CastSpell(GetTarget(), SpellIds.CauterizeDot, TriggerCastFlags.FullMask);
GetTarget().CastSpell(GetTarget(), SpellIds.Cauterized, TriggerCastFlags.FullMask);
@@ -303,7 +303,7 @@ namespace Scripts.Spells.Mage
}
}
// 37447 - Improved Mana Gems
// 37447 - Improved Mana Gems
[Script] // 61062 - Improved Mana Gems
class spell_mage_imp_mana_gems : AuraScript
{
@@ -501,7 +501,7 @@ namespace Scripts.Spells.Mage
ObjectGuid _ringOfFrostGUID;
}
[Script] // 82691 - Ring of Frost (freeze efect)
class spell_mage_ring_of_frost_freeze : SpellScript
{
@@ -552,7 +552,7 @@ namespace Scripts.Spells.Mage
AfterEffectRemove.Add(new EffectApplyHandler(OnRemove, 0, AuraType.ModStun, AuraEffectHandleModes.Real));
}
}
[Script] // 80353 - Time Warp
class spell_mage_time_warp : SpellScript
{
+2 -2
View File
@@ -162,7 +162,7 @@ namespace Scripts.Spells.Paladin
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.Forbearance) //, SPELL_PALADIN_IMMUNE_SHIELD_MARKER) // uncomment when we have serverside only spells
return ValidateSpellInfo(SpellIds.Forbearance) //, SpellIds._PALADIN_IMMUNE_SHIELD_MARKER) // uncomment when we have serverside only spells
&& spellInfo.ExcludeTargetAuraSpell == SpellIds.ImmuneShieldMarker;
}
@@ -218,7 +218,7 @@ namespace Scripts.Spells.Paladin
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.FinalStand, SpellIds.FinalStandEffect, SpellIds.Forbearance) //, SPELL_PALADIN_IMMUNE_SHIELD_MARKER // uncomment when we have serverside only spells
return ValidateSpellInfo(SpellIds.FinalStand, SpellIds.FinalStandEffect, SpellIds.Forbearance) //, SpellIds._PALADIN_IMMUNE_SHIELD_MARKER // uncomment when we have serverside only spells
&& spellInfo.ExcludeCasterAuraSpell == SpellIds.ImmuneShieldMarker;
}
+1 -1
View File
@@ -473,7 +473,7 @@ namespace Scripts.Spells.Priest
return;
int healAmount = (int)target.CountPctFromMaxHealth((int)healPct);
// remove the aura now, we don't want 40% healing bonus
// Remove the aura now, we don't want 40% healing bonus
Remove(AuraRemoveMode.EnemySpell);
target.CastCustomSpell(target, SpellIds.GuardianSpiritHeal, healAmount, 0, 0, true);
absorbAmount = dmgInfo.GetDamage();
+3 -4
View File
@@ -284,12 +284,11 @@ namespace Scripts.Spells.Quest
// 34665 Administer Antidote
// http://www.wowhead.com/quest=11515 Blood for Blood
// 44936 Quest - Fel Siphon Dummy
[Script("spell_q55_sacred_cleansing", SpellEffectName.Dummy, 1u, CreatureIds.Morbent, CreatureIds.WeakenedMorbent, true)]
[Script("spell_q10255_administer_antidote", SpellEffectName.Dummy, 0u, CreatureIds.Helboar, CreatureIds.Dreadtusk, true)]
[Script("spell_q11515_fel_siphon_dummy", SpellEffectName.Dummy, 0u, CreatureIds.FelbloodInitiate, CreatureIds.EmaciatedFelblood, true)]
[Script("spell_q55_sacred_cleansing", SpellEffectName.Dummy, 1u, CreatureIds.Morbent, CreatureIds.WeakenedMorbent, true, 0)]
[Script("spell_q10255_administer_antidote", SpellEffectName.Dummy, 0u, CreatureIds.Helboar, CreatureIds.Dreadtusk, true, 0)]
[Script("spell_q11515_fel_siphon_dummy", SpellEffectName.Dummy, 0u, CreatureIds.FelbloodInitiate, CreatureIds.EmaciatedFelblood, true, 0)]
class spell_generic_quest_update_entry : SpellScript
{
public spell_generic_quest_update_entry(SpellEffectName spellEffect, uint effIndex, uint originalEntry, uint newEntry, bool shouldAttack) : this(spellEffect, effIndex, originalEntry, newEntry, shouldAttack, 0) { }
public spell_generic_quest_update_entry(SpellEffectName spellEffect, uint effIndex, uint originalEntry, uint newEntry, bool shouldAttack, uint despawnTime)
{
_spellEffect = spellEffect;
+8 -10
View File
@@ -89,7 +89,7 @@ namespace Scripts.Spells.Warlock
Unit target = GetHitUnit();
if (target)
{
// Casting Banish on a banished target will remove applied aura
// Casting Banish on a banished target will Remove applied aura
Aura banishAura = target.GetAura(GetSpellInfo().Id, GetCaster().GetGUID());
if (banishAura != null)
banishAura.Remove();
@@ -119,7 +119,7 @@ namespace Scripts.Spells.Warlock
public override void Register()
{
//OnEffectHitTarget.Add(new EffectHandler(spell_warl_conflagrate_SpellScript::HandleHit, 0, SPELL_EFFECT_SCHOOL_DAMAGE);
//OnEffectHitTarget.Add(new EffectHandler(spell_warl_conflagrate_SpellScript::HandleHit, 0, SpellIds._EFFECT_SCHOOL_DAMAGE);
}
}
@@ -128,15 +128,15 @@ namespace Scripts.Spells.Warlock
{
void HandleAbsorb(AuraEffect aurEff, DamageInfo dmgInfo, ref uint absorbAmount)
{
AuraEffect effect1 = GetEffect(1);
if (effect1 == null || !GetTargetApplication().HasEffect(1))
AuraEffect auraEffect = GetEffect(1);
if (auraEffect == null || !GetTargetApplication().HasEffect(1))
{
PreventDefaultAction();
return;
}
// You take ${$s2/3}% reduced damage
float damageReductionPct = (float)effect1.GetAmount() / 3;
float damageReductionPct = (float)auraEffect.GetAmount() / 3;
// plus a random amount of up to ${$s2/3}% additional reduced damage
damageReductionPct += RandomHelper.FRand(0.0f, damageReductionPct);
@@ -210,7 +210,7 @@ namespace Scripts.Spells.Warlock
{
void HandleRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
// If effect is removed by expire remove the summoned demonic circle too.
// If effect is Removed by expire Remove the summoned demonic circle too.
if (!mode.HasAnyFlag(AuraEffectHandleModes.Reapply))
GetTarget().RemoveGameObject(GetId(), true);
@@ -224,7 +224,7 @@ namespace Scripts.Spells.Warlock
{
// Here we check if player is in demonic circle teleport range, if so add
// WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST; allowing him to cast the WARLOCK_DEMONIC_CIRCLE_TELEPORT.
// If not in range remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST.
// If not in range Remove the WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST.
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(SpellIds.DemonicCircleTeleport, GetCastDifficulty());
@@ -646,7 +646,7 @@ namespace Scripts.Spells.Warlock
{
if (caster.GetOwner() && caster.GetOwner().HasAura(SpellIds.GlyphOfSuccubus))
{
target.RemoveAurasByType(AuraType.PeriodicDamage, ObjectGuid.Empty, target.GetAura(SpellIds.PriestShadowWordDeath)); // SW:D shall not be removed.
target.RemoveAurasByType(AuraType.PeriodicDamage, ObjectGuid.Empty, target.GetAura(SpellIds.PriestShadowWordDeath)); // SW:D shall not be Removed.
target.RemoveAurasByType(AuraType.PeriodicDamagePercent);
target.RemoveAurasByType(AuraType.PeriodicLeech);
}
@@ -828,8 +828,6 @@ namespace Scripts.Spells.Warlock
public List<uint> GetDotList() { return _dotList; }
public Unit GetOriginalSwapSource() { return _swapCaster; }
public void SetOriginalSwapSource(Unit victim) { _swapCaster = victim; }
List<uint> _dotList = new List<uint>();
Unit _swapCaster;
}
+1 -3
View File
@@ -483,8 +483,6 @@ namespace Scripts.Spells.Warrior
OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.Any));
}
}
[Script] // 97462 - Rallying Cry
class spell_warr_rallying_cry : SpellScript
{
@@ -574,7 +572,7 @@ namespace Scripts.Spells.Warrior
{
PreventHitDefaultEffect(effIndex);
// remove shields, will still display immune to damage part
// Remove shields, will still display immune to damage part
Unit target = GetHitUnit();
if (target)
target.RemoveAurasWithMechanic(1 << (int)Mechanics.ImmuneShield, AuraRemoveMode.EnemySpell);
-581
View File
@@ -1,581 +0,0 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.World.BossEmeraldDragons
{
struct CreatureIds
{
public const uint DragonYsondre = 14887;
public const uint DragonLethon = 14888;
public const uint DragonEmeriss = 14889;
public const uint DragonTaerar = 14890;
public const uint DreamFog = 15224;
//Ysondre
public const uint DementedDruid = 15260;
//Lethon
public const uint SpiritShade = 15261;
}
struct Spells
{
public const uint TailSweep = 15847; // Tail Sweep - Slap Everything Behind Dragon (2 Seconds Interval)
public const uint SummonPlayer = 24776; // Teleport Highest Threat Player In Front Of Dragon If Wandering Off
public const uint DreamFog = 24777; // Auraspell For Dream Fog Npc (15224)
public const uint Sleep = 24778; // Sleep Triggerspell (Used For Dream Fog)
public const uint SeepingFogLeft = 24813; // Dream Fog - Summon Left
public const uint SeepingFogRight = 24814; // Dream Fog - Summon Right
public const uint NoxiousBreath = 24818;
public const uint MarkOfNature = 25040; // Mark Of Nature Trigger (Applied On Target Death - 15 Minutes Of Being Suspectible To Aura Of Nature)
public const uint MarkOfNatureAura = 25041; // Mark Of Nature (Passive Marker-Test; Ticks Every 10 Seconds From Boss; Triggers Spellid 25042 (Scripted)
public const uint AuraOfNature = 25043; // Stun For 2 Minutes (Used When public const uint MarkOfNature Exists On The Target)
//Ysondre
public const uint LightningWave = 24819;
public const uint SummonDruidSpirits = 24795;
//Lethon
public const uint DrawSpirit = 24811;
public const uint ShadowBoltWhirl = 24834;
public const uint DarkOffering = 24804;
//Emeriss
public const uint PutridMushroom = 24904;
public const uint CorruptionOfEarth = 24910;
public const uint VolatileInfection = 24928;
//Taerar
public const uint BellowingRoar = 22686;
public const uint Shade = 24313;
public const uint ArcaneBlast = 24857;
public static uint[] TaerarShadeSpells = { 24841, 24842, 24843 };
}
struct Texts
{
//Ysondre
public const uint YsondreAggro = 0;
public const uint YsondreSummonDruids = 1;
//Lethon
public const uint LethonAggro = 0;
public const uint LethonDrawSpirit = 1;
//Emeriss
public const uint EmerissAggro = 0;
public const uint EmerissCastCorruption = 1;
//Taerar
public const uint TaerarAggro = 0;
public const uint TaerarSummonShades = 1;
}
class emerald_dragonAI : WorldBossAI
{
public emerald_dragonAI(Creature creature) : base(creature) { }
public override void Reset()
{
base.Reset();
me.RemoveUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Aggressive);
DoCast(me, Spells.MarkOfNatureAura, true);
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
// Tail Sweep is cast every two seconds, no matter what goes on in front of the dragon
DoCast(me, Spells.TailSweep);
task.Repeat(TimeSpan.FromSeconds(2));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7.5), TimeSpan.FromSeconds(15), task =>
{
// Noxious Breath is cast on random intervals, no less than 7.5 seconds between
DoCast(me, Spells.NoxiousBreath);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20), task =>
{
// Seeping Fog appears only as "pairs", and only ONE pair at any given time!
// Despawntime is 2 minutes, so reschedule it for new cast after 2 minutes + a minor "random time" (30 seconds at max)
DoCast(me, Spells.SeepingFogLeft, true);
DoCast(me, Spells.SeepingFogRight, true);
task.Repeat(TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2.5));
});
}
// Target killed during encounter, mark them as suspectible for Aura Of Nature
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
who.CastSpell(who, Spells.MarkOfNature, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_scheduler.Update(diff);
Unit target = SelectTarget(SelectAggroTarget.MaxThreat, 0, -50.0f, true);
if (target)
DoCast(target, Spells.SummonPlayer);
DoMeleeAttackIfReady();
}
}
[Script]
class npc_dream_fog : ScriptedAI
{
public npc_dream_fog(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_roamTimer = 0;
}
public override void Reset()
{
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (_roamTimer == 0)
{
// Chase target, but don't attack - otherwise just roam around
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
_roamTimer = RandomHelper.URand(15000, 30000);
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveChase(target, 0.2f);
}
else
{
_roamTimer = 2500;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveRandom(25.0f);
}
// Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
me.SetWalk(true);
me.SetSpeedRate(UnitMoveType.Walk, 0.75f);
}
else
_roamTimer -= diff;
}
uint _roamTimer;
}
[Script]
class boss_ysondre : CreatureScript
{
public boss_ysondre() : base("boss_ysondre") { }
class boss_ysondreAI : emerald_dragonAI
{
public boss_ysondreAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(Spells.LightningWave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.YsondreAggro);
base.EnterCombat(who);
}
// Summon druid spirits on 75%, 50% and 25% health
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.YsondreSummonDruids);
for (byte i = 0; i < 10; ++i)
DoCast(me, Spells.SummonDruidSpirits, true);
++_stage;
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_ysondreAI(creature);
}
}
[Script]
class boss_lethon : CreatureScript
{
public boss_lethon() : base("boss_lethon") { }
class boss_lethonAI : emerald_dragonAI
{
public boss_lethonAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
me.CastSpell((Unit)null, Spells.ShadowBoltWhirl, false);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.LethonAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.LethonDrawSpirit);
DoCast(me, Spells.DrawSpirit);
++_stage;
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == Spells.DrawSpirit && target.IsTypeId(TypeId.Player))
{
Position targetPos = target.GetPosition();
me.SummonCreature(CreatureIds.SpiritShade, targetPos, TempSummonType.TimedDespawnOOC, 50000);
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_lethonAI(creature);
}
}
[Script]
class npc_spirit_shade : PassiveAI
{
public npc_spirit_shade(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
_summonerGuid = summoner.GetGUID();
me.GetMotionMaster().MoveFollow(summoner, 0.0f, 0.0f);
}
public override void MovementInform(MovementGeneratorType moveType, uint data)
{
if (moveType == MovementGeneratorType.Follow && data == _summonerGuid.GetCounter())
{
me.CastSpell((Unit)null, Spells.DarkOffering, false);
me.DespawnOrUnsummon(1000);
}
}
ObjectGuid _summonerGuid;
}
[Script]
class boss_emeriss : CreatureScript
{
public boss_emeriss() : base("boss_emeriss") { }
class boss_emerissAI : emerald_dragonAI
{
public boss_emerissAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(Spells.VolatileInfection);
task.Repeat(TimeSpan.FromSeconds(120));
});
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
DoCast(who, Spells.PutridMushroom, true);
base.KilledUnit(who);
}
public override void EnterCombat(Unit who)
{
Talk(Texts.EmerissAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.EmerissCastCorruption);
DoCast(me, Spells.CorruptionOfEarth, true);
++_stage;
}
}
byte _stage;
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_emerissAI(creature);
}
}
[Script]
class boss_taerar : CreatureScript
{
public boss_taerar() : base("boss_taerar") { }
class boss_taerarAI : emerald_dragonAI
{
public boss_taerarAI(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
_shades = 0;
_banished = false;
_banishedTimer = 0;
}
public override void Reset()
{
me.RemoveAurasDueToSpell(Spells.Shade);
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCast(Spells.ArcaneBlast);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
DoCast(Spells.BellowingRoar);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.TaerarAggro);
base.EnterCombat(who);
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
--_shades;
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
// At 75, 50 or 25 percent health, we need to activate the shades and go "banished"
// Note: _stage holds the amount of times they have been summoned
if (!_banished && !HealthAbovePct(100 - 25 * _stage))
{
_banished = true;
_banishedTimer = 60000;
me.InterruptNonMeleeSpells(false);
DoStopAttack();
Talk(Texts.TaerarSummonShades);
foreach (var spell in Spells.TaerarShadeSpells)
DoCastVictim(spell, true);
_shades += (byte)Spells.TaerarShadeSpells.Length;
DoCast(Spells.Shade);
me.AddUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Passive);
++_stage;
}
}
public override void UpdateAI(uint diff)
{
if (!me.IsInCombat())
return;
if (_banished)
{
// If all three shades are dead, OR it has taken too long, end the current event and get Taerar back into business
if (_banishedTimer <= diff || _shades == 0)
{
_banished = false;
me.RemoveUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.RemoveAurasDueToSpell(Spells.Shade);
me.SetReactState(ReactStates.Aggressive);
}
// _banishtimer has not expired, and we still have active shades:
else
_banishedTimer -= diff;
// Update the scheduler before we return (handled under emerald_dragonAI.UpdateAI(diff); if we're not inside this check)
_scheduler.Update(diff);
return;
}
base.UpdateAI(diff);
}
bool _banished; // used for shades activation testing
uint _banishedTimer; // counter for banishment timeout
byte _shades; // keep track of how many shades are dead
byte _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
}
public override CreatureAI GetAI(Creature creature)
{
return new boss_taerarAI(creature);
}
}
[Script]
class spell_dream_fog_sleep : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
Unit unit = obj.ToUnit();
if (unit)
return unit.HasAura(Spells.Sleep);
return true;
});
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaEnemy));
}
}
[Script]
class spell_mark_of_nature : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(Spells.MarkOfNature, Spells.AuraOfNature);
}
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
// return those not tagged or already under the influence of Aura of Nature
Unit unit = obj.ToUnit();
if (unit)
return !(unit.HasAura(Spells.MarkOfNature) && !unit.HasAura(Spells.AuraOfNature));
return true;
});
}
void HandleEffect(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit().CastSpell(GetHitUnit(), Spells.AuraOfNature, true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.ApplyAura));
}
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ namespace Scripts.World
void ResetSpellCooldowns(Player player, bool onStartDuel)
{
// remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold
// Remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold
player.GetSpellHistory().ResetCooldowns(itr =>
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itr.Key, Difficulty.None);
+541
View File
@@ -0,0 +1,541 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.World.BossEmeraldDragons
{
struct CreatureIds
{
public const uint DragonYsondre = 14887;
public const uint DragonLethon = 14888;
public const uint DragonEmeriss = 14889;
public const uint DragonTaerar = 14890;
public const uint DreamFog = 15224;
//Ysondre
public const uint DementedDruid = 15260;
//Lethon
public const uint SpiritShade = 15261;
}
struct SpellIds
{
public const uint TailSweep = 15847; // Tail Sweep - Slap Everything Behind Dragon (2 Seconds Interval)
public const uint SummonPlayer = 24776; // Teleport Highest Threat Player In Front Of Dragon If Wandering Off
public const uint DreamFog = 24777; // Auraspell For Dream Fog Npc (15224)
public const uint Sleep = 24778; // Sleep Triggerspell (Used For Dream Fog)
public const uint SeepingFogLeft = 24813; // Dream Fog - Summon Left
public const uint SeepingFogRight = 24814; // Dream Fog - Summon Right
public const uint NoxiousBreath = 24818;
public const uint MarkOfNature = 25040; // Mark Of Nature Trigger (Applied On Target Death - 15 Minutes Of Being Suspectible To Aura Of Nature)
public const uint MarkOfNatureAura = 25041; // Mark Of Nature (Passive Marker-Test; Ticks Every 10 Seconds From Boss; Triggers Spellid 25042 (Scripted)
public const uint AuraOfNature = 25043; // Stun For 2 Minutes (Used When public const uint MarkOfNature Exists On The Target)
//Ysondre
public const uint LightningWave = 24819;
public const uint SummonDruidSpirits = 24795;
//Lethon
public const uint DrawSpirit = 24811;
public const uint ShadowBoltWhirl = 24834;
public const uint DarkOffering = 24804;
//Emeriss
public const uint PutridMushroom = 24904;
public const uint CorruptionOfEarth = 24910;
public const uint VolatileInfection = 24928;
//Taerar
public const uint BellowingRoar = 22686;
public const uint Shade = 24313;
public const uint ArcaneBlast = 24857;
public static uint[] TaerarShadeSpells = new uint[] { 24841, 24842, 24843 };
}
struct Texts
{
//Ysondre
public const uint YsondreAggro = 0;
public const uint YsondreSummonDruids = 1;
//Lethon
public const uint LethonAggro = 0;
public const uint LethonDrawSpirit = 1;
//Emeriss
public const uint EmerissAggro = 0;
public const uint EmerissCastCorruption = 1;
//Taerar
public const uint TaerarAggro = 0;
public const uint TaerarSummonShades = 1;
}
class emerald_dragonAI : WorldBossAI
{
public emerald_dragonAI(Creature creature) : base(creature) { }
public override void Reset()
{
base.Reset();
me.RemoveUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Aggressive);
DoCast(me, SpellIds.MarkOfNatureAura, true);
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
// Tail Sweep is cast every two seconds, no matter what goes on in front of the dragon
DoCast(me, SpellIds.TailSweep);
task.Repeat(TimeSpan.FromSeconds(2));
});
_scheduler.Schedule(TimeSpan.FromSeconds(7.5), TimeSpan.FromSeconds(15), task =>
{
// Noxious Breath is cast on random intervals, no less than 7.5 seconds between
DoCast(me, SpellIds.NoxiousBreath);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(12.5), TimeSpan.FromSeconds(20), task =>
{
// Seeping Fog appears only as "pairs", and only ONE pair at any given time!
// Despawntime is 2 minutes, so reschedule it for new cast after 2 minutes + a minor "random time" (30 seconds at max)
DoCast(me, SpellIds.SeepingFogLeft, true);
DoCast(me, SpellIds.SeepingFogRight, true);
task.Repeat(TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2.5));
});
}
// Target killed during encounter, mark them as suspectible for Aura Of Nature
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
who.CastSpell(who, SpellIds.MarkOfNature, true);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitState(UnitState.Casting))
return;
_scheduler.Update(diff);
Unit target = SelectTarget(SelectAggroTarget.MaxThreat, 0, -50.0f, true);
if (target)
DoCast(target, SpellIds.SummonPlayer);
DoMeleeAttackIfReady();
}
}
[Script]
class npc_dream_fog : ScriptedAI
{
public npc_dream_fog(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_roamTimer = 0;
}
public override void Reset()
{
Initialize();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (_roamTimer == 0)
{
// Chase target, but don't attack - otherwise just roam around
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true);
if (target)
{
_roamTimer = RandomHelper.URand(15000, 30000);
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveChase(target, 0.2f);
}
else
{
_roamTimer = 2500;
me.GetMotionMaster().Clear(false);
me.GetMotionMaster().MoveRandom(25.0f);
}
// Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
me.SetWalk(true);
me.SetSpeedRate(UnitMoveType.Walk, 0.75f);
}
else
_roamTimer -= diff;
}
uint _roamTimer;
}
[Script]
class boss_ysondre : emerald_dragonAI
{
public boss_ysondre(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.LightningWave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.YsondreAggro);
base.EnterCombat(who);
}
// Summon druid spirits on 75%, 50% and 25% health
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.YsondreSummonDruids);
for (byte i = 0; i < 10; ++i)
DoCast(me, SpellIds.SummonDruidSpirits, true);
++_stage;
}
}
byte _stage;
}
[Script]
class boss_lethon : emerald_dragonAI
{
public boss_lethon(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
me.CastSpell((Unit)null, SpellIds.ShadowBoltWhirl, false);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.LethonAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.LethonDrawSpirit);
DoCast(me, SpellIds.DrawSpirit);
++_stage;
}
}
public override void SpellHitTarget(Unit target, SpellInfo spell)
{
if (spell.Id == SpellIds.DrawSpirit && target.IsTypeId(TypeId.Player))
{
Position targetPos = target.GetPosition();
me.SummonCreature(CreatureIds.SpiritShade, targetPos, TempSummonType.TimedDespawnOOC, 50000);
}
}
byte _stage;
}
[Script]
class npc_spirit_shade : PassiveAI
{
public npc_spirit_shade(Creature creature) : base(creature) { }
public override void IsSummonedBy(Unit summoner)
{
_summonerGuid = summoner.GetGUID();
me.GetMotionMaster().MoveFollow(summoner, 0.0f, 0.0f);
}
public override void MovementInform(MovementGeneratorType moveType, uint data)
{
if (moveType == MovementGeneratorType.Follow && data == _summonerGuid.GetCounter())
{
me.CastSpell((Unit)null, SpellIds.DarkOffering, false);
me.DespawnOrUnsummon(1000);
}
}
ObjectGuid _summonerGuid;
}
[Script]
class boss_emeriss : emerald_dragonAI
{
public boss_emeriss(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
}
public override void Reset()
{
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.VolatileInfection);
task.Repeat(TimeSpan.FromSeconds(120));
});
}
public override void KilledUnit(Unit who)
{
if (who.IsTypeId(TypeId.Player))
DoCast(who, SpellIds.PutridMushroom, true);
base.KilledUnit(who);
}
public override void EnterCombat(Unit who)
{
Talk(Texts.EmerissAggro);
base.EnterCombat(who);
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (!HealthAbovePct(100 - 25 * _stage))
{
Talk(Texts.EmerissCastCorruption);
DoCast(me, SpellIds.CorruptionOfEarth, true);
++_stage;
}
}
byte _stage;
}
[Script]
class boss_taerar : emerald_dragonAI
{
public boss_taerar(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_stage = 1;
_shades = 0;
_banished = false;
_banishedTimer = 0;
}
public override void Reset()
{
me.RemoveAurasDueToSpell(SpellIds.Shade);
Initialize();
base.Reset();
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCast(SpellIds.ArcaneBlast);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
{
DoCast(SpellIds.BellowingRoar);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
});
}
public override void EnterCombat(Unit who)
{
Talk(Texts.TaerarAggro);
base.EnterCombat(who);
}
public override void SummonedCreatureDies(Creature summon, Unit killer)
{
--_shades;
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
// At 75, 50 or 25 percent health, we need to activate the shades and go "banished"
// Note: _stage holds the amount of times they have been summoned
if (!_banished && !HealthAbovePct(100 - 25 * _stage))
{
_banished = true;
_banishedTimer = 60000;
me.InterruptNonMeleeSpells(false);
DoStopAttack();
Talk(Texts.TaerarSummonShades);
foreach (var spell in SpellIds.TaerarShadeSpells)
DoCastVictim(spell, true);
_shades += (byte)SpellIds.TaerarShadeSpells.Length;
DoCast(SpellIds.Shade);
me.AddUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.SetReactState(ReactStates.Passive);
++_stage;
}
}
public override void UpdateAI(uint diff)
{
if (!me.IsInCombat())
return;
if (_banished)
{
// If all three shades are dead, OR it has taken too long, end the current event and get Taerar back into business
if (_banishedTimer <= diff || _shades == 0)
{
_banished = false;
me.RemoveUnitFlag(UnitFlags.NotSelectable | UnitFlags.NonAttackable);
me.RemoveAurasDueToSpell(SpellIds.Shade);
me.SetReactState(ReactStates.Aggressive);
}
// _banishtimer has not expired, and we still have active shades:
else
_banishedTimer -= diff;
// Update the scheduler before we return (handled under emerald_dragonAI.UpdateAI(diff); if we're not inside this check)
_scheduler.Update(diff);
return;
}
base.UpdateAI(diff);
}
bool _banished; // used for shades activation testing
uint _banishedTimer; // counter for banishment timeout
byte _shades; // keep track of how many shades are dead
byte _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
}
[Script]
class spell_dream_fog_sleep : SpellScript
{
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
Unit unit = obj.ToUnit();
if (unit)
return unit.HasAura(SpellIds.Sleep);
return true;
});
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitDestAreaEnemy));
}
}
[Script]
class spell_mark_of_nature : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MarkOfNature, SpellIds.AuraOfNature);
}
void FilterTargets(List<WorldObject> targets)
{
targets.RemoveAll(obj =>
{
// return those not tagged or already under the influence of Aura of Nature
Unit unit = obj.ToUnit();
if (unit)
return !(unit.HasAura(SpellIds.MarkOfNature) && !unit.HasAura(SpellIds.AuraOfNature));
return true;
});
}
void HandleEffect(uint effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit().CastSpell(GetHitUnit(), SpellIds.AuraOfNature, true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
OnEffectHitTarget.Add(new EffectHandler(HandleEffect, 0, SpellEffectName.ApplyAura));
}
}
}
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More