Tombe de Sargeras : module complet 9/9 boss porte depuis DestinyCoreNew (mudyx)
AVANT : 4 boss etaient des coquilles vides de 28-33 lignes (Hote affige, Jeune fille de vigilance, Sassz ine, KIL JAEDEN le boss final) et AUCUN boss n etait binde en DB (ScriptName vides sauf Goroth) -> le raid entier etait decoratif malgre 978 spawns. APRES : module lignee uwow complet (12 161 lignes, 12 fichiers) transcrit vers nos APIs en 7 passes de compatibilite (~880 erreurs de compilation resorbees) : instance script complet (portes, frames, graveyards), 9 encounters scriptes, trash/evenements, 74 bindings de sorts, ~60 ScriptName de creatures, ATs. Ajouts CORE reutilisables (compat DestinyCoreNew, prepareront le futur port Antorus) : - UnitAI : DoCastTopAggro, GetObjectData, hooks no-op (SpellFinishCast, OnApplyOrRemoveAura, OnRemoveAuraTarget, OnAreaTriggerDespawn/Cast, OnInterruptCast, IsDisableGenerateLoot, GetModifyedData) - CreatureAI : Talk(guid), Talk(liste aleatoire), ZoneTalk - ScriptedAI : CheckHomeDistToEvade + alias IsHeroicRaid/IsMythicRaid/IsLfrRaid/ IsNormalRaid/IsHeroicPlusRaid ; SummonList::GetCreature - Unit : GetAnyOwner, CastSpellDelay x2 ; Creature : SetReactState(delay), StopAttack - Map : ApplyOnEveryPlayer, IsHeroicPlusRaid ; GameObject : AddDelayedEvent (m_Events) - Position : SimplePosXYRelocationByAngle, GenerateNonDuplicatePoints, IsLinesCross (reecrit sans G3D::LineSegment2D, absent de notre g3dlite) - MotionMaster : MoveSmoothFlyPath x2 ; AreaTrigger : GetRadius/SetSphereScale(no-op)/ isMoving/Despawn/GetProgressCompat ; AreaTriggerAI : IsValidTarget/CalculateSpline Degradations douces assumees (documentees en commentaire dans le code) : filtrage de cibles des ATs (IsValidTarget jamais appele par notre moteur), scale dynamique des zones de Kil jaeden, conversations cinematiques, distribution de loot personnelle, hooks d interruption/notification d aura, quelques approximations de roles (SoloQ->ROLE_TANK) et de type de degats. SQL : sql/sylvania/tomb_of_sargeras_bindings.sql (applique en DB). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,21 @@
|
||||
class AreaTrigger;
|
||||
class Unit;
|
||||
|
||||
|
||||
// Moments d action des areatriggers (compat scripts DestinyCoreNew ; notre moteur
|
||||
// n appelle PAS IsValidTarget : le filtrage de cibles de ces scripts est inactif)
|
||||
enum AreaTriggerActionMoment
|
||||
{
|
||||
AT_ACTION_MOMENT_ENTER = 0x0001,
|
||||
AT_ACTION_MOMENT_LEAVE = 0x0002,
|
||||
AT_ACTION_MOMENT_UPDATE_TARGET = 0x0004,
|
||||
AT_ACTION_MOMENT_DESPAWN = 0x0008,
|
||||
AT_ACTION_MOMENT_SPAWN = 0x0010,
|
||||
AT_ACTION_MOMENT_REMOVE = 0x0020,
|
||||
AT_ACTION_MOMENT_ON_THE_WAY = 0x0040,
|
||||
AT_ACTION_MOMENT_ON_STOP_MOVE = 0x0080,
|
||||
};
|
||||
|
||||
class TC_GAME_API AreaTriggerAI
|
||||
{
|
||||
protected:
|
||||
@@ -63,6 +78,8 @@ class TC_GAME_API AreaTriggerAI
|
||||
|
||||
// Called when the AreaTrigger is update target
|
||||
virtual void ActionOnUpdate(GuidList& affectedPlayers) {}
|
||||
virtual bool IsValidTarget(Unit* /*caster*/, Unit* /*target*/, AreaTriggerActionMoment /*actionM*/) { return true; }
|
||||
virtual bool CalculateSpline(Position const* /*pos*/, Position& /*startPos*/, Position& /*endPos*/, std::vector<Position>& /*path*/) { return false; }
|
||||
};
|
||||
|
||||
class NullAreaTriggerAI : public AreaTriggerAI
|
||||
|
||||
@@ -194,6 +194,12 @@ void UnitAI::DoCastVictim(uint32 spellId, bool triggered)
|
||||
me->CastSpell(me->GetVictim(), spellId, triggered);
|
||||
}
|
||||
|
||||
void UnitAI::DoCastTopAggro(uint32 spellId, bool triggered, bool onlyPlayer /*= true*/)
|
||||
{
|
||||
if (Unit* victim = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 100.0f, onlyPlayer))
|
||||
me->CastSpell(victim, spellId, triggered);
|
||||
}
|
||||
|
||||
void UnitAI::DoCastAOE(uint32 spellId, bool triggered)
|
||||
{
|
||||
if (!triggered && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "EventMap.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ThreatManager.h"
|
||||
#include "SpellAuraDefines.h"
|
||||
|
||||
#define CAST_AI(a, b) (dynamic_cast<a*>(b))
|
||||
#define ENSURE_AI(a,b) (EnsureAI<a>(b))
|
||||
@@ -224,6 +225,17 @@ class TC_GAME_API UnitAI
|
||||
// Note: it for recalculation damage or special reaction at damage
|
||||
// for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
|
||||
virtual void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { }
|
||||
// Hook generique guid->bool utilise par les scripts portes de DestinyCoreNew (uwow)
|
||||
virtual bool GetObjectData(ObjectGuid const& /*guid*/, uint32 /*type*/) { return false; }
|
||||
// Hooks de notification uwow : notre moteur ne les appelle pas (code mort tolere)
|
||||
virtual void SpellFinishCast(SpellInfo const* /*spell*/) { }
|
||||
virtual void OnApplyOrRemoveAura(uint32 /*spellId*/, AuraRemoveMode /*mode*/, bool /*apply*/) { }
|
||||
virtual void OnRemoveAuraTarget(Unit* /*target*/, uint32 /*spellId*/, AuraRemoveMode /*mode*/) { }
|
||||
virtual bool IsDisableGenerateLoot() { return false; }
|
||||
virtual uint32 GetModifyedData(uint32 /*type*/) { return 0; }
|
||||
virtual void OnAreaTriggerDespawn(uint32 /*spellId*/, Position /*pos*/, bool /*duration*/) { }
|
||||
virtual void OnAreaTriggerCast(Unit* /*caster*/, Unit* /*target*/, uint32 /*spellId*/, uint32 /*atEntry*/) { }
|
||||
virtual void OnInterruptCast(Unit* /*caster*/, uint32 /*spellId*/, uint32 /*curSpellID*/, uint32 /*schoolMask*/) { }
|
||||
|
||||
// Called when the creature receives heal
|
||||
virtual void HealReceived(Unit* /*done_by*/, uint32& /*addhealth*/) { }
|
||||
@@ -242,6 +254,7 @@ class TC_GAME_API UnitAI
|
||||
void DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false);
|
||||
void DoCastSelf(uint32 spellId, bool triggered = false) { DoCast(me, spellId, triggered); }
|
||||
void DoCastVictim(uint32 spellId, bool triggered = false);
|
||||
void DoCastTopAggro(uint32 spellId, bool triggered = false, bool onlyPlayer = true);
|
||||
void DoCastAOE(uint32 spellId, bool triggered = false);
|
||||
void DoCastRandom(uint32 spellId, float dist, bool triggered = false, int32 aura = 0, uint32 position = 0);
|
||||
|
||||
|
||||
@@ -439,3 +439,24 @@ void CreatureAI::SetFlyMode(bool fly)
|
||||
else
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
}
|
||||
|
||||
void CreatureAI::Talk(uint8 id, ObjectGuid whisperGuid)
|
||||
{
|
||||
WorldObject const* target = nullptr;
|
||||
if (!whisperGuid.IsEmpty())
|
||||
target = ObjectAccessor::GetUnit(*me, whisperGuid);
|
||||
Talk(id, target);
|
||||
}
|
||||
|
||||
void CreatureAI::Talk(std::initializer_list<uint8> ids, ObjectGuid whisperGuid /*= ObjectGuid::Empty*/)
|
||||
{
|
||||
if (ids.size() == 0)
|
||||
return;
|
||||
uint8 id = *(ids.begin() + urand(0, uint32(ids.size()) - 1));
|
||||
Talk(id, whisperGuid);
|
||||
}
|
||||
|
||||
void CreatureAI::ZoneTalk(uint8 id)
|
||||
{
|
||||
sCreatureTextMgr->SendChat(me, id, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define CREATUREAI_H
|
||||
|
||||
#include "UnitAI.h"
|
||||
#include <initializer_list>
|
||||
#include "Common.h"
|
||||
#include "ObjectDefines.h"
|
||||
|
||||
@@ -100,6 +101,9 @@ class TC_GAME_API CreatureAI : public UnitAI
|
||||
virtual ~CreatureAI();
|
||||
|
||||
void Talk(uint8 id, WorldObject const* whisperTarget = nullptr);
|
||||
void Talk(uint8 id, ObjectGuid whisperGuid); // compat DestinyCoreNew
|
||||
void ZoneTalk(uint8 id); // texte a toute la zone
|
||||
void Talk(std::initializer_list<uint8> ids, ObjectGuid whisperGuid = ObjectGuid::Empty); // choix aleatoire
|
||||
|
||||
void AddDelayedEvent(uint64 timeOffset, std::function<void()>&& function);
|
||||
void KillAllDelayedEvents();
|
||||
|
||||
@@ -1641,3 +1641,48 @@ void ScriptedAI::GetTalkData(uint32 eventId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ScriptedAI::CheckHomeDistToEvade(uint32 diff, float dist, float x, float y, float z, bool onlyZ)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
return false;
|
||||
|
||||
bool evade = false;
|
||||
|
||||
if (_checkHomeTimer <= diff)
|
||||
{
|
||||
_checkHomeTimer = 1500;
|
||||
|
||||
if (onlyZ)
|
||||
{
|
||||
if ((me->GetPositionZ() > z + dist) || (me->GetPositionZ() < z - dist))
|
||||
evade = true;
|
||||
}
|
||||
else if (x != 0.0f || y != 0.0f || z != 0.0f)
|
||||
{
|
||||
if (me->GetDistance(x, y, z) >= dist)
|
||||
evade = true;
|
||||
}
|
||||
else if (me->GetDistance(me->GetHomePosition()) >= dist)
|
||||
evade = true;
|
||||
|
||||
if (evade)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
_checkHomeTimer -= diff;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* SummonList::GetCreature(uint32 entry)
|
||||
{
|
||||
for (auto const& guid : *this)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
|
||||
if (summon->GetEntry() == entry)
|
||||
return summon;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
|
||||
void Summon(Creature const* summon);
|
||||
void Despawn(Creature const* summon);
|
||||
Creature* GetCreature(uint32 entry);
|
||||
void DespawnEntry(uint32 entry);
|
||||
void DespawnAll();
|
||||
|
||||
@@ -347,6 +348,14 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
// - for raid in mode 25-heroic
|
||||
// DO NOT USE to check raid in mode 25-normal.
|
||||
bool IsHeroic() const { return _isHeroic; }
|
||||
bool IsHeroicRaid() const { return IsHeroic(); }
|
||||
bool IsHeroicPlusRaid() const { return IsHeroic() || me->GetMap()->IsMythic(); }
|
||||
bool IsMythicRaid() const { return me->GetMap()->IsMythic(); }
|
||||
bool IsLfrRaid() const { return _difficulty == DIFFICULTY_LFR || _difficulty == DIFFICULTY_LFR_NEW; }
|
||||
bool IsNormalRaid() const { return _difficulty == DIFFICULTY_NORMAL_RAID; }
|
||||
// Evade si trop loin du point d ancrage (helper des scripts portes de DestinyCoreNew)
|
||||
bool CheckHomeDistToEvade(uint32 diff, float dist = 0.0f, float x = 0.0f, float y = 0.0f, float z = 0.0f, bool onlyZ = false);
|
||||
uint32 _checkHomeTimer = 1500;
|
||||
|
||||
// return the dungeon or raid difficulty
|
||||
Difficulty GetDifficulty() const { return _difficulty; }
|
||||
|
||||
@@ -1001,3 +1001,10 @@ void AreaTrigger::AI_Destroy()
|
||||
{
|
||||
_ai.reset();
|
||||
}
|
||||
|
||||
float AreaTrigger::GetRadius() const
|
||||
{
|
||||
if (AreaTriggerTemplate const* t = GetTemplate())
|
||||
return t->MaxSearchRadius;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge
|
||||
|
||||
AreaTriggerMiscTemplate const* GetMiscTemplate() const { return _areaTriggerMiscTemplate; }
|
||||
AreaTriggerTemplate const* GetTemplate() const;
|
||||
// compat DestinyCoreNew : rayon courant approxime par le rayon du template ;
|
||||
// l animation de scale dynamique n est pas supportee par notre moteur (no-op)
|
||||
float GetRadius() const;
|
||||
void SetSphereScale(float /*scale*/, uint32 /*time*/ = 0, bool /*grow*/ = false) { }
|
||||
bool isMoving() const { return false; } // compat : pas de suivi spline expose
|
||||
void Despawn() { Remove(); }
|
||||
float GetProgressCompat() const { return GetProgress(); }
|
||||
ObjectGuid::LowType GetSpawnId() const { return _spawnId; }
|
||||
uint32 GetScriptId() const;
|
||||
|
||||
|
||||
@@ -3327,3 +3327,23 @@ void Creature::ReLoad(bool skipDB)
|
||||
|
||||
TC_LOG_DEBUG("sql.sql", "Creature SpawnID (" SI64FMTD ") reloaded.", GetSpawnId());
|
||||
}
|
||||
|
||||
void Creature::SetReactState(ReactStates st, uint32 delay)
|
||||
{
|
||||
if (!delay)
|
||||
{
|
||||
SetReactState(st);
|
||||
return;
|
||||
}
|
||||
AddDelayedEvent(delay, [this, st]() -> void { SetReactState(st); });
|
||||
}
|
||||
|
||||
void Creature::StopAttack(bool clearMove /*= false*/, bool interruptSpells /*= false*/)
|
||||
{
|
||||
SetReactState(REACT_PASSIVE);
|
||||
AttackStop();
|
||||
if (clearMove)
|
||||
GetMotionMaster()->Clear();
|
||||
if (interruptSpells)
|
||||
InterruptNonMeleeSpells(false);
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool CanFly() const override { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; }
|
||||
|
||||
void SetReactState(ReactStates st) { m_reactState = st; }
|
||||
void SetReactState(ReactStates st, uint32 delay); // variante differee (compat DestinyCoreNew)
|
||||
void StopAttack(bool clearMove = false, bool interruptSpells = false);
|
||||
ReactStates GetReactState() const { return m_reactState; }
|
||||
bool HasReactState(ReactStates state) const { return (m_reactState == state); }
|
||||
void InitializeReactState();
|
||||
|
||||
@@ -300,6 +300,18 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
|
||||
/// Event handler
|
||||
EventProcessor m_Events;
|
||||
// compat DestinyCoreNew : evenement differe via m_Events (mis a jour dans GameObject::Update)
|
||||
void AddDelayedEvent(uint64 timeOffset, std::function<void()>&& function)
|
||||
{
|
||||
class LambdaEvent : public BasicEvent
|
||||
{
|
||||
std::function<void()> _fn;
|
||||
public:
|
||||
explicit LambdaEvent(std::function<void()>&& fn) : _fn(std::move(fn)) { }
|
||||
bool Execute(uint64, uint32) override { _fn(); return true; }
|
||||
};
|
||||
m_Events.AddEvent(new LambdaEvent(std::move(function)), m_Events.CalculateTime(timeOffset));
|
||||
}
|
||||
|
||||
uint32 GetWorldEffectID() const { return _worldEffectID; }
|
||||
void SetWorldEffectID(uint32 worldEffectID) { _worldEffectID = worldEffectID; }
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "Position.h"
|
||||
#include <cmath>
|
||||
#include "ByteBuffer.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Random.h"
|
||||
@@ -279,3 +280,73 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::Packed
|
||||
buf.appendPackXYZ(streamer.Pos->GetPositionX(), streamer.Pos->GetPositionY(), streamer.Pos->GetPositionZ());
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Position::SimplePosXYRelocationByAngle(Position& pos, float dist, float angle, bool relative /*= false*/) const
|
||||
{
|
||||
if (!relative)
|
||||
angle += GetOrientation();
|
||||
|
||||
pos.m_positionX = m_positionX + dist * std::cos(angle);
|
||||
pos.m_positionY = m_positionY + dist * std::sin(angle);
|
||||
pos.m_positionZ = m_positionZ;
|
||||
|
||||
if (!Trinity::IsValidMapCoord(pos.m_positionX, pos.m_positionY))
|
||||
{
|
||||
pos.Relocate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
Trinity::NormalizeMapCoord(pos.m_positionX);
|
||||
Trinity::NormalizeMapCoord(pos.m_positionY);
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
void Position::GenerateNonDuplicatePoints(std::list<Position>& randPosList, Position const& centerPos, uint8 maxPoint, float randMin, float randMax, float minDist) const
|
||||
{
|
||||
Position pos;
|
||||
uint8 traiCount = 0;
|
||||
|
||||
while (randPosList.size() < maxPoint)
|
||||
{
|
||||
bool badPos = false;
|
||||
centerPos.SimplePosXYRelocationByAngle(pos, frand(randMin, randMax), frand(0.0f, 6.28f));
|
||||
++traiCount;
|
||||
|
||||
for (auto const& _pos : randPosList)
|
||||
{
|
||||
if (pos.GetExactDist(&_pos) <= minDist)
|
||||
{
|
||||
badPos = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!badPos || traiCount > uint8(maxPoint * 10))
|
||||
randPosList.push_back(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool Position::IsLinesCross(Position const& pos11, Position const& pos12, Position const& pos21, Position const& pos22, Position* dest /*= nullptr*/) const
|
||||
{
|
||||
// intersection parametrique de deux segments 2D (sans G3D::LineSegment2D, absent de notre g3dlite)
|
||||
float x1 = pos11.GetPositionX(), y1 = pos11.GetPositionY();
|
||||
float x2 = pos12.GetPositionX(), y2 = pos12.GetPositionY();
|
||||
float x3 = pos21.GetPositionX(), y3 = pos21.GetPositionY();
|
||||
float x4 = pos22.GetPositionX(), y4 = pos22.GetPositionY();
|
||||
|
||||
float denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
||||
if (std::fabs(denom) < 1e-6f)
|
||||
return false; // paralleles ou colineaires
|
||||
|
||||
float t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
|
||||
float u = ((x1 - x3) * (y1 - y2) - (y1 - y3) * (x1 - x2)) / denom;
|
||||
if (t < 0.0f || t > 1.0f || u < 0.0f || u > 1.0f)
|
||||
return false; // intersection hors des segments
|
||||
|
||||
if (dest)
|
||||
{
|
||||
dest->m_positionX = x1 + t * (x2 - x1);
|
||||
dest->m_positionY = y1 + t * (y2 - y1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define Trinity_game_Position_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <G3D/Vector3.h>
|
||||
@@ -103,6 +104,9 @@ public:
|
||||
float GetPositionY() const { return m_positionY; }
|
||||
float GetPositionZ() const { return m_positionZ; }
|
||||
float GetOrientation() const { return m_orientation; }
|
||||
void SimplePosXYRelocationByAngle(Position& pos, float dist, float angle, bool relative = false) const;
|
||||
void GenerateNonDuplicatePoints(std::list<Position>& randPosList, Position const& centerPos, uint8 maxPoint, float randMin, float randMax, float minDist) const;
|
||||
bool IsLinesCross(Position const& pos11, Position const& pos12, Position const& pos21, Position const& pos22, Position* dest = nullptr) const;
|
||||
|
||||
void GetPosition(float &x, float &y) const
|
||||
{
|
||||
|
||||
@@ -15214,3 +15214,45 @@ void Unit::EmoteWithDelay(uint32 Delay, uint8 Id)
|
||||
|
||||
m_Events.AddEvent(new EmoteWithDelay(this, Id, Delay), m_Events.CalculateTime(Delay));
|
||||
}
|
||||
|
||||
void Unit::CastSpellDelay(Unit* victim, uint32 spellId, bool triggered, uint32 delay, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster)
|
||||
{
|
||||
if (m_cleanupDone)
|
||||
return;
|
||||
|
||||
ObjectGuid targetGUID = victim->GetGUID();
|
||||
AddDelayedCombat(delay, [this, spellId, triggered, castItem, triggeredByAura, originalCaster, targetGUID]() -> void
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*this, targetGUID);
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
CastSpell(target, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
|
||||
});
|
||||
}
|
||||
|
||||
void Unit::CastSpellDelay(Position pos, uint32 spellId, bool triggered, uint32 delay)
|
||||
{
|
||||
if (m_cleanupDone)
|
||||
return;
|
||||
|
||||
if (!delay)
|
||||
CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), spellId, triggered);
|
||||
else
|
||||
AddDelayedCombat(delay, [this, pos, spellId, triggered]() -> void
|
||||
{
|
||||
CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), spellId, triggered);
|
||||
});
|
||||
}
|
||||
|
||||
Unit* Unit::GetAnyOwner() const
|
||||
{
|
||||
if (GetCharmerGUID())
|
||||
return GetCharmer();
|
||||
if (ToTempSummon())
|
||||
return ToTempSummon()->GetSummoner();
|
||||
if (GetOwner())
|
||||
return GetOwner();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1426,6 +1426,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
BrawlersGuild* GetBrawlerGuild();
|
||||
|
||||
Unit* GetOwner() const;
|
||||
Unit* GetAnyOwner() const; // charmeur > summoner > owner (compat DestinyCoreNew)
|
||||
Guardian* GetGuardianPet() const;
|
||||
Minion* GetFirstMinion() const;
|
||||
Unit* GetCharmer() const;
|
||||
@@ -1702,6 +1703,9 @@ class TC_GAME_API Unit : public WorldObject
|
||||
m_Functions.KillAllFunctions();
|
||||
}
|
||||
|
||||
// Cast differe (helpers des scripts portes de DestinyCoreNew)
|
||||
void CastSpellDelay(Unit* victim, uint32 spellId, bool triggered, uint32 delay, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty);
|
||||
void CastSpellDelay(Position pos, uint32 spellId, bool triggered, uint32 delay);
|
||||
void AddDelayedCombat(uint64 timeOffset, std::function<void()>&& function)
|
||||
{
|
||||
m_CombatFunctions.AddDelayedEvent(timeOffset, std::move(function));
|
||||
|
||||
@@ -4702,3 +4702,15 @@ void Map::UpdateAreaDependentAuras()
|
||||
if (player->IsInWorld())
|
||||
player->UpdateAreaDependentAuras();
|
||||
}
|
||||
|
||||
void Map::ApplyOnEveryPlayer(std::function<void(Player*)> function)
|
||||
{
|
||||
auto const& players = GetPlayers();
|
||||
if (players.isEmpty())
|
||||
return;
|
||||
|
||||
for (auto const& itr : players)
|
||||
if (Player* player = itr.GetSource())
|
||||
if (player->IsInWorld() && player->GetMap() == this)
|
||||
function(player);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <bitset>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
@@ -416,6 +417,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
bool IsMythic() const;
|
||||
bool Is25ManRaid() const;
|
||||
bool IsLFR() const;
|
||||
bool IsHeroicPlusRaid() const { return IsHeroic() || IsMythic(); }
|
||||
bool IsChallengeMode() const;
|
||||
bool IsBattleground() const;
|
||||
bool IsBattleArena() const;
|
||||
@@ -443,6 +445,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
|
||||
typedef MapRefManager PlayerList;
|
||||
PlayerList const& GetPlayers() const { return m_mapRefManager; }
|
||||
void ApplyOnEveryPlayer(std::function<void(Player*)> function);
|
||||
|
||||
//per-map script storage
|
||||
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
|
||||
|
||||
@@ -942,3 +942,28 @@ void MotionMaster::DelayedDelete(MovementGenerator* curr)
|
||||
_expireList = new ExpireList();
|
||||
_expireList->push_back(curr);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveSmoothFlyPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize)
|
||||
{
|
||||
Movement::MoveSplineInit init(_owner);
|
||||
init.SetSmooth();
|
||||
init.SetFly();
|
||||
init.SetUncompressed();
|
||||
Movement::PointsArray path(pathPoints, pathPoints + pathSize);
|
||||
init.MovebyPath(path);
|
||||
init.Launch();
|
||||
Mutate(new EffectMovementGenerator(pointId), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveSmoothFlyPath(uint32 pointId, Position const position, float flightSpeed /*= 0.0f*/)
|
||||
{
|
||||
Movement::MoveSplineInit init(_owner);
|
||||
init.SetSmooth();
|
||||
init.SetFly();
|
||||
init.SetUncompressed();
|
||||
init.MoveTo(position.m_positionX, position.m_positionY, position.m_positionZ, false, false);
|
||||
if (flightSpeed > 0.0f)
|
||||
init.SetVelocity(flightSpeed);
|
||||
init.Launch();
|
||||
Mutate(new EffectMovementGenerator(pointId), MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
|
||||
@@ -180,6 +180,8 @@ class TC_GAME_API MotionMaster
|
||||
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount);
|
||||
void MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk = false, bool fly = false);
|
||||
void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk);
|
||||
void MoveSmoothFlyPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize);
|
||||
void MoveSmoothFlyPath(uint32 pointId, Position const position, float flightSpeed = 0.0f);
|
||||
void MoveSmoothPath(uint32 pointId, Movement::PointsArray const& points, bool walk);
|
||||
// Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints)
|
||||
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk);
|
||||
|
||||
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
https://uwow.biz/
|
||||
|
||||
To-DO: Conversation 5002/5003 when near. Now it don't work =C
|
||||
*/
|
||||
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
|
||||
// 116689
|
||||
SPELL_BONE_SCYTHE = 233423, // aura
|
||||
SPELL_SCYTHE_SWEEP = 233426,
|
||||
|
||||
SPELL_BONE_SAW = 233441, // 100% energy
|
||||
SPELL_BONE_SAW_ENERGY = 234550, // proc
|
||||
|
||||
|
||||
SPELL_DEBUFF_OVERRIDE = 233103, // 233652
|
||||
SPELL_DEBUFF_OVER_AURA = 233104,
|
||||
SPELL_DEBUFF_OVER_AURA1 = 234364,
|
||||
SPELL_DEBUFF_UNBEAR_TOR = 233430,
|
||||
|
||||
// not normal
|
||||
SPELL_CALCIFIED_QUILS = 233431, // 233432(233435)
|
||||
|
||||
// 116691
|
||||
SPELL_GET_ENERGY = 246454,
|
||||
SPELL_ECHOING_ANGUISH = 233983, // 22
|
||||
SPELL_FEL_SQUAL = 235230, // 100%
|
||||
SPELL_FEL_SQUAL_ENERGY = 235237,
|
||||
|
||||
SPELL_TORMENTING_BURST = 234015, // 17
|
||||
SPELL_PANGS_OF_GUILT = 239401, // 10
|
||||
|
||||
// not normal
|
||||
SPELL_SUFFOCATING_DARK = 233894, // 24
|
||||
|
||||
SPELL_AOE_SILENCE = 250306, // ????
|
||||
SPELL_REGENERATE_ENERGY = 246455,
|
||||
SPELL_ENRAGE = 248671, // 720 secs
|
||||
|
||||
SPELL_BELAC_PRISONER = 236283,
|
||||
SPELL_SOUL_CORRUPTION = 248713,
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_SCYTHE_SWEEP = 1,
|
||||
EVENT_CALCIFIED_QUILS,
|
||||
|
||||
EVENT_ECHOING_ANGUISH,
|
||||
EVENT_PANGS_OF_GUILT,
|
||||
EVENT_TORMENTING_BURST,
|
||||
EVENT_SUFFOCATING_DARK,
|
||||
|
||||
EVENT_CHECK_ENERGY,
|
||||
EVENT_ENRAGE,
|
||||
EVENT_SUMMON_ADD,
|
||||
};
|
||||
|
||||
std::map<uint32, uint32> hitSpells
|
||||
{
|
||||
{ SPELL_BONE_SAW , SPELL_BONE_SAW_ENERGY},
|
||||
{ SPELL_FEL_SQUAL , SPELL_FEL_SQUAL_ENERGY}
|
||||
};
|
||||
|
||||
// 116689, 116691
|
||||
class boss_demonic_inquisition : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_demonic_inquisition() : CreatureScript("boss_demonic_inquisition") {}
|
||||
|
||||
struct boss_demonic_inquisitionAI : BossAI
|
||||
{
|
||||
boss_demonic_inquisitionAI(Creature* creature) : BossAI(creature, DATA_DEMONIC_INQUISITION)
|
||||
{
|
||||
if (me->GetEntry() == NPC_BELAK)
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
std::unordered_map<ObjectGuid, std::array<bool, 2>> calcifiedQuilsTargets{};
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->IsAlive())
|
||||
_Reset();
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_DEBUFF_OVERRIDE);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DEBUFF_OVER_AURA);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DEBUFF_OVER_AURA1);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ECHOING_ANGUISH);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BELAC_PRISONER);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SOUL_CORRUPTION);
|
||||
me->KillAllDelayedEvents();
|
||||
me->RemoveAllAreaTriggers();
|
||||
|
||||
if (me->IsAlive())
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DEBUFF_UNBEAR_TOR);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
_EnterCombat();
|
||||
events.Reset();
|
||||
|
||||
me->SetPower(me->GetPowerType(), 0);
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_ATRIGAN:
|
||||
DoCast(me, SPELL_DEBUFF_OVERRIDE);
|
||||
events.RescheduleEvent(EVENT_SCYTHE_SWEEP, 5200);
|
||||
if (IsHeroicRaid() || IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_CALCIFIED_QUILS, 8500);
|
||||
Talk(0);
|
||||
events.RescheduleEvent(EVENT_SUMMON_ADD, 1000);
|
||||
break;
|
||||
case NPC_BELAK:
|
||||
DoCast(me, SPELL_GET_ENERGY);
|
||||
events.RescheduleEvent(EVENT_PANGS_OF_GUILT, 100);
|
||||
events.RescheduleEvent(EVENT_ECHOING_ANGUISH, 5000);
|
||||
events.RescheduleEvent(EVENT_TORMENTING_BURST, 9000);
|
||||
if (IsHeroicRaid() || IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_SUFFOCATING_DARK, 10000);
|
||||
me->AddDelayedEvent(6500, [this]() -> void
|
||||
{
|
||||
Talk(0);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
DoCast(me, SPELL_REGENERATE_ENERGY);
|
||||
events.RescheduleEvent(EVENT_CHECK_ENERGY, 100); // both
|
||||
|
||||
if (!IsLfrRaid())
|
||||
events.RescheduleEvent(EVENT_ENRAGE, 720000);
|
||||
|
||||
if (Creature* other = instance->instance->GetCreature(instance->GetGuidData(me->GetEntry() == NPC_BELAK ? NPC_ATRIGAN : NPC_BELAK)))
|
||||
{
|
||||
other->AddDelayedEvent(100, [other,who]() -> void
|
||||
{
|
||||
if (who)
|
||||
if(!other->IsInCombat())
|
||||
other->AI()->EnterCombat(who);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
Reset();
|
||||
me->NearTeleportTo(me->GetHomePosition());
|
||||
|
||||
if (Creature* other = instance->instance->GetCreature(instance->GetGuidData(me->GetEntry() == NPC_BELAK ? NPC_ATRIGAN : NPC_BELAK)))
|
||||
{
|
||||
other->AddDelayedEvent(100, [other]() -> void
|
||||
{
|
||||
if (other->IsInCombat())
|
||||
other->AI()->EnterEvadeMode();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage) override
|
||||
{
|
||||
if (attacker == me)
|
||||
return;
|
||||
|
||||
if (Creature* other = instance->instance->GetCreature(instance->GetGuidData(me->GetEntry() == NPC_BELAK ? NPC_ATRIGAN : NPC_BELAK)))
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
other->Kill(other, true);
|
||||
else
|
||||
other->DealDamage(other, damage);
|
||||
}
|
||||
|
||||
// approximation : notre DamageTaken n expose pas le type de degats,
|
||||
// le renvoi d epines se declenche donc sur tout degat (l original excluait DoT/split)
|
||||
|
||||
for (const auto& pair : hitSpells)
|
||||
if (me->HasAura(pair.first))
|
||||
attacker->CastSpell(attacker, pair.second, true);
|
||||
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
//Talk(SAY_DEATH);
|
||||
if (me->GetEntry() == NPC_ATRIGAN)
|
||||
DoCast(240053);
|
||||
|
||||
_JustDied();
|
||||
|
||||
if (me->GetEntry() == NPC_ATRIGAN)
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->HasAura(SPELL_DEBUFF_UNBEAR_TOR))
|
||||
{
|
||||
instance->DoUpdateAchievementCriteria(CRITERIA_TYPE_BE_SPELL_TARGET, 243355);
|
||||
break;
|
||||
}
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DEBUFF_UNBEAR_TOR);
|
||||
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool GetObjectData(ObjectGuid const& guid, uint32 type) override
|
||||
{
|
||||
if (calcifiedQuilsTargets[guid][type])
|
||||
return true;
|
||||
|
||||
calcifiedQuilsTargets[guid][type] = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (CheckHomeDistToEvade(diff, 50.0f))
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_CALCIFIED_QUILS) || me->HasAura(SPELL_BONE_SAW) || me->HasAura(SPELL_FEL_SQUAL))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SCYTHE_SWEEP:
|
||||
DoCast(SPELL_SCYTHE_SWEEP);
|
||||
events.RescheduleEvent(EVENT_SCYTHE_SWEEP, 24500);
|
||||
break;
|
||||
case EVENT_CHECK_ENERGY:
|
||||
if (me->GetPower(me->GetPowerType()) >= 100)
|
||||
{
|
||||
DoCast(me->GetEntry() == NPC_ATRIGAN ? SPELL_BONE_SAW : SPELL_FEL_SQUAL);
|
||||
Talk(1);
|
||||
}
|
||||
|
||||
events.RescheduleEvent(EVENT_CHECK_ENERGY, 100);
|
||||
break;
|
||||
case EVENT_CALCIFIED_QUILS:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
|
||||
{
|
||||
calcifiedQuilsTargets.clear();
|
||||
|
||||
DoCast(target, SPELL_CALCIFIED_QUILS);
|
||||
me->AddDelayedEvent(5000, [this, target]()
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
Position pos = target->GetPosition();
|
||||
float diff_x = pos.GetPositionX() - me->GetPositionX();
|
||||
float diff_y = pos.GetPositionY() - me->GetPositionY();
|
||||
float dist = sqrt(diff_x * diff_x + diff_y * diff_y);
|
||||
for (float mod = 2 / dist, time = 0; mod < 60.0f / dist; mod += (2 / dist), time++)
|
||||
{
|
||||
for (float i = -0.5f; i <= 0.5f; i += 0.2f)
|
||||
{
|
||||
if (urand(1, 5) == 5)
|
||||
continue;
|
||||
|
||||
float new_x = mod*diff_x*sqrt(3) / 2 - i * mod *diff_y / 2;
|
||||
float new_y = i * mod *diff_x / 2 + mod* diff_y * sqrt(3) / 2;
|
||||
me->AddDelayedEvent(1 + time * 50, [=]()
|
||||
{
|
||||
me->CastSpell({ me->GetPositionX() + new_x + frand(-2, 2), me->GetPositionY() + new_y + frand(-2, 2), me->GetPositionZ(), 0 }, 233435, true);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
events.RescheduleEvent(EVENT_CALCIFIED_QUILS, 20000);
|
||||
break;
|
||||
case EVENT_PANGS_OF_GUILT:
|
||||
DoCast(SPELL_PANGS_OF_GUILT);
|
||||
events.RescheduleEvent(EVENT_PANGS_OF_GUILT, 10000);
|
||||
break;
|
||||
case EVENT_ECHOING_ANGUISH:
|
||||
DoCast(SPELL_ECHOING_ANGUISH);
|
||||
events.RescheduleEvent(EVENT_ECHOING_ANGUISH, 22000);
|
||||
break;
|
||||
case EVENT_TORMENTING_BURST:
|
||||
DoCast(SPELL_TORMENTING_BURST);
|
||||
events.RescheduleEvent(EVENT_TORMENTING_BURST, 17000);
|
||||
break;
|
||||
case EVENT_SUFFOCATING_DARK:
|
||||
{
|
||||
std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList();
|
||||
|
||||
threatlist.remove_if([this](HostileReference* ref)
|
||||
{
|
||||
if (!ref->getTarget()->IsPlayer())
|
||||
return true;
|
||||
|
||||
return me->GetDistance(ref->getTarget()) >= 60.0f;
|
||||
});
|
||||
|
||||
std::list<HostileReference*> threatListTemp = threatlist;
|
||||
threatListTemp.remove_if([this](HostileReference* ref)
|
||||
{
|
||||
return ref->getTarget()->ToPlayer()->GetRoleForGroup() == ROLE_TANK; // approximation : on ecarte seulement les tanks
|
||||
});
|
||||
|
||||
uint8 count = std::min(3, int32(ceil(float(threatlist.size()) / 5.0f)));
|
||||
if (threatListTemp.size() >= count)
|
||||
threatlist = threatListTemp;
|
||||
|
||||
Trinity::Containers::RandomResize(threatlist, count);
|
||||
for (const auto& target : threatlist)
|
||||
if (Unit* targ = target->getTarget())
|
||||
me->CastSpell(targ->GetPositionX(), targ->GetPositionY(), 3011.62f, SPELL_SUFFOCATING_DARK, true);
|
||||
|
||||
events.RescheduleEvent(EVENT_SUFFOCATING_DARK, 24000);
|
||||
break;
|
||||
}
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(SPELL_ENRAGE);
|
||||
break;
|
||||
case EVENT_SUMMON_ADD:
|
||||
me->SummonCreature(NPC_TORMENTED_SOUL, 6403.00f, -935.00f, 3037.16f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetEntry() != NPC_BELAK)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new boss_demonic_inquisitionAI (creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 117957
|
||||
class npc_tos_tormented_soul : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tos_tormented_soul() : CreatureScript("npc_tos_tormented_soul") {}
|
||||
|
||||
struct npc_tos_tormented_soulAI : public ScriptedAI
|
||||
{
|
||||
npc_tos_tormented_soulAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
me->m_SightDistance = 20;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->RemoveAurasDueToSpell(239135);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
events.RescheduleEvent(EVENT_1, 6000);
|
||||
events.RescheduleEvent(EVENT_2, 5000);
|
||||
}
|
||||
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage) override
|
||||
{
|
||||
if (urand(1, 3) == 2)
|
||||
DoCast(attacker, 235301);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (CheckHomeDistToEvade(diff, 17.0f))
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_1:
|
||||
DoCast(SPELL_SOUL_CORRUPTION);
|
||||
events.RescheduleEvent(EVENT_1, 6000);
|
||||
break;
|
||||
case EVENT_2:
|
||||
DoCast(239135);
|
||||
events.RescheduleEvent(EVENT_2, urand(16000, 19000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_tos_tormented_soulAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 233652
|
||||
class spell_tos_confess : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tos_confess() : SpellScriptLoader("spell_tos_confess") { }
|
||||
|
||||
class spell_tos_confess_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_confess_AuraScript);
|
||||
|
||||
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetTarget())
|
||||
{
|
||||
if (!caster->IsPlayer())
|
||||
return;
|
||||
|
||||
caster->GetMotionMaster()->MoveSmoothFlyPath(0, { caster->GetPositionX() + frand(-3, 3), caster->GetPositionY() + frand(-3, 3), caster->GetPositionZ() + 10.0f, caster->GetOrientation() });
|
||||
caster->AddDelayedEvent(1500, [caster]() -> void {
|
||||
caster->RemoveAurasDueToSpell(233652);
|
||||
caster->GetMotionMaster()->Clear();
|
||||
caster->ToPlayer()->TeleportTo(caster->GetMapId(), 6403.13f, -935.55f, 3060.23f, caster->GetOrientation(),TELE_TO_SEAMLESS);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_tos_confess_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_tos_confess_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 233104
|
||||
class spell_tos_torment : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tos_torment() : SpellScriptLoader("spell_tos_torment") { }
|
||||
|
||||
class spell_tos_torment_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_torment_AuraScript);
|
||||
|
||||
void OnTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (target->GetPower(POWER_ALTERNATE_POWER) >= 100)
|
||||
target->CastSpell(target, SPELL_DEBUFF_UNBEAR_TOR, true);
|
||||
else if (target->GetPower(POWER_ALTERNATE_POWER) == 0)
|
||||
if (target->GetDistance2d(6403.13f, -935.55f) <= 30.0f)
|
||||
target->CastSpell(target, 243560, true); // 235293
|
||||
|
||||
if (target->GetDistance2d(6403.13f, -935.55f) > 40.0f && target->HasAura(SPELL_BELAC_PRISONER))
|
||||
{
|
||||
target->RemoveAurasDueToSpell(SPELL_BELAC_PRISONER);
|
||||
target->RemoveAurasDueToSpell(SPELL_DEBUFF_OVER_AURA1); // clear
|
||||
target->CastSpell(target, SPELL_DEBUFF_OVER_AURA1, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*auraEffect*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target || !target->IsPlayer())
|
||||
return;
|
||||
|
||||
if (target->GetDistance2d(6403.13f, -935.55f) <= 30.0f)
|
||||
if (target->IsAlive())
|
||||
target->ToPlayer()->TeleportTo(target->GetMapId(), 6401.96f, -795.64f, 3020.17f, 0.01f, TELE_TO_SEAMLESS);
|
||||
else
|
||||
target->NearTeleportTo(6401.96f, -795.64f, 3020.17f, 0.01f);
|
||||
|
||||
target->RemoveAurasDueToSpell(SPELL_BELAC_PRISONER);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tos_torment_AuraScript::OnTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_tos_torment_AuraScript::OnRemove, SpellEffIndex::EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AuraEffectHandleModes::AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_tos_torment_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 235305
|
||||
class spell_tos_prisoner : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tos_prisoner() : SpellScriptLoader("spell_tos_prisoner") { }
|
||||
|
||||
class spell_tos_prisoner_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_prisoner_AuraScript);
|
||||
|
||||
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/)
|
||||
{
|
||||
amount = -1;
|
||||
}
|
||||
|
||||
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32& absorbAmount)
|
||||
{
|
||||
absorbAmount = dmgInfo.GetDamage();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_tos_prisoner_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_tos_prisoner_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 233435
|
||||
class spell_tos_calcified_quils : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_calcified_quils);
|
||||
|
||||
void HandleDamage(SpellEffIndex /*effectIndex*/)
|
||||
{
|
||||
if (GetCaster() && GetHitUnit())
|
||||
if (GetCaster()->GetEntry() == NPC_ATRIGAN)
|
||||
if (GetCaster()->ToCreature()->AI()->GetObjectData(GetHitUnit()->GetGUID(), 0))
|
||||
SetHitDamage(0);
|
||||
}
|
||||
|
||||
void RecalculateDamage(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
|
||||
if (GetCaster() && GetHitUnit())
|
||||
if (GetCaster()->GetEntry() == NPC_ATRIGAN)
|
||||
if (!GetCaster()->ToCreature()->AI()->GetObjectData(GetHitUnit()->GetGUID(), 1))
|
||||
GetHitUnit()->SetPower(POWER_ALTERNATE_POWER, GetHitUnit()->GetPower(POWER_ALTERNATE_POWER) + 10);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tos_calcified_quils::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tos_calcified_quils::RecalculateDamage, EFFECT_2, SPELL_EFFECT_ENERGIZE);
|
||||
}
|
||||
};
|
||||
|
||||
// 235295
|
||||
class spell_tos_adherent_fragment : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_adherent_fragment);
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
||||
if (instance->instance->IsMythic())
|
||||
caster->CastSpellDelay(caster, 241505, true, 1000);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterCast += SpellCastFn(spell_tos_adherent_fragment::HandleAfterCast);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_grin_and_bear_it : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_grin_and_bear_it() : AchievementCriteriaScript("achievement_grin_and_bear_it") { }
|
||||
|
||||
bool OnCheck(Player* source, Unit* /*target*/) override
|
||||
{
|
||||
if (source->IsAlive() && source->HasAura(233430))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_demonic_inquisition()
|
||||
{
|
||||
new boss_demonic_inquisition();
|
||||
new npc_tos_tormented_soul();
|
||||
new spell_tos_confess();
|
||||
new spell_tos_torment();
|
||||
new spell_tos_prisoner();
|
||||
RegisterSpellScript(spell_tos_calcified_quils);
|
||||
RegisterSpellScript(spell_tos_adherent_fragment);
|
||||
new achievement_grin_and_bear_it();
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,755 @@
|
||||
/*
|
||||
https://uwow.biz/
|
||||
*/
|
||||
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_GOROTH_ENERGIZE = 237333,
|
||||
SPELL_BURNING_ARMOR = 231363,
|
||||
SPELL_BURNING_ERUPTION = 231395,
|
||||
SPELL_BURNING_ERUPTION_DUMMY = 233025,
|
||||
SPELL_CRASHING_COMET_FILTER = 232249, //Caster Boss
|
||||
SPELL_CRASHING_COMET_LFR_FILTER = 244548, //Caster Boss. Only LFR
|
||||
SPELL_CRASHING_COMET_FILTER2 = 232254, //Caster Ember Stalker - 115892
|
||||
SPELL_CRASHING_COMET_LFR_FILTER2 = 244580, //Caster Ember Stalker - 115892. Only LFR
|
||||
SPELL_CRASHING_COMET_MISSILE = 230339,
|
||||
SPELL_CRASHING_COMET_LFR_MISSILE = 244581,
|
||||
SPELL_INFERNAL_SPIKE_FILTER = 233050,
|
||||
SPELL_INFERNAL_SPIKE_SUMMON = 233055,
|
||||
SPELL_INFERNAL_SPIKE_AT = 233019,
|
||||
SPELL_INFERNAL_SPIKE_PROTECTION = 234475,
|
||||
SPELL_SHATTERING_STAR_FILTER = 233269,
|
||||
SPELL_SHATTERING_STAR_MARK = 233272,
|
||||
SPELL_SHATTERING_STAR_AURA = 233289, //unk
|
||||
SPELL_SHATTERING_STAR_SPEED = 233290,
|
||||
SPELL_SHATTERING_STAR_HIT = 233274,
|
||||
SPELL_SHATTERING_STAR_AT = 233279,
|
||||
SPELL_SHATTERING_NOVA = 233283,
|
||||
SPELL_STAR_BURN = 236329,
|
||||
SPELL_INFERNAL_BURNING = 233062,
|
||||
SPELL_INFERNAL_DETONATION = 233900, //Mythic
|
||||
SPELL_RAIN_OF_BRIMSTONE_DUMMY = 233285, //Mythic
|
||||
SPELL_RAIN_OF_BRIMSTONE_MISSILE = 238587, //Mythic
|
||||
SPELL_RAIN_OF_BRIMSTONE_SUMMON = 233266, //Mythic
|
||||
SPELL_RAIN_OF_BRIMSTONE_SPIKE_DESTROY = 238659, //Mythic
|
||||
|
||||
//Lava Stalker
|
||||
SPELL_FEL_PERIODIC_TRIGGER = 234386,
|
||||
SPELL_FEL_ERUPTION_TELEGRAPH = 234366,
|
||||
SPELL_FEL_ERUPTION_DUMMY = 234368,
|
||||
SPELL_FEL_ERUPTION_MISSILE = 234387,
|
||||
SPELL_FEL_ERUPTION_AT = 234330,
|
||||
|
||||
//Brimstone Infernal
|
||||
SPELL_FEL_FIRE = 241455,
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_BURNING_ARMOR = 1,
|
||||
EVENT_CRASHING_COMET = 2,
|
||||
EVENT_INFERNAL_SPIKE = 3,
|
||||
EVENT_SHATTERING_STAR = 4,
|
||||
EVENT_RAIN_OF_BRIMSTONE = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
SPELLVISUAL_INFERNAL_SPIKE_DESTROY = 66119,
|
||||
DATA_SPIKES_COUNTER,
|
||||
};
|
||||
|
||||
Position const centrPos = {6101.30f, -795.72f, 2971.72f};
|
||||
|
||||
//115844
|
||||
struct boss_goroth : BossAI
|
||||
{
|
||||
explicit boss_goroth(Creature* creature) : BossAI(creature, DATA_GOROTH) {}
|
||||
|
||||
uint8 spiketouched = 0;
|
||||
uint8 felRand = 0;
|
||||
uint8 shatteringCounter = 0;
|
||||
uint8 rainBrimstoneCounter = 0;
|
||||
uint32 felEruptionTimer = 0;
|
||||
uint32 shatteringTimer = 0;
|
||||
uint32 rainBrimstoneTimer = 0;
|
||||
ObjectGuid shatteringTargetGUID;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
spiketouched = 0;
|
||||
shatteringCounter = 0;
|
||||
rainBrimstoneCounter = 0;
|
||||
shatteringTimer = 60000;
|
||||
rainBrimstoneTimer = 60000;
|
||||
me->RemoveAurasDueToSpell(SPELL_GOROTH_ENERGIZE);
|
||||
me->SetMaxPower(POWER_ENERGY, 100);
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
me->SummonCreature(NPC_EMBER_STALKER, 6194.41f, -842.93f, 3042.72f, 0.0f);
|
||||
|
||||
if (IsHeroicPlusRaid())
|
||||
{
|
||||
felRand = 0;
|
||||
felEruptionTimer = 30000;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
DoCast(me, SPELL_GOROTH_ENERGIZE, true);
|
||||
events.RescheduleEvent(EVENT_BURNING_ARMOR, 10000);
|
||||
events.RescheduleEvent(EVENT_CRASHING_COMET, 8000);
|
||||
events.RescheduleEvent(EVENT_INFERNAL_SPIKE, 4000);
|
||||
events.RescheduleEvent(EVENT_SHATTERING_STAR, IsMythicRaid() ? 34000 : 24000);
|
||||
|
||||
if (IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_RAIN_OF_BRIMSTONE, 12000);
|
||||
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INFERNAL_SPIKE_PROTECTION);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(12);
|
||||
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INFERNAL_SPIKE_PROTECTION);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_STAR_BURN);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (!who->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk({ 7, 9, 10 });
|
||||
}
|
||||
|
||||
void DoAction(int32 const action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_1:
|
||||
if (auto player = ObjectAccessor::GetPlayer(*me, shatteringTargetGUID))
|
||||
DoCast(player, SPELL_STAR_BURN, true);
|
||||
break;
|
||||
case ACTION_2:
|
||||
++spiketouched;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
if (type == DATA_SPIKES_COUNTER)
|
||||
return spiketouched;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnRemoveAuraTarget(Unit* target, uint32 spellId, AuraRemoveMode mode) override
|
||||
{
|
||||
if (!me->IsInCombat() || !target || mode != AURA_REMOVE_BY_EXPIRE)
|
||||
return;
|
||||
|
||||
switch (spellId)
|
||||
{
|
||||
case SPELL_BURNING_ARMOR:
|
||||
target->CastSpell(target, SPELL_BURNING_ERUPTION, true);
|
||||
me->CastSpell(target, SPELL_BURNING_ERUPTION_DUMMY, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellFinishCast(const SpellInfo* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_INFERNAL_BURNING:
|
||||
{
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
EntryCheckPredicate pred(NPC_INFERNAL_SPIKE);
|
||||
summons.DoAction(ACTION_1, pred);
|
||||
break;
|
||||
}
|
||||
case SPELL_RAIN_OF_BRIMSTONE_DUMMY:
|
||||
{
|
||||
Position pos;
|
||||
std::list<Position> randPosList;
|
||||
bool badPos = false;
|
||||
uint16 traiCount = 0;
|
||||
while (randPosList.size() < 3)
|
||||
{
|
||||
badPos = false;
|
||||
centrPos.SimplePosXYRelocationByAngle(pos, frand(25.0f, 35.0f), frand(0.0f, 6.28f));
|
||||
++traiCount;
|
||||
|
||||
for (auto _pos : randPosList)
|
||||
{
|
||||
if (pos.GetExactDist(&_pos) <= 10.0f)
|
||||
{
|
||||
badPos = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!badPos || traiCount > 15)
|
||||
randPosList.push_back(pos);
|
||||
}
|
||||
for (auto _pos : randPosList)
|
||||
me->CastSpell(_pos, SPELL_RAIN_OF_BRIMSTONE_MISSILE, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_SHATTERING_STAR_HIT:
|
||||
if (me->IsInCombat())
|
||||
DoCast(target, SPELL_SHATTERING_STAR_AT, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_INFERNAL_SPIKE_FILTER:
|
||||
DoCast(target, SPELL_INFERNAL_SPIKE_SUMMON, true);
|
||||
break;
|
||||
case SPELL_SHATTERING_STAR_FILTER:
|
||||
shatteringTargetGUID = target->GetGUID();
|
||||
DoCast(target, SPELL_SHATTERING_STAR_MARK, true);
|
||||
DoCast(target, SPELL_SHATTERING_STAR_SPEED, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (CheckHomeDistToEvade(diff, 62.0f, 6100.85f, -795.70f, 2971.72f))
|
||||
return;
|
||||
|
||||
if (felEruptionTimer)
|
||||
{
|
||||
if (felEruptionTimer <= diff)
|
||||
{
|
||||
felEruptionTimer = 30000;
|
||||
uint8 felRandOld = felRand;
|
||||
|
||||
while (felRandOld == felRand)
|
||||
{
|
||||
felRand = urand(2, 5);
|
||||
}
|
||||
; // SummonCreatureGroupDespawn : groupes d invocation uwow, non porte
|
||||
me->SummonCreatureGroup(felRand);
|
||||
}
|
||||
else
|
||||
felEruptionTimer -= diff;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BURNING_ARMOR:
|
||||
DoCastTopAggro(SPELL_BURNING_ARMOR);
|
||||
events.RescheduleEvent(EVENT_BURNING_ARMOR, 24000);
|
||||
break;
|
||||
case EVENT_CRASHING_COMET:
|
||||
{
|
||||
if (IsLfrRaid())
|
||||
DoCast(SPELL_CRASHING_COMET_LFR_FILTER);
|
||||
else
|
||||
DoCast(SPELL_CRASHING_COMET_FILTER);
|
||||
EntryCheckPredicate pred(NPC_EMBER_STALKER);
|
||||
summons.DoAction(ACTION_1, pred);
|
||||
events.RescheduleEvent(EVENT_CRASHING_COMET, 18000);
|
||||
break;
|
||||
}
|
||||
case EVENT_INFERNAL_SPIKE:
|
||||
DoCast(SPELL_INFERNAL_SPIKE_FILTER);
|
||||
events.RescheduleEvent(EVENT_INFERNAL_SPIKE, 16000);
|
||||
break;
|
||||
case EVENT_SHATTERING_STAR:
|
||||
if (++shatteringCounter == 4)
|
||||
shatteringTimer = IsMythicRaid() ? 30000 : 50000;
|
||||
shatteringTargetGUID.Clear();
|
||||
DoCast(SPELL_SHATTERING_STAR_FILTER);
|
||||
events.RescheduleEvent(EVENT_SHATTERING_STAR, shatteringTimer);
|
||||
break;
|
||||
case EVENT_RAIN_OF_BRIMSTONE:
|
||||
if (++rainBrimstoneCounter == 4)
|
||||
{
|
||||
rainBrimstoneCounter = 0;
|
||||
rainBrimstoneTimer = 68000;
|
||||
}
|
||||
else
|
||||
rainBrimstoneTimer = 60000;
|
||||
DoCast(SPELL_RAIN_OF_BRIMSTONE_DUMMY);
|
||||
events.RescheduleEvent(EVENT_RAIN_OF_BRIMSTONE, rainBrimstoneTimer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
//115892
|
||||
struct npc_goroth_ember_stalker : public ScriptedAI
|
||||
{
|
||||
npc_goroth_ember_stalker(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetDisplayId(11686);
|
||||
}
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void DoAction(int32 const action) override
|
||||
{
|
||||
if (IsLfrRaid())
|
||||
me->CastSpellDelay(me, SPELL_CRASHING_COMET_LFR_FILTER2, true, 500);
|
||||
else
|
||||
me->CastSpellDelay(me, SPELL_CRASHING_COMET_FILTER2, true, 500);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
auto owner = me->GetAnyOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_CRASHING_COMET_LFR_FILTER2:
|
||||
me->CastSpell(target, SPELL_CRASHING_COMET_LFR_MISSILE, true, nullptr, nullptr, owner->GetGUID());
|
||||
break;
|
||||
case SPELL_CRASHING_COMET_FILTER2:
|
||||
me->CastSpell(target, SPELL_CRASHING_COMET_MISSILE, true, nullptr, nullptr, owner->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) {}
|
||||
};
|
||||
|
||||
//116976
|
||||
struct npc_goroth_infernal_spike : public ScriptedAI
|
||||
{
|
||||
npc_goroth_infernal_spike(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
bool despawn = false;
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
me->CastSpellDelay(me, SPELL_INFERNAL_SPIKE_AT, false, 500);
|
||||
}
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (despawn || caster->GetEntry() != NPC_GOROTH)
|
||||
return;
|
||||
|
||||
if (spell->Id == SPELL_BURNING_ERUPTION_DUMMY || spell->Id == SPELL_RAIN_OF_BRIMSTONE_SPIKE_DESTROY)
|
||||
DoAction(true);
|
||||
}
|
||||
|
||||
void OnAreaTriggerDespawn(uint32 spellId, Position pos, bool duration) override
|
||||
{
|
||||
if (despawn)
|
||||
return;
|
||||
|
||||
if (spellId == SPELL_INFERNAL_SPIKE_AT)
|
||||
DoAction(true);
|
||||
}
|
||||
|
||||
void DoAction(int32 const action) override
|
||||
{
|
||||
if (despawn)
|
||||
return;
|
||||
|
||||
despawn = true;
|
||||
|
||||
if (IsMythicRaid())
|
||||
{
|
||||
if (auto owner = me->GetAnyOwner())
|
||||
owner->CastSpell(me, SPELL_INFERNAL_DETONATION, true);
|
||||
}
|
||||
|
||||
; // (PlaySpellVisual positionnel : cosmetique uwow, non porte)
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) {}
|
||||
};
|
||||
|
||||
//117931
|
||||
struct npc_goroth_lava_stalker : public ScriptedAI
|
||||
{
|
||||
npc_goroth_lava_stalker(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
me->CastSpellDelay(me, SPELL_FEL_ERUPTION_TELEGRAPH, true, 500);
|
||||
me->CastSpellDelay(me, SPELL_FEL_PERIODIC_TRIGGER, true, 7000);
|
||||
}
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void UpdateAI(uint32 diff) {}
|
||||
};
|
||||
|
||||
//119950
|
||||
struct npc_goroth_brimstone_infernal : public ScriptedAI
|
||||
{
|
||||
npc_goroth_brimstone_infernal(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
uint32 felTimer = 0;
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE, 2000);
|
||||
felTimer = 12000; //Need correct time!
|
||||
}
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (felTimer)
|
||||
{
|
||||
if (felTimer <= diff)
|
||||
{
|
||||
felTimer = 15000; //Need correct time!
|
||||
DoCast(SPELL_FEL_FIRE);
|
||||
}
|
||||
else
|
||||
felTimer -= diff;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
//233024
|
||||
class spell_tos_goroth_crashing_comet : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_goroth_crashing_comet);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
std::list<WorldObject*> infernalSpikes;
|
||||
for (auto target : targets)
|
||||
{
|
||||
if (target->GetEntry() == NPC_INFERNAL_SPIKE)
|
||||
infernalSpikes.push_back(target);
|
||||
}
|
||||
|
||||
for (auto infernalSpike : infernalSpikes)
|
||||
{
|
||||
if (auto spike = ObjectAccessor::GetCreature(*GetCaster(), infernalSpike->GetGUID()))
|
||||
spike->GetAI()->DoAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tos_goroth_crashing_comet::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
//234368
|
||||
class spell_tos_goroth_fel_eruption_dummy : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_goroth_fel_eruption_dummy);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effectIndex*/)
|
||||
{
|
||||
if (!GetCaster() || !GetHitDest())
|
||||
return;
|
||||
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* goroth = instance->instance->GetCreature(instance->GetGuidData(DATA_GOROTH)))
|
||||
goroth->CastSpell(GetHitDest()->GetPositionX(), GetHitDest()->GetPositionY(), GetHitDest()->GetPositionZ(), SPELL_FEL_ERUPTION_AT, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunch += SpellEffectFn(spell_tos_goroth_fel_eruption_dummy::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
//238588
|
||||
class spell_tos_goroth_rain_of_brimstone : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_goroth_rain_of_brimstone);
|
||||
|
||||
uint8 targetCount = 0;
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (!GetCaster() || !GetExplTargetDest())
|
||||
return;
|
||||
|
||||
GetCaster()->CastSpell(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY(), GetExplTargetDest()->GetPositionZ(), SPELL_RAIN_OF_BRIMSTONE_SPIKE_DESTROY, true);
|
||||
|
||||
if (targets.empty())
|
||||
GetCaster()->CastSpell(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY(), GetExplTargetDest()->GetPositionZ(), SPELL_RAIN_OF_BRIMSTONE_SUMMON, true);
|
||||
else
|
||||
targetCount = targets.size();
|
||||
}
|
||||
|
||||
void HandleDamage(SpellEffIndex /*effectIndex*/)
|
||||
{
|
||||
if (targetCount)
|
||||
SetHitDamage(GetHitDamage() / targetCount);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tos_goroth_rain_of_brimstone::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tos_goroth_rain_of_brimstone::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
//237333
|
||||
class spell_tos_goroth_energy_tracker : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_goroth_energy_tracker);
|
||||
|
||||
uint8 powerTick = 0;
|
||||
|
||||
void OnTick(AuraEffect const* aurEff)
|
||||
{
|
||||
auto caster = GetCaster()->ToCreature();
|
||||
if (!caster || !caster->IsInCombat())
|
||||
return;
|
||||
|
||||
auto powerCount = caster->GetPower(POWER_ENERGY);
|
||||
if (powerCount < 100)
|
||||
{
|
||||
if (powerTick < 8)
|
||||
{
|
||||
++powerTick;
|
||||
|
||||
if (aurEff->GetTickNumber() == 1)
|
||||
caster->SetPower(POWER_ENERGY, powerCount + 1);
|
||||
else
|
||||
caster->SetPower(POWER_ENERGY, powerCount + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
powerTick = 0;
|
||||
caster->SetPower(POWER_ENERGY, powerCount + 1);
|
||||
}
|
||||
}
|
||||
else if (!caster->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_INFERNAL_BURNING, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tos_goroth_energy_tracker::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
//234386
|
||||
class spell_tos_goroth_fel_periodic_trigger : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_goroth_fel_periodic_trigger);
|
||||
|
||||
void OnTick(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
if (auto caster = GetCaster())
|
||||
{
|
||||
Position pos;
|
||||
float angle = caster->GetRelativeAngle(centrPos.GetPositionX(), centrPos.GetPositionY()) + frand(-1.0f, 1.0f);
|
||||
pos = caster->GetNearPosition(frand(35.0f, 45.0f), angle);
|
||||
caster->CastSpell(pos, SPELL_FEL_ERUPTION_MISSILE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tos_goroth_fel_periodic_trigger::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
//955600
|
||||
struct at_goroth_infernal_spike_los_blocker : AreaTriggerAI
|
||||
{
|
||||
at_goroth_infernal_spike_los_blocker(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) {}
|
||||
|
||||
bool IsValidTarget(Unit* caster, Unit* target, AreaTriggerActionMoment actionM) override
|
||||
{
|
||||
if (caster && target && target->IsPlayer())
|
||||
{
|
||||
if (auto instance = target->GetInstanceScript())
|
||||
{
|
||||
if (auto goroth = ObjectAccessor::GetCreature(*target, instance->GetGuidData(DATA_GOROTH)))
|
||||
{
|
||||
if (at->IsInBetween(target, goroth, 2.5f))
|
||||
{
|
||||
if (!target->HasAura(SPELL_INFERNAL_SPIKE_PROTECTION))
|
||||
target->CastSpell(target, SPELL_INFERNAL_SPIKE_PROTECTION, true, nullptr, nullptr, caster->GetGUID());
|
||||
}
|
||||
else if (auto aura = target->GetAura(SPELL_INFERNAL_SPIKE_PROTECTION, caster->GetGUID()))
|
||||
aura->Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//13412
|
||||
struct at_goroth_shattering_star : AreaTriggerAI
|
||||
{
|
||||
explicit at_goroth_shattering_star(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) {}
|
||||
|
||||
uint8 infernalSpikeTouched = 1;
|
||||
|
||||
void OnUnitEnter(Unit* unit) override
|
||||
{
|
||||
auto caster = at->GetCaster();
|
||||
if (unit->GetEntry() == NPC_INFERNAL_SPIKE)
|
||||
{
|
||||
++infernalSpikeTouched;
|
||||
|
||||
if (unit->IsAIEnabled)
|
||||
unit->GetAI()->DoAction(true);
|
||||
|
||||
//Achievement
|
||||
if (caster->IsAIEnabled)
|
||||
caster->GetAI()->DoAction(ACTION_2);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestinationReached() override
|
||||
{
|
||||
auto caster = at->GetCaster();
|
||||
if (!caster)
|
||||
{
|
||||
at->Remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto spellInfo = sSpellMgr->GetSpellInfo(SPELL_SHATTERING_NOVA))
|
||||
{
|
||||
if (auto effInfo = spellInfo->GetEffect(EFFECT_0, caster->GetMap()->GetDifficultyID()))
|
||||
{
|
||||
float damage = effInfo->BasePoints / std::max(infernalSpikeTouched, uint8(1));
|
||||
SpellCastTargets targets;
|
||||
; // (SetCaster : le caster est fourni au CastSpell, inutile chez nous)
|
||||
targets.SetDst(at->GetPosition());
|
||||
CustomSpellValues values;
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
|
||||
|
||||
caster->CastSpell(targets, spellInfo, &values, TriggerCastFlags(TRIGGERED_FULL_MASK));
|
||||
}
|
||||
}
|
||||
if (infernalSpikeTouched < 2 && caster->IsAIEnabled)
|
||||
caster->GetAI()->DoAction(ACTION_1);
|
||||
}
|
||||
};
|
||||
|
||||
//13526
|
||||
struct at_goroth_fel_pool : AreaTriggerAI
|
||||
{
|
||||
explicit at_goroth_fel_pool(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) {}
|
||||
|
||||
void OnUnitEnter(Unit* unit) override
|
||||
{
|
||||
if (unit->GetEntry() == NPC_INFERNAL_SPIKE)
|
||||
unit->GetAI()->DoAction(true);
|
||||
}
|
||||
};
|
||||
|
||||
//36337
|
||||
class achievement_fel_turkey : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_fel_turkey() : AchievementCriteriaScript("achievement_fel_turkey") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target) override
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
if (auto boss = target->ToCreature())
|
||||
if (boss->IsAIEnabled && boss->AI()->GetData(DATA_SPIKES_COUNTER) >= 30)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_goroth()
|
||||
{
|
||||
RegisterCreatureAI(boss_goroth);
|
||||
RegisterCreatureAI(npc_goroth_ember_stalker);
|
||||
RegisterCreatureAI(npc_goroth_infernal_spike);
|
||||
RegisterCreatureAI(npc_goroth_lava_stalker);
|
||||
RegisterCreatureAI(npc_goroth_brimstone_infernal);
|
||||
RegisterSpellScript(spell_tos_goroth_crashing_comet);
|
||||
RegisterSpellScript(spell_tos_goroth_fel_eruption_dummy);
|
||||
RegisterSpellScript(spell_tos_goroth_rain_of_brimstone);
|
||||
RegisterAuraScript(spell_tos_goroth_energy_tracker);
|
||||
RegisterAuraScript(spell_tos_goroth_fel_periodic_trigger);
|
||||
RegisterAreaTriggerAI(at_goroth_infernal_spike_los_blocker);
|
||||
RegisterAreaTriggerAI(at_goroth_shattering_star);
|
||||
RegisterAreaTriggerAI(at_goroth_fel_pool);
|
||||
new achievement_fel_turkey();
|
||||
}
|
||||
@@ -0,0 +1,766 @@
|
||||
/*
|
||||
https://uwow.biz/
|
||||
*/
|
||||
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_CALL = 1,
|
||||
SAY_DRAW_IN = 2,
|
||||
SAY_DEATH = 3,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DRAW_IN = 232061, //
|
||||
SPELL_FRIGID_BLOWS = 233429, //
|
||||
SPELL_DRENCHING_SLOUGH = 233526, // dummy
|
||||
SPELL_FROSTY_DISCHARGE = 232174, // at end link
|
||||
|
||||
SPELL_UNCHECKED_RAGE = 231854, // 100%
|
||||
SPELL_UNCHECKED_RAGE_VICTIM = 247403, //
|
||||
SPELL_CALL_ADDS = 232192, //
|
||||
|
||||
SPELL_CANCEL_DRENCHED = 239926, // link
|
||||
SPELL_CHANGE_ENERGY = 241486, //
|
||||
SPELL_REGENERATE_ENERGY = 232379, //
|
||||
|
||||
SPELL_ENQUBATION = 240347,
|
||||
SPELL_HARDENED_SHELL = 240315,
|
||||
|
||||
SPELL_ENQUBATION_RED = 242027,
|
||||
SPELL_ENQUBATION_BLUE = 242030,
|
||||
SPELL_ENQUBATION_GREEN = 242031,
|
||||
|
||||
SPELL_ENRAGE = 64238, //
|
||||
|
||||
SPELL_JAGGED_ABRASION = 231998,
|
||||
|
||||
//achievement npc spells
|
||||
SPELL_SONIC_WAVE = 241436,
|
||||
SPELL_SPLASH = 241393,
|
||||
SPELL_ELDERS_RAGE = 241416,
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_CHECK_ENERGY = 1,
|
||||
EVENT_CALL_ADDS,
|
||||
EVENT_DRAW_IN,
|
||||
EVENT_HATCHING,
|
||||
EVENT_HATCHING_CLEAN_UP,
|
||||
|
||||
EVENT_ENRAGE,
|
||||
|
||||
EVENT_ELDER1,
|
||||
EVENT_ELDER2,
|
||||
EVENT_ELDER3,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
DATA_COMPLETE,
|
||||
};
|
||||
|
||||
enum Action
|
||||
{
|
||||
ACTION_COMPLETE,
|
||||
};
|
||||
|
||||
Position const addsPos[4]
|
||||
{
|
||||
{5877.17f, -906.50f, 2920.25f, 6.20f},
|
||||
{5880.17f, -896.95f, 2920.35f, 5.73f},
|
||||
{5889.86f, -886.83f, 2920.35f, 5.42f},
|
||||
{5946.16f, -919.47f, 2919.52f, 2.62f}
|
||||
|
||||
};
|
||||
|
||||
Position const eggsPos[4]
|
||||
{
|
||||
{5915.40f, -876.02f, 2919.83f, 0.0f},
|
||||
{5944.42f, -900.28f, 2919.46f, 0.0f},
|
||||
{5918.47f, -945.27f, 2919.86f, 0.0f},
|
||||
{5882.26f, -920.99f, 2920.99f, 0.0f}
|
||||
};
|
||||
|
||||
uint32 const eggsCasts[3]
|
||||
{
|
||||
SPELL_ENQUBATION_BLUE,
|
||||
SPELL_ENQUBATION_RED,
|
||||
SPELL_ENQUBATION_GREEN
|
||||
};
|
||||
|
||||
// 116407
|
||||
class boss_harjatan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_harjatan() : CreatureScript("boss_harjatan") {}
|
||||
|
||||
struct boss_harjatanAI : BossAI
|
||||
{
|
||||
boss_harjatanAI(Creature* creature) : BossAI(creature, DATA_HARJATAN), achievecomplete(false)
|
||||
{
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
achievecomplete = false;
|
||||
}
|
||||
|
||||
std::map<uint8, std::vector<ObjectGuid>> eggs{};
|
||||
bool achievecomplete;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->IsAlive())
|
||||
{
|
||||
_Reset();
|
||||
achievecomplete = false;
|
||||
|
||||
if (Creature* elder = instance->instance->GetCreature(instance->GetGuidData(NPC_ELDER)))
|
||||
if (!elder->IsAlive())
|
||||
elder->Respawn();
|
||||
}
|
||||
|
||||
eggs.clear();
|
||||
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(231770);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_JAGGED_ABRASION);
|
||||
|
||||
std::list<AreaTrigger*> list;
|
||||
me->GetAreatriggerListInRange(list, 80.0f);
|
||||
list.remove_if([](AreaTrigger* at1) { AreaTriggerTemplate const* t1 = at1->GetTemplate(); return !t1 || t1->Id != 13251; });
|
||||
for (std::list<AreaTrigger*>::const_iterator itr = list.begin(); itr != list.end(); itr++)
|
||||
(*itr)->RemoveFromWorld();
|
||||
if (IsMythicRaid())
|
||||
{
|
||||
for (uint8 j = 0; j < 4; ++j)
|
||||
{
|
||||
const auto& pos = eggsPos[j];
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (Creature* add = me->SummonCreature(NPC_EGGS, pos.GetPositionX() + frand(-4, 4), pos.GetPositionY() + frand(-4, 4), pos.GetPositionZ(), 0.0f))
|
||||
{
|
||||
add->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||
add->CastSpell(add, SPELL_HARDENED_SHELL);
|
||||
eggs[j].push_back(add->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 const action)
|
||||
{
|
||||
if (action == ACTION_COMPLETE)
|
||||
achievecomplete = true;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_COMPLETE:
|
||||
return achievecomplete ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
DoCast(SPELL_REGENERATE_ENERGY);
|
||||
events.RescheduleEvent(EVENT_CHECK_ENERGY, 500);
|
||||
|
||||
events.RescheduleEvent(EVENT_ENRAGE, IsMythicRaid() ? 360000 : 480000);
|
||||
events.RescheduleEvent(EVENT_DRAW_IN, 58000);
|
||||
events.RescheduleEvent(EVENT_CALL_ADDS, 17000);
|
||||
if (IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_HATCHING, 30000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* creature) override
|
||||
{
|
||||
switch(creature->GetEntry())
|
||||
{
|
||||
case NPC_EGGS:
|
||||
creature->SetReactState(REACT_ATTACK_OFF);
|
||||
creature->SetControlled(true, UNIT_STATE_ROOT);
|
||||
break;
|
||||
case NPC_TADPOLE_3:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
|
||||
{
|
||||
creature->SetTarget(target->GetGUID());
|
||||
creature->AI()->DoAction(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BossAI::JustSummoned(creature);
|
||||
}
|
||||
|
||||
void SpellFinishCast(SpellInfo const* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_UNCHECKED_RAGE:
|
||||
DoCastVictim(SPELL_UNCHECKED_RAGE_VICTIM, true);
|
||||
for (const auto& vector : eggs)
|
||||
for (const auto& guid : vector.second)
|
||||
if (Creature* egg = instance->instance->GetCreature(guid))
|
||||
if (me->isInFront(egg) && me->GetDistance(egg) <= 20.0f)
|
||||
egg->RemoveAurasDueToSpell(SPELL_HARDENED_SHELL);
|
||||
break;
|
||||
case SPELL_CALL_ADDS:
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
me->SummonCreature(i < 2 ? 117596 : 116569, addsPos[i]);
|
||||
break;
|
||||
case SPELL_FROSTY_DISCHARGE:
|
||||
events.RescheduleEvent(EVENT_DRAW_IN, 59000);
|
||||
events.RescheduleEvent(EVENT_CALL_ADDS, 17000);
|
||||
if (IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_HATCHING, 30000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnApplyOrRemoveAura(uint32 spellId, AuraRemoveMode /*mode*/, bool apply) override
|
||||
{
|
||||
switch (spellId)
|
||||
{
|
||||
case SPELL_FRIGID_BLOWS:
|
||||
if (apply)
|
||||
return;
|
||||
|
||||
me->SetPower(me->GetPowerType(), 0);
|
||||
DoCast(SPELL_FROSTY_DISCHARGE);
|
||||
break;
|
||||
case SPELL_DRAW_IN:
|
||||
if (apply)
|
||||
return;
|
||||
if (!me->HasAura(SPELL_FRIGID_BLOWS))
|
||||
{
|
||||
DoCast(SPELL_FROSTY_DISCHARGE);
|
||||
me->SetPower(me->GetPowerType(), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (CheckHomeDistToEvade(diff, 50.0f))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHECK_ENERGY:
|
||||
if (me->GetPower(POWER_ENERGY) >= 100)
|
||||
DoCast(SPELL_UNCHECKED_RAGE);
|
||||
events.RescheduleEvent(EVENT_CHECK_ENERGY, 500);
|
||||
break;
|
||||
case EVENT_CALL_ADDS:
|
||||
Talk(SAY_CALL);
|
||||
DoCast(SPELL_CALL_ADDS);
|
||||
events.RescheduleEvent(EVENT_CALL_ADDS, 36000);
|
||||
break;
|
||||
case EVENT_DRAW_IN:
|
||||
Talk(SAY_DRAW_IN);
|
||||
DoCast(SPELL_DRAW_IN);
|
||||
break;
|
||||
case EVENT_HATCHING:
|
||||
{
|
||||
DoCast(SPELL_ENQUBATION);
|
||||
|
||||
std::vector<uint8> eggsIndexes{ 0, 1, 2, 3 };
|
||||
std::list<uint8> eggsColors{ 0, 1, 2 };
|
||||
|
||||
Trinity::Containers::RandomResize(eggsIndexes, 2);
|
||||
Trinity::Containers::RandomResize(eggsColors, 2);
|
||||
|
||||
for (auto i : eggsIndexes)
|
||||
{
|
||||
uint8 color = eggsColors.front();
|
||||
eggsColors.pop_front();
|
||||
if (eggsCasts[color] == SPELL_ENQUBATION_GREEN)
|
||||
{
|
||||
for (const auto& guid : eggs[i])
|
||||
if (Creature* egg = instance->instance->GetCreature(guid))
|
||||
{
|
||||
if (!egg->IsAlive())
|
||||
egg->Respawn(true);
|
||||
egg->AI()->EnterCombat(me->GetVictim());
|
||||
egg->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||
egg->CastSpell(egg, SPELL_HARDENED_SHELL);
|
||||
egg->CastSpellDelay(egg, eggsCasts[color], false, 100);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Creature* egg = instance->instance->GetCreature(eggs[i][urand(0, eggs[i].size())]))
|
||||
{
|
||||
if (!egg->IsAlive())
|
||||
egg->Respawn(true);
|
||||
egg->AI()->EnterCombat(me->GetVictim());
|
||||
egg->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||
egg->CastSpell(egg, SPELL_HARDENED_SHELL);
|
||||
egg->CastSpellDelay(egg, eggsCasts[color], false, 100);
|
||||
}
|
||||
}
|
||||
|
||||
events.RescheduleEvent(EVENT_HATCHING_CLEAN_UP, 28000);
|
||||
break;
|
||||
}
|
||||
case EVENT_HATCHING_CLEAN_UP:
|
||||
{
|
||||
for (const auto& vector : eggs)
|
||||
for (const auto& guid : vector.second)
|
||||
if (Creature* egg = instance->instance->GetCreature(guid))
|
||||
{
|
||||
if (!egg->IsAlive())
|
||||
egg->Respawn(true);
|
||||
else
|
||||
egg->SetHealth(egg->GetMaxHealth());
|
||||
|
||||
for (const auto& spell : eggsCasts)
|
||||
egg->RemoveAurasDueToSpell(spell);
|
||||
egg->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_ATTACKABLE_1);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(SPELL_ENRAGE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new boss_harjatanAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 121184
|
||||
class npc_mistress_sasszine : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_mistress_sasszine() : CreatureScript("npc_mistress_sasszine") {}
|
||||
|
||||
struct npc_mistress_sasszineAI : ScriptedAI
|
||||
{
|
||||
npc_mistress_sasszineAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetCanSeeEvenInPassiveMode(true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
bool _introDone = false;
|
||||
uint32 introAdds = 0;
|
||||
|
||||
void DoAction(const int32) override
|
||||
{
|
||||
if (!introAdds)
|
||||
introAdds = 1;
|
||||
|
||||
switch (--introAdds)
|
||||
{
|
||||
case 1:
|
||||
Talk(2);
|
||||
break;
|
||||
case 0:
|
||||
me->CastSpell(me, 241744);
|
||||
|
||||
me->CastSpellDelay(me, 241680, false, 11000);
|
||||
me->DespawnOrUnsummon(13500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!who->IsPlayer())
|
||||
return;
|
||||
|
||||
if (me->GetDistance(who) < 100.0f && !_introDone)
|
||||
{
|
||||
_introDone = true;
|
||||
InstanceScript* instance = me->GetInstanceScript();
|
||||
if (!instance)
|
||||
return;
|
||||
|
||||
if (instance->GetBossState(DATA_HARJATAN) != NOT_STARTED)
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(0);
|
||||
|
||||
for (auto id : { NPC_EVENT_1, NPC_EVENT_2 })
|
||||
if (Creature* add = instance->instance->GetCreature(instance->GetGuidData(id)))
|
||||
if (add->IsAlive())
|
||||
++introAdds;
|
||||
|
||||
if (introAdds)
|
||||
return;
|
||||
|
||||
me->CastSpellDelay(me, 241744, false, 11000);
|
||||
me->CastSpellDelay(me, 241680, false, 21000);
|
||||
me->DespawnOrUnsummon(23500);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override {}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_mistress_sasszineAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 121155
|
||||
struct npc_tos_tadpole : ScriptedAI
|
||||
{
|
||||
npc_tos_tadpole(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
uint32 timer;
|
||||
bool canDoEvent = false;
|
||||
|
||||
void DoAction(const int32) override
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
me->AddDelayedEvent(1500, [this]()-> void
|
||||
{
|
||||
if (Unit* target = me->GetVictim())
|
||||
{
|
||||
me->GetMotionMaster()->MoveFollow(target, 0, 0);
|
||||
me->CastSpell(target, 241600);
|
||||
}
|
||||
|
||||
timer = 1000;
|
||||
canDoEvent = true;
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
DoCast(me, 241587, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (canDoEvent)
|
||||
{
|
||||
if (timer <= diff)
|
||||
{
|
||||
if (Unit* target = me->GetVictim())
|
||||
{
|
||||
if (me->GetDistance2d(target) <= 2.2f)
|
||||
{
|
||||
DoCast(241603);
|
||||
me->DespawnOrUnsummon(100);
|
||||
}
|
||||
else
|
||||
me->GetMotionMaster()->MoveFollow(target, 0, 0);
|
||||
}
|
||||
else
|
||||
me->DespawnOrUnsummon();
|
||||
timer = 1000;
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 121071 achievement npc
|
||||
class npc_elder_murk_eye : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_elder_murk_eye() : CreatureScript("npc_elder_murk_eye") {}
|
||||
|
||||
struct npc_elder_murk_eyeAI : ScriptedAI
|
||||
{
|
||||
npc_elder_murk_eyeAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetVisible(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 CheckTimer;
|
||||
uint32 EvadeTimer;
|
||||
Position const jumppoint = { 5892.11f, -898.21f, 2919.83f, 5.7f };
|
||||
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
CheckTimer = 2000;
|
||||
EvadeTimer = 5000;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetVisible(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->RemoveAura(241416);
|
||||
me->RemoveAura(241393);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
events.RescheduleEvent(EVENT_ELDER1, 6000); //wave
|
||||
events.RescheduleEvent(EVENT_ELDER2, 8000); //splash
|
||||
events.RescheduleEvent(EVENT_ELDER3, 25000); //rage
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if ((!me->IsInCombat()) && (instance->GetBossState(DATA_HARJATAN) == FAIL) || (!me->IsInCombat()) && (instance->GetBossState(DATA_HARJATAN) == NOT_STARTED))
|
||||
{
|
||||
if (EvadeTimer <= diff)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
|
||||
EvadeTimer = 5000;
|
||||
}
|
||||
|
||||
else EvadeTimer -= diff;
|
||||
}
|
||||
|
||||
if ((!me->IsInCombat()) && (instance->GetBossState(DATA_HARJATAN) == IN_PROGRESS))
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->HasAura(232454))
|
||||
{
|
||||
me->SetVisible(true);
|
||||
me->GetMotionMaster()->MoveJump(jumppoint, 10.0f, 10.0f);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
}
|
||||
CheckTimer = 2000;
|
||||
|
||||
}
|
||||
else CheckTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ELDER1:
|
||||
DoCast(SPELL_SONIC_WAVE);
|
||||
events.RescheduleEvent(EVENT_ELDER1, 6000);
|
||||
break;
|
||||
case EVENT_ELDER2:
|
||||
DoCast(SPELL_SPLASH);
|
||||
events.RescheduleEvent(EVENT_ELDER2, 20000);
|
||||
break;
|
||||
case EVENT_ELDER3:
|
||||
DoCast(SPELL_ELDERS_RAGE);
|
||||
events.RescheduleEvent(EVENT_ELDER3, 45000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* Harjatan = instance->instance->GetCreature(instance->GetGuidData(NPC_HARJATAN)))
|
||||
{
|
||||
Harjatan->AI()->DoAction(ACTION_COMPLETE);
|
||||
}
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(231770);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_elder_murk_eyeAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 231854
|
||||
class spell_tos_unchecked_rage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tos_unchecked_rage() : SpellScriptLoader("spell_tos_unchecked_rage") { }
|
||||
|
||||
class spell_tos_unchecked_rage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_unchecked_rage_SpellScript);
|
||||
|
||||
void CorrectTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
auto caster = GetCaster();
|
||||
|
||||
if (targets.size() < 5)
|
||||
caster->CastSpell(caster, 247782, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tos_unchecked_rage_SpellScript::CorrectTargets, SpellEffIndex::EFFECT_0, Targets::TARGET_UNIT_CONE_ENEMY_104);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_tos_unchecked_rage_SpellScript();
|
||||
};
|
||||
};
|
||||
|
||||
// 234016
|
||||
class spell_tos_fixate : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_fixate);
|
||||
|
||||
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
Unit* caster = GetCaster();
|
||||
if (!target || !caster)
|
||||
return;
|
||||
|
||||
caster->AddAura(234128, caster);
|
||||
|
||||
caster->AddThreat(target, std::numeric_limits<float>::max());
|
||||
caster->TauntApply(target);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*auraEffect*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (GetCaster() && GetTarget())
|
||||
GetCaster()->TauntFadeOut(GetTarget());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_tos_fixate::OnApply, EFFECT_0, SPELL_AURA_FIXATE, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_tos_fixate::OnRemove, SpellEffIndex::EFFECT_0, SPELL_AURA_FIXATE, AuraEffectHandleModes::AURA_EFFECT_HANDLE_REAL);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 232061
|
||||
class spell_tos_draw_in : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_draw_in);
|
||||
|
||||
uint8 counter = 0;
|
||||
|
||||
void OnTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
std::list<AreaTrigger*> list;
|
||||
caster->GetAreatriggerListInRange(list, 80.0f);
|
||||
list.remove_if([](AreaTrigger* at1) { AreaTriggerTemplate const* t1 = at1->GetTemplate(); return !t1 || t1->Id != 13251; });
|
||||
uint8 realCount = 0;
|
||||
for (std::list<AreaTrigger*>::const_iterator itr = list.begin(); itr != list.end(); itr++)
|
||||
{
|
||||
if ((*itr)->GetDuration() <= 9000)
|
||||
continue;
|
||||
|
||||
// adaptation : notre API de creation manuelle d AT differe, on recaste le sort
|
||||
// createur (231754) a la meme position pour regenerer la zone avec sa duree fraiche
|
||||
caster->CastSpell((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), 231754, true);
|
||||
|
||||
(*itr)->RemoveFromWorld();
|
||||
++realCount;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < realCount; ++i)
|
||||
caster->CastSpellDelay(caster, SPELL_FRIGID_BLOWS, true, (1 + i) * GetDuration() / realCount);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tos_draw_in::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_grand_fin_ale : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_grand_fin_ale() : AchievementCriteriaScript("achievement_grand_fin_ale") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target) override
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
if (Creature* boss = target->ToCreature())
|
||||
if (boss->AI()->GetData(DATA_COMPLETE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_harjatan()
|
||||
{
|
||||
new boss_harjatan();
|
||||
new npc_mistress_sasszine();
|
||||
new npc_elder_murk_eye();
|
||||
new achievement_grand_fin_ale();
|
||||
RegisterCreatureAI(npc_tos_tadpole);
|
||||
new spell_tos_unchecked_rage();
|
||||
RegisterAuraScript(spell_tos_fixate);
|
||||
RegisterAuraScript(spell_tos_draw_in);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,785 @@
|
||||
/*
|
||||
* This file is part of the DestinyCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_INFUSION_START = 1,
|
||||
SAY_INFUSION_END = 2,
|
||||
SAY_SECOND_PHASE = 3,
|
||||
SAY_SECOND_PHASE_LATER = 4,
|
||||
SAY_BEFORE_DEATH = 5, // ????????????
|
||||
SAY_DEATH = 6,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Global
|
||||
SPELL_INFUSION = 235271, //
|
||||
SPELL_MASS_INSTABILITY = 235267, // real cast aura (235117) + 8 //
|
||||
SPELL_UNSTABLE_SOUL = 235117, // maybe need it late 243275 //
|
||||
|
||||
// Light Side
|
||||
SPELL_LIGHT_INFUSION = 235213, // dmg 235214 //
|
||||
SPELL_HAMMER_OF_CREATION = 241635, // Aoe 235569 and tank dmg 241624 //
|
||||
SPELL_HAMMER_OF_CREATION_AOE = 235569, //
|
||||
SPELL_HAMMER_OF_CREATION_VICT = 241624, //
|
||||
SPELL_LIGHT_REMANENCE = 237994, // 119825
|
||||
SPELL_LIGHT_REMANENCE_SMALL = 238311, // myth
|
||||
|
||||
// Fel side
|
||||
SPELL_FEL_INFUSION = 235240, // dmg 235253 //
|
||||
SPELL_HAMMER_OF_OBLITERATION = 241636, // aoe dmg 235573 and tank dmg 241634 + 17 //
|
||||
SPELL_HAMMER_OF_OBLITERATION_AOE = 235573, //
|
||||
SPELL_HAMMER_OF_OBLITERATION_VICT = 241634, //
|
||||
SPELL_FEL_REMANENCE = 238316, // 119826
|
||||
SPELL_FEL_REMANENCE_SMALL = 238416, // myth
|
||||
|
||||
// Phase two
|
||||
SPELL_MOVE_TO_ANOTHER = 235630,
|
||||
SPELL_BLOWBACK = 248812, // by links; can find auras //
|
||||
SPELL_TITANIC_BULWARK = 235028, // by links //
|
||||
|
||||
SPELL_WRATH_OF_THE_CREATORS = 234891, // dmg 234896 (holy) and 236432(fel)
|
||||
SPELL_WRATH_OF_THE_CREATORS_TICK = 235014, //
|
||||
SPELL_WRATH_OF_THE_CREATORS_TICK_LIGHT = 234917, //
|
||||
SPELL_WRATH_OF_THE_CREATORS_TICK_FEL = 236433, //
|
||||
SPELL_WRATH_OF_THE_CREATORS_TICK_LIGHT_DMG = 234896, //
|
||||
SPELL_WRATH_OF_THE_CREATORS_TICK_FEL_DMG = 236432, //
|
||||
SPELL_WRATH_OF_THE_CREATORS_BUFF = 237339, //
|
||||
|
||||
SPELL_EXTINGUISH_LIFE = 238475, //
|
||||
|
||||
SPELL_ESSENCE_FRAGMENTS = 236061, //
|
||||
SPELL_ESSENCE_FRAGMENTS_TICK = 235859, //
|
||||
SPELL_CREATE_AT_VISUAL_FEL = 236708, //
|
||||
SPELL_CREATE_AT_VISUAL_LIGHT = 236690, //
|
||||
|
||||
SPELL_ESSENCE_HIT_LIGHT = 235554, // visual
|
||||
SPELL_ESSENCE_BUFF_LIGHT = 235534, //
|
||||
SPELL_ESSENCE_HIT_FEL = 235555, // visual
|
||||
SPELL_ESSENCE_BUFF_FEL = 235538, //
|
||||
|
||||
// myth
|
||||
SPELL_FRAGMENT_BURST = 239069,
|
||||
SPELL_FRAGMENT_BURST_DEBUFF = 241729,
|
||||
|
||||
SPELL_FRAGMENTING = 239153,
|
||||
SPELL_LIGHT_FRAGMENT = 241697,
|
||||
SPELL_LIGHT_FRAGMENT_FOCUS = 241713,
|
||||
SPELL_FEL_FRAGMENT = 241728,
|
||||
SPELL_FEL_FRAGMENT_FOCUS = 241727,
|
||||
|
||||
SPELL_ENRAGE = 64238, //
|
||||
SPELL_SHIELD = 241593,
|
||||
|
||||
SPELL_UNKWN = 237856, // also 235859
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_INFUSION = 1,
|
||||
EVENT_LIGHT_HAMMER,
|
||||
EVENT_FEL_HAMMER,
|
||||
EVENT_MASS_INSTABILITY,
|
||||
EVENT_SECOND_PHASE,
|
||||
|
||||
EVENT_FRAGMENTS,
|
||||
|
||||
};
|
||||
|
||||
Position const fragmentsPos[6]
|
||||
{
|
||||
{6375.67f, -789.47f, 2887.84f, 0.0f}, // original right 1
|
||||
{6384.21f, -788.24f, 2887.84f, 0.0f}, // original right 2
|
||||
{6394.00f, -786.70f, 2887.84f, 0.0f}, // original right 3
|
||||
{6376.05f, -799.67f, 2887.84f, 0.0f}, // original left 1
|
||||
{6384.74f, -801.70f, 2887.84f, 0.0f}, // original left 2
|
||||
{6393.59f, -803.61f, 2887.84f, 0.0f} // original left 3
|
||||
|
||||
//6319.85 other side
|
||||
};
|
||||
|
||||
// 118289
|
||||
struct boss_maiden_of_vigilance : BossAI
|
||||
{
|
||||
boss_maiden_of_vigilance(Creature* creature) : BossAI(creature, DATA_MAIDEN_OF_VIGILANCE) {}
|
||||
|
||||
uint32 wrathOfCreatorsCasts;
|
||||
uint32 countOfTeleports;
|
||||
|
||||
bool empoweredPhase;
|
||||
bool isFelNeed = true;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->IsAlive())
|
||||
_Reset();
|
||||
|
||||
me->KillAllDelayedEvents();
|
||||
wrathOfCreatorsCasts = 0;
|
||||
countOfTeleports = 0;
|
||||
empoweredPhase = false; // set true on 3 phase (second 1 phase)
|
||||
SetCombatMovement(true);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_LIGHT_INFUSION);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FEL_INFUSION);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SHIELD);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FRAGMENT_BURST_DEBUFF);
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, false);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_EnterCombat();
|
||||
|
||||
me->AddDelayedEvent(480000, [this]() -> void
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE, true);
|
||||
});
|
||||
|
||||
if (!IsLfrRaid())
|
||||
{
|
||||
events.RescheduleEvent(EVENT_INFUSION, 2000);
|
||||
events.RescheduleEvent(EVENT_LIGHT_HAMMER, 12000);
|
||||
events.RescheduleEvent(EVENT_MASS_INSTABILITY, 21000);
|
||||
events.RescheduleEvent(EVENT_SECOND_PHASE, 40000);
|
||||
if (IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_FRAGMENTS, 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.RescheduleEvent(EVENT_MASS_INSTABILITY, 6000);
|
||||
events.RescheduleEvent(EVENT_INFUSION, 40000);
|
||||
events.RescheduleEvent(EVENT_SECOND_PHASE, 47000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* creature) override
|
||||
{
|
||||
BossAI::JustSummoned(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_REMANENCE_LIGHT:
|
||||
if (IsHeroicPlusRaid())
|
||||
creature->CastSpell(creature, SPELL_LIGHT_REMANENCE_SMALL);
|
||||
break;
|
||||
case NPC_REMANENCE_FEL:
|
||||
if (IsHeroicPlusRaid())
|
||||
creature->CastSpell(creature, SPELL_FEL_REMANENCE_SMALL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* creature) override
|
||||
{
|
||||
if (!IsMythicRaid())
|
||||
return;
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ESSENCE_FEL:
|
||||
case NPC_ESSENCE_LIGHT:
|
||||
me->CastSpell(me, SPELL_FRAGMENT_BURST, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_HAMMER_OF_CREATION_AOE:
|
||||
case SPELL_HAMMER_OF_CREATION_VICT:
|
||||
if (target->HasAura(SPELL_FEL_INFUSION))
|
||||
DoCast(target, SPELL_UNSTABLE_SOUL, true);
|
||||
break;
|
||||
case SPELL_HAMMER_OF_OBLITERATION_AOE:
|
||||
case SPELL_HAMMER_OF_OBLITERATION_VICT:
|
||||
if (target->HasAura(SPELL_LIGHT_INFUSION))
|
||||
DoCast(target, SPELL_UNSTABLE_SOUL, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellFinishCast(SpellInfo const* spell) override
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_MASS_INSTABILITY:
|
||||
{
|
||||
uint32 spell = isFelNeed ? SPELL_FEL_INFUSION : SPELL_LIGHT_INFUSION;
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0,
|
||||
[spell](Unit* targett)
|
||||
{
|
||||
if (!targett->IsPlayer() || !targett->IsAlive() || !targett->ToPlayer()->isInTankSpec())
|
||||
return false;
|
||||
|
||||
return targett->HasAura(spell);
|
||||
}))
|
||||
me->CastSpell(target, SPELL_UNSTABLE_SOUL, false);
|
||||
for (uint32 spell : {SPELL_LIGHT_INFUSION, SPELL_FEL_INFUSION})
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0,
|
||||
[spell](Unit* targett)
|
||||
{
|
||||
if (!targett->IsPlayer() || !targett->IsAlive() || targett->ToPlayer()->isInTankSpec())
|
||||
return false;
|
||||
|
||||
return targett->HasAura(spell);
|
||||
}))
|
||||
me->CastSpell(target, SPELL_UNSTABLE_SOUL, false);
|
||||
break;
|
||||
}
|
||||
case SPELL_WRATH_OF_THE_CREATORS_TICK:
|
||||
{
|
||||
bool lightOrFel = wrathOfCreatorsCasts++ % 2 == 0;
|
||||
me->CastSpell(me, lightOrFel ? SPELL_WRATH_OF_THE_CREATORS_TICK_LIGHT : SPELL_WRATH_OF_THE_CREATORS_TICK_FEL, true);
|
||||
instance->instance->ApplyOnEveryPlayer([this, lightOrFel](Player* player)
|
||||
{
|
||||
me->CastSpell(player, lightOrFel ? SPELL_WRATH_OF_THE_CREATORS_TICK_LIGHT_DMG : SPELL_WRATH_OF_THE_CREATORS_TICK_FEL_DMG, true);
|
||||
});
|
||||
|
||||
if (me->GetAuraCount(SPELL_WRATH_OF_THE_CREATORS_BUFF) >= 30)
|
||||
{
|
||||
// me->CastStop();
|
||||
instance->instance->ApplyOnEveryPlayer([this](Player* player)
|
||||
{
|
||||
me->CastSpell(player, SPELL_EXTINGUISH_LIFE, true);
|
||||
});
|
||||
// OnInterruptCast(me, NULL, SPELL_WRATH_OF_THE_CREATORS, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_ESSENCE_FRAGMENTS_TICK:
|
||||
// countOfTeleports % 2 == 1 - other side, == 0 - original side
|
||||
for (uint8 i =0;i < 6;++i)
|
||||
{
|
||||
const auto& pos = fragmentsPos[i];
|
||||
uint32 spellid = (urand(1, 2) == 1 ? SPELL_CREATE_AT_VISUAL_FEL : SPELL_CREATE_AT_VISUAL_LIGHT);
|
||||
me->CastSpell(pos.GetPositionX() - (countOfTeleports % 2 == 1 ? 73.2f : 0), pos.GetPositionY(), pos.GetPositionZ(), spellid, true);
|
||||
if (Creature* add = me->SummonCreature((spellid == SPELL_CREATE_AT_VISUAL_FEL ? NPC_ESSENCE_FEL : NPC_ESSENCE_LIGHT), pos.GetPositionX() - (countOfTeleports % 2 == 1 ? 73.2f : 0), pos.GetPositionY(), pos.GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 12000))
|
||||
{
|
||||
float change_speed = 1.2f * M_PI*add->GetDistance2d(6348.20f, -795.95f) / 45;
|
||||
add->SetSpeed(MOVE_WALK, change_speed);
|
||||
add->GetMotionMaster()->MoveCirclePath(6348.20f, -795.95f, add->GetPositionZ(), add->GetDistance2d(6348.20f, -795.95f), (countOfTeleports % 2 == 0 ? i > 2 : i <= 2), 24);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPELL_HAMMER_OF_CREATION:
|
||||
case SPELL_HAMMER_OF_OBLITERATION:
|
||||
DoCastTopAggro(spell->Id == SPELL_HAMMER_OF_OBLITERATION ? SPELL_HAMMER_OF_OBLITERATION_VICT : SPELL_HAMMER_OF_CREATION_VICT, true);
|
||||
DoCastTopAggro(spell->Id == SPELL_HAMMER_OF_OBLITERATION ? SPELL_HAMMER_OF_OBLITERATION_AOE : SPELL_HAMMER_OF_CREATION_AOE, true);
|
||||
if (IsHeroicPlusRaid())
|
||||
{
|
||||
uint32 spellid = spell->Id == SPELL_HAMMER_OF_CREATION ? SPELL_FEL_INFUSION : SPELL_LIGHT_INFUSION;
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0,
|
||||
[spellid](Unit* targett)
|
||||
{
|
||||
if (!targett->IsPlayer() || !targett->IsAlive())
|
||||
return false;
|
||||
|
||||
return targett->HasAura(spellid);
|
||||
}))
|
||||
me->CastSpell(target, spell->Id == SPELL_HAMMER_OF_OBLITERATION ? SPELL_FEL_REMANENCE : SPELL_LIGHT_REMANENCE, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnApplyOrRemoveAura(uint32 spellId, AuraRemoveMode /*mode*/, bool apply) override
|
||||
{
|
||||
if (spellId != SPELL_BLOWBACK || !me->IsInCombat() || !me->IsAlive())
|
||||
return;
|
||||
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, apply);
|
||||
}
|
||||
|
||||
void OnInterruptCast(Unit* /*caster*/, uint32 spellId, uint32 curSpellID, uint32 /*schoolMask*/) override
|
||||
{
|
||||
if (curSpellID == SPELL_WRATH_OF_THE_CREATORS)
|
||||
{
|
||||
empoweredPhase = true;
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
if (!IsLfrRaid())
|
||||
{
|
||||
events.RescheduleEvent(EVENT_INFUSION, 3000);
|
||||
events.RescheduleEvent(EVENT_LIGHT_HAMMER, 12000);
|
||||
events.RescheduleEvent(EVENT_MASS_INSTABILITY, 21000);
|
||||
events.RescheduleEvent(EVENT_SECOND_PHASE, 82000);
|
||||
if (IsMythicRaid())
|
||||
events.RescheduleEvent(EVENT_FRAGMENTS, 8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.RescheduleEvent(EVENT_MASS_INSTABILITY, 8000);
|
||||
events.RescheduleEvent(EVENT_INFUSION, 21000);
|
||||
events.RescheduleEvent(EVENT_SECOND_PHASE, 67000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (me->HasAura(SPELL_WRATH_OF_THE_CREATORS))
|
||||
{
|
||||
bool needEvade = true;
|
||||
auto list = me->getThreatManager().getThreatList();
|
||||
for (auto& itr: list)
|
||||
if (Unit* target = itr->getTarget())
|
||||
if (target->IsPlayer() && target->IsAlive())
|
||||
{
|
||||
needEvade = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (needEvade)
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_INFUSION:
|
||||
me->CastSpell(me, SPELL_INFUSION);
|
||||
if (!empoweredPhase)
|
||||
Talk(SAY_INFUSION_START);
|
||||
|
||||
if (empoweredPhase)
|
||||
events.RescheduleEvent(EVENT_INFUSION, 38000);
|
||||
break;
|
||||
case EVENT_LIGHT_HAMMER:
|
||||
DoCast(SPELL_HAMMER_OF_CREATION);
|
||||
isFelNeed = false;
|
||||
events.RescheduleEvent(EVENT_FEL_HAMMER, 19000);
|
||||
break;
|
||||
case EVENT_FEL_HAMMER:
|
||||
DoCast(SPELL_HAMMER_OF_OBLITERATION);
|
||||
isFelNeed = true;
|
||||
if (empoweredPhase)
|
||||
events.RescheduleEvent(EVENT_LIGHT_HAMMER, 19000);
|
||||
break;
|
||||
case EVENT_MASS_INSTABILITY:
|
||||
DoCast(SPELL_MASS_INSTABILITY);
|
||||
if (empoweredPhase)
|
||||
events.RescheduleEvent(EVENT_MASS_INSTABILITY, 36000);
|
||||
break;
|
||||
case EVENT_SECOND_PHASE:
|
||||
events.Reset();
|
||||
Talk(SAY_SECOND_PHASE);
|
||||
me->AddDelayedEvent(8000, [this]()
|
||||
{
|
||||
Talk(SAY_SECOND_PHASE_LATER);
|
||||
});
|
||||
wrathOfCreatorsCasts = 0;
|
||||
if (++countOfTeleports % 2)
|
||||
me->CastSpell(6310.30f, -795.36f, 2887.84f, SPELL_MOVE_TO_ANOTHER);
|
||||
else
|
||||
me->CastSpell(me->GetHomePosition(), SPELL_MOVE_TO_ANOTHER,false);
|
||||
SetCombatMovement(false);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
break;
|
||||
case EVENT_FRAGMENTS:
|
||||
{
|
||||
Unit* target = nullptr;
|
||||
for (int8 i = 2; i >= 0; i--)
|
||||
if (target = SelectTarget(SELECT_TARGET_RANDOM, i))
|
||||
break;
|
||||
|
||||
if (!target)
|
||||
break;
|
||||
|
||||
DoCast(SPELL_FRAGMENTING);
|
||||
bool isFelFragment = target->HasAura(SPELL_LIGHT_INFUSION);
|
||||
me->CastSpell(target, (isFelFragment ? SPELL_FEL_FRAGMENT : SPELL_LIGHT_FRAGMENT));
|
||||
Position pos(target->GetPosition());
|
||||
ObjectGuid guid = target->GetGUID();
|
||||
me->AddDelayedEvent(3000, [this, guid, isFelFragment, pos]() -> void
|
||||
{
|
||||
me->SummonCreature((isFelFragment ? NPC_ESSENCE_FEL : NPC_ESSENCE_LIGHT), pos, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
// 118640 light 118643 fel
|
||||
struct npc_tos_essences : ScriptedAI
|
||||
{
|
||||
npc_tos_essences(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetCanSeeEvenInPassiveMode(true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
; // (m_RateUpdateTimer : optimisation de cadence uwow, non portee)
|
||||
}
|
||||
|
||||
bool justDoIt = false;
|
||||
uint32 updateTimer = 200;
|
||||
|
||||
void IsSummonedBy(Unit* cre) override
|
||||
{
|
||||
if (me->GetTarget().IsEmpty())
|
||||
return;
|
||||
|
||||
Unit* unit = me->GetVictim();
|
||||
if (!unit || !unit->IsAlive())
|
||||
unit = me->FindNearestPlayer(60, true);
|
||||
|
||||
if (unit)
|
||||
me->GetMotionMaster()->MoveFollow(unit, 0, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (justDoIt)
|
||||
return;
|
||||
|
||||
if (updateTimer <= diff)
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (const auto& itr : players)
|
||||
{
|
||||
Player* who = itr.GetSource();
|
||||
if (!who->IsAlive())
|
||||
continue;
|
||||
|
||||
if (me->GetDistance(who) < 0.22f && !justDoIt)
|
||||
{
|
||||
justDoIt = true;
|
||||
|
||||
me->CastSpell(who, me->GetEntry() == NPC_ESSENCE_FEL ? SPELL_ESSENCE_HIT_FEL : SPELL_ESSENCE_HIT_LIGHT);
|
||||
|
||||
if (who->HasAura(SPELL_LIGHT_INFUSION) && me->GetEntry() == NPC_ESSENCE_LIGHT)
|
||||
{
|
||||
for (const auto& itr : players)
|
||||
if (Player* temp = itr.GetSource())
|
||||
if ((temp == who || temp->GetDistance(who) <= 10.0f) && temp->HasAura(SPELL_LIGHT_INFUSION))
|
||||
temp->CastSpell(temp, SPELL_ESSENCE_BUFF_LIGHT);
|
||||
}
|
||||
else if (who->HasAura(SPELL_FEL_INFUSION) && me->GetEntry() == NPC_ESSENCE_FEL)
|
||||
{
|
||||
for (const auto& itr : players)
|
||||
if (Player* temp = itr.GetSource())
|
||||
if ((temp == who || temp->GetDistance(who) <= 10.0f) && temp->HasAura(SPELL_FEL_INFUSION))
|
||||
temp->CastSpell(temp, SPELL_ESSENCE_BUFF_FEL);
|
||||
}
|
||||
else
|
||||
who->CastSpell(who, SPELL_UNSTABLE_SOUL);
|
||||
|
||||
if (TempSummon* tempSum = me->ToTempSummon()) // we need it for disabling call SummonedCreatureDespawn
|
||||
; // (SetSummonerGUID : detachement du summoner, non porte)
|
||||
|
||||
me->DespawnOrUnsummon(100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateTimer = 200;
|
||||
}
|
||||
else
|
||||
updateTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
// 120132, 120131
|
||||
struct npc_tos_essences_intro : ScriptedAI
|
||||
{
|
||||
npc_tos_essences_intro(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
SetCanSeeEvenInPassiveMode(true);
|
||||
}
|
||||
|
||||
std::set<ObjectGuid> players{};
|
||||
uint32 timer = 500;
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (timer <= diff)
|
||||
{
|
||||
Map::PlayerList const& pPlayers = me->GetMap()->GetPlayers();
|
||||
for (const auto& itr : pPlayers)
|
||||
{
|
||||
Player* who = itr.GetSource();
|
||||
if (me->GetDistance(who) < 1.0f)
|
||||
{
|
||||
if (players.find(who->GetGUID()) != players.end())
|
||||
return;
|
||||
|
||||
players.insert(who->GetGUID());
|
||||
|
||||
uint32 enemySpell = (me->GetEntry() == 120132 ? 239408 : 239407);
|
||||
if (who->HasAura(enemySpell))
|
||||
who->CastSpell(who, 239409);
|
||||
else
|
||||
who->CastSpell(who, (me->GetEntry() != 120132 ? 239408 : 239407));
|
||||
}
|
||||
}
|
||||
|
||||
timer = 500;
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
// 235271
|
||||
class spell_tos_infusion : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_infusion);
|
||||
|
||||
std::vector<uint32> spellsForTank{ SPELL_LIGHT_INFUSION, SPELL_FEL_INFUSION };
|
||||
|
||||
void CorrectTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
auto caster = GetCaster();
|
||||
|
||||
if (caster->IsCreature())
|
||||
caster->ToCreature()->AI()->Talk(SAY_INFUSION_END);
|
||||
|
||||
targets.remove_if([](WorldObject* target)
|
||||
{
|
||||
return !target->IsPlayer();
|
||||
});
|
||||
|
||||
for (auto itr = targets.begin(); itr != targets.end(); )
|
||||
{
|
||||
Unit* target = (*itr)->ToUnit();
|
||||
if (!target->IsPlayer())
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto spell : { SPELL_LIGHT_INFUSION, SPELL_FEL_INFUSION })
|
||||
target->ToUnit()->RemoveAurasDueToSpell(spell);
|
||||
|
||||
if (Player* player = target->ToPlayer())
|
||||
if (ROLE_TANK == player->GetRoleForGroup() && !spellsForTank.empty()) // tanks have are different buffs
|
||||
{
|
||||
caster->CastSpell(player, spellsForTank.back(), true);
|
||||
spellsForTank.pop_back();
|
||||
itr = targets.erase(itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
++itr;
|
||||
}
|
||||
|
||||
uint8 i = 0;
|
||||
for (auto target : targets)
|
||||
{
|
||||
if (!target->IsPlayer())
|
||||
continue;
|
||||
|
||||
for (auto spell : { SPELL_LIGHT_INFUSION, SPELL_FEL_INFUSION })
|
||||
target->ToUnit()->RemoveAurasDueToSpell(spell);
|
||||
|
||||
if (++i <= (targets.size() / 2))
|
||||
caster->CastSpell(target->ToUnit(), SPELL_LIGHT_INFUSION, true);
|
||||
else
|
||||
caster->CastSpell(target->ToUnit(), SPELL_FEL_INFUSION, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tos_infusion::CorrectTargets, SpellEffIndex::EFFECT_0, Targets::TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 248812
|
||||
class spell_tos_blowback : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_blowback);
|
||||
|
||||
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (!GetCaster() || !GetTarget())
|
||||
return;
|
||||
|
||||
if (GetCaster()->GetDistance2d(GetTarget()) >= 60.0f)
|
||||
SetDuration(10);
|
||||
else
|
||||
SetDuration(1000*(60-GetCaster()->GetDistance2d(GetTarget())) * 12.0f / 60.0f);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_tos_blowback::OnApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 234896, 236432
|
||||
class spell_tos_wrath_of_the_creators : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tos_wrath_of_the_creators);
|
||||
|
||||
void HandleDamage(SpellEffIndex /*effectIndex*/)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
if (auto caster = GetCaster())
|
||||
{
|
||||
uint32 count = caster->GetAuraCount(SPELL_WRATH_OF_THE_CREATORS_BUFF);
|
||||
|
||||
SetHitDamage(GetHitDamage() * (1 + 0.05*count));
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tos_wrath_of_the_creators::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
// 235117
|
||||
class spell_tos_unstable_soul : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_unstable_soul);
|
||||
|
||||
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (!GetTarget())
|
||||
return;
|
||||
Unit* target = GetTarget();
|
||||
|
||||
if (target->GetAuraCount(235117) <= 1)
|
||||
{
|
||||
target->CastSpell(target, 249912);
|
||||
return;
|
||||
}
|
||||
|
||||
Aura* aura = GetAura();
|
||||
|
||||
if (target->GetMap()->IsMythic())
|
||||
{
|
||||
target->RemoveAppliedAuras(235117, [aura](AuraApplication const* aplication) -> bool
|
||||
{
|
||||
Aura const* curAura = aplication->GetBase();
|
||||
return curAura != aura;
|
||||
});
|
||||
target->CastSpell(target, 249912);
|
||||
}
|
||||
else
|
||||
target->RemoveAura(aura);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_tos_unstable_soul::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 235213 235240
|
||||
class spell_tos_infusions : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tos_infusions);
|
||||
|
||||
bool isFirstTick = true;
|
||||
|
||||
void OnTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
|
||||
if (isFirstTick)
|
||||
{
|
||||
isFirstTick = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
target->RemoveAurasDueToSpell(GetSpellInfo()->Id == SPELL_FEL_INFUSION ? 241316 : 241315);
|
||||
if (target->IsAlive())
|
||||
target->CastSpell(target, GetSpellInfo()->Id == SPELL_FEL_INFUSION ? 241316 : 241315, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tos_infusions::OnTick, EFFECT_0, SPELL_AURA_ANY);
|
||||
}
|
||||
};
|
||||
|
||||
// 241593
|
||||
class spell_egvin_levitation : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_egvin_levitation);
|
||||
|
||||
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (!GetTarget())
|
||||
return;
|
||||
Unit* target = GetTarget();
|
||||
|
||||
if (!target->GetMap()->IsHeroicPlusRaid())
|
||||
target->CastSpell(target, 241565, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_egvin_levitation::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void AddSC_boss_maiden_of_vigilance()
|
||||
{
|
||||
RegisterCreatureAI(boss_maiden_of_vigilance);
|
||||
RegisterCreatureAI(npc_tos_essences);
|
||||
RegisterCreatureAI(npc_tos_essences_intro);
|
||||
RegisterSpellScript(spell_tos_infusion);
|
||||
RegisterAuraScript(spell_tos_blowback);
|
||||
RegisterSpellScript(spell_tos_wrath_of_the_creators);
|
||||
RegisterAuraScript(spell_tos_unstable_soul);
|
||||
RegisterAuraScript(spell_tos_infusions);
|
||||
RegisterAuraScript(spell_egvin_levitation);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,391 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 MagicStaorm
|
||||
*
|
||||
* Este codigo es de uso exclusivo y privado para la red de gaming
|
||||
* ColossusWoW está totalmente prohibida su distribución y
|
||||
* uso en proyectos ajenos, si has obtenido o encontrado este codigo
|
||||
* publicamente envianos un email a administracion@colossuswow.com
|
||||
* indicandonos como y donde has obtenido este codigo
|
||||
*
|
||||
* Recuerda, no distribuyas, no compartas y no subas este codigo a ningun
|
||||
* lugar publico, usa siempre nuestros repositorios Git!
|
||||
*/
|
||||
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum atriganSpells
|
||||
{
|
||||
SPELL_TORMENT = 233104,
|
||||
SPELL_BONE_SCYTHE = 233423,
|
||||
SPELL_SCYTHE_SWIP = 233426,
|
||||
SPELL_BONE_SAW = 233441,
|
||||
SPELL_UNBEARABLE_TORMENT = 233430,
|
||||
};
|
||||
|
||||
enum atriganEvents
|
||||
{
|
||||
EVENT_TORMENT = 1,
|
||||
EVENT_BONE_SCYTHE,
|
||||
EVENT_SCYTHE_SWIP,
|
||||
EVENT_BONE_SAW,
|
||||
EVENT_CHECK_FOR_PLAYERS,
|
||||
};
|
||||
|
||||
class boss_atrigan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_atrigan() : CreatureScript("boss_atrigan") {}
|
||||
|
||||
struct boss_atriganAI : public BossAI
|
||||
{
|
||||
boss_atriganAI(Creature* creature) : BossAI(creature, DATA_ATRIGAN)
|
||||
{
|
||||
instance->SetBossState(DATA_ATRIGAN, NOT_STARTED);
|
||||
}
|
||||
|
||||
Vehicle* vehicle;
|
||||
bool isCasting;
|
||||
int8 count = 0;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
instance->SetBossState(DATA_ATRIGAN, FAIL);
|
||||
}
|
||||
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
_DespawnAtEvade(0, nullptr);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
//Talk(SAY_COMBAT);
|
||||
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
|
||||
SetPlayersInCombat(true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustDied();
|
||||
instance->SetBossState(DATA_ATRIGAN, DONE);
|
||||
}
|
||||
|
||||
//Talk(SAY_DIED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
//if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
// Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_ATRIGAN, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void DespawnGameObjects(uint32 entry)
|
||||
{
|
||||
std::list<GameObject*> gameObjects;
|
||||
GetGameObjectListWithEntryInGrid(gameObjects, me, entry, 1000.0f);
|
||||
|
||||
if (gameObjects.empty())
|
||||
return;
|
||||
|
||||
for (std::list<GameObject*>::iterator iter = gameObjects.begin(); iter != gameObjects.end(); ++iter)
|
||||
(*iter)->Delete();
|
||||
}
|
||||
|
||||
void DespawnCreatures(uint32 entry)
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
GetCreatureListWithEntryInGrid(creatures, me, entry, 1000.0f);
|
||||
|
||||
if (creatures.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::iterator iter = creatures.begin(); iter != creatures.end(); ++iter)
|
||||
(*iter)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void SetPlayersInCombat(bool evade)
|
||||
{
|
||||
uint8 players = 0;
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (Player *player = i->GetSource())
|
||||
{
|
||||
if (player->IsAlive() && player->GetDistance(me) <= 150.0f && !player->IsGameMaster())
|
||||
{
|
||||
++players;
|
||||
|
||||
player->SetInCombatWith(me->ToUnit());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (players == 0 && evade == true)
|
||||
_EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_TORMENT:
|
||||
break;
|
||||
|
||||
case EVENT_BONE_SCYTHE:
|
||||
break;
|
||||
|
||||
case EVENT_SCYTHE_SWIP:
|
||||
break;
|
||||
|
||||
case EVENT_BONE_SAW:
|
||||
break;
|
||||
|
||||
case EVENT_CHECK_FOR_PLAYERS:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<boss_atriganAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
enum belacSpells
|
||||
{
|
||||
SPELL_PANGS_OF_GUILT = 239401,
|
||||
SPELL_CONFESS = 233652,
|
||||
SPELL_TORMENTING_BURST = 234015,
|
||||
SPELL_ECHOING_ANGUIS = 233983,
|
||||
SPELL_FEL_SQUAL = 235230,
|
||||
};
|
||||
|
||||
enum belacEvents
|
||||
{
|
||||
EVENT_PANGS_OF_GUILT = 1,
|
||||
EVENT_CONFESS,
|
||||
EVENT_TORMENTING_BURST,
|
||||
EVENT_ECHOING_ANGUIS,
|
||||
EVENT_FEL_SQUAL,
|
||||
};
|
||||
|
||||
class boss_belac : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_belac() : CreatureScript("boss_belac") {}
|
||||
|
||||
struct boss_belacAI : public BossAI
|
||||
{
|
||||
boss_belacAI(Creature* creature) : BossAI(creature, DATA_BELAC)
|
||||
{
|
||||
instance->SetBossState(DATA_BELAC, NOT_STARTED);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
instance->SetBossState(DATA_BELAC, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
_DespawnAtEvade(0, nullptr);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
//Talk(SAY_COMBAT);
|
||||
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
|
||||
SetPlayersInCombat(true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustDied();
|
||||
instance->SetBossState(DATA_BELAC, DONE);
|
||||
}
|
||||
|
||||
//Talk(SAY_DIED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
//if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
// Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_BELAC, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void DespawnGameObjects(uint32 entry)
|
||||
{
|
||||
std::list<GameObject*> gameObjects;
|
||||
GetGameObjectListWithEntryInGrid(gameObjects, me, entry, 1000.0f);
|
||||
|
||||
if (gameObjects.empty())
|
||||
return;
|
||||
|
||||
for (std::list<GameObject*>::iterator iter = gameObjects.begin(); iter != gameObjects.end(); ++iter)
|
||||
(*iter)->Delete();
|
||||
}
|
||||
|
||||
void DespawnCreatures(uint32 entry)
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
GetCreatureListWithEntryInGrid(creatures, me, entry, 1000.0f);
|
||||
|
||||
if (creatures.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::iterator iter = creatures.begin(); iter != creatures.end(); ++iter)
|
||||
(*iter)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void SetPlayersInCombat(bool evade)
|
||||
{
|
||||
uint8 players = 0;
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (Player *player = i->GetSource())
|
||||
{
|
||||
if (player->IsAlive() && player->GetDistance(me) <= 150.0f && !player->IsGameMaster())
|
||||
{
|
||||
++players;
|
||||
|
||||
player->SetInCombatWith(me->ToUnit());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (players == 0 && evade == true)
|
||||
_EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_PANGS_OF_GUILT:
|
||||
break;
|
||||
|
||||
case EVENT_CONFESS:
|
||||
break;
|
||||
|
||||
case EVENT_TORMENTING_BURST:
|
||||
break;
|
||||
|
||||
case EVENT_ECHOING_ANGUIS:
|
||||
break;
|
||||
|
||||
case EVENT_FEL_SQUAL:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<boss_belacAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_demonic_inquisition()
|
||||
{
|
||||
new boss_atrigan();
|
||||
new boss_belac();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SPIRIT_WORLD = 235621
|
||||
};
|
||||
|
||||
void AddSC_boss_desolate_host()
|
||||
{
|
||||
}
|
||||
@@ -1,392 +0,0 @@
|
||||
/*
|
||||
lyosky
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "PhaseShift.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
//Stage One: A Slumber Disturbed
|
||||
SPELL_TOUCH_OF_SARGERAS = 239207,//?????? 14s 42s mythic 60
|
||||
SPELL_TOUCH_OF_SARGERAS_VISUAL = 234012,//239057 summon
|
||||
SPELL_RUPTURE_REALITIES = 239132,//???? to do 31s 60s phase2 every 37s
|
||||
//SPELL_RUPTURE_REALITIES = 239132,235572
|
||||
//SPELL_RUPTURE_REALITIES = 239152, //???? 236419 dmg 234090 visual
|
||||
SPELL_UNBOUND_CHAOS = 234059, //7s 35-60 s
|
||||
SPELL_UNBOUND_CHAOS_MARK = 239482,
|
||||
SPELL_SHADOWY_BLADES = 236571,//27s 30-46 236591/???? 241588
|
||||
SPELL_SHADOWY_BLADES_MOVETO = 236591,
|
||||
SPELL_SHADOWY_BLADES_DMG = 241588,
|
||||
SPELL_DESOLATE = 236494,//?? 13s-19s 11.4s
|
||||
//Maiden of Valor
|
||||
NPC_MAIDEN_OF_VALOR = 120437,
|
||||
SPELL_CORRUPTED_MATRIX = 233556,// 10s 40s
|
||||
SPELL_MATRIX_EMPOWERMENT = 233961,// add
|
||||
SPELL_CLEANSING_PROTOCOL = 233856,
|
||||
SPELL_MALFUNCTION = 233739,// on 233856 remove ,damage 25%hp
|
||||
//Stage Two: An Avatar Awakened
|
||||
SPELL_DARK_MARK = 239739,//???? mythic 31.6 ,21 every mythic 25 34s
|
||||
SPELL_RAIN_OF_THE_DESTROYER = 240396, //only mythic 15s 35s
|
||||
|
||||
SPELL_RIPPLE_OF_DARKNESS = 236528,// on no one in range AOE
|
||||
SPELL_SEAR = 234179, //aura
|
||||
SPELL_INTRO = 239847,//????
|
||||
SPELL_ANNIHILATION = 235597,//PHASE_2 ??
|
||||
SPELL_CONSUME = 240594,//??
|
||||
|
||||
GO_GROUND = 267934,
|
||||
NPC_CORRUPTED_BLADE = 119158,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_INTRO = 1,
|
||||
EVENT_ATTACK_RANGE = 2000,
|
||||
};
|
||||
|
||||
struct boss_fallen_avatar : public BossAI
|
||||
{
|
||||
boss_fallen_avatar(Creature* creature) : BossAI(creature, DATA_FALLEN_AVATAR) { Initialize(); }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
PhaseStatus = PHASE_01;
|
||||
SetCombatMovement(false);
|
||||
//me->SetDisableGravity(true);
|
||||
IsLock = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
if (Creature* maidenofvalor = me->FindNearestCreature(NPC_MAIDEN_OF_VALOR, 150.0f, true))
|
||||
maidenofvalor->DespawnOrUnsummon();
|
||||
//if (!me->FindNearestGameObject(GO_GROUND, 500.0f))
|
||||
// me->SummonGameObject(GO_GROUND, Position(5825.93f, -1216.87f, 2787.37f, 0.872664f), QuaternionData(), WEEK);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
instance->DoDelayedConversation(5000, 4955);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case 1:
|
||||
SwitchPhase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (me->HealthWillBeBelowPctDamaged(20, damage))
|
||||
SwitchPhase();
|
||||
}
|
||||
|
||||
void SwitchPhase()
|
||||
{
|
||||
if(PhaseStatus == PHASE_01)
|
||||
{
|
||||
PhaseStatus = PHASE_02;
|
||||
SetCombatMovement(true);
|
||||
//me->SetDisableGravity(false);
|
||||
if (GameObject* ground = me->FindNearestGameObject(GO_GROUND, 150.0f))
|
||||
ground->Delete();
|
||||
|
||||
events.Reset();
|
||||
DoCastSelf(SPELL_ANNIHILATION);
|
||||
AddTimedDelayedOperation(3500, [this]() -> void
|
||||
{
|
||||
me->NearTeleportTo(Position(6621.16f, -794.8966f, 1519.918f, 2.9986f));
|
||||
instance->DoNearTeleportPlayers(Position(6561.1f, -791.82f, 1509.91f, 6.2429f));
|
||||
DoCastSelf(SPELL_ANNIHILATION);
|
||||
});
|
||||
AddTimedDelayedOperation(5000, [this]() -> void
|
||||
{
|
||||
//me->GetMotionMaster()->Clear();
|
||||
//me->GetMotionMaster()->MovePoint(0, Position(6561.1f, -791.82f, 1509.91f, 6.2429f), true);
|
||||
//me->GetMotionMaster()->MoveChase(me->SelectNearestPlayer());
|
||||
DoCastSelf(SPELL_SEAR);
|
||||
events.ScheduleEvent(SPELL_RUPTURE_REALITIES, 37s);
|
||||
events.ScheduleEvent(SPELL_DESOLATE, 19s);
|
||||
if (IsMythic())
|
||||
events.ScheduleEvent(SPELL_DARK_MARK, 31s, 32s);
|
||||
else
|
||||
events.ScheduleEvent(SPELL_DARK_MARK, 21s);
|
||||
if (IsMythic())
|
||||
events.ScheduleEvent(SPELL_RAIN_OF_THE_DESTROYER, 15s);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
PhaseStatus = PHASE_01;
|
||||
me->RemoveAurasDueToSpell(SPELL_INTRO);
|
||||
events.ScheduleEvent(SPELL_TOUCH_OF_SARGERAS, 14s, 15s);
|
||||
events.ScheduleEvent(SPELL_RUPTURE_REALITIES, 31s);
|
||||
events.ScheduleEvent(SPELL_UNBOUND_CHAOS, 7s);
|
||||
events.ScheduleEvent(SPELL_SHADOWY_BLADES, 27s);
|
||||
events.ScheduleEvent(SPELL_DESOLATE, 13s);
|
||||
events.ScheduleEvent(NPC_MAIDEN_OF_VALOR, 4s);
|
||||
|
||||
//events.ScheduleEvent(SPELL_ANNIHILATION, 120s);
|
||||
//events.ScheduleEvent(SPELL_FEL_INFUSION, 5s);
|
||||
//events.ScheduleEvent(SPELL_CONSUME, 5s);
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
/*
|
||||
for (auto threat : me->getThreatManager().getThreatList())
|
||||
if (me->IsWithinCombatRange(threat->getTarget(), me->GetCombatReach()))
|
||||
me->RemoveAurasDueToSpell(SPELL_RIPPLE_OF_DARKNESS);
|
||||
*/
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case SPELL_TOUCH_OF_SARGERAS:
|
||||
{
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
{
|
||||
me->CastSpell(target1, SPELL_TOUCH_OF_SARGERAS, false);
|
||||
|
||||
AddTimedDelayedOperation(2500, [this, target1]() -> void
|
||||
{
|
||||
me->CastSpell(target1, SPELL_TOUCH_OF_SARGERAS_VISUAL, false);
|
||||
});
|
||||
}
|
||||
|
||||
if(IsMythic())
|
||||
events.Repeat(60s);
|
||||
else
|
||||
events.Repeat(42s);
|
||||
break;
|
||||
}
|
||||
case SPELL_RUPTURE_REALITIES:
|
||||
{
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
me->CastSpell(target1, SPELL_RUPTURE_REALITIES, false);
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
me->SummonCreature(NPC_CORRUPTED_BLADE, me->GetRandomNearPosition(10.0f), TEMPSUMMON_MANUAL_DESPAWN, WEEK);
|
||||
|
||||
if (PhaseStatus == PHASE_01)
|
||||
events.Repeat(60s);
|
||||
else
|
||||
events.Repeat(37s);
|
||||
break;
|
||||
}
|
||||
case SPELL_UNBOUND_CHAOS:
|
||||
{
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
{
|
||||
me->CastSpell(target1, SPELL_UNBOUND_CHAOS, false);
|
||||
AddTimedDelayedOperation(500, [this, target1]() -> void
|
||||
{
|
||||
me->CastSpell(target1, SPELL_UNBOUND_CHAOS_MARK, false);
|
||||
});
|
||||
AddTimedDelayedOperation(1000, [this, target1]() -> void
|
||||
{
|
||||
me->CastSpell(target1, SPELL_UNBOUND_CHAOS_MARK, false);
|
||||
});
|
||||
AddTimedDelayedOperation(1500, [this, target1]() -> void
|
||||
{
|
||||
me->CastSpell(target1, SPELL_UNBOUND_CHAOS_MARK, false);
|
||||
});
|
||||
}
|
||||
|
||||
events.Repeat(35s);
|
||||
break;
|
||||
}
|
||||
case SPELL_SHADOWY_BLADES:
|
||||
{
|
||||
DoCast(SPELL_SHADOWY_BLADES);
|
||||
events.Repeat(30s);
|
||||
break;
|
||||
}
|
||||
case SPELL_DESOLATE:
|
||||
{
|
||||
DoCast(SPELL_DESOLATE);
|
||||
events.Repeat(11s, 12s);
|
||||
break;
|
||||
}
|
||||
case NPC_MAIDEN_OF_VALOR:
|
||||
{
|
||||
me->SummonCreature(NPC_MAIDEN_OF_VALOR, me->GetPositionWithDistInFront(25.0f), TEMPSUMMON_MANUAL_DESPAWN, WEEK);
|
||||
break;
|
||||
}
|
||||
case SPELL_DARK_MARK:
|
||||
{
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
me->CastSpell(target1, SPELL_DARK_MARK, false);
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
me->CastSpell(target1, SPELL_DARK_MARK, false);
|
||||
if (IsMythic())
|
||||
events.Repeat(25s);
|
||||
else
|
||||
events.Repeat(34s);
|
||||
break;
|
||||
}
|
||||
case SPELL_RAIN_OF_THE_DESTROYER:
|
||||
{
|
||||
DoCast(SPELL_RAIN_OF_THE_DESTROYER);
|
||||
events.Repeat(35s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (me->GetDistance2d(me->SelectNearestPlayer())>me->GetCombatReach())
|
||||
me->CastSpell(me, SPELL_RIPPLE_OF_DARKNESS, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->IsPlayer() && me->IsWithinDist(who, 25.0f, false) && !IsLock)
|
||||
{
|
||||
IsLock = true;
|
||||
instance->DoConversation(4899);
|
||||
if (Creature* jidan = me->FindNearestCreature(120867, 50.0f, true))
|
||||
{
|
||||
AddTimedDelayedOperation(25000, [this, jidan]() -> void
|
||||
{
|
||||
jidan->CastSpell(me, 240897, true);
|
||||
me->RemoveAurasDueToSpell(SPELL_INTRO);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
me->NearTeleportTo(me->GetPositionWithDistInFront(20.0f));
|
||||
});
|
||||
AddTimedDelayedOperation(30000, [this, jidan]() -> void
|
||||
{
|
||||
PhasingHandler::AddPhase(jidan, 180, true);
|
||||
});
|
||||
//jidan->DespawnOrUnsummon(30000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
case NPC_MAIDEN_OF_VALOR:
|
||||
{
|
||||
summon->setFaction(me->getFaction());
|
||||
uint64 health = (uint64)(me->GetMaxHealth()*0.5f);
|
||||
summon->SetMaxHealth(health);
|
||||
summon->SetHealth(health);
|
||||
break;
|
||||
}
|
||||
case NPC_CORRUPTED_BLADE:
|
||||
{
|
||||
summon->setFaction(me->getFaction());
|
||||
if (Unit* target1 = SelectTarget(SELECT_TARGET_RANDOM, 0.0, 0.0, true))
|
||||
{
|
||||
AddTimedDelayedOperation(3000, [this, summon, target1]() -> void
|
||||
{
|
||||
summon->CastSpell(target1, SPELL_SHADOWY_BLADES_MOVETO, false);
|
||||
});
|
||||
AddTimedDelayedOperation(5500, [this, summon, target1]() -> void
|
||||
{
|
||||
summon->CastSpell(target1, SPELL_SHADOWY_BLADES_DMG, false);
|
||||
summon->DespawnOrUnsummon();
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
*/
|
||||
uint8 PhaseStatus;
|
||||
uint8 PHASE_01;
|
||||
uint8 PHASE_02;
|
||||
bool IsLock;
|
||||
};
|
||||
|
||||
struct npc_maiden_of_valor_120437 : public ScriptedAI
|
||||
{
|
||||
npc_maiden_of_valor_120437(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* boss = me->FindNearestCreature(NPC_FALLEN_AVATAR, 150.0f, true))
|
||||
boss->AI()->DoAction(1);
|
||||
}
|
||||
/*
|
||||
SPELL_CORRUPTED_MATRIX = 233556,// 10s 40s
|
||||
SPELL_MATRIX_EMPOWERMENT = 233961,// add
|
||||
SPELL_CLEANSING_PROTOCOL = 233856,
|
||||
SPELL_MALFUNCTION = 233739,// on 233856 remove ,damage 25%hp
|
||||
*/
|
||||
void EnterCombat(Unit* /*victim*/)
|
||||
{
|
||||
events.ScheduleEvent(SPELL_CORRUPTED_MATRIX, 10s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case SPELL_CORRUPTED_MATRIX:
|
||||
{
|
||||
DoCast(SPELL_CORRUPTED_MATRIX);
|
||||
events.Repeat(40s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
int8 IsLock;
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (who->IsPlayer() && me->IsWithinDist(who, 25.0f, false) && !IsLock)
|
||||
{
|
||||
IsLock = true;
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_corrupted_blade_119158 : public ScriptedAI
|
||||
{
|
||||
npc_corrupted_blade_119158(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetCombatMovement(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override { }
|
||||
};
|
||||
|
||||
void AddSC_boss_fallen_avatar()
|
||||
{
|
||||
RegisterCreatureAI(boss_fallen_avatar);
|
||||
RegisterCreatureAI(npc_maiden_of_valor_120437);
|
||||
RegisterCreatureAI(npc_corrupted_blade_119158);
|
||||
}
|
||||
@@ -1,428 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "AreaTriggerTemplate.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Goroth
|
||||
SPELL_BURNING_ARMOR = 231363,
|
||||
SPELL_BURNING_ERUPTION = 231395, // Casted at SPELL_BURNING_ARMOR end
|
||||
|
||||
SPELL_CRASHING_COMET = 232249,
|
||||
SPELL_CRASHING_COMET_DAMAGE = 230345,
|
||||
|
||||
SPELL_INFERNAL_SPIKE_SUMMON = 233055,
|
||||
SPELL_INFERNAL_SPIKE = 233019,
|
||||
SPELL_INFERNAL_SPIKE_PROTECTION = 234475,
|
||||
|
||||
SPELL_SHATTERING_STAR = 233272,
|
||||
SPELL_SHATTERING_STAR_AT = 233279,
|
||||
SPELL_SHATTERING_STAR_DAMAGE = 233281,
|
||||
SPELL_SHATTERING_STAR_FINAL_DAMAGE = 233283,
|
||||
|
||||
SPELL_INFERNAL_BURNING = 233062,
|
||||
SPELL_INFERNAL_BURNING_REMOVE_SPIKES = 233078,
|
||||
|
||||
// Infernal chaosbringer
|
||||
SPELL_MASSIVE_ERUPTION = 242909
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_INFERNAL_SPIKE = 116976,
|
||||
|
||||
SPELLVISUAL_INFERNAL_SPIKE_DESTROY = 66119,
|
||||
|
||||
AT_SHATTERING_STAR = 13412
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 1,
|
||||
SAY_KILL = 2,
|
||||
SAY_WIPE = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_INFERNAL_BURNING = 5,
|
||||
SAY_SHATTERING_STAR = 6,
|
||||
SAY_INFERNAL_SPIKE = 7
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MASSIVE_ERUPTION = 1
|
||||
};
|
||||
|
||||
struct boss_goroth : public BossAI
|
||||
{
|
||||
boss_goroth(Creature* creature) : BossAI(creature, DATA_GOROTH) { }
|
||||
|
||||
void EnterCombat(Unit* /*attacker*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_GOROTH, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(SPELL_BURNING_ARMOR, 16s);
|
||||
events.ScheduleEvent(SPELL_CRASHING_COMET, 10s, 20s);
|
||||
events.ScheduleEvent(SPELL_INFERNAL_SPIKE_SUMMON, 12s);
|
||||
events.ScheduleEvent(SPELL_SHATTERING_STAR, 10s, 20s);
|
||||
events.ScheduleEvent(SPELL_INFERNAL_BURNING, 55s);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
instance->SetBossState(DATA_GOROTH, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
Talk(SAY_WIPE);
|
||||
instance->SetBossState(DATA_GOROTH, FAIL);
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case SPELL_BURNING_ARMOR:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
|
||||
DoCast(target, SPELL_BURNING_ARMOR);
|
||||
|
||||
events.Repeat(16s);
|
||||
break;
|
||||
}
|
||||
case SPELL_CRASHING_COMET:
|
||||
{
|
||||
UnitList targetList;
|
||||
SelectTargetList(targetList, 3, SELECT_TARGET_RANDOM, 200.0f, true);
|
||||
|
||||
for (Unit* target : targetList)
|
||||
DoCast(target, SPELL_CRASHING_COMET, true);
|
||||
|
||||
events.Repeat(10s, 20s);
|
||||
break;
|
||||
}
|
||||
case SPELL_INFERNAL_SPIKE_SUMMON:
|
||||
{
|
||||
Talk(SAY_INFERNAL_SPIKE);
|
||||
UnitList targetList;
|
||||
SelectTargetList(targetList, 3, SELECT_TARGET_RANDOM, 200.0f, true);
|
||||
|
||||
for (Unit* target : targetList)
|
||||
DoCast(target, SPELL_INFERNAL_SPIKE_SUMMON);
|
||||
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
}
|
||||
case SPELL_SHATTERING_STAR:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 2))
|
||||
{
|
||||
Talk(SAY_SHATTERING_STAR);
|
||||
_shatteringStarTargetGUID = target->GetGUID();
|
||||
DoCast(target, SPELL_SHATTERING_STAR);
|
||||
}
|
||||
|
||||
events.Repeat(10s, 20s);
|
||||
break;
|
||||
}
|
||||
case SPELL_INFERNAL_BURNING:
|
||||
{
|
||||
Talk(SAY_INFERNAL_BURNING);
|
||||
DoCast(SPELL_INFERNAL_BURNING);
|
||||
events.Repeat(55s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
BossAI::JustSummoned(summon);
|
||||
|
||||
if (summon->GetEntry() == NPC_INFERNAL_SPIKE)
|
||||
summon->CastSpell(summon, SPELL_INFERNAL_SPIKE, false);
|
||||
}
|
||||
|
||||
ObjectGuid GetGUID(int32 /*id*/ = 0) const override
|
||||
{
|
||||
return _shatteringStarTargetGUID;
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectGuid _shatteringStarTargetGUID;
|
||||
};
|
||||
|
||||
struct infernal_chaosbringer : public ScriptedAI
|
||||
{
|
||||
infernal_chaosbringer(Creature* creature) : ScriptedAI(creature), Summons(me) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->CombatStop(true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_MASSIVE_ERUPTION, 15s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MASSIVE_ERUPTION:
|
||||
|
||||
DoCastAOE(SPELL_MASSIVE_ERUPTION);
|
||||
_events.Repeat(15s);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
SummonList Summons;
|
||||
};
|
||||
|
||||
// 231363
|
||||
class spell_burning_armor : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_burning_armor);
|
||||
|
||||
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->CastSpell(nullptr, SPELL_BURNING_ERUPTION, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_burning_armor::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 232249
|
||||
class aura_crashing_comet : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(aura_crashing_comet);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(GetTarget(), SPELL_CRASHING_COMET_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(aura_crashing_comet::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 230345
|
||||
class spell_crashing_comet_damage : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_crashing_comet_damage);
|
||||
|
||||
void HandleHit(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
CreatureList infernalSpikes;
|
||||
target->GetCreatureListWithEntryInGrid(infernalSpikes, NPC_INFERNAL_SPIKE, GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius());
|
||||
|
||||
for (Creature* infernalSpike : infernalSpikes)
|
||||
{
|
||||
infernalSpike->SendPlaySpellVisual(infernalSpike->GetGUID(), SPELLVISUAL_INFERNAL_SPIKE_DESTROY);
|
||||
infernalSpike->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_crashing_comet_damage::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
// 233062
|
||||
class spell_infernal_burning : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_infernal_burning);
|
||||
|
||||
void BeforeCastHandler()
|
||||
{
|
||||
Creature* caster = GetCaster()->ToCreature();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
CreatureList infernalSpikes;
|
||||
caster->GetCreatureListWithEntryInGrid(infernalSpikes, NPC_INFERNAL_SPIKE, 200.0f);
|
||||
|
||||
for (auto reference : caster->getThreatManager().getThreatList())
|
||||
for (Creature* spike : infernalSpikes)
|
||||
if (spike->IsInBetween(GetCaster(), reference->getTarget(), 2.0f))
|
||||
reference->getTarget()->AddAura(SPELL_INFERNAL_SPIKE_PROTECTION);
|
||||
}
|
||||
|
||||
void AfterCastHandler()
|
||||
{
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
for (auto reference : caster->getThreatManager().getThreatList())
|
||||
reference->getTarget()->RemoveAurasDueToSpell(SPELL_INFERNAL_SPIKE_PROTECTION);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeCast += SpellCastFn(spell_infernal_burning::BeforeCastHandler);
|
||||
AfterCast += SpellCastFn(spell_infernal_burning::AfterCastHandler);
|
||||
}
|
||||
};
|
||||
|
||||
// 233078
|
||||
class spell_infernal_burning_remove_spikes : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_infernal_burning_remove_spikes);
|
||||
|
||||
void HandleOnCast()
|
||||
{
|
||||
CreatureList infernalSpikes;
|
||||
GetCaster()->GetCreatureListWithEntryInGrid(infernalSpikes, NPC_INFERNAL_SPIKE, GetSpellInfo()->GetMaxRange());
|
||||
|
||||
for (Creature* infernalSpike : infernalSpikes)
|
||||
{
|
||||
infernalSpike->SendPlaySpellVisual(GetCaster()->GetGUID(), SPELLVISUAL_INFERNAL_SPIKE_DESTROY);
|
||||
infernalSpike->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCast += SpellCastFn(spell_infernal_burning_remove_spikes::HandleOnCast);
|
||||
}
|
||||
};
|
||||
|
||||
// 233274
|
||||
class spell_shattering_star_dummy : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_shattering_star_dummy);
|
||||
|
||||
void HandleHit(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Creature* goroth = GetHitUnit()->ToCreature())
|
||||
if (goroth->AI())
|
||||
goroth->CastSpell(GetCaster(), SPELL_SHATTERING_STAR_AT, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_shattering_star_dummy::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
//AT : 13412
|
||||
//Spell : 233279
|
||||
struct at_goroth_shattering_star : AreaTriggerAI
|
||||
{
|
||||
at_goroth_shattering_star(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
|
||||
|
||||
void OnInitialize() override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Creature* creCaster = caster->ToCreature())
|
||||
if (creCaster->IsAIEnabled)
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*creCaster, creCaster->AI()->GetGUID()))
|
||||
at->SetDestination(*target, 1000);
|
||||
}
|
||||
|
||||
void OnUnitEnter(Unit* unit) override
|
||||
{
|
||||
if (unit->GetEntry() == NPC_INFERNAL_SPIKE)
|
||||
{
|
||||
++_infernalSpikeTouched;
|
||||
unit->SendPlaySpellVisual(unit->GetGUID(), SPELLVISUAL_INFERNAL_SPIKE_DESTROY);
|
||||
unit->ToCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
else if (Unit* caster = at->GetCaster())
|
||||
{
|
||||
if (caster->IsValidAttackTarget(unit))
|
||||
caster->CastSpell(unit, SPELL_SHATTERING_STAR_DAMAGE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestinationReached() override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_SHATTERING_STAR_FINAL_DAMAGE))
|
||||
if (SpellEffectInfo const* spellEffectInfo = spellInfo->GetEffect(caster->GetMap()->GetDifficultyID(), EFFECT_0))
|
||||
caster->CastCustomSpell(SPELL_SHATTERING_STAR_FINAL_DAMAGE, SPELLVALUE_BASE_POINT0, spellEffectInfo->BasePoints / std::max(_infernalSpikeTouched, uint8(1)), nullptr, TRIGGERED_FULL_MASK);
|
||||
|
||||
// TODO : Deal damage to target if _infernalSpikeTouched == 0
|
||||
at->Remove();
|
||||
}
|
||||
|
||||
uint8 _infernalSpikeTouched = 0;
|
||||
};
|
||||
|
||||
void AddSC_boss_goroth()
|
||||
{
|
||||
RegisterCreatureAI(boss_goroth);
|
||||
RegisterCreatureAI(infernal_chaosbringer);
|
||||
|
||||
RegisterAuraScript(spell_burning_armor);
|
||||
RegisterAuraScript(aura_crashing_comet);
|
||||
RegisterSpellScript(spell_crashing_comet_damage);
|
||||
RegisterSpellScript(spell_infernal_burning);
|
||||
RegisterSpellScript(spell_infernal_burning_remove_spikes);
|
||||
RegisterSpellScript(spell_shattering_star_dummy);
|
||||
|
||||
RegisterAreaTriggerAI(at_goroth_shattering_star);
|
||||
}
|
||||
@@ -1,640 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 MagicStorm
|
||||
*
|
||||
* Este codigo es de uso exclusivo y privado para la red de gaming
|
||||
* ColossusWoW est? totalmente prohibida su distribuci?n y
|
||||
* uso en proyectos ajenos, si has obtenido o encontrado este codigo
|
||||
* publicamente envianos un email a administracion@colossuswow.com
|
||||
* indicandonos como y donde has obtenido este codigo
|
||||
*
|
||||
* Recuerda, no distribuyas, no compartas y no subas este codigo a ningun
|
||||
* lugar publico, usa siempre nuestros repositorios Git!
|
||||
*/
|
||||
|
||||
#include "AreaTriggerTemplate.h"
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "GameObject.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
enum harjatanSpells
|
||||
{
|
||||
SPELL_ABRASIVE_ARMOR = 233071,
|
||||
SPELL_JAGGED_ABRASION = 231998,
|
||||
SPELL_UNCHECKED_RAGE = 231854,
|
||||
SPELL_COMMANDING_ROAR = 232192,
|
||||
SPELL_DRENCHED = 231770,
|
||||
SPELL_WATERY_SPLASH = 233371,
|
||||
SPELL_AQUEOUS_BURST = 231729,
|
||||
SPELL_AQUEOUS_BURST_DMG = 231754,
|
||||
SPELL_DRIPPING_BLADE = 239907,
|
||||
SPELL_DRIVEN_ASSAULT = 234128,
|
||||
SPELL_SPLASHY_CLEAVE = 234129,
|
||||
SPELL_DRENCHING_WATERS = 231768,
|
||||
SPELL_DRAW_IN = 232061,
|
||||
SPELL_FRIGID_BLOWS = 233429,
|
||||
SPELL_GATHER_ENERGY = 232379,
|
||||
SPELL_ENRAGED = 241587,
|
||||
SPELL_FROSTY_DISCHARGE = 232174,
|
||||
};
|
||||
|
||||
enum harjatanEvents
|
||||
{
|
||||
EVENT_UNCHECKED_RAGE = 1,
|
||||
EVENT_COMMANDING_ROAR,
|
||||
EVENT_WATERY_SPLASH,
|
||||
EVENT_AQUEOUS_BURST,
|
||||
EVENT_DRIVEN_ASSAULT,
|
||||
EVENT_SPLASHY_CLEAVE,
|
||||
EVENT_DRENCHING_WATERS,
|
||||
EVENT_DRAW_IN,
|
||||
EVENT_CHECK_FOR_PLAYERS,
|
||||
};
|
||||
|
||||
class boss_harjatan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_harjatan() : CreatureScript("boss_harjatan") {}
|
||||
|
||||
struct boss_harjatanAI : public BossAI
|
||||
{
|
||||
boss_harjatanAI(Creature* creature) : BossAI(creature, DATA_HARJATAN)
|
||||
{
|
||||
instance->SetBossState(DATA_HARJATAN, NOT_STARTED);
|
||||
|
||||
//me->setPowerType(POWER_ENERGY);
|
||||
me->SetMaxPower(POWER_ENERGY, 100);
|
||||
me->SetPower(POWER_ENERGY, 100);
|
||||
}
|
||||
|
||||
bool isCasting;
|
||||
std::list<Creature*> waveMender;
|
||||
std::list<Creature*> gladiator;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
instance->SetBossState(DATA_HARJATAN, FAIL);
|
||||
}
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(269192, 500.0f))
|
||||
go->SetLootState(GO_READY);
|
||||
|
||||
isCasting = false;
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_GATHER_ENERGY);
|
||||
|
||||
//me->setPowerType(POWER_ENERGY);
|
||||
me->SetMaxPower(POWER_ENERGY, 100);
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
_DespawnAtEvade(0, nullptr);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
DoCast(SPELL_ABRASIVE_ARMOR);
|
||||
|
||||
//Talk(SAY_COMBAT);
|
||||
|
||||
me->SetPower(POWER_ENERGY, 0);
|
||||
|
||||
events.ScheduleEvent(EVENT_COMMANDING_ROAR, 17.3 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_DRAW_IN, 59 * IN_MILLISECONDS);
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(269192, 500.0f))
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(121184, 150.0f))
|
||||
creature->SetVisible(false);
|
||||
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
|
||||
DoCast(SPELL_GATHER_ENERGY);
|
||||
|
||||
SetPlayersInCombat(true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustDied();
|
||||
instance->SetBossState(DATA_HARJATAN, DONE);
|
||||
}
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(269192, 500.0f))
|
||||
go->SetLootState(GO_READY);
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(269120, 500.0f))
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
|
||||
//Talk(SAY_DIED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
//if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
// Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_HARJATAN, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void DespawnGameObjects(uint32 entry)
|
||||
{
|
||||
std::list<GameObject*> gameObjects;
|
||||
GetGameObjectListWithEntryInGrid(gameObjects, me, entry, 1000.0f);
|
||||
|
||||
if (gameObjects.empty())
|
||||
return;
|
||||
|
||||
for (std::list<GameObject*>::iterator iter = gameObjects.begin(); iter != gameObjects.end(); ++iter)
|
||||
(*iter)->Delete();
|
||||
}
|
||||
|
||||
void DespawnCreatures(uint32 entry)
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
GetCreatureListWithEntryInGrid(creatures, me, entry, 1000.0f);
|
||||
|
||||
if (creatures.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::iterator iter = creatures.begin(); iter != creatures.end(); ++iter)
|
||||
(*iter)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void SetPlayersInCombat(bool evade)
|
||||
{
|
||||
uint8 players = 0;
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (Player *player = i->GetSource())
|
||||
{
|
||||
if (player->IsAlive() && player->GetDistance(me) <= 150.0f && !player->IsGameMaster())
|
||||
{
|
||||
++players;
|
||||
|
||||
player->SetInCombatWith(me->ToUnit());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (players == 0 && evade == true)
|
||||
_EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (uint32 power = me->GetPower(POWER_ENERGY))
|
||||
if (power == 100)
|
||||
if (!isCasting)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_UNCHECKED_RAGE, 1 * IN_MILLISECONDS);
|
||||
isCasting = true;
|
||||
}
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_UNCHECKED_RAGE:
|
||||
DoCast(SPELL_UNCHECKED_RAGE);
|
||||
|
||||
isCasting = false;
|
||||
break;
|
||||
|
||||
case EVENT_COMMANDING_ROAR:
|
||||
DoCast(SPELL_COMMANDING_ROAR);
|
||||
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
me->SummonCreature(NPC_RAZORJAW_WAVEMENDER, 5898.825f, -879.8507f, 2941.018f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_RAZORJAW_GLADIATOR, 5876.136f, -887.0951f, 2933.093f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_COMMANDING_ROAR, 31.8 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_DRAW_IN:
|
||||
DoCast(SPELL_DRAW_IN);
|
||||
|
||||
events.ScheduleEvent(EVENT_DRAW_IN, 59 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_CHECK_FOR_PLAYERS:
|
||||
SetPlayersInCombat(true);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_FOR_PLAYERS, 1 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<boss_harjatanAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 116569 - Razorjaw Wavemender
|
||||
class npc_razorjaw_wavemender : public CreatureScript
|
||||
{
|
||||
public:
|
||||
|
||||
npc_razorjaw_wavemender() : CreatureScript("npc_razorjaw_wavemender") { }
|
||||
|
||||
struct npc_razorjaw_wavemenderAI : public ScriptedAI
|
||||
{
|
||||
npc_razorjaw_wavemenderAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_WATERY_SPLASH, 10 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_AQUEOUS_BURST, 12 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_WATERY_SPLASH:
|
||||
if (Unit* target = me->GetVictim())
|
||||
me->CastSpell(target, SPELL_WATERY_SPLASH, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_WATERY_SPLASH, 10 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_AQUEOUS_BURST:
|
||||
if (Unit* target = me->GetVictim()/*SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f, true)*/)
|
||||
me->CastSpell(target, SPELL_AQUEOUS_BURST, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_AQUEOUS_BURST, 16 * IN_MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap events;
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<npc_razorjaw_wavemenderAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 117596 - Razorjaw Gladiator
|
||||
class npc_razorjaw_gladiator : public CreatureScript
|
||||
{
|
||||
public:
|
||||
|
||||
npc_razorjaw_gladiator() : CreatureScript("npc_razorjaw_gladiator") { }
|
||||
|
||||
struct npc_razorjaw_gladiatorAI : public ScriptedAI
|
||||
{
|
||||
npc_razorjaw_gladiatorAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
std::list<AreaTrigger*> areaTriggerList;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
|
||||
me->RemoveAllAreaTriggers();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
DoCast(SPELL_DRIPPING_BLADE);
|
||||
|
||||
events.ScheduleEvent(EVENT_DRIVEN_ASSAULT, 10 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_SPLASHY_CLEAVE, 12 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DRIVEN_ASSAULT:
|
||||
if (Unit* target = me->GetVictim()/*SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f, true)*/)
|
||||
{
|
||||
if (!target->HasAura(240792))
|
||||
{
|
||||
me->CastSpell(target, 234016, true);
|
||||
me->CastSpell(me, SPELL_DRIVEN_ASSAULT, true);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_DRIVEN_ASSAULT, 1 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_DRIVEN_ASSAULT, 10 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_SPLASHY_CLEAVE:
|
||||
DoCast(SPELL_SPLASHY_CLEAVE);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPLASHY_CLEAVE, 12 * IN_MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<npc_razorjaw_gladiatorAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 233429 - frigid blows
|
||||
class spell_harjatan_frigid_blows : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_harjatan_frigid_blows() : SpellScriptLoader("spell_harjatan_frigid_blows") { }
|
||||
|
||||
class spell_harjatan_frigid_blows_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_harjatan_frigid_blows_AuraScript);
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
if (Aura* aura = target->GetAura(GetId()))
|
||||
if (aura->GetStackAmount() <= 1)
|
||||
target->CastSpell(target, SPELL_FROSTY_DISCHARGE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_harjatan_frigid_blows_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_harjatan_frigid_blows_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 231729 - Aqueous Burst
|
||||
class spell_harjatan_aqueous_burst : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_harjatan_aqueous_burst() : SpellScriptLoader("spell_harjatan_aqueous_burst") { }
|
||||
|
||||
class spell_harjatan_aqueous_burst_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_harjatan_aqueous_burst_AuraScript);
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
target->CastSpell(target, SPELL_AQUEOUS_BURST_DMG, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_harjatan_aqueous_burst_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_harjatan_aqueous_burst_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 13251 - Drenching waters
|
||||
class areatrigger_drenching_waters : public AreaTriggerEntityScript
|
||||
{
|
||||
public:
|
||||
areatrigger_drenching_waters() : AreaTriggerEntityScript("areatrigger_drenching_waters") { }
|
||||
|
||||
struct areatrigger_drenching_watersAI : AreaTriggerAI
|
||||
{
|
||||
areatrigger_drenching_watersAI(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
|
||||
|
||||
bool isCasting = false;
|
||||
uint32 checkTime;
|
||||
uint8 count;
|
||||
|
||||
void OnInitialize() override
|
||||
{
|
||||
checkTime = 1000;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
if (checkTime <= diff)
|
||||
{
|
||||
if (Creature* boss = at->FindNearestCreature(BOSS_HARJATAN, 500.0f))
|
||||
if (boss->HasAura(SPELL_DRAW_IN))
|
||||
{
|
||||
Position pos = at->GetNearPosition(float(-count), at->GetAngle(*boss));
|
||||
at->GetMap()->AreaTriggerRelocation(at, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* boss = at->FindNearestCreature(BOSS_HARJATAN, 5.0f))
|
||||
if (boss->HasAura(SPELL_DRAW_IN))
|
||||
{
|
||||
boss->CastSpell(boss, SPELL_FRIGID_BLOWS, true);
|
||||
at->RemoveFromWorld();
|
||||
}
|
||||
|
||||
if (Creature* boss = at->FindNearestCreature(BOSS_HARJATAN, 500.0f, false))
|
||||
at->RemoveFromWorld();
|
||||
|
||||
checkTime = 1000;
|
||||
}
|
||||
else
|
||||
checkTime -= diff;
|
||||
}
|
||||
|
||||
void OnUnitEnter(Unit* target) override
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (Unit* caster = at->GetCaster())
|
||||
caster->CastSpell(target, SPELL_DRENCHING_WATERS, true);
|
||||
}
|
||||
|
||||
void OnUnitExit(Unit* target) override
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (target->HasAura(SPELL_DRENCHING_WATERS))
|
||||
target->RemoveAurasDueToSpell(SPELL_DRENCHING_WATERS);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
AreaTriggerAI* GetAI(AreaTrigger* areatrigger) const override
|
||||
{
|
||||
return new areatrigger_drenching_watersAI(areatrigger);
|
||||
}
|
||||
};
|
||||
|
||||
// 231854 - Unchecked Rage
|
||||
class spell_harjatan_unchecked_rage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_harjatan_unchecked_rage() : SpellScriptLoader("spell_harjatan_unchecked_rage") { }
|
||||
|
||||
class spell_harjatan_unchecked_rage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_harjatan_unchecked_rage_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (auto target : targets)
|
||||
++count;
|
||||
|
||||
if (count < 5)
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, SPELL_ENRAGED, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_harjatan_unchecked_rage_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CONE_ENEMY_104);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_harjatan_unchecked_rage_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 232174 - Frosty Discharge
|
||||
class spell_harjatan_frosty_discharge : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_harjatan_frosty_discharge() : SpellScriptLoader("spell_harjatan_frosty_discharge") { }
|
||||
|
||||
class spell_harjatan_frosty_discharge_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_harjatan_frosty_discharge_SpellScript);
|
||||
|
||||
void HandleDummy()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, GetSpellInfo()->GetEffect(EFFECT_0)->BasePoints, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCast += SpellCastFn(spell_harjatan_frosty_discharge_SpellScript::HandleDummy);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_harjatan_frosty_discharge_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_harjatan()
|
||||
{
|
||||
new boss_harjatan();
|
||||
new npc_razorjaw_wavemender();
|
||||
new npc_razorjaw_gladiator();
|
||||
new spell_harjatan_frigid_blows();
|
||||
new spell_harjatan_aqueous_burst();
|
||||
new areatrigger_drenching_waters();
|
||||
new spell_harjatan_unchecked_rage();
|
||||
new spell_harjatan_frosty_discharge();
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
void AddSC_boss_tos_kiljaeden()
|
||||
{
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
void AddSC_boss_maiden_of_vigilance()
|
||||
{
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
void AddSC_boss_sasszine()
|
||||
{
|
||||
}
|
||||
@@ -1,901 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "SpellScript.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
|
||||
|
||||
//constant positions about teleports and Kasparian Jumps
|
||||
Position const LunaspyreTeleports[5] =
|
||||
{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
};
|
||||
|
||||
Position const CenterCombat[1] =
|
||||
{
|
||||
{},
|
||||
};
|
||||
|
||||
Position const YathaeTeleports[5] =
|
||||
{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
};
|
||||
|
||||
Position const KasparianJumps[5] =
|
||||
{
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
};
|
||||
|
||||
enum Says
|
||||
{
|
||||
// Sisters
|
||||
SAY_SISTERS_AGGRO = 1,
|
||||
SAY_SISTERS_DEATH = 2,
|
||||
SAY_SISTERS_EVADE = 3,
|
||||
SAY_SISTER_KILLS = 4,
|
||||
|
||||
// Kasparian
|
||||
SAY_KASPARIAN_AGGRO = 1,
|
||||
SAY_SPELL_GLAIVE = 2,
|
||||
SAY_KASPARIAN_KILLS = 3,
|
||||
SAY_KASPARIAN_EVADE = 4,
|
||||
SAY_KASPARIAN_DIED = 5,
|
||||
|
||||
// Yathae
|
||||
SAY_YATHAE_AGGRO = 6,
|
||||
SAY_PHASE_COMBAT = 7,
|
||||
SAY_SPELLS_ARROW = 8,
|
||||
SAY_SPELL_AOE = 9,
|
||||
SAY_YATHAE_KILLS = 10,
|
||||
SAY_YATHAE_EVADE = 11,
|
||||
SAY_YATHAE_DIED = 12,
|
||||
|
||||
// Lunaspyre
|
||||
SAY_LUNASPYRE_AGGRO = 13,
|
||||
SAY_SPELL = 14,
|
||||
SAY_FOUNTAIN_OF_ELUNE = 15,
|
||||
SAY_LUNASPYRE_KILLS = 16,
|
||||
SAY_LUNASPYRE_EVADE = 17,
|
||||
SAY_LUNASPYRE_DIED = 18
|
||||
};
|
||||
|
||||
enum SistersSpells
|
||||
{
|
||||
// Generic
|
||||
SPELL_QUIET_SUICIDE = 3617, // Serverside spell
|
||||
SPELL_INCORPOREAL_TELEPORT = 236115, // Cast
|
||||
SPELL_INCORPOREAL_TELEPORT_2 = 236224, // Not sure if this is the teleport or need script. Instant cast. These two teleport spells are the same for Lunaspyre
|
||||
SPELL_COOLDOWN_CREATURE_SPECIAL = 61207, // To block other spells from interfering with their special
|
||||
SPELL_GHOST_AURA = 235268, // Cosmetic for Sisters
|
||||
SPELL_ELUNE_FOUNTAIN = 236357, // Create AT 11284
|
||||
SPELL_LUNAR_SUFFUSION = 234995, // Add the aura every 3 seconds on the bright side
|
||||
SPELL_UMBRA_SUFFUSION = 234996, // Add the aura every 3 seconds on the dark side
|
||||
SPELL_ASTRAL_PURGE = 234998, // Will trigger on change side in Fountain of Elune, and reset Suffusion marks.
|
||||
|
||||
// Generic Talk
|
||||
// Kasparian
|
||||
SPELL_KASPARIAN_KILL_CONVERSATION_A = 243051, // When unactive sister kills a player
|
||||
SPELL_KASPARIAN_KILL_CONVERSATION_B = 243052, // When unactive sister kills a player
|
||||
SPELL_KASPARIAN_KILL_CONVERSATION_C = 243053, // When unactive sister kills a player
|
||||
|
||||
// Yathae
|
||||
SPELL_YATHAE_BECOMES_ACTIVE_CONVERSATION = 243044, // Probably at Start Combat in Active Phase
|
||||
|
||||
// Lunaspyre
|
||||
SPELL_LUNASPYRE_BECOMES_ACTIVE_CONVERSATION = 243047, // Probably at Start Combat in Active Phase
|
||||
SPELL_LUNASPYRE_KILL_CONVERSATION_A = 243059, // When unactive sister kills a player
|
||||
SPELL_LUNASPYPE_KILL_CONVERSATION_B = 243060, // When unactive sister kills a player
|
||||
SPELL_LUNASPYRE_KILL_CONVERSATION_C = 243061, // When unactive sister kills a player
|
||||
|
||||
// Kasparian
|
||||
SPELL_TWILIGHT_GLAIVE_AT = 236529, // AT 9785 and add aura to bunny + make bunny got target,then return
|
||||
SPELL_TWILIGHT_GLAIVE_DAMAGE = 236541,
|
||||
SPELL_TWILIGHT_GLAIVE_DUMMY = 237561,
|
||||
SPELL_MOON_GLAIVE = 236547,
|
||||
SPELL_DISCORPORATE = 236550, // Astral Purge will remove it
|
||||
SPELL_GLAIVE_STORM = 239379, // Only used in Elune's Fountain Phase 3 (normal), phase 2 and 3 heroic and mythic
|
||||
|
||||
// Yathae
|
||||
SPELL_SHADOW_SHOT = 237630,
|
||||
SPELL_INCORPOREAL_SHOT_CAST = 236305, // Only used in Elune's Fountain Phase 2 (normal), phase 1 and 3 heroic and mythic
|
||||
SPELL_INCORPOREAL_SHOT_DAMAGE = 236306,
|
||||
SPELL_CALL_MOONTALON = 236694,
|
||||
SPELL_TWILIGHT_VOLLEY_AT = 236442, // AT 9777
|
||||
SPELL_TWILIGHT_VOLLEY_DAMAGE = 236516, // Apply this aura OnUnitEnter();
|
||||
SPELL_RAPID_SHOT = 236598,
|
||||
SPELL_RAPID_SHOT_AURA = 236596,
|
||||
|
||||
// Lunaspyre
|
||||
SPELL_EMBRACE_OF_THE_ECLIPSE_HEAL = 233263, // Shields Heal
|
||||
SPELL_EMBRACE_OF_THE_ECLIPSE_BOSS = 233264, // Shield Boss
|
||||
SPELL_LUNAR_BEACON = 236712, // OnRemove(); actives Lunar barrage.
|
||||
SPELL_LUNAR_FIRE = 239264, // Only on current target,active.
|
||||
SPELL_LUNAR_STRIKE = 237632,
|
||||
SPELL_MOON_BURN = 236518, // Astral Purge will remove this.
|
||||
SPELL_LUNAR_BARRAGE_AT = 236726, // AT 9807
|
||||
SPELL_LUNAR_BARRAGE_DAMAGE = 237351
|
||||
};
|
||||
|
||||
enum SistersEvents
|
||||
{
|
||||
// General
|
||||
EVENT_INCORPOREAL_TELEPORT = 1,
|
||||
EVENT_TELEPORT_CENTER_COMBAT,
|
||||
EVENT_BACK_TO_GHOST,
|
||||
EVENT_BERSERKER,
|
||||
|
||||
// Kasparian
|
||||
EVENT_TWILIGHT_GLAIVE,
|
||||
EVENT_MOON_GLAIVE,
|
||||
EVENT_GLAIVE_STORM,
|
||||
EVENT_JUMP_TIGER,
|
||||
EVENT_KASPARIAN_JUST_DIED,
|
||||
EVENT_KASPARIAN_AGGRO,
|
||||
|
||||
// Yathae
|
||||
EVENT_SHADOW_SHOT,
|
||||
EVENT_INCORPOREAL_SHOT,
|
||||
EVENT_CALL_MOONTALON,
|
||||
EVENT_TWILIGHT_VOLLEY,
|
||||
EVENT_RAPID_SHOT,
|
||||
EVENT_YATHAE_JUST_DIED,
|
||||
EVENT_YATHAE_AGGRO,
|
||||
|
||||
// Lunaspyre
|
||||
EVENT_EMBRACE_OF_THE_ECLIPSE,
|
||||
EVENT_LUNAR_BEACON,
|
||||
EVENT_LUNAR_FIRE,
|
||||
EVENT_LUNAR_STRIKE,
|
||||
EVENT_MOON_BURN,
|
||||
EVENT_LUNASPYRE_JUST_DIED,
|
||||
EVENT_LUNASPYRE_AGGRO
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_RETURN_PHASE1 = 1,
|
||||
ACTION_RETURN = 2,
|
||||
ACTION_SAY_SISTERS_AGGRO = 3,
|
||||
ACTION_EVADE = 4,
|
||||
ACTION_PHASE_2 = 5,
|
||||
ACTION_PHASE_3 = 6,
|
||||
ACTION_SISTERS_DEAD = 7
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
THE_HUNTRESS = 1,
|
||||
THE_CAPTAIN = 2,
|
||||
THE_PRIESTESS = 3,
|
||||
SISTER_GHOST = 4
|
||||
};
|
||||
|
||||
enum Objects
|
||||
{
|
||||
DATA_HUNTRESS_KASPARIAN,
|
||||
DATA_CAPTAIN_YATHAE_MOONSTRIKE,
|
||||
DATA_PRIESTESS_LUNASPYRE,
|
||||
};
|
||||
|
||||
class boss_sisters_of_the_moon : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_sisters_of_the_moon() : CreatureScript("boss_sisters_of_the_moon") { }
|
||||
|
||||
struct boss_sisters_of_the_moon_AI : public BossAI
|
||||
{
|
||||
boss_sisters_of_the_moon_AI(Creature* creature) : BossAI(creature, DATA_SISTERS_OF_THE_MOON)
|
||||
{
|
||||
creature->GetInstanceScript();
|
||||
|
||||
Creature* kasparian = instance->GetCreature(NPC_HUNTRESS_KASPARIAN);
|
||||
Creature* yathae = instance->GetCreature(NPC_CAPTAIN_YATHAE_MOONSTRIKE);
|
||||
Creature* lunaspyre = instance->GetCreature(NPC_PRIESTESS_LUNASPYRE);
|
||||
|
||||
if (instance)
|
||||
{
|
||||
EncounterState bossState = instance->GetBossState(DATA_SISTERS_OF_THE_MOON);
|
||||
if (bossState != DONE && bossState != NOT_STARTED)
|
||||
instance->SetBossState(DATA_SISTERS_OF_THE_MOON, NOT_STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->RemoveAllAreaTriggers();
|
||||
|
||||
events.Reset();
|
||||
|
||||
if (instance)
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
DoAction(ACTION_RETURN_PHASE1);
|
||||
break;
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
DoAction(ACTION_RETURN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*attacker*/) override
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
|
||||
instance->SetBossState(DATA_SISTERS_OF_THE_MOON, IN_PROGRESS);
|
||||
}
|
||||
|
||||
events.AddPhase(THE_HUNTRESS);
|
||||
DoAction(ACTION_SAY_SISTERS_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
events.ScheduleEvent(EVENT_MOON_GLAIVE, 17s, THE_HUNTRESS);
|
||||
events.ScheduleEvent(EVENT_TWILIGHT_GLAIVE, 22s);
|
||||
break;
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
events.ScheduleEvent(EVENT_TWILIGHT_VOLLEY, 15s);
|
||||
events.ScheduleEvent(EVENT_CALL_MOONTALON, 40s, 0, THE_CAPTAIN);
|
||||
events.ScheduleEvent(EVENT_INCORPOREAL_TELEPORT, 30s, 38s, 0, ((THE_HUNTRESS), (THE_PRIESTESS)));
|
||||
events.ScheduleEvent(EVENT_RAPID_SHOT, 25s, 0, THE_CAPTAIN);
|
||||
events.ScheduleEvent(EVENT_SHADOW_SHOT, 10s, 0, THE_CAPTAIN);
|
||||
break;
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
events.ScheduleEvent(EVENT_LUNAR_FIRE, 12s);
|
||||
events.ScheduleEvent(EVENT_LUNAR_BEACON, 17s, 0 , THE_PRIESTESS);
|
||||
events.ScheduleEvent(EVENT_MOON_BURN, 10s, 0 , THE_PRIESTESS);
|
||||
events.ScheduleEvent(EVENT_INCORPOREAL_TELEPORT, 30s, 38s, ((THE_HUNTRESS), (THE_CAPTAIN)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
_DespawnAtEvade();
|
||||
|
||||
me->RemoveAllAreaTriggers();
|
||||
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MOON_BURN);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_RAPID_SHOT);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MOON_GLAIVE);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_LUNAR_BARRAGE_DAMAGE);
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
{
|
||||
if (events.IsInPhase(THE_HUNTRESS))
|
||||
Talk(SAY_KASPARIAN_EVADE);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
{
|
||||
if (events.IsInPhase(THE_CAPTAIN))
|
||||
Talk(SAY_YATHAE_EVADE);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
{
|
||||
if (events.IsInPhase(THE_PRIESTESS))
|
||||
Talk(SAY_LUNASPYRE_EVADE);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(const int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_EVADE:
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveAurasDueToSpell(SPELL_GHOST_AURA);
|
||||
break;
|
||||
}
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->AddAura(SPELL_GHOST_AURA, me);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTION_PHASE_2:
|
||||
{
|
||||
events.SetPhase(THE_CAPTAIN);
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
{
|
||||
me->AddAura(SPELL_GHOST_AURA, me);
|
||||
// Disable Movement
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
events.ScheduleEvent(EVENT_TELEPORT_CENTER_COMBAT, 0s);
|
||||
//Enable Movement
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTION_PHASE_3:
|
||||
{
|
||||
events.SetPhase(THE_PRIESTESS);
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->AddAura(SPELL_GHOST_AURA, me);
|
||||
events.ScheduleEvent(EVENT_BACK_TO_GHOST, 0s);
|
||||
// Disable Movement
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_GHOST_AURA);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
events.ScheduleEvent(EVENT_TELEPORT_CENTER_COMBAT, 0s);
|
||||
// Enable Movement
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTION_SISTERS_DEAD:
|
||||
{
|
||||
events.ScheduleEvent(EVENT_LUNASPYRE_JUST_DIED, 0s);
|
||||
events.ScheduleEvent(EVENT_YATHAE_JUST_DIED, 8s);
|
||||
events.ScheduleEvent(EVENT_KASPARIAN_JUST_DIED, 16s);
|
||||
break;
|
||||
}
|
||||
|
||||
case ACTION_SAY_SISTERS_AGGRO:
|
||||
{
|
||||
events.ScheduleEvent(EVENT_KASPARIAN_AGGRO, 0s);
|
||||
events.ScheduleEvent(EVENT_LUNASPYRE_AGGRO, 4s);
|
||||
events.ScheduleEvent(EVENT_YATHAE_AGGRO, 9s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32 &damage) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_HUNTRESS_KASPARIAN)
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(70, damage))
|
||||
{
|
||||
DoAction(ACTION_PHASE_2);
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetEntry() == NPC_CAPTAIN_YATHAE_MOONSTRIKE)
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(40, damage))
|
||||
{
|
||||
DoAction(ACTION_PHASE_3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
DoAction(ACTION_SISTERS_DEAD);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* killer) override
|
||||
{
|
||||
if (killer->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode())
|
||||
{
|
||||
/*switch (killer)
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
{
|
||||
if (events.IsInPhase(THE_HUNTRESS))
|
||||
killer->Talk(SAY_KASPARIAN_KILLS);
|
||||
else if (events.IsInPhase(THE_CAPTAIN))
|
||||
yathae->AI()->Talk(SAY_SISTER_KILLS);
|
||||
else if (events.IsInPhase(THE_PRIESTESS))
|
||||
lunaspyre->AI()->Talk(SAY_SISTER_KILLS);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
{
|
||||
if (events.IsInPhase(THE_HUNTRESS))
|
||||
kasparian->AI()->Talk(SAY_SISTER_KILLS);
|
||||
else if (events.IsInPhase(THE_CAPTAIN))
|
||||
killer->Talk(SAY_YATHAE_KILLS);
|
||||
else if (events.IsInPhase(THE_PRIESTESS))
|
||||
lunaspyre->AI()->Talk(SAY_SISTER_KILLS);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
{
|
||||
if (events.IsInPhase(THE_HUNTRESS))
|
||||
kasparian->AI()->Talk(SAY_SISTER_KILLS);
|
||||
else if (events.IsInPhase(THE_CAPTAIN))
|
||||
yathae->AI()->Talk(SAY_YATHAE_KILLS);
|
||||
else if (events.IsInPhase(THE_PRIESTESS))
|
||||
killer->Talk(SAY_LUNASPYRE_KILLS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
// Kasparian
|
||||
case EVENT_KASPARIAN_AGGRO:
|
||||
Talk(SAY_KASPARIAN_AGGRO);
|
||||
break;
|
||||
|
||||
case EVENT_MOON_GLAIVE:
|
||||
{
|
||||
DoCastVictim(SPELL_MOON_GLAIVE);
|
||||
events.Repeat(17s);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_TWILIGHT_GLAIVE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_TWILIGHT_GLAIVE_AT);
|
||||
events.Repeat(22s);
|
||||
break;
|
||||
|
||||
case EVENT_GLAIVE_STORM:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case EVENT_KASPARIAN_JUST_DIED:
|
||||
Talk(SAY_KASPARIAN_DIED);
|
||||
break;
|
||||
|
||||
// Yathae
|
||||
case EVENT_YATHAE_AGGRO:
|
||||
Talk(SAY_YATHAE_AGGRO);
|
||||
break;
|
||||
|
||||
case EVENT_CALL_MOONTALON:
|
||||
DoCast(me, SPELL_CALL_MOONTALON);
|
||||
events.Repeat(40s);
|
||||
break;
|
||||
|
||||
case EVENT_TWILIGHT_VOLLEY:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_TWILIGHT_VOLLEY_AT);
|
||||
|
||||
events.Repeat(15s);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_RAPID_SHOT:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_RAPID_SHOT);
|
||||
DoCast(me, SPELL_COOLDOWN_CREATURE_SPECIAL, true);
|
||||
}
|
||||
events.Repeat(17s);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_SHADOW_SHOT:
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_SHADOW_SHOT);
|
||||
}
|
||||
events.Repeat(20s);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_YATHAE_JUST_DIED:
|
||||
Talk(SAY_YATHAE_DIED);
|
||||
break;
|
||||
|
||||
// Lunaspyre
|
||||
case EVENT_LUNASPYRE_AGGRO:
|
||||
Talk(SAY_LUNASPYRE_AGGRO);
|
||||
break;
|
||||
|
||||
case EVENT_LUNAR_BEACON:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_LUNAR_BEACON);
|
||||
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
|
||||
case EVENT_LUNAR_FIRE:
|
||||
DoCastVictim(SPELL_LUNAR_FIRE);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
|
||||
case EVENT_MOON_BURN:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_MOON_BURN);
|
||||
|
||||
events.Repeat(14s);
|
||||
break;
|
||||
|
||||
case EVENT_LUNAR_STRIKE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_LUNAR_STRIKE);
|
||||
|
||||
events.Repeat(16s);
|
||||
break;
|
||||
|
||||
case EVENT_EMBRACE_OF_THE_ECLIPSE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case EVENT_LUNASPYRE_JUST_DIED:
|
||||
Talk(SAY_LUNASPYRE_DIED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
{
|
||||
if (events.IsInPhase(THE_HUNTRESS))
|
||||
DoMeleeAttackIfReady();
|
||||
else
|
||||
DoSpellAttackIfReady(SPELL_MOON_GLAIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
{
|
||||
if (events.IsInPhase(THE_CAPTAIN))
|
||||
DoMeleeAttackIfReady();
|
||||
else
|
||||
DoSpellAttackIfReady(SPELL_SHADOW_SHOT);
|
||||
break;
|
||||
}
|
||||
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
{
|
||||
if (events.IsInPhase(THE_PRIESTESS))
|
||||
DoMeleeAttackIfReady();
|
||||
else
|
||||
DoSpellAttackIfReady(SPELL_LUNAR_STRIKE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new boss_sisters_of_the_moon_AI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Kasparian Spells & ATs
|
||||
struct at_twilight_glaive : AreaTriggerAI
|
||||
{
|
||||
at_twilight_glaive(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
|
||||
|
||||
void OnInitialize() override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Creature* creCaster = caster->ToCreature())
|
||||
if (creCaster->IsAIEnabled)
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*creCaster, creCaster->AI()->GetGUID()))
|
||||
{
|
||||
Position targetPos = target->GetPosition();
|
||||
float targetDist = caster->GetDistance(target);
|
||||
float targetAngle = caster->GetAngle(target);
|
||||
at->MovePosition(targetPos, targetDist, targetAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void OnUnitEnter(Unit* /*unit*/) override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Unit* target = at->GetTarget())
|
||||
if (caster->IsValidAttackTarget(target))
|
||||
caster->CastSpell(target, SPELL_TWILIGHT_GLAIVE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void OnDestinationReached() override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
{
|
||||
Position casterPos = caster->GetPosition();
|
||||
float casterDist = at->GetDistance(caster);
|
||||
float casterAngle = at->GetAngle(caster);
|
||||
at->MovePosition(casterPos, casterDist, casterAngle);
|
||||
}
|
||||
|
||||
at->Remove();
|
||||
}
|
||||
};
|
||||
|
||||
// Yathae Spells & AT
|
||||
struct at_twilight_volley : AreaTriggerAI
|
||||
{
|
||||
at_twilight_volley(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
|
||||
|
||||
void OnInitialize() override
|
||||
{
|
||||
/*if (Unit* caster = at->GetCaster())
|
||||
if (Creature* creCaster = caster->ToCreature())
|
||||
if (creCaster->IsAIEnabled)
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*creCaster, creCaster->AI()->GetGUID()))
|
||||
at->SetPosition(*target);*/
|
||||
}
|
||||
|
||||
void OnUnitEnter(Unit* /*unit*/) override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Unit* target = at->GetTarget())
|
||||
if (caster->IsValidAttackTarget(target))
|
||||
caster->CastSpell(target, SPELL_TWILIGHT_VOLLEY_DAMAGE, true);
|
||||
}
|
||||
|
||||
void OnUnitExit(Unit* /*unit*/) override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Unit* target = at->GetTarget())
|
||||
if (caster->IsValidAttackTarget(target))
|
||||
target->RemoveAurasDueToSpell(SPELL_TWILIGHT_VOLLEY_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
// Lunasypre Spells & AT
|
||||
/*class spell_embrace_of_the_eclipse : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_embrace_of_the_eclipse() : SpellScriptLoader("spell_embrace_of_the_eclipse") { }
|
||||
|
||||
class spell_embrace_of_the_eclipse_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_embrace_of_the_eclipse_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*//*) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_EMBRACE_OF_THE_ECLIPSE_HEAL, SPELL_EMBRACE_OF_THE_ECLIPSE_BOSS });
|
||||
}
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Creature* kasparian = instance->GetCreature(NPC_HUNTRESS_KASPARIAN);
|
||||
Creature* yathae = instance->GetCreature(NPC_CAPTAIN_YATHAE_MOONSTRIKE);
|
||||
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
std::list<Player*> playerList;
|
||||
GetPlayerListInGrid(playerList, me, 200.0f);
|
||||
|
||||
for (auto itr : playerList)
|
||||
itr->RemoveAura(SPELL_EMBRACE_OF_THE_ECLIPSE_HEAL);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterCast += SpellCastFn(spell_embrace_of_the_eclipse_SpellScript::HandleAfterCast);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_embrace_of_the_eclipse_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_embrace_of_the_eclipse_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*//*) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_EMBRACE_OF_THE_ECLIPSE_BOSS, SPELL_EMBRACE_OF_THE_ECLIPSE_HEAL });
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* aurEff, uint32 &shieldType, AuraEffectHandleModes /*mode*//*)
|
||||
{
|
||||
AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode();
|
||||
|
||||
if (removeMode == AURA_REMOVE_BY_EXPIRE)
|
||||
{
|
||||
switch (shieldType)
|
||||
{
|
||||
case SPELL_EMBRACE_OF_THE_ECLIPSE_BOSS:
|
||||
break;
|
||||
case SPELL_EMBRACE_OF_THE_ECLIPSE_HEAL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_embrace_of_the_eclipse_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_ABSORB, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_embrace_of_the_eclipse_SpellScript();
|
||||
}
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_embrace_of_the_eclipse_AuraScript();
|
||||
}
|
||||
};*/
|
||||
|
||||
class spell_lunar_beacon : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_lunar_beacon() : SpellScriptLoader("spell_lunar_beacon") { }
|
||||
|
||||
class spell_lunar_beacon_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_lunar_beacon_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_LUNAR_BARRAGE_AT });
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (GetCaster())
|
||||
{
|
||||
AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode();
|
||||
|
||||
if (removeMode == AURA_REMOVE_BY_EXPIRE)
|
||||
GetCaster()->CastSpell(GetTarget(), SPELL_LUNAR_BARRAGE_AT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_lunar_beacon_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_lunar_beacon_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
struct at_lunar_barrage : AreaTriggerAI
|
||||
{
|
||||
at_lunar_barrage(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
|
||||
|
||||
void OnInitialize() override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Creature* creCaster = caster->ToCreature())
|
||||
if (creCaster->IsAIEnabled)
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*creCaster, creCaster->AI()->GetGUID()))
|
||||
at->SetDestination(*target, 1000);
|
||||
}
|
||||
|
||||
void OnUnitEnter(Unit* /*unit*/) override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Unit* target = at->GetTarget())
|
||||
if (caster->IsValidAttackTarget(target))
|
||||
caster->CastSpell(target, SPELL_LUNAR_BARRAGE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void OnUnitExit(Unit* /*unit*/) override
|
||||
{
|
||||
if (Unit* caster = at->GetCaster())
|
||||
if (Unit* target = at->GetTarget())
|
||||
if (caster->IsValidAttackTarget(target))
|
||||
target->RemoveAurasDueToSpell(SPELL_LUNAR_BARRAGE_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_sisters_of_the_moon_debug()
|
||||
{
|
||||
// Boss
|
||||
new boss_sisters_of_the_moon();
|
||||
// Kasparian ATs & Spells
|
||||
RegisterAreaTriggerAI(at_twilight_glaive);
|
||||
// Yathae ATs & Spells
|
||||
RegisterAreaTriggerAI(at_twilight_volley);
|
||||
// Lunaspyre ATs & Spells
|
||||
new spell_lunar_beacon();
|
||||
//new spell_embrace_of_the_eclipse();
|
||||
RegisterAreaTriggerAI(at_lunar_barrage);
|
||||
}
|
||||
@@ -1,164 +1,605 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
https://uwow.biz/
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
#include "GameObject.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_DOOR_ROOM_GOROTH_S, DATA_GOROTH, DOOR_TYPE_ROOM },
|
||||
{ GO_DOOR_ROOM_GOROTH_N, DATA_GOROTH, DOOR_TYPE_PASSAGE },
|
||||
{ GO_DOOR_ROOM_GOROTH_E, DATA_GOROTH, DOOR_TYPE_PASSAGE },
|
||||
//{269164, DATA_GOROTH, DOOR_TYPE_PASSAGE},
|
||||
{268514, DATA_GOROTH, DOOR_TYPE_PASSAGE},
|
||||
{268580, DATA_GOROTH, DOOR_TYPE_PASSAGE},
|
||||
{GO_GOROTH_GATES, DATA_GOROTH, DOOR_TYPE_PASSAGE},
|
||||
{269975, DATA_GOROTH, DOOR_TYPE_ROOM},
|
||||
{269974, DATA_GOROTH, DOOR_TYPE_ROOM},
|
||||
{269973, DATA_GOROTH, DOOR_TYPE_ROOM},
|
||||
{ GO_INTRODESTROY_2, DATA_GOROTH, DOOR_TYPE_PASSAGE},
|
||||
{269120, DATA_HARJATAN, DOOR_TYPE_PASSAGE},
|
||||
{269192, DATA_HARJATAN, DOOR_TYPE_ROOM},
|
||||
{GO_SASSZINE_DOOR, DATA_MISTRESS_SASSZINE, DOOR_TYPE_ROOM},
|
||||
{GO_INQUISITION_DOOR, DATA_DEMONIC_INQUISITION, DOOR_TYPE_ROOM},
|
||||
{GO_HAMMER_THRONE, DATA_DEMONIC_INQUISITION, DOOR_TYPE_PASSAGE},
|
||||
{GO_ELUNES_THRONE, DATA_THE_DESOLATE_HOST, DOOR_TYPE_PASSAGE},
|
||||
{GO_GOLGANETH_THRONE, DATA_MISTRESS_SASSZINE, DOOR_TYPE_PASSAGE},
|
||||
{GO_MAIDEN_DOOR, DATA_MAIDEN_OF_VIGILANCE, DOOR_TYPE_ROOM},
|
||||
{GO_SISTERS_MOON_DOOR, DATA_SISTERS_OF_THEMOON, DOOR_TYPE_ROOM},
|
||||
{GO_AVATARA_DOOR, DATA_FALLEN_AVATAR, DOOR_TYPE_ROOM},
|
||||
{GO_DESOLATE_HOST_DOOR_1, DATA_THE_DESOLATE_HOST, DOOR_TYPE_ROOM},
|
||||
{GO_DESOLATE_HOST_DOOR_2, DATA_THE_DESOLATE_HOST, DOOR_TYPE_ROOM},
|
||||
{0, 0, DOOR_TYPE_ROOM} // END
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{NPC_BREACH_IN_WINDOW, NPC_BREACH_IN_WINDOW},
|
||||
|
||||
{NPC_KHADGAR, NPC_KHADGAR},
|
||||
{NPC_VELEN, NPC_VELEN},
|
||||
{NPC_ILLIDAN, NPC_ILLIDAN},
|
||||
{NPC_MAEIV, NPC_MAEIV},
|
||||
{NPC_DURGAN, NPC_DURGAN},
|
||||
{NPC_ATRIGAN_MISC, NPC_ATRIGAN_MISC},
|
||||
|
||||
{NPC_EVENT_1, NPC_EVENT_1},
|
||||
{NPC_EVENT_2, NPC_EVENT_2},
|
||||
{NPC_SASSZINE_MISC, NPC_SASSZINE_MISC},
|
||||
|
||||
{NPC_GOROTH, DATA_GOROTH},
|
||||
{NPC_SASSZINE, DATA_MISTRESS_SASSZINE},
|
||||
{NPC_MOON_STALKER, DATA_SISTERS_OF_THEMOON},
|
||||
{NPC_HUNTRESS_KASPARIAN, NPC_HUNTRESS_KASPARIAN},
|
||||
{NPC_PRIESTESS_LUNASPYRE, NPC_PRIESTESS_LUNASPYRE},
|
||||
{NPC_CAPTAIN_YATHAE, NPC_CAPTAIN_YATHAE},
|
||||
{NPC_KILJAEDEN, DATA_KILJAEDEN},
|
||||
|
||||
{NPC_HAMMER_1, NPC_HAMMER_1},
|
||||
{NPC_HAMMER_2, NPC_HAMMER_2},
|
||||
{NPC_ELUNES_1, NPC_ELUNES_1},
|
||||
{NPC_ELUNES_2, NPC_ELUNES_2},
|
||||
{NPC_GOLGANETH_1, NPC_GOLGANETH_1},
|
||||
{NPC_GOLGANETH_2, NPC_GOLGANETH_2},
|
||||
{NPC_SASSZINE_NPC_OUTRO, NPC_SASSZINE_NPC_OUTRO},
|
||||
{NPC_KILDJEDAN_AVATARA, NPC_KILDJEDAN_AVATARA},
|
||||
{NPC_ATRIGAN, NPC_ATRIGAN},
|
||||
{NPC_BELAK, NPC_BELAK},
|
||||
{NPC_HARJATAN, NPC_HARJATAN},
|
||||
{NPC_ELDER, NPC_ELDER},
|
||||
{NPC_AVATARA_MAIDEN , NPC_AVATARA_MAIDEN},
|
||||
{NPC_SISTERS_ACH_ADD, NPC_SISTERS_ACH_ADD},
|
||||
{0, 0} // END
|
||||
};
|
||||
|
||||
ObjectData const gobjectData[] =
|
||||
{
|
||||
{GO_GOROTH_GATES, GO_GOROTH_GATES},
|
||||
{GO_INTRODESTROY_1, GO_INTRODESTROY_1},
|
||||
{GO_INTRODESTROY_2, GO_INTRODESTROY_2},
|
||||
{GO_INTRODESTROY_3, GO_INTRODESTROY_3},
|
||||
{GO_ELEVATOR, GO_ELEVATOR},
|
||||
{GO_KILJAEDEN_BRIDGE_1, GO_KILJAEDEN_BRIDGE_1},
|
||||
{GO_KILJAEDEN_BRIDGE_2, GO_KILJAEDEN_BRIDGE_2},
|
||||
{GO_KILJAEDEN_CHEST, GO_KILJAEDEN_CHEST},
|
||||
|
||||
{269164, 269164},
|
||||
{268580, 268580},
|
||||
{GO_AVATARA_FLOOR , GO_AVATARA_FLOOR},
|
||||
|
||||
// Avataras floor blocks
|
||||
{267700, 267700},
|
||||
{267701, 267701},
|
||||
{267702, 267702},
|
||||
{267703, 267703},
|
||||
{267704, 267704},
|
||||
{267705, 267705},
|
||||
{267706, 267706},
|
||||
{267707, 267707},
|
||||
{267708, 267708},
|
||||
{267709, 267709},
|
||||
{267710, 267710},
|
||||
{267711, 267711},
|
||||
{267712, 267712},
|
||||
{267713, 267713},
|
||||
{267714, 267714},
|
||||
{267715, 267715},
|
||||
{267716, 267716},
|
||||
{267717, 267717},
|
||||
{267718, 267718},
|
||||
{267719, 267719},
|
||||
{267720, 267720},
|
||||
{267721, 267721},
|
||||
{267722, 267722},
|
||||
{267723, 267723},
|
||||
{267724, 267724},
|
||||
|
||||
// end Avatara bloks
|
||||
{0, 0 } // END
|
||||
};
|
||||
|
||||
class instance_tomb_of_sargeras : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_tomb_of_sargeras() : InstanceMapScript("instance_tomb_of_sargeras", 1676) { }
|
||||
public:
|
||||
instance_tomb_of_sargeras() : InstanceMapScript(ToSScriptName, 1676) {}
|
||||
|
||||
struct instance_tomb_of_sargeras_InstanceMapScript : public InstanceScript
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_tomb_of_sargeras_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_tomb_of_sargeras_InstanceMapScript : InstanceScript
|
||||
{
|
||||
instance_tomb_of_sargeras_InstanceMapScript(Map* map) : InstanceScript(map->ToInstanceMap())
|
||||
{
|
||||
instance_tomb_of_sargeras_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { }
|
||||
SetBossNumber(MAX_ENCOUNTER);
|
||||
}
|
||||
|
||||
void Initialize() override
|
||||
{
|
||||
SetBossNumber(ENCOUNTER_COUNT);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
|
||||
std::vector<ObjectGuid> addsIntro{};
|
||||
std::set<ObjectGuid> lunarArchersEvent{};
|
||||
WorldLocation loc_res_pla{};
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
std::vector<ObjectGuid> avatarasFloors{};
|
||||
|
||||
uint32 checkTimer = 1000;
|
||||
uint32 checkPlayersFallTimer = 1000;
|
||||
|
||||
void Initialize() override
|
||||
{
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, gobjectData);
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player) override {}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case BOSS_GOROTH:
|
||||
case 121024:
|
||||
case 121023:
|
||||
if (creature->GetPositionX() >= 6019.0f && creature->GetPositionZ() <= 2972.0f)
|
||||
{
|
||||
if (!creature->HasAura(35356) && !false /* flag3 feign death non porte */)
|
||||
{
|
||||
creature->AddDelayedEvent(1000, [creature] () -> void {creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);});
|
||||
addsIntro.push_back(creature->GetGUID());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NPC_GOROTH:
|
||||
creature->SetVisible(false);
|
||||
creature->setActive(false);
|
||||
GorothGUID = creature->GetGUID();
|
||||
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
break;
|
||||
|
||||
case BOSS_ATRIGAN:
|
||||
AtriganGUID = creature->GetGUID();
|
||||
case NPC_MAEIV:
|
||||
case NPC_ILLIDAN:
|
||||
creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);
|
||||
break;
|
||||
|
||||
case BOSS_BELAC:
|
||||
BelacGUID = creature->GetGUID();
|
||||
case NPC_VELEN:
|
||||
creature->CastSpell(creature, 241186); // he don't want use it like aura =C
|
||||
break;
|
||||
|
||||
case BOSS_HARJATAN:
|
||||
case NPC_HUNTRESS_KASPARIAN:
|
||||
case NPC_CAPTAIN_YATHAE_MOONSTRIKE:
|
||||
case NPC_PRIESTESS_LUNASPYRE:
|
||||
case NPC_SASSZINE:
|
||||
case NPC_ENGINE_OF_SOULS:
|
||||
case NPC_SOUL_QUEEN_DEJAHNA:
|
||||
case NPC_DESOLATE_HOST:
|
||||
case NPC_MAIDEN_OF_VIGILANCE:
|
||||
case NPC_FALLEN_AVATAR:
|
||||
case NPC_KILJAEDEN:
|
||||
AddObject(creature, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case NPC_ATRIGAN_MISC:
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
if (GetBossState(DATA_GOROTH) != NOT_STARTED)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_HAMMER_1:
|
||||
case NPC_HAMMER_2:
|
||||
if (GetBossState(DATA_DEMONIC_INQUISITION) != DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_ELUNES_1:
|
||||
case NPC_ELUNES_2:
|
||||
if (GetBossState(DATA_THE_DESOLATE_HOST) != DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_GOLGANETH_1:
|
||||
case NPC_GOLGANETH_2:
|
||||
if (GetBossState(DATA_MISTRESS_SASSZINE) != DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_LUNAR_ARCHER:
|
||||
if (creature->GetDistance(6088.19f, -1030.07f, 2896.31f) <= 10.0f)
|
||||
lunarArchersEvent.insert(creature->GetGUID());
|
||||
break;
|
||||
case NPC_KILDJEDAN_AVATARA:
|
||||
if (GetBossState(DATA_FALLEN_AVATAR) == DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_TADPOLE_1:
|
||||
case NPC_TADPOLE_2:
|
||||
case NPC_TADPOLE_3:
|
||||
if (Creature* harjatan = instance->GetCreature(GetGuidData(NPC_HARJATAN)))
|
||||
harjatan->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_FRAGMENT_SOUL:
|
||||
if (!instance->IsMythic())
|
||||
creature->DespawnOrUnsummon(100);
|
||||
else if (Creature* atrigan = instance->GetCreature(GetGuidData(NPC_ATRIGAN)))
|
||||
{
|
||||
atrigan->AI()->JustSummoned(creature);
|
||||
creature->CastSpell(creature, 241521);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
InstanceScript::OnGameObjectCreate(go);
|
||||
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_DESTRUCTIBLE_1:
|
||||
DestructibleGUID[0] = go->GetGUID();
|
||||
|
||||
if (GetBossState(DATA_GOROTH) == DONE)
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
case GO_ELEVATOR:
|
||||
if (GetBossState(DATA_MAIDEN_OF_VIGILANCE) != DONE)
|
||||
// (SetPhaseMask 2 : phasing legacy uwow, non porte)
|
||||
break;
|
||||
|
||||
case GO_DESTRUCTIBLE_2:
|
||||
DestructibleGUID[1] = go->GetGUID();
|
||||
|
||||
if (GetBossState(DATA_GOROTH) == DONE)
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
|
||||
case 267700:
|
||||
case 267701:
|
||||
case 267702:
|
||||
case 267703:
|
||||
case 267704:
|
||||
case 267705:
|
||||
case 267706:
|
||||
case 267707:
|
||||
case 267708:
|
||||
case 267709:
|
||||
case 267710:
|
||||
case 267711:
|
||||
case 267712:
|
||||
case 267713:
|
||||
case 267714:
|
||||
case 267715:
|
||||
case 267716:
|
||||
case 267717:
|
||||
case 267718:
|
||||
case 267719:
|
||||
case 267720:
|
||||
case 267721:
|
||||
case 267722:
|
||||
case 267723:
|
||||
case 267724:
|
||||
avatarasFloors.push_back(go->GetGUID());
|
||||
break;
|
||||
|
||||
case GO_DESTRUCTIBLE_3:
|
||||
DestructibleGUID[2] = go->GetGUID();
|
||||
|
||||
if (GetBossState(DATA_GOROTH) == DONE)
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
|
||||
break;
|
||||
|
||||
case GO_DOOR_TO_MISTRESS:
|
||||
case GO_DOOR_TO_MISTRESS2:
|
||||
if (GetBossState(DATA_HARJATAN) == DONE)
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
|
||||
break;
|
||||
|
||||
case GO_DOOR_ROOM_GOROTH_S:
|
||||
case GO_DOOR_ROOM_GOROTH_N:
|
||||
case GO_DOOR_ROOM_GOROTH_E:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_GOROTH:
|
||||
return GorothGUID;
|
||||
|
||||
case DATA_ATRIGAN:
|
||||
return AtriganGUID;
|
||||
|
||||
case DATA_BELAC:
|
||||
return BelacGUID;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
protected:
|
||||
EventMap events;
|
||||
ObjectGuid GorothGUID;
|
||||
ObjectGuid AtriganGUID;
|
||||
ObjectGuid BelacGUID;
|
||||
ObjectGuid DestructibleGUID[3];
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_tomb_of_sargeras_InstanceMapScript(map);
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
InstanceScript::OnGameObjectRemove(go);
|
||||
}
|
||||
|
||||
void OnUnitDeath(Unit* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_LUNAR_ARCHER:
|
||||
if (lunarArchersEvent.find(creature->GetGUID()) != lunarArchersEvent.end())
|
||||
{
|
||||
lunarArchersEvent.erase(creature->GetGUID());
|
||||
if (lunarArchersEvent.empty())
|
||||
instance->SummonCreature(NPC_GUARDIAN_SENTRY, { 6088.50f, -1027.06f, 2896.43f, 4.23f });
|
||||
}
|
||||
break;
|
||||
case NPC_EVENT_1:
|
||||
case NPC_EVENT_2:
|
||||
if (Creature* event = instance->GetCreature(GetGuidData(NPC_SASSZINE_MISC)))
|
||||
if (event->IsAlive() && event->IsInWorld())
|
||||
event->AI()->DoAction(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
if (type != DATA_MAIDEN_OF_VIGILANCE && type != DATA_FALLEN_AVATAR && type != DATA_KILJAEDEN)
|
||||
if (GameObject* go = instance->GetGameObject(GetGuidData(269164)))
|
||||
HandleGameObject(go->GetGUID(), CheckRequiredBosses(DATA_MAIDEN_OF_VIGILANCE), go);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case DONE:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_GOROTH:
|
||||
if (auto khadgar = instance->GetCreature(GetGuidData(NPC_KHADGAR)))
|
||||
khadgar->AI()->DoAction(true);
|
||||
break;
|
||||
case DATA_DEMONIC_INQUISITION:
|
||||
for (auto id : {NPC_HAMMER_1, NPC_HAMMER_2})
|
||||
if (auto hammer = instance->GetCreature(GetGuidData(id)))
|
||||
hammer->SetVisible(true);
|
||||
break;
|
||||
case DATA_HARJATAN:
|
||||
if (auto sivash = instance->GetCreature(GetGuidData(NPC_SASSZINE_NPC_OUTRO)))
|
||||
sivash->AddDelayedEvent(2000, [sivash] {sivash->AI()->ZoneTalk(0); });
|
||||
break;
|
||||
case DATA_THE_DESOLATE_HOST:
|
||||
for (auto id : { NPC_ELUNES_1, NPC_ELUNES_2 })
|
||||
if (auto elunes = instance->GetCreature(GetGuidData(id)))
|
||||
elunes->SetVisible(true);
|
||||
break;
|
||||
case DATA_MISTRESS_SASSZINE:
|
||||
for (auto id : { NPC_GOLGANETH_1, NPC_GOLGANETH_2 })
|
||||
if (auto golganeth = instance->GetCreature(GetGuidData(id)))
|
||||
golganeth->SetVisible(true);
|
||||
break;
|
||||
case DATA_MAIDEN_OF_VIGILANCE:
|
||||
if (auto go = instance->GetGameObject(GetGuidData(GO_ELEVATOR)))
|
||||
// (SetPhaseMask 1 : phasing legacy uwow, non porte)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NOT_STARTED:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_FALLEN_AVATAR:
|
||||
if (GameObject* go = instance->GetGameObject(GetGuidData(GO_AVATARA_FLOOR)))
|
||||
go->SetDestructibleState(GO_DESTRUCTIBLE_INTACT);
|
||||
|
||||
for (auto i : avatarasFloors)
|
||||
if (GameObject* go = instance->GetGameObject(i))
|
||||
go->SetDestructibleState(GO_DESTRUCTIBLE_INTACT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
// TODO: handle IN_PROGRESS if needed
|
||||
break;
|
||||
case FAIL:
|
||||
// TODO: handle FAIL if needed
|
||||
break;
|
||||
case SPECIAL:
|
||||
// TODO: handle SPECIAL if needed
|
||||
break;
|
||||
case TO_BE_DECIDED:
|
||||
// TODO: handle TO_BE_DECIDED if needed
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == DATA_KILJAEDEN)
|
||||
{
|
||||
if (state == IN_PROGRESS)
|
||||
{
|
||||
HandleGameObject(GetGuidData(GO_KILJAEDEN_BRIDGE_1), true);
|
||||
HandleGameObject(GetGuidData(GO_KILJAEDEN_BRIDGE_2), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleGameObject(GetGuidData(GO_KILJAEDEN_BRIDGE_1), false);
|
||||
HandleGameObject(GetGuidData(GO_KILJAEDEN_BRIDGE_2), false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: // intro
|
||||
for (auto guid : addsIntro)
|
||||
if (auto creature = instance->GetCreature(guid))
|
||||
{
|
||||
creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
creature->CombatStop();
|
||||
creature->CastSpell(creature, 35356);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
//switch (type)
|
||||
//{
|
||||
//default:
|
||||
return 0;
|
||||
//}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
//switch (type)
|
||||
//{
|
||||
//default:
|
||||
return InstanceScript::GetGuidData(type);
|
||||
//}
|
||||
}
|
||||
|
||||
bool CheckRequiredBosses(uint32 bossId, Player const* /*player*/ = nullptr) const override
|
||||
{
|
||||
if (false)
|
||||
return true;
|
||||
|
||||
switch (bossId)
|
||||
{
|
||||
case DATA_MAIDEN_OF_VIGILANCE:
|
||||
for (uint32 i = DATA_GOROTH; i < DATA_MAIDEN_OF_VIGILANCE; ++i)
|
||||
if (GetBossState(i) != DONE)
|
||||
return false;
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
WorldLocation* GetClosestGraveYard(float x, float y, float z) /* signature uwow, la table graveyard_zone fait foi */
|
||||
{
|
||||
Position playerPosition(x, y, z);
|
||||
uint32 graveyardId = 5889;
|
||||
|
||||
std::vector<uint32> availableGravs{ 6014, 6017, 6019, 5889 };
|
||||
|
||||
if (GetBossState(DATA_GOROTH) == DONE)
|
||||
availableGravs.push_back(6015);
|
||||
|
||||
if (CheckRequiredBosses(DATA_MAIDEN_OF_VIGILANCE))
|
||||
availableGravs.push_back(6016);
|
||||
if (GetBossState(DATA_HARJATAN) == DONE)
|
||||
availableGravs.push_back(6018);
|
||||
if (GetBossState(DATA_MAIDEN_OF_VIGILANCE) == DONE)
|
||||
availableGravs.push_back(6020);
|
||||
if (GetBossState(DATA_FALLEN_AVATAR) == DONE)
|
||||
availableGravs.push_back(6210);
|
||||
|
||||
if (GetBossState(DATA_KILJAEDEN) == DONE)
|
||||
availableGravs.push_back(6117);
|
||||
|
||||
for (auto gravYard : availableGravs)
|
||||
{
|
||||
WorldSafeLocsEntry const* temp = sWorldSafeLocsStore.LookupEntry(gravYard);
|
||||
WorldSafeLocsEntry const* saved = sWorldSafeLocsStore.LookupEntry(graveyardId);
|
||||
if (!temp)
|
||||
continue;
|
||||
if (!saved)
|
||||
graveyardId = gravYard;
|
||||
|
||||
Position pos1(temp->Loc.X, temp->Loc.Y, temp->Loc.Z);
|
||||
Position pos2(saved->Loc.X, saved->Loc.Y, saved->Loc.Z);
|
||||
if (playerPosition.GetExactDist(&pos1) < playerPosition.GetExactDist(&pos2))
|
||||
graveyardId = gravYard;
|
||||
}
|
||||
|
||||
if (GetBossState(DATA_GOROTH) != DONE)
|
||||
{
|
||||
WorldSafeLocsEntry const* temp = sWorldSafeLocsStore.LookupEntry(6015);
|
||||
WorldSafeLocsEntry const* saved = sWorldSafeLocsStore.LookupEntry(graveyardId);
|
||||
if (temp)
|
||||
{
|
||||
Position pos1(temp->Loc.X, temp->Loc.Y, temp->Loc.Z);
|
||||
Position pos2(saved->Loc.X, saved->Loc.Y, saved->Loc.Z);
|
||||
if (playerPosition.GetExactDist(&pos1) < playerPosition.GetExactDist(&pos2))
|
||||
graveyardId = 6015;
|
||||
}
|
||||
}
|
||||
|
||||
if (WorldSafeLocsEntry const* gy = sWorldSafeLocsStore.LookupEntry(graveyardId))
|
||||
{
|
||||
loc_res_pla.Relocate(gy->Loc.X, gy->Loc.Y, gy->Loc.Z);
|
||||
loc_res_pla.m_mapId = gy->MapID;
|
||||
}
|
||||
|
||||
return &loc_res_pla;
|
||||
}
|
||||
|
||||
std::string GetSaveData() override
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "T O S " << GetSaveData();
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* data) override
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(data);
|
||||
|
||||
char dataHead1, dataHead2, dataHead3;
|
||||
|
||||
std::istringstream loadStream(data);
|
||||
loadStream >> dataHead1 >> dataHead2 >> dataHead3;
|
||||
|
||||
if (dataHead1 == 'T' && dataHead2 == 'O' && dataHead3 == 'S')
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
|
||||
}
|
||||
|
||||
void Update(uint32 diff) override
|
||||
{
|
||||
if (checkTimer <= diff)
|
||||
{
|
||||
checkTimer = 1000;
|
||||
|
||||
instance->ApplyOnEveryPlayer([&](Player* player)
|
||||
{
|
||||
if (GetBossState(DATA_FALLEN_AVATAR) == IN_PROGRESS &&
|
||||
(player->GetPositionZ() <= 1509.50f || (player->GetPositionX() >= 6667.59f && player->GetPositionZ() <= 1540.68f)))
|
||||
{
|
||||
if (!player->HasAura(240249))
|
||||
player->CastSpell(player, 240249, true);
|
||||
}
|
||||
else if (player->HasAura(240249))
|
||||
player->RemoveAurasDueToSpell(240249);
|
||||
|
||||
if (player->IsAlive())
|
||||
if (GetBossState(DATA_MAIDEN_OF_VIGILANCE) == IN_PROGRESS || GetBossState(DATA_MAIDEN_OF_VIGILANCE) == NOT_STARTED)
|
||||
if (player->GetDistance2d(6348.49f, -796.72f) <= 21.0f)
|
||||
if (player->GetPositionZ() <= 2855.0f)
|
||||
player->Kill(player);
|
||||
});
|
||||
}
|
||||
else
|
||||
checkTimer -= diff;
|
||||
|
||||
if (checkPlayersFallTimer <= diff)
|
||||
{
|
||||
checkPlayersFallTimer = 500;
|
||||
|
||||
instance->ApplyOnEveryPlayer([&](Player* player)
|
||||
{
|
||||
if (player->IsFalling())
|
||||
{
|
||||
if (player->IsWithinBox({ 4500.0f, -1510.0f, 5330.0f }, 200.0f, 200.0f, 20.0f))
|
||||
{
|
||||
if (player->IsAlive())
|
||||
player->Kill(player);
|
||||
|
||||
player->NearTeleportTo(4500.18f, -1484.60f, 5385.64f, player->GetOrientation());
|
||||
}
|
||||
|
||||
if (player->GetDistance(6437.81f, -1089.29f, 2881.52f) < 100.0f && player->GetPositionZ() < 2870.0f)
|
||||
{
|
||||
if (player->IsAlive())
|
||||
player->Kill(player);
|
||||
|
||||
player->NearTeleportTo(6402.37f, -1064.89f, 2881.05f, player->GetOrientation());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
checkPlayersFallTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_tomb_of_sargeras()
|
||||
|
||||
@@ -1,312 +1,542 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 MagicStorm
|
||||
*
|
||||
* Este codigo es de uso exclusivo y privado para la red de gaming
|
||||
* ColossusWoW est? totalmente prohibida su distribuci?n y
|
||||
* uso en proyectos ajenos, si has obtenido o encontrado este codigo
|
||||
* publicamente envianos un email a administracion@colossuswow.com
|
||||
* indicandonos como y donde has obtenido este codigo
|
||||
*
|
||||
* Recuerda, no distribuyas, no compartas y no subas este codigo a ningun
|
||||
* lugar publico, usa siempre nuestros repositorios Git!
|
||||
https://uwow.biz/
|
||||
*/
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "tomb_of_sargeras.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "GameObjectAI.h"
|
||||
|
||||
const Position infernalChaosbringer[4] =
|
||||
Position const InfernalsPos[3] =
|
||||
{
|
||||
{ 6130.221f, -801.1302f, 2971.884f, 2.807055f },
|
||||
{ 6086.503f, -816.4011f, 2971.987f, 2.965497f },
|
||||
{ 6064.199f, -782.8004f, 2971.644f, 2.827615f },
|
||||
{ 6131.155f, -773.0943f, 2971.543f, 0.0f },
|
||||
{ 6130.221f, -801.1302f, 2971.544f, 2.807055f },
|
||||
{ 6086.503f, -816.4011f, 2971.721f, 2.965497f },
|
||||
{ 6064.199f, -782.8004f, 2971.544f, 2.827615f },
|
||||
};
|
||||
|
||||
// 119726 - Archimage Khadgar
|
||||
class npc_archimage_khadgar_tos : public CreatureScript
|
||||
// 121605
|
||||
struct npc_tos_breach : ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_archimage_khadgar_tos() : CreatureScript("npc_archimage_khadgar_tos") { }
|
||||
explicit npc_tos_breach(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
enum velenEvents
|
||||
void DoAction(int32 const actionID) override
|
||||
{
|
||||
EVENT_FALL_BACK = 1,
|
||||
EVENT_IMPACT,
|
||||
EVENT_CHECK_FOR_EVENT_START,
|
||||
EVENT_ILLIDAN_TALK,
|
||||
EVENT_TALK_ATRIGAN1,
|
||||
EVENT_CAST_SCENE,
|
||||
EVENT_SUMMONS,
|
||||
};
|
||||
|
||||
enum velenSay
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
};
|
||||
|
||||
struct npc_archimage_khadgar_tosAI : public ScriptedAI
|
||||
{
|
||||
npc_archimage_khadgar_tosAI(Creature* creature) : ScriptedAI(creature)
|
||||
me->SetVisible(true);
|
||||
|
||||
switch (actionID)
|
||||
{
|
||||
//me->SummonGameObject(GO_DESTRUCTIBLE_2, 6146.56f, -762.025f, 2970.9f, 3.14159f, QuaternionData(-0.0f, -0.0f, -0.284929f, -0.958549f), 100000);
|
||||
}
|
||||
|
||||
uint32 startTimer;
|
||||
bool eventStarted;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_VELEN, 1000.0f))
|
||||
case 1:
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
creature->AttackStop();
|
||||
}
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(117931, 1000.0f))
|
||||
{
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
creature->AttackStop();
|
||||
creature->setFaction(35);
|
||||
}
|
||||
|
||||
std::list<Unit*> unitList;
|
||||
//me->GetAnyUnitListInRange(unitList, 1000.0f);
|
||||
|
||||
if (!unitList.empty())
|
||||
{
|
||||
for (auto unit : unitList)
|
||||
me->AddDelayedEvent(100 + 600 * i, [this, i]() -> void
|
||||
{
|
||||
if (unit->GetTypeId() != TYPEID_UNIT)
|
||||
continue;
|
||||
|
||||
unit->ToCreature()->Respawn();
|
||||
}
|
||||
me->CastSpell(InfernalsPos[i], 242915, false);
|
||||
});
|
||||
}
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
|
||||
DoZoneInCombat();
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_FOR_EVENT_START, 1 * IN_MILLISECONDS);
|
||||
|
||||
eventStarted = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void CheckForStartEvent()
|
||||
{
|
||||
if (!eventStarted)
|
||||
{
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
if (Player *player = i->GetSource())
|
||||
if (player->IsAlive() && player->GetDistance2d(5967.10f, -795.73f) <= 3.0f)
|
||||
{
|
||||
if (eventStarted)
|
||||
continue;
|
||||
|
||||
me->Yell("Quickly, bolster our ranks! We must push through!", LANG_UNIVERSAL, NULL);
|
||||
|
||||
events.ScheduleEvent(EVENT_ILLIDAN_TALK, 6 * IN_MILLISECONDS);
|
||||
|
||||
events.CancelEvent(EVENT_CHECK_FOR_EVENT_START);
|
||||
|
||||
eventStarted = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CastSceneToPlayers()
|
||||
{
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
if (Player *player = i->GetSource())
|
||||
if (player->IsAlive())
|
||||
player->CastSpell(player, SPELL_GOROTH_INTRO, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_IMPACT:
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_VELEN, 1000.0f))
|
||||
creature->DespawnOrUnsummon();
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_ILLIDAN, 1000.0f))
|
||||
creature->DespawnOrUnsummon();
|
||||
|
||||
DoCast(SPELL_IMPACT);
|
||||
|
||||
me->DespawnCreaturesInArea(121024, 1000.0f);
|
||||
me->DespawnCreaturesInArea(119742, 1000.0f);
|
||||
me->DespawnCreaturesInArea(119768, 1000.0f);
|
||||
me->DespawnCreaturesInArea(121005, 1000.0f);
|
||||
me->DespawnCreaturesInArea(119730, 1000.0f);
|
||||
me->DespawnCreaturesInArea(117931, 1000.0f);
|
||||
me->DespawnCreaturesInArea(119777, 1000.0f);
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_ATRIGAN, 1000.0f))
|
||||
{
|
||||
creature->SummonCreature(NPC_INFERNAL_CHAOSBRINGER, 6130.221f, -801.1302f, 2971.884f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
creature->SummonCreature(NPC_INFERNAL_CHAOSBRINGER, 6086.503f, -816.4011f, 2971.987f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
creature->SummonCreature(NPC_INFERNAL_CHAOSBRINGER, 6064.199f, -782.8004f, 2971.644f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
|
||||
creature->DespawnOrUnsummon(5000);
|
||||
}
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
|
||||
case EVENT_FALL_BACK:
|
||||
Talk(SAY_INTRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_IMPACT, 100);
|
||||
break;
|
||||
|
||||
case EVENT_ILLIDAN_TALK:
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_ILLIDAN, 1000.0f))
|
||||
creature->Yell("Leave none standing! If we fall here, Azeroth burns.", LANG_UNIVERSAL, NULL);
|
||||
|
||||
events.ScheduleEvent(EVENT_TALK_ATRIGAN1, 6 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_TALK_ATRIGAN1:
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_ATRIGAN, 1000.0f))
|
||||
{
|
||||
creature->Yell("Yes! Let them come! Their bodies will fuel the flames or their burning world!", LANG_UNIVERSAL, NULL);
|
||||
|
||||
CastSceneToPlayers();
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_DESTRUCTIBLE_1, 5000.0f))
|
||||
{
|
||||
/*if (Creature* boss = me->FindNearestCreature(BOSS_GOROTH, 1000.0f))
|
||||
go->CastSpell(boss, SPELL_SUMMON, true);*/
|
||||
|
||||
go->SetLootState(GO_READY);
|
||||
go->UseDoorOrButton(1000000, true);
|
||||
}
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CAST_SCENE, 1 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_CHECK_FOR_EVENT_START:
|
||||
CheckForStartEvent();
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_FOR_EVENT_START, 1 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_CAST_SCENE:
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_DESTRUCTIBLE_2, 1000.0f))
|
||||
{
|
||||
go->SetLootState(GO_READY);
|
||||
go->UseDoorOrButton(1000000, false);
|
||||
}
|
||||
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_DESTRUCTIBLE_3, 1000.0f))
|
||||
{
|
||||
go->SetLootState(GO_READY);
|
||||
go->UseDoorOrButton(1000000, false);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMONS, 3 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_FALL_BACK, 5 * IN_MILLISECONDS);
|
||||
break;
|
||||
|
||||
case EVENT_SUMMONS:
|
||||
if (Creature* creature = me->FindNearestCreature(BOSS_GOROTH, 1000.0f))
|
||||
{
|
||||
creature->SetVisible(true);
|
||||
creature->SetAIAnimKitId(8801);
|
||||
creature->PlayOneShotAnimKitId(8801);
|
||||
creature->CastSpell(creature, 233081, true);
|
||||
creature->CastSpell(creature, SPELL_IMPACT, true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetTombOfSargerasAI<npc_archimage_khadgar_tosAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 241227 - Summon
|
||||
class spell_goroth_summon : public SpellScriptLoader
|
||||
uint32 const introEntries[4]
|
||||
{
|
||||
NPC_VELEN,
|
||||
NPC_ILLIDAN,
|
||||
NPC_MAEIV,
|
||||
NPC_DURGAN
|
||||
};
|
||||
|
||||
Position const introPositions[5]
|
||||
{
|
||||
{ 5986.409f, -795.8195f, 2978.126f, 6.269365f },
|
||||
{ 5978.724f, -801.1215f, 2978.127f, 0.1859942f },
|
||||
{ 5993.796f, -789.9375f, 2976.677f, 5.799626f },
|
||||
{ 5990.001f, -801.5347f, 2977.88f, 0.3382317f },
|
||||
{ 5980.707f, -790.559f, 2978.127f, 6.063946f }
|
||||
};
|
||||
|
||||
// 119726
|
||||
struct npc_tos_kadghar_1 : ScriptedAI
|
||||
{
|
||||
explicit npc_tos_kadghar_1(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
if (me->GetMapId() == 1676)
|
||||
{
|
||||
instance = me->GetInstanceScript();
|
||||
IntroDone = false;
|
||||
outroDone = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
IntroDone = true;
|
||||
outroDone = false;
|
||||
}
|
||||
|
||||
|
||||
SetCanSeeEvenInPassiveMode(true);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
bool IntroDone, outroDone;
|
||||
|
||||
void DoAction(int32 const actionID) override
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, 6087.42f, -796.14f, 2971.72f);
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if (auto add = me->GetMap()->GetCreature(instance->GetGuidData(introEntries[i])))
|
||||
add->GetMotionMaster()->MovePoint(0, 6087.42f, -796.14f, 2971.72f);
|
||||
|
||||
|
||||
me->AddDelayedEvent(8500, [this]() -> void
|
||||
{
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MovePoint(0, introPositions[0].GetPositionX() + 217.0f, introPositions[0].GetPositionY(), introPositions[0].GetPositionZ());
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if (auto add = me->GetMap()->GetCreature(instance->GetGuidData(introEntries[i])))
|
||||
{
|
||||
add->GetMotionMaster()->Clear();
|
||||
add->GetMotionMaster()->MovePoint(0, introPositions[i + 1].GetPositionX() + 217.0f, introPositions[i + 1].GetPositionY(), introPositions[i + 1].GetPositionZ());
|
||||
}
|
||||
});
|
||||
|
||||
me->AddDelayedEvent(25000, [this]() -> void
|
||||
{
|
||||
if (Creature* egvin = me->SummonCreature(NPC_EGVIN, 6213.44f, -795.67f, 2975.00, 3.18f))
|
||||
{
|
||||
egvin->CastSpell(egvin, 241351);
|
||||
egvin->CastSpell(me, 245480); // me->CreateConversation(4951);
|
||||
|
||||
egvin->AddDelayedEvent(600, [egvin] {
|
||||
egvin->SetWalk(true);
|
||||
egvin->GetMotionMaster()->MovePoint(0, 6209.66f, -795.69f, 2974.36f);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!who->IsPlayer())
|
||||
return;
|
||||
|
||||
if (!IntroDone && instance->GetBossState(DATA_GOROTH) == DONE)
|
||||
{
|
||||
IntroDone = true;
|
||||
me->CastStop();
|
||||
me->CastSpell(introPositions[0], SPELL_INTRO_TELEPORT, false);
|
||||
me->AddDelayedEvent(1000, [this] {me->SetFacingTo(6.25f); });
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if (auto add = me->GetMap()->GetCreature(instance->GetGuidData(introEntries[i])))
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
add->RemoveAurasDueToSpell(241186);
|
||||
add->CastStop();
|
||||
}
|
||||
|
||||
add->CombatStop();
|
||||
add->CastSpell(introPositions[i + 1], SPELL_INTRO_TELEPORT, false);
|
||||
add->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||
add->AddDelayedEvent(1000, [add] {add->SetFacingTo(6.25f); });
|
||||
}
|
||||
|
||||
if (auto visual_boss = me->GetMap()->GetCreature(instance->GetGuidData(NPC_ATRIGAN_MISC)))
|
||||
visual_boss->DespawnOrUnsummon();
|
||||
|
||||
}
|
||||
|
||||
if(IntroDone)
|
||||
return;
|
||||
|
||||
if (!instance)
|
||||
return;
|
||||
|
||||
if (me->GetDistance(who) < 100.0f && !IntroDone)
|
||||
{
|
||||
IntroDone = true;
|
||||
|
||||
for (auto goid : { GO_INTRODESTROY_1, GO_INTRODESTROY_2, GO_INTRODESTROY_3})
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(goid)))
|
||||
go->SetByteValue(GAMEOBJECT_BYTES_1, 0, 0);
|
||||
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(GO_GOROTH_GATES)))
|
||||
go->SetByteValue(GAMEOBJECT_BYTES_1, 0, 1);
|
||||
|
||||
|
||||
me->AddDelayedEvent(2000, [this] () -> void
|
||||
{
|
||||
Talk(1);
|
||||
me->CastStop();
|
||||
me->CastSpell(introPositions[0], SPELL_INTRO_TELEPORT, false);
|
||||
me->AddDelayedEvent(1000, [this] {me->SetFacingTo(6.25f); });
|
||||
|
||||
for (uint8 i =0; i < 4; ++i)
|
||||
if (auto add = me->GetMap()->GetCreature(instance->GetGuidData(introEntries[i])))
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
add->RemoveAurasDueToSpell(241186);
|
||||
add->CastStop();
|
||||
}
|
||||
|
||||
add->CombatStop();
|
||||
add->CastSpell(introPositions[i + 1], SPELL_INTRO_TELEPORT, false);
|
||||
add->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||
add->AddDelayedEvent(1000, [add] {add->SetFacingTo(6.25f); });
|
||||
}
|
||||
|
||||
instance->SetData(1, 1);
|
||||
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(instance->GetGuidData(GO_INQUISITION_DOOR_INTRO)))
|
||||
{
|
||||
go->SetByteValue(GAMEOBJECT_BYTES_1, 0, 0);
|
||||
go->AddDelayedEvent(4000, [go] {
|
||||
go->SetByteValue(GAMEOBJECT_BYTES_1, 0, 1);
|
||||
});
|
||||
}
|
||||
|
||||
if (auto visual_boss = me->GetMap()->GetCreature(instance->GetGuidData(NPC_ATRIGAN_MISC)))
|
||||
{
|
||||
visual_boss->RemoveAllAuras();
|
||||
visual_boss->GetMotionMaster()->MovePoint(0, 6370.82f, -795.00f, 3011.62f);
|
||||
visual_boss->DespawnOrUnsummon(5000);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
me->AddDelayedEvent(7000, [this]() -> void
|
||||
{
|
||||
if (auto boss = me->GetMap()->GetCreature(instance->GetGuidData(DATA_GOROTH)))
|
||||
{
|
||||
boss->SetVisible(true);
|
||||
boss->SetReactState(REACT_DEFENSIVE);
|
||||
boss->GetMotionMaster()->MovePath(25759848, false);
|
||||
boss->AI()->Talk(10);
|
||||
boss->AddDelayedEvent(4000, [boss]() -> void
|
||||
{
|
||||
boss->AI()->Talk(0);
|
||||
boss->SetHomePosition(boss->GetPosition());
|
||||
});
|
||||
}
|
||||
|
||||
me->AddDelayedEvent(1000, [this]() -> void {
|
||||
if (auto summoner = me->GetMap()->GetCreature(instance->GetGuidData(NPC_BREACH_IN_WINDOW)))
|
||||
summoner->AI()->DoAction(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (me->GetDistance(who) < 20.0f && !outroDone)
|
||||
{
|
||||
bool canUseIt = true;
|
||||
for (uint8 i = 0; i < DATA_MAIDEN_OF_VIGILANCE; ++i)
|
||||
if (instance->GetBossState(i) != DONE)
|
||||
canUseIt = false;
|
||||
|
||||
if (!canUseIt)
|
||||
return;
|
||||
|
||||
outroDone = true;
|
||||
Creature* egvin = me->FindNearestCreature(NPC_EGVIN, 40.0f, true);
|
||||
if (!egvin)
|
||||
egvin = me->SummonCreature(NPC_EGVIN, 6213.44f, -795.67f, 2975.00, 3.18f);
|
||||
|
||||
if (!egvin)
|
||||
return; // it's unreal
|
||||
|
||||
egvin->CastSpell(egvin, 240060);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 269783
|
||||
struct go_tos_tele_to_kiljedan : GameObjectAI
|
||||
{
|
||||
explicit go_tos_tele_to_kiljedan(GameObject* gameobject) : GameObjectAI(gameobject)
|
||||
{
|
||||
instance = go->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
uint32 timer = 1000;
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (timer <= diff)
|
||||
{
|
||||
if (!instance || instance->GetBossState(DATA_FALLEN_AVATAR) != DONE)
|
||||
return;
|
||||
|
||||
const auto& players = instance->instance->GetPlayers();
|
||||
for (auto& pitr : players)
|
||||
{
|
||||
Player* who = pitr.GetSource();
|
||||
if (who->IsBeingTeleported())
|
||||
return;
|
||||
|
||||
if (go->GetDistance(who) < 13)
|
||||
who->NearTeleportTo(4499.94f, -1072.47f, 5335.96f, 4.70f);
|
||||
}
|
||||
timer = 1000;
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
class spell_vantus_rune_tomb_of_sargeras : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_goroth_summon() : SpellScriptLoader("spell_goroth_summon") { }
|
||||
spell_vantus_rune_tomb_of_sargeras() : SpellScriptLoader("spell_vantus_rune_tomb_of_sargeras") {}
|
||||
|
||||
class spell_goroth_summon_SpellScript : public SpellScript
|
||||
class spell_vantus_rune_tomb_of_sargeras_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareSpellScript(spell_goroth_summon_SpellScript);
|
||||
PrepareAuraScript(spell_vantus_rune_tomb_of_sargeras_AuraScript);
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
uint16 checkOnProc;
|
||||
uint16 checkOnRemove;
|
||||
|
||||
bool Load()
|
||||
{
|
||||
/*if (Unit* caster = GetCaster())
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff, AuraEffect* /*aurEff*/)
|
||||
{
|
||||
Unit* player = GetCaster();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
InstanceScript* instance = player->GetInstanceScript();
|
||||
if (!instance)
|
||||
return;
|
||||
|
||||
if (checkOnProc <= diff)
|
||||
{
|
||||
if (GameObject* go = caster->FindNearestGameObject(269839, 1000.0f))
|
||||
if (instance->GetBossState(DATA_FALLEN_AVATAR) == IN_PROGRESS)
|
||||
{
|
||||
go->setActive(true);
|
||||
go->SetLootState(GO_ACTIVATED);
|
||||
if (!player->HasAura(237795) && player->HasAura(237820))
|
||||
{
|
||||
player->CastSpell(player, 237795, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (GameObject* go = caster->FindNearestGameObject(269838, 1000.0f))
|
||||
if (instance->GetBossState(DATA_GOROTH) == IN_PROGRESS)
|
||||
{
|
||||
go->setActive(true);
|
||||
go->SetLootState(GO_ACTIVATED);
|
||||
if (!player->HasAura(237796) && player->HasAura(237821))
|
||||
{
|
||||
player->CastSpell(player, 237796, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (Creature* creature = caster->FindNearestCreature(BOSS_GOROTH, 1000.0f))
|
||||
if (instance->GetBossState(DATA_SISTERS_OF_THEMOON) == IN_PROGRESS)
|
||||
{
|
||||
creature->SetVisible(true);
|
||||
creature->AddAura(233081, creature);
|
||||
if (!player->HasAura(237797) && player->HasAura(237822))
|
||||
{
|
||||
player->CastSpell(player, 237797, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_MAIDEN_OF_VIGILANCE) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237798) && player->HasAura(237823))
|
||||
{
|
||||
player->CastSpell(player, 237798, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_HARJATAN) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237799) && player->HasAura(237824))
|
||||
{
|
||||
player->CastSpell(player, 237799, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_KILJAEDEN) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237800) && player->HasAura(237825))
|
||||
{
|
||||
player->CastSpell(player, 237800, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_MISTRESS_SASSZINE) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237801) && player->HasAura(237826))
|
||||
{
|
||||
player->CastSpell(player, 237801, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_THE_DESOLATE_HOST) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237802) && player->HasAura(237827))
|
||||
{
|
||||
player->CastSpell(player, 237802, false);
|
||||
}
|
||||
}
|
||||
if (instance->GetBossState(DATA_DEMONIC_INQUISITION) == IN_PROGRESS)
|
||||
{
|
||||
if (!player->HasAura(237803) && player->HasAura(237828))
|
||||
{
|
||||
player->CastSpell(player, 237803, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else checkOnProc -= diff;
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
caster->SummonCreature(NPC_INFERNAL_CHAOSBRINGER, infernalChaosbringer[i], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
|
||||
caster->ToCreature()->DespawnOrUnsummon();
|
||||
}*/
|
||||
if (checkOnRemove <= diff)
|
||||
{
|
||||
if (player->HasAura(237795) && player->HasAura(237820))
|
||||
{
|
||||
if (instance->GetBossState(DATA_FALLEN_AVATAR) == DONE || instance->GetBossState(DATA_FALLEN_AVATAR) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237795);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237796) && player->HasAura(237821))
|
||||
{
|
||||
if (instance->GetBossState(DATA_GOROTH) == DONE || instance->GetBossState(DATA_GOROTH) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237796);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237797) && player->HasAura(237822))
|
||||
{
|
||||
if (instance->GetBossState(DATA_SISTERS_OF_THEMOON) == DONE || instance->GetBossState(DATA_SISTERS_OF_THEMOON) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237797);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237798) && player->HasAura(237823))
|
||||
{
|
||||
if (instance->GetBossState(DATA_MAIDEN_OF_VIGILANCE) == DONE || instance->GetBossState(DATA_MAIDEN_OF_VIGILANCE) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237798);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237799) && player->HasAura(237824))
|
||||
{
|
||||
if (instance->GetBossState(DATA_HARJATAN) == DONE || instance->GetBossState(DATA_HARJATAN) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237799);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237800) && player->HasAura(237825))
|
||||
{
|
||||
if (instance->GetBossState(DATA_KILJAEDEN) == DONE || instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237800);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237801) && player->HasAura(237826))
|
||||
{
|
||||
if (instance->GetBossState(DATA_MISTRESS_SASSZINE) == DONE || instance->GetBossState(DATA_MISTRESS_SASSZINE) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237801);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237802) && player->HasAura(237827))
|
||||
{
|
||||
if (instance->GetBossState(DATA_THE_DESOLATE_HOST) == DONE || instance->GetBossState(DATA_THE_DESOLATE_HOST) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237802);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
if (player->HasAura(237803) && player->HasAura(237828))
|
||||
{
|
||||
if (instance->GetBossState(DATA_DEMONIC_INQUISITION) == DONE || instance->GetBossState(DATA_DEMONIC_INQUISITION) == NOT_STARTED)
|
||||
{
|
||||
player->RemoveAura(237803);
|
||||
checkOnProc = 1000;
|
||||
checkOnRemove = 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else checkOnRemove -= diff;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_goroth_summon_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
/* hook EffectUpdate (tick par diff) non supporte par notre AuraScript */;
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_vantus_rune_tomb_of_sargeras_AuraScript();
|
||||
}
|
||||
|
||||
class spell_vantus_rune_tomb_of_sargeras_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_vantus_rune_tomb_of_sargeras_SpellScript);
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (Player* player = caster->ToPlayer())
|
||||
{
|
||||
if (!player->GetQuestRewardStatus(39695))
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_YOU_ALREADY_USED_VANTUS_RUNE);
|
||||
return SPELL_FAILED_CUSTOM_ERROR;
|
||||
}
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
if (Player* player = GetCaster()->ToPlayer())
|
||||
{
|
||||
uint32 questId = 39695;
|
||||
if (questId)
|
||||
{
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest)
|
||||
return;
|
||||
|
||||
if (player->CanTakeQuest(quest, false))
|
||||
player->CompleteQuest(questId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_vantus_rune_tomb_of_sargeras_SpellScript::CheckCast);
|
||||
OnHit += SpellHitFn(spell_vantus_rune_tomb_of_sargeras_SpellScript::HandleOnHit);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_goroth_summon_SpellScript();
|
||||
return new spell_vantus_rune_tomb_of_sargeras_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void AddSC_tomb_of_sargeras()
|
||||
{
|
||||
new npc_archimage_khadgar_tos();
|
||||
new spell_goroth_summon();
|
||||
}
|
||||
RegisterCreatureAI(npc_tos_breach);
|
||||
RegisterCreatureAI(npc_tos_kadghar_1);
|
||||
RegisterGameObjectAI(go_tos_tele_to_kiljedan);
|
||||
new spell_vantus_rune_tomb_of_sargeras();
|
||||
}
|
||||
@@ -1,161 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 AshamaneProject <https://github.com/AshamaneProject>
|
||||
*
|
||||
* 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 2 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/>.
|
||||
*/
|
||||
https://uwow.biz/
|
||||
*/
|
||||
|
||||
#ifndef TOMB_OF_SARGERAS_H
|
||||
#define TOMB_OF_SARGERAS_H
|
||||
#ifndef TombOsSargeasH_
|
||||
#define TombOsSargeasH_
|
||||
|
||||
#define DataHeader "TOS"
|
||||
#define TombOfSargerasScriptName "instance_tomb_of_sargeras"
|
||||
|
||||
#include "InstanceScript.h"
|
||||
#include "AreaTriggerTemplate.h"
|
||||
#include "AreaTrigger.h"
|
||||
#include "AreaTriggerAI.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "EventMap.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Unit.h"
|
||||
#include "GameObject.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Vehicle.h"
|
||||
#include "VehicleDefines.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Player.h"
|
||||
#include "Map.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "MapManager.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "Player.h"
|
||||
|
||||
uint32 const EncounterCount = 10;
|
||||
#include "Spell.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
enum tosDataTypes
|
||||
// Constantes uwow absentes de notre core (valeurs = SharedDefines de DestinyCoreNew).
|
||||
// Les hooks references sur ces valeurs ne matchent simplement pas si le client n a pas l effet.
|
||||
#define SPELL_AURA_FIXATE AuraType(128)
|
||||
#define SPELL_EFFECT_TELEPORT_L SpellEffectName(252)
|
||||
#define TARGET_UNIT_ENEMY_BETWEEN_DEST Targets(129)
|
||||
#define TARGET_UNIT_BETWEEN_ENEMY Targets(134)
|
||||
#define REACT_ATTACK_OFF REACT_PASSIVE
|
||||
#define UNIT_DYNFLAG_NOT_SELECTABLE_MODEL 0x0002
|
||||
#define CREATURE_SUMMON_GROUP_RESET 0
|
||||
|
||||
enum eData
|
||||
{
|
||||
DATA_GOROTH,
|
||||
DATA_HARJATAN,
|
||||
DATA_MISTRESS_SASSZINE,
|
||||
DATA_ATRIGAN,
|
||||
DATA_BELAC,
|
||||
DATA_SISTERS_OF_THE_MOON,
|
||||
DATA_THE_DESOLATE_HOST,
|
||||
DATA_MAIDEN_OF_VIGILANCE,
|
||||
DATA_FALLEN_AVATAR,
|
||||
DATA_KILJAEDEN,
|
||||
DATA_GOROTH = 0,
|
||||
DATA_HARJATAN = 1,
|
||||
DATA_MISTRESS_SASSZINE = 2,
|
||||
|
||||
ENCOUNTER_COUNT,
|
||||
DATA_DEMONIC_INQUISITION = 3,
|
||||
DATA_THE_DESOLATE_HOST = 4,
|
||||
DATA_SISTERS_OF_THEMOON = 5,
|
||||
|
||||
DATA_MAIDEN_OF_VIGILANCE = 6,
|
||||
DATA_FALLEN_AVATAR = 7,
|
||||
DATA_KILJAEDEN = 8,
|
||||
|
||||
MAX_ENCOUNTER
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
enum eCreatures
|
||||
{
|
||||
BOSS_GOROTH = 115844,
|
||||
BOSS_ATRIGAN = 120996,
|
||||
NPC_BREACH_IN_WINDOW = 121605,
|
||||
|
||||
// Demonic Inquisition
|
||||
BOSS_BELAC = 116691,
|
||||
BOSS_HARJATAN = 116407,
|
||||
|
||||
// Sisters of the Moon
|
||||
NPC_HUNTRESS_KASPARIAN = 118523,
|
||||
NPC_CAPTAIN_YATHAE_MOONSTRIKE = 118374,
|
||||
NPC_PRIESTESS_LUNASPYRE = 118518,
|
||||
|
||||
NPC_SASSZINE = 115767,
|
||||
|
||||
// Desolate Host
|
||||
NPC_ENGINE_OF_SOULS = 118460,
|
||||
NPC_SOUL_QUEEN_DEJAHNA = 118462,
|
||||
NPC_DESOLATE_HOST = 119072,
|
||||
|
||||
NPC_MAIDEN_OF_VIGILANCE = 118289,
|
||||
NPC_FALLEN_AVATAR = 120436,
|
||||
NPC_KILJAEDEN = 117269,
|
||||
NPC_RAZORJAW_WAVEMENDER = 116569,
|
||||
NPC_RAZORJAW_GLADIATOR = 117596,
|
||||
NPC_INFERNAL_CHAOSBRINGER = 118022,
|
||||
NPC_BRIMSTONE_INFERNAL = 119950,
|
||||
NPC_KHADGAR = 119726,
|
||||
NPC_VELEN = 119728,
|
||||
NPC_ILLIDAN = 119729,
|
||||
NPC_ATRIGAN = 120996,
|
||||
NPC_MAEIV = 119730,
|
||||
NPC_DURGAN = 119777,
|
||||
|
||||
NPC_EGIDA = 121630,
|
||||
NPC_HAMMER_1 = 121494,
|
||||
NPC_HAMMER_2 = 121111,
|
||||
NPC_ELUNES_1 = 121495,
|
||||
NPC_ELUNES_2 = 121110,
|
||||
NPC_GOLGANETH_1 = 121496,
|
||||
NPC_GOLGANETH_2 = 121105,
|
||||
|
||||
NPC_EGVIN = 119723,
|
||||
|
||||
NPC_ATRIGAN_MISC = 120996, //Not boss
|
||||
NPC_SASSZINE_NPC_OUTRO = 121190,
|
||||
NPC_SASSZINE_MISC = 121184,
|
||||
NPC_LUNAR_ARCHER = 120721,
|
||||
NPC_GUARDIAN_SENTRY = 120777,
|
||||
NPC_TORMENTED_SOUL = 117957,
|
||||
NPC_FRAGMENT_SOUL = 121138,
|
||||
|
||||
NPC_KILDJEDAN_AVATARA = 120867,
|
||||
|
||||
//! BOSSES
|
||||
|
||||
//Goroth
|
||||
NPC_GOROTH = 115844,
|
||||
NPC_EMBER_STALKER = 115892,
|
||||
NPC_INFERNAL_SPIKE = 116976,
|
||||
NPC_LAVA_STALKER = 117931, //Heroic+
|
||||
NPC_BRIMSTONE_INFERNAL = 119950,
|
||||
|
||||
//Harajatan
|
||||
NPC_HARJATAN = 116407,
|
||||
NPC_EGGS = 120545,
|
||||
NPC_ELDER = 121071,
|
||||
NPC_TADPOLE_1 = 120574,
|
||||
NPC_TADPOLE_2 = 121156,
|
||||
NPC_TADPOLE_3 = 121155,
|
||||
NPC_EVENT_1 = 121011,
|
||||
NPC_EVENT_2 = 117123,
|
||||
|
||||
//Mistress Sassz'ine
|
||||
NPC_SASSZINE = 115767,
|
||||
NPC_ABYSS_STALKER = 115795,
|
||||
NPC_TORNADO_TRIGGER = 118286,
|
||||
NPC_ELECTRIFYING_JELLYFISH = 115896,
|
||||
NPC_RAZORJAW_WAVERUNNER = 115902,
|
||||
NPC_SARUKEL_TRIGGER = 116843,
|
||||
NPC_OSSUNET_TRIGGER = 116881,
|
||||
NPC_PIRANHADO_TRIGGER = 116841,
|
||||
NPC_DELICIOUS_BUFFERFISH = 119791, //Mythic
|
||||
NPC_TIDESTONE_GOLGANNETH = 121105, //Spawn after death boss
|
||||
|
||||
//Demonic Inquisitor
|
||||
NPC_ATRIGAN = 116689,
|
||||
NPC_BELAK = 116691,
|
||||
|
||||
NPC_ESSENCE_LIGHT = 118640,
|
||||
NPC_ESSENCE_FEL = 118643,
|
||||
NPC_REMANENCE_LIGHT = 119825,
|
||||
NPC_REMANENCE_FEL = 119826,
|
||||
|
||||
//Sisters of the Moon
|
||||
NPC_MOON_STALKER = 118182,
|
||||
NPC_HUNTRESS_KASPARIAN = 118523,
|
||||
NPC_PRIESTESS_LUNASPYRE = 118518,
|
||||
NPC_CAPTAIN_YATHAE = 118374,
|
||||
NPC_MOONTALON = 119205,
|
||||
NPC_GLAIVE_TARGET = 119054,
|
||||
NPC_SISTERS_ACH_ADD = 121498,
|
||||
|
||||
//The Desolate Host
|
||||
NPC_SWIRLING_SOULS_TRIG = 120988, //Event Manager
|
||||
NPC_DESOLATE_HOST = 119072, //!Real world
|
||||
NPC_ENGINE_OF_SOULS = 118460,
|
||||
NPC_REANIMATED_TEMPLAR = 118715,
|
||||
NPC_REANIMATED_TEMPLAR_MIRROR = 119938, //Mythic
|
||||
NPC_GHASTLY_BONEWARDEN = 118728,
|
||||
NPC_GHASTLY_BONEWARDEN_MIRROR = 119939, //Mythic
|
||||
NPC_TORMENTED_CRIES_TRIG = 118924,
|
||||
NPC_SOUL_QUEEN_DEJAHNA = 118462, //!Spirit world
|
||||
NPC_FALLEN_PRIESTESS = 118729,
|
||||
NPC_FALLEN_PRIESTESS_MIRROR = 119940, //Mythic
|
||||
NPC_SOUL_RESIDUE = 118730,
|
||||
NPC_SOUL_RESIDUE_MIRROR = 119941, //Mythic
|
||||
NPC_SPIRITUAL_FONT = 118701, //!Other
|
||||
NPC_SPIRITUAL_BARRIER_TRIG = 118727,
|
||||
NPC_TEARS_OF_ELUNE = 121110, //Spawn After Dies Boss
|
||||
|
||||
//Avatara
|
||||
NPC_FALLEN_AVATAR = 116939,
|
||||
NPC_CORRUPTED_BLADE = 119158,
|
||||
NPC_PILONES = 117279,
|
||||
NPC_AVATARA_MAIDEN = 117264,
|
||||
NPC_BLACK_WINDS = 121294,
|
||||
NPC_TOUCH_OF_SARGERAS = 120838,
|
||||
|
||||
//Maiden of Vigilance
|
||||
NPC_MAIDEN_OF_VIGILANCE = 118289,
|
||||
|
||||
//Kil'jaeden <The Deceiver>
|
||||
NPC_KILJAEDEN = 117269,
|
||||
NPC_ARMAGEDDON_STALKER = 120839,
|
||||
NPC_ERUPTING_REFLECTION = 119206,
|
||||
NPC_WAILING_REFLECTION = 119107, //Mythic
|
||||
NPC_HOPELESS_REFLECTION = 119663, //Mythic
|
||||
NPC_SHADOWSOUL = 121193,
|
||||
NPC_STAGE4_ILLIDAN_STORMRAGE = 121227,
|
||||
NPC_DEMONIC_OBELISK = 120270,
|
||||
NPC_NETHER_RIFT = 120390,
|
||||
NPC_FLAMING_ORB = 120082, //Heroic+
|
||||
};
|
||||
|
||||
enum CosmeticSpells
|
||||
enum eGameObjects
|
||||
{
|
||||
SPELL_COSMETIC_TELEPORT = 240923, // Used by Kil'jaeden after Fallen Avatar activation
|
||||
SPELL_AWAKEN = 240897, // Kil'jaeden activate Fallen Avatar spell.
|
||||
SPELL_FEL_INFUSION = 236682, // Used by Maiden of Valor.
|
||||
GO_INTRODESTROY_1 = 269839,
|
||||
GO_INTRODESTROY_2 = 269838,
|
||||
GO_INTRODESTROY_3 = 269842,
|
||||
|
||||
GO_GOROTH_GATES = 272802,
|
||||
GO_GOROTH_INFERNAL_SPIKE = 266938, //LOS_BLOCKER
|
||||
|
||||
GO_SASSZINE_DOOR = 269976,
|
||||
GO_INQUISITION_DOOR = 268579,
|
||||
GO_INQUISITION_DOOR_INTRO = 268580,
|
||||
GO_SISTERS_MOON_DOOR = 269045,
|
||||
|
||||
GO_HAMMER_THRONE = 269780,
|
||||
GO_ELUNES_THRONE = 269779,
|
||||
GO_GOLGANETH_THRONE = 269782,
|
||||
|
||||
GO_MAIDEN_DOOR = 269988,
|
||||
GO_ELEVATOR = 268574,
|
||||
|
||||
GO_AVATARA_FLOOR = 267934,
|
||||
GO_AVATARA_DOOR = 269262,
|
||||
|
||||
GO_DESOLATE_HOST_DOOR_1 = 268749,
|
||||
GO_DESOLATE_HOST_DOOR_2 = 269781,
|
||||
|
||||
GO_KILJAEDEN_BRIDGE_1 = 271126,
|
||||
GO_KILJAEDEN_BRIDGE_2 = 271127,
|
||||
GO_KILJAEDEN_CHEST = 271099,
|
||||
};
|
||||
|
||||
enum tosSpells
|
||||
enum eSpells
|
||||
{
|
||||
SPELL_SUMMON = 241227,
|
||||
SPELL_IMPACT = 242924,
|
||||
SPELL_PILLAR_COSMETIC = 243149,
|
||||
SPELL_GOROTH_INTRO = 247931,
|
||||
SPELL_INTRO_TELEPORT = 241303,
|
||||
};
|
||||
|
||||
enum tosSounds
|
||||
|
||||
|
||||
enum TosGenericActions
|
||||
{
|
||||
SOUND_INTRO = 81787,
|
||||
SOUND_GOROTH2 = 81789,
|
||||
ACTION_NONE = 0,
|
||||
ACTION_1 = 1,
|
||||
ACTION_2,
|
||||
ACTION_3,
|
||||
ACTION_4,
|
||||
ACTION_5,
|
||||
ACTION_6,
|
||||
ACTION_7,
|
||||
ACTION_8,
|
||||
ACTION_9,
|
||||
ACTION_10,
|
||||
ACTION_11,
|
||||
ACTION_12,
|
||||
ACTION_13,
|
||||
ACTION_14,
|
||||
ACTION_15,
|
||||
ACTION_16,
|
||||
ACTION_17,
|
||||
ACTION_18,
|
||||
ACTION_19,
|
||||
ACTION_20,
|
||||
ACTION_21,
|
||||
ACTION_22,
|
||||
ACTION_23,
|
||||
ACTION_24,
|
||||
ACTION_25,
|
||||
ACTION_26,
|
||||
ACTION_27,
|
||||
ACTION_28,
|
||||
ACTION_29,
|
||||
ACTION_30,
|
||||
ACTION_31,
|
||||
ACTION_32,
|
||||
ACTION_33,
|
||||
ACTION_34,
|
||||
ACTION_35,
|
||||
ACTION_36,
|
||||
ACTION_37,
|
||||
ACTION_38,
|
||||
ACTION_39,
|
||||
ACTION_40,
|
||||
ACTION_41,
|
||||
ACTION_42,
|
||||
ACTION_43,
|
||||
ACTION_44,
|
||||
ACTION_45,
|
||||
ACTION_46,
|
||||
ACTION_47,
|
||||
ACTION_48,
|
||||
ACTION_49,
|
||||
ACTION_50,
|
||||
};
|
||||
|
||||
enum Gameobjects
|
||||
// Enum generique d evenements (present dans l EventMap.h de DestinyCoreNew, module-local ici)
|
||||
enum TosGenericEvents
|
||||
{
|
||||
GO_MOON_CHAMBER_WINDOW = 269842,
|
||||
|
||||
GO_DOOR_ROOM_GOROTH_S = 269974,
|
||||
GO_DOOR_ROOM_GOROTH_N = 269975,
|
||||
GO_DOOR_ROOM_GOROTH_E = 269973,
|
||||
GO_DOOR_ROOM_GOROTH_4 = 268580,
|
||||
|
||||
GO_DOOR_HARJATAN_1 = 269120,
|
||||
GO_DOOR_HARJATAN_2 = 269192,
|
||||
|
||||
GO_DOOR_AFTER_SASSZINE_1 = 268752,
|
||||
GO_DOOR_SISTERS_OF_THE_MOON_1 = 268750,
|
||||
GO_DOOR_SISTERS_OF_THE_MOON_2 = 268514,
|
||||
GO_DOOR_SISTERS_OF_THE_MOON_3 = 268751,
|
||||
GO_DOOR_SISTERS_OF_THE_MOON_4 = 268749,
|
||||
GO_DOOR_DEMONIC_INQUISITION_1 = 268579,
|
||||
GO_DOOR_MAIDEN_OF_VIGILANCE_1 = 269164,
|
||||
GO_DOOR_MAIDEN_OF_VIGILANCE_2 = 269261,
|
||||
GO_DOOR_MAIDEN_OF_VIGILANCE_3 = 269262,
|
||||
GO_DOOR_FALLEN_AVATAR = 267934,
|
||||
|
||||
GO_DOOR_FELSTORM_COLLISION_01 = 269987,
|
||||
GO_DESTRUCTIBLE_1 = 269842,
|
||||
GO_DESTRUCTIBLE_2 = 269839,
|
||||
GO_DESTRUCTIBLE_3 = 269838,
|
||||
GO_DOOR_TO_MISTRESS = 269120,
|
||||
GO_DOOR_TO_MISTRESS2 = 270940,
|
||||
EVENT_1 = 1,
|
||||
EVENT_2,
|
||||
EVENT_3,
|
||||
EVENT_4,
|
||||
EVENT_5,
|
||||
EVENT_6,
|
||||
EVENT_7,
|
||||
EVENT_8,
|
||||
EVENT_9,
|
||||
EVENT_10,
|
||||
EVENT_11,
|
||||
EVENT_12,
|
||||
EVENT_13,
|
||||
EVENT_14,
|
||||
EVENT_15,
|
||||
EVENT_16,
|
||||
EVENT_17,
|
||||
EVENT_18,
|
||||
EVENT_19,
|
||||
EVENT_20,
|
||||
EVENT_21,
|
||||
EVENT_22,
|
||||
EVENT_23,
|
||||
EVENT_24,
|
||||
EVENT_25,
|
||||
EVENT_26,
|
||||
EVENT_27,
|
||||
EVENT_28,
|
||||
EVENT_29,
|
||||
EVENT_30,
|
||||
EVENT_31,
|
||||
EVENT_32,
|
||||
EVENT_33,
|
||||
EVENT_34,
|
||||
EVENT_35,
|
||||
EVENT_36,
|
||||
EVENT_37,
|
||||
EVENT_38,
|
||||
EVENT_39,
|
||||
EVENT_40,
|
||||
EVENT_41,
|
||||
EVENT_42,
|
||||
EVENT_43,
|
||||
EVENT_44,
|
||||
EVENT_45,
|
||||
EVENT_46,
|
||||
EVENT_47,
|
||||
EVENT_48,
|
||||
EVENT_49,
|
||||
EVENT_50,
|
||||
};
|
||||
|
||||
template<class AI>
|
||||
CreatureAI* GetTombOfSargerasAI(Creature* creature)
|
||||
{
|
||||
if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
|
||||
if (instance->GetInstanceScript())
|
||||
if (instance->GetScriptId() == sObjectMgr->GetScriptId(TombOfSargerasScriptName))
|
||||
return new AI(creature);
|
||||
return NULL;
|
||||
}
|
||||
#define ToSScriptName "instance_tomb_of_sargeras"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -175,14 +175,15 @@ void AddSC_instance_emerald_nightmare();
|
||||
|
||||
// Tomb of Sargeras
|
||||
void AddSC_boss_demonic_inquisition();
|
||||
void AddSC_boss_desolate_host();
|
||||
void AddSC_boss_the_desolate_host();
|
||||
void AddSC_boss_fallen_avatar();
|
||||
void AddSC_boss_goroth();
|
||||
void AddSC_boss_sisters_of_the_moon();
|
||||
void AddSC_boss_shiwar();
|
||||
void AddSC_boss_harjatan();
|
||||
void AddSC_boss_tos_kiljaeden();
|
||||
void AddSC_boss_maiden_of_vigilance();
|
||||
void AddSC_boss_sasszine();
|
||||
void AddSC_boss_mistress_sasszine();
|
||||
void AddSC_tomb_of_sargeras();
|
||||
void AddSC_instance_tomb_of_sargeras();
|
||||
|
||||
@@ -376,14 +377,15 @@ void AddBrokenIslesScripts()
|
||||
|
||||
// Tomb of Sargeras
|
||||
AddSC_boss_demonic_inquisition();
|
||||
AddSC_boss_desolate_host();
|
||||
AddSC_boss_the_desolate_host();
|
||||
AddSC_boss_fallen_avatar();
|
||||
AddSC_boss_goroth();
|
||||
AddSC_boss_sisters_of_the_moon();
|
||||
AddSC_boss_shiwar();
|
||||
AddSC_boss_harjatan();
|
||||
AddSC_boss_tos_kiljaeden();
|
||||
AddSC_boss_maiden_of_vigilance();
|
||||
AddSC_boss_sasszine();
|
||||
AddSC_boss_mistress_sasszine();
|
||||
AddSC_tomb_of_sargeras();
|
||||
AddSC_instance_tomb_of_sargeras();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user