Scripts/Utgarde Pinnacle:
- Re-write Svala Sorrowgrave - Scripted achievement The Incredible Hulk. This script was writen basing on work and data: - Original TC script. - Albis fix for Arthas sounds and texts https://github.com/TrinityCore/TrinityCore/issues/4002 . - Ric event start fix. - Recorded encounters uploaded on YouTube. - Data found on ScriptDev2 forums. - Iov's custom SD2 repo and Svalas's script https://github.com/Iov/scriptdev2 . Also thx to: - ZxBiohazardZx for pointing how to fix looting problem when boss is killed when flying. - Aokromes for confirmig how many times event "Ritual of the Sword" is performed. - Mini event with Arthas. - Call Flames: timers of cast and time between "Ball of Flame" (48246) can be wrong (based on videos). - Ritual of the Sword works and is performed once at 50% hp but: a) Still need retail data for teleport position of Svala floating above player. b) Need fully fixed spell Ritual of the Sword (48276), the triggering of spell Ritual Strike - Trigger Missile (48331) part was hardcoded. - Spell Paralyze (48278) used by Ritual Channeler: fixed stacking and selection to ritual player only. - Achievement "The Incredible Hulk": works but often Scourge Hulk don't get initial dmg from spell Ritual Strike (spell 48277 Effect #1 Value: 6650 to 7350). - Looting problems when Svala was killed in air (require vmaps and option "vmap.enableHeight = 1" enabled in "worldserver.conf"). - Moved script_texts to creature_text. It require option "vmap.enableHeight = 1" to work properly.
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/* Texts */
|
||||
|
||||
-- Move text used in Svala Sorrowgrave from script_texts to creature_text
|
||||
-- Remove old script text for boss_svala.cpp
|
||||
DELETE FROM `script_texts` WHERE `entry` BETWEEN -1575027 AND -1575015;
|
||||
|
||||
DELETE FROM `creature_text` WHERE `entry` IN (26668,29281);
|
||||
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
|
||||
(26668,0,0, 'The sensation is... beyond my imagining. I am yours to command, my king.',14,0,0,0,0,13857, 'Svala Sorrowgrave SAY_DIALOG_WITH_ARTHAS_2'),
|
||||
(26668,1,0, 'I will be happy to slaughter them in your name! Come, enemies of the Scourge! I will show you the might of the Lich King!',14,0,0,0,0,13858, 'Svala Sorrowgrave SAY_DIALOG_WITH_ARTHAS_3'),
|
||||
(26668,2,0, 'I will vanquish your soul!',14,0,0,0,0,13842, 'Svala Sorrowgrave SAY_AGGRO'),
|
||||
(26668,3,0, 'You were a fool to challenge the power of the Lich King!',14,0,0,0,0,13845, 'Svala Sorrowgrave SAY_SLAY_1'),
|
||||
(26668,3,1, 'Your will is done, my king.',14,0,0,0,0,13847, 'Svala Sorrowgrave SAY_SLAY_2'),
|
||||
(26668,3,2, 'Another soul for my master.',14,0,0,0,0,13848, 'Svala Sorrowgrave SAY_SLAY_3'),
|
||||
(26668,4,0, 'Nooo! I did not come this far... to...',14,0,0,0,0,13855, 'Svala Sorrowgrave SAY_DEATH'),
|
||||
(26668,5,0, 'Your death approaches.',14,0,0,0,0,13850, 'Svala Sorrowgrave SAY_SACRIFICE_1'),
|
||||
(26668,5,1, 'Go now to my master.',14,0,0,0,0,13851, 'Svala Sorrowgrave SAY_SACRIFICE_2'),
|
||||
(26668,5,2, 'Your end is inevitable.',14,0,0,0,0,13852, 'Svala Sorrowgrave SAY_SACRIFICE_3'),
|
||||
(26668,5,3, 'Yor-guul mak!',14,0,0,0,0,13853, 'Svala Sorrowgrave SAY_SACRIFICE_4'),
|
||||
(26668,5,4, 'Any last words?',14,0,0,0,0,13854, 'Svala Sorrowgrave SAY_SACRIFICE_5'),
|
||||
(29281,0,0, 'My liege! I have done as you asked, and now beseech you for your blessing!',14,0,0,0,0,13856, 'Svala SAY_DIALOG_WITH_ARTHAS_1');
|
||||
|
||||
/* Templates */
|
||||
|
||||
UPDATE `creature_template` SET `unit_flags`=2 WHERE `entry` IN (29281, 30809); -- And this, fixes her flag so script can be started (credit to ric)
|
||||
UPDATE `creature` SET `spawntimesecs`=86400 WHERE `id`=29281; -- Set Svala's spawn time
|
||||
UPDATE `creature_template` SET `flags_extra`=`flags_extra`|1 WHERE `entry`=30809; -- Set flags_extra = 1 for Svala hero difficulty
|
||||
UPDATE `creature_template` SET `InhabitType`=7, `flags_extra`=`flags_extra`|130 WHERE `entry`=30805; -- Set same data on heroic ver to triggers
|
||||
UPDATE `creature_template` SET `InhabitType`=7, `flags_extra`=`flags_extra`|128 WHERE `entry`=30771; -- Set same data on heroic ver to triggers
|
||||
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`
|
||||
|1 -- CHARM
|
||||
|2 -- DISORIENTED
|
||||
|4 -- DISARM
|
||||
|8 -- DISTRACT
|
||||
|16 -- FEAR
|
||||
|32 -- GRIP
|
||||
|64 -- ROOT
|
||||
|128 -- PACIFY
|
||||
|256 -- SILENCE
|
||||
|512 -- SLEEP
|
||||
|1024 -- SNARE
|
||||
|2048 -- STUN
|
||||
|4096 -- FREEZE
|
||||
|8192 -- KNOCKOUT
|
||||
|65536 -- POLYMORPH
|
||||
|131072 -- BANISH
|
||||
|524288 -- SHACKLE
|
||||
|4194304 -- TURN
|
||||
|8388608 -- HORROR
|
||||
|67108864 -- DAZE
|
||||
|536870912 -- SAPPED
|
||||
WHERE `entry` IN (29281, 30809, 26668, 30810);
|
||||
|
||||
-- Apply Image of Arthas Visual Effect
|
||||
DELETE FROM `creature_template_addon` WHERE `entry`=29280;
|
||||
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
|
||||
(29280, 0, 0, 0, 1, 0, '54134');
|
||||
|
||||
-- Flame Brazier triggers deletion (will spawn them after activating event 17841 called by spell Call Flames 48258)
|
||||
DELETE FROM `creature` WHERE `id`=27273 AND `map`=575;
|
||||
DELETE FROM `creature_addon` WHERE `guid` IN (126121, 126122);
|
||||
|
||||
/* Spells */
|
||||
|
||||
DELETE FROM `spell_target_position` WHERE `id` IN (48267,48276, 48271, 48274, 48275);
|
||||
INSERT INTO `spell_target_position` (`id`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`) VALUES
|
||||
(48267, 575, 296.632, -346.075, 90.5474, 4.60767), -- Svala Ritual - Player teleport position
|
||||
(48276, 575, 296.651, -346.293, 108.5474, 1.58), -- Svala Ritual - Svala teleport position
|
||||
(48271, 575, 296.42, -355.01, 90.94, 1.58), -- Summon Ritual Channeler positions
|
||||
(48274, 575, 302.36, -352.01, 90.54, 2.20), -- Summon Ritual Channeler positions
|
||||
(48275, 575, 291.39, -352.01, 90.54, 0.91); -- Summon Ritual Channeler positions
|
||||
|
||||
DELETE FROM `conditions` WHERE `SourceEntry` IN (48331,48246,48277) AND `SourceTypeOrReferenceId`=13;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13, 0, 48331, 0, 18, 1, 27327, 0, 0, '', NULL), -- Spell script target for flying sword
|
||||
(13, 0, 48246, 0, 18, 1, 0, 0, 0, '', NULL), -- Spell script target for Flame Brazier's (on players only)
|
||||
(13, 0, 48277, 0, 18, 1, 26555, 0, 0, '', NULL), -- Spell script target for Ritual Strike DMG -- Players
|
||||
(13, 0, 48277, 0, 18, 1, 27327, 0, 0, '', NULL); -- Spell script target for Ritual Strike DMG -- Ritual Target
|
||||
|
||||
/* Achivements */
|
||||
|
||||
-- The Incredible Hulk achievement 2043
|
||||
DELETE FROM `disables` WHERE `sourceType`=4 AND `entry`=7322;
|
||||
DELETE FROM `achievement_criteria_data` WHERE `criteria_id`=7322 AND `type`=11;
|
||||
INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
|
||||
(7322, 11, 0, 0, 'achievement_incredible_hulk');
|
||||
|
||||
/* AI */
|
||||
|
||||
DELETE FROM `creature_ai_scripts` WHERE `creature_id`=26555; -- Scourge Hulk
|
||||
UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=27273; -- Flame Brazier
|
||||
|
||||
-- Add Send Script Event (17841) summon 3 triggers
|
||||
DELETE FROM `event_scripts` WHERE `id`=17841;
|
||||
INSERT INTO `event_scripts` (`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`) VALUES
|
||||
(17841, 0, 10, 27273, 10000, 0, 285.6, -357.5, 91.0833, 5.75959),
|
||||
(17841, 3, 10, 27273, 10000, 0, 307, -357.5, 91.0833, 6.02139),
|
||||
(17841, 6, 10, 27273, 10000, 0, 285.6, -357.5, 91.0833, 5.75959);
|
||||
|
||||
-- SmartAI script Flame Brazier's cast Ball of Flame (48246) on random player
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid`=27273 AND `source_type`=0;
|
||||
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(27273, 0, 0, 0, 1, 0, 100, 1, 100, 100, 100, 100, 11, 48246, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Flame Brazier - Ball of Flame');
|
||||
|
||||
/* Script names */
|
||||
|
||||
UPDATE `creature_template` SET `AIName`='', `ScriptName`='npc_scourge_hulk' WHERE `entry`=26555;
|
||||
UPDATE `creature_template` SET `ScriptName`='' WHERE `entry`=26668; -- "boss_svala_sorrowgrave" script is now merged with "boss_svala" script
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_spectator' WHERE `entry`=26667; -- Spectators escape script
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_ritual_channeler' WHERE `entry`=27281; -- Change 'mob_ritual_channeler' to 'npc_ritual_channeler'
|
||||
|
||||
-- Paralyze -- Filter targets -- cast only on sacrafacing target
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id`=48278;
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(48278, 'spell_paralyze_pinnacle');
|
||||
|
||||
@@ -3041,6 +3041,7 @@ void SpellMgr::LoadDbcDataCorrections()
|
||||
case 42611: // Shoot
|
||||
case 61588: // Blazing Harpoon
|
||||
case 52479: // Gift of the Harvester
|
||||
case 48246: // Ball of Flame
|
||||
spellInfo->MaxAffectedTargets = 1;
|
||||
break;
|
||||
case 41376: // Spite
|
||||
@@ -3383,6 +3384,7 @@ void SpellMgr::LoadDbcDataCorrections()
|
||||
spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
|
||||
break;
|
||||
case 70602: // Corruption
|
||||
case 48278: // Paralyze
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
|
||||
break;
|
||||
case 70715: // Column of Frost (visual marker)
|
||||
|
||||
@@ -20,66 +20,93 @@
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CALL_FLAMES = 48258,
|
||||
SPELL_RITUAL_OF_THE_SWORD = 48276, //Effect #1 Teleport, Effect #2 Dummy
|
||||
SPELL_SVALA_TRANSFORMING1 = 54140,
|
||||
SPELL_SVALA_TRANSFORMING2 = 54205,
|
||||
SPELL_TRANSFORMING_CHANNEL = 54142,
|
||||
|
||||
SPELL_CALL_FLAMES = 48258, // caster effect only, triggers event 17841
|
||||
SPELL_SINSTER_STRIKE = 15667,
|
||||
H_SPELL_SINSTER_STRIKE = 59409,
|
||||
SPELL_SVALA_TRANSFORMING1 = 54140,
|
||||
SPELL_SVALA_TRANSFORMING2 = 54205
|
||||
|
||||
SPELL_RITUAL_PREPARATION = 48267,
|
||||
SPELL_RITUAL_OF_THE_SWORD = 48276,
|
||||
SPELL_RITUAL_STRIKE_TRIGGER = 48331, // triggers 48277 & 59930, needs NPC_RITUAL_TARGET as spell_script_target
|
||||
SPELL_RITUAL_DISARM = 54159,
|
||||
SPELL_RITUAL_STRIKE_EFF_1 = 48277,
|
||||
SPELL_RITUAL_STRIKE_EFF_2 = 59930,
|
||||
|
||||
SPELL_SUMMONED_VIS = 64446,
|
||||
SPELL_RITUAL_CHANNELER_1 = 48271,
|
||||
SPELL_RITUAL_CHANNELER_2 = 48274,
|
||||
SPELL_RITUAL_CHANNELER_3 = 48275,
|
||||
|
||||
// Ritual Channeler spells
|
||||
SPELL_PARALYZE = 48278,
|
||||
SPELL_SHADOWS_IN_THE_DARK = 59407,
|
||||
|
||||
// Scourge Hulk spells
|
||||
SPELL_MIGHTY_BLOW = 48697,
|
||||
SPELL_VOLATILE_INFECTION = 56785,
|
||||
H_SPELL_VOLATILE_INFECTION = 59228
|
||||
};
|
||||
//not in db
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_DIALOG_WITH_ARTHAS_1 = -1575015,
|
||||
SAY_DIALOG_WITH_ARTHAS_2 = -1575016,
|
||||
SAY_DIALOG_WITH_ARTHAS_3 = -1575017,
|
||||
SAY_AGGRO = -1575018,
|
||||
SAY_SLAY_1 = -1575019,
|
||||
SAY_SLAY_2 = -1575020,
|
||||
SAY_SLAY_3 = -1575021,
|
||||
SAY_DEATH = -1575022,
|
||||
SAY_SACRIFICE_PLAYER_1 = -1575023,
|
||||
SAY_SACRIFICE_PLAYER_2 = -1575024,
|
||||
SAY_SACRIFICE_PLAYER_3 = -1575025,
|
||||
SAY_SACRIFICE_PLAYER_4 = -1575026,
|
||||
SAY_SACRIFICE_PLAYER_5 = -1575027,
|
||||
SAY_DIALOG_OF_ARTHAS_1 = -1575028,
|
||||
SAY_DIALOG_OF_ARTHAS_2 = -1575029
|
||||
// Svala
|
||||
SAY_SVALA_INTRO_0 = 0,
|
||||
|
||||
// Svala Sorrowgrave
|
||||
SAY_SVALA_INTRO_1 = 0,
|
||||
SAY_SVALA_INTRO_2 = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_SACRIFICE_PLAYER = 5,
|
||||
|
||||
// Image of Arthas
|
||||
SAY_DIALOG_OF_ARTHAS_1 = 0,
|
||||
SAY_DIALOG_OF_ARTHAS_2 = 1
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
CREATURE_ARTHAS = 29280, // Image of Arthas
|
||||
CREATURE_SVALA_SORROWGRAVE = 26668, // Svala after transformation
|
||||
CREATURE_SVALA = 29281, // Svala before transformation
|
||||
CREATURE_RITUAL_CHANNELER = 27281
|
||||
CREATURE_RITUAL_CHANNELER = 27281,
|
||||
CREATURE_SPECTATOR = 26667,
|
||||
CREATURE_RITUAL_TARGET = 27327,
|
||||
CREATURE_FLAME_BRAZIER = 27273,
|
||||
CREATURE_SCOURGE_HULK = 26555
|
||||
};
|
||||
enum ChannelerSpells
|
||||
|
||||
enum Objects
|
||||
{
|
||||
//ritual channeler's spells
|
||||
SPELL_PARALYZE = 48278,
|
||||
SPELL_SHADOWS_IN_THE_DARK = 59407
|
||||
OBJECT_UTGARDE_MIRROR = 191745
|
||||
};
|
||||
enum Misc
|
||||
{
|
||||
DATA_SVALA_DISPLAY_ID = 25944
|
||||
};
|
||||
enum IntroPhase
|
||||
|
||||
enum SvalaPhase
|
||||
{
|
||||
IDLE,
|
||||
INTRO,
|
||||
FINISHED
|
||||
};
|
||||
enum CombatPhase
|
||||
{
|
||||
NORMAL,
|
||||
SACRIFICING
|
||||
SACRIFICING,
|
||||
SVALADEAD
|
||||
};
|
||||
|
||||
#define DATA_INCREDIBLE_HULK 2043
|
||||
|
||||
static const float spectatorWP[2][3] =
|
||||
{
|
||||
{296.95f,-312.76f,86.36f},
|
||||
{297.69f,-275.81f,86.36f}
|
||||
};
|
||||
|
||||
static Position RitualChannelerPos[]=
|
||||
{
|
||||
{296.42f, -355.01f, 90.94f, 0.0f},
|
||||
{302.36f, -352.01f, 90.54f, 0.0f},
|
||||
{291.39f, -350.89f, 90.54f, 0.0f}
|
||||
{296.42f, -355.01f, 90.94f, 1.58f},
|
||||
{302.36f, -352.01f, 90.54f, 2.20f},
|
||||
{291.39f, -352.01f, 90.54f, 0.91f}
|
||||
};
|
||||
static Position ArthasPos = { 295.81f, -366.16f, 92.57f, 1.58f };
|
||||
static Position SvalaPos = { 296.632f, -346.075f, 90.6307f, 1.58f };
|
||||
@@ -96,31 +123,96 @@ public:
|
||||
|
||||
struct boss_svalaAI : public ScriptedAI
|
||||
{
|
||||
boss_svalaAI(Creature* c) : ScriptedAI(c)
|
||||
boss_svalaAI(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
{
|
||||
instance = c->GetInstanceScript();
|
||||
instance = creature->GetInstanceScript();
|
||||
Phase = IDLE;
|
||||
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_1, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_2, true);
|
||||
}
|
||||
|
||||
uint32 uiIntroTimer;
|
||||
|
||||
uint8 uiIntroPhase;
|
||||
|
||||
IntroPhase Phase;
|
||||
|
||||
TempSummon* pArthas;
|
||||
uint64 uiArthasGUID;
|
||||
|
||||
InstanceScript* instance;
|
||||
SummonList summons;
|
||||
SvalaPhase Phase;
|
||||
|
||||
Position pos;
|
||||
float x, y, z;
|
||||
|
||||
uint32 introTimer;
|
||||
uint8 introPhase;
|
||||
uint8 sacrePhase;
|
||||
|
||||
TempSummon* arthas;
|
||||
uint64 arthasGUID;
|
||||
|
||||
uint32 sinsterStrikeTimer;
|
||||
uint32 callFlamesTimer;
|
||||
uint32 sacrificeTimer;
|
||||
|
||||
bool sacrificed;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Phase = IDLE;
|
||||
uiIntroTimer = 1 * IN_MILLISECONDS;
|
||||
uiIntroPhase = 0;
|
||||
uiArthasGUID = 0;
|
||||
sacrificed = false;
|
||||
SetCombatMovement(true);
|
||||
|
||||
summons.DespawnAll();
|
||||
me->RemoveAllAuras();
|
||||
|
||||
if (Phase > INTRO)
|
||||
{
|
||||
me->SetFlying(true);
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
}
|
||||
|
||||
if (Phase > NORMAL)
|
||||
Phase = NORMAL;
|
||||
|
||||
introTimer = 1 * IN_MILLISECONDS;
|
||||
introPhase = 0;
|
||||
arthasGUID = 0;
|
||||
|
||||
if (instance)
|
||||
{
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
|
||||
instance->SetData64(DATA_SACRIFICED_PLAYER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
if (Phase > INTRO)
|
||||
{
|
||||
me->SetFlying(false);
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
me->SetOrientation(1.58f);
|
||||
me->SendMovementFlagUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
sinsterStrikeTimer = 7 * IN_MILLISECONDS;
|
||||
callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
|
||||
|
||||
if (instance)
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() == CREATURE_RITUAL_CHANNELER)
|
||||
summon->CastSpell(summon, SPELL_SUMMONED_VIS, true);
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
@@ -133,286 +225,499 @@ public:
|
||||
Phase = INTRO;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
if (Creature* pArthas = me->SummonCreature(CREATURE_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
if (GameObject* mirror = GetClosestGameObjectWithEntry(me, OBJECT_UTGARDE_MIRROR, 100.0f))
|
||||
mirror->SetGoState(GO_STATE_READY);
|
||||
|
||||
if (Creature* arthas = me->SummonCreature(CREATURE_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
uiArthasGUID = pArthas->GetGUID();
|
||||
arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
arthasGUID = arthas->GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* /*who*/) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (Phase != INTRO)
|
||||
if (victim != me)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32 &damage)
|
||||
{
|
||||
if (Phase == SVALADEAD)
|
||||
{
|
||||
if (attacker != me)
|
||||
damage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
if (Phase == SACRIFICING)
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
||||
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(x, y, z, true, 50);
|
||||
|
||||
if (me->GetPositionZ() > z)
|
||||
{
|
||||
damage = 0;
|
||||
Phase = SVALADEAD;
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetHealth(1);
|
||||
|
||||
SetCombatMovement(false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
|
||||
me->GetMotionMaster()->MoveFall(z, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 motionType, uint32 pointId)
|
||||
{
|
||||
if (motionType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (uiIntroTimer <= diff)
|
||||
if (pointId == 1)
|
||||
{
|
||||
Creature* pArthas = Unit::GetCreature(*me, uiArthasGUID);
|
||||
if (!pArthas)
|
||||
return;
|
||||
|
||||
switch (uiIntroPhase)
|
||||
{
|
||||
case 0:
|
||||
DoScriptText(SAY_DIALOG_WITH_ARTHAS_1, me);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 3500;
|
||||
break;
|
||||
case 1:
|
||||
DoScriptText(SAY_DIALOG_OF_ARTHAS_1, pArthas);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 3500;
|
||||
break;
|
||||
case 2:
|
||||
DoScriptText(SAY_DIALOG_WITH_ARTHAS_2, me);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 3500;
|
||||
break;
|
||||
case 3:
|
||||
DoScriptText(SAY_DIALOG_OF_ARTHAS_2, pArthas);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 3500;
|
||||
break;
|
||||
case 4:
|
||||
DoScriptText(SAY_DIALOG_WITH_ARTHAS_3, me);
|
||||
DoCast(me, SPELL_SVALA_TRANSFORMING1);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 2800;
|
||||
break;
|
||||
case 5:
|
||||
DoCast(me, SPELL_SVALA_TRANSFORMING2);
|
||||
++uiIntroPhase;
|
||||
uiIntroTimer = 200;
|
||||
break;
|
||||
case 6:
|
||||
if (me->SummonCreature(CREATURE_SVALA_SORROWGRAVE, SvalaPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60*IN_MILLISECONDS))
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetDisplayId(DATA_SVALA_DISPLAY_ID);
|
||||
pArthas->DespawnOrUnsummon();
|
||||
uiArthasGUID = 0;
|
||||
Phase = FINISHED;
|
||||
me->Relocate(x, y, z, me->GetOrientation());
|
||||
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
}
|
||||
else
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
} else uiIntroTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class mob_ritual_channeler : public CreatureScript
|
||||
{
|
||||
public:
|
||||
mob_ritual_channeler() : CreatureScript("mob_ritual_channeler") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new mob_ritual_channelerAI(creature);
|
||||
}
|
||||
|
||||
struct mob_ritual_channelerAI : public Scripted_NoMovementAI
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
mob_ritual_channelerAI(Creature* c) :Scripted_NoMovementAI(c)
|
||||
{
|
||||
instance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
|
||||
}
|
||||
|
||||
// called by svala sorrowgrave to set guid of victim
|
||||
void DoAction(const int32 /*action*/)
|
||||
{
|
||||
if (instance)
|
||||
if (Unit* victim = me->GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
|
||||
DoCast(victim, SPELL_PARALYZE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_svala_sorrowgrave : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_svala_sorrowgrave() : CreatureScript("boss_svala_sorrowgrave") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_svala_sorrowgraveAI(creature);
|
||||
}
|
||||
|
||||
struct boss_svala_sorrowgraveAI : public ScriptedAI
|
||||
{
|
||||
boss_svala_sorrowgraveAI(Creature* c) : ScriptedAI(c), summons(c)
|
||||
{
|
||||
instance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 uiSinsterStrikeTimer;
|
||||
uint32 uiCallFlamesTimer;
|
||||
uint32 uiRitualOfSwordTimer;
|
||||
uint32 uiSacrificeTimer;
|
||||
|
||||
CombatPhase Phase;
|
||||
|
||||
SummonList summons;
|
||||
|
||||
bool bSacrificed;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
uiSinsterStrikeTimer = 7 * IN_MILLISECONDS;
|
||||
uiCallFlamesTimer = 10 * IN_MILLISECONDS;
|
||||
uiRitualOfSwordTimer = 20 * IN_MILLISECONDS;
|
||||
uiSacrificeTimer = 8 * IN_MILLISECONDS;
|
||||
|
||||
bSacrificed = false;
|
||||
|
||||
Phase = NORMAL;
|
||||
|
||||
DoTeleportTo(296.632f, -346.075f, 90.6307f);
|
||||
me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
if (instance)
|
||||
{
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
|
||||
instance->SetData64(DATA_SACRIFICED_PLAYER, 0);
|
||||
}
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
if (spell->Id == SPELL_RITUAL_STRIKE_EFF_1 && Phase != NORMAL && Phase != SVALADEAD)
|
||||
{
|
||||
Phase = NORMAL;
|
||||
SetCombatMovement(true);
|
||||
|
||||
if (instance)
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 300, true))
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (Phase == IDLE)
|
||||
return;
|
||||
|
||||
if (Phase == INTRO)
|
||||
{
|
||||
if (introTimer <= diff)
|
||||
{
|
||||
Creature* arthas = Unit::GetCreature(*me, arthasGUID);
|
||||
if (!arthas)
|
||||
return;
|
||||
|
||||
switch (introPhase)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_SVALA_INTRO_0);
|
||||
++introPhase;
|
||||
introTimer = 8100;
|
||||
break;
|
||||
case 1:
|
||||
arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_1);
|
||||
++introPhase;
|
||||
introTimer = 10000;
|
||||
break;
|
||||
case 2:
|
||||
arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
|
||||
me->SetFlying(true);
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
pos.Relocate(me);
|
||||
pos.m_positionZ += 8.0f;
|
||||
me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
|
||||
// spectators flee event
|
||||
if (instance)
|
||||
{
|
||||
std::list<Creature*> lspectatorList;
|
||||
GetCreatureListWithEntryInGrid(lspectatorList, me, CREATURE_SPECTATOR, 100.0f);
|
||||
for(std::list<Creature*>::iterator itr = lspectatorList.begin(); itr != lspectatorList.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->isAlive())
|
||||
{
|
||||
(*itr)->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
(*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
(*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0][0], spectatorWP[0][1], spectatorWP[0][2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
++introPhase;
|
||||
introTimer = 4200;
|
||||
break;
|
||||
case 3:
|
||||
me->CastSpell(me, SPELL_SVALA_TRANSFORMING1, false);
|
||||
++introPhase;
|
||||
introTimer = 6200;
|
||||
break;
|
||||
case 4:
|
||||
me->CastSpell(me, SPELL_SVALA_TRANSFORMING2, false);
|
||||
arthas->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->UpdateEntry(CREATURE_SVALA_SORROWGRAVE);
|
||||
me->SetFacingToObject(arthas);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
++introPhase;
|
||||
introTimer = 3200;
|
||||
break;
|
||||
case 5:
|
||||
Talk(SAY_SVALA_INTRO_1);
|
||||
++introPhase;
|
||||
introTimer = 10000;
|
||||
break;
|
||||
case 6:
|
||||
arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_2);
|
||||
++introPhase;
|
||||
introTimer = 7200;
|
||||
break;
|
||||
case 7:
|
||||
Talk(SAY_SVALA_INTRO_2);
|
||||
me->SetOrientation(1.58f);
|
||||
me->SendMovementFlagUpdate();
|
||||
arthas->SetVisible(false);
|
||||
++introPhase;
|
||||
introTimer = 13800;
|
||||
break;
|
||||
case 8:
|
||||
me->SetFlying(false);
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
me->SendMovementFlagUpdate();
|
||||
pos.Relocate(me);
|
||||
pos.m_positionX = me->GetHomePosition().GetPositionX();
|
||||
pos.m_positionY = me->GetHomePosition().GetPositionY();
|
||||
pos.m_positionZ = 90.6065f;
|
||||
me->GetMotionMaster()->MoveLand(0, pos, 6.247422f);
|
||||
++introPhase;
|
||||
introTimer = 3000;
|
||||
break;
|
||||
case 9:
|
||||
if (GameObject* mirror = GetClosestGameObjectWithEntry(me, OBJECT_UTGARDE_MIRROR, 100.0f))
|
||||
mirror->SetGoState(GO_STATE_ACTIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
arthas->DespawnOrUnsummon();
|
||||
arthasGUID = 0;
|
||||
Phase = NORMAL;
|
||||
break;
|
||||
}
|
||||
} else introTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Phase == NORMAL)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiSinsterStrikeTimer <= diff)
|
||||
if (me->IsWithinMeleeRange(me->getVictim()) && me->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING))
|
||||
{
|
||||
me->SetFlying(false);
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
me->SendMovementFlagUpdate();
|
||||
}
|
||||
|
||||
if (sinsterStrikeTimer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_SINSTER_STRIKE);
|
||||
uiSinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
|
||||
} else uiSinsterStrikeTimer -= diff;
|
||||
sinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
|
||||
} else sinsterStrikeTimer -= diff;
|
||||
|
||||
if (uiCallFlamesTimer <= diff)
|
||||
if (callFlamesTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
DoCast(target, SPELL_CALL_FLAMES);
|
||||
uiCallFlamesTimer = urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS);
|
||||
callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
|
||||
}
|
||||
} else uiCallFlamesTimer -= diff;
|
||||
} else callFlamesTimer -= diff;
|
||||
|
||||
if (!bSacrificed)
|
||||
if (!sacrificed)
|
||||
{
|
||||
if (uiRitualOfSwordTimer <= diff)
|
||||
if (HealthBelowPct(50))
|
||||
{
|
||||
if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
if (Unit* sacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
|
||||
{
|
||||
DoScriptText(RAND(SAY_SACRIFICE_PLAYER_1, SAY_SACRIFICE_PLAYER_2, SAY_SACRIFICE_PLAYER_3, SAY_SACRIFICE_PLAYER_4, SAY_SACRIFICE_PLAYER_5), me);
|
||||
DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD);
|
||||
//Spell doesn't teleport
|
||||
DoTeleportPlayer(pSacrificeTarget, 296.632f, -346.075f, 90.63f, 4.6f);
|
||||
me->SetUnitMovementFlags(MOVEMENTFLAG_CAN_FLY);
|
||||
DoTeleportTo(296.632f, -346.075f, 120.85f);
|
||||
Phase = SACRIFICING;
|
||||
if (instance)
|
||||
{
|
||||
instance->SetData64(DATA_SACRIFICED_PLAYER, pSacrificeTarget->GetGUID());
|
||||
instance->SetData64(DATA_SACRIFICED_PLAYER, sacrificeTarget->GetGUID());
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Creature* summon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
|
||||
summon->AI()->DoAction(0);
|
||||
}
|
||||
Talk(SAY_SACRIFICE_PLAYER);
|
||||
|
||||
bSacrificed = true;
|
||||
DoCast(sacrificeTarget, SPELL_RITUAL_PREPARATION);
|
||||
|
||||
SetCombatMovement(false);
|
||||
me->SetFlying(true);
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
|
||||
|
||||
Phase = SACRIFICING;
|
||||
sacrePhase = 0;
|
||||
sacrificeTimer = 1 * IN_MILLISECONDS;
|
||||
|
||||
DoCast(me, SPELL_RITUAL_OF_THE_SWORD);
|
||||
sacrificed = true;
|
||||
}
|
||||
}
|
||||
} else uiRitualOfSwordTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else //SACRIFICING
|
||||
{
|
||||
if (uiSacrificeTimer <= diff)
|
||||
if (sacrificeTimer <= diff)
|
||||
{
|
||||
Unit* pSacrificeTarget = instance ? Unit::GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)) : NULL;
|
||||
if (instance && !summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive())
|
||||
me->Kill(pSacrificeTarget, false); // durability damage?
|
||||
|
||||
//go down
|
||||
Phase = NORMAL;
|
||||
pSacrificeTarget = NULL;
|
||||
me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
|
||||
uiSacrificeTimer = 8 * IN_MILLISECONDS;
|
||||
}
|
||||
else uiSacrificeTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
switch (sacrePhase)
|
||||
{
|
||||
case 0:
|
||||
// spawn ritual channelers
|
||||
if (instance)
|
||||
{
|
||||
Creature* pSvala = Unit::GetCreature((*me), instance->GetData64(DATA_SVALA));
|
||||
if (pSvala && pSvala->isAlive())
|
||||
killer->Kill(pSvala);
|
||||
|
||||
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
|
||||
DoCast(me, SPELL_RITUAL_CHANNELER_1, true);
|
||||
DoCast(me, SPELL_RITUAL_CHANNELER_2, true);
|
||||
DoCast(me, SPELL_RITUAL_CHANNELER_3, true);
|
||||
}
|
||||
++sacrePhase;
|
||||
sacrificeTimer = 2 * IN_MILLISECONDS;
|
||||
break;
|
||||
case 1:
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_RITUAL_STRIKE_TRIGGER, true);
|
||||
++sacrePhase;
|
||||
sacrificeTimer = 200;
|
||||
break;
|
||||
case 2:
|
||||
DoCast(me, SPELL_RITUAL_DISARM);
|
||||
++sacrePhase;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else sacrificeTimer -= diff;
|
||||
}
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_ritual_channeler : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ritual_channeler() : CreatureScript("npc_ritual_channeler") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_ritual_channelerAI(creature);
|
||||
}
|
||||
|
||||
struct npc_ritual_channelerAI : public Scripted_NoMovementAI
|
||||
{
|
||||
npc_ritual_channelerAI(Creature* c) :Scripted_NoMovementAI(c)
|
||||
{
|
||||
instance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
uint32 paralyzeTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
paralyzeTimer = 1600;
|
||||
if (instance)
|
||||
if (IsHeroic())
|
||||
DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
if (paralyzeTimer <= diff)
|
||||
{
|
||||
if (instance)
|
||||
if (Unit* victim = me->GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
|
||||
DoCast(victim, SPELL_PARALYZE, false);
|
||||
|
||||
paralyzeTimer = 200;
|
||||
}
|
||||
else
|
||||
paralyzeTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_spectator : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_spectator() : CreatureScript("npc_spectator") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_spectatorAI(creature);
|
||||
}
|
||||
|
||||
struct npc_spectatorAI : public ScriptedAI
|
||||
{
|
||||
npc_spectatorAI(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MovementInform(uint32 motionType, uint32 pointId)
|
||||
{
|
||||
if (motionType == POINT_MOTION_TYPE)
|
||||
{
|
||||
if (pointId == 1)
|
||||
me->GetMotionMaster()->MovePoint(2,spectatorWP[1][0],spectatorWP[1][1],spectatorWP[1][2]);
|
||||
else if (pointId == 2)
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class checkRitualTarget
|
||||
{
|
||||
public:
|
||||
explicit checkRitualTarget(Unit* _caster) : caster(_caster) { }
|
||||
|
||||
bool operator() (Unit* unit)
|
||||
{
|
||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
||||
if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Unit* caster;
|
||||
};
|
||||
|
||||
class spell_paralyze_pinnacle : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_paralyze_pinnacle() : SpellScriptLoader("spell_paralyze_pinnacle") { }
|
||||
|
||||
class spell_paralyze_pinnacle_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_paralyze_pinnacle_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<Unit*>& unitList)
|
||||
{
|
||||
unitList.remove_if(checkRitualTarget(GetCaster()));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnUnitTargetSelect += SpellUnitTargetFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_paralyze_pinnacle_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class npc_scourge_hulk : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_scourge_hulk() : CreatureScript("npc_scourge_hulk") { }
|
||||
|
||||
struct npc_scourge_hulkAI : public ScriptedAI
|
||||
{
|
||||
npc_scourge_hulkAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 mightyBlow;
|
||||
uint32 volatileInfection;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mightyBlow = urand(4000, 9000);
|
||||
volatileInfection = urand(10000, 14000);
|
||||
killedByRitualStrike = false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
return type == DATA_INCREDIBLE_HULK ? killedByRitualStrike : 0;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32 &damage)
|
||||
{
|
||||
if (damage >= me->GetHealth() && attacker->GetEntry() == CREATURE_SVALA_SORROWGRAVE)
|
||||
killedByRitualStrike = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 const diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (mightyBlow <= diff)
|
||||
{
|
||||
if (Unit* victim = me->getVictim())
|
||||
if (!victim->HasUnitState(UNIT_STAT_STUNNED)) // Prevent knocking back a ritual player
|
||||
DoCast(victim, SPELL_MIGHTY_BLOW);
|
||||
mightyBlow = urand(12000, 17000);
|
||||
}
|
||||
else
|
||||
mightyBlow -= diff;
|
||||
|
||||
if (volatileInfection <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_VOLATILE_INFECTION);
|
||||
volatileInfection = urand(13000, 17000);
|
||||
}
|
||||
else
|
||||
volatileInfection -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool killedByRitualStrike;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_scourge_hulkAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_incredible_hulk : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_incredible_hulk() : AchievementCriteriaScript("achievement_incredible_hulk") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
return target && target->IsAIEnabled && target->GetAI()->GetData(DATA_INCREDIBLE_HULK);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_svala()
|
||||
{
|
||||
new boss_svala();
|
||||
new mob_ritual_channeler();
|
||||
new boss_svala_sorrowgrave();
|
||||
new npc_ritual_channeler();
|
||||
new npc_spectator();
|
||||
new spell_paralyze_pinnacle();
|
||||
new npc_scourge_hulk();
|
||||
new achievement_incredible_hulk();
|
||||
}
|
||||
|
||||
@@ -170,8 +170,12 @@ public:
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
if (type == DATA_SACRIFICED_PLAYER)
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SACRIFICED_PLAYER:
|
||||
uiSacrificedPlayer = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
@@ -201,6 +205,7 @@ public:
|
||||
case DATA_MOB_ORB: return uiPalehoofOrb;
|
||||
case DATA_SVALA: return uiSvala;
|
||||
case DATA_GORTOK_PALEHOOF_SPHERE: return uiGortokPalehoofSphere;
|
||||
case DATA_SACRIFICED_PLAYER: return uiSacrificedPlayer;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -53,7 +53,7 @@ enum eCreatures
|
||||
MOB_MASSIVE_JORMUNGAR = 26685,
|
||||
MOB_FEROCIOUS_RHINO = 26686,
|
||||
MOB_SVALA = 29281,
|
||||
MOB_PALEHOOF_ORB = 26688,
|
||||
MOB_PALEHOOF_ORB = 26688
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user