Script Instance Forge of Souls.

Script based on proposal of Synric on trinitycore forum (submitted by Skarabex on GC).
Fix EventMap::DelayEvents
Fixes issue #1310.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-04-08 21:03:26 +02:00
parent 6f3996fd11
commit d93e4079f7
13 changed files with 1597 additions and 95 deletions
+26 -9
View File
@@ -405,18 +405,27 @@ class EventMap : private std::map<uint32, uint32>
return 0;
}
void DelayEvents(uint32 time, uint32 gcd)
// Delay all events
void DelayEvents(uint32 delay)
{
time += m_time;
if (delay < m_time)
m_time -= delay;
else
m_time = 0;
}
// Delay all events having the specified Global Cooldown.
void DelayEvents(uint32 delay, uint32 gcd)
{
uint32 nextTime = m_time + delay;
gcd = (1 << (gcd + 16));
for (iterator itr = begin(); itr != end();)
for (iterator itr = begin(); itr != end() && itr->first < nextTime;)
{
if (itr->first >= time)
break;
if (itr->second & gcd)
{
ScheduleEvent(time, itr->second);
erase(itr++);
ScheduleEvent(itr->second, itr->first-m_time+delay);
erase(itr);
itr = begin();
}
else
++itr;
@@ -428,7 +437,10 @@ class EventMap : private std::map<uint32, uint32>
for (iterator itr = begin(); itr != end();)
{
if (eventId == (itr->second & 0x0000FFFF))
erase(itr++);
{
erase(itr);
itr = begin();
}
else
++itr;
}
@@ -436,10 +448,15 @@ class EventMap : private std::map<uint32, uint32>
void CancelEventsByGCD(uint32 gcd)
{
gcd = (1 << (gcd + 16));
for (iterator itr = begin(); itr != end();)
{
if (itr->second & gcd)
erase(itr++);
{
erase(itr);
itr = begin();
}
else
++itr;
}
+8
View File
@@ -407,6 +407,10 @@ void AddSC_boss_xevozz();
void AddSC_boss_zuramat();
void AddSC_instance_violet_hold();
void AddSC_violet_hold();
void AddSC_instance_forge_of_souls(); //Forge of Souls
void AddSC_forge_of_souls();
void AddSC_boss_bronjahm();
void AddSC_boss_devourer_of_souls();
void AddSC_instance_pit_of_saron(); //Pit of Saron
void AddSC_pit_of_saron();
void AddSC_boss_garfrost();
@@ -899,6 +903,10 @@ void AddScripts()
AddSC_boss_zuramat();
AddSC_instance_violet_hold();
AddSC_violet_hold();
AddSC_instance_forge_of_souls(); //Forge of Souls
AddSC_forge_of_souls();
AddSC_boss_bronjahm();
AddSC_boss_devourer_of_souls();
AddSC_instance_pit_of_saron(); //Pit of Saron
AddSC_pit_of_saron();
AddSC_boss_garfrost();
+2
View File
@@ -341,7 +341,9 @@ SET(scripts_STAT_SRCS
northrend/draktharon_keep/drak_tharon_keep.h
northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp
northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp
northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
northrend/frozen_halls/forge_of_souls/forge_of_souls.h
northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp
northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
@@ -17,28 +17,53 @@
#include "ScriptedPch.h"
#include "forge_of_souls.h"
/*
* TODO:
* - Fix Soul Storm spell and remove work around.
*/
enum Yells
{
SAY_AGGRO = -1632001,
SAY_SLAY_1 = -1632002,
SAY_SLAY_2 = -1632003,
SAY_DEATH = -1632004,
SAY_SOUL_STORM = -1632005,
SAY_CORRUPT_SOUL = -1632006,
};
enum Spells
{
SPELL_MAGIC_S_BANE = 68793,
SPELL_MAGIC_S_BANE_H = 69050,
H_SPELL_MAGIC_S_BANE = 69050,
SPELL_CORRUPT_SOUL = 68839,
SPELL_CONSUME_SOUL = 68858,
SPELL_CONSUME_SOUL_H = 69047,
H_SPELL_CONSUME_SOUL = 69047,
SPELL_TELEPORT = 68988,
SPELL_FEAR = 68950,
SPELL_SOULSTORM = 68872,
SPELL_SOULSTORM_H = 69049,
SPELL_SHADOW_BOLT = 70043
SPELL_SOULSTORM_AURA = 68921,
H_SPELL_SOULSTORM_AURA = 69049,
SPELL_SHADOW_BOLT = 70043,
};
enum Events
{
EVENT_NONE,
EVENT_SHADOW_BOLT,
EVENT_MAGIC_BANE,
EVENT_CORRUPT_SOUL,
EVENT_SOUL_STORM,
EVENT_SOUL_STORM_AURA,
EVENT_FEAR,
};
enum CombatPhases
{
PHASE_1,
PHASE_2
};
/*enum Adds
{
CREATURE_CORRUPTED_SOUL_FRAGMENT = 36535
};*/
struct boss_bronjahmAI : public ScriptedAI
{
boss_bronjahmAI(Creature *c) : ScriptedAI(c)
@@ -46,23 +71,20 @@ struct boss_bronjahmAI : public ScriptedAI
pInstance = m_creature->GetInstanceData();
}
uint32 uiFearTimer;
uint32 uiShadowBoltTimer;
uint32 uiMagicsBaneTimer;
uint32 uiCorruptSoulTimer;
CombatPhases Phase;
ScriptedInstance* pInstance;
EventMap events;
CombatPhases phase;
void Reset()
{
Phase = PHASE_1;
phase = PHASE_1;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
uiFearTimer = urand(8000,12000);
uiShadowBoltTimer = 2000;
uiMagicsBaneTimer = urand(8000,15000);
uiCorruptSoulTimer = urand(15000,25000);
events.Reset();
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000,15000));
events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(15000,25000));
if (pInstance)
pInstance->SetData(DATA_BRONJAHM_EVENT, NOT_STARTED);
@@ -70,7 +92,7 @@ struct boss_bronjahmAI : public ScriptedAI
void EnterCombat(Unit* who)
{
//DoScriptText(SAY_AGGRO, m_creature);
DoScriptText(SAY_AGGRO, m_creature);
if (pInstance)
pInstance->SetData(DATA_BRONJAHM_EVENT, IN_PROGRESS);
@@ -78,55 +100,91 @@ struct boss_bronjahmAI : public ScriptedAI
void JustDied(Unit* killer)
{
//DoScriptText(SAY_DEATH, m_creature);
DoScriptText(SAY_DEATH, m_creature);
if (pInstance)
pInstance->SetData(DATA_BRONJAHM_EVENT, DONE);
}
void KilledUnit(Unit *pWho)
{
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
}
// Cast aura spell on all players farther than 10y
void ApplySoulStorm()
{
const std::list<HostileReference*>& threatlist = m_creature->getThreatManager().getThreatList();
if (threatlist.empty())
return;
for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if (pUnit && pUnit->isAlive() && pUnit->GetDistance(m_creature) > 10.0f)
m_creature->CastSpell(pUnit, DUNGEON_MODE(SPELL_SOULSTORM_AURA,H_SPELL_SOULSTORM_AURA), true);
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
switch (Phase)
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
if (phase == PHASE_1 && HealthBelowPct(30))
{
case PHASE_1:
if (uiCorruptSoulTimer <= diff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(pTarget,SPELL_CORRUPT_SOUL);
uiCorruptSoulTimer = urand(15000,25000);
} else uiCorruptSoulTimer -= diff;
break;
case PHASE_2:
if (!me->HasAura(SPELL_SOULSTORM) || !me->HasAura(SPELL_SOULSTORM_H))
DoCast(m_creature, DUNGEON_MODE(SPELL_SOULSTORM,SPELL_SOULSTORM_H));
if (uiFearTimer <= diff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(m_creature->getVictim(),SPELL_FEAR);
uiFearTimer = urand(8000,12000);
} else uiFearTimer -= diff;
break;
phase = PHASE_2;
DoCast(m_creature,SPELL_TELEPORT);
m_creature->GetMotionMaster()->Clear();
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
events.CancelEvent(EVENT_CORRUPT_SOUL);
events.ScheduleEvent(EVENT_SOUL_STORM, 1000);
events.ScheduleEvent(EVENT_FEAR, urand(8000,12000));
return;
}
if (HealthBelowPct(30))
DoCast(m_creature,SPELL_TELEPORT);
if (uiShadowBoltTimer <= diff)
while(uint32 eventId = events.ExecuteEvent())
{
if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
DoCastVictim(SPELL_SHADOW_BOLT);
uiShadowBoltTimer = 2000;
} else uiShadowBoltTimer -= diff;
if (uiMagicsBaneTimer <= diff)
{
DoCastVictim(DUNGEON_MODE(SPELL_MAGIC_S_BANE,SPELL_MAGIC_S_BANE_H));
uiMagicsBaneTimer = urand(8000,15000);
} else uiMagicsBaneTimer -= diff;
switch(eventId)
{
case EVENT_CORRUPT_SOUL:
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
{
DoScriptText(SAY_CORRUPT_SOUL, m_creature);
DoCast(pTarget,SPELL_CORRUPT_SOUL);
}
events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(15000,25000));
break;
case EVENT_SOUL_STORM:
DoScriptText(SAY_SOUL_STORM, m_creature);
// DoCast(m_creature, SPELL_SOULSTORM); bug: put the aura without the limit of 10 yards.
events.ScheduleEvent(EVENT_SOUL_STORM_AURA, 1000);
break;
case EVENT_SOUL_STORM_AURA:
ApplySoulStorm();
events.ScheduleEvent(EVENT_SOUL_STORM_AURA, 1000);
break;
case EVENT_FEAR:
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(pTarget,SPELL_FEAR);
events.ScheduleEvent(EVENT_FEAR, urand(8000,12000));
break;
case EVENT_SHADOW_BOLT:
DoCastVictim(SPELL_SHADOW_BOLT);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
break;
case EVENT_MAGIC_BANE:
DoCastVictim(DUNGEON_MODE(SPELL_MAGIC_S_BANE,H_SPELL_MAGIC_S_BANE));
events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000,15000));
break;
}
}
DoMeleeAttackIfReady();
}
@@ -159,7 +217,7 @@ struct mob_corrupted_soul_fragmentAI : public ScriptedAI
{
if (pInstance)
if (Creature* pBronjham = Unit::GetCreature(*m_creature,pInstance->GetData64(DATA_BRONJAHM)))
DoCast(pBronjham,DUNGEON_MODE(SPELL_CONSUME_SOUL,SPELL_CONSUME_SOUL_H));
DoCast(pBronjham,DUNGEON_MODE(SPELL_CONSUME_SOUL,H_SPELL_CONSUME_SOUL));
}
void UpdateAI(const uint32 diff) {}
@@ -174,13 +232,13 @@ void AddSC_boss_bronjahm()
{
Script *newscript;
newscript = new Script;
newscript->Name = "mob_corruptel_soul_fragment";
newscript->GetAI = &GetAI_mob_corrupted_soul_fragment;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_bronjahm";
newscript->GetAI = &GetAI_boss_bronjahm;
newscript->RegisterSelf();
}
newscript = new Script;
newscript->Name = "mob_corrupted_soul_fragment";
newscript->GetAI = &GetAI_mob_corrupted_soul_fragment;
newscript->RegisterSelf();
}
@@ -0,0 +1,349 @@
/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "forge_of_souls.h"
/*
* TODO:
* - Fix model id during unleash soul -> seems DB issue 36503 is missing (likewise 36504 is also missing).
* - Fix outro npc movement
*/
#define PI 3.1415f
enum Yells
{
SAY_FACE_ANGER_AGGRO = -1632010,
SAY_FACE_DESIRE_AGGRO = -1632011,
SAY_FACE_ANGER_SLAY_1 = -1632012,
SAY_FACE_SORROW_SLAY_1 = -1632013,
SAY_FACE_DESIRE_SLAY_1 = -1632014,
SAY_FACE_ANGER_SLAY_2 = -1632015,
SAY_FACE_SORROW_SLAY_2 = -1632016,
SAY_FACE_DESIRE_SLAY_2 = -1632017,
SAY_FACE_SORROW_DEATH = -1632019,
SAY_FACE_DESIRE_DEATH = -1632020,
EMOTE_MIRRORED_SOUL = -1632021,
EMOTE_UNLEASH_SOUL = -1632022,
SAY_FACE_ANGER_UNLEASH_SOUL = -1632023,
SAY_FACE_SORROW_UNLEASH_SOUL = -1632024,
SAY_FACE_DESIRE_UNLEASH_SOUL = -1632025,
EMOTE_WAILING_SOUL = -1632026,
SAY_FACE_ANGER_WAILING_SOUL = -1632027,
SAY_FACE_DESIRE_WAILING_SOUL = -1632028,
SAY_JAINA_OUTRO = -1632029,
SAY_SYLVANAS_OUTRO = -1632030,
};
enum Spells
{
SPELL_PHANTOM_BLAST = 68982,
H_SPELL_PHANTOM_BLAST = 70322,
SPELL_MIRRORED_SOUL = 69051,
SPELL_WELL_OF_SOULS = 68820,
SPELL_WELL_OF_SOULS_VIS = 68854,
SPELL_UNLEASHED_SOULS = 68939,
SPELL_WAILING_SOULS_STARTING = 68912, // Initial spell cast at begining of wailing souls phase
SPELL_WAILING_SOULS_BEAM = 68875, // the beam visual
SPELL_WAILING_SOULS = 68873, // the actual spell
H_SPELL_WAILING_SOULS = 70324,
// 68871,68873,68875,68876,68899,68912,70324,
// 68899 trigger 68871
};
enum Events
{
EVENT_NONE,
EVENT_PHANTOM_BLAST,
EVENT_MIRRORED_SOUL,
EVENT_WELL_OF_SOULS,
EVENT_UNLEASHED_SOULS,
EVENT_WAILING_SOULS,
EVENT_WAILING_SOULS_TICK,
EVENT_FACE_ANGER,
};
enum eEnum
{
ACHIEV_THREE_FACED = 4523,
DISPLAY_ANGER = 30148,
DISPLAY_SORROW = 30149,
DISPLAY_DESIRE = 30150,
};
struct
{
uint32 entry[2];
Position movePosition;
} outroPositions[] =
{
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5590.47, 2427.79, 705.935, 0.802851 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5593.59, 2428.34, 705.935, 0.977384 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5600.81, 2429.31, 705.935, 0.890118 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5600.81, 2421.12, 705.935, 0.890118 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5601.43, 2426.53, 705.935, 0.890118 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5601.55, 2418.36, 705.935, 1.15192 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5598, 2429.14, 705.935, 1.0472 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5594.04, 2424.87, 705.935, 1.15192 } },
{ NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5597.89, 2421.54, 705.935, 0.610865 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5598.57, 2434.62, 705.935, 1.13446 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5585.46, 2417.99, 705.935, 1.06465 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5605.81, 2428.42, 705.935, 0.820305 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5591.61, 2412.66, 705.935, 0.925025 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5593.9, 2410.64, 705.935, 0.872665 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5586.76, 2416.73, 705.935, 0.942478 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5592.23, 2419.14, 705.935, 0.855211 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5594.61, 2416.87, 705.935, 0.907571 } },
{ NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5589.77, 2421.03, 705.935, 0.855211 } },
{ NPC_KORELN, NPC_LORALEN, { 5602.58, 2435.95, 705.935, 0.959931 } },
{ NPC_ELANDRA, NPC_KALIRA, { 5606.13, 2433.16, 705.935, 0.785398 } },
{ NPC_JAINA_PART2, NPC_SYLVANAS_PART2, { 5606.12, 2436.6, 705.935, 0.890118 } },
{ 0, 0, { 0, 0, 0, 0 } }
};
struct boss_devourer_of_soulsAI : public ScriptedAI
{
boss_devourer_of_soulsAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
bool bThreeFaceAchievement;
ScriptedInstance* pInstance;
EventMap events;
// wailing soul event
float beamAngle;
float beamAngleDiff;
int8 wailingSoulTick;
uint64 uiMirroredSoulTarget;
void Reset()
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
m_creature->SetDisplayId(DISPLAY_ANGER);
m_creature->SetReactState(REACT_AGGRESSIVE);
events.Reset();
bThreeFaceAchievement = true;
uiMirroredSoulTarget = 0;
if (pInstance)
pInstance->SetData(DATA_DEVOURER_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* who)
{
if (pInstance)
pInstance->SetData(DATA_DEVOURER_EVENT, IN_PROGRESS);
DoScriptText(RAND(SAY_FACE_ANGER_AGGRO,SAY_FACE_DESIRE_AGGRO), m_creature);
events.ScheduleEvent(EVENT_PHANTOM_BLAST, 5000);
events.ScheduleEvent(EVENT_MIRRORED_SOUL, 8000);
events.ScheduleEvent(EVENT_WELL_OF_SOULS, 30000);
events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 20000);
events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000,70000));
}
void DamageTaken(Unit *pDoneBy, uint32 &uiDamage)
{
if (uiMirroredSoulTarget && m_creature->HasAura(SPELL_MIRRORED_SOUL))
{
if (Player *pPlayer = Unit::GetPlayer(uiMirroredSoulTarget))
{
if (Aura *pAura = pPlayer->GetAura(SPELL_MIRRORED_SOUL))
{
int32 mirrorDamage = (uiDamage * 45)/100;
m_creature->CastCustomSpell(pPlayer, 69034, &mirrorDamage, 0, 0, true);
// m_creature->DealDamage(pPlayer, (uiDamage * 45)/100, 0, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW);
}
else
uiMirroredSoulTarget = 0;
}
}
}
void KilledUnit(Unit *victim)
{
DoScriptText(RAND(SAY_FACE_ANGER_SLAY_1,SAY_FACE_SORROW_SLAY_1,SAY_FACE_DESIRE_SLAY_1,
SAY_FACE_ANGER_SLAY_2,SAY_FACE_SORROW_SLAY_2,SAY_FACE_DESIRE_SLAY_2), m_creature);
}
void JustDied(Unit* killer)
{
Position spawnPoint = { 5618.139, 2451.873, 705.854 };
DoScriptText(RAND(SAY_FACE_SORROW_DEATH,SAY_FACE_DESIRE_DEATH), m_creature);
if (pInstance)
{
pInstance->SetData(DATA_DEVOURER_EVENT, DONE);
if (bThreeFaceAchievement && IsHeroic())
pInstance->DoCompleteAchievement(ACHIEV_THREE_FACED);
int32 entryIndex;
if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
entryIndex = 0;
else
entryIndex = 1;
for (int8 i = 0; outroPositions[i].entry[entryIndex] != 0; ++i)
{
if (Creature *pSummon = m_creature->SummonCreature(outroPositions[i].entry[entryIndex], spawnPoint, TEMPSUMMON_DEAD_DESPAWN))
{
pSummon->GetMotionMaster()->MovePoint(0, outroPositions[i].movePosition);
if (pSummon->GetEntry() == NPC_JAINA_PART2)
DoScriptText(SAY_JAINA_OUTRO, pSummon);
else if (pSummon->GetEntry() == NPC_SYLVANAS_PART2)
DoScriptText(SAY_SYLVANAS_OUTRO, pSummon);
}
}
}
}
void SpellHitTarget(Unit* pTarget, const SpellEntry *pSpell)
{
if (pSpell->Id == SPELL_PHANTOM_BLAST)
bThreeFaceAchievement = false;
}
void UpdateAI(const uint32 diff)
{
// Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_PHANTOM_BLAST:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_PHANTOM_BLAST,H_SPELL_PHANTOM_BLAST));
events.ScheduleEvent(EVENT_PHANTOM_BLAST, 5000);
break;
case EVENT_MIRRORED_SOUL:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
{
uiMirroredSoulTarget = pTarget->GetGUID();
DoCast(pTarget, SPELL_MIRRORED_SOUL);
DoScriptText(EMOTE_MIRRORED_SOUL, m_creature);
}
events.ScheduleEvent(EVENT_MIRRORED_SOUL, urand(15000,30000));
break;
case EVENT_WELL_OF_SOULS:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_WELL_OF_SOULS);
events.ScheduleEvent(EVENT_WELL_OF_SOULS, 20000);
break;
case EVENT_UNLEASHED_SOULS:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_UNLEASHED_SOULS);
m_creature->SetDisplayId(DISPLAY_SORROW);
DoScriptText(RAND(SAY_FACE_ANGER_UNLEASH_SOUL,SAY_FACE_SORROW_UNLEASH_SOUL,SAY_FACE_DESIRE_UNLEASH_SOUL), m_creature);
DoScriptText(EMOTE_UNLEASH_SOUL, m_creature);
events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 30000);
events.ScheduleEvent(EVENT_FACE_ANGER, 5000);
break;
case EVENT_FACE_ANGER:
m_creature->SetDisplayId(DISPLAY_ANGER);
break;
case EVENT_WAILING_SOULS:
m_creature->SetDisplayId(DISPLAY_DESIRE);
DoScriptText(RAND(SAY_FACE_ANGER_WAILING_SOUL,SAY_FACE_DESIRE_WAILING_SOUL), m_creature);
DoScriptText(EMOTE_WAILING_SOUL, m_creature);
DoCast(m_creature, SPELL_WAILING_SOULS_STARTING);
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
m_creature->SetOrientation(m_creature->GetAngle(pTarget));
DoCast(m_creature, SPELL_WAILING_SOULS_BEAM);
}
beamAngle = m_creature->GetOrientation();
beamAngleDiff = PI/30.0f; // PI/2 in 15 sec = PI/30 per tick
if (RAND(true,false))
beamAngleDiff = -beamAngleDiff;
m_creature->InterruptNonMeleeSpells(false);
m_creature->SetReactState(REACT_PASSIVE);
//Remove any target
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
m_creature->GetMotionMaster()->Clear();
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
wailingSoulTick = 15;
events.DelayEvents(18000); // no other events during wailing souls
events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 3000); // first one after 3 secs.
break;
case EVENT_WAILING_SOULS_TICK:
beamAngle += beamAngleDiff;
m_creature->SetOrientation(beamAngle);
m_creature->StopMoving();
DoCast(m_creature, SPELL_WAILING_SOULS);
if (--wailingSoulTick)
events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 1000);
else
{
m_creature->SetReactState(REACT_AGGRESSIVE);
m_creature->SetDisplayId(DISPLAY_ANGER);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000,70000));
}
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_devourer_of_souls(Creature* pCreature)
{
return new boss_devourer_of_soulsAI(pCreature);
}
void AddSC_boss_devourer_of_souls()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_devourer_of_souls";
newscript->GetAI = &GetAI_boss_devourer_of_souls;
newscript->RegisterSelf();
}
@@ -0,0 +1,899 @@
/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptedPch.h"
#include "forge_of_souls.h"
enum Spells
{
//Spiteful Apparition
SPELL_SPITE = 68895,
H_SPELL_SPITE = 70212,
//Spectral Warden
SPELL_VEIL_OF_SHADOWS = 69633,
SPELL_WAIL_OF_SOULS = 69148,
H_SPELL_WAIL_OF_SOULS = 70210,
//Soulguard Watchman
SPELL_SHROUD_OF_RUNES = 69056,
SPELL_UNHOLY_RAGE = 69053,
//Soulguard Reaper
SPELL_FROST_NOVA = 69060,
H_SPELL_FROST_NOVA = 70209,
SPELL_SHADOW_LANCE = 69058,
//Soulguard Bonecaster
SPELL_BONE_VOLLEY = 69080,
H_SPELL_BONE_VOLLEY = 70206,
SPELL_RAISE_DEAD = 69562,
SPELL_SHIELD_OF_BONES = 69069,
H_SPELL_SHIELD_OF_BONES = 70207,
//Soulguard Animator
// Raise dead 69562
SPELL_SHADOW_BOLT = 69068,
H_SPELL_SHADOW_BOLT = 70208,
SPELL_SOUL_SICKNESS = 69131,
SPELL_SOUL_SIPHON = 69128,
//Soulguard Adept
//Raise dead 69562
//Shadow Bolt 69068/70208
SPELL_DRAIN_LIFE = 69066,
H_SPELL_DRAIN_LIFE = 70213,
SPELL_SHADOW_MEND = 69564,
H_SPELL_SHADOW_MEND = 70205,
//Soul Horror
SPELL_SOUL_STRIKE = 69088,
H_SPELL_SOUL_STRIKE = 70211,
};
enum Events
{
EVENT_NONE,
// Jaina/Sylvanas Intro
EVENT_INTRO_1,
EVENT_INTRO_2,
EVENT_INTRO_3,
EVENT_INTRO_4,
EVENT_INTRO_5,
EVENT_INTRO_6,
EVENT_INTRO_7,
EVENT_INTRO_8,
//Spiteful Apparition
EVENT_SPITE,
//Spectral Warden
EVENT_VEIL_OF_SHADOWS,
EVENT_WAIL_OF_SOULS,
//Soulguard Watchman
EVENT_SHROUD_OF_RUNES,
EVENT_UNHOLY_RAGE,
//Soulguard Reaper
EVENT_FROST_NOVA,
EVENT_SHADOW_LANCE,
//Soulguard Bonecaster
EVENT_BONE_VOLLEY,
EVENT_RAISE_DEAD,
EVENT_SHIELD_OF_BONES,
//Soulguard Animator
EVENT_SHADOW_BOLT,
EVENT_SOUL_SICKNESS,
EVENT_SOUL_SIPHON,
//Soulguard Adept
EVENT_DRAIN_LIFE,
EVENT_SHADOW_MEND,
//Soul Horror
EVENT_SOUL_STRIKE,
};
/****************************************SYLVANAS************************************/
#define GOSSIP_SYLVANAS_ITEM "What would you have of me, Banshee Queen?"
#define GOSSIP_JAINA_ITEM "What would you have of me, my lady?"
enum Yells
{
SAY_JAINA_INTRO_1 = -1632040,
SAY_JAINA_INTRO_2 = -1632041,
SAY_JAINA_INTRO_3 = -1632042,
SAY_JAINA_INTRO_4 = -1632043,
SAY_JAINA_INTRO_5 = -1632044,
SAY_JAINA_INTRO_6 = -1632045,
SAY_JAINA_INTRO_7 = -1632046,
SAY_JAINA_INTRO_8 = -1632047,
SAY_SYLVANAS_INTRO_1 = -1632050,
SAY_SYLVANAS_INTRO_2 = -1632051,
SAY_SYLVANAS_INTRO_3 = -1632052,
SAY_SYLVANAS_INTRO_4 = -1632053,
SAY_SYLVANAS_INTRO_5 = -1632054,
SAY_SYLVANAS_INTRO_6 = -1632055,
};
enum eSylvanas
{
GOSSIP_SPEECHINTRO = 13525,
ACTION_INTRO,
};
enum Phase
{
PHASE_NORMAL,
PHASE_INTRO,
};
struct npc_sylvanas_fosAI: public ScriptedAI
{
npc_sylvanas_fosAI(Creature *c) : ScriptedAI(c)
{
pInstance = m_creature->GetInstanceData();
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
ScriptedInstance* pInstance;
EventMap events;
Phase phase;
void Reset()
{
events.Reset();
phase = PHASE_NORMAL;
}
void DoAction(const int32 actionId)
{
switch(actionId)
{
case ACTION_INTRO:
{
phase = PHASE_INTRO;
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
events.Reset();
events.ScheduleEvent(EVENT_INTRO_1, 1000);
}
}
}
void UpdateAI(const uint32 diff)
{
if (phase == PHASE_INTRO)
{
if (!pInstance)
return;
events.Update(diff);
switch(events.ExecuteEvent())
{
case EVENT_INTRO_1:
DoScriptText(SAY_SYLVANAS_INTRO_1, m_creature);
events.ScheduleEvent(EVENT_INTRO_2, 11500);
break;
case EVENT_INTRO_2:
DoScriptText(SAY_SYLVANAS_INTRO_2, m_creature);
events.ScheduleEvent(EVENT_INTRO_3, 10500);
break;
case EVENT_INTRO_3:
DoScriptText(SAY_SYLVANAS_INTRO_3, m_creature);
events.ScheduleEvent(EVENT_INTRO_4, 9500);
break;
case EVENT_INTRO_4:
DoScriptText(SAY_SYLVANAS_INTRO_4, m_creature);
events.ScheduleEvent(EVENT_INTRO_5, 10500);
break;
case EVENT_INTRO_5:
DoScriptText(SAY_SYLVANAS_INTRO_5, m_creature);
events.ScheduleEvent(EVENT_INTRO_6, 9500);
break;
case EVENT_INTRO_6:
DoScriptText(SAY_SYLVANAS_INTRO_6, m_creature);
// End of Intro
phase = PHASE_NORMAL;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
//if (m_creature->hasUnitState(UNIT_STAT_CASTING))
// return;
//while(uint32 eventId = events.ExecuteEvent())
//{
// switch(eventId)
// {
// }
//}
DoMeleeAttackIfReady();
}
};
struct npc_jaina_fosAI: public ScriptedAI
{
npc_jaina_fosAI(Creature *c) : ScriptedAI(c)
{
pInstance = m_creature->GetInstanceData();
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
ScriptedInstance* pInstance;
EventMap events;
Phase phase;
void Reset()
{
events.Reset();
phase = PHASE_NORMAL;
}
void DoAction(const int32 actionId)
{
switch(actionId)
{
case ACTION_INTRO:
{
phase = PHASE_INTRO;
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
events.Reset();
events.ScheduleEvent(EVENT_INTRO_1, 1000);
}
}
}
void UpdateAI(const uint32 diff)
{
if (phase == PHASE_INTRO)
{
if (!pInstance)
return;
events.Update(diff);
switch(events.ExecuteEvent())
{
case EVENT_INTRO_1:
DoScriptText(SAY_JAINA_INTRO_1, m_creature);
events.ScheduleEvent(EVENT_INTRO_2, 8000);
break;
case EVENT_INTRO_2:
DoScriptText(SAY_JAINA_INTRO_2, m_creature);
events.ScheduleEvent(EVENT_INTRO_3, 8500);
break;
case EVENT_INTRO_3:
DoScriptText(SAY_JAINA_INTRO_3, m_creature);
events.ScheduleEvent(EVENT_INTRO_4, 8000);
break;
case EVENT_INTRO_4:
DoScriptText(SAY_JAINA_INTRO_4, m_creature);
events.ScheduleEvent(EVENT_INTRO_5, 10000);
break;
case EVENT_INTRO_5:
DoScriptText(SAY_JAINA_INTRO_5, m_creature);
events.ScheduleEvent(EVENT_INTRO_6, 8000);
break;
case EVENT_INTRO_6:
DoScriptText(SAY_JAINA_INTRO_6, m_creature);
events.ScheduleEvent(EVENT_INTRO_7, 12000);
break;
case EVENT_INTRO_7:
DoScriptText(SAY_JAINA_INTRO_7, m_creature);
events.ScheduleEvent(EVENT_INTRO_8, 8000);
break;
case EVENT_INTRO_8:
DoScriptText(SAY_JAINA_INTRO_8, m_creature);
// End of Intro
phase = PHASE_NORMAL;
break;
}
}
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
//if (m_creature->hasUnitState(UNIT_STAT_CASTING))
// return;
//while(uint32 eventId = events.ExecuteEvent())
//{
// switch(eventId)
// {
// }
//}
DoMeleeAttackIfReady();
}
};
bool GossipHello_npc_jaina_or_slyvanas_fos(Player* pPlayer, Creature* pCreature)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pCreature->GetEntry() == NPC_JAINA_PART1)
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_JAINA_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
else
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SYLVANAS_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
return true;
}
bool GossipSelect_npc_jaina_or_slyvanas_fos(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
switch(uiAction)
{
case GOSSIP_ACTION_INFO_DEF+1:
pPlayer->CLOSE_GOSSIP_MENU();
if (pCreature->AI())
pCreature->AI()->DoAction(ACTION_INTRO);
break;
}
return true;
}
struct mob_spiteful_apparitionAI: public ScriptedAI
{
mob_spiteful_apparitionAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_SPITE, 8000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SPITE:
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_SPITE,H_SPELL_SPITE));
events.RescheduleEvent(EVENT_SPITE, 8000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_spectral_wardenAI: public ScriptedAI
{
mob_spectral_wardenAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_VEIL_OF_SHADOWS, 5000);
events.ScheduleEvent(EVENT_WAIL_OF_SOULS, 10000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_VEIL_OF_SHADOWS:
DoCast(m_creature->getVictim(), SPELL_VEIL_OF_SHADOWS);
events.RescheduleEvent(EVENT_VEIL_OF_SHADOWS, 10000);
return;
case EVENT_WAIL_OF_SOULS:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_WAIL_OF_SOULS,H_SPELL_WAIL_OF_SOULS));
events.RescheduleEvent(EVENT_WAIL_OF_SOULS, 5000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soulguard_watchmanAI: public ScriptedAI
{
mob_soulguard_watchmanAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_SHROUD_OF_RUNES, 1000);
events.ScheduleEvent(EVENT_UNHOLY_RAGE, 1000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SHROUD_OF_RUNES:
DoCast(m_creature, SPELL_SHROUD_OF_RUNES);
events.RescheduleEvent(EVENT_SHROUD_OF_RUNES, 5000);
return;
case EVENT_UNHOLY_RAGE:
DoCast(m_creature, SPELL_UNHOLY_RAGE);
events.RescheduleEvent(EVENT_UNHOLY_RAGE, 99999);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soulguard_reaperAI: public ScriptedAI
{
mob_soulguard_reaperAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_FROST_NOVA, 8000);
events.ScheduleEvent(EVENT_SHADOW_LANCE, 5000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_FROST_NOVA:
DoCast(m_creature, DUNGEON_MODE(SPELL_FROST_NOVA,H_SPELL_FROST_NOVA));
events.RescheduleEvent(EVENT_FROST_NOVA, 9600);
return;
case EVENT_SHADOW_LANCE:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_SHADOW_LANCE);
events.RescheduleEvent(EVENT_SHADOW_LANCE, 8000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soulguard_bonecasterAI: public ScriptedAI
{
mob_soulguard_bonecasterAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_BONE_VOLLEY, 6000);
events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
events.ScheduleEvent(EVENT_SHIELD_OF_BONES, 6000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_BONE_VOLLEY:
DoCastAOE(DUNGEON_MODE(SPELL_BONE_VOLLEY,H_SPELL_BONE_VOLLEY));
events.RescheduleEvent(EVENT_BONE_VOLLEY, 7000);
return;
case EVENT_RAISE_DEAD:
DoCast(m_creature, SPELL_RAISE_DEAD);
events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
return;
case EVENT_SHIELD_OF_BONES:
DoCast(m_creature, DUNGEON_MODE(SPELL_SHIELD_OF_BONES,H_SPELL_SHIELD_OF_BONES));
events.RescheduleEvent(EVENT_SHIELD_OF_BONES, 8000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soulguard_animatorAI: public ScriptedAI
{
mob_soulguard_animatorAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 5000);
events.ScheduleEvent(EVENT_SOUL_SICKNESS, 8000);
events.ScheduleEvent(EVENT_SOUL_SIPHON, 10000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_RAISE_DEAD:
DoCast(m_creature, SPELL_RAISE_DEAD);
events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
return;
case EVENT_SHADOW_BOLT:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_SHADOW_BOLT,H_SPELL_SHADOW_BOLT));
events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000);
return;
case EVENT_SOUL_SICKNESS:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_SOUL_SICKNESS);
events.RescheduleEvent(EVENT_SOUL_SICKNESS, 10000);
return;
case EVENT_SOUL_SIPHON:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_SOUL_SIPHON);
events.RescheduleEvent(EVENT_SOUL_SIPHON, 8000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soulguard_adeptAI: public ScriptedAI
{
mob_soulguard_adeptAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 8000);
events.ScheduleEvent(EVENT_DRAIN_LIFE, 7000);
events.ScheduleEvent(EVENT_SHADOW_MEND, 35000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_RAISE_DEAD:
DoCast(m_creature, SPELL_RAISE_DEAD);
events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
return;
case EVENT_SHADOW_BOLT:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_SHADOW_BOLT,H_SPELL_SHADOW_BOLT));
events.RescheduleEvent(EVENT_SHADOW_BOLT, 4000);
return;
case EVENT_DRAIN_LIFE:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_DRAIN_LIFE,H_SPELL_DRAIN_LIFE));
events.RescheduleEvent(EVENT_DRAIN_LIFE, 9000);
return;
case EVENT_SHADOW_MEND:
DoCast(m_creature, DUNGEON_MODE(SPELL_SHADOW_MEND,H_SPELL_SHADOW_MEND));
events.RescheduleEvent(EVENT_SHADOW_MEND, 20000);
return;
}
}
DoMeleeAttackIfReady();
}
};
struct mob_soul_horrorAI: public ScriptedAI
{
mob_soul_horrorAI(Creature *c) : ScriptedAI(c)
{
}
EventMap events;
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* who)
{
events.ScheduleEvent(EVENT_SOUL_STRIKE, 6000);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SOUL_STRIKE:
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_SOUL_STRIKE,H_SPELL_SOUL_STRIKE));
events.RescheduleEvent(EVENT_SOUL_STRIKE, 8000);
return;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_jaina_fosAI(Creature* pCreature)
{
return new npc_jaina_fosAI(pCreature);
};
CreatureAI* GetAI_npc_sylvanas_fosAI(Creature* pCreature)
{
return new npc_sylvanas_fosAI(pCreature);
};
CreatureAI* GetAI_mob_spiteful_apparitionAI(Creature* pCreature)
{
return new mob_spiteful_apparitionAI(pCreature);
}
CreatureAI* GetAI_mob_spectral_wardenAI(Creature* pCreature)
{
return new mob_spectral_wardenAI(pCreature);
}
CreatureAI* GetAI_mob_soulguard_watchmanAI(Creature* pCreature)
{
return new mob_soulguard_watchmanAI(pCreature);
}
CreatureAI* GetAI_mob_soulguard_reaperAI(Creature* pCreature)
{
return new mob_soulguard_reaperAI(pCreature);
}
CreatureAI* GetAI_mob_soulguard_bonecasterAI(Creature* pCreature)
{
return new mob_soulguard_bonecasterAI(pCreature);
}
CreatureAI* GetAI_mob_soulguard_animatorAI(Creature* pCreature)
{
return new mob_soulguard_animatorAI(pCreature);
}
CreatureAI* GetAI_mob_soulguard_adeptAI(Creature* pCreature)
{
return new mob_soulguard_adeptAI(pCreature);
}
CreatureAI* GetAI_mob_soul_horrorAI(Creature* pCreature)
{
return new mob_soul_horrorAI(pCreature);
}
void AddSC_forge_of_souls()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_sylvanas_fos";
newscript->GetAI = &GetAI_npc_sylvanas_fosAI;
newscript->pGossipHello = &GossipHello_npc_jaina_or_slyvanas_fos;
newscript->pGossipSelect = &GossipSelect_npc_jaina_or_slyvanas_fos;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_jaina_fos";
newscript->GetAI = &GetAI_npc_jaina_fosAI;
newscript->pGossipHello = &GossipHello_npc_jaina_or_slyvanas_fos;
newscript->pGossipSelect = &GossipSelect_npc_jaina_or_slyvanas_fos;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_spiteful_apparition";
newscript->GetAI = &GetAI_mob_spiteful_apparitionAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_spectral_warden";
newscript->GetAI = &GetAI_mob_spectral_wardenAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soulguard_watchman";
newscript->GetAI = &GetAI_mob_soulguard_watchmanAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soulguard_reaper";
newscript->GetAI = &GetAI_mob_soulguard_reaperAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soulguard_bonecaster";
newscript->GetAI = &GetAI_mob_soulguard_bonecasterAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soulguard_animator";
newscript->GetAI = &GetAI_mob_soulguard_animatorAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soulguard_adept";
newscript->GetAI = &GetAI_mob_soulguard_adeptAI;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_soul_horror";
newscript->GetAI = &GetAI_mob_soul_horrorAI;
newscript->RegisterSelf();
}
@@ -16,18 +16,37 @@
#ifndef DEF_FORGE_OF_SOULS_H
#define DEF_FORGE_OF_SOULS_H
enum Data
{
DATA_BRONJAHM_EVENT,
DATA_DEVOURER_EVENT
DATA_DEVOURER_EVENT,
DATA_TEAM_IN_INSTANCE,
};
enum Data64
{
DATA_BRONJAHM
DATA_BRONJAHM,
DATA_DEVOURER,
};
enum Creatures
{
CREATURE_BRONJAHM = 36497,
CREATURE_DEVOURER = 36502
CREATURE_DEVOURER = 36502,
NPC_SYLVANAS_PART1 = 37596,
NPC_SYLVANAS_PART2 = 38161,
NPC_JAINA_PART1 = 37597,
NPC_JAINA_PART2 = 38160,
NPC_KALIRA = 37583,
NPC_ELANDRA = 37774,
NPC_LORALEN = 37779,
NPC_KORELN = 37582,
NPC_CHAMPION_1_HORDE = 37584,
NPC_CHAMPION_2_HORDE = 37587,
NPC_CHAMPION_3_HORDE = 37588,
NPC_CHAMPION_1_ALLIANCE = 37496,
NPC_CHAMPION_2_ALLIANCE = 37497,
};
#endif
@@ -26,24 +26,41 @@
struct instance_forge_of_souls : public ScriptedInstance
{
instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap) {};
uint64 uiBronjahm;
uint64 uiDevourer;
uint32 m_auiEncounter[MAX_ENCOUNTER];
uint32 uiEncounter[MAX_ENCOUNTER];
uint32 uiTeamInInstance;
void Initialize()
{
uiBronjahm = 0;
uiDevourer = 0;
uiTeamInInstance = 0;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
m_auiEncounter[i] = NOT_STARTED;
uiEncounter[i] = NOT_STARTED;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (uiEncounter[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
Map::PlayerList const &players = instance->GetPlayers();
if (!players.isEmpty())
if (Player* pPlayer = players.begin()->getSource())
uiTeamInInstance = pPlayer->GetTeam();
switch(pCreature->GetEntry())
{
case CREATURE_BRONJAHM:
@@ -54,23 +71,16 @@ struct instance_forge_of_souls : public ScriptedInstance
break;
}
}
/*
void OnGameObjectCreate(GameObject* pGo, bool add)
{
switch(pGo->GetEntry())
{
}
}
*/
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_BRONJAHM_EVENT:
m_auiEncounter[0] = data;
uiEncounter[0] = data;
break;
case DATA_DEVOURER_EVENT:
m_auiEncounter[1] = data;
uiEncounter[1] = data;
break;
}
@@ -82,8 +92,9 @@ struct instance_forge_of_souls : public ScriptedInstance
{
switch(type)
{
case DATA_BRONJAHM_EVENT: return m_auiEncounter[0];
case DATA_DEVOURER_EVENT: return m_auiEncounter[1];
case DATA_BRONJAHM_EVENT: return uiEncounter[0];
case DATA_DEVOURER_EVENT: return uiEncounter[1];
case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
}
return 0;
@@ -94,6 +105,7 @@ struct instance_forge_of_souls : public ScriptedInstance
switch(identifier)
{
case DATA_BRONJAHM: return uiBronjahm;
case DATA_DEVOURER: return uiBronjahm;
}
return 0;
@@ -104,7 +116,7 @@ struct instance_forge_of_souls : public ScriptedInstance
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "F S " << m_auiEncounter[0] << " " << m_auiEncounter[1];
saveStream << "F S " << uiEncounter[0] << " " << uiEncounter[1];
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
@@ -128,12 +140,12 @@ struct instance_forge_of_souls : public ScriptedInstance
if (dataHead1 == 'F' && dataHead2 == 'S')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
uiEncounter[0] = data0;
uiEncounter[1] = data1;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
if (uiEncounter[i] == IN_PROGRESS)
uiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
@@ -146,7 +158,7 @@ InstanceData* GetInstanceData_instance_forge_of_souls(Map* pMap)
return new instance_forge_of_souls(pMap);
}
void AddSC_forge_of_souls()
void AddSC_instance_forge_of_souls()
{
Script *newscript;
newscript = new Script;