Start adding missing scripts Part4
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair.Broodlord
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Cleave = 26350;
|
||||
public const uint Blastwave = 23331;
|
||||
public const uint Mortalstrike = 24573;
|
||||
public const uint Knockback = 25778;
|
||||
public const uint SuppressionAura = 22247; // Suppression Device Spell
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SayLeash = 1;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
// Suppression Device Events
|
||||
public const uint SuppressionCast = 1;
|
||||
public const uint SuppressionReset = 2;
|
||||
}
|
||||
|
||||
struct ActionIds
|
||||
{
|
||||
public const int Deactivate = 0;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_broodlord : BossAI
|
||||
{
|
||||
public boss_broodlord(Creature creature) : base(creature, DataTypes.BroodlordLashlayer) { }
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Cleave);
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Blastwave);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Mortalstrike);
|
||||
task.Repeat(TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Knockback);
|
||||
if (GetThreat(me.GetVictim()) != 0)
|
||||
ModifyThreatByPercent(me.GetVictim(), -50);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
|
||||
{
|
||||
if (me.GetDistance(me.GetHomePosition()) > 150.0f)
|
||||
{
|
||||
Talk(TextIds.SayLeash);
|
||||
EnterEvadeMode(EvadeReason.Boundary);
|
||||
}
|
||||
task.Repeat(TimeSpan.FromSeconds(1));
|
||||
});
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
List<GameObject> _goList = me.GetGameObjectListWithEntryInGrid(BWLGameObjectIds.SuppressionDevice, 200.0f);
|
||||
foreach (var go in _goList)
|
||||
go.GetAI().DoAction(ActionIds.Deactivate);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_suppression_device : GameObjectAI
|
||||
{
|
||||
InstanceScript _instance;
|
||||
bool _active;
|
||||
|
||||
public go_suppression_device(GameObject go) : base(go)
|
||||
{
|
||||
_instance = go.GetInstanceScript();
|
||||
_active = true;
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
if (_instance.GetBossState(DataTypes.BroodlordLashlayer) == EncounterState.Done)
|
||||
{
|
||||
Deactivate();
|
||||
return;
|
||||
}
|
||||
|
||||
_events.ScheduleEvent(EventIds.SuppressionCast, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.SuppressionCast:
|
||||
if (me.GetGoState() == GameObjectState.Ready)
|
||||
{
|
||||
me.CastSpell(null, SpellIds.SuppressionAura, true);
|
||||
me.SendCustomAnim(0);
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.SuppressionCast, TimeSpan.FromSeconds(5));
|
||||
break;
|
||||
case EventIds.SuppressionReset:
|
||||
Activate();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnLootStateChanged(uint state, Unit unit)
|
||||
{
|
||||
switch ((LootState)state)
|
||||
{
|
||||
case LootState.Activated:
|
||||
Deactivate();
|
||||
_events.CancelEvent(EventIds.SuppressionCast);
|
||||
_events.ScheduleEvent(EventIds.SuppressionReset, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(120));
|
||||
break;
|
||||
case LootState.JustDeactivated: // This case prevents the Gameobject despawn by Disarm Trap
|
||||
me.SetLootState(LootState.Ready);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == ActionIds.Deactivate)
|
||||
{
|
||||
Deactivate();
|
||||
_events.CancelEvent(EventIds.SuppressionReset);
|
||||
}
|
||||
}
|
||||
|
||||
void Activate()
|
||||
{
|
||||
if (_active)
|
||||
return;
|
||||
_active = true;
|
||||
if (me.GetGoState() == GameObjectState.Active)
|
||||
me.SetGoState(GameObjectState.Ready);
|
||||
me.SetLootState(LootState.Ready);
|
||||
me.RemoveFlag(GameObjectFlags.NotSelectable);
|
||||
_events.ScheduleEvent(EventIds.SuppressionCast, TimeSpan.FromSeconds(0));
|
||||
}
|
||||
|
||||
void Deactivate()
|
||||
{
|
||||
if (!_active)
|
||||
return;
|
||||
_active = false;
|
||||
me.SetGoState(GameObjectState.Active);
|
||||
me.SetFlag(GameObjectFlags.NotSelectable);
|
||||
_events.CancelEvent(EventIds.SuppressionCast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.BlackwingLair
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// These spells are actually called elemental shield
|
||||
// What they do is decrease all damage by 75% then they increase
|
||||
// One school of damage by 1100%
|
||||
public const uint FireVulnerability = 22277;
|
||||
public const uint FrostVulnerability = 22278;
|
||||
public const uint ShadowVulnerability = 22279;
|
||||
public const uint NatureVulnerability = 22280;
|
||||
public const uint ArcaneVulnerability = 22281;
|
||||
// Other spells
|
||||
public const uint Incinerate = 23308; //Incinerate 23308; 23309
|
||||
public const uint Timelapse = 23310; //Time lapse 23310; 23311(old threat mod that was removed in 2.01)
|
||||
public const uint Corrosiveacid = 23313; //Corrosive Acid 23313; 23314
|
||||
public const uint Igniteflesh = 23315; //Ignite Flesh 23315; 23316
|
||||
public const uint Frostburn = 23187; //Frost burn 23187; 23189
|
||||
// Brood Affliction 23173 - Scripted Spell that cycles through all targets within 100 yards and has a chance to cast one of the afflictions on them
|
||||
// Since Scripted spells arn't coded I'll just write a function that does the same thing
|
||||
public const uint BroodafBlue = 23153; //Blue affliction 23153
|
||||
public const uint BroodafBlack = 23154; //Black affliction 23154
|
||||
public const uint BroodafRed = 23155; //Red affliction 23155 (23168 on death)
|
||||
public const uint BroodafBronze = 23170; //Bronze Affliction 23170
|
||||
public const uint BroodafGreen = 23169; //Brood Affliction Green 23169
|
||||
public const uint ChromaticMut1 = 23174; //Spell cast on player if they get all 5 debuffs
|
||||
public const uint Frenzy = 28371; //The frenzy spell may be wrong
|
||||
public const uint Enrage = 28747;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteFrenzy = 0;
|
||||
public const uint EmoteShimmer = 1;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_chromaggus : BossAI
|
||||
{
|
||||
uint Breath1_Spell;
|
||||
uint Breath2_Spell;
|
||||
uint CurrentVurln_Spell;
|
||||
bool Enraged;
|
||||
|
||||
public boss_chromaggus(Creature creature) : base(creature, DataTypes.Chromaggus)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
Breath1_Spell = 0;
|
||||
Breath2_Spell = 0;
|
||||
|
||||
// Select the 2 breaths that we are going to use until despawned
|
||||
// 5 possiblities for the first breath, 4 for the second, 20 total possiblites
|
||||
// This way we don't end up casting 2 of the same breath
|
||||
// Tl Tl would be stupid
|
||||
switch (RandomHelper.URand(0, 19))
|
||||
{
|
||||
// B1 - Incin
|
||||
case 0:
|
||||
Breath1_Spell = SpellIds.Incinerate;
|
||||
Breath2_Spell = SpellIds.Timelapse;
|
||||
break;
|
||||
case 1:
|
||||
Breath1_Spell = SpellIds.Incinerate;
|
||||
Breath2_Spell = SpellIds.Corrosiveacid;
|
||||
break;
|
||||
case 2:
|
||||
Breath1_Spell = SpellIds.Incinerate;
|
||||
Breath2_Spell = SpellIds.Igniteflesh;
|
||||
break;
|
||||
case 3:
|
||||
Breath1_Spell = SpellIds.Incinerate;
|
||||
Breath2_Spell = SpellIds.Frostburn;
|
||||
break;
|
||||
|
||||
// B1 - Tl
|
||||
case 4:
|
||||
Breath1_Spell = SpellIds.Timelapse;
|
||||
Breath2_Spell = SpellIds.Incinerate;
|
||||
break;
|
||||
case 5:
|
||||
Breath1_Spell = SpellIds.Timelapse;
|
||||
Breath2_Spell = SpellIds.Corrosiveacid;
|
||||
break;
|
||||
case 6:
|
||||
Breath1_Spell = SpellIds.Timelapse;
|
||||
Breath2_Spell = SpellIds.Igniteflesh;
|
||||
break;
|
||||
case 7:
|
||||
Breath1_Spell = SpellIds.Timelapse;
|
||||
Breath2_Spell = SpellIds.Frostburn;
|
||||
break;
|
||||
|
||||
//B1 - Acid
|
||||
case 8:
|
||||
Breath1_Spell = SpellIds.Corrosiveacid;
|
||||
Breath2_Spell = SpellIds.Incinerate;
|
||||
break;
|
||||
case 9:
|
||||
Breath1_Spell = SpellIds.Corrosiveacid;
|
||||
Breath2_Spell = SpellIds.Timelapse;
|
||||
break;
|
||||
case 10:
|
||||
Breath1_Spell = SpellIds.Corrosiveacid;
|
||||
Breath2_Spell = SpellIds.Igniteflesh;
|
||||
break;
|
||||
case 11:
|
||||
Breath1_Spell = SpellIds.Corrosiveacid;
|
||||
Breath2_Spell = SpellIds.Frostburn;
|
||||
break;
|
||||
|
||||
//B1 - Ignite
|
||||
case 12:
|
||||
Breath1_Spell = SpellIds.Igniteflesh;
|
||||
Breath2_Spell = SpellIds.Incinerate;
|
||||
break;
|
||||
case 13:
|
||||
Breath1_Spell = SpellIds.Igniteflesh;
|
||||
Breath2_Spell = SpellIds.Corrosiveacid;
|
||||
break;
|
||||
case 14:
|
||||
Breath1_Spell = SpellIds.Igniteflesh;
|
||||
Breath2_Spell = SpellIds.Timelapse;
|
||||
break;
|
||||
case 15:
|
||||
Breath1_Spell = SpellIds.Igniteflesh;
|
||||
Breath2_Spell = SpellIds.Frostburn;
|
||||
break;
|
||||
|
||||
//B1 - Frost
|
||||
case 16:
|
||||
Breath1_Spell = SpellIds.Frostburn;
|
||||
Breath2_Spell = SpellIds.Incinerate;
|
||||
break;
|
||||
case 17:
|
||||
Breath1_Spell = SpellIds.Frostburn;
|
||||
Breath2_Spell = SpellIds.Timelapse;
|
||||
break;
|
||||
case 18:
|
||||
Breath1_Spell = SpellIds.Frostburn;
|
||||
Breath2_Spell = SpellIds.Corrosiveacid;
|
||||
break;
|
||||
case 19:
|
||||
Breath1_Spell = SpellIds.Frostburn;
|
||||
Breath2_Spell = SpellIds.Igniteflesh;
|
||||
break;
|
||||
}
|
||||
|
||||
EnterEvadeMode();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
CurrentVurln_Spell = 0; // We use this to store our last vulnerabilty spell so we can remove it later
|
||||
Enraged = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(0), task =>
|
||||
{
|
||||
// Remove old vulnerabilty spell
|
||||
if (CurrentVurln_Spell != 0)
|
||||
me.RemoveAurasDueToSpell(CurrentVurln_Spell);
|
||||
|
||||
// Cast new random vulnerabilty on self
|
||||
uint spell = RandomHelper.RAND(SpellIds.FireVulnerability, SpellIds.FrostVulnerability, SpellIds.ShadowVulnerability, SpellIds.NatureVulnerability, SpellIds.ArcaneVulnerability);
|
||||
DoCast(me, spell);
|
||||
CurrentVurln_Spell = spell;
|
||||
Talk(TextIds.EmoteShimmer);
|
||||
task.Repeat(TimeSpan.FromSeconds(45));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(Breath1_Spell);
|
||||
task.Repeat(TimeSpan.FromSeconds(60));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(60), task =>
|
||||
{
|
||||
DoCastVictim(Breath2_Spell);
|
||||
task.Repeat(TimeSpan.FromSeconds(60));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
var players = me.GetMap().GetPlayers();
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
DoCast(player, RandomHelper.RAND(SpellIds.BroodafBlue, SpellIds.BroodafBlack, SpellIds.BroodafRed, SpellIds.BroodafBronze, SpellIds.BroodafGreen), new CastSpellExtraArgs(true));
|
||||
|
||||
if (player.HasAura(SpellIds.BroodafBlue) &&
|
||||
player.HasAura(SpellIds.BroodafBlack) &&
|
||||
player.HasAura(SpellIds.BroodafRed) &&
|
||||
player.HasAura(SpellIds.BroodafBronze) &&
|
||||
player.HasAura(SpellIds.BroodafGreen))
|
||||
{
|
||||
DoCast(player, SpellIds.ChromaticMut1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(10));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.Frenzy);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
// Enrage if not already enraged and below 20%
|
||||
if (!Enraged && HealthBelowPct(20))
|
||||
{
|
||||
DoCast(me, SpellIds.Enrage);
|
||||
Enraged = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_chromaggus_lever : GameObjectAI
|
||||
{
|
||||
InstanceScript _instance;
|
||||
|
||||
public go_chromaggus_lever(GameObject go) : base(go)
|
||||
{
|
||||
_instance = go.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override bool OnGossipHello(Player player)
|
||||
{
|
||||
if (_instance.GetBossState(DataTypes.Chromaggus) != EncounterState.Done && _instance.GetBossState(DataTypes.Chromaggus) != EncounterState.InProgress)
|
||||
{
|
||||
_instance.SetBossState(DataTypes.Chromaggus, EncounterState.InProgress);
|
||||
|
||||
Creature creature = _instance.GetCreature(DataTypes.Chromaggus);
|
||||
if (creature)
|
||||
creature.GetAI().JustEngagedWith(player);
|
||||
|
||||
GameObject go = _instance.GetGameObject(DataTypes.GoChromaggusDoor);
|
||||
if (go)
|
||||
_instance.HandleGameObject(ObjectGuid.Empty, true, go);
|
||||
}
|
||||
|
||||
me.SetFlag(GameObjectFlags.NotSelectable | GameObjectFlags.InUse);
|
||||
me.SetGoState(GameObjectState.Active);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair.Ebonroc
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Shadowflame = 22539;
|
||||
public const uint Wingbuffet = 23339;
|
||||
public const uint Shadowofebonroc = 23340;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_ebonroc : BossAI
|
||||
{
|
||||
public boss_ebonroc(Creature creature) : base(creature, DataTypes.Ebonroc) { }
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shadowflame);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Wingbuffet);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shadowofebonroc);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair.Firemaw
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Shadowflame = 22539;
|
||||
public const uint Wingbuffet = 23339;
|
||||
public const uint Flamebuffet = 23341;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_firemaw : BossAI
|
||||
{
|
||||
public boss_firemaw(Creature creature) : base(creature, DataTypes.Firemaw) { }
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shadowflame);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Wingbuffet);
|
||||
if (GetThreat(me.GetVictim()) != 0)
|
||||
ModifyThreatByPercent(me.GetVictim(), -75);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Flamebuffet);
|
||||
task.Repeat(TimeSpan.FromSeconds(5));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair.Flamegor
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Shadowflame = 22539;
|
||||
public const uint Wingbuffet = 23339;
|
||||
public const uint Frenzy = 23342; //This spell periodically triggers fire nova
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteFrenzy = 0;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_flamegor : BossAI
|
||||
{
|
||||
public boss_flamegor(Creature creature) : base(creature, DataTypes.Flamegor) { }
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Shadowflame);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Wingbuffet);
|
||||
if (GetThreat(me.GetVictim()) != 0)
|
||||
ModifyThreatByPercent(me.GetVictim(), -75);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
Talk(TextIds.EmoteFrenzy);
|
||||
DoCast(me, SpellIds.Frenzy);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(10));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
using Game.Maps;
|
||||
using System.Collections.Generic;
|
||||
using Framework.Constants;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair
|
||||
{
|
||||
//uint const EncounterCount = 8;
|
||||
|
||||
|
||||
struct DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
public const uint RazorgoreTheUntamed = 0;
|
||||
public const uint VaelastrazTheCorrupt = 1;
|
||||
public const uint BroodlordLashlayer = 2;
|
||||
public const uint Firemaw = 3;
|
||||
public const uint Ebonroc = 4;
|
||||
public const uint Flamegor = 5;
|
||||
public const uint Chromaggus = 6;
|
||||
public const uint Nefarian = 7;
|
||||
|
||||
// Additional Data
|
||||
public const uint LordVictorNefarius = 8;
|
||||
|
||||
// Doors
|
||||
public const uint GoChromaggusDoor = 9;
|
||||
}
|
||||
|
||||
struct BWLCreatureIds
|
||||
{
|
||||
public const uint Razorgore = 12435;
|
||||
public const uint BlackwingDragon = 12422;
|
||||
public const uint BlackwingTaskmaster = 12458;
|
||||
public const uint BlackwingLegionaire = 12416;
|
||||
public const uint BlackwingWarlock = 12459;
|
||||
public const uint Vaelastraz = 13020;
|
||||
public const uint Broodlord = 12017;
|
||||
public const uint Firemaw = 11983;
|
||||
public const uint Ebonroc = 14601;
|
||||
public const uint Flamegor = 11981;
|
||||
public const uint Chromaggus = 14020;
|
||||
public const uint VictorNefarius = 10162;
|
||||
public const uint Nefarian = 11583;
|
||||
}
|
||||
|
||||
struct BWLGameObjectIds
|
||||
{
|
||||
public const uint BlackDragonEgg = 177807;
|
||||
public const uint PortcullisRazorgore = 176965;
|
||||
public const uint PortcullisVaelastrasz = 179364;
|
||||
public const uint PortcullisBroodlord = 179365;
|
||||
public const uint PortcullisThreedragons = 179115;
|
||||
public const uint PortcullisChromaggus = 179117; //Door after you kill him, not the one for his room
|
||||
public const uint ChromaggusLever = 179148;
|
||||
public const uint ChromaggusDoor = 179116;
|
||||
public const uint PortcullisNefarian = 176966;
|
||||
public const uint SuppressionDevice = 179784;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint RazorSpawn = 1;
|
||||
public const uint RazorPhaseTwo = 2;
|
||||
public const uint RespawnNefarius = 3;
|
||||
}
|
||||
|
||||
struct BWLMisc
|
||||
{
|
||||
public const uint EncounterCount = 8;
|
||||
|
||||
// Razorgore Egg Event
|
||||
public const int ActionPhaseTwo = 1;
|
||||
public const uint DataEggEvent = 2;
|
||||
|
||||
public static DoorData[] doorData =
|
||||
{
|
||||
new DoorData(BWLGameObjectIds.PortcullisRazorgore, DataTypes.RazorgoreTheUntamed, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisVaelastrasz, DataTypes.VaelastrazTheCorrupt, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisBroodlord, DataTypes.BroodlordLashlayer, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisThreedragons, DataTypes.Firemaw, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisThreedragons, DataTypes.Ebonroc, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisThreedragons, DataTypes.Flamegor, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisChromaggus, DataTypes.Chromaggus, DoorType.Passage),
|
||||
new DoorData(BWLGameObjectIds.PortcullisNefarian, DataTypes.Nefarian, DoorType.Room),
|
||||
};
|
||||
|
||||
public static ObjectData[] creatureData =
|
||||
{
|
||||
new ObjectData(BWLCreatureIds.Razorgore, DataTypes.RazorgoreTheUntamed),
|
||||
new ObjectData(BWLCreatureIds.Vaelastraz, DataTypes.VaelastrazTheCorrupt),
|
||||
new ObjectData(BWLCreatureIds.Broodlord, DataTypes.BroodlordLashlayer),
|
||||
new ObjectData(BWLCreatureIds.Firemaw, DataTypes.Firemaw),
|
||||
new ObjectData(BWLCreatureIds.Ebonroc, DataTypes.Ebonroc),
|
||||
new ObjectData(BWLCreatureIds.Flamegor, DataTypes.Flamegor),
|
||||
new ObjectData(BWLCreatureIds.Chromaggus, DataTypes.Chromaggus),
|
||||
new ObjectData(BWLCreatureIds.Nefarian, DataTypes.Nefarian),
|
||||
new ObjectData(BWLCreatureIds.VictorNefarius, DataTypes.LordVictorNefarius),
|
||||
};
|
||||
|
||||
public static ObjectData[] gameObjectData =
|
||||
{
|
||||
new ObjectData(BWLGameObjectIds.ChromaggusDoor, DataTypes.GoChromaggusDoor),
|
||||
};
|
||||
|
||||
public static Position[] SummonPosition =
|
||||
{
|
||||
new Position(-7661.207520f, -1043.268188f, 407.199554f, 6.280452f),
|
||||
new Position(-7644.145020f, -1065.628052f, 407.204956f, 0.501492f),
|
||||
new Position(-7624.260742f, -1095.196899f, 407.205017f, 0.544694f),
|
||||
new Position(-7608.501953f, -1116.077271f, 407.199921f, 0.816443f),
|
||||
new Position(-7531.841797f, -1063.765381f, 407.199615f, 2.874187f),
|
||||
new Position(-7547.319336f, -1040.971924f, 407.205078f, 3.789175f),
|
||||
new Position(-7568.547852f, -1013.112488f, 407.204926f, 3.773467f),
|
||||
new Position(-7584.175781f, -989.6691289f, 407.199585f, 4.527447f),
|
||||
};
|
||||
|
||||
public static uint[] Entry = { 12422, 12458, 12416, 12420, 12459 };
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_blackwing_lair : InstanceMapScript
|
||||
{
|
||||
public instance_blackwing_lair() : base(nameof(instance_blackwing_lair), 469) { }
|
||||
|
||||
class instance_blackwing_lair_InstanceMapScript : InstanceScript
|
||||
{
|
||||
// Razorgore
|
||||
byte EggCount;
|
||||
uint EggEvent;
|
||||
List<ObjectGuid> EggList = new();
|
||||
|
||||
public instance_blackwing_lair_InstanceMapScript(InstanceMap map) : base(map)
|
||||
{
|
||||
SetHeaders("BWL");
|
||||
SetBossNumber(BWLMisc.EncounterCount);
|
||||
LoadDoorData(BWLMisc.doorData);
|
||||
LoadObjectData(BWLMisc.creatureData, BWLMisc.gameObjectData);
|
||||
|
||||
// Razorgore
|
||||
EggCount = 0;
|
||||
EggEvent = 0;
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
base.OnCreatureCreate(creature);
|
||||
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case BWLCreatureIds.BlackwingDragon:
|
||||
case BWLCreatureIds.BlackwingTaskmaster:
|
||||
case BWLCreatureIds.BlackwingLegionaire:
|
||||
case BWLCreatureIds.BlackwingWarlock:
|
||||
Creature razor = GetCreature(DataTypes.RazorgoreTheUntamed);
|
||||
if (razor != null)
|
||||
{
|
||||
CreatureAI razorAI = razor.GetAI();
|
||||
if (razorAI != null)
|
||||
razorAI.JustSummoned(creature);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetGameObjectEntry(ulong spawnId, uint entry)
|
||||
{
|
||||
if (entry == BWLGameObjectIds.BlackDragonEgg && GetBossState(DataTypes.Firemaw) == EncounterState.Done)
|
||||
return 0;
|
||||
return entry;
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
base.OnGameObjectCreate(go);
|
||||
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case BWLGameObjectIds.BlackDragonEgg:
|
||||
EggList.Add(go.GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectRemove(GameObject go)
|
||||
{
|
||||
base.OnGameObjectRemove(go);
|
||||
|
||||
if (go.GetEntry() == BWLGameObjectIds.BlackDragonEgg)
|
||||
EggList.Remove(go.GetGUID());
|
||||
}
|
||||
|
||||
public override bool CheckRequiredBosses(uint bossId, Player player = null)
|
||||
{
|
||||
if (_SkipCheckRequiredBosses(player))
|
||||
return true;
|
||||
|
||||
switch (bossId)
|
||||
{
|
||||
case DataTypes.BroodlordLashlayer:
|
||||
if (GetBossState(DataTypes.VaelastrazTheCorrupt) != EncounterState.Done)
|
||||
return false;
|
||||
break;
|
||||
case DataTypes.Firemaw:
|
||||
case DataTypes.Ebonroc:
|
||||
case DataTypes.Flamegor:
|
||||
if (GetBossState(DataTypes.BroodlordLashlayer) != EncounterState.Done)
|
||||
return false;
|
||||
break;
|
||||
case DataTypes.Chromaggus:
|
||||
if (GetBossState(DataTypes.Firemaw) != EncounterState.Done
|
||||
|| GetBossState(DataTypes.Ebonroc) != EncounterState.Done
|
||||
|| GetBossState(DataTypes.Flamegor) != EncounterState.Done)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint type, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DataTypes.RazorgoreTheUntamed:
|
||||
if (state == EncounterState.Done)
|
||||
{
|
||||
foreach (var guid in EggList)
|
||||
{
|
||||
GameObject egg = instance.GetGameObject(guid);
|
||||
if (egg)
|
||||
egg.SetLootState(LootState.JustDeactivated);
|
||||
}
|
||||
}
|
||||
SetData(BWLMisc.DataEggEvent, (uint)EncounterState.NotStarted);
|
||||
break;
|
||||
case DataTypes.Nefarian:
|
||||
switch (state)
|
||||
{
|
||||
case EncounterState.NotStarted:
|
||||
Creature nefarian = GetCreature(DataTypes.Nefarian);
|
||||
if (nefarian)
|
||||
nefarian.DespawnOrUnsummon();
|
||||
break;
|
||||
case EncounterState.Fail:
|
||||
_events.ScheduleEvent(EventIds.RespawnNefarius, TimeSpan.FromMinutes(15));
|
||||
SetBossState(DataTypes.Nefarian, EncounterState.NotStarted);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
if (type == BWLMisc.DataEggEvent)
|
||||
{
|
||||
switch ((EncounterState)data)
|
||||
{
|
||||
case EncounterState.InProgress:
|
||||
_events.ScheduleEvent(EventIds.RazorSpawn, TimeSpan.FromSeconds(45));
|
||||
EggEvent = data;
|
||||
EggCount = 0;
|
||||
break;
|
||||
case EncounterState.NotStarted:
|
||||
_events.CancelEvent(EventIds.RazorSpawn);
|
||||
EggEvent = data;
|
||||
EggCount = 0;
|
||||
break;
|
||||
case EncounterState.Special:
|
||||
if (++EggCount == 15)
|
||||
{
|
||||
Creature razor = GetCreature(DataTypes.RazorgoreTheUntamed);
|
||||
if (razor)
|
||||
{
|
||||
SetData(BWLMisc.DataEggEvent, (uint)EncounterState.Done);
|
||||
razor.RemoveAurasDueToSpell(42013); // MindControl
|
||||
DoRemoveAurasDueToSpellOnPlayers(42013, true, true);
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.RazorPhaseTwo, TimeSpan.FromSeconds(1));
|
||||
_events.CancelEvent(EventIds.RazorSpawn);
|
||||
}
|
||||
if (EggEvent == (uint)EncounterState.NotStarted)
|
||||
SetData(BWLMisc.DataEggEvent, (uint)EncounterState.InProgress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnUnitDeath(Unit unit)
|
||||
{
|
||||
//! Hack, needed because of buggy CreatureAI after charm
|
||||
if (unit.GetEntry() == BWLCreatureIds.Razorgore && GetBossState(DataTypes.RazorgoreTheUntamed) != EncounterState.Done)
|
||||
SetBossState(DataTypes.RazorgoreTheUntamed, EncounterState.Done);
|
||||
}
|
||||
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
if (_events.Empty())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.RazorSpawn:
|
||||
for (uint i = RandomHelper.URand(2, 5); i > 0; --i)
|
||||
{
|
||||
Creature summon = instance.SummonCreature(BWLMisc.Entry[RandomHelper.URand(0, 4)], BWLMisc.SummonPosition[RandomHelper.URand(0, 7)]);
|
||||
if (summon)
|
||||
summon.GetAI().DoZoneInCombat();
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.RazorSpawn, TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(17));
|
||||
break;
|
||||
case EventIds.RazorPhaseTwo:
|
||||
_events.CancelEvent(EventIds.RazorSpawn);
|
||||
Creature razor = GetCreature(DataTypes.RazorgoreTheUntamed);
|
||||
if (razor)
|
||||
razor.GetAI().DoAction(BWLMisc.ActionPhaseTwo);
|
||||
break;
|
||||
case EventIds.RespawnNefarius:
|
||||
Creature nefarius = GetCreature(DataTypes.LordVictorNefarius);
|
||||
if (nefarius)
|
||||
{
|
||||
nefarius.SetActive(true);
|
||||
nefarius.SetFarVisible(true);
|
||||
nefarius.Respawn();
|
||||
nefarius.GetMotionMaster().MoveTargetedHome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_blackwing_lair_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* 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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.BlackwingLair.VictorNefarius
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Victor Nefarius
|
||||
// Ubrs Spells
|
||||
public const uint ChromaticChaos = 16337; // Self Cast hits 10339
|
||||
public const uint VaelastraszzSpawn = 16354; // Self Cast Depawn one sec after
|
||||
// Bwl Spells
|
||||
public const uint Shadowbolt = 22677;
|
||||
public const uint ShadowboltVolley = 22665;
|
||||
public const uint ShadowCommand = 22667;
|
||||
public const uint Fear = 22678;
|
||||
|
||||
public const uint NefariansBarrier = 22663;
|
||||
|
||||
// Nefarian
|
||||
public const uint ShadowflameInitial = 22992;
|
||||
public const uint Shadowflame = 22539;
|
||||
public const uint Bellowingroar = 22686;
|
||||
public const uint Veilofshadow = 7068;
|
||||
public const uint Cleave = 20691;
|
||||
public const uint Taillash = 23364;
|
||||
|
||||
public const uint Mage = 23410; // wild magic
|
||||
public const uint Warrior = 23397; // beserk
|
||||
public const uint Druid = 23398; // cat form
|
||||
public const uint Priest = 23401; // corrupted healing
|
||||
public const uint Paladin = 23418; // syphon blessing
|
||||
public const uint Shaman = 23425; // totems
|
||||
public const uint Warlock = 23427; // infernals
|
||||
public const uint Hunter = 23436; // bow broke
|
||||
public const uint Rogue = 23414; // Paralise
|
||||
public const uint DeathKnight = 49576; // Death Grip
|
||||
|
||||
// 19484
|
||||
// 22664
|
||||
// 22674
|
||||
// 22666
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
// Nefarius
|
||||
// Ubrs
|
||||
public const uint SayChaosSpell = 9;
|
||||
public const uint SaySuccess = 10;
|
||||
public const uint SayFailure = 11;
|
||||
// Bwl
|
||||
public const uint SayGamesbegin1 = 12;
|
||||
public const uint SayGamesbegin2 = 13;
|
||||
// public const uint SayVaelIntro = 14; Not used - when he corrupts Vaelastrasz
|
||||
|
||||
// Nefarian
|
||||
public const uint SayRandom = 0;
|
||||
public const uint SayRaiseSkeletons = 1;
|
||||
public const uint SaySlay = 2;
|
||||
public const uint SayDeath = 3;
|
||||
|
||||
public const uint SayMage = 4;
|
||||
public const uint SayWarrior = 5;
|
||||
public const uint SayDruid = 6;
|
||||
public const uint SayPriest = 7;
|
||||
public const uint SayPaladin = 8;
|
||||
public const uint SayShaman = 9;
|
||||
public const uint SayWarlock = 10;
|
||||
public const uint SayHunter = 11;
|
||||
public const uint SayRogue = 12;
|
||||
public const uint SayDeathKnight = 13;
|
||||
|
||||
public const uint GossipId = 6045;
|
||||
public const uint GossipOptionId = 0;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint BronzeDrakanoid = 14263;
|
||||
public const uint BlueDrakanoid = 14261;
|
||||
public const uint RedDrakanoid = 14264;
|
||||
public const uint GreenDrakanoid = 14262;
|
||||
public const uint BlackDrakanoid = 14265;
|
||||
public const uint ChromaticDrakanoid = 14302;
|
||||
public const uint BoneConstruct = 14605;
|
||||
// Ubrs
|
||||
public const uint Gyth = 10339;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint PortcullisActive = 164726;
|
||||
public const uint PortcullisTobossrooms = 175186;
|
||||
}
|
||||
|
||||
struct MiscConst
|
||||
{
|
||||
public const uint NefariusPath2 = 1379671;
|
||||
public const uint NefariusPath3 = 1379672;
|
||||
|
||||
public static Position[] DrakeSpawnLoc = // drakonid
|
||||
{
|
||||
new Position(-7591.151855f, -1204.051880f, 476.800476f, 3.0f),
|
||||
new Position(-7514.598633f, -1150.448853f, 476.796570f, 3.0f)
|
||||
};
|
||||
|
||||
public static Position[] NefarianLoc =
|
||||
{
|
||||
new Position(-7449.763672f, -1387.816040f, 526.783691f, 3.0f), // nefarian spawn
|
||||
new Position(-7535.456543f, -1279.562500f, 476.798706f, 3.0f) // nefarian move
|
||||
};
|
||||
|
||||
public static uint[] Entry = { CreatureIds.BronzeDrakanoid, CreatureIds.BlueDrakanoid, CreatureIds.RedDrakanoid, CreatureIds.GreenDrakanoid, CreatureIds.BlackDrakanoid };
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
// Victor Nefarius
|
||||
public const uint SpawnAdd = 1;
|
||||
public const uint ShadowBolt = 2;
|
||||
public const uint Fear = 3;
|
||||
public const uint MindControl = 4;
|
||||
// Nefarian
|
||||
public const uint Shadowflame = 5;
|
||||
public const uint Veilofshadow = 6;
|
||||
public const uint Cleave = 7;
|
||||
public const uint Taillash = 8;
|
||||
public const uint Classcall = 9;
|
||||
// Ubrs
|
||||
public const uint Chaos1 = 10;
|
||||
public const uint Chaos2 = 11;
|
||||
public const uint Path2 = 12;
|
||||
public const uint Path3 = 13;
|
||||
public const uint Success1 = 14;
|
||||
public const uint Success2 = 15;
|
||||
public const uint Success3 = 16;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_victor_nefarius : BossAI
|
||||
{
|
||||
uint SpawnedAdds;
|
||||
|
||||
public boss_victor_nefarius(Creature creature) : base(creature, DataTypes.Nefarian)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
SpawnedAdds = 0;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (me.GetMapId() == 469)
|
||||
{
|
||||
if (!me.FindNearestCreature(BWLCreatureIds.Nefarian, 1000.0f, true))
|
||||
_Reset();
|
||||
|
||||
me.SetVisible(true);
|
||||
me.SetNpcFlag(NPCFlags.Gossip);
|
||||
me.SetFaction((uint)FactionTemplates.Friendly);
|
||||
me.SetStandState(UnitStandStateType.SitHighChair);
|
||||
me.RemoveAura(SpellIds.NefariansBarrier);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void BeginEvent(Player target)
|
||||
{
|
||||
_JustEngagedWith(target);
|
||||
|
||||
Talk(TextIds.SayGamesbegin2);
|
||||
|
||||
me.SetFaction((uint)FactionTemplates.DragonflightBlack);
|
||||
me.RemoveNpcFlag(NPCFlags.Gossip);
|
||||
DoCast(me, SpellIds.NefariansBarrier);
|
||||
me.SetStandState(UnitStandStateType.Stand);
|
||||
me.SetImmuneToPC(false);
|
||||
AttackStart(target);
|
||||
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(10));
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
|
||||
//_events.ScheduleEvent(EventIds.MindControl, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
_events.ScheduleEvent(EventIds.SpawnAdd, TimeSpan.FromSeconds(10));
|
||||
}
|
||||
|
||||
public override void SummonedCreatureDies(Creature summon, Unit killer)
|
||||
{
|
||||
if (summon.GetEntry() != BWLCreatureIds.Nefarian)
|
||||
{
|
||||
summon.UpdateEntry(CreatureIds.BoneConstruct);
|
||||
summon.SetUnitFlag(UnitFlags.Uninteractible);
|
||||
summon.SetReactState(ReactStates.Passive);
|
||||
summon.SetStandState(UnitStandStateType.Dead);
|
||||
}
|
||||
}
|
||||
|
||||
public override void JustSummoned(Creature summon) { }
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
if (type == 1 && data == 1)
|
||||
{
|
||||
me.StopMoving();
|
||||
_events.ScheduleEvent(EventIds.Path2, TimeSpan.FromSeconds(9));
|
||||
}
|
||||
|
||||
if (type == 1 && data == 2)
|
||||
_events.ScheduleEvent(EventIds.Success1, TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.Path2:
|
||||
me.GetMotionMaster().MovePath(MiscConst.NefariusPath2, false);
|
||||
_events.ScheduleEvent(EventIds.Chaos1, TimeSpan.FromSeconds(7));
|
||||
break;
|
||||
case EventIds.Chaos1:
|
||||
Creature gyth = me.FindNearestCreature(CreatureIds.Gyth, 75.0f, true);
|
||||
if (gyth)
|
||||
{
|
||||
me.SetFacingToObject(gyth);
|
||||
Talk(TextIds.SayChaosSpell);
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.Chaos2, TimeSpan.FromSeconds(2));
|
||||
break;
|
||||
case EventIds.Chaos2:
|
||||
DoCast(SpellIds.ChromaticChaos);
|
||||
me.SetFacingTo(1.570796f);
|
||||
break;
|
||||
case EventIds.Success1:
|
||||
Unit player = me.SelectNearestPlayer(60.0f);
|
||||
if (player)
|
||||
{
|
||||
me.SetFacingToObject(player);
|
||||
Talk(TextIds.SaySuccess);
|
||||
GameObject portcullis1 = me.FindNearestGameObject(GameObjectIds.PortcullisActive, 65.0f);
|
||||
if (portcullis1)
|
||||
portcullis1.SetGoState(GameObjectState.Active);
|
||||
GameObject portcullis2 = me.FindNearestGameObject(GameObjectIds.PortcullisTobossrooms, 80.0f);
|
||||
if (portcullis2)
|
||||
portcullis2.SetGoState(GameObjectState.Active);
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.Success2, TimeSpan.FromSeconds(4));
|
||||
break;
|
||||
case EventIds.Success2:
|
||||
DoCast(me, SpellIds.VaelastraszzSpawn);
|
||||
me.DespawnOrUnsummon(TimeSpan.FromSeconds(1));
|
||||
break;
|
||||
case EventIds.Path3:
|
||||
me.GetMotionMaster().MovePath(MiscConst.NefariusPath3, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Only do this if we haven't spawned nefarian yet
|
||||
if (UpdateVictim() && SpawnedAdds <= 42)
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.ShadowBolt:
|
||||
switch (RandomHelper.URand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
DoCastVictim(SpellIds.ShadowboltVolley);
|
||||
break;
|
||||
case 1:
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 40, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Shadowbolt);
|
||||
break;
|
||||
}
|
||||
ResetThreatList();
|
||||
_events.ScheduleEvent(EventIds.ShadowBolt, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(10));
|
||||
break;
|
||||
case EventIds.Fear:
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 40, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Fear);
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
|
||||
break;
|
||||
}
|
||||
case EventIds.MindControl:
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 40, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.ShadowCommand);
|
||||
_events.ScheduleEvent(EventIds.MindControl, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
break;
|
||||
}
|
||||
case EventIds.SpawnAdd:
|
||||
for (byte i = 0; i < 2; ++i)
|
||||
{
|
||||
uint CreatureID;
|
||||
if (RandomHelper.URand(0, 2) == 0)
|
||||
CreatureID = CreatureIds.ChromaticDrakanoid;
|
||||
else
|
||||
CreatureID = MiscConst.Entry[RandomHelper.URand(0, 4)];
|
||||
Creature dragon = me.SummonCreature(CreatureID, MiscConst.DrakeSpawnLoc[i]);
|
||||
if (dragon)
|
||||
{
|
||||
dragon.SetFaction((uint)FactionTemplates.DragonflightBlack);
|
||||
dragon.GetAI().AttackStart(me.GetVictim());
|
||||
}
|
||||
|
||||
if (++SpawnedAdds >= 42)
|
||||
{
|
||||
Creature nefarian = me.SummonCreature(BWLCreatureIds.Nefarian, MiscConst.NefarianLoc[0]);
|
||||
if (nefarian)
|
||||
{
|
||||
nefarian.SetActive(true);
|
||||
nefarian.SetFarVisible(true);
|
||||
nefarian.SetCanFly(true);
|
||||
nefarian.SetDisableGravity(true);
|
||||
nefarian.CastSpell(null, SpellIds.ShadowflameInitial);
|
||||
nefarian.GetMotionMaster().MovePoint(1, MiscConst.NefarianLoc[1]);
|
||||
}
|
||||
_events.CancelEvent(EventIds.MindControl);
|
||||
_events.CancelEvent(EventIds.Fear);
|
||||
_events.CancelEvent(EventIds.ShadowBolt);
|
||||
me.SetVisible(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.SpawnAdd, TimeSpan.FromSeconds(4));
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (menuId == TextIds.GossipId && gossipListId == TextIds.GossipOptionId)
|
||||
{
|
||||
player.CloseGossipMenu();
|
||||
Talk(TextIds.SayGamesbegin1);
|
||||
BeginEvent(player);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_nefarian : BossAI
|
||||
{
|
||||
bool canDespawn;
|
||||
uint DespawnTimer;
|
||||
bool Phase3;
|
||||
|
||||
public boss_nefarian(Creature creature) : base(creature, DataTypes.Nefarian)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Phase3 = false;
|
||||
canDespawn = false;
|
||||
DespawnTimer = 30000;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void JustReachedHome()
|
||||
{
|
||||
canDespawn = true;
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
_events.ScheduleEvent(EventIds.Shadowflame, TimeSpan.FromSeconds(12));
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
_events.ScheduleEvent(EventIds.Veilofshadow, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
_events.ScheduleEvent(EventIds.Cleave, TimeSpan.FromSeconds(7));
|
||||
//_events.ScheduleEvent(EventIds.Taillash, TimeSpan.FromSeconds(10));
|
||||
_events.ScheduleEvent(EventIds.Classcall, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
Talk(TextIds.SayRandom);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if ((RandomHelper.Rand32() % 5) != 0)
|
||||
return;
|
||||
|
||||
Talk(TextIds.SaySlay, victim);
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
{
|
||||
if (type != MovementGeneratorType.Point)
|
||||
return;
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
if (me.GetVictim())
|
||||
AttackStart(me.GetVictim());
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (canDespawn && DespawnTimer <= diff)
|
||||
{
|
||||
instance.SetBossState(DataTypes.Nefarian, EncounterState.Fail);
|
||||
|
||||
List<Creature> constructList = me.GetCreatureListWithEntryInGrid(CreatureIds.BoneConstruct, 500.0f);
|
||||
foreach (var creature in constructList)
|
||||
creature.DespawnOrUnsummon();
|
||||
|
||||
}
|
||||
else DespawnTimer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (canDespawn)
|
||||
canDespawn = false;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.Shadowflame:
|
||||
DoCastVictim(SpellIds.Shadowflame);
|
||||
_events.ScheduleEvent(EventIds.Shadowflame, TimeSpan.FromSeconds(12));
|
||||
break;
|
||||
case EventIds.Fear:
|
||||
DoCastVictim(SpellIds.Bellowingroar);
|
||||
_events.ScheduleEvent(EventIds.Fear, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
break;
|
||||
case EventIds.Veilofshadow:
|
||||
DoCastVictim(SpellIds.Veilofshadow);
|
||||
_events.ScheduleEvent(EventIds.Veilofshadow, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(35));
|
||||
break;
|
||||
case EventIds.Cleave:
|
||||
DoCastVictim(SpellIds.Cleave);
|
||||
_events.ScheduleEvent(EventIds.Cleave, TimeSpan.FromSeconds(7));
|
||||
break;
|
||||
case EventIds.Taillash:
|
||||
// Cast Nyi since we need a better check for behind target
|
||||
DoCastVictim(SpellIds.Taillash);
|
||||
_events.ScheduleEvent(EventIds.Taillash, TimeSpan.FromSeconds(10));
|
||||
break;
|
||||
case EventIds.Classcall:
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 100.0f, true);
|
||||
if (target)
|
||||
switch (target.GetClass())
|
||||
{
|
||||
case Class.Mage:
|
||||
Talk(TextIds.SayMage);
|
||||
DoCast(me, SpellIds.Mage);
|
||||
break;
|
||||
case Class.Warrior:
|
||||
Talk(TextIds.SayWarrior);
|
||||
DoCast(me, SpellIds.Warrior);
|
||||
break;
|
||||
case Class.Druid:
|
||||
Talk(TextIds.SayDruid);
|
||||
DoCast(target, SpellIds.Druid);
|
||||
break;
|
||||
case Class.Priest:
|
||||
Talk(TextIds.SayPriest);
|
||||
DoCast(me, SpellIds.Priest);
|
||||
break;
|
||||
case Class.Paladin:
|
||||
Talk(TextIds.SayPaladin);
|
||||
DoCast(me, SpellIds.Paladin);
|
||||
break;
|
||||
case Class.Shaman:
|
||||
Talk(TextIds.SayShaman);
|
||||
DoCast(me, SpellIds.Shaman);
|
||||
break;
|
||||
case Class.Warlock:
|
||||
Talk(TextIds.SayWarlock);
|
||||
DoCast(me, SpellIds.Warlock);
|
||||
break;
|
||||
case Class.Hunter:
|
||||
Talk(TextIds.SayHunter);
|
||||
DoCast(me, SpellIds.Hunter);
|
||||
break;
|
||||
case Class.Rogue:
|
||||
Talk(TextIds.SayRogue);
|
||||
DoCast(me, SpellIds.Rogue);
|
||||
break;
|
||||
case Class.Deathknight:
|
||||
Talk(TextIds.SayDeathKnight);
|
||||
DoCast(me, SpellIds.DeathKnight);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.Classcall, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35));
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
// Phase3 begins when health below 20 pct
|
||||
if (!Phase3 && HealthBelowPct(20))
|
||||
{
|
||||
List<Creature> constructList = me.GetCreatureListWithEntryInGrid(CreatureIds.BoneConstruct, 500.0f);
|
||||
foreach (var creature in constructList)
|
||||
{
|
||||
if (creature != null && !creature.IsAlive())
|
||||
{
|
||||
creature.Respawn();
|
||||
DoZoneInCombat(creature);
|
||||
creature.RemoveUnitFlag(UnitFlags.Uninteractible);
|
||||
creature.SetReactState(ReactStates.Aggressive);
|
||||
creature.SetStandState(UnitStandStateType.Stand);
|
||||
}
|
||||
}
|
||||
|
||||
Phase3 = true;
|
||||
Talk(TextIds.SayRaiseSkeletons);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.BlackwingLair.Razorgore
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// @todo orb uses the wrong spell, this needs sniffs
|
||||
public const uint Mindcontrol = 42013;
|
||||
public const uint Channel = 45537;
|
||||
public const uint EggDestroy = 19873;
|
||||
|
||||
public const uint Cleave = 22540;
|
||||
public const uint Warstomp = 24375;
|
||||
public const uint Fireballvolley = 22425;
|
||||
public const uint Conflagration = 23023;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayEggsBroken1 = 0;
|
||||
public const uint SayEggsBroken2 = 1;
|
||||
public const uint SayEggsBroken3 = 2;
|
||||
public const uint SayDeath = 3;
|
||||
}
|
||||
|
||||
struct CreatureIds
|
||||
{
|
||||
public const uint EliteDrachkin = 12422;
|
||||
public const uint EliteWarrior = 12458;
|
||||
public const uint Warrior = 12416;
|
||||
public const uint Mage = 12420;
|
||||
public const uint Warlock = 12459;
|
||||
}
|
||||
|
||||
struct GameObjectIds
|
||||
{
|
||||
public const uint Egg = 177807;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_razorgore : BossAI
|
||||
{
|
||||
bool secondPhase;
|
||||
|
||||
public boss_razorgore(Creature creature) : base(creature, DataTypes.RazorgoreTheUntamed)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
secondPhase = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
Initialize();
|
||||
instance.SetData(BWLMisc.DataEggEvent, (uint)EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TextIds.SayDeath);
|
||||
|
||||
instance.SetData(BWLMisc.DataEggEvent, (uint)EncounterState.NotStarted);
|
||||
}
|
||||
|
||||
void DoChangePhase()
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Cleave);
|
||||
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(10));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(35), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Warstomp);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Fireballvolley);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Conflagration);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
|
||||
secondPhase = true;
|
||||
me.RemoveAllAuras();
|
||||
me.SetFullHealth();
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == BWLMisc.ActionPhaseTwo)
|
||||
DoChangePhase();
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit who, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||
{
|
||||
// @todo this is wrong - razorgore should still take damage, he should just nuke the whole room and respawn if he dies during P1
|
||||
if (!secondPhase)
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class go_orb_of_domination : GameObjectAI
|
||||
{
|
||||
InstanceScript instance;
|
||||
|
||||
public go_orb_of_domination(GameObject go) : base(go)
|
||||
{
|
||||
instance = go.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override bool OnGossipHello(Player player)
|
||||
{
|
||||
if (instance.GetData(BWLMisc.DataEggEvent) != (uint)EncounterState.Done)
|
||||
{
|
||||
Creature razorgore = instance.GetCreature(DataTypes.RazorgoreTheUntamed);
|
||||
if (razorgore)
|
||||
{
|
||||
razorgore.Attack(player, true);
|
||||
player.CastSpell(razorgore, SpellIds.Mindcontrol);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 19873 - Destroy Egg
|
||||
class spell_egg_event : SpellScript
|
||||
{
|
||||
void HandleOnHit()
|
||||
{
|
||||
InstanceScript instance = GetCaster().GetInstanceScript();
|
||||
if (instance != null)
|
||||
instance.SetData(BWLMisc.DataEggEvent, (uint)EncounterState.Special);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnHit.Add(new HitHandler(HandleOnHit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.BlackwingLair.Vaelastrasz
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Essenceofthered = 23513;
|
||||
public const uint Flamebreath = 23461;
|
||||
public const uint Firenova = 23462;
|
||||
public const uint Tailswipe = 15847;
|
||||
public const uint Burningadrenaline = 18173; //Cast this one. It's what 3.3.5 Dbm expects.
|
||||
public const uint BurningadrenalineExplosion = 23478;
|
||||
public const uint Cleave = 19983; //Chain cleave is most likely named something different and contains a dummy effect
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayLine1 = 0;
|
||||
public const uint SayLine2 = 1;
|
||||
public const uint SayLine3 = 2;
|
||||
public const uint SayHalflife = 3;
|
||||
public const uint SayKilltarget = 4;
|
||||
|
||||
public const uint GossipId = 6101;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_vaelastrasz : BossAI
|
||||
{
|
||||
ObjectGuid PlayerGUID;
|
||||
bool HasYelled;
|
||||
|
||||
public boss_vaelastrasz(Creature creature) : base(creature, DataTypes.VaelastrazTheCorrupt)
|
||||
{
|
||||
Initialize();
|
||||
creature.SetNpcFlag(NPCFlags.Gossip);
|
||||
creature.SetFaction((uint)FactionTemplates.Friendly);
|
||||
creature.RemoveUnitFlag(UnitFlags.Uninteractible);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
PlayerGUID.Clear();
|
||||
HasYelled = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
me.SetStandState(UnitStandStateType.Dead);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
|
||||
DoCast(me, SpellIds.Essenceofthered);
|
||||
me.SetHealth(me.CountPctFromMaxHealth(30));
|
||||
// now drop damage requirement to be able to take loot
|
||||
me.ResetPlayerDamageReq();
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Cleave);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Flamebreath);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(14));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Firenova);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(11), task =>
|
||||
{
|
||||
//Only cast if we are behind
|
||||
if (!me.HasInArc(MathF.PI, me.GetVictim()))
|
||||
{
|
||||
DoCast(me.GetVictim(), SpellIds.Tailswipe);
|
||||
}
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
//selects a random target that isn't the current victim and is a mana user (selects mana users) but not pets
|
||||
//it also ignores targets who have the aura. We don't want to place the debuff on the same target twice.
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 1, u => { return u && !u.IsPet() && u.GetPowerType() == PowerType.Mana && !u.HasAura(SpellIds.Burningadrenaline); });
|
||||
if (target != null)
|
||||
me.CastSpell(target, SpellIds.Burningadrenaline, true);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(45), task =>
|
||||
{
|
||||
//Vael has to cast it himself; contrary to the previous commit's comment. Nothing happens otherwise.
|
||||
me.CastSpell(me.GetVictim(), SpellIds.Burningadrenaline, true);
|
||||
task.Repeat(TimeSpan.FromSeconds(45));
|
||||
});
|
||||
}
|
||||
|
||||
void BeginSpeech(Unit target)
|
||||
{
|
||||
PlayerGUID = target.GetGUID();
|
||||
me.RemoveNpcFlag(NPCFlags.Gossip);
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
|
||||
{
|
||||
Talk(TextIds.SayLine1);
|
||||
me.SetStandState(UnitStandStateType.Stand);
|
||||
me.HandleEmoteCommand(Emote.OneshotTalk);
|
||||
task.Schedule(TimeSpan.FromSeconds(12), speechTask2 =>
|
||||
{
|
||||
Talk(TextIds.SayLine2);
|
||||
me.HandleEmoteCommand(Emote.OneshotTalk);
|
||||
speechTask2.Schedule(TimeSpan.FromSeconds(12), speechTask3 =>
|
||||
{
|
||||
Talk(TextIds.SayLine3);
|
||||
me.HandleEmoteCommand(Emote.OneshotTalk);
|
||||
speechTask3.Schedule(TimeSpan.FromSeconds(16), speechTask4 =>
|
||||
{
|
||||
me.SetFaction((uint)FactionTemplates.DragonflightBlack);
|
||||
Player player = Global.ObjAccessor.GetPlayer(me, PlayerGUID);
|
||||
if (player)
|
||||
AttackStart(player);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if ((RandomHelper.Rand32() % 5) != 0)
|
||||
return;
|
||||
|
||||
Talk(TextIds.SayKilltarget, victim);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
// Yell if hp lower than 15%
|
||||
if (HealthBelowPct(15) && !HasYelled)
|
||||
{
|
||||
Talk(TextIds.SayHalflife);
|
||||
HasYelled = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (menuId == TextIds.GossipId && gossipListId == 0)
|
||||
{
|
||||
player.CloseGossipMenu();
|
||||
BeginSpeech(player);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Need to define an aurascript for EventBurningadrenaline's death effect.
|
||||
[Script] // 18173 - Burning Adrenaline
|
||||
class spell_vael_burning_adrenaline : AuraScript
|
||||
{
|
||||
void OnAuraRemoveHandler(AuraEffect aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
//The tooltip says the on death the AoE occurs. According to information: http://qaliaresponse.stage.lithium.com/t5/WoW-Mayhem/Surviving-Burning-Adrenaline-For-tanks/td-p/48609
|
||||
//Burning Adrenaline can be survived therefore Blizzard's implementation was an AoE bomb that went off if you were still alive and dealt
|
||||
//damage to the target. You don't have to die for it to go off. It can go off whether you live or die.
|
||||
GetTarget().CastSpell(GetTarget(), SpellIds.BurningadrenalineExplosion, true);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
AfterEffectRemove.Add(new EffectApplyHandler(OnAuraRemoveHandler, 2, AuraType.PeriodicTriggerSpell, AuraEffectHandleModes.Real));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.MoltenCore.BaronGeddon
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Inferno = 19695;
|
||||
public const uint InfernoDmg = 19698;
|
||||
public const uint IgniteMana = 19659;
|
||||
public const uint LivingBomb = 20475;
|
||||
public const uint Armageddon = 20478;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteService = 0;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_baron_geddon : BossAI
|
||||
{
|
||||
public boss_baron_geddon(Creature creature) : base(creature, BossIds.BaronGeddon) { }
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(45), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.Inferno);
|
||||
task.Repeat(TimeSpan.FromSeconds(45));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true, true, -(int)SpellIds.IgniteMana);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.IgniteMana);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(35), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.LivingBomb);
|
||||
task.Repeat(TimeSpan.FromSeconds(35));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
// If we are <2% hp cast Armageddon
|
||||
if (!HealthAbovePct(2))
|
||||
{
|
||||
me.InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SpellIds.Armageddon);
|
||||
Talk(TextIds.EmoteService);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 19695 - Inferno
|
||||
class spell_baron_geddon_inferno : AuraScript
|
||||
{
|
||||
void OnPeriodic(AuraEffect aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
int[] damageForTick = { 500, 500, 1000, 1000, 2000, 2000, 3000, 5000 };
|
||||
CastSpellExtraArgs args = new CastSpellExtraArgs(TriggerCastFlags.FullMask);
|
||||
args.TriggeringAura = aurEff;
|
||||
args.AddSpellMod(SpellValueMod.BasePoint0, damageForTick[aurEff.GetTickNumber() - 1]);
|
||||
GetTarget().CastSpell((WorldObject)null, SpellIds.InfernoDmg, args);
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnEffectPeriodic.Add(new EffectPeriodicHandler(OnPeriodic, 0, AuraType.PeriodicTriggerSpell));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.MoltenCore.Garr
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Garr
|
||||
public const uint AntimagicPulse = 19492;
|
||||
public const uint MagmaShackles = 19496;
|
||||
public const uint Enrage = 19516;
|
||||
public const uint SeparationAnxiety = 23492;
|
||||
|
||||
// Adds
|
||||
public const uint Eruption = 19497;
|
||||
public const uint Immolate = 15732;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_garr : BossAI
|
||||
{
|
||||
public boss_garr(Creature creature) : base(creature, BossIds.Garr) { }
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(25), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.AntimagicPulse);
|
||||
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.MagmaShackles);
|
||||
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(12));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_firesworn : ScriptedAI
|
||||
{
|
||||
public npc_firesworn(Creature creature) : base(creature) { }
|
||||
|
||||
void ScheduleTasks()
|
||||
{
|
||||
// Timers for this are probably wrong
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Immolate);
|
||||
|
||||
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10));
|
||||
});
|
||||
|
||||
// Separation Anxiety - Periodically check if Garr is nearby
|
||||
// ...and enrage if he is not.
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
|
||||
{
|
||||
if (!me.FindNearestCreature(MCCreatureIds.Garr, 20.0f))
|
||||
DoCastSelf(SpellIds.SeparationAnxiety);
|
||||
else if (me.HasAura(SpellIds.SeparationAnxiety))
|
||||
me.RemoveAurasDueToSpell(SpellIds.SeparationAnxiety);
|
||||
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
ScheduleTasks();
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||
{
|
||||
ulong health10pct = me.CountPctFromMaxHealth(10);
|
||||
ulong health = me.GetHealth();
|
||||
if (health - damage < health10pct)
|
||||
{
|
||||
damage = 0;
|
||||
DoCastVictim(SpellIds.Eruption);
|
||||
me.DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore.Gehennas
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint GehennasCurse = 19716;
|
||||
public const uint RainOfFire = 19717;
|
||||
public const uint ShadowBolt = 19728;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_gehennas : BossAI
|
||||
{
|
||||
public boss_gehennas(Creature creature) : base(creature, BossIds.Gehennas) { }
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.GehennasCurse);
|
||||
task.Repeat(TimeSpan.FromSeconds(22), TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.RainOfFire);
|
||||
task.Repeat(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(12));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 1);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.ShadowBolt);
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.MoltenCore.Golemagg
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Golemagg
|
||||
public const uint Magmasplash = 13879;
|
||||
public const uint Pyroblast = 20228;
|
||||
public const uint Earthquake = 19798;
|
||||
public const uint Enrage = 19953;
|
||||
public const uint GolemaggTrust = 20553;
|
||||
|
||||
// Core Rager
|
||||
public const uint Mangle = 19820;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteLowhp = 0;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_golemagg : BossAI
|
||||
{
|
||||
public boss_golemagg(Creature creature) : base(creature, BossIds.GolemaggTheIncinerator) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
DoCast(me, SpellIds.Magmasplash, new CastSpellExtraArgs(true));
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Pyroblast);
|
||||
task.Repeat(TimeSpan.FromSeconds(7));
|
||||
});
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||
{
|
||||
if (!HealthBelowPct(10) || me.HasAura(SpellIds.Enrage))
|
||||
return;
|
||||
|
||||
DoCast(me, SpellIds.Enrage, new CastSpellExtraArgs(true));
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Earthquake);
|
||||
task.Repeat(TimeSpan.FromSeconds(3));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_core_rager : ScriptedAI
|
||||
{
|
||||
InstanceScript _instance;
|
||||
|
||||
public npc_core_rager(Creature creature) : base(creature)
|
||||
{
|
||||
_instance = creature.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(7), task => // These times are probably wrong
|
||||
{
|
||||
DoCastVictim(SpellIds.Mangle);
|
||||
task.Repeat(TimeSpan.FromSeconds(10));
|
||||
});
|
||||
}
|
||||
|
||||
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||
{
|
||||
if (HealthAbovePct(50) || _instance == null)
|
||||
return;
|
||||
|
||||
Creature pGolemagg = ObjectAccessor.GetCreature(me, _instance.GetGuidData(BossIds.GolemaggTheIncinerator));
|
||||
if (pGolemagg)
|
||||
{
|
||||
if (pGolemagg.IsAlive())
|
||||
{
|
||||
me.AddAura(SpellIds.GolemaggTrust, me);
|
||||
Talk(TextIds.EmoteLowhp);
|
||||
me.SetFullHealth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore
|
||||
{
|
||||
struct BossIds
|
||||
{
|
||||
public const uint Lucifron = 0;
|
||||
public const uint Magmadar = 1;
|
||||
public const uint Gehennas = 2;
|
||||
public const uint Garr = 3;
|
||||
public const uint Shazzrah = 4;
|
||||
public const uint BaronGeddon = 5;
|
||||
public const uint SulfuronHarbinger = 6;
|
||||
public const uint GolemaggTheIncinerator = 7;
|
||||
public const uint MajordomoExecutus = 8;
|
||||
public const uint Ragnaros = 9;
|
||||
|
||||
public const uint MaxEncounter = 10;
|
||||
}
|
||||
|
||||
struct ActionIds
|
||||
{
|
||||
public const int StartRagnaros = 0;
|
||||
public const int StartRagnarosAlt = 1;
|
||||
}
|
||||
|
||||
struct MCCreatureIds
|
||||
{
|
||||
public const uint Lucifron = 12118;
|
||||
public const uint Magmadar = 11982;
|
||||
public const uint Gehennas = 12259;
|
||||
public const uint Garr = 12057;
|
||||
public const uint Shazzrah = 12264;
|
||||
public const uint BaronGeddon = 12056;
|
||||
public const uint SulfuronHarbinger = 12098;
|
||||
public const uint GolemaggTheIncinerator = 11988;
|
||||
public const uint MajordomoExecutus = 12018;
|
||||
public const uint Ragnaros = 11502;
|
||||
public const uint FlamewakerHealer = 11663;
|
||||
public const uint FlamewakerElite = 11664;
|
||||
}
|
||||
|
||||
struct MCGameObjectIds
|
||||
{
|
||||
public const uint CacheOfTheFirelord = 179703;
|
||||
}
|
||||
|
||||
struct MCMiscConst
|
||||
{
|
||||
public const uint DataRagnarosAdds = 0;
|
||||
|
||||
public static Position[] SummonPositions =
|
||||
{
|
||||
new Position(737.850f, -1145.35f, -120.288f, 4.71368f),
|
||||
new Position(744.162f, -1151.63f, -119.726f, 4.58204f),
|
||||
new Position(751.247f, -1152.82f, -119.744f, 4.49673f),
|
||||
new Position(759.206f, -1155.09f, -120.051f, 4.30104f),
|
||||
new Position(755.973f, -1152.33f, -120.029f, 4.25588f),
|
||||
new Position(731.712f, -1147.56f, -120.195f, 4.95955f),
|
||||
new Position(726.499f, -1149.80f, -120.156f, 5.24055f),
|
||||
new Position(722.408f, -1152.41f, -120.029f, 5.33087f),
|
||||
new Position(718.994f, -1156.36f, -119.805f, 5.75738f),
|
||||
new Position(838.510f, -829.840f, -232.000f, 2.00000f),
|
||||
};
|
||||
|
||||
public static Position RagnarosTelePos = new Position(829.159f, -815.773f, -228.972f, 5.30500f);
|
||||
public static Position RagnarosSummonPos = new Position(838.510f, -829.840f, -232.000f, 2.00000f);
|
||||
}
|
||||
|
||||
[Script]
|
||||
class instance_molten_core : InstanceMapScript
|
||||
{
|
||||
public instance_molten_core() : base(nameof(instance_molten_core), 409) { }
|
||||
|
||||
class instance_molten_core_InstanceMapScript : InstanceScript
|
||||
{
|
||||
ObjectGuid _golemaggTheIncineratorGUID;
|
||||
ObjectGuid _majordomoExecutusGUID;
|
||||
ObjectGuid _cacheOfTheFirelordGUID;
|
||||
bool _executusSchedule;
|
||||
byte _ragnarosAddDeaths;
|
||||
|
||||
public instance_molten_core_InstanceMapScript(InstanceMap map) : base(map)
|
||||
{
|
||||
SetHeaders("MC");
|
||||
SetBossNumber(BossIds.MaxEncounter);
|
||||
_executusSchedule = false;
|
||||
_ragnarosAddDeaths = 0;
|
||||
}
|
||||
|
||||
public override void OnPlayerEnter(Player player)
|
||||
{
|
||||
if (_executusSchedule)
|
||||
SummonMajordomoExecutus();
|
||||
}
|
||||
|
||||
public override void OnCreatureCreate(Creature creature)
|
||||
{
|
||||
switch (creature.GetEntry())
|
||||
{
|
||||
case MCCreatureIds.GolemaggTheIncinerator:
|
||||
_golemaggTheIncineratorGUID = creature.GetGUID();
|
||||
break;
|
||||
case MCCreatureIds.MajordomoExecutus:
|
||||
_majordomoExecutusGUID = creature.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameObjectCreate(GameObject go)
|
||||
{
|
||||
switch (go.GetEntry())
|
||||
{
|
||||
case MCGameObjectIds.CacheOfTheFirelord:
|
||||
_cacheOfTheFirelordGUID = go.GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetData(uint type, uint data)
|
||||
{
|
||||
if (type == MCMiscConst.DataRagnarosAdds)
|
||||
{
|
||||
if (data == 1)
|
||||
++_ragnarosAddDeaths;
|
||||
else if (data == 0)
|
||||
_ragnarosAddDeaths = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override uint GetData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MCMiscConst.DataRagnarosAdds:
|
||||
return _ragnarosAddDeaths;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override ObjectGuid GetGuidData(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case BossIds.GolemaggTheIncinerator:
|
||||
return _golemaggTheIncineratorGUID;
|
||||
case BossIds.MajordomoExecutus:
|
||||
return _majordomoExecutusGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
public override bool SetBossState(uint bossId, EncounterState state)
|
||||
{
|
||||
if (!base.SetBossState(bossId, state))
|
||||
return false;
|
||||
|
||||
if (state == EncounterState.Done && bossId < BossIds.MajordomoExecutus)
|
||||
if (CheckMajordomoExecutus())
|
||||
SummonMajordomoExecutus();
|
||||
|
||||
if (bossId == BossIds.MajordomoExecutus && state == EncounterState.Done)
|
||||
DoRespawnGameObject(_cacheOfTheFirelordGUID, TimeSpan.FromDays(7));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SummonMajordomoExecutus()
|
||||
{
|
||||
_executusSchedule = false;
|
||||
if (!_majordomoExecutusGUID.IsEmpty())
|
||||
return;
|
||||
|
||||
if (GetBossState(BossIds.MajordomoExecutus) != EncounterState.Done)
|
||||
{
|
||||
instance.SummonCreature(MCCreatureIds.MajordomoExecutus, MCMiscConst.SummonPositions[0]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerHealer, MCMiscConst.SummonPositions[1]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerHealer, MCMiscConst.SummonPositions[2]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerHealer, MCMiscConst.SummonPositions[3]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerHealer, MCMiscConst.SummonPositions[4]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerElite, MCMiscConst.SummonPositions[5]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerElite, MCMiscConst.SummonPositions[6]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerElite, MCMiscConst.SummonPositions[7]);
|
||||
instance.SummonCreature(MCCreatureIds.FlamewakerElite, MCMiscConst.SummonPositions[8]);
|
||||
}
|
||||
else
|
||||
{
|
||||
TempSummon summon = instance.SummonCreature(MCCreatureIds.MajordomoExecutus, MCMiscConst.RagnarosTelePos);
|
||||
if (summon)
|
||||
summon.GetAI().DoAction(ActionIds.StartRagnarosAlt);
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckMajordomoExecutus()
|
||||
{
|
||||
if (GetBossState(BossIds.Ragnaros) == EncounterState.Done)
|
||||
return false;
|
||||
|
||||
for (byte i = 0; i < BossIds.MajordomoExecutus; ++i)
|
||||
if (GetBossState(i) != EncounterState.Done)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(string data)
|
||||
{
|
||||
if (CheckMajordomoExecutus())
|
||||
_executusSchedule = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override InstanceScript GetInstanceScript(InstanceMap map)
|
||||
{
|
||||
return new instance_molten_core_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore.Lucifron
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint ImpendingDoom = 19702;
|
||||
public const uint LucifronCurse = 19703;
|
||||
public const uint ShadowShock = 20603;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_lucifron : BossAI
|
||||
{
|
||||
public boss_lucifron(Creature creature) : base(creature, BossIds.Lucifron) { }
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ImpendingDoom);
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.LucifronCurse);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.ShadowShock);
|
||||
task.Repeat(TimeSpan.FromSeconds(6));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore.Magmadar
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint Frenzy = 19451;
|
||||
public const uint MagmaSpit = 19449;
|
||||
public const uint Panic = 19408;
|
||||
public const uint LavaBomb = 19428;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint EmoteFrenzy = 0;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_magmadar : BossAI
|
||||
{
|
||||
public boss_magmadar(Creature creature) : base(creature, BossIds.Magmadar) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
DoCast(me, SpellIds.MagmaSpit, new CastSpellExtraArgs(true));
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
Talk(TextIds.EmoteFrenzy);
|
||||
DoCast(me, SpellIds.Frenzy);
|
||||
task.Repeat(TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Panic);
|
||||
task.Repeat(TimeSpan.FromSeconds(35));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true, true, -(int)SpellIds.LavaBomb);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.LavaBomb);
|
||||
task.Repeat(TimeSpan.FromSeconds(12));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.MoltenCore.Majordomo
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint SummonRagnaros = 19774;
|
||||
public const uint BlastWave = 20229;
|
||||
public const uint Teleport = 20618;
|
||||
public const uint MagicReflection = 20619;
|
||||
public const uint AegisOfRagnaros = 20620;
|
||||
public const uint DamageReflection = 21075;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SayAggro = 0;
|
||||
public const uint SaySpawn = 1;
|
||||
public const uint SaySlay = 2;
|
||||
public const uint SaySpecial = 3;
|
||||
public const uint SayDefeat = 4;
|
||||
|
||||
public const uint SaySummonMaj = 5;
|
||||
public const uint SayArrival2Maj = 6;
|
||||
|
||||
public const uint OptionIdYouChallengedUs = 0;
|
||||
public const uint MenuOptionYouChallengedUs = 4108;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_majordomo : BossAI
|
||||
{
|
||||
public boss_majordomo(Creature creature) : base(creature, BossIds.MajordomoExecutus) { }
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (RandomHelper.URand(0, 99) < 25)
|
||||
Talk(TextIds.SaySlay);
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
base.JustEngagedWith(who);
|
||||
Talk(TextIds.SayAggro);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.MagicReflection);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.DamageReflection);
|
||||
task.Repeat(TimeSpan.FromSeconds(30));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.BlastWave);
|
||||
task.Repeat(TimeSpan.FromSeconds(10));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(20), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 1);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Teleport);
|
||||
task.Repeat(TimeSpan.FromSeconds(20));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (instance.GetBossState(BossIds.MajordomoExecutus) != EncounterState.Done)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!me.FindNearestCreature(MCCreatureIds.FlamewakerHealer, 100.0f) && !me.FindNearestCreature(MCCreatureIds.FlamewakerElite, 100.0f))
|
||||
{
|
||||
instance.UpdateEncounterStateForKilledCreature(me.GetEntry(), me);
|
||||
me.SetFaction((uint)FactionTemplates.Friendly);
|
||||
EnterEvadeMode();
|
||||
Talk(TextIds.SayDefeat);
|
||||
_JustDied();
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(32), task =>
|
||||
{
|
||||
me.NearTeleportTo(MCMiscConst.RagnarosTelePos.GetPositionX(), MCMiscConst.RagnarosTelePos.GetPositionY(), MCMiscConst.RagnarosTelePos.GetPositionZ(), MCMiscConst.RagnarosTelePos.GetOrientation());
|
||||
me.SetNpcFlag(NPCFlags.Gossip);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
|
||||
if (HealthBelowPct(50))
|
||||
DoCast(me, SpellIds.AegisOfRagnaros, new CastSpellExtraArgs(true));
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
public override void DoAction(int action)
|
||||
{
|
||||
if (action == ActionIds.StartRagnaros)
|
||||
{
|
||||
me.RemoveNpcFlag(NPCFlags.Gossip);
|
||||
Talk(TextIds.SaySummonMaj);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
instance.instance.SummonCreature(MCCreatureIds.Ragnaros, MCMiscConst.RagnarosSummonPos);
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(24), task =>
|
||||
{
|
||||
Talk(TextIds.SayArrival2Maj);
|
||||
});
|
||||
}
|
||||
else if (action == ActionIds.StartRagnarosAlt)
|
||||
{
|
||||
me.SetFaction((uint)FactionTemplates.Friendly);
|
||||
me.SetNpcFlag(NPCFlags.Gossip);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnGossipSelect(Player player, uint menuId, uint gossipListId)
|
||||
{
|
||||
if (menuId == TextIds.MenuOptionYouChallengedUs && gossipListId == TextIds.OptionIdYouChallengedUs)
|
||||
{
|
||||
player.CloseGossipMenu();
|
||||
DoAction(ActionIds.StartRagnaros);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* 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.EasternKingdoms.BlackrockMountain.MoltenCore
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint HandOfRagnaros = 19780;
|
||||
public const uint WrathOfRagnaros = 20566;
|
||||
public const uint LavaBurst = 21158;
|
||||
public const uint MagmaBlast = 20565; // Ranged attack
|
||||
public const uint SonsOfFlameDummy = 21108; // Server side effect
|
||||
public const uint Ragsubmerge = 21107; // Stealth aura
|
||||
public const uint Ragemerge = 20568;
|
||||
public const uint MeltWeapon = 21388;
|
||||
public const uint ElementalFire = 20564;
|
||||
public const uint Erruption = 17731;
|
||||
}
|
||||
|
||||
struct TextIds
|
||||
{
|
||||
public const uint SaySummonMaj = 0;
|
||||
public const uint SayArrival1Rag = 1;
|
||||
public const uint SayArrival2Maj = 2;
|
||||
public const uint SayArrival3Rag = 3;
|
||||
public const uint SayArrival5Rag = 4;
|
||||
public const uint SayReinforcements1 = 5;
|
||||
public const uint SayReinforcements2 = 6;
|
||||
public const uint SayHand = 7;
|
||||
public const uint SayWrath = 8;
|
||||
public const uint SayKill = 9;
|
||||
public const uint SayMagmaburst = 10;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint Eruption = 1;
|
||||
public const uint WrathOfRagnaros = 2;
|
||||
public const uint HandOfRagnaros = 3;
|
||||
public const uint LavaBurst = 4;
|
||||
public const uint ElementalFire = 5;
|
||||
public const uint MagmaBlast = 6;
|
||||
public const uint Submerge = 7;
|
||||
|
||||
public const uint Intro1 = 8;
|
||||
public const uint Intro2 = 9;
|
||||
public const uint Intro3 = 10;
|
||||
public const uint Intro4 = 11;
|
||||
public const uint Intro5 = 12;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_ragnaros : BossAI
|
||||
{
|
||||
uint _emergeTimer;
|
||||
byte _introState;
|
||||
bool _hasYelledMagmaBurst;
|
||||
bool _hasSubmergedOnce;
|
||||
bool _isBanished;
|
||||
|
||||
public boss_ragnaros(Creature creature) : base(creature, BossIds.Ragnaros)
|
||||
{
|
||||
Initialize();
|
||||
_introState = 0;
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
me.SetUnitFlag(UnitFlags.NonAttackable);
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_emergeTimer = 90000;
|
||||
_hasYelledMagmaBurst = false;
|
||||
_hasSubmergedOnce = false;
|
||||
_isBanished = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
Initialize();
|
||||
me.SetEmoteState(Emote.OneshotNone);
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
_events.ScheduleEvent(EventIds.Eruption, TimeSpan.FromSeconds(15));
|
||||
_events.ScheduleEvent(EventIds.WrathOfRagnaros, TimeSpan.FromSeconds(30));
|
||||
_events.ScheduleEvent(EventIds.HandOfRagnaros, TimeSpan.FromSeconds(25));
|
||||
_events.ScheduleEvent(EventIds.LavaBurst, TimeSpan.FromSeconds(10));
|
||||
_events.ScheduleEvent(EventIds.ElementalFire, TimeSpan.FromSeconds(3));
|
||||
_events.ScheduleEvent(EventIds.MagmaBlast, TimeSpan.FromSeconds(2));
|
||||
_events.ScheduleEvent(EventIds.Submerge, TimeSpan.FromMinutes(3));
|
||||
}
|
||||
|
||||
public override void KilledUnit(Unit victim)
|
||||
{
|
||||
if (RandomHelper.URand(0, 99) < 25)
|
||||
Talk(TextIds.SayKill);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (_introState != 2)
|
||||
{
|
||||
if (_introState == 0)
|
||||
{
|
||||
me.HandleEmoteCommand(Emote.OneshotEmerge);
|
||||
_events.ScheduleEvent(EventIds.Intro1, TimeSpan.FromSeconds(4));
|
||||
_events.ScheduleEvent(EventIds.Intro2, TimeSpan.FromSeconds(23));
|
||||
_events.ScheduleEvent(EventIds.Intro3, TimeSpan.FromSeconds(42));
|
||||
_events.ScheduleEvent(EventIds.Intro4, TimeSpan.FromSeconds(43));
|
||||
_events.ScheduleEvent(EventIds.Intro5, TimeSpan.FromSeconds(53));
|
||||
_introState = 1;
|
||||
}
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.Intro1:
|
||||
Talk(TextIds.SayArrival1Rag);
|
||||
break;
|
||||
case EventIds.Intro2:
|
||||
Talk(TextIds.SayArrival3Rag);
|
||||
break;
|
||||
case EventIds.Intro3:
|
||||
me.HandleEmoteCommand(Emote.OneshotAttack1h);
|
||||
break;
|
||||
case EventIds.Intro4:
|
||||
Talk(TextIds.SayArrival5Rag);
|
||||
Creature executus = ObjectAccessor.GetCreature(me, instance.GetGuidData(BossIds.MajordomoExecutus));
|
||||
if (executus)
|
||||
Unit.Kill(me, executus);
|
||||
break;
|
||||
case EventIds.Intro5:
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
me.RemoveUnitFlag(UnitFlags.NonAttackable);
|
||||
me.SetImmuneToPC(false);
|
||||
_introState = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isBanished && ((_emergeTimer <= diff) || (instance.GetData(MCMiscConst.DataRagnarosAdds)) > 8))
|
||||
{
|
||||
//Become unbanished again
|
||||
me.SetReactState(ReactStates.Aggressive);
|
||||
me.SetFaction((uint)FactionTemplates.Monster);
|
||||
me.RemoveUnitFlag(UnitFlags.Uninteractible);
|
||||
me.SetEmoteState(Emote.OneshotNone);
|
||||
me.HandleEmoteCommand(Emote.OneshotEmerge);
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target)
|
||||
AttackStart(target);
|
||||
instance.SetData(MCMiscConst.DataRagnarosAdds, 0);
|
||||
|
||||
//DoCast(me, SpellRagemerge); //"phase spells" didnt worked correctly so Ive commented them and wrote solution witch doesnt need core support
|
||||
_isBanished = false;
|
||||
}
|
||||
else if (_isBanished)
|
||||
{
|
||||
_emergeTimer -= diff;
|
||||
//Do nothing while banished
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
_events.ExecuteEvents(eventId =>
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EventIds.Eruption:
|
||||
DoCastVictim(SpellIds.Erruption);
|
||||
_events.ScheduleEvent(EventIds.Eruption, TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(45));
|
||||
break;
|
||||
case EventIds.WrathOfRagnaros:
|
||||
DoCastVictim(SpellIds.WrathOfRagnaros);
|
||||
if (RandomHelper.URand(0, 1) != 0)
|
||||
Talk(TextIds.SayWrath);
|
||||
_events.ScheduleEvent(EventIds.WrathOfRagnaros, TimeSpan.FromSeconds(25));
|
||||
break;
|
||||
case EventIds.HandOfRagnaros:
|
||||
DoCast(me, SpellIds.HandOfRagnaros);
|
||||
if (RandomHelper.URand(0, 1) != 0)
|
||||
Talk(TextIds.SayHand);
|
||||
_events.ScheduleEvent(EventIds.HandOfRagnaros, TimeSpan.FromSeconds(20));
|
||||
break;
|
||||
case EventIds.LavaBurst:
|
||||
DoCastVictim(SpellIds.LavaBurst);
|
||||
_events.ScheduleEvent(EventIds.LavaBurst, TimeSpan.FromSeconds(10));
|
||||
break;
|
||||
case EventIds.ElementalFire:
|
||||
DoCastVictim(SpellIds.ElementalFire);
|
||||
_events.ScheduleEvent(EventIds.ElementalFire, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(14));
|
||||
break;
|
||||
case EventIds.MagmaBlast:
|
||||
if (!me.IsWithinMeleeRange(me.GetVictim()))
|
||||
{
|
||||
DoCastVictim(SpellIds.MagmaBlast);
|
||||
if (!_hasYelledMagmaBurst)
|
||||
{
|
||||
//Say our dialog
|
||||
Talk(TextIds.SayMagmaburst);
|
||||
_hasYelledMagmaBurst = true;
|
||||
}
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.MagmaBlast, TimeSpan.FromMilliseconds(2500));
|
||||
break;
|
||||
case EventIds.Submerge:
|
||||
{
|
||||
if (!_isBanished)
|
||||
{
|
||||
//Creature spawning and ragnaros becomming unattackable
|
||||
//is not very well supported in the core //no it really isnt
|
||||
//so added normaly spawning and banish workaround and attack again after 90 secs.
|
||||
me.AttackStop();
|
||||
ResetThreatList();
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
me.InterruptNonMeleeSpells(false);
|
||||
//Root self
|
||||
//DoCast(me, 23973);
|
||||
me.SetFaction((uint)FactionTemplates.Friendly);
|
||||
me.SetUnitFlag(UnitFlags.Uninteractible);
|
||||
me.SetEmoteState(Emote.StateSubmerged);
|
||||
me.HandleEmoteCommand(Emote.OneshotSubmerge);
|
||||
instance.SetData(MCMiscConst.DataRagnarosAdds, 0);
|
||||
|
||||
if (!_hasSubmergedOnce)
|
||||
{
|
||||
Talk(TextIds.SayReinforcements1);
|
||||
|
||||
// summon 8 elementals
|
||||
for (byte i = 0; i < 8; ++i)
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target != null)
|
||||
{
|
||||
Creature summoned = me.SummonCreature(12143, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), 0.0f, TempSummonType.TimedOrCorpseDespawn, TimeSpan.FromMinutes(15));
|
||||
if (summoned != null)
|
||||
summoned.GetAI().AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
_hasSubmergedOnce = true;
|
||||
_isBanished = true;
|
||||
//DoCast(me, SpellRagsubmerge);
|
||||
_emergeTimer = 90000;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(TextIds.SayReinforcements2);
|
||||
|
||||
for (byte i = 0; i < 8; ++i)
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0);
|
||||
if (target != null)
|
||||
{
|
||||
Creature summoned = me.SummonCreature(12143, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), 0.0f, TempSummonType.TimedOrCorpseDespawn, TimeSpan.FromMinutes(15));
|
||||
if (summoned != null)
|
||||
summoned.GetAI().AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
_isBanished = true;
|
||||
//DoCast(me, SpellRagsubmerge);
|
||||
_emergeTimer = 90000;
|
||||
}
|
||||
}
|
||||
_events.ScheduleEvent(EventIds.Submerge, TimeSpan.FromMinutes(3));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_son_of_flame : ScriptedAI //didnt work correctly in Eai for me...
|
||||
{
|
||||
InstanceScript instance;
|
||||
|
||||
public npc_son_of_flame(Creature creature) : base(creature)
|
||||
{
|
||||
instance = me.GetInstanceScript();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
instance.SetData(MCMiscConst.DataRagnarosAdds, 1);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.BlackrockMountain.MoltenCore.Shazzrah
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
public const uint ArcaneExplosion = 19712;
|
||||
public const uint ShazzrahCurse = 19713;
|
||||
public const uint MagicGrounding = 19714;
|
||||
public const uint Counterspell = 19715;
|
||||
public const uint ShazzrahGateDummy = 23138; // Teleports to and attacks a random target.
|
||||
public const uint ShazzrahGate = 23139;
|
||||
}
|
||||
|
||||
struct EventIds
|
||||
{
|
||||
public const uint ArcaneExplosion = 1;
|
||||
public const uint ArcaneExplosionTriggered = 2;
|
||||
public const uint ShazzrahCurse = 3;
|
||||
public const uint MagicGrounding = 4;
|
||||
public const uint Counterspell = 5;
|
||||
public const uint ShazzrahGate = 6;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_shazzrah : BossAI
|
||||
{
|
||||
public boss_shazzrah(Creature creature) : base(creature, BossIds.Shazzrah) { }
|
||||
|
||||
public override void JustEngagedWith(Unit target)
|
||||
{
|
||||
base.JustEngagedWith(target);
|
||||
_events.ScheduleEvent(EventIds.ArcaneExplosion, TimeSpan.FromSeconds(6));
|
||||
_events.ScheduleEvent(EventIds.ShazzrahCurse, TimeSpan.FromSeconds(10));
|
||||
_events.ScheduleEvent(EventIds.MagicGrounding, TimeSpan.FromSeconds(24));
|
||||
_events.ScheduleEvent(EventIds.Counterspell, TimeSpan.FromSeconds(15));
|
||||
_events.ScheduleEvent(EventIds.ShazzrahGate, TimeSpan.FromSeconds(45));
|
||||
}
|
||||
|
||||
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.ArcaneExplosion:
|
||||
DoCastVictim(SpellIds.ArcaneExplosion);
|
||||
_events.ScheduleEvent(EventIds.ArcaneExplosion, TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(7));
|
||||
break;
|
||||
// Triggered subsequent to using "Gate of Shazzrah".
|
||||
case EventIds.ArcaneExplosionTriggered:
|
||||
DoCastVictim(SpellIds.ArcaneExplosion);
|
||||
break;
|
||||
case EventIds.ShazzrahCurse:
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true, true, -(int)SpellIds.ShazzrahCurse);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.ShazzrahCurse);
|
||||
_events.ScheduleEvent(EventIds.ShazzrahCurse, TimeSpan.FromSeconds(25), TimeSpan.FromSeconds(30));
|
||||
break;
|
||||
case EventIds.MagicGrounding:
|
||||
DoCast(me, SpellIds.MagicGrounding);
|
||||
_events.ScheduleEvent(EventIds.MagicGrounding, TimeSpan.FromSeconds(35));
|
||||
break;
|
||||
case EventIds.Counterspell:
|
||||
DoCastVictim(SpellIds.Counterspell);
|
||||
_events.ScheduleEvent(EventIds.Counterspell, TimeSpan.FromSeconds(16), TimeSpan.FromSeconds(20));
|
||||
break;
|
||||
case EventIds.ShazzrahGate:
|
||||
ResetThreatList();
|
||||
DoCastAOE(SpellIds.ShazzrahGateDummy);
|
||||
_events.ScheduleEvent(EventIds.ArcaneExplosionTriggered, TimeSpan.FromSeconds(2));
|
||||
_events.RescheduleEvent(EventIds.ArcaneExplosion, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6));
|
||||
_events.ScheduleEvent(EventIds.ShazzrahGate, TimeSpan.FromSeconds(45));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.HasUnitState(UnitState.Casting))
|
||||
return;
|
||||
});
|
||||
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 23138 - Gate of Shazzrah
|
||||
class spell_shazzrah_gate_dummy : SpellScript
|
||||
{
|
||||
public override bool Validate(SpellInfo spellInfo)
|
||||
{
|
||||
return ValidateSpellInfo(SpellIds.ShazzrahGate);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
target.CastSpell(GetCaster(), SpellIds.ShazzrahGate, true);
|
||||
Creature creature = GetCaster().ToCreature();
|
||||
if (creature)
|
||||
creature.GetAI().AttackStart(target); // Attack the target which caster will teleport to.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(FilterTargets, 0, Targets.UnitSrcAreaEnemy));
|
||||
OnEffectHitTarget.Add(new EffectHandler(HandleScript, 0, SpellEffectName.Dummy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.AI;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore.Sulfuron
|
||||
{
|
||||
struct SpellIds
|
||||
{
|
||||
// Sulfuron Harbringer
|
||||
public const uint DarkStrike = 19777;
|
||||
public const uint DemoralizingShout = 19778;
|
||||
public const uint Inspire = 19779;
|
||||
public const uint Knockdown = 19780;
|
||||
public const uint Flamespear = 19781;
|
||||
|
||||
// Adds
|
||||
public const uint Heal = 19775;
|
||||
public const uint Shadowwordpain = 19776;
|
||||
public const uint Immolate = 20294;
|
||||
}
|
||||
|
||||
[Script]
|
||||
class boss_sulfuron : BossAI
|
||||
{
|
||||
public boss_sulfuron(Creature creature) : base(creature, BossIds.SulfuronHarbinger) { }
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(10), task =>
|
||||
{
|
||||
DoCast(me, SpellIds.DarkStrike);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(18));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.DemoralizingShout);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(13), task =>
|
||||
{
|
||||
List<Creature> healers = DoFindFriendlyMissingBuff(45.0f, SpellIds.Inspire);
|
||||
if (!healers.Empty())
|
||||
DoCast(healers.SelectRandom(), SpellIds.Inspire);
|
||||
|
||||
DoCast(me, SpellIds.Inspire);
|
||||
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(26));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
|
||||
{
|
||||
DoCastVictim(SpellIds.Knockdown);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(15));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Flamespear);
|
||||
task.Repeat(TimeSpan.FromSeconds(12), TimeSpan.FromSeconds(16));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
|
||||
[Script]
|
||||
class npc_flamewaker_priest : ScriptedAI
|
||||
{
|
||||
public npc_flamewaker_priest(Creature creature) : base(creature)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void JustDied(Unit killer)
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
{
|
||||
base.JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30), task =>
|
||||
{
|
||||
Unit target = DoSelectLowestHpFriendly(60.0f, 1);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Heal);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true, true, -(int)SpellIds.Shadowwordpain);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Shadowwordpain);
|
||||
task.Repeat(TimeSpan.FromSeconds(18), TimeSpan.FromSeconds(26));
|
||||
});
|
||||
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
|
||||
{
|
||||
Unit target = SelectTarget(SelectTargetMethod.Random, 0, 0.0f, true, true, -(int)SpellIds.Immolate);
|
||||
if (target)
|
||||
DoCast(target, SpellIds.Immolate);
|
||||
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(25));
|
||||
});
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, () => DoMeleeAttackIfReady());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user