Files
CypherCore/Source/Scripts/EasternKingdoms/Karazhan/OperaEvent.cs
T
2020-01-09 11:35:00 -05:00

1665 lines
51 KiB
C#

/*
* 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.EasternKingdoms.Karazhan.OperaEvent
{
struct TextIds
{
public const uint SayDorotheeDeath = 0;
public const uint SayDorotheeSummon = 1;
public const uint SayDorotheeTitoDeath = 2;
public const uint SayDorotheeAggro = 3;
public const uint SayRoarAggro = 0;
public const uint SayRoarDeath = 1;
public const uint SayRoarSlay = 2;
public const uint SayStrawmanAggro = 0;
public const uint SayStrawmanDeath = 1;
public const uint SayStrawmanSlay = 2;
public const uint SayTinheadAggro = 0;
public const uint SayTinheadDeath = 1;
public const uint SayTinheadSlay = 2;
public const uint EmoteRust = 3;
public const uint SayCroneAggro = 0;
public const uint SayCroneDeath = 1;
public const uint SayCroneSlay = 2;
}
struct SpellIds
{
// Dorothee
public const uint Waterbolt = 31012;
public const uint Scream = 31013;
public const uint Summontito = 31014;
// Tito
public const uint Yipping = 31015;
// Strawman
public const uint BrainBash = 31046;
public const uint BrainWipe = 31069;
public const uint BurningStraw = 31075;
// Tinhead
public const uint Cleave = 31043;
public const uint Rust = 31086;
// Roar
public const uint Mangle = 31041;
public const uint Shred = 31042;
public const uint FrightenedScream = 31013;
// Crone
public const uint ChainLightning = 32337;
// Cyclone
public const uint Knockback = 32334;
public const uint CycloneVisual = 32332;
}
struct CreatureIds
{
public const uint Tito = 17548;
public const uint Cyclone = 18412;
public const uint Crone = 18168;
}
#region Wizard of Oz
public abstract class WizardofOzBase : ScriptedAI
{
public WizardofOzBase(Creature creature) : base(creature)
{
Initialize();
instance = creature.GetInstanceScript();
}
public abstract void Initialize();
public override void Reset()
{
Initialize();
}
public void SummonCroneIfReady(InstanceScript instance, Creature creature)
{
instance.SetBossState(DataTypes.OperaOzDeathcount, EncounterState.Special); // Increment DeathCount
if (instance.GetData(DataTypes.OperaOzDeathcount) == 4)
{
Creature pCrone = creature.SummonCreature(CreatureIds.Crone, -10891.96f, -1755.95f, creature.GetPositionZ(), 4.64f, TempSummonType.TimedOrDeadDespawn, Time.Hour * 2 * Time.InMilliseconds);
if (pCrone)
{
if (creature.GetVictim())
pCrone.GetAI().AttackStart(creature.GetVictim());
}
}
}
public bool TitoDied;
public ObjectGuid DorotheeGUID;
public uint AggroTimer;
public InstanceScript instance;
}
[Script]
public class boss_dorothee : WizardofOzBase
{
public boss_dorothee(Creature creature) : base(creature) { }
public override void Initialize()
{
AggroTimer = 500;
WaterBoltTimer = 5000;
FearTimer = 15000;
SummonTitoTimer = 47500;
SummonedTito = false;
TitoDied = false;
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayDorotheeAggro);
}
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayDorotheeDeath);
SummonCroneIfReady(instance, me);
}
public override void AttackStart(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.AttackStart(who);
}
public override void MoveInLineOfSight(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.MoveInLineOfSight(who);
}
public override void UpdateAI(uint diff)
{
if (AggroTimer != 0)
{
if (AggroTimer <= diff)
{
me.RemoveUnitFlag(UnitFlags.NonAttackable);
AggroTimer = 0;
}
else AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (WaterBoltTimer <= diff)
{
DoCast(SelectTarget(SelectAggroTarget.Random, 0), SpellIds.Waterbolt);
WaterBoltTimer = (uint)(TitoDied ? 1500 : 5000);
}
else WaterBoltTimer -= diff;
if (FearTimer <= diff)
{
DoCastVictim(SpellIds.Scream);
FearTimer = 30000;
}
else FearTimer -= diff;
if (!SummonedTito)
{
if (SummonTitoTimer <= diff)
SummonTito();
else SummonTitoTimer -= diff;
}
DoMeleeAttackIfReady();
}
void SummonTito()
{
Creature pTito = me.SummonCreature(CreatureIds.Tito, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType.TimedDespawnOOC, 30000);
if (pTito)
{
Talk(TextIds.SayDorotheeSummon);
DorotheeGUID = me.GetGUID();
pTito.GetAI().AttackStart(me.GetVictim());
SummonedTito = true;
TitoDied = false;
}
}
uint WaterBoltTimer;
uint FearTimer;
uint SummonTitoTimer;
bool SummonedTito;
}
[Script]
public class npc_tito : WizardofOzBase
{
public npc_tito(Creature creature) : base(creature)
{
Initialize();
}
public override void Initialize()
{
DorotheeGUID.Clear();
YipTimer = 10000;
}
public override void EnterCombat(Unit who) { }
public override void JustDied(Unit killer)
{
if (!DorotheeGUID.IsEmpty())
{
Creature Dorothee = ObjectAccessor.GetCreature(me, DorotheeGUID);
if (Dorothee && Dorothee.IsAlive())
{
TitoDied = true;
Talk(TextIds.SayDorotheeTitoDeath, Dorothee);
}
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (YipTimer <= diff)
{
DoCastVictim(SpellIds.Yipping);
YipTimer = 10000;
}
else YipTimer -= diff;
DoMeleeAttackIfReady();
}
uint YipTimer;
}
[Script]
class boss_strawman : WizardofOzBase
{
public boss_strawman(Creature creature) : base(creature)
{
Initialize();
instance = creature.GetInstanceScript();
}
public override void Initialize()
{
AggroTimer = 13000;
BrainBashTimer = 5000;
BrainWipeTimer = 7000;
}
public override void AttackStart(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.AttackStart(who);
}
public override void MoveInLineOfSight(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.MoveInLineOfSight(who);
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayStrawmanAggro);
}
public override void SpellHit(Unit caster, SpellInfo Spell)
{
if ((Spell.SchoolMask == SpellSchoolMask.Fire) && ((RandomHelper.randChance() % 10) == 0))
{
DoCast(me, SpellIds.BurningStraw, true);
}
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayStrawmanDeath);
SummonCroneIfReady(instance, me);
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayStrawmanSlay);
}
public override void UpdateAI(uint diff)
{
if (AggroTimer != 0)
{
if (AggroTimer <= diff)
{
me.RemoveUnitFlag(UnitFlags.NonAttackable);
AggroTimer = 0;
}
else AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (BrainBashTimer <= diff)
{
DoCastVictim(SpellIds.BrainBash);
BrainBashTimer = 15000;
}
else BrainBashTimer -= diff;
if (BrainWipeTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
DoCast(target, SpellIds.BrainWipe);
BrainWipeTimer = 20000;
}
else BrainWipeTimer -= diff;
DoMeleeAttackIfReady();
}
uint BrainBashTimer;
uint BrainWipeTimer;
}
[Script]
class boss_tinhead : WizardofOzBase
{
public boss_tinhead(Creature creature) : base(creature) { }
public override void Initialize()
{
AggroTimer = 15000;
CleaveTimer = 5000;
RustTimer = 30000;
RustCount = 0;
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayTinheadAggro);
}
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void AttackStart(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.AttackStart(who);
}
public override void MoveInLineOfSight(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.MoveInLineOfSight(who);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayTinheadDeath);
SummonCroneIfReady(instance, me);
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayTinheadSlay);
}
public override void UpdateAI(uint diff)
{
if (AggroTimer != 0)
{
if (AggroTimer <= diff)
{
me.RemoveUnitFlag(UnitFlags.NonAttackable);
AggroTimer = 0;
}
else AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (CleaveTimer <= diff)
{
DoCastVictim(SpellIds.Cleave);
CleaveTimer = 5000;
}
else CleaveTimer -= diff;
if (RustCount < 8)
{
if (RustTimer <= diff)
{
++RustCount;
Talk(TextIds.EmoteRust);
DoCast(me, SpellIds.Rust);
RustTimer = 6000;
}
else RustTimer -= diff;
}
DoMeleeAttackIfReady();
}
uint CleaveTimer;
uint RustTimer;
byte RustCount;
}
[Script]
class boss_roar : WizardofOzBase
{
public boss_roar(Creature creature) : base(creature) { }
public override void Initialize()
{
AggroTimer = 20000;
MangleTimer = 5000;
ShredTimer = 10000;
ScreamTimer = 15000;
}
public override void AttackStart(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.AttackStart(who);
}
public override void MoveInLineOfSight(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.MoveInLineOfSight(who);
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayRoarAggro);
}
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayRoarDeath);
SummonCroneIfReady(instance, me);
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayRoarSlay);
}
public override void UpdateAI(uint diff)
{
if (AggroTimer != 0)
{
if (AggroTimer <= diff)
{
me.RemoveUnitFlag(UnitFlags.NonAttackable);
AggroTimer = 0;
}
else AggroTimer -= diff;
}
if (!UpdateVictim())
return;
if (MangleTimer <= diff)
{
DoCastVictim(SpellIds.Mangle);
MangleTimer = RandomHelper.URand(5000, 8000);
}
else MangleTimer -= diff;
if (ShredTimer <= diff)
{
DoCastVictim(SpellIds.Shred);
ShredTimer = RandomHelper.URand(10000, 15000);
}
else ShredTimer -= diff;
if (ScreamTimer <= diff)
{
DoCastVictim(SpellIds.FrightenedScream);
ScreamTimer = RandomHelper.URand(20000, 30000);
}
else ScreamTimer -= diff;
DoMeleeAttackIfReady();
}
uint MangleTimer;
uint ShredTimer;
uint ScreamTimer;
}
[Script]
class boss_crone : WizardofOzBase
{
public boss_crone(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
}
public override void Initialize()
{
me.RemoveUnitFlag(UnitFlags.ImmuneToPc | UnitFlags.NonAttackable);
CycloneTimer = 30000;
ChainLightningTimer = 10000;
}
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void KilledUnit(Unit victim)
{
Talk(TextIds.SayCroneSlay);
}
public override void EnterCombat(Unit who)
{
Talk(TextIds.SayCroneAggro);
me.RemoveUnitFlag(UnitFlags.NonAttackable);
me.RemoveUnitFlag(UnitFlags.ImmuneToPc);
}
public override void JustDied(Unit killer)
{
Talk(TextIds.SayCroneDeath);
instance.SetBossState(DataTypes.OperaPerformance, EncounterState.Done);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
if (me.HasUnitFlag(UnitFlags.NonAttackable))
me.RemoveUnitFlag(UnitFlags.NonAttackable);
if (CycloneTimer <= diff)
{
Creature Cyclone = DoSpawnCreature(CreatureIds.Cyclone, RandomHelper.FRand(0, 9), RandomHelper.FRand(0, 9), 0, 0, TempSummonType.TimedDespawn, 15000);
if (Cyclone)
Cyclone.CastSpell(Cyclone, SpellIds.CycloneVisual, true);
CycloneTimer = 30000;
}
else CycloneTimer -= diff;
if (ChainLightningTimer <= diff)
{
DoCastVictim(SpellIds.ChainLightning);
ChainLightningTimer = 15000;
}
else ChainLightningTimer -= diff;
DoMeleeAttackIfReady();
}
uint CycloneTimer;
uint ChainLightningTimer;
}
[Script]
class npc_cyclone : ScriptedAI
{
public npc_cyclone(Creature creature) : base(creature) { }
public override void Reset()
{
MoveTimer = 1000;
}
public override void EnterCombat(Unit who) { }
public override void MoveInLineOfSight(Unit who) { }
public override void UpdateAI(uint diff)
{
if (!me.HasAura(SpellIds.Knockback))
DoCast(me, SpellIds.Knockback, true);
if (MoveTimer <= diff)
{
Position pos = me.GetRandomNearPosition(10);
me.GetMotionMaster().MovePoint(0, pos);
MoveTimer = RandomHelper.URand(5000, 8000);
}
else MoveTimer -= diff;
}
uint MoveTimer;
}
#endregion
#region Red Riding Hood
struct RedRidingHood
{
public const uint SayWolfAggro = 0;
public const uint SayWolfSlay = 1;
public const uint SayWolfHood = 2;
public const uint OptionWhatPhatLewtsYouHave = 7443;
public const uint SoundWolfDeath = 9275;
public const uint SpellLittleRedRidingHood = 30768;
public const uint SpellTerrifyingHowl = 30752;
public const uint SpellWideSwipe = 30761;
public const uint NpcBigBadWolf = 17521;
}
[Script]
class npc_grandmother : ScriptedAI
{
public npc_grandmother(Creature creature) : base(creature) { }
public override void GossipSelect(Player player, uint menuId, uint gossipListId)
{
if (menuId == RedRidingHood.OptionWhatPhatLewtsYouHave && gossipListId == 0)
{
player.PlayerTalkClass.SendCloseGossip();
Creature pBigBadWolf = me.SummonCreature(RedRidingHood.NpcBigBadWolf, me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetOrientation(), TempSummonType.TimedOrDeadDespawn, Time.Hour * 2 * Time.InMilliseconds);
if (pBigBadWolf)
pBigBadWolf.GetAI().AttackStart(player);
me.DespawnOrUnsummon();
}
}
}
[Script]
class boss_bigbadwolf : ScriptedAI
{
public boss_bigbadwolf(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
}
public override void Reset()
{
ChaseTimer = 30000;
FearTimer = RandomHelper.URand(25000, 35000);
SwipeTimer = 5000;
HoodGUID.Clear();
TempThreat = 0;
IsChasing = false;
}
public override void EnterCombat(Unit who)
{
Talk(RedRidingHood.SayWolfAggro);
}
public override void KilledUnit(Unit victim)
{
Talk(RedRidingHood.SayWolfSlay);
}
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void JustDied(Unit killer)
{
DoPlaySoundToSet(me, RedRidingHood.SoundWolfDeath);
instance.SetBossState(DataTypes.OperaPerformance, EncounterState.Done);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
if (ChaseTimer <= diff)
{
if (!IsChasing)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
{
Talk(RedRidingHood.SayWolfHood);
DoCast(target, RedRidingHood.SpellLittleRedRidingHood, true);
TempThreat = DoGetThreat(target);
if (TempThreat != 0.0f)
DoModifyThreatPercent(target, -100);
HoodGUID = target.GetGUID();
me.AddThreat(target, 1000000.0f);
ChaseTimer = 20000;
IsChasing = true;
}
}
else
{
IsChasing = false;
Unit target = Global.ObjAccessor.GetUnit(me, HoodGUID);
if (target)
{
HoodGUID.Clear();
if (DoGetThreat(target) != 0f)
DoModifyThreatPercent(target, -100);
me.AddThreat(target, TempThreat);
TempThreat = 0;
}
ChaseTimer = 40000;
}
}
else ChaseTimer -= diff;
if (IsChasing)
return;
if (FearTimer <= diff)
{
DoCastVictim(RedRidingHood.SpellTerrifyingHowl);
FearTimer = RandomHelper.URand(25000, 35000);
}
else FearTimer -= diff;
if (SwipeTimer <= diff)
{
DoCastVictim(RedRidingHood.SpellWideSwipe);
SwipeTimer = RandomHelper.URand(25000, 30000);
}
else SwipeTimer -= diff;
}
InstanceScript instance;
uint ChaseTimer;
uint FearTimer;
uint SwipeTimer;
ObjectGuid HoodGUID;
float TempThreat;
bool IsChasing;
}
#endregion
#region Romeo & Juliet
struct JulianneRomulo
{
public const uint SayJulianneAggro = 0;
public const uint SayJulianneEnter = 1;
public const uint SayJulianneDeath01 = 2;
public const uint SayJulianneDeath02 = 3;
public const uint SayJulianneResurrect = 4;
public const uint SayJulianneSlay = 5;
public const uint SayRomuloAggro = 0;
public const uint SayRomuloDeath = 1;
public const uint SayRomuloEnter = 2;
public const uint SayRomuloResurrect = 3;
public const uint SayRomuloSlay = 4;
public const uint SpellBlindingPassion = 30890;
public const uint SpellDevotion = 30887;
public const uint SpellEternalAffection = 30878;
public const uint SpellPowerfulAttraction = 30889;
public const uint SpellDrinkPoison = 30907;
public const uint SpellBackwardLunge = 30815;
public const uint SpellDaring = 30841;
public const uint SpellDeadlySwathe = 30817;
public const uint SpellPoisonThrust = 30822;
public const uint SpellUndyingLove = 30951;
public const uint SpellResVisual = 24171;
public const uint NpcRomulo = 17533;
public const int RomuloX = -10900;
public const int RomuloY = -1758;
}
public enum RAJPhase
{
Julianne = 0,
Romulo = 1,
Both = 2,
}
public class julianne_romuloAI : ScriptedAI
{
public julianne_romuloAI(Creature creature) : base(creature) { }
public override void JustReachedHome()
{
me.DespawnOrUnsummon();
}
public override void MoveInLineOfSight(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.MoveInLineOfSight(who);
}
public void PretendToDie()
{
me.InterruptNonMeleeSpells(true);
me.RemoveAllAuras();
me.SetHealth(0);
me.AddUnitFlag(UnitFlags.NotSelectable);
me.GetMotionMaster().MovementExpired(false);
me.GetMotionMaster().MoveIdle();
me.SetStandState(UnitStandStateType.Dead);
}
public void Resurrect(Creature target)
{
target.RemoveUnitFlag(UnitFlags.NotSelectable);
target.SetFullHealth();
target.SetStandState(UnitStandStateType.Stand);
target.CastSpell(target, JulianneRomulo.SpellResVisual, true);
if (target.GetVictim())
{
target.GetMotionMaster().MoveChase(target.GetVictim());
target.GetAI().AttackStart(target.GetVictim());
}
else
target.GetMotionMaster().Initialize();
}
public InstanceScript instance;
public ObjectGuid JulianneGUID;
public ObjectGuid RomuloGUID;
public uint EntryYellTimer;
public uint AggroYellTimer;
public RAJPhase Phase;
public uint ResurrectSelfTimer;
public uint ResurrectTimer;
public bool JulianneDead;
public bool RomuloDead;
public bool IsFakingDeath;
}
[Script]
public class boss_julianne : julianne_romuloAI
{
public boss_julianne(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
EntryYellTimer = 1000;
AggroYellTimer = 10000;
IsFakingDeath = false;
}
public override void Reset()
{
RomuloGUID.Clear();
Phase = RAJPhase.Julianne;
BlindingPassionTimer = 30000;
DevotionTimer = 15000;
EternalAffectionTimer = 25000;
PowerfulAttractionTimer = 5000;
SummonRomuloTimer = 10000;
DrinkPoisonTimer = 0;
ResurrectSelfTimer = 0;
if (IsFakingDeath)
{
Resurrect(me);
IsFakingDeath = false;
}
SummonedRomulo = false;
RomuloDead = false;
}
public override void EnterCombat(Unit who) { }
public override void AttackStart(Unit who)
{
if (me.HasUnitFlag(UnitFlags.NonAttackable))
return;
base.AttackStart(who);
}
public override void SpellHit(Unit caster, SpellInfo Spell)
{
if (Spell.Id == JulianneRomulo.SpellDrinkPoison)
{
Talk(JulianneRomulo.SayJulianneDeath01);
DrinkPoisonTimer = 2500;
}
}
public override void DamageTaken(Unit done_by, ref uint damage)
{
if (damage < me.GetHealth())
return;
//anything below only used if incoming damage will kill
if (Phase == RAJPhase.Julianne)
{
damage = 0;
//this means already drinking, so return
if (IsFakingDeath)
return;
me.InterruptNonMeleeSpells(true);
DoCast(me, JulianneRomulo.SpellDrinkPoison);
IsFakingDeath = true;
//IS THIS USEFULL? Creature Julianne = (Global.ObjAccessor.GetCreature(me, JulianneGUID));
return;
}
if (Phase == RAJPhase.Romulo)
{
Log.outError(LogFilter.Scripts, "boss_julianneAI: cannot take damage in PHASE_ROMULO, why was i here?");
damage = 0;
return;
}
if (Phase == RAJPhase.Both)
{
Creature Romulo;
//if this is true then we have to kill romulo too
if (RomuloDead)
{
Romulo = ObjectAccessor.GetCreature(me, RomuloGUID);
if (Romulo)
{
Romulo.RemoveUnitFlag(UnitFlags.NotSelectable);
Romulo.GetMotionMaster().Clear();
Romulo.SetDeathState(DeathState.JustDied);
Romulo.CombatStop(true);
Romulo.DeleteThreatList();
Romulo.SetDynamicFlags(UnitDynFlags.Lootable);
}
return;
}
//if not already returned, then romulo is alive and we can pretend die
Romulo = ObjectAccessor.GetCreature(me, RomuloGUID);
if (Romulo)
{
PretendToDie();
IsFakingDeath = true;
((julianne_romuloAI)Romulo.GetAI()).ResurrectTimer = 10000;
((julianne_romuloAI)Romulo.GetAI()).JulianneDead = true;
damage = 0;
return;
}
}
Log.outError(LogFilter.Scripts, "boss_julianneAI: DamageTaken reach end of code, that should not happen.");
}
public override void JustDied(Unit killer)
{
Talk(JulianneRomulo.SayJulianneDeath02);
instance.SetBossState(DataTypes.OperaPerformance, EncounterState.Done);
}
public override void KilledUnit(Unit victim)
{
Talk(JulianneRomulo.SayJulianneSlay);
}
public override void UpdateAI(uint diff)
{
if (EntryYellTimer != 0)
{
if (EntryYellTimer <= diff)
{
Talk(JulianneRomulo.SayJulianneEnter);
EntryYellTimer = 0;
}
else EntryYellTimer -= diff;
}
if (AggroYellTimer != 0)
{
if (AggroYellTimer <= diff)
{
Talk(JulianneRomulo.SayJulianneAggro);
me.RemoveUnitFlag(UnitFlags.NonAttackable);
me.SetFaction(16);
AggroYellTimer = 0;
}
else AggroYellTimer -= diff;
}
if (DrinkPoisonTimer != 0)
{
//will do this 2secs after spell hit. this is time to display visual as expected
if (DrinkPoisonTimer <= diff)
{
PretendToDie();
Phase = RAJPhase.Romulo;
SummonRomuloTimer = 10000;
DrinkPoisonTimer = 0;
}
else DrinkPoisonTimer -= diff;
}
if (Phase == RAJPhase.Romulo && !SummonedRomulo)
{
if (SummonRomuloTimer <= diff)
{
Creature pRomulo = me.SummonCreature(JulianneRomulo.NpcRomulo, JulianneRomulo.RomuloX, JulianneRomulo.RomuloY, me.GetPositionZ(), 0, TempSummonType.TimedOrDeadDespawn, Time.Hour * 2 * Time.InMilliseconds);
if (pRomulo)
{
RomuloGUID = pRomulo.GetGUID();
((julianne_romuloAI)pRomulo.GetAI()).JulianneGUID = me.GetGUID();
((julianne_romuloAI)pRomulo.GetAI()).Phase = RAJPhase.Romulo;
DoZoneInCombat(pRomulo);
pRomulo.SetFaction(16);
}
SummonedRomulo = true;
}
else SummonRomuloTimer -= diff;
}
if (ResurrectSelfTimer != 0)
{
if (ResurrectSelfTimer <= diff)
{
Resurrect(me);
Phase = RAJPhase.Both;
IsFakingDeath = false;
if (me.GetVictim())
AttackStart(me.GetVictim());
ResurrectSelfTimer = 0;
ResurrectTimer = 1000;
}
else ResurrectSelfTimer -= diff;
}
if (!UpdateVictim() || IsFakingDeath)
return;
if (RomuloDead)
{
if (ResurrectTimer <= diff)
{
Creature Romulo = ObjectAccessor.GetCreature(me, RomuloGUID);
if (Romulo && ((julianne_romuloAI)Romulo.GetAI()).IsFakingDeath)
{
Talk(JulianneRomulo.SayJulianneResurrect);
Resurrect(Romulo);
((julianne_romuloAI)Romulo.GetAI()).IsFakingDeath = false;
RomuloDead = false;
ResurrectTimer = 10000;
}
}
else ResurrectTimer -= diff;
}
if (BlindingPassionTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
DoCast(target, JulianneRomulo.SpellBlindingPassion);
BlindingPassionTimer = RandomHelper.URand(30000, 45000);
}
else BlindingPassionTimer -= diff;
if (DevotionTimer <= diff)
{
DoCast(me, JulianneRomulo.SpellDevotion);
DevotionTimer = RandomHelper.URand(15000, 45000);
}
else DevotionTimer -= diff;
if (PowerfulAttractionTimer <= diff)
{
DoCast(SelectTarget(SelectAggroTarget.Random, 0), JulianneRomulo.SpellPowerfulAttraction);
PowerfulAttractionTimer = RandomHelper.URand(5000, 30000);
}
else PowerfulAttractionTimer -= diff;
if (EternalAffectionTimer <= diff)
{
if (RandomHelper.URand(0, 1) != 0 && SummonedRomulo)
{
Creature Romulo = ObjectAccessor.GetCreature(me, RomuloGUID);
if (Romulo && Romulo.IsAlive() && !RomuloDead)
DoCast(Romulo, JulianneRomulo.SpellEternalAffection);
}
else DoCast(me, JulianneRomulo.SpellEternalAffection);
EternalAffectionTimer = RandomHelper.URand(45000, 60000);
}
else EternalAffectionTimer -= diff;
DoMeleeAttackIfReady();
}
uint BlindingPassionTimer;
uint DevotionTimer;
uint EternalAffectionTimer;
uint PowerfulAttractionTimer;
uint SummonRomuloTimer;
uint DrinkPoisonTimer;
bool SummonedRomulo;
}
[Script]
public class boss_romulo : julianne_romuloAI
{
public boss_romulo(Creature creature) : base(creature)
{
instance = creature.GetInstanceScript();
EntryYellTimer = 8000;
AggroYellTimer = 15000;
}
public override void Reset()
{
JulianneGUID.Clear();
Phase = RAJPhase.Romulo;
BackwardLungeTimer = 15000;
DaringTimer = 20000;
DeadlySwatheTimer = 25000;
PoisonThrustTimer = 10000;
ResurrectTimer = 10000;
IsFakingDeath = false;
JulianneDead = false;
}
public override void DamageTaken(Unit attacker, ref uint damage)
{
if (damage < me.GetHealth())
return;
//anything below only used if incoming damage will kill
if (Phase == RAJPhase.Romulo)
{
Talk(JulianneRomulo.SayRomuloDeath);
PretendToDie();
IsFakingDeath = true;
Phase = RAJPhase.Both;
Creature Julianne = ObjectAccessor.GetCreature(me, JulianneGUID);
if (Julianne)
{
((julianne_romuloAI)Julianne.GetAI()).RomuloDead = true;
((julianne_romuloAI)Julianne.GetAI()).ResurrectSelfTimer = 10000;
}
damage = 0;
return;
}
if (Phase == RAJPhase.Both)
{
Creature Julianne;
if (JulianneDead)
{
Julianne = ObjectAccessor.GetCreature(me, JulianneGUID);
if (Julianne)
{
Julianne.RemoveUnitFlag(UnitFlags.NotSelectable);
Julianne.GetMotionMaster().Clear();
Julianne.SetDeathState(DeathState.JustDied);
Julianne.CombatStop(true);
Julianne.DeleteThreatList();
Julianne.SetDynamicFlags(UnitDynFlags.Lootable);
}
return;
}
Julianne = ObjectAccessor.GetCreature(me, JulianneGUID);
if (Julianne)
{
PretendToDie();
IsFakingDeath = true;
((julianne_romuloAI)Julianne.GetAI()).ResurrectTimer = 10000;
((julianne_romuloAI)Julianne.GetAI()).RomuloDead = true;
damage = 0;
return;
}
}
Log.outError(LogFilter.Scripts, "boss_romuloAI: DamageTaken reach end of code, that should not happen.");
}
public override void EnterCombat(Unit who)
{
Talk(JulianneRomulo.SayRomuloAggro);
if (!JulianneGUID.IsEmpty())
{
Creature Julianne = (ObjectAccessor.GetCreature(me, JulianneGUID));
if (Julianne && Julianne.GetVictim())
{
me.AddThreat(Julianne.GetVictim(), 1.0f);
AttackStart(Julianne.GetVictim());
}
}
}
public override void JustDied(Unit killer)
{
Talk(JulianneRomulo.SayRomuloDeath);
instance.SetBossState(DataTypes.OperaPerformance, EncounterState.Done);
}
public override void KilledUnit(Unit victim)
{
Talk(JulianneRomulo.SayRomuloSlay);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || IsFakingDeath)
return;
if (JulianneDead)
{
if (ResurrectTimer <= diff)
{
Creature Julianne = (ObjectAccessor.GetCreature(me, JulianneGUID));
if (Julianne && ((julianne_romuloAI)Julianne.GetAI()).IsFakingDeath)
{
Talk(JulianneRomulo.SayRomuloResurrect);
Resurrect(Julianne);
((julianne_romuloAI)Julianne.GetAI()).IsFakingDeath = false;
JulianneDead = false;
ResurrectTimer = 10000;
}
}
else ResurrectTimer -= diff;
}
if (BackwardLungeTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 1, 100, true);
if (target && !me.HasInArc(MathFunctions.PI, target))
{
DoCast(target, JulianneRomulo.SpellBackwardLunge);
BackwardLungeTimer = RandomHelper.URand(15000, 30000);
}
}
else BackwardLungeTimer -= diff;
if (DaringTimer <= diff)
{
DoCast(me, JulianneRomulo.SpellDaring);
DaringTimer = RandomHelper.URand(20000, 40000);
}
else DaringTimer -= diff;
if (DeadlySwatheTimer <= diff)
{
Unit target = SelectTarget(SelectAggroTarget.Random, 0, 100, true);
if (target)
DoCast(target, JulianneRomulo.SpellDeadlySwathe);
DeadlySwatheTimer = RandomHelper.URand(15000, 25000);
}
else DeadlySwatheTimer -= diff;
if (PoisonThrustTimer <= diff)
{
DoCastVictim(JulianneRomulo.SpellPoisonThrust);
PoisonThrustTimer = RandomHelper.URand(10000, 20000);
}
else PoisonThrustTimer -= diff;
DoMeleeAttackIfReady();
}
uint BackwardLungeTimer;
uint DaringTimer;
uint DeadlySwatheTimer;
uint PoisonThrustTimer;
}
#endregion
[Script]
class npc_barnes : CreatureScript
{
public npc_barnes() : base("npc_barnes") { }
class npc_barnesAI : NpcEscortAI
{
public npc_barnesAI(Creature creature) : base(creature)
{
Initialize();
instance = creature.GetInstanceScript();
}
void Initialize()
{
m_uiSpotlightGUID.Clear();
TalkCount = 0;
TalkTimer = 2000;
WipeTimer = 5000;
PerformanceReady = false;
}
public override void Reset()
{
Initialize();
m_uiEventId = instance.GetData(DataTypes.OperaPerformance);
}
public void StartEvent()
{
instance.SetBossState(DataTypes.OperaPerformance, EncounterState.InProgress);
//resets count for this event, in case earlier failed
if (m_uiEventId == OperaEvents.Oz)
instance.SetData(DataTypes.OperaOzDeathcount, (uint)EncounterState.InProgress);
Start(false, false);
}
public override void EnterCombat(Unit who) { }
public override void WaypointReached(uint waypointId)
{
switch (waypointId)
{
case 0:
DoCast(me, karazhanConst.SpellTuxedo, false);
instance.DoUseDoorOrButton(instance.GetGuidData(DataTypes.GoStagedoorleft));
break;
case 4:
TalkCount = 0;
SetEscortPaused(true);
Creature spotlight = me.SummonCreature(karazhanConst.NpcSpotlight, me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), 0.0f, TempSummonType.TimedOrDeadDespawn, 60000);
if (spotlight)
{
spotlight.AddUnitFlag(UnitFlags.NotSelectable);
spotlight.CastSpell(spotlight, karazhanConst.SpellSpotlight, false);
m_uiSpotlightGUID = spotlight.GetGUID();
}
break;
case 8:
instance.DoUseDoorOrButton(instance.GetGuidData(DataTypes.GoStagedoorleft));
PerformanceReady = true;
break;
case 9:
PrepareEncounter();
instance.DoUseDoorOrButton(instance.GetGuidData(DataTypes.GoCurtains));
break;
}
}
void Talk(uint count)
{
int text = 0;
switch (m_uiEventId)
{
case OperaEvents.Oz:
if (karazhanConst.OzDialogue[count].TextId != 0)
text = karazhanConst.OzDialogue[count].TextId;
if (karazhanConst.OzDialogue[count].Timer != 0)
TalkTimer = karazhanConst.OzDialogue[count].Timer;
break;
case OperaEvents.Hood:
if (karazhanConst.HoodDialogue[count].TextId != 0)
text = karazhanConst.HoodDialogue[count].TextId;
if (karazhanConst.HoodDialogue[count].Timer != 0)
TalkTimer = karazhanConst.HoodDialogue[count].Timer;
break;
case OperaEvents.RAJ:
if (karazhanConst.RAJDialogue[count].TextId != 0)
text = karazhanConst.RAJDialogue[count].TextId;
if (karazhanConst.RAJDialogue[count].Timer != 0)
TalkTimer = karazhanConst.RAJDialogue[count].Timer;
break;
}
if (text != 0)
base.Talk((uint)text);
}
void PrepareEncounter()
{
int index = 0;
int count = 0;
switch (m_uiEventId)
{
case OperaEvents.Oz:
index = 0;
count = 4;
break;
case OperaEvents.Hood:
index = 4;
count = index + 1;
break;
case OperaEvents.RAJ:
index = 5;
count = index + 1;
break;
}
for (; index < count; ++index)
{
uint entry = (uint)karazhanConst.Spawns[index][0];
float PosX = karazhanConst.Spawns[index][1];
Creature creature = me.SummonCreature(entry, PosX, karazhanConst.SPAWN_Y, karazhanConst.SPAWN_Z, karazhanConst.SPAWN_O, TempSummonType.TimedOrDeadDespawn, Time.Hour * 2 * Time.InMilliseconds);
if (creature)
creature.AddUnitFlag(UnitFlags.NonAttackable);
}
RaidWiped = false;
}
public override void UpdateAI(uint diff)
{
base.UpdateAI(diff);
if (HasEscortState(EscortState.Paused))
{
if (TalkTimer <= diff)
{
if (TalkCount > 3)
{
Creature pSpotlight = ObjectAccessor.GetCreature(me, m_uiSpotlightGUID);
if (pSpotlight)
pSpotlight.DespawnOrUnsummon();
SetEscortPaused(false);
return;
}
Talk(TalkCount);
++TalkCount;
}
else
TalkTimer -= diff;
}
if (PerformanceReady)
{
if (!RaidWiped)
{
if (WipeTimer <= diff)
{
var PlayerList = me.GetMap().GetPlayers();
if (PlayerList.Empty())
return;
RaidWiped = true;
foreach (var player in PlayerList)
{
if (player.IsAlive() && !player.IsGameMaster())
{
RaidWiped = false;
break;
}
}
if (RaidWiped)
{
RaidWiped = true;
EnterEvadeMode();
return;
}
WipeTimer = 15000;
}
else
WipeTimer -= diff;
}
}
}
InstanceScript instance;
ObjectGuid m_uiSpotlightGUID;
uint TalkCount;
uint TalkTimer;
uint WipeTimer;
public uint m_uiEventId;
bool PerformanceReady;
public bool RaidWiped;
}
public override bool OnGossipSelect(Player player, Creature creature, uint sender, uint action)
{
player.PlayerTalkClass.ClearMenus();
npc_barnesAI pBarnesAI = (npc_barnesAI)creature.GetAI();
switch (action)
{
case eTradeskill.GossipActionInfoDef + 1:
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, karazhanConst.OZ_GOSSIP2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 2);
player.SEND_GOSSIP_MENU(8971, creature.GetGUID());
break;
case eTradeskill.GossipActionInfoDef + 2:
player.CLOSE_GOSSIP_MENU();
pBarnesAI.StartEvent();
break;
case eTradeskill.GossipActionInfoDef + 3:
player.CLOSE_GOSSIP_MENU();
pBarnesAI.m_uiEventId = OperaEvents.Oz;
Log.outInfo(LogFilter.Scripts, "player (GUID {0}) manually set Opera event to EVENT_OZ", player.GetGUID());
break;
case eTradeskill.GossipActionInfoDef + 4:
player.CLOSE_GOSSIP_MENU();
pBarnesAI.m_uiEventId = OperaEvents.Hood;
Log.outInfo(LogFilter.Scripts, "player (GUID {0}) manually set Opera event to EVENT_HOOD", player.GetGUID());
break;
case eTradeskill.GossipActionInfoDef + 5:
player.CLOSE_GOSSIP_MENU();
pBarnesAI.m_uiEventId = OperaEvents.RAJ;
Log.outInfo(LogFilter.Scripts, "player (GUID {0}) manually set Opera event to EVENT_RAJ", player.GetGUID());
break;
}
return true;
}
public override bool OnGossipHello(Player player, Creature creature)
{
InstanceScript instance = creature.GetInstanceScript();
if (instance != null)
{
// Check for death of Moroes and if opera event is not done already
if (instance.GetBossState(DataTypes.Moroes) == EncounterState.Done && instance.GetBossState(DataTypes.OperaPerformance) != EncounterState.Done)
{
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Chat, karazhanConst.OZ_GOSSIP1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 1);
if (player.IsGameMaster())
{
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Dot, karazhanConst.OZ_GM_GOSSIP1, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 3);
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Dot, karazhanConst.OZ_GM_GOSSIP2, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 4);
player.ADD_GOSSIP_ITEM(GossipOptionIcon.Dot, karazhanConst.OZ_GM_GOSSIP3, eTradeskill.GossipSenderMain, eTradeskill.GossipActionInfoDef + 5);
}
npc_barnesAI pBarnesAI = (npc_barnesAI)creature.GetAI();
if (pBarnesAI != null)
{
if (!pBarnesAI.RaidWiped)
player.SEND_GOSSIP_MENU(8970, creature.GetGUID());
else
player.SEND_GOSSIP_MENU(8975, creature.GetGUID());
return true;
}
}
}
player.SEND_GOSSIP_MENU(8978, creature.GetGUID());
return true;
}
public override CreatureAI GetAI(Creature creature)
{
return GetInstanceAI<npc_barnesAI>(creature);
}
}
}