Scripts/Oculus: cleanup a bit

This commit is contained in:
joschiwald
2013-11-24 21:17:45 +01:00
parent d4d4eb3123
commit 2c307aa67c
9 changed files with 1441 additions and 1344 deletions
@@ -0,0 +1,168 @@
UPDATE `gameobject_template` SET `flags`=16 WHERE `entry` IN (191349, 193603);
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` AND `SourceGroup` IN (27692,27755,27756);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(21,27692,50344,0,0,13,1,2,3,2,0,0,0,'','Vehicle Spell requires Boss Urom must be done'),
(21,27755,49592,0,0,13,1,2,3,2,0,0,0,'','Vehicle Spell requires Boss Urom must be done'),
(21,27756,50253,0,0,13,1,2,3,2,0,0,0,'','Vehicle Spell requires Boss Urom must be done');
UPDATE `creature_template` SET `npcflag`=0 WHERE `entry` IN (27657,27659);
UPDATE `creature_template` SET `gossip_menu_id`=9573 WHERE `entry`=27657;
UPDATE `creature_template` SET `gossip_menu_id`=9708 WHERE `entry`=27658;
UPDATE `creature_template` SET `gossip_menu_id`=9574 WHERE `entry`=27659;
DELETE FROM `npc_text` WHERE `ID`=13467;
INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `lang0`, `prob0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `lang1`, `prob1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `lang2`, `prob2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `lang3`, `prob3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `lang4`, `prob4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `lang5`, `prob5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `lang6`, `prob6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `lang7`, `prob7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `WDBVerified`) VALUES
(13467, 'The trickster Mage-Lord Urom protects the third ring. He will appear alone and defenseless, but do not be fooled by appearances! Urom is a powerful conjurer who commands a menagerie of Phantasmal creatures. Seek him out above.', 'The trickster Mage-Lord Urom protects the third ring. He will appear alone and defenseless, but do not be fooled by appearances! Urom is a powerful conjurer who commands a menagerie of Phantasmal creatures. Seek him out above.', 0, 1, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 14545);
DELETE FROM `gossip_menu` WHERE `entry` IN (9573,9703,9704,9787,9575,9699,9700,9708,9574,9701,9702,9786);
INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES
-- Verdisa
(9573, 12915), -- 27657 -- init -- urom not done
(9573, 13241), -- 27657 -- eregos done
(9573, 13269), -- 27657 -- eregos not done
(9703, 13258), -- 27657 -- attacks
(9704, 13259), -- 27657 -- special
(9787, 13466), -- 27657 -- varos not done
(9787, 13467), -- 27657 -- urom not done
(9787, 13468), -- 27657 -- eregos not done
-- Belgaristrasz
(9575, 12916), -- 27658 -- varos not done
(9575, 13237), -- 27658 -- urom not done
(9575, 13238), -- 27658 -- eregos not done
(9575, 13239), -- 27658 -- eregos done
(9699, 13254), -- 27658 -- attacks
(9700, 13255), -- 27658 -- special
(9708, 13267), -- 27658 -- init
-- Eternos
(9574, 12917), -- 27659 -- init -- urom not done
(9574, 13240), -- 27659 -- eregos done
(9574, 13268), -- 27659 -- eregos not done
(9701, 13256), -- 27659 -- attacks
(9702, 13257), -- 27659 -- special
(9786, 13466), -- 27659 -- varos not done
(9786, 13467), -- 27659 -- urom not done
(9786, 13468); -- 27659 -- eregos not done
DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (9708,9574,9573,9575);
INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`) VALUES
-- Verdisa
(9573, 0, 0, 'What should we do next?', 1, 1, 9787, 0, 0, 0, ''), -- 27657 -- eregos not done
(9573, 1, 0, 'I want to fly on the wings of the green flight.', 1, 1, 0, 0, 0, 0, ''), -- 27657 -- no essence
(9573, 2, 0, 'I want to exchange my Amber Essence for Emerald Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27657 -- has amber essence
(9573, 3, 0, 'I want to exchange my Ruby Essence for Emerald Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27657 -- has ruby essence
(9573, 4, 0, 'What abilities do emerald drakes have?', 1, 1, 9703, 0, 0, 0, ''), -- 27657
(9573, 5, 0, 'What is the ultimate ability of the emerald drake?', 1, 1, 9704, 0, 0, 0, ''), -- 27657 -- urom must be done
-- Eternos
(9574, 0, 0, 'What should we do next?', 1, 1, 9786, 0, 0, 0, ''), -- 27659 -- eregos not done
(9574, 1, 0, 'I want to fly on the wings of the bronze flight.', 1, 1, 0, 0, 0, 0, ''), -- 27659 -- no essence
(9574, 2, 0, 'I want to exchange my Emerald Essence for Amber Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27659 -- has emerald essence
(9574, 3, 0, 'I want to exchange my Ruby Essence for Amber Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27659 -- has ruby essence
(9574, 4, 0, 'What abilities do amber drakes have?', 1, 1, 9701, 0, 0, 0, ''), -- 27659
(9574, 5, 0, 'What is the ultimate ability of the amber drake?', 1, 1, 9702, 0, 0, 0, ''), -- 27659 -- urom must be done
-- Belgaristrasz
(9708, 0, 0, 'So where do we go from here?', 1, 1, 9575, 0, 0, 0, ''), -- 27658
(9575, 0, 0, 'I want to fly on the wings of the red flight.', 1, 1, 0, 0, 0, 0, ''), -- 27658 -- no essence
(9575, 1, 0, 'I want to exchange my Amber Essence for Ruby Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27658 -- has amber essence
(9575, 2, 0, 'I want to exchange my Emerald Essence for Ruby Essence.', 1, 1, 0, 0, 0, 0, ''), -- 27658 -- has emerald essence
(9575, 3, 0, 'What abilities do ruby drakes have?', 1, 1, 9699, 0, 0, 0, ''), -- 27658
(9575, 4, 0, 'What is the ultimate ability of the Ruby Drake?', 1, 1, 9700, 0, 0, 0, ''); -- 27658 -- urom must be done
/*
DATA_DRAKOS = 0,
DATA_VAROS = 1,
DATA_UROM = 2,
DATA_EREGOS = 3,
DONE = 3,
ITEM_EMERALD_ESSENCE = 37815,
ITEM_AMBER_ESSENCE = 37859,
ITEM_RUBY_ESSENCE = 37860,
*/
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup` IN (9573,9787,9575,9574,9786);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(14,9573,12915,0,0,13,1,2,3,2,1,0,0,'','Show text only if Boss Urom not done'), -- urom not done
(14,9573,13241,0,0,13,1,3,3,2,0,0,0,'','Show text only if Boss Eregos done'), -- eregos done
(14,9573,13269,0,0,13,1,2,3,2,0,0,0,'','Show text only if Boss Urom done'), -- urom done
(14,9573,13269,0,0,13,1,3,3,2,1,0,0,'','Show text only if Boss Eregos not done'), -- eregos not done
(14,9787,13466,0,0,13,1,1,3,2,1,0,0,'','Show text only if Boss Varos not done'), -- varos not done
(14,9787,13467,0,0,13,1,1,3,2,0,0,0,'','Show text only if Boss Varos done'), -- varos done
(14,9787,13467,0,0,13,1,2,3,2,1,0,0,'','Show text only if Boss Urom not done'), -- urom not done
(14,9787,13468,0,0,13,1,2,3,2,0,0,0,'','Show text only if Boss Urom done'), -- urom done
(14,9787,13468,0,0,13,1,3,3,2,1,0,0,'','Show text only if Boss Eregos not done'), -- eregos not done
(14,9575,12916,0,0,13,1,1,3,2,1,0,0,'','Show text only if Boss Varos not done'), -- varos not done
(14,9575,13237,0,0,13,1,1,3,2,0,0,0,'','Show text only if Boss Varos done'), -- varos done
(14,9575,13237,0,0,13,1,2,3,2,1,0,0,'','Show text only if Boss Urom not done'), -- urom not done
(14,9575,13238,0,0,13,1,2,3,2,0,0,0,'','Show text only if Boss Urom done'), -- urom done
(14,9575,13238,0,0,13,1,3,3,2,1,0,0,'','Show text only if Boss Eregos not done'), -- eregos not done
(14,9575,13239,0,0,13,1,3,3,2,0,0,0,'','Show text only if Boss Eregos done'), -- eregos done
(14,9574,12917,0,0,13,1,2,3,2,1,0,0,'','Show text only if Boss Urom not done'), -- urom not done
(14,9574,13240,0,0,13,1,3,3,2,0,0,0,'','Show text only if Boss Eregos done'), -- eregos done
(14,9574,13268,0,0,13,1,2,3,2,0,0,0,'','Show text only if Boss Urom done'), -- urom done
(14,9574,13268,0,0,13,1,3,3,2,1,0,0,'','Show text only if Boss Eregos not done'), -- eregos not done
(14,9786,13466,0,0,13,1,1,3,2,1,0,0,'','Show text only if Boss Varos not done'), -- varos not done
(14,9786,13467,0,0,13,1,1,3,2,0,0,0,'','Show text only if Boss Varos done'), -- varos done
(14,9786,13467,0,0,13,1,2,3,2,1,0,0,'','Show text only if Boss Urom not done'), -- urom not done
(14,9786,13468,0,0,13,1,2,3,2,0,0,0,'','Show text only if Boss Urom done'), -- urom done
(14,9786,13468,0,0,13,1,3,3,2,1,0,0,'','Show text only if Boss Eregos not done'); -- eregos not done
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (9573,9574,9575);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(15,9573,0,0,0,13,1,3,3,2,1,0,0,'','Show options for gossip only if Boss Eregos not done'), -- eregos not done
(15,9573,1,0,0,2,0,37859,1,0,1,0,0,'','Show options for gossip only if Player has no amber essence'), -- has no amber essence
(15,9573,1,0,0,2,0,37815,1,0,1,0,0,'','Show options for gossip only if Player has no emerald essence'), -- has no emerald essence
(15,9573,1,0,0,2,0,37860,1,0,1,0,0,'','Show options for gossip only if Player has no ruby essence'), -- has no ruby essence
(15,9573,2,0,0,2,0,37859,1,0,0,0,0,'','Show options for gossip only if Player has amber essence'), -- has amber essence
(15,9573,3,0,0,2,0,37860,1,0,0,0,0,'','Show options for gossip only if Player has ruby essence'), -- has ruby essence
(15,9573,5,0,0,13,1,2,3,2,0,0,0,'','Show options for gossip only if Boss Urom done'), -- urom done
(15,9574,0,0,0,13,1,3,3,2,1,0,0,'','Show options for gossip only if Boss Eregos not done'), -- eregos not done
(15,9574,1,0,0,2,0,37859,1,0,1,0,0,'','Show options for gossip only if Player has no amber essence'), -- has no amber essence
(15,9574,1,0,0,2,0,37815,1,0,1,0,0,'','Show options for gossip only if Player has no emerald essence'), -- has no emerald essence
(15,9574,1,0,0,2,0,37860,1,0,1,0,0,'','Show options for gossip only if Player has no ruby essence'), -- has no ruby essence
(15,9574,2,0,0,2,0,37815,1,0,0,0,0,'','Show options for gossip only if Player has emerald essence'), -- has emerald essence
(15,9574,3,0,0,2,0,37860,1,0,0,0,0,'','Show options for gossip only if Player has ruby essence'), -- has ruby essence
(15,9574,5,0,0,13,1,2,3,2,0,0,0,'','Show options for gossip only if Boss Urom done'), -- urom done
(15,9575,0,0,0,2,0,37859,1,0,1,0,0,'','Show options for gossip only if Player has no amber essence'), -- has no amber essence
(15,9575,0,0,0,2,0,37815,1,0,1,0,0,'','Show options for gossip only if Player has no emerald essence'), -- has no emerald essence
(15,9575,0,0,0,2,0,37860,1,0,1,0,0,'','Show options for gossip only if Player has no ruby essence'), -- has no ruby essence
(15,9575,1,0,0,2,0,37859,1,0,0,0,0,'','Show options for gossip only if Player has amber essence'), -- has amber essence
(15,9575,2,0,0,2,0,37815,1,0,0,0,0,'','Show options for gossip only if Player has emerald essence'), -- has emerald essence
(15,9575,4,0,0,13,1,2,3,2,0,0,0,'','Show options for gossip only if Boss Urom done'); -- urom done
DELETE FROM `spell_script_names` WHERE `spell_id` IN (49345,49461,49462,49427,49459,49463,49838);
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(49345, 'spell_oculus_call_ruby_emerald_amber_drake'),
(49461, 'spell_oculus_call_ruby_emerald_amber_drake'),
(49462, 'spell_oculus_call_ruby_emerald_amber_drake'),
(49427, 'spell_oculus_ride_ruby_emerald_amber_drake_que'),
(49459, 'spell_oculus_ride_ruby_emerald_amber_drake_que'),
(49463, 'spell_oculus_ride_ruby_emerald_amber_drake_que'),
(49838, 'spell_oculus_stop_time');
-- Remove invalid ScriptNames from DB
UPDATE `conditions` SET `ScriptName`='' WHERE `ScriptName`='0';
@@ -9629,6 +9629,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
data << uint32(3932) << uint32(0); // 13 WORLDSTATE_TIME_GUARDIAN_SHOW
}
break;
// The Oculus
case 4228:
if (instance && mapid == 578)
instance->FillInitialWorldStates(data);
else
{
data << uint32(3524) << uint32(0); // 9 WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW
data << uint32(3486) << uint32(0); // 10 WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT
}
break;
// Ulduar
case 4273:
if (instance && mapid == 603)
@@ -52,141 +52,141 @@ enum DrakosEvents
class boss_drakos : public CreatureScript
{
public:
boss_drakos() : CreatureScript("boss_drakos") { }
public:
boss_drakos() : CreatureScript("boss_drakos") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_drakosAI(creature);
}
struct boss_drakosAI : public BossAI
{
boss_drakosAI(Creature* creature) : BossAI(creature, DATA_DRAKOS_EVENT) { }
void Reset() OVERRIDE
struct boss_drakosAI : public BossAI
{
_Reset();
boss_drakosAI(Creature* creature) : BossAI(creature, DATA_DRAKOS) { }
events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
events.ScheduleEvent(EVENT_STOMP, 17000);
events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
postPull = false;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
}
void UpdateAI(uint32 diff) OVERRIDE
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
void Reset() OVERRIDE
{
switch (eventId)
{
case EVENT_BOMB_SUMMON:
{
Position pPosition;
me->GetPosition(&pPosition);
_Reset();
for (uint8 i = 0; i <= (postPull ? 3 : 0); i++)
{
me->GetRandomNearPosition(pPosition, float(urand(0, 10)));
me->SummonCreature(NPC_UNSTABLE_SPHERE, pPosition);
}
}
events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
break;
case EVENT_MAGIC_PULL:
DoCast(SPELL_MAGIC_PULL);
postPull = true;
events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
break;
case EVENT_STOMP:
Talk(SAY_STOMP);
DoCast(SPELL_THUNDERING_STOMP);
events.ScheduleEvent(EVENT_STOMP, 17000);
break;
}
events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
events.ScheduleEvent(EVENT_STOMP, 17000);
events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
postPull = false;
}
DoMeleeAttackIfReady();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
}
void JustDied(Unit* /*killer*/) OVERRIDE
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_BOMB_SUMMON:
{
Position position;
me->GetPosition(&position);
for (uint8 i = 0; i <= (postPull ? 3 : 0); i++)
{
me->GetRandomNearPosition(position, frand(0.0f, 10.0f));
me->SummonCreature(NPC_UNSTABLE_SPHERE, position);
}
}
events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
break;
case EVENT_MAGIC_PULL:
DoCast(SPELL_MAGIC_PULL);
postPull = true;
events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
break;
case EVENT_STOMP:
Talk(SAY_STOMP);
DoCast(SPELL_THUNDERING_STOMP);
events.ScheduleEvent(EVENT_STOMP, 17000);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
// start achievement timer (kill Eregos within 20 min)
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(SAY_KILL);
}
private:
bool postPull;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
// start achievement timer (kill Eregos within 20 min)
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
return GetOculusAI<boss_drakosAI>(creature);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(SAY_KILL);
}
private:
bool postPull;
};
};
class npc_unstable_sphere : public CreatureScript
{
public:
npc_unstable_sphere() : CreatureScript("npc_unstable_sphere") { }
public:
npc_unstable_sphere() : CreatureScript("npc_unstable_sphere") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_unstable_sphereAI(creature);
}
struct npc_unstable_sphereAI : public ScriptedAI
{
npc_unstable_sphereAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() OVERRIDE
struct npc_unstable_sphereAI : public ScriptedAI
{
me->SetReactState(REACT_PASSIVE);
me->GetMotionMaster()->MoveRandom(40.0f);
npc_unstable_sphereAI(Creature* creature) : ScriptedAI(creature) { }
me->AddAura(SPELL_UNSTABLE_SPHERE_PASSIVE, me);
me->AddAura(SPELL_UNSTABLE_SPHERE_TIMER, me);
pulseTimer = 3000;
deathTimer = 19000;
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (pulseTimer <= diff)
void Reset() OVERRIDE
{
DoCast(SPELL_UNSTABLE_SPHERE_PULSE);
pulseTimer = 3*IN_MILLISECONDS;
} else pulseTimer -= diff;
me->SetReactState(REACT_PASSIVE);
me->GetMotionMaster()->MoveRandom(40.0f);
if (deathTimer <= diff)
me->DisappearAndDie();
else deathTimer -= diff;
me->AddAura(SPELL_UNSTABLE_SPHERE_PASSIVE, me);
me->AddAura(SPELL_UNSTABLE_SPHERE_TIMER, me);
pulseTimer = 3000;
me->DespawnOrUnsummon(19000);
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (pulseTimer <= diff)
{
DoCast(SPELL_UNSTABLE_SPHERE_PULSE);
pulseTimer = 3 * IN_MILLISECONDS;
}
else
pulseTimer -= diff;
}
private:
uint32 pulseTimer;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_unstable_sphereAI(creature);
}
private:
uint32 pulseTimer;
uint32 deathTimer;
};
};
void AddSC_boss_drakos()
@@ -21,8 +21,8 @@
#include "SpellAuraEffects.h"
#include "oculus.h"
//Types of drake mounts: Ruby(Tank), Amber(DPS), Emerald(Healer)
//Two Repeating phases
// Types of drake mounts: Ruby (Tank), Amber (DPS), Emerald (Healer)
// Two Repeating phases
enum Events
{
@@ -61,8 +61,8 @@ enum Npcs
enum Phases
{
PHASE_NORMAL = 1,
PHASE_FIRST_PLANAR = 2,
PHASE_NORMAL = 1,
PHASE_FIRST_PLANAR = 2,
PHASE_SECOND_PLANAR = 3
};
@@ -80,172 +80,174 @@ enum EregosData
class boss_eregos : public CreatureScript
{
public:
boss_eregos() : CreatureScript("boss_eregos") { }
public:
boss_eregos() : CreatureScript("boss_eregos") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_eregosAI(creature);
}
struct boss_eregosAI : public BossAI
{
boss_eregosAI(Creature* creature) : BossAI(creature, DATA_EREGOS_EVENT) { }
void Reset() OVERRIDE
struct boss_eregosAI : public BossAI
{
_Reset();
_phase = PHASE_NORMAL;
boss_eregosAI(Creature* creature) : BossAI(creature, DATA_EREGOS) { }
_rubyVoid = true;
_emeraldVoid = true;
_amberVoid = true;
DoAction(ACTION_SET_NORMAL_EVENTS);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(SAY_KILL);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
/* Checks for present drakes vehicles from each type and deactivate achievement that corresponds to each found
The checks are so big in case some party try weird things like pulling boss down or hiding out of check range, the only thing player need is to get the boss kill credit after the check /even if he or his drake die/
Drakes mechanic would despawn all after unmount and also drakes should be auto mounted after item use, item use after Eregos is engaged leads to his despawn - based on retail data. */
if (me->FindNearestCreature(NPC_RUBY_DRAKE_VEHICLE, 500.0f, true))
_rubyVoid = false;
if (me->FindNearestCreature(NPC_EMERALD_DRAKE_VEHICLE, 500.0f, true))
_emeraldVoid = false;
if (me->FindNearestCreature(NPC_AMBER_DRAKE_VEHICLE, 500.0f, true))
_amberVoid = false;
}
uint32 GetData(uint32 type) const OVERRIDE
{
switch (type)
{
case DATA_RUBY_VOID:
return _rubyVoid;
case DATA_EMERALD_VOID:
return _emeraldVoid;
case DATA_AMBER_VOID:
return _amberVoid;
default:
break;
}
return 0;
}
void DoAction(int32 action) OVERRIDE
{
if (action != ACTION_SET_NORMAL_EVENTS)
return;
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
}
void JustSummoned(Creature* summon) OVERRIDE
{
BossAI::JustSummoned(summon);
if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
return;
summon->CombatStop(true);
summon->SetReactState(REACT_PASSIVE);
summon->GetMotionMaster()->MoveRandom(100.0f);
}
void SummonedCreatureDespawn(Creature* summon) OVERRIDE
{
if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
return;
// TO-DO: See why the spell is not casted
summon->CastSpell(summon, SPELL_PLANAR_BLAST, true);
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
{
if (!me->GetMap()->IsHeroic())
return;
if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && _phase < PHASE_FIRST_PLANAR)
|| (me->GetHealthPct() < 20.0f && _phase < PHASE_SECOND_PLANAR) )
void Reset() OVERRIDE
{
events.Reset();
_phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR;
_Reset();
_phase = PHASE_NORMAL;
Talk(SAY_SHIELD);
DoCast(SPELL_PLANAR_SHIFT);
_rubyVoid = true;
_emeraldVoid = true;
_amberVoid = true;
// not sure about the amount, and if we should despawn previous spawns (dragon trashs)
summons.DespawnAll();
for (uint8 i = 0; i < 6; i++)
DoCast(SPELL_PLANAR_ANOMALIES);
DoAction(ACTION_SET_NORMAL_EVENTS);
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
switch (eventId)
Talk(SAY_KILL);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
/* Checks for present drakes vehicles from each type and deactivate achievement that corresponds to each found
The checks are so big in case some party try weird things like pulling boss down or hiding out of check range, the only thing player need is to get the boss kill credit after the check /even if he or his drake die/
Drakes mechanic would despawn all after unmount and also drakes should be auto mounted after item use, item use after Eregos is engaged leads to his despawn - based on retail data. */
if (me->FindNearestCreature(NPC_RUBY_DRAKE_VEHICLE, 500.0f, true))
_rubyVoid = false;
if (me->FindNearestCreature(NPC_EMERALD_DRAKE_VEHICLE, 500.0f, true))
_emeraldVoid = false;
if (me->FindNearestCreature(NPC_AMBER_DRAKE_VEHICLE, 500.0f, true))
_amberVoid = false;
}
uint32 GetData(uint32 type) const OVERRIDE
{
switch (type)
{
case DATA_RUBY_VOID:
return _rubyVoid;
case DATA_EMERALD_VOID:
return _emeraldVoid;
case DATA_AMBER_VOID:
return _amberVoid;
default:
break;
}
return 0;
}
void DoAction(int32 action) OVERRIDE
{
if (action != ACTION_SET_NORMAL_EVENTS)
return;
events.SetPhase(PHASE_NORMAL);
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
}
void JustSummoned(Creature* summon) OVERRIDE
{
BossAI::JustSummoned(summon);
if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
return;
summon->CombatStop(true);
summon->SetReactState(REACT_PASSIVE);
summon->GetMotionMaster()->MoveRandom(100.0f);
}
void SummonedCreatureDespawn(Creature* summon) OVERRIDE
{
if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
return;
/// @todo: See why the spell is not casted
summon->CastSpell(summon, SPELL_PLANAR_BLAST, true);
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
{
if (!IsHeroic())
return;
if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && _phase < PHASE_FIRST_PLANAR)
|| (me->GetHealthPct() < 20.0f && _phase < PHASE_SECOND_PLANAR) )
{
case EVENT_ARCANE_BARRAGE:
DoCastVictim(SPELL_ARCANE_BARRAGE);
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_ARCANE_VOLLEY:
DoCastAOE(SPELL_ARCANE_VOLLEY);
events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_ENRAGED_ASSAULT:
Talk(SAY_ENRAGE);
DoCast(SPELL_ENRAGED_ASSAULT);
events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_SUMMON_LEY_WHELP:
for (uint8 i = 0; i < 3; i++)
DoCast(SPELL_SUMMON_LEY_WHELP);
events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
events.Reset();
_phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR;
Talk(SAY_SHIELD);
DoCast(SPELL_PLANAR_SHIFT);
// not sure about the amount, and if we should despawn previous spawns (dragon trashs)
summons.DespawnAll();
for (uint8 i = 0; i < 6; i++)
DoCast(SPELL_PLANAR_ANOMALIES);
}
}
DoMeleeAttackIfReady();
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
void JustDied(Unit* /*killer*/) OVERRIDE
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ARCANE_BARRAGE:
DoCastVictim(SPELL_ARCANE_BARRAGE);
events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_ARCANE_VOLLEY:
DoCastAOE(SPELL_ARCANE_VOLLEY);
events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_ENRAGED_ASSAULT:
Talk(SAY_ENRAGE);
DoCast(SPELL_ENRAGED_ASSAULT);
events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
case EVENT_SUMMON_LEY_WHELP:
for (uint8 i = 0; i < 3; i++)
DoCast(SPELL_SUMMON_LEY_WHELP);
events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
Talk(SAY_DEATH);
_JustDied();
}
private:
uint8 _phase;
bool _rubyVoid;
bool _emeraldVoid;
bool _amberVoid;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
Talk(SAY_DEATH);
_JustDied();
return new boss_eregosAI(creature);
}
private:
uint8 _phase;
bool _rubyVoid;
bool _emeraldVoid;
bool _amberVoid;
};
};
class spell_eregos_planar_shift : public SpellScriptLoader
@@ -259,9 +261,8 @@ class spell_eregos_planar_shift : public SpellScriptLoader
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (Creature* creatureCaster = caster->ToCreature())
creatureCaster->AI()->DoAction(ACTION_SET_NORMAL_EVENTS);
if (Creature* creature = GetTarget()->ToCreature())
creature->AI()->DoAction(ACTION_SET_NORMAL_EVENTS);
}
void Register() OVERRIDE
@@ -29,7 +29,6 @@ EndScriptData */
enum Spells
{
SPELL_ARCANE_SHIELD = 53813, //Dummy --> Channeled, shields the caster from damage.
SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
@@ -89,274 +88,242 @@ static uint32 TeleportSpells[]=
class boss_urom : public CreatureScript
{
public:
boss_urom() : CreatureScript("boss_urom") { }
public:
boss_urom() : CreatureScript("boss_urom") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_uromAI(creature);
}
struct boss_uromAI : public BossAI
{
boss_uromAI(Creature* creature) : BossAI(creature, DATA_UROM_EVENT) { }
void Reset() OVERRIDE
struct boss_uromAI : public BossAI
{
me->CastSpell(me, SPELL_EVOCATE);
_Reset();
if (instance->GetData(DATA_UROM_PLATAFORM) == 0)
boss_uromAI(Creature* creature) : BossAI(creature, DATA_UROM)
{
for (uint8 i = 0; i < 3; i++)
group[i] = 0;
platform = 0;
for (uint8 i = 0; i < 3; ++i)
group[i] = i;
std::random_shuffle(group, group + 3);
}
x = 0.0f;
y = 0.0f;
canCast = false;
canGoBack = false;
me->GetMotionMaster()->MoveIdle();
teleportTimer = urand(30000, 35000);
arcaneExplosionTimer = 9000;
castArcaneExplosionTimer = 2000;
frostBombTimer = urand(5000, 8000);
timeBombTimer = urand(20000, 25000);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
SetGroups();
SummonGroups();
CastTeleport();
if (instance->GetData(DATA_UROM_PLATAFORM) != 3)
instance->SetData(DATA_UROM_PLATAFORM, instance->GetData(DATA_UROM_PLATAFORM)+1);
}
void AttackStart(Unit* who) OVERRIDE
{
if (!who)
return;
if (me->GetPositionZ() > 518.63f)
DoStartNoMovement(who);
if (me->GetPositionZ() < 518.63f)
void Reset() OVERRIDE
{
if (me->Attack(who, true))
{
Talk(SAY_AGGRO);
me->SetInCombatWith(who);
who->SetInCombatWith(me);
me->GetMotionMaster()->MoveChase(who, 0, 0);
}
}
}
void SetGroups()
{
if (!instance || instance->GetData(DATA_UROM_PLATAFORM) != 0)
return;
while (group[0] == group[1] || group[0] == group[2] || group[1] == group[2])
{
for (uint8 i = 0; i < 3; i++)
group[i] = urand(0, 2);
}
}
void SetPosition(uint8 i)
{
switch (i)
{
case 0:
x = me->GetPositionX() + 4;
y = me->GetPositionY() - 4;
break;
case 1:
x = me->GetPositionX() + 4;
y = me->GetPositionY() + 4;
break;
case 2:
x = me->GetPositionX() - 4;
y = me->GetPositionY() + 4;
break;
case 3:
x = me->GetPositionX() - 4;
y = me->GetPositionY() - 4;
break;
default:
break;
}
}
void SummonGroups()
{
if (!instance || instance->GetData(DATA_UROM_PLATAFORM) > 2)
return;
for (uint8 i = 0; i < 4; i++)
{
SetPosition(i);
me->SummonCreature(Group[group[instance->GetData(DATA_UROM_PLATAFORM)]].entry[i], x, y, me->GetPositionZ(), me->GetOrientation());
// teleport to next platform and spawn adds
switch (instance->GetData(DATA_UROM_PLATAFORM))
me->CastSpell(me, SPELL_EVOCATE);
_Reset();
x = 0.0f;
y = 0.0f;
canCast = false;
canGoBack = false;
me->GetMotionMaster()->MoveIdle();
teleportTimer = urand(30000, 35000);
arcaneExplosionTimer = 9000;
castArcaneExplosionTimer = 2000;
frostBombTimer = urand(5000, 8000);
timeBombTimer = urand(20000, 25000);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
StartAttack();
}
void AttackStart(Unit* who) OVERRIDE
{
if (!who)
return;
if (me->GetPositionZ() > 518.63f)
DoStartNoMovement(who);
else
BossAI::AttackStart(who);
}
void SetPosition(uint8 i)
{
switch (i)
{
case 0:
x = me->GetPositionX() + 4;
y = me->GetPositionY() - 4;
break;
case 1:
Talk(SAY_SUMMON_1);
x = me->GetPositionX() + 4;
y = me->GetPositionY() + 4;
break;
case 2:
Talk(SAY_SUMMON_2);
x = me->GetPositionX() - 4;
y = me->GetPositionY() + 4;
break;
case 3:
Talk(SAY_SUMMON_3);
x = me->GetPositionX() - 4;
y = me->GetPositionY() - 4;
break;
default:
break;
}
}
}
void CastTeleport()
{
if (!instance || instance->GetData(DATA_UROM_PLATAFORM) > 2)
return;
Talk(instance->GetData(DATA_UROM_PLATAFORM) < 5 ? instance->GetData(DATA_UROM_PLATAFORM) : 0);
DoCast(TeleportSpells[instance->GetData(DATA_UROM_PLATAFORM)]);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 uiDiff) OVERRIDE
{
if (!UpdateVictim())
return;
if (!instance || instance->GetData(DATA_UROM_PLATAFORM) < 2)
return;
if (teleportTimer <= uiDiff)
void StartAttack()
{
me->InterruptNonMeleeSpells(false);
me->GetMotionMaster()->MoveIdle();
DoCast(SPELL_TELEPORT);
teleportTimer = urand(30000, 35000);
} else teleportTimer -= uiDiff;
if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
{
if (castArcaneExplosionTimer <= uiDiff)
if (platform > 2)
{
canCast = false;
canGoBack = true;
DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
castArcaneExplosionTimer = 2000;
}else castArcaneExplosionTimer -= uiDiff;
Talk(SAY_AGGRO);
return;
}
// summon guards and jump to next platform
for (uint8 i = 0; i < 4; ++i)
{
SetPosition(i);
me->SummonCreature(Group[group[platform]].entry[i], x, y, me->GetPositionZ(), me->GetOrientation());
}
Talk(platform);
DoCast(TeleportSpells[platform]);
++platform;
}
if (canGoBack)
void KilledUnit(Unit* who) OVERRIDE
{
if (arcaneExplosionTimer <= uiDiff)
{
Position pPos;
me->GetVictim()->GetPosition(&pPos);
me->NearTeleportTo(pPos.GetPositionX(), pPos.GetPositionY(), pPos.GetPositionZ(), pPos.GetOrientation());
me->GetMotionMaster()->MoveChase(me->GetVictim(), 0, 0);
me->SetWalk(true);
Talk(EMOTE_ARCANE_EXPLOSION);
Talk(SAY_ARCANE_EXPLOSION);
canCast = false;
canGoBack = false;
arcaneExplosionTimer = 9000;
} else arcaneExplosionTimer -= uiDiff;
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_PLAYER_KILL);
}
if (!me->IsNonMeleeSpellCasted(false, true, true))
void UpdateAI(uint32 diff) OVERRIDE
{
if (frostBombTimer <= uiDiff)
{
DoCastVictim(SPELL_FROSTBOMB);
frostBombTimer = urand(5000, 8000);
} else frostBombTimer -= uiDiff;
if (!UpdateVictim())
return;
if (timeBombTimer <= uiDiff)
{
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(unit, SPELL_TIME_BOMB);
if (platform < 3)
return;
timeBombTimer = urand(20000, 25000);
} else timeBombTimer -= uiDiff;
events.Update(diff);
if (teleportTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
me->GetMotionMaster()->MoveIdle();
DoCast(SPELL_TELEPORT);
teleportTimer = urand(30000, 35000);
}
else
teleportTimer -= diff;
if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
{
if (castArcaneExplosionTimer <= diff)
{
canCast = false;
canGoBack = true;
DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
castArcaneExplosionTimer = 2000;
}
else
castArcaneExplosionTimer -= diff;
}
if (canGoBack)
{
if (arcaneExplosionTimer <= diff)
{
Position pos;
me->GetVictim()->GetPosition(&pos);
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
me->GetMotionMaster()->MoveChase(me->GetVictim());
me->SetWalk(true);
Talk(EMOTE_ARCANE_EXPLOSION);
Talk(SAY_ARCANE_EXPLOSION);
canCast = false;
canGoBack = false;
arcaneExplosionTimer = 9000;
}
else
arcaneExplosionTimer -= diff;
}
if (!me->IsNonMeleeSpellCasted(false, true, true))
{
if (frostBombTimer <= diff)
{
DoCastVictim(SPELL_FROSTBOMB);
frostBombTimer = urand(5000, 8000);
}
else
frostBombTimer -= diff;
if (timeBombTimer <= diff)
{
if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(unit, SPELL_TIME_BOMB);
timeBombTimer = urand(20000, 25000);
}
else
timeBombTimer -= diff;
}
DoMeleeAttackIfReady();
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
}
void LeaveCombat()
{
me->RemoveAllAuras();
me->CombatStop(false);
me->DeleteThreatList();
}
void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) OVERRIDE
{
switch (pSpell->Id)
void JustDied(Unit* /*killer*/) OVERRIDE
{
case SPELL_SUMMON_MENAGERIE:
me->SetHomePosition(968.66f, 1042.53f, 527.32f, 0.077f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_SUMMON_MENAGERIE_2:
me->SetHomePosition(1164.02f, 1170.85f, 527.321f, 3.66f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_SUMMON_MENAGERIE_3:
me->SetHomePosition(1118.31f, 1080.377f, 508.361f, 4.25f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_TELEPORT:
//! Unconfirmed, previous below
me->SetDisableGravity(true);
//me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); // with out it the npc will fall down while is casting
canCast = true;
break;
default:
break;
_JustDied();
Talk(SAY_DEATH);
DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
}
}
void LeaveCombat()
{
me->RemoveAllAuras();
me->CombatStop(false);
me->DeleteThreatList();
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) OVERRIDE
{
switch (spellInfo->Id)
{
case SPELL_SUMMON_MENAGERIE:
me->SetHomePosition(968.66f, 1042.53f, 527.32f, 0.077f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_SUMMON_MENAGERIE_2:
me->SetHomePosition(1164.02f, 1170.85f, 527.321f, 3.66f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_SUMMON_MENAGERIE_3:
me->SetHomePosition(1118.31f, 1080.377f, 508.361f, 4.25f);
LeaveCombat();
me->CastSpell(me, SPELL_EVOCATE);
break;
case SPELL_TELEPORT:
//! Unconfirmed, previous below
me->SetDisableGravity(true);
//me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); // with out it the npc will fall down while is casting
canCast = true;
break;
default:
break;
}
}
private:
float x, y;
bool canCast;
bool canGoBack;
uint8 platform;
uint8 group[3];
uint32 teleportTimer;
@@ -364,7 +331,12 @@ public:
uint32 castArcaneExplosionTimer;
uint32 frostBombTimer;
uint32 timeBombTimer;
};
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetOculusAI<boss_uromAI>(creature);
}
};
void AddSC_boss_urom()
@@ -54,105 +54,110 @@ enum Events
class boss_varos : public CreatureScript
{
public:
boss_varos() : CreatureScript("boss_varos") { }
public:
boss_varos() : CreatureScript("boss_varos") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_varosAI(creature);
}
struct boss_varosAI : public BossAI
{
boss_varosAI(Creature* creature) : BossAI(creature, DATA_VAROS_EVENT)
struct boss_varosAI : public BossAI
{
if (instance->GetBossState(DATA_DRAKOS_EVENT) != DONE)
DoCast(me, SPELL_CENTRIFUGE_SHIELD);
}
boss_varosAI(Creature* creature) : BossAI(creature, DATA_VAROS) { }
void Reset() OVERRIDE
{
_Reset();
events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(20, 25) * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
// not sure if this is handled by a timer or hp percentage
events.ScheduleEvent(EVENT_CALL_AZURE, urand(15, 30) * IN_MILLISECONDS);
firstCoreEnergize = false;
coreEnergizeOrientation = 0.0f;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
}
float GetCoreEnergizeOrientation()
{
return coreEnergizeOrientation;
}
void UpdateAI(uint32 diff) OVERRIDE
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
void InitializeAI() OVERRIDE
{
switch (eventId)
{
case EVENT_ENERGIZE_CORES:
DoCast(me, SPELL_ENERGIZE_CORES);
events.CancelEvent(EVENT_ENERGIZE_CORES);
break;
case EVENT_ENERGIZE_CORES_VISUAL:
if (!firstCoreEnergize)
{
coreEnergizeOrientation = me->GetOrientation();
firstCoreEnergize = true;
} else
coreEnergizeOrientation = Position::NormalizeOrientation(coreEnergizeOrientation - 2.0f);
DoCast(me, SPELL_ENERGIZE_CORES_VISUAL);
events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
events.ScheduleEvent(EVENT_ENERGIZE_CORES, 4000);
break;
case EVENT_CALL_AZURE:
// not sure how blizz handles this, i cant see any pattern between the differnt spells
DoCast(me, SPELL_CALL_AZURE_RING_CAPTAIN);
Talk(SAY_AZURE);
Talk(SAY_AZURE_EMOTE);
events.ScheduleEvent(EVENT_CALL_AZURE, urand(20, 25) * IN_MILLISECONDS);
break;
case EVENT_AMPLIFY_MAGIC:
DoCastVictim(SPELL_CALL_AMPLIFY_MAGIC);
events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(17, 20) * IN_MILLISECONDS);
break;
}
if (instance->GetBossState(DATA_DRAKOS) != DONE)
DoCast(me, SPELL_CENTRIFUGE_SHIELD);
}
DoMeleeAttackIfReady();
}
void Reset() OVERRIDE
{
_Reset();
void JustDied(Unit* /*killer*/) OVERRIDE
events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(20, 25) * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
// not sure if this is handled by a timer or hp percentage
events.ScheduleEvent(EVENT_CALL_AZURE, urand(15, 30) * IN_MILLISECONDS);
firstCoreEnergize = false;
coreEnergizeOrientation = 0.0f;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
Talk(SAY_AGGRO);
}
float GetCoreEnergizeOrientation()
{
return coreEnergizeOrientation;
}
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_ENERGIZE_CORES:
DoCast(me, SPELL_ENERGIZE_CORES);
events.CancelEvent(EVENT_ENERGIZE_CORES);
break;
case EVENT_ENERGIZE_CORES_VISUAL:
if (!firstCoreEnergize)
{
coreEnergizeOrientation = me->GetOrientation();
firstCoreEnergize = true;
}
else
coreEnergizeOrientation = Position::NormalizeOrientation(coreEnergizeOrientation - 2.0f);
DoCast(me, SPELL_ENERGIZE_CORES_VISUAL);
events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
events.ScheduleEvent(EVENT_ENERGIZE_CORES, 4000);
break;
case EVENT_CALL_AZURE:
// not sure how blizz handles this, i cant see any pattern between the differnt spells
DoCast(me, SPELL_CALL_AZURE_RING_CAPTAIN);
Talk(SAY_AZURE);
Talk(SAY_AZURE_EMOTE);
events.ScheduleEvent(EVENT_CALL_AZURE, urand(20, 25) * IN_MILLISECONDS);
break;
case EVENT_AMPLIFY_MAGIC:
DoCastVictim(SPELL_CALL_AMPLIFY_MAGIC);
events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(17, 20) * IN_MILLISECONDS);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
}
private:
bool firstCoreEnergize;
float coreEnergizeOrientation;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
return GetOculusAI<boss_varosAI>(creature);
}
private:
bool firstCoreEnergize;
float coreEnergizeOrientation;
};
};
class npc_azure_ring_captain : public CreatureScript
@@ -259,7 +264,6 @@ class spell_varos_centrifuge_shield : public SpellScriptLoader
if (Unit* caster = GetCaster())
{
// flags taken from sniffs
// UNIT_FLAG_UNK_9 -> means passive but it is not yet implemented in core
if (caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_UNK_6))
{
caster->ToCreature()->SetReactState(REACT_PASSIVE);
@@ -18,354 +18,336 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
#include "WorldPacket.h"
#include "oculus.h"
#include "Player.h"
#define MAX_ENCOUNTER 4
DoorData const doorData[] =
{
{ GO_DRAGON_CAGE_DOOR, DATA_DRAKOS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
};
/* The Occulus encounters:
0 - Drakos the Interrogator
1 - Varos Cloudstrider
2 - Mage-Lord Urom
3 - Ley-Guardian Eregos */
Position const VerdisaMove = { 949.188f, 1032.91f, 359.967f, 1.093027f };
Position const BelgaristraszMove = { 941.453f, 1044.1f, 359.967f, 0.1984709f };
Position const EternosMove = { 943.202f, 1059.35f, 359.967f, 5.757278f };
class instance_oculus : public InstanceMapScript
{
public:
instance_oculus() : InstanceMapScript("instance_oculus", 578) { }
public:
instance_oculus() : InstanceMapScript(OculusScriptName, 578) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
return new instance_oculus_InstanceMapScript(map);
}
struct instance_oculus_InstanceMapScript : public InstanceScript
{
instance_oculus_InstanceMapScript(Map* map) : InstanceScript(map) { }
void Initialize() OVERRIDE
struct instance_oculus_InstanceMapScript : public InstanceScript
{
SetBossNumber(MAX_ENCOUNTER);
drakosGUID = 0;
varosGUID = 0;
uromGUID = 0;
eregosGUID = 0;
platformUrom = 0;
centrifugueConstructCounter = 0;
eregosCacheGUID = 0;
gwhelpList.clear();
gameObjectList.clear();
belgaristraszGUID = 0;
eternosGUID = 0;
verdisaGUID = 0;
}
void OnUnitDeath(Unit* unit) OVERRIDE
{
Creature* creature = unit->ToCreature();
if (!creature)
return;
if (creature->GetEntry() != NPC_CENTRIFUGE_CONSTRUCT)
return;
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --centrifugueConstructCounter);
if (!centrifugueConstructCounter)
if (Creature* varos = instance->GetCreature(varosGUID))
varos->RemoveAllAuras();
}
void OnPlayerEnter(Player* player) OVERRIDE
{
if (GetBossState(DATA_DRAKOS_EVENT) == DONE && GetBossState(DATA_VAROS_EVENT) != DONE)
instance_oculus_InstanceMapScript(Map* map) : InstanceScript(map)
{
player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, centrifugueConstructCounter);
} else
{
player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, 0);
}
}
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
void ProcessEvent(WorldObject* /*unit*/, uint32 eventId)
{
if (eventId != EVENT_CALL_DRAGON)
return;
DrakosGUID = 0;
VarosGUID = 0;
UromGUID = 0;
EregosGUID = 0;
Creature* varos = instance->GetCreature(varosGUID);
CentrifugueConstructCounter = 0;
if (!varos)
return;
EregosCacheGUID = 0;
if (Creature* drake = varos->SummonCreature(NPC_AZURE_RING_GUARDIAN, varos->GetPositionX(), varos->GetPositionY(), varos->GetPositionZ()+40))
drake->AI()->DoAction(ACTION_CALL_DRAGON_EVENT);
}
GreaterWhelpList.clear();
void OnCreatureCreate(Creature* creature) OVERRIDE
{
switch (creature->GetEntry())
{
case NPC_DRAKOS:
drakosGUID = creature->GetGUID();
break;
case NPC_VAROS:
varosGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_UROM:
uromGUID = creature->GetGUID();
if (GetBossState(DATA_VAROS_EVENT) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_EREGOS:
eregosGUID = creature->GetGUID();
if (GetBossState(DATA_UROM_EVENT) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_CENTRIFUGE_CONSTRUCT:
if (creature->IsAlive())
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++centrifugueConstructCounter);
break;
case NPC_BELGARISTRASZ:
belgaristraszGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
{
creature->SetWalk(true),
creature->GetMotionMaster()->MovePoint(0, 941.453f, 1044.1f, 359.967f),
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
break;
case NPC_ETERNOS:
eternosGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
{
creature->SetWalk(true),
creature->GetMotionMaster()->MovePoint(0, 943.202f, 1059.35f, 359.967f),
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
break;
case NPC_VERDISA:
verdisaGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
{
creature->SetWalk(true),
creature->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f),
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
break;
case NPC_GREATER_WHELP:
if (GetBossState(DATA_UROM_EVENT) == DONE)
{
creature->SetPhaseMask(1, true);
gwhelpList.push_back(creature->GetGUID());
}
break;
}
}
void OnGameObjectCreate(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
case GO_DRAGON_CAGE_DOOR:
if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
else
go->SetGoState(GO_STATE_READY);
gameObjectList.push_back(go->GetGUID());
break;
case GO_EREGOS_CACHE_N:
case GO_EREGOS_CACHE_H:
eregosCacheGUID = go->GetGUID();
break;
default:
break;
}
}
bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
if (!InstanceScript::SetBossState(type, state))
return false;
switch (type)
{
case DATA_DRAKOS_EVENT:
if (state == DONE)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, centrifugueConstructCounter);
OpenCageDoors();
FreeDragons();
if (Creature* varos = instance->GetCreature(varosGUID))
varos->SetPhaseMask(1, true);
}
break;
case DATA_VAROS_EVENT:
if (state == DONE)
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
if (Creature* urom = instance->GetCreature(uromGUID))
urom->SetPhaseMask(1, true);
break;
case DATA_UROM_EVENT:
if (state == DONE)
{
if (Creature* eregos = instance->GetCreature(eregosGUID))
{
eregos->SetPhaseMask(1, true);
GreaterWhelps();
}
}
break;
case DATA_EREGOS_EVENT:
if (state == DONE)
DoRespawnGameObject(eregosCacheGUID, 7*DAY);
break;
BelgaristraszGUID = 0;
EternosGUID = 0;
VerdisaGUID = 0;
}
return true;
}
void SetData(uint32 type, uint32 data) OVERRIDE
{
switch (type)
void OnCreatureCreate(Creature* creature) OVERRIDE
{
case DATA_UROM_PLATAFORM:
platformUrom = data;
break;
}
}
uint32 GetData(uint32 type) const OVERRIDE
{
switch (type)
{
case DATA_UROM_PLATAFORM: return platformUrom;
// used by condition system
case DATA_UROM_EVENT: return GetBossState(DATA_UROM_EVENT);
}
return 0;
}
uint64 GetData64(uint32 identifier) const OVERRIDE
{
switch (identifier)
{
case DATA_DRAKOS: return drakosGUID;
case DATA_VAROS: return varosGUID;
case DATA_UROM: return uromGUID;
case DATA_EREGOS: return eregosGUID;
}
return 0;
}
void OpenCageDoors()
{
if (gameObjectList.empty())
return;
for (std::list<uint64>::const_iterator itr = gameObjectList.begin(); itr != gameObjectList.end(); ++itr)
{
if (GameObject* go = instance->GetGameObject(*itr))
go->SetGoState(GO_STATE_ACTIVE);
}
}
void FreeDragons()
{
if (Creature* belgaristrasz = instance->GetCreature(belgaristraszGUID))
belgaristrasz->SetWalk(true),
belgaristrasz->GetMotionMaster()->MovePoint(0, 941.453f, 1044.1f, 359.967f);
if (Creature* eternos = instance->GetCreature(eternosGUID))
eternos->SetWalk(true),
eternos->GetMotionMaster()->MovePoint(0, 943.202f, 1059.35f, 359.967f);
if (Creature* verdisa = instance->GetCreature(verdisaGUID))
verdisa->SetWalk(true),
verdisa->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f);
}
void GreaterWhelps()
{
if (gwhelpList.empty())
return;
for (std::list<uint64>::const_iterator itr = gwhelpList.begin(); itr != gwhelpList.end(); ++itr)
if (Creature* gwhelp = instance->GetCreature(*itr))
gwhelp->SetPhaseMask(1, true);
}
std::string GetSaveData() OVERRIDE
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "T O " << GetBossSaveData();
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in) OVERRIDE
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'T' && dataHead2 == 'O')
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
switch (creature->GetEntry())
{
uint32 tmpState;
loadStream >> tmpState;
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
tmpState = NOT_STARTED;
SetBossState(i, EncounterState(tmpState));
case NPC_DRAKOS:
DrakosGUID = creature->GetGUID();
break;
case NPC_VAROS:
VarosGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_UROM:
UromGUID = creature->GetGUID();
if (GetBossState(DATA_VAROS) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_EREGOS:
EregosGUID = creature->GetGUID();
if (GetBossState(DATA_UROM) == DONE)
creature->SetPhaseMask(1, true);
break;
case NPC_CENTRIFUGE_CONSTRUCT:
if (creature->IsAlive())
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++CentrifugueConstructCounter);
break;
case NPC_BELGARISTRASZ:
BelgaristraszGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS) == DONE)
{
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->Relocate(BelgaristraszMove);
}
break;
case NPC_ETERNOS:
EternosGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS) == DONE)
{
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->Relocate(EternosMove);
}
break;
case NPC_VERDISA:
VerdisaGUID = creature->GetGUID();
if (GetBossState(DATA_DRAKOS) == DONE)
{
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->Relocate(VerdisaMove);
}
break;
case NPC_GREATER_WHELP:
if (GetBossState(DATA_UROM) == DONE)
{
creature->SetPhaseMask(1, true);
GreaterWhelpList.push_back(creature->GetGUID());
}
break;
default:
break;
}
} else OUT_LOAD_INST_DATA_FAIL;
}
OUT_LOAD_INST_DATA_COMPLETE;
void OnGameObjectCreate(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
case GO_DRAGON_CAGE_DOOR:
AddDoor(go, true);
break;
case GO_EREGOS_CACHE_N:
case GO_EREGOS_CACHE_H:
EregosCacheGUID = go->GetGUID();
break;
default:
break;
}
}
void OnGameObjectRemove(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
case GO_DRAGON_CAGE_DOOR:
AddDoor(go, false);
break;
default:
break;
}
}
void OnUnitDeath(Unit* unit) OVERRIDE
{
Creature* creature = unit->ToCreature();
if (!creature)
return;
if (creature->GetEntry() == NPC_CENTRIFUGE_CONSTRUCT)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --CentrifugueConstructCounter);
if (!CentrifugueConstructCounter)
if (Creature* varos = instance->GetCreature(VarosGUID))
varos->RemoveAllAuras();
}
}
void FillInitialWorldStates(WorldPacket& data) OVERRIDE
{
if (GetBossState(DATA_DRAKOS) == DONE && GetBossState(DATA_VAROS) != DONE)
{
data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW) << uint32(1);
data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT) << uint32(CentrifugueConstructCounter);
}
else
{
data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW) << uint32(0);
data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT) << uint32(0);
}
}
void ProcessEvent(WorldObject* /*unit*/, uint32 eventId)
{
if (eventId != EVENT_CALL_DRAGON)
return;
if (Creature* varos = instance->GetCreature(VarosGUID))
if (Creature* drake = varos->SummonCreature(NPC_AZURE_RING_GUARDIAN, varos->GetPositionX(), varos->GetPositionY(), varos->GetPositionZ() + 40))
drake->AI()->DoAction(ACTION_CALL_DRAGON_EVENT);
}
bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
if (!InstanceScript::SetBossState(type, state))
return false;
switch (type)
{
case DATA_DRAKOS:
if (state == DONE)
{
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
FreeDragons();
if (Creature* varos = instance->GetCreature(VarosGUID))
varos->SetPhaseMask(1, true);
}
break;
case DATA_VAROS:
if (state == DONE)
DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
if (Creature* urom = instance->GetCreature(UromGUID))
urom->SetPhaseMask(1, true);
break;
case DATA_UROM:
if (state == DONE)
{
if (Creature* eregos = instance->GetCreature(EregosGUID))
{
eregos->SetPhaseMask(1, true);
GreaterWhelps();
}
}
break;
case DATA_EREGOS:
if (state == DONE)
{
if (GameObject* cache = instance->GetGameObject(EregosCacheGUID))
{
cache->SetRespawnTime(cache->GetRespawnDelay());
cache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
}
break;
}
return true;
}
uint64 GetData64(uint32 type) const OVERRIDE
{
switch (type)
{
case DATA_DRAKOS:
return DrakosGUID;
case DATA_VAROS:
return VarosGUID;
case DATA_UROM:
return UromGUID;
case DATA_EREGOS:
return EregosGUID;
default:
break;
}
return 0;
}
void FreeDragons()
{
if (Creature* belgaristrasz = instance->GetCreature(BelgaristraszGUID))
{
belgaristrasz->SetWalk(true);
belgaristrasz->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, BelgaristraszMove);
}
if (Creature* eternos = instance->GetCreature(EternosGUID))
{
eternos->SetWalk(true);
eternos->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, EternosMove);
}
if (Creature* verdisa = instance->GetCreature(VerdisaGUID))
{
verdisa->SetWalk(true);
verdisa->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, VerdisaMove);
}
}
void GreaterWhelps()
{
for (std::list<uint64>::const_iterator itr = GreaterWhelpList.begin(); itr != GreaterWhelpList.end(); ++itr)
if (Creature* gwhelp = instance->GetCreature(*itr))
gwhelp->SetPhaseMask(1, true);
}
std::string GetSaveData() OVERRIDE
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "T O " << GetBossSaveData();
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
void Load(char const* str) OVERRIDE
{
if (!str)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(str);
char dataHead1, dataHead2;
std::istringstream loadStream(str);
loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'T' && dataHead2 == 'O')
{
for (uint32 i = 0; i < EncounterCount; ++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;
}
protected:
uint64 DrakosGUID;
uint64 VarosGUID;
uint64 UromGUID;
uint64 EregosGUID;
uint64 BelgaristraszGUID;
uint64 EternosGUID;
uint64 VerdisaGUID;
uint8 CentrifugueConstructCounter;
uint64 EregosCacheGUID;
std::list<uint64> GreaterWhelpList;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
return new instance_oculus_InstanceMapScript(map);
}
private:
uint64 drakosGUID;
uint64 varosGUID;
uint64 uromGUID;
uint64 eregosGUID;
uint64 belgaristraszGUID;
uint64 eternosGUID;
uint64 verdisaGUID;
uint8 platformUrom;
uint8 centrifugueConstructCounter;
uint64 eregosCacheGUID;
std::string str_data;
std::list<uint64> gameObjectList;
std::list<uint64> gwhelpList;
};
};
void AddSC_instance_oculus()
@@ -20,39 +20,20 @@
#include "ScriptedGossip.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Vehicle.h"
#include "CombatAI.h"
#include "oculus.h"
#include "Player.h"
#define GOSSIP_ITEM_DRAKES "So where do we go from here?"
#define GOSSIP_ITEM_BELGARISTRASZ1 "I want to fly on the wings of the Red Flight"
#define GOSSIP_ITEM_BELGARISTRASZ2 "What abilities do Ruby Drakes have?"
#define GOSSIP_ITEM_VERDISA1 "I want to fly on the wings of the Green Flight"
#define GOSSIP_ITEM_VERDISA2 "What abilities do Emerald Drakes have?"
#define GOSSIP_ITEM_ETERNOS1 "I want to fly on the wings of the Bronze Flight"
#define GOSSIP_ITEM_ETERNOS2 "What abilities do Amber Drakes have?"
#define HAS_ESSENCE(a) ((a)->HasItemCount(ITEM_EMERALD_ESSENCE) || (a)->HasItemCount(ITEM_AMBER_ESSENCE) || (a)->HasItemCount(ITEM_RUBY_ESSENCE))
#include "Vehicle.h"
#include "oculus.h"
enum GossipNPCs
{
GOSSIP_TEXTID_DRAKES = 13267,
GOSSIP_TEXTID_BELGARISTRASZ1 = 12916,
GOSSIP_TEXTID_BELGARISTRASZ2 = 13466,
GOSSIP_TEXTID_BELGARISTRASZ3 = 13254,
GOSSIP_TEXTID_VERDISA1 = 1,
GOSSIP_TEXTID_VERDISA2 = 1,
GOSSIP_TEXTID_VERDISA3 = 1,
GOSSIP_TEXTID_ETERNOS1 = 1,
GOSSIP_TEXTID_ETERNOS2 = 1,
GOSSIP_TEXTID_ETERNOS3 = 13256,
GOSSIP_MENU_VERDISA = 9573,
GOSSIP_MENU_ETERNOS = 9574,
GOSSIP_MENU_BELGARISTRASZ = 9575,
ITEM_EMERALD_ESSENCE = 37815,
ITEM_AMBER_ESSENCE = 37859,
ITEM_RUBY_ESSENCE = 37860,
SPELL_SHOCK_CHARGE = 49836
ITEM_EMERALD_ESSENCE = 37815,
ITEM_AMBER_ESSENCE = 37859,
ITEM_RUBY_ESSENCE = 37860
};
enum Drakes
@@ -73,9 +54,9 @@ enum Drakes
(npc 27755) (item 37859)
(summoned by spell Amber Essence = 37859 ---> Call Amber Drake == 49461 ---> Summon 27755)
*/
SPELL_RIDE_AMBER_DRAKE_QUE = 49459, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49460
SPELL_AMBER_DRAKE_SADDLE = 49460, //Allows you to ride on the back of an Amber Drake. ---> Dummy
SPELL_AMBER_SHOCK_CHARGE = 49836,
SPELL_AMBER_SHOCK_LANCE = 49840, //(60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
// SPELL_AMBER_STOP_TIME //Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
//you do not have access to until you kill the Mage-Lord Urom.
@@ -91,6 +72,20 @@ enum Drakes
SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, //(60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25, 000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
// you do not have access to until you kill the Mage-Lord Urom
SPELL_EMERALD_DREAM_FUNNEL = 50344, //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
// Misc
POINT_LAND = 2,
POINT_TAKE_OFF = 3
};
enum DrakeEvents
{
EVENT_WELCOME = 1,
EVENT_ABILITIES,
EVENT_SPECIAL_ATTACK,
EVENT_LOW_HEALTH,
EVENT_RESET_LOW_HEALTH,
EVENT_TAKE_OFF
};
enum Says
@@ -107,420 +102,376 @@ enum Says
class npc_verdisa_beglaristrasz_eternos : public CreatureScript
{
public:
npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
public:
npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
{
player->PlayerTalkClass->ClearMenus();
switch (creature->GetEntry())
struct npc_verdisa_beglaristrasz_eternosAI : public ScriptedAI
{
case NPC_VERDISA: //Verdisa
{
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
if (!HAS_ESSENCE(player))
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA1, creature->GetGUID());
}
else
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA2, creature->GetGUID());
}
break;
case GOSSIP_ACTION_INFO_DEF + 2:
{
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_EMERALD_ESSENCE, 1);
if (msg == EQUIP_ERR_OK)
player->StoreNewItem(dest, ITEM_EMERALD_ESSENCE, true);
player->CLOSE_GOSSIP_MENU();
break;
}
case GOSSIP_ACTION_INFO_DEF + 3:
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA3, creature->GetGUID());
break;
}
break;
}
case NPC_BELGARISTRASZ: //Belgaristrasz
{
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
if (!HAS_ESSENCE(player))
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ1, creature->GetGUID());
}
else
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ2, creature->GetGUID());
}
break;
case GOSSIP_ACTION_INFO_DEF + 2:
{
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_RUBY_ESSENCE, 1);
if (msg == EQUIP_ERR_OK)
player->StoreNewItem(dest, ITEM_RUBY_ESSENCE, true);
player->CLOSE_GOSSIP_MENU();
break;
}
case GOSSIP_ACTION_INFO_DEF + 3:
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ3, creature->GetGUID());
break;
}
break;
}
case NPC_ETERNOS: //Eternos
{
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
if (!HAS_ESSENCE(player))
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS1, creature->GetGUID());
}
else
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS2, creature->GetGUID());
}
break;
case GOSSIP_ACTION_INFO_DEF + 2:
{
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_AMBER_ESSENCE, 1);
if (msg == EQUIP_ERR_OK)
player->StoreNewItem(dest, ITEM_AMBER_ESSENCE, true);
player->CLOSE_GOSSIP_MENU();
break;
}
case GOSSIP_ACTION_INFO_DEF + 3:
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS3, creature->GetGUID());
break;
}
break;
}
}
npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { }
return true;
}
void StoreEssence(Player* player, uint32 itemId)
{
/// @todo: should be handled by spell, but not found in dbc (49450 and other?)
uint32 count = 1;
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count);
if (msg == EQUIP_ERR_OK)
if (Item* item = player->StoreNewItem(dest, itemId, true))
player->SendNewItem(item, count, true, true);
}
bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
void RemoveEssence(Player* player, uint32 itemId)
{
player->DestroyItemCount(itemId, 1, true, false);
}
if (InstanceScript* instance = creature->GetInstanceScript())
void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) OVERRIDE
{
switch (menuId)
{
case GOSSIP_MENU_VERDISA:
if (gossipListId >= 1 && gossipListId <= 3)
{
if (gossipListId == 2)
RemoveEssence(player, ITEM_AMBER_ESSENCE);
else if (gossipListId == 3)
RemoveEssence(player, ITEM_RUBY_ESSENCE);
StoreEssence(player, ITEM_EMERALD_ESSENCE);
break;
}
return;
case GOSSIP_MENU_ETERNOS:
if (gossipListId >= 1 && gossipListId <= 3)
{
if (gossipListId == 2)
RemoveEssence(player, ITEM_EMERALD_ESSENCE);
else if (gossipListId == 3)
RemoveEssence(player, ITEM_RUBY_ESSENCE);
StoreEssence(player, ITEM_AMBER_ESSENCE);
break;
}
return;
case GOSSIP_MENU_BELGARISTRASZ:
if (gossipListId >= 0 && gossipListId <= 2)
{
if (gossipListId == 1)
RemoveEssence(player, ITEM_AMBER_ESSENCE);
else if (gossipListId == 2)
RemoveEssence(player, ITEM_EMERALD_ESSENCE);
StoreEssence(player, ITEM_RUBY_ESSENCE);
break;
}
return;
default:
return;
}
player->PlayerTalkClass->SendCloseGossip();
}
void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
{
if (id != POINT_MOVE_OUT)
return;
// When Belgaristraz finish his moving say grateful text
if (me->GetEntry() == NPC_BELGARISTRASZ)
Talk(SAY_BELGARISTRASZ);
// The gossip flag should activate when Drakos die and not from DB
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
if (instance->GetBossState(DATA_DRAKOS_EVENT) == DONE)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DRAKES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DRAKES, creature->GetGUID());
}
return GetOculusAI<npc_verdisa_beglaristrasz_eternosAI>(creature);
}
return true;
}
struct npc_verdisa_beglaristrasz_eternosAI : public ScriptedAI
{
npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { }
void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
{
if (id)
return;
// When Belgaristraz finish his moving say grateful text
if (me->GetEntry() == NPC_BELGARISTRASZ)
Talk(SAY_BELGARISTRASZ);
// The gossip flag should activate when Drakos die and not from DB
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_verdisa_beglaristrasz_eternosAI(creature);
}
};
class npc_image_belgaristrasz : public CreatureScript
{
public:
npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { }
public:
npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { }
struct npc_image_belgaristraszAI : public ScriptedAI
{
npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(Unit* summoner) OVERRIDE
struct npc_image_belgaristraszAI : public ScriptedAI
{
if (summoner->GetEntry() == NPC_VAROS)
{
Talk(SAY_VAROS);
me->DespawnOrUnsummon(60000);
}
if (summoner->GetEntry() == NPC_UROM)
{
Talk(SAY_UROM);
me->DespawnOrUnsummon(60000);
}
}
};
npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_image_belgaristraszAI(creature);
}
void IsSummonedBy(Unit* summoner) OVERRIDE
{
if (summoner->GetEntry() == NPC_VAROS)
{
Talk(SAY_VAROS);
me->DespawnOrUnsummon(60000);
}
if (summoner->GetEntry() == NPC_UROM)
{
Talk(SAY_UROM);
me->DespawnOrUnsummon(60000);
}
}
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetOculusAI<npc_image_belgaristraszAI>(creature);
}
};
class npc_ruby_emerald_amber_drake : public CreatureScript
{
public:
npc_ruby_emerald_amber_drake() : CreatureScript("npc_ruby_emerald_amber_drake") { }
public:
npc_ruby_emerald_amber_drake() : CreatureScript("npc_ruby_emerald_amber_drake") { }
struct npc_ruby_emerald_amber_drakeAI : public VehicleAI
{
npc_ruby_emerald_amber_drakeAI(Creature* creature) : VehicleAI(creature)
struct npc_ruby_emerald_amber_drakeAI : public VehicleAI
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint64 summonerGUID;
uint32 WelcomeTimer;
uint32 WelcomeSequelTimer;
uint32 SpecialTimer;
uint32 WarningTimer;
uint32 TakeOffTimer;
bool WelcomeOff;
bool WelcomeSequelOff;
bool SpecialOff;
bool HealthWarningOff;
bool DisableTakeOff;
void Reset() OVERRIDE
{
summonerGUID = 0;
WelcomeTimer = 4500;
WelcomeSequelTimer = 4500;
SpecialTimer = 10000;
WarningTimer = 25000;
TakeOffTimer = 3500;
WelcomeOff = false;
WelcomeSequelOff = false;
SpecialOff = false;
HealthWarningOff = false;
DisableTakeOff = false;
}
void IsSummonedBy(Unit* summoner) OVERRIDE
{
if (instance->GetBossState(DATA_EREGOS_EVENT) == IN_PROGRESS)
if (Creature* eregos = me->FindNearestCreature(NPC_EREGOS, 450.0f, true))
{
eregos->DespawnOrUnsummon(); // On retail this kills abusive call of drake during engaged Eregos
}
summonerGUID = summoner->GetGUID();
me->SetFacingToObject(summoner);
// TO DO: Drake Ques should be casted from vehicle to player, however the way core handle triggered spells from auras break it no matter the conditions. So this change the caster and give the same result until someone fix triggered spells from auras that involve implicit targets or make exception for this case.
if (me->GetEntry() == NPC_RUBY_DRAKE_VEHICLE)
summoner->CastSpell(summoner, SPELL_RIDE_RUBY_DRAKE_QUE);
if (me->GetEntry() == NPC_EMERALD_DRAKE_VEHICLE)
summoner->CastSpell(summoner, SPELL_RIDE_EMERALD_DRAKE_QUE);
if (me->GetEntry() == NPC_AMBER_DRAKE_VEHICLE)
summoner->CastSpell(summoner, SPELL_RIDE_AMBER_DRAKE_QUE);
Position pos;
summoner->GetPosition(&pos);
me->GetMotionMaster()->MovePoint(0, pos);
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (type == POINT_MOTION_TYPE && id == 0)
me->SetDisableGravity(false); // Needed this for proper animation after spawn, the summon in air fall to ground bug leave no other option for now, if this isn't used the drake will only walk on move.
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!(instance->GetBossState(DATA_VAROS_EVENT) == DONE))
npc_ruby_emerald_amber_drakeAI(Creature* creature) : VehicleAI(creature)
{
if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
_instance = creature->GetInstanceScript();
}
void Reset() OVERRIDE
{
_events.Reset();
_healthWarning = true;
}
void IsSummonedBy(Unit* summoner) OVERRIDE
{
if (_instance->GetBossState(DATA_EREGOS) == IN_PROGRESS)
if (Creature* eregos = me->FindNearestCreature(NPC_EREGOS, 450.0f, true))
eregos->DespawnOrUnsummon(); // On retail this kills abusive call of drake during engaged Eregos
me->SetFacingToObject(summoner);
switch (me->GetEntry())
{
if (!(WelcomeOff))
{
if (WelcomeTimer <= diff)
{
Talk(WHISPER_DRAKES_WELCOME, me->GetCreatorGUID());
WelcomeOff = true;
WelcomeSequelOff = true;
}
else WelcomeTimer -= diff;
}
case NPC_RUBY_DRAKE_VEHICLE:
me->CastSpell(summoner, SPELL_RIDE_RUBY_DRAKE_QUE);
break;
case NPC_EMERALD_DRAKE_VEHICLE:
me->CastSpell(summoner, SPELL_RIDE_EMERALD_DRAKE_QUE);
break;
case NPC_AMBER_DRAKE_VEHICLE:
me->CastSpell(summoner, SPELL_RIDE_AMBER_DRAKE_QUE);
break;
default:
return;
}
Position pos;
summoner->GetPosition(&pos);
me->GetMotionMaster()->MovePoint(POINT_LAND, pos);
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (type == POINT_MOTION_TYPE && id == POINT_LAND)
me->SetDisableGravity(false); // Needed this for proper animation after spawn, the summon in air fall to ground bug leave no other option for now, if this isn't used the drake will only walk on move.
}
void PassengerBoarded(Unit* passenger, int8 seatId, bool apply)
{
if (passenger->GetTypeId() != TYPEID_PLAYER)
return;
if (apply)
{
if (_instance->GetBossState(DATA_VAROS) != DONE)
_events.ScheduleEvent(EVENT_WELCOME, 10 * IN_MILLISECONDS);
else if (_instance->GetBossState(DATA_UROM) == DONE)
_events.ScheduleEvent(EVENT_SPECIAL_ATTACK, 10 * IN_MILLISECONDS);
}
else
{
_events.Reset();
_events.ScheduleEvent(EVENT_TAKE_OFF, 2 * IN_MILLISECONDS);
}
}
if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
void UpdateAI(uint32 diff) OVERRIDE
{
if (WelcomeSequelOff)
{
if (WelcomeSequelTimer <= diff)
{
Talk(WHISPER_DRAKES_ABILITIES, me->GetCreatorGUID());
WelcomeSequelOff = false;
}
else WelcomeSequelTimer -= diff;
}
if (instance->GetBossState(DATA_UROM_EVENT) == DONE)
{
if (!(SpecialOff))
{
if (SpecialTimer <= diff)
{
Talk(WHISPER_DRAKES_SPECIAL, me->GetCreatorGUID());
SpecialOff = true;
}
else SpecialTimer -= diff;
}
}
if (!(HealthWarningOff))
if (_healthWarning)
{
if (me->GetHealthPct() <= 40.0f)
{
Talk(WHISPER_DRAKES_LOWHEALTH, me->GetCreatorGUID());
HealthWarningOff = true;
}
_events.ScheduleEvent(EVENT_LOW_HEALTH, 0);
}
if (HealthWarningOff)
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
if (WarningTimer <= diff)
switch (eventId)
{
HealthWarningOff = false;
WarningTimer = 25000;
case EVENT_WELCOME:
Talk(WHISPER_DRAKES_WELCOME, me->GetCreatorGUID());
_events.ScheduleEvent(EVENT_ABILITIES, 5 * IN_MILLISECONDS);
break;
case EVENT_ABILITIES:
Talk(WHISPER_DRAKES_ABILITIES, me->GetCreatorGUID());
break;
case EVENT_SPECIAL_ATTACK:
Talk(WHISPER_DRAKES_SPECIAL, me->GetCreatorGUID());
break;
case EVENT_LOW_HEALTH:
Talk(WHISPER_DRAKES_LOWHEALTH, me->GetCreatorGUID());
_healthWarning = false;
_events.ScheduleEvent(EVENT_RESET_LOW_HEALTH, 25000);
break;
case EVENT_RESET_LOW_HEALTH:
_healthWarning = true;
break;
case EVENT_TAKE_OFF:
{
me->DespawnOrUnsummon(2050);
me->SetOrientation(2.5f);
me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
Talk(SAY_DRAKES_TAKEOFF);
Position pos;
me->GetPosition(&pos);
Position offset = { 10.0f, 10.0f, 12.0f, 0.0f };
pos.RelocateOffset(offset);
me->SetDisableGravity(true);
me->GetMotionMaster()->MovePoint(POINT_TAKE_OFF, pos);
break;
}
default:
break;
}
else WarningTimer -= diff;
}
};
private:
InstanceScript* _instance;
EventMap _events;
bool _healthWarning;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetOculusAI<npc_ruby_emerald_amber_drakeAI>(creature);
}
};
// 49345 - Call Emerald Drake
// 49461 - Call Amber Drake
// 49462 - Call Ruby Drake
class spell_oculus_call_ruby_emerald_amber_drake : public SpellScriptLoader
{
public:
spell_oculus_call_ruby_emerald_amber_drake() : SpellScriptLoader("spell_oculus_call_ruby_emerald_amber_drake") { }
class spell_oculus_call_ruby_emerald_amber_drake_SpellScript : public SpellScript
{
PrepareSpellScript(spell_oculus_call_ruby_emerald_amber_drake_SpellScript);
void ChangeSummonPos(SpellEffIndex /*effIndex*/)
{
// Adjust effect summon position
WorldLocation summonPos = *GetExplTargetDest();
Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
summonPos.RelocateOffset(offset);
SetExplTargetDest(summonPos);
GetHitDest()->RelocateOffset(offset);
}
if (!(me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE)))
void ModDestHeight(SpellEffIndex /*effIndex*/)
{
if (!(DisableTakeOff))
{
if (TakeOffTimer <= diff)
{
me->DespawnOrUnsummon(2050);
me->SetOrientation(2.5f);
me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
Talk(SAY_DRAKES_TAKEOFF);
Position pos;
me->GetPosition(&pos);
pos.m_positionX += 10.0f;
pos.m_positionY += 10.0f;
pos.m_positionZ += 12.0f;
me->GetMotionMaster()->MovePoint(1, pos);
DisableTakeOff = true;
}
else TakeOffTimer -= diff;
}
// Used to cast visual effect at proper position
Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
}
void Register() OVERRIDE
{
OnEffectHit += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
OnEffectLaunch += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_ruby_emerald_amber_drakeAI(creature);
}
SpellScript* GetSpellScript() const OVERRIDE
{
return new spell_oculus_call_ruby_emerald_amber_drake_SpellScript();
}
};
class spell_gen_stop_time : public SpellScriptLoader
// 49427 - Ride Emerald Drake Que
// 49459 - Ride Amber Drake Que
// 49463 - Ride Ruby Drake Que
class spell_oculus_ride_ruby_emerald_amber_drake_que : public SpellScriptLoader
{
public:
spell_gen_stop_time() : SpellScriptLoader("spell_gen_stop_time") { }
public:
spell_oculus_ride_ruby_emerald_amber_drake_que() : SpellScriptLoader("spell_oculus_ride_ruby_emerald_amber_drake_que") { }
class spell_gen_stop_time_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_stop_time_AuraScript);
void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
class spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript : public AuraScript
{
Unit* caster = GetCaster();
if (!caster)
return;
Unit* target = GetTarget();
for (uint32 i = 0; i < 5; ++i)
caster->CastSpell(target, SPELL_SHOCK_CHARGE, false);
}
PrepareAuraScript(spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript);
void Register() OVERRIDE
void HandlePeriodic(AuraEffect const* aurEff)
{
// caster of the triggered spell is wrong for an unknown reason, handle it here correctly
PreventDefaultAction();
if (Unit* caster = GetCaster())
GetTarget()->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void Register() OVERRIDE
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
return new spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript();
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
return new spell_gen_stop_time_AuraScript();
}
};
class spell_call_ruby_emerald_amber_drake : public SpellScriptLoader
// 49838 - Stop Time
class spell_oculus_stop_time : public SpellScriptLoader
{
public:
spell_call_ruby_emerald_amber_drake() : SpellScriptLoader("spell_call_ruby_emerald_amber_drake") { }
public:
spell_oculus_stop_time() : SpellScriptLoader("spell_oculus_stop_time") { }
class spell_call_ruby_emerald_amber_drake_SpellScript : public SpellScript
{
PrepareSpellScript(spell_call_ruby_emerald_amber_drake_SpellScript);
void ChangeSummonPos(SpellEffIndex /*effIndex*/)
class spell_oculus_stop_time_AuraScript : public AuraScript
{
// Adjust effect summon position
WorldLocation summonPos = *GetExplTargetDest();
Position offset = {0.0f, 0.0f, 12.0f, 0.0f};
summonPos.RelocateOffset(offset);
SetExplTargetDest(summonPos);
GetHitDest()->RelocateOffset(offset);
}
PrepareAuraScript(spell_oculus_stop_time_AuraScript);
void ModDestHeight(SpellEffIndex /*effIndex*/)
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
if (!sSpellMgr->GetSpellInfo(SPELL_AMBER_SHOCK_CHARGE))
return false;
return true;
}
void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
return;
Unit* target = GetTarget();
for (uint32 i = 0; i < 5; ++i)
caster->CastSpell(target, SPELL_AMBER_SHOCK_CHARGE, false);
}
void Register() OVERRIDE
{
AfterEffectApply += AuraEffectApplyFn(spell_oculus_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
// Used to cast visual effect at proper position
Position offset = {0.0f, 0.0f, 12.0f, 0.0f};
const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
return new spell_oculus_stop_time_AuraScript();
}
void Register() OVERRIDE
{
OnEffectHit += SpellEffectFn(spell_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
OnEffectLaunch += SpellEffectFn(spell_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
return new spell_call_ruby_emerald_amber_drake_SpellScript();
}
};
class spell_oculus_touch_the_nightmare : public SpellScriptLoader
{
public:
@@ -582,8 +533,9 @@ void AddSC_oculus()
new npc_verdisa_beglaristrasz_eternos();
new npc_image_belgaristrasz();
new npc_ruby_emerald_amber_drake();
new spell_gen_stop_time();
new spell_call_ruby_emerald_amber_drake();
new spell_oculus_call_ruby_emerald_amber_drake();
new spell_oculus_ride_ruby_emerald_amber_drake_que();
new spell_oculus_stop_time();
new spell_oculus_touch_the_nightmare();
new spell_oculus_dream_funnel();
}
@@ -15,59 +15,55 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEF_OCULUS_H
#define DEF_OCULUS_H
#ifndef OCULUS_H_
#define OCULUS_H_
enum Data
#define OculusScriptName "instance_oculus"
uint32 const EncounterCount = 4;
enum DataTypes
{
DATA_DRAKOS_EVENT,
DATA_VAROS_EVENT,
DATA_UROM_EVENT,
DATA_EREGOS_EVENT,
DATA_UROM_PLATAFORM
// Encounter States/Boss GUIDs
DATA_DRAKOS = 0,
DATA_VAROS = 1,
DATA_UROM = 2,
DATA_EREGOS = 3
};
enum Data64
{
DATA_DRAKOS,
DATA_VAROS,
DATA_UROM,
DATA_EREGOS
};
enum Bosses_NPCs
enum CreatureIds
{
NPC_DRAKOS = 27654,
NPC_VAROS = 27447,
NPC_UROM = 27655,
NPC_EREGOS = 27656,
NPC_AZURE_RING_GUARDIAN = 28236,
NPC_CENTRIFUGE_CONSTRUCT = 27641,
NPC_RUBY_DRAKE_VEHICLE = 27756,
NPC_EMERALD_DRAKE_VEHICLE = 27692,
NPC_AMBER_DRAKE_VEHICLE = 27755,
NPC_VERDISA = 27657,
NPC_BELGARISTRASZ = 27658,
NPC_ETERNOS = 27659,
NPC_GREATER_WHELP = 28276
NPC_AZURE_RING_GUARDIAN = 28236,
NPC_CENTRIFUGE_CONSTRUCT = 27641,
NPC_RUBY_DRAKE_VEHICLE = 27756,
NPC_EMERALD_DRAKE_VEHICLE = 27692,
NPC_AMBER_DRAKE_VEHICLE = 27755,
NPC_VERDISA = 27657,
NPC_BELGARISTRASZ = 27658,
NPC_ETERNOS = 27659,
NPC_GREATER_WHELP = 28276
};
enum GameObjects
enum GameObjectIds
{
GO_DRAGON_CAGE_DOOR = 193995,
GO_EREGOS_CACHE_N = 191349,
GO_EREGOS_CACHE_H = 193603
GO_DRAGON_CAGE_DOOR = 193995,
GO_EREGOS_CACHE_N = 191349,
GO_EREGOS_CACHE_H = 193603
};
enum SpellEvents
{
EVENT_CALL_DRAGON = 12229
EVENT_CALL_DRAGON = 12229
};
enum CreatureActions
{
ACTION_CALL_DRAGON_EVENT = 1
ACTION_CALL_DRAGON_EVENT = 1
};
enum OculusWorldStates
@@ -78,7 +74,19 @@ enum OculusWorldStates
enum OculusSpells
{
SPELL_CENTRIFUGE_SHIELD = 50053,
SPELL_DEATH_SPELL = 50415
SPELL_CENTRIFUGE_SHIELD = 50053,
SPELL_DEATH_SPELL = 50415
};
#endif
enum Misc
{
POINT_MOVE_OUT = 1
};
template<class AI>
AI* GetOculusAI(Creature* creature)
{
return GetInstanceAI<AI>(creature, OculusScriptName);
}
#endif // OCULUS_H_