aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGacko <gacko28@gmx.de>2013-01-05 18:03:11 +0100
committerGacko <gacko28@gmx.de>2013-01-05 18:03:11 +0100
commitc86230208f1ca797cc2f350fbc5f8e090816fa95 (patch)
treed38e2c832f1c31315c54c5ed79a3b9db7e226e97
parent7dd0cd4403d7f28343a751e7b85aeb30d3968ff5 (diff)
Script: Novos rewrite
-rw-r--r--sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql63
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp474
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h9
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp142
4 files changed, 408 insertions, 280 deletions
diff --git a/sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql b/sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql
new file mode 100644
index 00000000000..49f8b21e3a7
--- /dev/null
+++ b/sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql
@@ -0,0 +1,63 @@
+-- Summon minions
+DELETE FROM `spell_script_names` WHERE `spell_id`=59910;
+INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUE
+(59910,'spell_summon_minions');
+
+-- Heroic spells
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (49198,49034,49037,50089,49668,51363) OR `spellid0` IN (49198,49034,49037,50089,49668,51363);
+INSERT INTO `spelldifficulty_dbc`(`id`,`spellid0`,`spellid1`) VALUES
+(49198,49198,59909), -- Arcance Blast
+(49034,49034,59854), -- Blizzard
+(49037,49037,59855), -- Frostbolt
+(50089,50089,59856), -- Wrath of Misery
+(49668,49668,59004), -- Flash of Darkness
+(51363,51363,59016); -- Shadow Bolt
+
+-- Script assignment for summoners
+UPDATE `creature_template` SET `ScriptName`='npc_crystal_channel_target',`AIName`='' WHERE `entry`=26712;
+
+-- Spawn summoner for Crystal Handlers
+SET @GUID = 40153;
+DELETE FROM `creature` WHERE `guid`=@GUID;
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `modelid`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `curhealth`) VALUE
+(@GUID,26712,600,3,17188,-341.31,-724.4,28.57,3.78,3600,8982);
+
+-- Check instance script for achievement Oh Novos
+DELETE FROM `achievement_criteria_data` WHERE `criteria_id`=7361;
+INSERT INTO `achievement_criteria_data`(`criteria_id`,`type`,`ScriptName`) VALUE
+(7361,11,'achievement_oh_novos');
+
+-- Waypoints for summoned adds
+DELETE FROM `waypoint_data` WHERE `id` IN(2759700,2759800,2760000,2662700);
+INSERT INTO `waypoint_data`(`id`,`point`,`position_x`,`position_y`,`position_z`) VALUES
+(2759700,1,-379.473,-810.974,59.7612),
+(2759700,2,-379.449,-791.535,44.1756),
+(2759700,3,-379.448,-790.328,44.1756),
+(2759700,4,-379.426,-772.338,28.5884),
+(2759700,5,-379.415,-763.518,28.5884),
+(2760000,1,-376.571,-810.681,59.6673),
+(2760000,2,-375.627,-791.874,44.1756),
+(2760000,3,-375.629,-790.273,44.1434),
+(2760000,4,-375.402,-771.145,28.5895),
+(2760000,5,-375.337,-765.027,28.5895),
+(2759800,1,-382.303,-810.815,59.7628),
+(2759800,2,-382.324,-791.595,44.1756),
+(2759800,3,-382.326,-790.331,44.1746),
+(2759800,4,-383.037,-770.382,28.5884),
+(2759800,5,-383.140,-765.399,28.5884),
+(2662700,1,-346.977,-733.319,28.5838),
+(2662700,2,-363.009,-765.202,28.5907),
+(2662700,3,-378.269,-765.701,28.5893);
+
+-- SAI for Crystal Handlers and Risen Shadowcasters
+UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry` IN (26627,27600);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (26627,27600) AND `source_type`=0;
+INSERT INTO `smart_scripts`(`entryorguid`,`event_type`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`target_type`,`comment`) VALUES
+(26627,0,1000,1000,5000,5000,11,49668,2,'Crystal Handler - In fight - After 1s then every 5s - Cast Flash of Darkness - On victim'),
+(27600,0,1000,1000,5000,5000,11,51363,2,'Risen Shadowcaster - In fight - After 1s then every 5s - Cast Shadow Bolt - On victim');
+
+-- Conditions for beam spell
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=52106;
+INSERT INTO `conditions`(`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`Comment`) VALUES
+(13,1,52106,31,0,3,26712,0,'Beam Channel target has to be Crystal Channel Target'),
+(13,1,52106,35,1,0, 18,1,'Beam Channel target must not be self');
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
index 6d33efb4515..8a858d4d5eb 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp
@@ -19,226 +19,240 @@
#include "ScriptedCreature.h"
#include "drak_tharon_keep.h"
-enum Spells
+enum Misc
{
- SPELL_ARCANE_BLAST = 49198,
- H_SPELL_ARCANE_BLAST = 59909,
- SPELL_ARCANE_FIELD = 47346,
- SPELL_BLIZZARD = 49034,
- H_SPELL_BLIZZARD = 59854,
- SPELL_FROSTBOLT = 49037,
- H_SPELL_FROSTBOLT = 59855,
- SPELL_WRATH_OF_MISERY = 50089,
- H_SPELL_WRATH_OF_MISERY = 59856,
- SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster.
+ ACTION_RESET_CRYSTALS,
+ ACTION_ACTIVATE_CRYSTAL,
+ ACTION_DEACTIVATE,
+ EVENT_ATTACK,
+ EVENT_SUMMON_MINIONS,
+ DATA_NOVOS_ACHIEV
};
-//not in db
-enum Yells
+enum Creatures
{
- SAY_AGGRO = 0,
- SAY_KILL = 1,
- SAY_DEATH = 2,
- SAY_NECRO_ADD = 3,
- SAY_REUBBLE = 4
+ NPC_CRYSTAL_CHANNEL_TARGET = 26712,
+ NPC_FETID_TROLL_CORPSE = 27597,
+ NPC_RISEN_SHADOWCASTER = 27600,
+ NPC_HULKING_CORPSE = 27597
};
-enum Creatures
+enum Spells
{
- CREATURE_RISEN_SHADOWCASTER = 27600,
- CREATURE_FETID_TROLL_CORPSE = 27598,
- CREATURE_HULKING_CORPSE = 27597,
- CREATURE_CRYSTAL_HANDLER = 26627
+ SPELL_BEAM_CHANNEL = 52106,
+ SPELL_ARCANE_FIELD = 47346,
+
+ SPELL_SUMMON_RISEN_SHADOWCASTER = 49105,
+ SPELL_SUMMON_FETID_TROLL_CORPSE = 49103,
+ SPELL_SUMMON_HULKING_CORPSE = 49104,
+ SPELL_SUMMON_CRYSTAL_HANDLER = 49179,
+
+ SPELL_ARCANE_BLAST = 49198,
+ SPELL_BLIZZARD = 49034,
+ SPELL_FROSTBOLT = 49037,
+ SPELL_WRATH_OF_MISERY = 50089,
+ SPELL_SUMMON_MINIONS = 59910
};
-enum CombatPhase
+struct SummonerInfo
{
- IDLE,
- PHASE_1,
- PHASE_2
+ uint32 data, spell, timer;
};
-#define ACTION_MINION_REACHED 1
-#define DATA_OH_NOVOS 2
+const SummonerInfo summoners[] = {
+ { DATA_NOVOS_SUMMONER_1, SPELL_SUMMON_RISEN_SHADOWCASTER, 15000 },
+ { DATA_NOVOS_SUMMONER_2, SPELL_SUMMON_FETID_TROLL_CORPSE, 5000 },
+ { DATA_NOVOS_SUMMONER_3, SPELL_SUMMON_HULKING_CORPSE, 30000 },
+ { DATA_NOVOS_SUMMONER_4, SPELL_SUMMON_CRYSTAL_HANDLER, 30000 }
+};
-static Position AddSpawnPoint = { -379.20f, -816.76f, 59.70f, 0.0f };
-static Position CrystalHandlerSpawnPoint = { -326.626343f, -709.956604f, 27.813314f, 0.0f };
-static Position AddDestinyPoint = { -379.314545f, -772.577637f, 28.58837f, 0.0f };
+#define MAX_Y_COORD_OH_NOVOS -771.95f
class boss_novos : public CreatureScript
{
public:
boss_novos() : CreatureScript("boss_novos") { }
- struct boss_novosAI : public Scripted_NoMovementAI
+ struct boss_novosAI : public BossAI
{
- boss_novosAI(Creature* creature) : Scripted_NoMovementAI(creature), lSummons(me)
+ boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS_EVENT) {}
+
+ void Reset()
{
- instance = creature->GetInstanceScript();
+ events.Reset();
+ summons.DespawnAll();
+ instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
+
+ _ohNovos = true;
+ _crystalHandlerCount = 0;
+ SetCrystalsStatus(false);
+ SetSummonerStatus(false);
+ SetBubbled(false);
}
- uint32 uiTimer;
- uint32 uiCrystalHandlerTimer;
- uint8 crystalHandlerAmount;
+ void EnterCombat(Unit* /* victim */)
+ {
+ me->setActive(true);
+ DoZoneInCombat();
+ instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
- bool ohNovos;
+ SetCrystalsStatus(true);
+ SetSummonerStatus(true);
+ SetBubbled(true);
+ }
- SummonList lSummons;
+ void AttackStart(Unit* target)
+ {
+ if (!target)
+ return;
- std::list<uint64> luiCrystals;
+ if (me->Attack(target, true))
+ DoStartNoMovement(target);
+ }
- CombatPhase Phase;
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() || _bubbled)
+ return;
- InstanceScript* instance;
+ events.Update(diff);
- void Reset()
- {
- Phase = IDLE;
- luiCrystals.clear();
- ohNovos = true;
- me->CastStop();
- lSummons.DespawnAll();
- crystalHandlerAmount = 0;
-
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- if (instance)
- {
- instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
- for (uint8 n = 0; n < 4; ++n)
- luiCrystals.push_back(instance->GetData64(DATA_NOVOS_CRYSTAL_1 + n));
- for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
- {
- if (GameObject* temp = instance->instance->GetGameObject(*itr))
- temp->SetGoState(GO_STATE_READY);
- }
- }
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- void EnterCombat(Unit* /*who*/)
- {
- Talk(SAY_AGGRO);
- Phase = PHASE_1;
- uiCrystalHandlerTimer = 30*IN_MILLISECONDS;
- uiTimer = 1*IN_MILLISECONDS;
- DoCast(SPELL_ARCANE_FIELD);
- if (instance)
+ if (uint32 eventId = events.ExecuteEvent())
{
- for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
+ switch (eventId)
{
- if (GameObject* temp = instance->instance->GetGameObject(*itr))
- temp->SetGoState(GO_STATE_ACTIVE);
+ case EVENT_SUMMON_MINIONS:
+ DoCast(SPELL_SUMMON_MINIONS);
+ events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000);
+ break;
+ case EVENT_ATTACK:
+ if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(victim, RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY));
+ events.ScheduleEvent(EVENT_ATTACK, 3000);
+ break;
+ default:
+ break;
}
- instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
}
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void UpdateAI(const uint32 diff)
+ void DoAction(int32 const action)
{
- switch (Phase)
- {
- case PHASE_1:
- if (uiTimer <= diff)
- {
- Creature* summon = me->SummonCreature(RAND(CREATURE_FETID_TROLL_CORPSE, CREATURE_HULKING_CORPSE, CREATURE_RISEN_SHADOWCASTER), AddSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
- summon->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
- //If spell is casted stops casting arcane field so no spell casting
- //DoCast(me, SPELL_SUMMON_MINIONS);
- uiTimer = 3*IN_MILLISECONDS;
- } else uiTimer -= diff;
- if (crystalHandlerAmount < 4)
- {
- if (uiCrystalHandlerTimer <= diff)
- {
- Talk(SAY_NECRO_ADD);
- Creature* pCrystalHandler = me->SummonCreature(CREATURE_CRYSTAL_HANDLER, CrystalHandlerSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
- pCrystalHandler->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
- uiCrystalHandlerTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else uiCrystalHandlerTimer -= diff;
- }
- break;
- case PHASE_2:
- if (uiTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, DUNGEON_MODE(RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY),
- RAND(H_SPELL_ARCANE_BLAST, H_SPELL_BLIZZARD, H_SPELL_FROSTBOLT, H_SPELL_WRATH_OF_MISERY)));
- uiTimer = urand(1*IN_MILLISECONDS, 3*IN_MILLISECONDS);
- } else uiTimer -= diff;
- break;
- default:
- break;
- }
+ if (action == ACTION_CRYSTAL_HANDLER_DIED)
+ CrystalHandlerDied();
}
- void JustDied(Unit* /*killer*/)
+
+ void MoveInLineOfSight(Unit* who)
{
- Talk(SAY_DEATH);
- if (instance)
- instance->SetData(DATA_NOVOS_EVENT, DONE);
- lSummons.DespawnAll();
+ BossAI::MoveInLineOfSight(who);
+
+ if (!_ohNovos || !who || who->GetTypeId() != TYPEID_UNIT || who->GetPositionY() > MAX_Y_COORD_OH_NOVOS)
+ return;
+
+ uint32 entry = who->GetEntry();
+ if (entry == NPC_HULKING_CORPSE || entry == NPC_RISEN_SHADOWCASTER || entry == NPC_FETID_TROLL_CORPSE)
+ _ohNovos = false;
}
- void KilledUnit(Unit* victim)
+ uint32 GetData(uint32 type) const
{
- if (victim == me)
- return;
- Talk(SAY_KILL);
+ return type == DATA_NOVOS_ACHIEV && _ohNovos ? 1 : 0;
}
void JustSummoned(Creature* summon)
{
- if (summon->GetEntry() == CREATURE_CRYSTAL_HANDLER)
- crystalHandlerAmount++;
-
- lSummons.Summon(summon);
+ summons.Summon(summon);
}
- void DoAction(int32 const action)
+ private:
+ void SetBubbled(bool state)
{
- if (action == ACTION_MINION_REACHED)
- ohNovos = false;
+ _bubbled = state;
+ if (!state)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ me->CastStop();
+ }
+ else
+ {
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ DoCast(SPELL_ARCANE_FIELD);
+ }
}
- uint32 GetData(uint32 type) const
+ void SetSummonerStatus(bool active)
{
- if (type == DATA_OH_NOVOS)
- return ohNovos ? 1 : 0;
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(summoners[i].data))
+ if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid))
+ {
+ if (active)
+ crystalChannelTarget->AI()->SetData(summoners[i].spell, summoners[i].timer);
+ else
+ crystalChannelTarget->AI()->Reset();
+ }
+ }
- return 0;
+ void SetCrystalsStatus(bool active)
+ {
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i))
+ if (GameObject* crystal = instance->instance->GetGameObject(guid))
+ SetCrystalStatus(crystal, active);
}
- void RemoveCrystal()
+ void SetCrystalStatus(GameObject* crystal, bool active)
{
- if (!luiCrystals.empty())
- {
- if (instance)
- if (GameObject* temp = instance->instance->GetGameObject(luiCrystals.back()))
- temp->SetGoState(GO_STATE_READY);
- luiCrystals.pop_back();
- }
- if (luiCrystals.empty())
+ if (!crystal)
+ return;
+
+ crystal->SetGoState(active ? GO_STATE_ACTIVE : GO_STATE_READY);
+ if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f))
{
- me->CastStop();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Phase = PHASE_2;
- uiTimer = 1*IN_MILLISECONDS;
+ if (active)
+ crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL);
+ else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING))
+ crystalChannelTarget->CastStop();
}
}
- Unit* GetRandomTarget()
+ void CrystalHandlerDied()
{
- return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ for (uint8 i = 0; i < 4; i++)
+ if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i))
+ if (GameObject* crystal = instance->instance->GetGameObject(guid))
+ if (crystal->GetGoState() == GO_STATE_ACTIVE)
+ {
+ SetCrystalStatus(crystal, false);
+ break;
+ }
+
+ if (++_crystalHandlerCount >= 4)
+ {
+ SetSummonerStatus(false);
+ SetBubbled(false);
+ events.ScheduleEvent(EVENT_ATTACK, 3000);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000);
+ }
+ else if (uint64 guid = instance->GetData64(DATA_NOVOS_SUMMONER_4))
+ if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid))
+ crystalChannelTarget->AI()->SetData(SPELL_SUMMON_CRYSTAL_HANDLER, 15000);
}
+
+ uint8 _crystalHandlerCount;
+ bool _ohNovos;
+ bool _bubbled;
};
CreatureAI* GetAI(Creature* creature) const
@@ -247,126 +261,116 @@ public:
}
};
-enum CrystalHandlerSpells
-{
- SPELL_FLASH_OF_DARKNESS = 49668,
- H_SPELL_FLASH_OF_DARKNESS = 59004
-};
-
-class mob_crystal_handler : public CreatureScript
+class npc_crystal_channel_target : public CreatureScript
{
public:
- mob_crystal_handler() : CreatureScript("mob_crystal_handler") { }
+ npc_crystal_channel_target() : CreatureScript("npc_crystal_channel_target") {}
- struct mob_crystal_handlerAI : public ScriptedAI
+ struct npc_crystal_channel_targetAI : public ScriptedAI
{
- mob_crystal_handlerAI(Creature* creature) : ScriptedAI(creature)
+ npc_crystal_channel_targetAI(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset()
{
- instance = creature->GetInstanceScript();
+ _spell = 0;
+ _timer = 0;
+ _temp = 0;
}
- uint32 uiFlashOfDarknessTimer;
-
- InstanceScript* instance;
-
- void Reset()
+ void UpdateAI(const uint32 diff)
{
- uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
+ if (_spell)
+ {
+ if (_temp <= diff)
+ {
+ DoCast(_spell);
+ _temp = _timer;
+ }
+ else
+ _temp -= diff;
+ }
}
- void JustDied(Unit* /*killer*/)
+ void SetData(uint32 id, uint32 value)
{
- if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->RemoveCrystal();
+ _spell = id;
+ _timer = value;
+ _temp = value;
}
- void UpdateAI(const uint32 diff)
+ void JustSummoned(Creature* summon)
{
- if (!UpdateVictim())
- return;
+ if (InstanceScript* instance = me->GetInstanceScript())
+ if (uint64 guid = instance->GetData64(DATA_NOVOS))
+ if (Creature* novos = Creature::GetCreature(*me, guid))
+ novos->AI()->JustSummoned(summon);
- if (uiFlashOfDarknessTimer <= diff)
- {
- DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS, H_SPELL_FLASH_OF_DARKNESS));
- uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
- } else uiFlashOfDarknessTimer -= diff;
+ if (summon)
+ summon->GetMotionMaster()->MovePath(summon->GetEntry() * 100, false);
- DoMeleeAttackIfReady();
+ if (_spell == SPELL_SUMMON_CRYSTAL_HANDLER)
+ Reset();
}
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE || id != 0)
- return;
- if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- if (Unit* target = CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->GetRandomTarget())
- AttackStart(target);
- }
+ private:
+ uint32 _spell;
+ uint32 _timer;
+ uint32 _temp;
};
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_crystal_handlerAI(creature);
+ return new npc_crystal_channel_targetAI(creature);
}
};
-class mob_novos_minion : public CreatureScript
+class achievement_oh_novos : public AchievementCriteriaScript
{
public:
- mob_novos_minion() : CreatureScript("mob_novos_minion") { }
+ achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") {}
- struct mob_novos_minionAI : public ScriptedAI
+ bool OnCheck(Player* /*player*/, Unit* target)
{
- mob_novos_minionAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
+ return target && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(DATA_NOVOS_ACHIEV);
+ }
+};
- InstanceScript* instance;
+enum SummonMinions
+{
+ SPELL_COPY_OF_SUMMON_MINIONS = 59933
+};
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE || id !=0)
- return;
- if (Creature* Novos = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
- {
- Novos->AI()->DoAction(ACTION_MINION_REACHED);
- if (Unit* target = CAST_AI(boss_novos::boss_novosAI, Novos->AI())->GetRandomTarget())
- AttackStart(target);
- }
- }
- };
+class spell_summon_minions : public SpellScriptLoader
+{
+public:
+ spell_summon_minions() : SpellScriptLoader("spell_summon_minions") { }
- CreatureAI* GetAI(Creature* creature) const
+ class spell_summon_minions_SpellScript : public SpellScript
{
- return new mob_novos_minionAI(creature);
- }
-};
+ PrepareSpellScript(spell_summon_minions_SpellScript);
-class achievement_oh_novos : public AchievementCriteriaScript
-{
- public:
- achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos")
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
+ GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true);
+ GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true);
}
- bool OnCheck(Player* /*player*/, Unit* target)
+ void Register()
{
- if (!target)
- return false;
-
- if (Creature* Novos = target->ToCreature())
- if (Novos->AI()->GetData(DATA_OH_NOVOS))
- return true;
-
- return false;
+ OnEffectHitTarget += SpellEffectFn(spell_summon_minions_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_summon_minions_SpellScript();
+ }
};
void AddSC_boss_novos()
{
new boss_novos();
- new mob_crystal_handler();
- new mob_novos_minion();
+ new npc_crystal_channel_target();
+ new spell_summon_minions();
new achievement_oh_novos();
}
diff --git a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
index dc8428f9104..e17cba4bccd 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
+++ b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h
@@ -31,9 +31,16 @@ enum Data64
DATA_NOVOS,
DATA_DRED,
DATA_THARON_JA,
+
DATA_NOVOS_CRYSTAL_1,
DATA_NOVOS_CRYSTAL_2,
DATA_NOVOS_CRYSTAL_3,
- DATA_NOVOS_CRYSTAL_4
+ DATA_NOVOS_CRYSTAL_4,
+ DATA_NOVOS_SUMMONER_1,
+ DATA_NOVOS_SUMMONER_2,
+ DATA_NOVOS_SUMMONER_3,
+ DATA_NOVOS_SUMMONER_4,
+
+ ACTION_CRYSTAL_HANDLER_DIED
};
#endif
diff --git a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
index 52c5c9eab8e..1d7c537d97a 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
@@ -30,17 +30,23 @@
enum Creatures
{
- NPC_TROLLGORE = 26630,
- NPC_NOVOS = 26631,
- NPC_KING_DRED = 27483,
- NPC_THARON_JA = 26632
+ NPC_TROLLGORE = 26630,
+ NPC_NOVOS = 26631,
+ NPC_KING_DRED = 27483,
+ NPC_THARON_JA = 26632,
+ NPC_CRYSTAL_CHANNEL_TARGET = 26712,
+ NPC_CRYSTAL_HANDLER = 26627
};
enum GameObjects
{
- GO_NOVOS_CRYSTAL_1 = 189299,
- GO_NOVOS_CRYSTAL_2 = 189300,
- GO_NOVOS_CRYSTAL_3 = 189301,
- GO_NOVOS_CRYSTAL_4 = 189302
+ GO_NOVOS_CRYSTAL_1 = 189299,
+ GO_NOVOS_CRYSTAL_2 = 189300,
+ GO_NOVOS_CRYSTAL_3 = 189301,
+ GO_NOVOS_CRYSTAL_4 = 189302
+};
+enum Achievements
+{
+ ACM_CRITERIA_OH_NOVOS = 7361
};
class instance_drak_tharon : public InstanceMapScript
@@ -52,17 +58,22 @@ public:
{
instance_drak_tharon_InstanceScript(Map* map) : InstanceScript(map) {}
- uint8 uiDredAchievCounter;
+ uint8 dredAchievCounter;
- uint64 uiTrollgore;
- uint64 uiNovos;
- uint64 uiDred;
- uint64 uiTharonJa;
+ uint64 trollgoreGUID;
+ uint64 novosGUID;
+ uint64 dredGUID;
+ uint64 tharonJaGUID;
- uint64 uiNovosCrystal1;
- uint64 uiNovosCrystal2;
- uint64 uiNovosCrystal3;
- uint64 uiNovosCrystal4;
+ uint64 novosCrystalGUID1;
+ uint64 novosCrystalGUID2;
+ uint64 novosCrystalGUID3;
+ uint64 novosCrystalGUID4;
+
+ uint64 novosSummonerGUID1;
+ uint64 novosSummonerGUID2;
+ uint64 novosSummonerGUID3;
+ uint64 novosSummonerGUID4;
uint16 m_auiEncounter[MAX_ENCOUNTER];
@@ -71,15 +82,23 @@ public:
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
- uiTrollgore = 0;
- uiNovos = 0;
- uiDred = 0;
- uiTharonJa = 0;
- uiNovosCrystal1 = 0;
- uiNovosCrystal2 = 0;
- uiNovosCrystal3 = 0;
- uiNovosCrystal4 = 0;
- uiDredAchievCounter = 0;
+
+ dredAchievCounter = 0;
+
+ trollgoreGUID = 0;
+ novosGUID = 0;
+ dredGUID = 0;
+ tharonJaGUID = 0;
+
+ novosCrystalGUID1 = 0;
+ novosCrystalGUID2 = 0;
+ novosCrystalGUID3 = 0;
+ novosCrystalGUID4 = 0;
+
+ novosSummonerGUID1 = 0;
+ novosSummonerGUID2 = 0;
+ novosSummonerGUID3 = 0;
+ novosSummonerGUID4 = 0;
}
bool IsEncounterInProgress() const
@@ -96,16 +115,20 @@ public:
switch (go->GetEntry())
{
case GO_NOVOS_CRYSTAL_1:
- uiNovosCrystal1 = go->GetGUID();
+ novosCrystalGUID1 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_2:
- uiNovosCrystal2 = go->GetGUID();
+ novosCrystalGUID2 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_3:
- uiNovosCrystal3 = go->GetGUID();
+ novosCrystalGUID3 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
case GO_NOVOS_CRYSTAL_4:
- uiNovosCrystal4 = go->GetGUID();
+ novosCrystalGUID4 = go->GetGUID();
+ go->SetGoState(GO_STATE_READY);
break;
}
}
@@ -115,32 +138,55 @@ public:
switch (creature->GetEntry())
{
case NPC_TROLLGORE:
- uiTrollgore = creature->GetGUID();
+ trollgoreGUID = creature->GetGUID();
break;
case NPC_NOVOS:
- uiNovos = creature->GetGUID();
+ novosGUID = creature->GetGUID();
break;
case NPC_KING_DRED:
- uiDred = creature->GetGUID();
+ dredGUID = creature->GetGUID();
break;
case NPC_THARON_JA:
- uiTharonJa = creature->GetGUID();
+ tharonJaGUID = creature->GetGUID();
+ break;
+ case NPC_CRYSTAL_CHANNEL_TARGET:
+ InitializeNovosSummoner(creature);
break;
}
}
+ void InitializeNovosSummoner(Creature* creature)
+ {
+ float x = creature->GetPositionX();
+ float y = creature->GetPositionY();
+ float z = creature->GetPositionZ();
+
+ if (x < -374.0f && x > -379.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID1 = creature->GetGUID();
+ else if (x < -379.0f && x > -385.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID2 = creature->GetGUID();
+ else if (x < -374.0f && x > -385.0f && y > -827.0f && y < -820.0f && z < 60.0f && z > 58.0f)
+ novosSummonerGUID3 = creature->GetGUID();
+ else if (x < -338.0f && x > -344.0f && y > -727.0f && y < 721.0f && z < 30.0f && z > 26.0f)
+ novosSummonerGUID4 = creature->GetGUID();
+ }
+
uint64 GetData64(uint32 identifier) const
{
switch (identifier)
{
- case DATA_TROLLGORE: return uiTrollgore;
- case DATA_NOVOS: return uiNovos;
- case DATA_DRED: return uiDred;
- case DATA_THARON_JA: return uiTharonJa;
- case DATA_NOVOS_CRYSTAL_1: return uiNovosCrystal1;
- case DATA_NOVOS_CRYSTAL_2: return uiNovosCrystal2;
- case DATA_NOVOS_CRYSTAL_3: return uiNovosCrystal3;
- case DATA_NOVOS_CRYSTAL_4: return uiNovosCrystal4;
+ case DATA_TROLLGORE: return trollgoreGUID;
+ case DATA_NOVOS: return novosGUID;
+ case DATA_DRED: return dredGUID;
+ case DATA_THARON_JA: return tharonJaGUID;
+ case DATA_NOVOS_CRYSTAL_1: return novosCrystalGUID1;
+ case DATA_NOVOS_CRYSTAL_2: return novosCrystalGUID2;
+ case DATA_NOVOS_CRYSTAL_3: return novosCrystalGUID3;
+ case DATA_NOVOS_CRYSTAL_4: return novosCrystalGUID4;
+ case DATA_NOVOS_SUMMONER_1: return novosSummonerGUID1;
+ case DATA_NOVOS_SUMMONER_2: return novosSummonerGUID2;
+ case DATA_NOVOS_SUMMONER_3: return novosSummonerGUID3;
+ case DATA_NOVOS_SUMMONER_4: return novosSummonerGUID4;
}
return 0;
@@ -164,7 +210,7 @@ public:
break;
case DATA_KING_DRED_ACHIEV:
- uiDredAchievCounter = data;
+ dredAchievCounter = data;
break;
}
@@ -182,7 +228,7 @@ public:
case DATA_NOVOS_EVENT: return m_auiEncounter[1];
case DATA_DRED_EVENT: return m_auiEncounter[2];
case DATA_THARON_JA_EVENT: return m_auiEncounter[3];
- case DATA_KING_DRED_ACHIEV: return uiDredAchievCounter;
+ case DATA_KING_DRED_ACHIEV: return dredAchievCounter;
}
return 0;
}
@@ -199,6 +245,14 @@ public:
return saveStream.str();
}
+ void OnUnitDeath(Unit* unit)
+ {
+ if (unit->GetEntry() == NPC_CRYSTAL_HANDLER)
+ if (novosGUID)
+ if (Creature* novos = instance->GetCreature(novosGUID))
+ novos->AI()->DoAction(ACTION_CRYSTAL_HANDLER_DIED);
+ }
+
void Load(const char* in)
{
if (!in)