Ported .Net Core commits:

hondacrx:
- Initial commit: Switch to .Net Core 2.0
- Fix build and removed not needed files
Fabi:
- Updated solution platforms.
- Changed folder structure.
- Change library target framework to netstandard2.0.
- Updated solution platforms again...
- Removed windows specific kernel32 function usage (Ctrl-C handler).
This commit is contained in:
Fabian
2017-10-26 17:23:44 +02:00
parent 227702e19c
commit a3dc7b3f48
844 changed files with 26064 additions and 1824 deletions
@@ -0,0 +1,204 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Scripts.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);
}
}*/
}
@@ -0,0 +1,305 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.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 SayMidnightKill = 0;
public const uint SayAppear = 1;
public const uint SayMount = 2;
public const uint SayKill = 0;
public const uint SayDisarmed = 1;
public const uint SayDeath = 2;
public const uint SayRandom = 3;
}
struct SpellIds
{
public const uint Shadowcleave = 29832;
public const uint IntangiblePresence = 29833;
public const uint BerserkerCharge = 26561; //Only When Mounted
}
[Script]
public class boss_attumen : ScriptedAI
{
public boss_attumen(Creature creature) : base(creature)
{
CleaveTimer = RandomHelper.URand(10000, 15000);
CurseTimer = 30000;
RandomYellTimer = RandomHelper.URand(30000, 60000); //Occasionally yell
ChargeTimer = 20000;
ResetTimer = 0;
}
public override void Reset()
{
ResetTimer = 0;
Midnight.Clear();
}
public override void EnterEvadeMode(EvadeReason why)
{
base.EnterEvadeMode(why);
ResetTimer = 2000;
}
public override void EnterCombat(Unit who) { }
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayKill);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
Unit midnight = Global.ObjAccessor.GetUnit(me, Midnight);
if (midnight)
midnight.KillSelf();
}
public override void UpdateAI(uint diff)
{
if (ResetTimer != 0)
{
if (ResetTimer <= diff)
{
ResetTimer = 0;
Unit pMidnight = Global.ObjAccessor.GetUnit(me, Midnight);
if (pMidnight)
{
pMidnight.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
pMidnight.SetVisible(true);
}
Midnight.Clear();
me.SetVisible(false);
me.KillSelf();
}
else ResetTimer -= diff;
}
//Return since we have no target
if (!UpdateVictim())
return;
if (me.HasFlag(UnitFields.Flags, UnitFlags.NonAttackable | UnitFlags.NotSelectable))
return;
if (CleaveTimer <= diff)
{
DoCastVictim(SpellIds.Shadowcleave);
CleaveTimer = RandomHelper.URand(10000, 15000);
}
else CleaveTimer -= diff;
if (CurseTimer <= diff)
{
DoCastVictim(SpellIds.IntangiblePresence);
CurseTimer = 30000;
}
else CurseTimer -= diff;
if (RandomYellTimer <= diff)
{
Talk(TextIds.SayRandom);
RandomYellTimer = RandomHelper.URand(30000, 60000);
}
else RandomYellTimer -= diff;
if (me.GetUInt32Value(UnitFields.DisplayId) == Misc.MountedDisplayid)
{
if (ChargeTimer <= diff)
{
var t_list = me.GetThreatManager().getThreatList();
List<Unit> target_list = new List<Unit>();
foreach (var hostileRefe in t_list)
{
var unit = Global.ObjAccessor.GetUnit(me, hostileRefe.getUnitGuid());
if (unit && !unit.IsWithinDist(me, SharedConst.AttackDistance, false))
target_list.Add(unit);
unit = null;
}
Unit target = null;
if (!target_list.Empty())
target = target_list.SelectRandom();
DoCast(target, SpellIds.BerserkerCharge);
ChargeTimer = 20000;
}
else ChargeTimer -= diff;
}
else
{
if (HealthBelowPct(25))
{
Creature pMidnight = ObjectAccessor.GetCreature(me, Midnight);
if (pMidnight && pMidnight.IsTypeId(TypeId.Unit))
{
((boss_midnight)pMidnight.GetAI()).Mount(me);
me.SetHealth(pMidnight.GetHealth());
DoResetThreat();
}
}
}
DoMeleeAttackIfReady();
}
public override void SpellHit(Unit source, SpellInfo spell)
{
if (spell.Mechanic == Mechanics.Disarm)
Talk(TextIds.SayDisarmed);
}
public ObjectGuid Midnight;
uint CleaveTimer;
uint CurseTimer;
uint RandomYellTimer;
uint ChargeTimer; //only when mounted
uint ResetTimer;
}
[Script]
public class boss_midnight : ScriptedAI
{
public boss_midnight(Creature creature) : base(creature) { }
public override void Reset()
{
Phase = 1;
Attumen.Clear();
mountTimer = 0;
me.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
me.SetVisible(true);
}
public override void EnterCombat(Unit who) { }
public override void KilledUnit(Unit victim)
{
if (Phase == 2)
{
Unit unit = Global.ObjAccessor.GetUnit(me, Attumen);
if (unit)
Talk(TextIds.SayMidnightKill, unit);
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (Phase == 1 && HealthBelowPct(95))
{
Phase = 2;
Creature attumen = me.SummonCreature(Misc.SummonAttumen, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType.TimedOrDeadDespawn, 30000);
if (attumen)
{
Attumen = attumen.GetGUID();
attumen.GetAI().AttackStart(me.GetVictim());
SetMidnight(attumen, me.GetGUID());
Talk(TextIds.SayAppear, attumen);
}
}
else if (Phase == 2 && HealthBelowPct(25))
{
Unit pAttumen = Global.ObjAccessor.GetUnit(me, Attumen);
if (pAttumen)
Mount(pAttumen);
}
else if (Phase == 3)
{
if (mountTimer != 0)
{
if (mountTimer <= diff)
{
mountTimer = 0;
me.SetVisible(false);
me.GetMotionMaster().MoveIdle();
Unit pAttumen = Global.ObjAccessor.GetUnit(me, Attumen);
if (pAttumen)
{
pAttumen.SetDisplayId(Misc.MountedDisplayid);
pAttumen.RemoveFlag(UnitFields.Flags, UnitFlags.NonAttackable);
if (pAttumen.GetVictim())
{
pAttumen.GetMotionMaster().MoveChase(pAttumen.GetVictim());
pAttumen.SetTarget(pAttumen.GetVictim().GetGUID());
}
pAttumen.SetObjectScale(1);
}
}
else mountTimer -= diff;
}
}
if (Phase != 3)
DoMeleeAttackIfReady();
}
public void Mount(Unit pAttumen)
{
Talk(TextIds.SayMount, pAttumen);
Phase = 3;
me.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
pAttumen.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
float angle = me.GetAngle(pAttumen);
float distance = me.GetDistance2d(pAttumen);
float newX = me.GetPositionX() + (float)Math.Cos(angle) * (distance / 2);
float newY = me.GetPositionY() + (float)Math.Sin(angle) * (distance / 2);
float newZ = 50;
me.GetMotionMaster().Clear();
me.GetMotionMaster().MovePoint(0, newX, newY, newZ);
distance += 10;
newX = me.GetPositionX() + (float)Math.Cos(angle) * (distance / 2);
newY = me.GetPositionY() + (float)Math.Sin(angle) * (distance / 2);
pAttumen.GetMotionMaster().Clear();
pAttumen.GetMotionMaster().MovePoint(0, newX, newY, newZ);
mountTimer = 1000;
}
void SetMidnight(Creature pAttumen, ObjectGuid value)
{
((boss_attumen)pAttumen.GetAI()).Midnight = value;
}
ObjectGuid Attumen;
byte Phase;
uint mountTimer;
}
}
@@ -0,0 +1,158 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.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
{
//Flare spell info
public const uint AstralFlarePassive = 30234; //Visual effect + Flare damage
//Curator spell info
public const uint HatefulBolt = 30383;
public const uint Evocation = 30254;
public const uint Enrage = 30403; //Arcane Infusion: Transforms Curator and adds damage.
public const uint Berserk = 26662;
}
[Script]
class boss_curator : ScriptedAI
{
public boss_curator(Creature creature) : base(creature)
{
Initialize();
}
void Initialize()
{
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
{
//Summon Astral Flare
Creature AstralFlare = DoSpawnCreature(17096, RandomHelper.Rand32() % 37, RandomHelper.Rand32() % 37, 0, 0, TempSummonType.TimedDespawnOOC, 5000);
Unit target = SelectTarget(SelectAggroTarget.Random, 0);
if (AstralFlare && target)
{
AstralFlare.CastSpell(AstralFlare, SpellIds.AstralFlarePassive, false);
AstralFlare.GetAI().AttackStart(target);
}
//Reduce Mana by 10% of max health
int mana = me.GetMaxPower(PowerType.Mana);
if (mana != 0)
{
mana /= 10;
me.ModifyPower(PowerType.Mana, -mana);
//if this get's us below 10%, then we evocate (the 10th should be summoned now)
if (me.GetPower(PowerType.Mana) * 100 / me.GetMaxPower(PowerType.Mana) < 10)
{
Talk(TextIds.SayEvocate);
me.InterruptNonMeleeSpells(false);
DoCast(me, SpellIds.Evocation);
_scheduler.DelayAll(TimeSpan.FromSeconds(20));
//Evocating = true;
//no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected
return;
}
else
{
if (RandomHelper.URand(0, 1) == 0)
{
Talk(TextIds.SaySummon);
}
}
}
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
{
if (Enraged)
task.Repeat(TimeSpan.FromSeconds(7));
else
task.Repeat();
Unit target = SelectTarget(SelectAggroTarget.TopAggro, 1);
if (target)
DoCast(target, SpellIds.HatefulBolt);
});
Enraged = false;
}
public override void Reset()
{
Initialize();
me.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Arcane, true);
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayKill);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDeath);
}
public override void EnterCombat(Unit victim)
{
Talk(TextIds.SayAggro);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
if (!Enraged)
{
if (!HealthAbovePct(15))
{
Enraged = true;
DoCast(me, SpellIds.Enrage);
Talk(TextIds.SayEnrage);
}
}
}
bool Enraged;
}
}
@@ -0,0 +1,468 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.IO;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.AI;
namespace Scripts.EasternKingdoms.Karazhan
{
struct karazhanConst
{
public const uint MaxEncounter = 12;
public const uint BossAttumen = 1;
public const uint BossMoroes = 2;
public const uint BossMaiden = 3;
public const uint OptionalBoss = 4;
public const uint BossOpera = 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 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;
}
struct Dialogue
{
public Dialogue(int textid, uint timer)
{
TextId = textid;
Timer = timer;
}
public int TextId;
public uint Timer;
}
struct DataTypes
{
public const uint OperaPerformance = 13;
public const uint OperaOzDeathcount = 14;
public const uint Kilrek = 15;
public const uint Terestian = 16;
public const uint Moroes = 17;
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;
}
struct OperaEvents
{
public const uint Oz = 1;
public const uint Hood = 2;
public const uint RAJ = 3;
}
[Script]
public class instance_karazhan : InstanceMapScript
{
public instance_karazhan() : base("instance_karazhan", 532) { }
public class instance_karazhan_InstanceMapScript : InstanceScript
{
public instance_karazhan_InstanceMapScript(Map map) : base(map)
{
SetHeaders("KZ");
// 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered.
m_uiOperaEvent = RandomHelper.URand(1, 3);
m_uiOzDeathCount = 0;
}
public override bool IsEncounterInProgress()
{
for (byte i = 0; i < karazhanConst.MaxEncounter; ++i)
if (m_auiEncounter[i] == (uint)EncounterState.InProgress)
return true;
return false;
}
public override void OnCreatureCreate(Creature creature)
{
switch (creature.GetEntry())
{
case 17229:
m_uiKilrekGUID = creature.GetGUID();
break;
case 15688:
m_uiTerestianGUID = creature.GetGUID();
break;
case 15687:
m_uiMoroesGUID = creature.GetGUID();
break;
}
}
public override void SetData(uint type, uint uiData)
{
switch (type)
{
case karazhanConst.BossAttumen:
m_auiEncounter[0] = uiData;
break;
case karazhanConst.BossMoroes:
if (m_auiEncounter[1] == (uint)EncounterState.Done)
break;
m_auiEncounter[1] = uiData;
break;
case karazhanConst.BossMaiden:
m_auiEncounter[2] = uiData;
break;
case karazhanConst.OptionalBoss:
m_auiEncounter[3] = uiData;
break;
case karazhanConst.BossOpera:
m_auiEncounter[4] = uiData;
if (uiData == (uint)EncounterState.Done)
UpdateEncounterStateForKilledCreature(16812, null);
break;
case karazhanConst.Curator:
m_auiEncounter[5] = uiData;
break;
case karazhanConst.Aran:
m_auiEncounter[6] = uiData;
break;
case karazhanConst.Terestian:
m_auiEncounter[7] = uiData;
break;
case karazhanConst.Netherspite:
m_auiEncounter[8] = uiData;
break;
case karazhanConst.Chess:
if (uiData == (uint)EncounterState.Done)
DoRespawnGameObject(DustCoveredChest, Time.Day);
m_auiEncounter[9] = uiData;
break;
case karazhanConst.Malchezzar:
m_auiEncounter[10] = uiData;
break;
case karazhanConst.Nightbane:
if (m_auiEncounter[11] != (uint)EncounterState.Done)
m_auiEncounter[11] = uiData;
break;
case DataTypes.OperaOzDeathcount:
if (uiData == (uint)EncounterState.Special)
++m_uiOzDeathCount;
else if (uiData == (uint)EncounterState.InProgress)
m_uiOzDeathCount = 0;
break;
}
if (uiData == (uint)EncounterState.Done)
{
OUT_SAVE_INST_DATA();
strSaveData = string.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}", m_auiEncounter[0], m_auiEncounter[1], m_auiEncounter[2], m_auiEncounter[3],
m_auiEncounter[4], m_auiEncounter[5], m_auiEncounter[6], m_auiEncounter[7], m_auiEncounter[8], m_auiEncounter[9], m_auiEncounter[10], m_auiEncounter[11]);
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE();
}
}
public override void SetGuidData(uint identifier, ObjectGuid data)
{
if (identifier == DataTypes.ImageOfMedivh)
ImageGUID = data;
}
public override void OnGameObjectCreate(GameObject go)
{
switch (go.GetEntry())
{
case 183932:
m_uiCurtainGUID = go.GetGUID();
break;
case 184278:
m_uiStageDoorLeftGUID = go.GetGUID();
if (m_auiEncounter[4] == (uint)EncounterState.Done)
go.SetGoState(GameObjectState.Active);
break;
case 184279:
m_uiStageDoorRightGUID = go.GetGUID();
if (m_auiEncounter[4] == (uint)EncounterState.Done)
go.SetGoState(GameObjectState.Active);
break;
case 184517:
m_uiLibraryDoor = go.GetGUID();
break;
case 185521:
m_uiMassiveDoor = go.GetGUID();
break;
case 184276:
m_uiGamesmansDoor = go.GetGUID();
break;
case 184277:
m_uiGamesmansExitDoor = go.GetGUID();
break;
case 185134:
m_uiNetherspaceDoor = go.GetGUID();
break;
case 184274:
MastersTerraceDoor[0] = go.GetGUID();
break;
case 184280:
MastersTerraceDoor[1] = go.GetGUID();
break;
case 184275:
m_uiSideEntranceDoor = go.GetGUID();
if (m_auiEncounter[4] == (uint)EncounterState.Done)
go.SetFlag(GameObjectFields.Flags, GameObjectFlags.Locked);
else
go.RemoveFlag(GameObjectFields.Flags, GameObjectFlags.Locked);
break;
case 185119:
DustCoveredChest = go.GetGUID();
break;
}
switch (m_uiOperaEvent)
{
/// @todo Set Object visibilities for Opera based on performance
case OperaEvents.Oz:
break;
case OperaEvents.Hood:
break;
case OperaEvents.RAJ:
break;
}
}
public override string GetSaveData()
{
return strSaveData;
}
public override uint GetData(uint uiData)
{
switch (uiData)
{
case karazhanConst.BossAttumen:
return m_auiEncounter[0];
case karazhanConst.BossMoroes:
return m_auiEncounter[1];
case karazhanConst.BossMaiden:
return m_auiEncounter[2];
case karazhanConst.OptionalBoss:
return m_auiEncounter[3];
case karazhanConst.BossOpera:
return m_auiEncounter[4];
case karazhanConst.Curator:
return m_auiEncounter[5];
case karazhanConst.Aran:
return m_auiEncounter[6];
case karazhanConst.Terestian:
return m_auiEncounter[7];
case karazhanConst.Netherspite:
return m_auiEncounter[8];
case karazhanConst.Chess:
return m_auiEncounter[9];
case karazhanConst.Malchezzar:
return m_auiEncounter[10];
case karazhanConst.Nightbane:
return m_auiEncounter[11];
case DataTypes.OperaPerformance:
return m_uiOperaEvent;
case DataTypes.OperaOzDeathcount:
return m_uiOzDeathCount;
}
return 0;
}
public override ObjectGuid GetGuidData(uint uiData)
{
switch (uiData)
{
case DataTypes.Kilrek:
return m_uiKilrekGUID;
case DataTypes.Terestian:
return m_uiTerestianGUID;
case DataTypes.Moroes:
return m_uiMoroesGUID;
case DataTypes.GoStagedoorleft:
return m_uiStageDoorLeftGUID;
case DataTypes.GoStagedoorright:
return m_uiStageDoorRightGUID;
case DataTypes.GoCurtains:
return m_uiCurtainGUID;
case DataTypes.GoLibraryDoor:
return m_uiLibraryDoor;
case DataTypes.GoMassiveDoor:
return m_uiMassiveDoor;
case DataTypes.GoSideEntranceDoor:
return m_uiSideEntranceDoor;
case DataTypes.GoGameDoor:
return m_uiGamesmansDoor;
case DataTypes.GoGameExitDoor:
return m_uiGamesmansExitDoor;
case DataTypes.GoNetherDoor:
return m_uiNetherspaceDoor;
case DataTypes.MastersTerraceDoor1:
return MastersTerraceDoor[0];
case DataTypes.MastersTerraceDoor2:
return MastersTerraceDoor[1];
case DataTypes.ImageOfMedivh:
return ImageGUID;
}
return ObjectGuid.Empty;
}
public override void Load(string str)
{
if (string.IsNullOrEmpty(str))
{
OUT_LOAD_INST_DATA_FAIL();
return;
}
OUT_LOAD_INST_DATA(str);
StringArguments loadStream = new StringArguments(str);
for (byte i = 0; i < karazhanConst.MaxEncounter; ++i)
{
var state = (EncounterState)loadStream.NextUInt32();
// Do not load an encounter as "In Progress" - reset it instead.
m_auiEncounter[i] = (uint)(state == EncounterState.InProgress ? EncounterState.NotStarted : state);
}
OUT_LOAD_INST_DATA_COMPLETE();
}
uint[] m_auiEncounter = new uint[karazhanConst.MaxEncounter];
string strSaveData;
uint m_uiOperaEvent;
uint m_uiOzDeathCount;
ObjectGuid m_uiCurtainGUID;
ObjectGuid m_uiStageDoorLeftGUID;
ObjectGuid m_uiStageDoorRightGUID;
ObjectGuid m_uiKilrekGUID;
ObjectGuid m_uiTerestianGUID;
ObjectGuid m_uiMoroesGUID;
ObjectGuid m_uiLibraryDoor; // Door at Shade of Aran
ObjectGuid m_uiMassiveDoor; // Door at Netherspite
ObjectGuid m_uiSideEntranceDoor; // Side Entrance
ObjectGuid m_uiGamesmansDoor; // Door before Chess
ObjectGuid m_uiGamesmansExitDoor; // Door after Chess
ObjectGuid m_uiNetherspaceDoor; // Door at Malchezaar
ObjectGuid[] MastersTerraceDoor = new ObjectGuid[2];
ObjectGuid ImageGUID;
ObjectGuid DustCoveredChest;
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_karazhan_InstanceMapScript(map);
}
public static T GetKarazhanAI<T>(Creature creature) where T : CreatureAI
{
return GetInstanceAI<T>(creature, "instance_karazhan");
}
}
}
@@ -0,0 +1,732 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System.Collections.Generic;
namespace Scripts.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.SetData(karazhanConst.BossMoroes, (uint)EncounterState.NotStarted);
}
void StartEvent()
{
instance.SetData(karazhanConst.BossMoroes, (uint)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.SetData(karazhanConst.BossMoroes, (uint)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(karazhanConst.BossMoroes) == 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)
{
List<Unit> targets = SelectTargetList(5, SelectAggroTarget.Random, me.GetCombatReach() * 5, true);
foreach (var i in targets)
{
if (!me.IsWithinMeleeRange(i))
{
DoCast(i, SpellIds.Blind);
break;
}
}
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.SetData(karazhanConst.BossMoroes, (uint)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(karazhanConst.BossMoroes) == 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
@@ -0,0 +1,353 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game;
using Game.AI;
using Game.Entities;
using Game.Scripting;
namespace Scripts.EasternKingdoms
{
enum UnworthyInitiatePhase
{
Chained,
ToEquip,
Equiping,
ToAttack,
Attacking
}
[Script]
public class npc_unworthy_initiate : ScriptedAI
{
public npc_unworthy_initiate(Creature creature) : base(creature)
{
me.SetReactState(ReactStates.Passive);
if (me.GetCurrentEquipmentId() == 0)
me.SetCurrentEquipmentId((byte)me.GetOriginalEquipmentId());
}
public override void Reset()
{
anchorGUID.Clear();
phase = UnworthyInitiatePhase.Chained;
_events.Reset();
me.SetFaction(7);
me.SetFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
me.SetStandState(UnitStandStateType.Kneel);
me.LoadEquipment(0, true);
}
public override void EnterCombat(Unit who)
{
_events.ScheduleEvent(EventIcyTouch, 1000, 1);
_events.ScheduleEvent(EventPlagueStrike, 3000, 1);
_events.ScheduleEvent(EventBloodStrike, 2000, 1);
_events.ScheduleEvent(EventDeathCoil, 5000, 1);
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point)
return;
if (id == 1)
{
wait_timer = 5000;
me.CastSpell(me, SpellDKInitateVisual, true);
Player starter = Global.ObjAccessor.GetPlayer(me, playerGUID);
if (starter)
Global.CreatureTextMgr.SendChat(me, (byte)SayEventAttack, null, ChatMsg.Addon, Language.Addon, CreatureTextRange.Normal, 0, Team.Other, false, starter);
phase = UnworthyInitiatePhase.ToAttack;
}
}
public void EventStart(Creature anchor, Player target)
{
wait_timer = 5000;
phase = UnworthyInitiatePhase.ToEquip;
me.SetStandState(UnitStandStateType.Stand);
me.RemoveAurasDueToSpell(SpellSoulPrisonChainSelf);
me.RemoveAurasDueToSpell(SpellSoulPrisonChain);
float z;
anchor.GetContactPoint(me, out anchorX, out anchorY, out z, 1.0f);
playerGUID = target.GetGUID();
Talk(SayEventStart);
}
public override void UpdateAI(uint diff)
{
switch (phase)
{
case UnworthyInitiatePhase.Chained:
if (anchorGUID.IsEmpty())
{
Creature anchor = me.FindNearestCreature(29521, 30);
if (anchor)
{
anchor.GetAI().SetGUID(me.GetGUID());
anchor.CastSpell(me, SpellSoulPrisonChain, true);
anchorGUID = anchor.GetGUID();
}
else
Log.outError(LogFilter.Scripts, "npc_unworthy_initiateAI: unable to find anchor!");
float dist = 99.0f;
GameObject prison = null;
for (byte i = 0; i < 12; ++i)
{
GameObject temp_prison = me.FindNearestGameObject(acherus_soul_prison[i], 30);
if (temp_prison)
{
if (me.IsWithinDist(temp_prison, dist, false))
{
dist = me.GetDistance2d(temp_prison);
prison = temp_prison;
}
}
}
if (prison)
prison.ResetDoorOrButton();
else
Log.outError(LogFilter.Scripts, "npc_unworthy_initiateAI: unable to find prison!");
}
break;
case UnworthyInitiatePhase.ToEquip:
if (wait_timer != 0)
{
if (wait_timer > diff)
wait_timer -= diff;
else
{
me.GetMotionMaster().MovePoint(1, anchorX, anchorY, me.GetPositionZ());
phase = UnworthyInitiatePhase.Equiping;
wait_timer = 0;
}
}
break;
case UnworthyInitiatePhase.ToAttack:
if (wait_timer != 0)
{
if (wait_timer > diff)
wait_timer -= diff;
else
{
me.SetFaction(14);
me.RemoveFlag(UnitFields.Flags, UnitFlags.ImmuneToPc);
phase = UnworthyInitiatePhase.Attacking;
Player target = Global.ObjAccessor.GetPlayer(me, playerGUID);
if (target)
AttackStart(target);
wait_timer = 0;
}
}
break;
case UnworthyInitiatePhase.Attacking:
if (!UpdateVictim())
return;
_events.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch (eventId)
{
case EventIcyTouch:
DoCastVictim(SpellIcyTouch);
_events.DelayEvents(1000, 1);
_events.ScheduleEvent(EventIcyTouch, 5000, 1);
break;
case EventPlagueStrike:
DoCastVictim(SpellPlagueStrike);
_events.DelayEvents(1000, 1);
_events.ScheduleEvent(EventPlagueStrike, 5000, 1);
break;
case EventBloodStrike:
DoCastVictim(SpellBloodStrike);
_events.DelayEvents(1000, 1);
_events.ScheduleEvent(EventBloodStrike, 5000, 1);
break;
case EventDeathCoil:
DoCastVictim(SpellDeathCoil);
_events.DelayEvents(1000, 1);
_events.ScheduleEvent(EventDeathCoil, 5000, 1);
break;
}
});
DoMeleeAttackIfReady();
break;
default:
break;
}
}
ObjectGuid playerGUID;
UnworthyInitiatePhase phase;
uint wait_timer;
float anchorX, anchorY;
ObjectGuid anchorGUID;
const uint SpellSoulPrisonChainSelf = 54612;
const uint SpellSoulPrisonChain = 54613;
const uint SpellDKInitateVisual = 51519;
const uint SpellIcyTouch = 52372;
const uint SpellPlagueStrike = 52373;
const uint SpellBloodStrike = 52374;
const uint SpellDeathCoil = 52375;
const uint SayEventStart = 0;
const uint SayEventAttack = 1;
const uint EventIcyTouch = 1;
const uint EventPlagueStrike = 2;
const uint EventBloodStrike = 3;
const uint EventDeathCoil = 4;
static uint[] acherus_soul_prison = { 191577, 191580, 191581, 191582, 191583, 191584, 191585, 191586, 191587, 191588, 191589, 191590 };
}
[Script]
class npc_unworthy_initiate_anchor : PassiveAI
{
public npc_unworthy_initiate_anchor(Creature creature) : base(creature) { }
public override void SetGUID(ObjectGuid guid, int id)
{
if (prisonerGUID.IsEmpty())
prisonerGUID = guid;
}
public override ObjectGuid GetGUID(int id)
{
return prisonerGUID;
}
ObjectGuid prisonerGUID;
}
[Script]
class go_acherus_soul_prison : GameObjectScript
{
public go_acherus_soul_prison() : base("go_acherus_soul_prison") { }
public override bool OnGossipHello(Player player, GameObject go)
{
Creature anchor = go.FindNearestCreature(29521, 15);
if (anchor)
{
ObjectGuid prisonerGUID = anchor.GetAI().GetGUID();
if (!prisonerGUID.IsEmpty())
{
Creature prisoner = ObjectAccessor.GetCreature(player, prisonerGUID);
if (prisoner)
((npc_unworthy_initiate)prisoner.GetAI()).EventStart(anchor, player);
}
}
return false;
}
}
struct EyeOfAcherus
{
public const uint EyeHugeDisplayId = 26320;
public const uint EyeSmallDisplayId = 25499;
public const uint SpellEyePhasemask = 70889;
public const uint SpellEyeVisual = 51892;
public const uint SpellEyeFlight = 51923;
public const uint SpellEyeFlightBoost = 51890;
public const uint SpellEyeControl = 51852;
public const string SayEyeLaunched = "Eye of Acherus is launched towards its destination.";
public const string SayEyeUnderControl = "You are now in control of the eye.";
public static float[] EyeDestination = { 1750.8276f, -5873.788f, 147.2266f };
}
[Script]
class npc_eye_of_acherus : ScriptedAI
{
public npc_eye_of_acherus(Creature creature) : base(creature)
{
Reset();
}
uint startTimer;
public override void Reset()
{
startTimer = 2000;
}
public override void AttackStart(Unit u) { }
public override void MoveInLineOfSight(Unit u) { }
public override void JustDied(Unit killer)
{
Unit charmer = me.GetCharmer();
if (charmer)
charmer.RemoveAurasDueToSpell(EyeOfAcherus.SpellEyeControl);
}
public override void UpdateAI(uint diff)
{
if (me.IsCharmed())
{
if (startTimer <= diff) // fly to start point
{
me.CastSpell(me, EyeOfAcherus.SpellEyePhasemask, true);
me.CastSpell(me, EyeOfAcherus.SpellEyeVisual, true);
me.CastSpell(me, EyeOfAcherus.SpellEyeFlightBoost, true);
me.SetSpeedRate(UnitMoveType.Flight, 4f);
me.GetMotionMaster().MovePoint(0, EyeOfAcherus.EyeDestination[0], EyeOfAcherus.EyeDestination[1], EyeOfAcherus.EyeDestination[2]);
return;
}
else
startTimer -= diff;
}
else
me.ForcedDespawn();
}
public override void MovementInform(MovementGeneratorType type, uint id)
{
if (type != MovementGeneratorType.Point || id != 0)
return;
me.SetDisplayId(EyeOfAcherus.EyeSmallDisplayId);
me.CastSpell(me, EyeOfAcherus.SpellEyeFlight, true);
me.Say(EyeOfAcherus.SayEyeUnderControl, Language.Universal);
if (me.GetCharmer() && me.GetCharmer().IsTypeId(TypeId.Player))
me.GetCharmer().ToPlayer().SetClientControl(me, true);
}
}
}
@@ -0,0 +1,133 @@
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;
}
});
}
}
}
@@ -0,0 +1,50 @@
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(Map map) : base(map)
{
SetHeaders("SS");
SetBossNumber(3);
}
}
public override InstanceScript GetInstanceScript(InstanceMap map)
{
return new instance_the_stockade_InstanceMapScript(map);
}
}
}