mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 09:17:36 +01:00
Script: Novos rewrite
This commit is contained in:
63
sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql
Normal file
63
sql/updates/world/2013_01_04_02_world_novos_the_summoner.sql
Normal file
@@ -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');
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
//not in db
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_NECRO_ADD = 3,
|
||||
SAY_REUBBLE = 4
|
||||
ACTION_RESET_CRYSTALS,
|
||||
ACTION_ACTIVATE_CRYSTAL,
|
||||
ACTION_DEACTIVATE,
|
||||
EVENT_ATTACK,
|
||||
EVENT_SUMMON_MINIONS,
|
||||
DATA_NOVOS_ACHIEV
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
CREATURE_RISEN_SHADOWCASTER = 27600,
|
||||
CREATURE_FETID_TROLL_CORPSE = 27598,
|
||||
CREATURE_HULKING_CORPSE = 27597,
|
||||
CREATURE_CRYSTAL_HANDLER = 26627
|
||||
NPC_CRYSTAL_CHANNEL_TARGET = 26712,
|
||||
NPC_FETID_TROLL_CORPSE = 27597,
|
||||
NPC_RISEN_SHADOWCASTER = 27600,
|
||||
NPC_HULKING_CORPSE = 27597
|
||||
};
|
||||
|
||||
enum CombatPhase
|
||||
enum Spells
|
||||
{
|
||||
IDLE,
|
||||
PHASE_1,
|
||||
PHASE_2
|
||||
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
|
||||
};
|
||||
|
||||
#define ACTION_MINION_REACHED 1
|
||||
#define DATA_OH_NOVOS 2
|
||||
struct SummonerInfo
|
||||
{
|
||||
uint32 data, spell, timer;
|
||||
};
|
||||
|
||||
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 };
|
||||
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 }
|
||||
};
|
||||
|
||||
#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)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 uiTimer;
|
||||
uint32 uiCrystalHandlerTimer;
|
||||
uint8 crystalHandlerAmount;
|
||||
|
||||
bool ohNovos;
|
||||
|
||||
SummonList lSummons;
|
||||
|
||||
std::list<uint64> luiCrystals;
|
||||
|
||||
CombatPhase Phase;
|
||||
|
||||
InstanceScript* instance;
|
||||
boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS_EVENT) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Phase = IDLE;
|
||||
luiCrystals.clear();
|
||||
ohNovos = true;
|
||||
me->CastStop();
|
||||
lSummons.DespawnAll();
|
||||
crystalHandlerAmount = 0;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
_ohNovos = true;
|
||||
_crystalHandlerCount = 0;
|
||||
SetCrystalsStatus(false);
|
||||
SetSummonerStatus(false);
|
||||
SetBubbled(false);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
void EnterCombat(Unit* /* victim */)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
Phase = PHASE_1;
|
||||
uiCrystalHandlerTimer = 30*IN_MILLISECONDS;
|
||||
uiTimer = 1*IN_MILLISECONDS;
|
||||
DoCast(SPELL_ARCANE_FIELD);
|
||||
if (instance)
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
|
||||
{
|
||||
if (GameObject* temp = instance->instance->GetGameObject(*itr))
|
||||
temp->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
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);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
|
||||
|
||||
SetCrystalsStatus(true);
|
||||
SetSummonerStatus(true);
|
||||
SetBubbled(true);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (me->Attack(target, true))
|
||||
DoStartNoMovement(target);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (instance)
|
||||
instance->SetData(DATA_NOVOS_EVENT, DONE);
|
||||
lSummons.DespawnAll();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim == me)
|
||||
if (!UpdateVictim() || _bubbled)
|
||||
return;
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() == CREATURE_CRYSTAL_HANDLER)
|
||||
crystalHandlerAmount++;
|
||||
events.Update(diff);
|
||||
|
||||
lSummons.Summon(summon);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 const action)
|
||||
{
|
||||
if (action == ACTION_MINION_REACHED)
|
||||
ohNovos = false;
|
||||
if (action == ACTION_CRYSTAL_HANDLER_DIED)
|
||||
CrystalHandlerDied();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
if (type == DATA_OH_NOVOS)
|
||||
return ohNovos ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
return type == DATA_NOVOS_ACHIEV && _ohNovos ? 1 : 0;
|
||||
}
|
||||
|
||||
void RemoveCrystal()
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (!luiCrystals.empty())
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
private:
|
||||
void SetBubbled(bool state)
|
||||
{
|
||||
_bubbled = state;
|
||||
if (!state)
|
||||
{
|
||||
if (instance)
|
||||
if (GameObject* temp = instance->instance->GetGameObject(luiCrystals.back()))
|
||||
temp->SetGoState(GO_STATE_READY);
|
||||
luiCrystals.pop_back();
|
||||
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();
|
||||
}
|
||||
if (luiCrystals.empty())
|
||||
else
|
||||
{
|
||||
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 (!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);
|
||||
}
|
||||
}
|
||||
|
||||
Unit* GetRandomTarget()
|
||||
void SetSummonerStatus(bool active)
|
||||
{
|
||||
return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 SetCrystalStatus(GameObject* crystal, bool active)
|
||||
{
|
||||
if (!crystal)
|
||||
return;
|
||||
|
||||
crystal->SetGoState(active ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f))
|
||||
{
|
||||
if (active)
|
||||
crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL);
|
||||
else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING))
|
||||
crystalChannelTarget->CastStop();
|
||||
}
|
||||
}
|
||||
|
||||
void CrystalHandlerDied()
|
||||
{
|
||||
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)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 uiFlashOfDarknessTimer;
|
||||
|
||||
InstanceScript* instance;
|
||||
npc_crystal_channel_targetAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0))
|
||||
CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->RemoveCrystal();
|
||||
_spell = 0;
|
||||
_timer = 0;
|
||||
_temp = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiFlashOfDarknessTimer <= diff)
|
||||
if (_spell)
|
||||
{
|
||||
DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS, H_SPELL_FLASH_OF_DARKNESS));
|
||||
uiFlashOfDarknessTimer = 5*IN_MILLISECONDS;
|
||||
} else uiFlashOfDarknessTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new mob_crystal_handlerAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class mob_novos_minion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
mob_novos_minion() : CreatureScript("mob_novos_minion") { }
|
||||
|
||||
struct mob_novos_minionAI : public ScriptedAI
|
||||
{
|
||||
mob_novos_minionAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
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);
|
||||
if (_temp <= diff)
|
||||
{
|
||||
DoCast(_spell);
|
||||
_temp = _timer;
|
||||
}
|
||||
else
|
||||
_temp -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 value)
|
||||
{
|
||||
_spell = id;
|
||||
_timer = value;
|
||||
_temp = value;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (uint64 guid = instance->GetData64(DATA_NOVOS))
|
||||
if (Creature* novos = Creature::GetCreature(*me, guid))
|
||||
novos->AI()->JustSummoned(summon);
|
||||
|
||||
if (summon)
|
||||
summon->GetMotionMaster()->MovePath(summon->GetEntry() * 100, false);
|
||||
|
||||
if (_spell == SPELL_SUMMON_CRYSTAL_HANDLER)
|
||||
Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _spell;
|
||||
uint32 _timer;
|
||||
uint32 _temp;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new mob_novos_minionAI(creature);
|
||||
return new npc_crystal_channel_targetAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_oh_novos : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos")
|
||||
public:
|
||||
achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") {}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
return target && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(DATA_NOVOS_ACHIEV);
|
||||
}
|
||||
};
|
||||
|
||||
enum SummonMinions
|
||||
{
|
||||
SPELL_COPY_OF_SUMMON_MINIONS = 59933
|
||||
};
|
||||
|
||||
class spell_summon_minions : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_summon_minions() : SpellScriptLoader("spell_summon_minions") { }
|
||||
|
||||
class spell_summon_minions_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_summon_minions_SpellScript);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user