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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user