Scripts/Firelands: Baleroc

Closes #17527
This commit is contained in:
Krudor
2017-08-22 18:28:07 +02:00
committed by Shauren
parent cc6ca733d8
commit 28ec50b053
7 changed files with 1509 additions and 2 deletions

View File

@@ -0,0 +1,174 @@
-- Baleroc
DELETE FROM `creature` WHERE `guid` IN (339184, 339185); -- Remove sniff spawn of Riplimb and Rageface in Baleroc encounter area
UPDATE `creature` SET `equipment_id`=1, `position_x`=95.15452, `position_y`=-63.20313, `position_z`=54.9362, `orientation`=3.16296, `spawntimesecs`=604800 WHERE `guid`=338782;
DELETE FROM `creature_equip_template` WHERE `CreatureID`=53494 AND ID IN (2, 3);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(53494, 2, 71138, 0, 0, 0),
(53494, 3, 71082, 0, 0, 0);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (339198,339284);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(339198, 339198, 0, 0, 2, 0, 0),
(339198, 317657, 0, 0, 2, 0, 0),
(339284, 339284, 0, 0, 2, 0, 0),
(339284, 339285, 0, 0, 2, 0, 0);
-- Baleroc (10-man Normal)
DELETE FROM `creature_loot_template` WHERE `Entry`=53494;
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(53494, 69815, 0, 100, 1, 1, 1, 18, 23, 'Baleroc 10N - Seething Cinder'),
(53494, 71141, 0, 80, 1, 1, 1, 1, 1, 'Baleroc 10N - Eternal Ember'),
(53494, 1, 34385, 100, 0, 1, 1, 2, 2, 'Baleroc 10N - Gear');
-- Baleroc (25-man Normal)
DELETE FROM `creature_loot_template` WHERE `Entry`=53587;
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(53587, 69815, 0, 100, 1, 1, 1, 48, 55, 'Baleroc 25N - Seeting Cinder'),
(53587, 71141, 0, 100, 1, 1, 1, 1, 3, 'Baleroc 25N - Eternal Ember'),
(53587, 1, 34385, 100, 0, 1, 1, 5, 5, 'Baleroc 25N - Gear');
-- Baleroc (10-man Heroic)
DELETE FROM `creature_loot_template` WHERE `Entry`=53588;
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(53588, 69815, 0, 100, 1, 1, 1, 23, 26, 'Baleroc 10H - Seething Cinder'),
(53588, 71141, 0, 80, 1, 1, 1, 1, 1, 'Baleroc 10H - Eternal Ember'),
(53588, 1, 34386, 100, 0, 1, 1, 2, 2, 'Baleroc 10H - Gear'),
(53588, 2, 34387, 100, 0, 1, 1, 1, 1, 'Baleroc 10H - Token');
-- Baleroc (25-man Heroic)
DELETE FROM `creature_loot_template` WHERE `Entry`=53589;
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(53589, 69815, 0, 100, 1, 1, 1, 55, 66, 'Baleroc 25H - Seething Cinder'),
(53589, 71141, 0, 100, 1, 1, 1, 1, 3, 'Baleroc 25H - Eternal Ember'),
(53589, 1, 34386, 100, 0, 1, 1, 5, 5, 'Baleroc 25H - Gear'),
(53589, 2, 34387, 100, 0, 1, 1, 3, 3, 'Baleroc 25H - Tokens');
UPDATE `creature_template` SET `difficulty_entry_1`=54162, `HealthScalingExpansion`=3, `speed_walk`=0.714286, `mechanic_immune_mask`=617561727, `flags_extra`=1073741824, `ScriptName`='npc_firelands_flame_archon' WHERE `entry`=54161;
UPDATE `creature_template` SET `minlevel`=87, `maxlevel`=87, `faction`=16, `speed_walk`=0.714286, `speed_run`=1.42857, `unit_flags`=32832, `unit_flags2`=`unit_flags2`|2097152, `mechanic_immune_mask`=617561727, `flags_extra`=1073741824 WHERE `entry`=54162;
UPDATE `creature_template` SET `difficulty_entry_1`=54196, `speed_walk`=0.277777, `speed_run`=1.71429, `mechanic_immune_mask`=617561687, `ScriptName`='npc_firelands_molten_flamefather' WHERE `entry`=54143;
UPDATE `creature_template` SET `minlevel`=87, `maxlevel`=87, `HealthScalingExpansion`=3, `faction`=16, `speed_walk`=0.277777, `speed_run`=1.71429, `unit_flags`=32832, `unit_flags2`=`unit_flags2`|4194304, `mechanic_immune_mask`=617561687 WHERE `entry`=54196;
UPDATE `creature_template` SET `speed_walk`=0.277777, `speed_run`=1.71429, `unit_flags`=64, `unit_flags2`=32768, `mechanic_immune_mask`=617561727, `flags_extra`=1073741824, `AIName`='PassiveAI' WHERE `entry`=54145;
UPDATE `creature_template` SET `difficulty_entry_1`=54204, `unit_flags2`=`unit_flags2`|2097152, `ScriptName`='npc_firelands_magmakin' WHERE `entry`=54144;
UPDATE `creature_template` SET `minlevel`=87, `maxlevel`=87, `HealthScalingExpansion`=3, `faction`=16, `speed_walk`=0.555556, `speed_run`=1.71429, `unit_flags2`=2099200 WHERE `entry`=54204;
UPDATE `creature_template` SET `minlevel`=88, `maxlevel`=88, `HealthScalingExpansion`=3, `faction`=14, `speed_walk`=1.14286, `speed_run`=2, `unit_flags`=32768, `unit_flags2`=2099200, `type_flags2`=128, `mechanic_immune_mask`=617561975, `flags_extra`=1073741825 WHERE `entry` IN (53587, 53588, 53589);
UPDATE `creature_template` SET `difficulty_entry_1`=53587, `difficulty_entry_2`=53588, `difficulty_entry_3`=53589, `speed_walk`=1.14286, `mechanic_immune_mask`=617561975, `flags_extra`=`flags_extra`|1073741824, `ScriptName`='boss_baleroc' WHERE `entry`=53494;
UPDATE `creature_template` SET `lootid`=53587 WHERE `entry`=53587;
UPDATE `creature_template` SET `lootid`=53588 WHERE `entry`=53588;
UPDATE `creature_template` SET `lootid`=53589 WHERE `entry`=53589;
UPDATE `creature_template` SET `speed_walk`=0.357142, `speed_run`=1.14286, `unit_flags`=33554432, `flags_extra`=128, `ScriptName`='npc_shard_of_torment' WHERE `entry`=53495;
DELETE FROM `creature_text` WHERE `entry`=53494;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(53494, 0, 0, 'You are forbidden from my master''s domain, mortals.', 14, 0, 100, 0, 0, 24441, 52180, 3, 'Baleroc - Enter Combat'),
(53494, 1, 0, 'Fool mortals. Hurl yourselves into your own demise!', 14, 0, 100, 0, 0, 24446, 52185, 3, 'Baleroc - Shards of Torment'),
(53494, 2, 0, 'Burn beneath my molten fury!', 14, 0, 100, 0, 0, 24459, 52181, 3, 'Baleroc - Inferno Blade'),
(53494, 3, 0, 'By the Firelord''s command, you, too, shall perish!', 14, 0, 100, 0, 0, 24447, 52182, 3, 'Baleroc - Decimation Blade'),
(53494, 4, 0, 'You have been judged.', 14, 0, 100, 0, 0, 24449, 52177, 3, 'Baleroc - Kill Player (1)'),
(53494, 4, 1, 'Behold your weakness.', 14, 0, 100, 0, 0, 24451, 52178, 3, 'Baleroc - Kill Player (2)'),
(53494, 4, 2, 'None shall pass!', 14, 0, 100, 0, 0, 24452, 52179, 3, 'Baleroc - Kill Player (3)'),
(53494, 5, 0, 'Mortal filth... the master''s keep is forbidden....', 14, 0, 100, 0, 0, 24444, 52650, 3, 'Baleroc - Death'),
(53494, 6, 0, 'Your flesh is forfeit to the fires of this realm.', 14, 0, 100, 0, 0, 24450, 52183, 3, 'Baleroc - Berserk'),
(53494, 7, 0, '%s goes into a berserker rage!', 41, 0, 100, 0, 0, 0, 4428, 3, 'Baleroc - Berserk (Emote)'),
(53494, 8, 0, '|TInterface\\Icons\\spell_shadow_curse.blp:20|t%s readies his |cFF7A0080|Hspell:99352|h[Decimation Blade]|h|r!', 41, 0, 100, 0, 0, 0, 52889, 3, 'Baleroc - Decimation Blade (Emote)'),
(53494, 9, 0, '|TInterface\\Icons\\inv_sword_09.blp:20|t%s readies his |cFFFF0000|Hspell:99350|h[Inferno Blade]|h|r!', 41, 0, 100, 0, 0, 0, 52890, 3, 'Baleroc - Inferno Blade (Emote)');
DELETE FROM `criteria_data` WHERE `criteria_id`=17577;
INSERT INTO `criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES (17577, 11, 0, 0, 'achievement_share_the_pain');
DELETE FROM `linked_respawn` WHERE `guid` IN (317642,317652,317657,339198,339284,339285); -- guid is unique, not linkedGuid
INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`) VALUES
(317642, 338782, 0),
(317652, 338782, 0),
(317657, 338782, 0),
(339198, 338782, 0),
(339284, 338782, 0),
(339285, 338782, 0);
-- Normal shared items
DELETE FROM `reference_loot_template` WHERE `Entry`=34380;
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(34380, 71782, 0, 16, 0, 1, 1, 1, 1, 'Normal - Shatterskull Bonecrusher'),
(34380, 71775, 0, 16, 0, 1, 1, 1, 1, 'Normal - Smoldering Censer of Purity'),
(34380, 71776, 0, 16, 0, 1, 1, 1, 1, 'Normal - Eye of Purification'),
(34380, 71780, 0, 13, 0, 1, 1, 1, 1, 'Normal - Zoid''s Firelit Greatsword'),
(34380, 71779, 0, 11, 0, 1, 1, 1, 1, 'Normal - Avool''s Incendiary Shanker'),
(34380, 71787, 0, 11, 0, 1, 1, 1, 1, 'Normal - Entrail Disgorger'),
(34380, 71785, 0, 17, 0, 1, 1, 1, 1, 'Normal - Firethorn Mindslicer');
-- Heroic shared items
DELETE FROM `reference_loot_template` WHERE `Entry`=34381;
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(34381, 71783, 0, 15, 0, 1, 1, 1, 1, 'Heroic - Shatterskull Bonecrusher'),
(34381, 71774, 0, 15, 0, 1, 1, 1, 1, 'Heroic - Smoldering Censer of Purity'),
(34381, 71777, 0, 15, 0, 1, 1, 1, 1, 'Heroic - Eye of Purification'),
(34381, 71781, 0, 12, 0, 1, 1, 1, 1, 'Heroic - Zoid''s Firelit Greatsword'),
(34381, 71778, 0, 11, 0, 1, 1, 1, 1, 'Heroic - Avool''s Incendiary Shanker'),
(34381, 71786, 0, 11, 0, 1, 1, 1, 1, 'Heroic - Entrail Disgorger'),
(34381, 71784, 0, 16, 0, 1, 1, 1, 1, 'Heroic - Firethorn Mindslicer'),
(34381, 71617, 0, 5, 0, 1, 1, 1, 1, 'Heroic - Crystallized Firestone');
-- Baleroc normal
DELETE FROM `reference_loot_template` WHERE `Entry`=34385;
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(34385, 68982, 0, 12, 0, 1, 1, 1, 1, 'Normal - Necromantic Focus'),
(34385, 71343, 0, 10, 0, 1, 1, 1, 1, 'Normal - Mantle of Closed Doors'),
(34385, 70917, 0, 8, 0, 1, 1, 1, 1, 'Normal - Flickering Handguards'),
(34385, 71323, 0, 8, 0, 1, 1, 1, 1, 'Normal - Molten Scream'),
(34385, 71315, 0, 7, 0, 1, 1, 1, 1, 'Normal - Decimation Treads'),
(34385, 71345, 0, 7, 0, 1, 1, 1, 1, 'Normal - Shoulderpads of the Forgotten Gate'),
(34385, 71314, 0, 7, 0, 1, 1, 1, 1, 'Normal - Breastplate of the Incendiary Soul'),
(34385, 71312, 0, 7, 0, 1, 1, 1, 1, 'Normal - Gatecrasher'),
(34385, 71342, 0, 6, 0, 1, 1, 1, 1, 'Normal - Casque of Flame'),
(34385, 71340, 0, 6, 0, 1, 1, 1, 1, 'Normal - Gatekeeper''s Embrace'),
(34385, 71341, 0, 6, 0, 1, 1, 1, 1, 'Normal - Glowing Wing Bracers'),
(34385, 70915, 0, 6, 0, 1, 1, 1, 1, 'Normal - Shard of Torment'),
(34385, 70916, 0, 5, 0, 1, 1, 1, 1, 'Normal - Helm of Blazing Glory'),
(34385, 1, 34380, 5, 0, 1, 0, 1, 1, 'Normal - Shared loot table');
-- Baleroc heroic
DELETE FROM `reference_loot_template` WHERE `Entry`=34386;
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(34386, 69139, 0, 12, 0, 1, 1, 1, 1, 'Heroic - Necromantic Focus'),
(34386, 71461, 0, 10, 0, 1, 1, 1, 1, 'Heroic - Mantle of Closed Doors'),
(34386, 71458, 0, 8, 0, 1, 1, 1, 1, 'Heroic - Flickering Handguards'),
(34386, 71462, 0, 8, 0, 1, 1, 1, 1, 'Heroic - Molten Scream'),
(34386, 71457, 0, 7, 0, 1, 1, 1, 1, 'Heroic - Decimation Treads'),
(34386, 71456, 0, 7, 0, 1, 1, 1, 1, 'Heroic - Shoulderpads of the Forgotten Gate'),
(34386, 71455, 0, 7, 0, 1, 1, 1, 1, 'Heroic - Breastplate of the Incendiary Soul'),
(34386, 71454, 0, 7, 0, 1, 1, 1, 1, 'Heroic - Gatecrasher'),
(34386, 71465, 0, 6, 0, 1, 1, 1, 1, 'Heroic - Casque of Flame'),
(34386, 71464, 0, 6, 0, 1, 1, 1, 1, 'Heroic - Gatekeeper''s Embrace'),
(34386, 71463, 0, 6, 0, 1, 1, 1, 1, 'Heroic - Glowing Wing Bracers'),
(34386, 71460, 0, 6, 0, 1, 1, 1, 1, 'Heroic - Shard of Torment'),
(34386, 71459, 0, 5, 0, 1, 1, 1, 1, 'Heroic - Helm of Blazing Glory'),
(34386, 1, 34381, 5, 0, 1, 0, 1, 1, 'Heroic - Shared loot table');
-- Baleroc heroic tokens
DELETE FROM `reference_loot_template` WHERE `Entry`=34387;
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(34387, 71669, 0, 40, 0, 1, 1, 1, 1, 'Heroic - Gauntlets of the Fiery Vanquisher'),
(34387, 71676, 0, 30, 0, 1, 1, 1, 1, 'Heroic - Gauntlets of the Fiery Conqueror'),
(34387, 71683, 0, 30, 0, 1, 1, 1, 1, 'Heroic - Gauntlets of the Fiery Protector');
DELETE FROM `spell_script_names` WHERE `spell_id` IN (100799,99342,99350,99352,99353,99515,99516,99517,99259,99253,99256,99257,99489,99263,99262);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(100799, 'spell_firelands_fiery_torment'),
(99342, 'spell_baleroc_blades_of_baleroc'),
(99350, 'spell_baleroc_inferno_blade'),
(99352, 'spell_baleroc_decimation_blade'),
(99353, 'spell_baleroc_decimating_strike'),
(99515, 'spell_baleroc_countdown_aoe_dummy'),
(99516, 'spell_baleroc_countdown'),
(99517, 'spell_baleroc_countdown_proximity_check'),
(99259, 'spell_baleroc_shards_of_torment_target_search'),
(99253, 'spell_baleroc_torment_target_search'),
(99256, 'spell_baleroc_torment'),
(99257, 'spell_baleroc_tormented'),
(99489, 'spell_baleroc_tormented_spread'),
(99263, 'spell_baleroc_vital_flame'),
(99262, 'spell_baleroc_vital_spark');
-- Firelands Spells
DELETE FROM `spell_script_names` WHERE `spell_id` IN (101089,101092,101093);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(101089, 'spell_firelands_smouldering'),
(101092, 'spell_firelands_smouldering'),
(101093, 'spell_firelands_smouldering_aura');
DELETE FROM `spell_proc` WHERE `SpellId`=99262;
INSERT INTO `spell_proc` (`SpellId`,`SpellTypeMask`,`SpellPhaseMask`) VALUES
(99262,2,2);

View File

@@ -3676,6 +3676,28 @@ void SpellMgr::LoadSpellInfoCorrections()
});
// ENDOF ISLE OF CONQUEST SPELLS
//
// FIRELANDS SPELLS
//
// Torment Searcher
ApplySpellFix({ 99253 }, [](SpellInfo* spellInfo)
{
const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_15_YARDS);
});
// Torment Damage
ApplySpellFix({ 99256 }, [](SpellInfo* spellInfo)
{
spellInfo->Attributes |= SPELL_ATTR0_NEGATIVE_1;
});
// Blaze of Glory
ApplySpellFix({ 99252 }, [](SpellInfo* spellInfo)
{
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
});
// ENDOF FIRELANDS SPELLS
// Summon Master Li Fei
ApplySpellFix({ 102445 }, [](SpellInfo* spellInfo)
{

View File

@@ -0,0 +1,874 @@
/*
* Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "Containers.h"
#include "firelands.h"
#include "GridNotifiers.h"
#include "PassiveAI.h"
#include "Spell.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
enum Spells
{
// Baleroc
//SPELL_LEASH = 101514, // Server-side, used to keep him in his encounter area? TrinityCore does not need a spell to handle this
SPELL_BLADES_OF_BALEROC = 99342,
SPELL_INFERNO_BLADE = 99350,
SPELL_INFERNO_STRIKE = 99351,
SPELL_DECIMATION_BLADE = 99352,
SPELL_DECIMATION_BLADE_2 = 99405,
SPELL_DECIMATING_STRIKE = 99353,
SPELL_BLAZE_OF_GLORY = 99252,
SPELL_INCENDIARY_SOUL = 99369,
SPELL_SHARDS_OF_TORMENT = 99259,
SPELL_SHARDS_OF_TORMENT_SUMMON = 99260,
SPELL_TORMENT_PRE_VISUAL = 99258,
SPELL_TORMENT_ACTIVE = 99254,
SPELL_TORMENT_PERIODIC = 99255,
SPELL_WAVE_OF_TORMENT = 99261,
SPELL_TORMENTED = 99257,
SPELL_TORMENT = 99256,
SPELL_COUNTDOWN = 99515,
SPELL_COUNTDOWN_AURA = 99516,
SPELL_COUNTDOWN_3 = 99517,
SPELL_COUNTDOWN_AOE_EXPLOSION = 99518,
SPELL_COUNTDOWN_VISUAL_LINK = 99519,
SPELL_VITAL_SPARK = 99262,
SPELL_VITAL_FLAME = 99263,
SPELL_BERSERK = 26662,
};
enum Emotes
{
SAY_AGGRO = 0,
SAY_SHARDS_OF_TORMENT = 1,
SAY_INFERNO_BLADE = 2,
SAY_DECIMATION_BLADE = 3,
SAY_KILL = 4,
SAY_DEATH = 5,
SAY_ENRAGE = 6,
EMOTE_ENRAGE = 7,
EMOTE_DECIMATION_BLADE = 8,
EMOTE_INFERNO_BLADE = 9,
};
enum Guids
{
GUID_TORMENTED = 1,
};
enum Actions
{
ACTION_EQUIP_DEFAULT = 1,
ACTION_EQUIP_INFERNO_BLADE = 2,
ACTION_EQUIP_DECIMATION_BLADE = 3,
};
enum Misc
{
EQUIP_DEFAULT = 1,
EQUIP_INFERNO_BLADE = 2,
EQUIP_DECIMATION_BLADE = 3,
};
enum Phases
{
PHASE_NONE = 0,
PHASE_ONE = 1
};
// http://www.wowhead.com/npc=53494/baleroc
struct boss_baleroc : public firelands_bossAI
{
boss_baleroc(Creature* creature) : firelands_bossAI(creature, DATA_BALEROC), _canYellKilledPlayer(true)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void Reset() override
{
firelands_bossAI::Reset();
_canYellKilledPlayer = true;
EquipWeapon(EQUIP_DEFAULT);
}
void EnterCombat(Unit* target) override
{
firelands_bossAI::EnterCombat(target);
Talk(SAY_AGGRO);
PreparePhase(PHASE_ONE);
_sharedThePain.clear();
}
void PreparePhase(Phases phase)
{
//events.SetPhase(phase);
switch (phase)
{
case PHASE_ONE:
scheduler.Schedule(Milliseconds(8500), [this](TaskContext context)
{
me->AddAura(SPELL_INCENDIARY_SOUL, me); // No cast
DoCastVictim(SPELL_BLAZE_OF_GLORY);
context.Repeat(Milliseconds(11500));
});
scheduler.Schedule(Seconds(5), [this](TaskContext context)
{
DoCastAOE(SPELL_SHARDS_OF_TORMENT);
context.Repeat(Seconds(34));
});
if (me->GetMap()->IsHeroic())
{
scheduler.Schedule(Seconds(26), [this](TaskContext context)
{
DoCastAOE(SPELL_COUNTDOWN);
context.Repeat(Seconds(48));
});
}
scheduler.Schedule(Milliseconds(30500), [this](TaskContext context)
{
DoCastSelf(SPELL_BLADES_OF_BALEROC);
context.Repeat(Seconds(47));
});
scheduler.Schedule(Minutes(6), [this](TaskContext)
{
Talk(SAY_ENRAGE);
Talk(EMOTE_ENRAGE);
DoCastSelf(SPELL_BERSERK);
});
break;
default:
break;
}
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_EQUIP_DEFAULT:
case ACTION_EQUIP_INFERNO_BLADE:
case ACTION_EQUIP_DECIMATION_BLADE:
EquipWeapon(action);
break;
default:
break;
}
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER && _canYellKilledPlayer)
{
_canYellKilledPlayer = false;
Talk(SAY_KILL);
separateScheduler.Schedule(Seconds(8), [this](TaskContext)
{
_canYellKilledPlayer = true;
});
}
}
void JustDied(Unit* killer) override
{
Talk(SAY_DEATH);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLAZE_OF_GLORY);
firelands_bossAI::JustDied(killer);
}
void EnterEvadeMode(EvadeReason reason) override
{
summons.DespawnAll();
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLAZE_OF_GLORY);
firelands_bossAI::EnterEvadeMode(reason);
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
separateScheduler.Update(diff);
firelands_bossAI::UpdateAI(diff);
}
void SetGUID(ObjectGuid guid, int32 type = 0) override
{
switch (type)
{
case GUID_TORMENTED:
++_sharedThePain[guid];
break;
default:
break;
}
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case GUID_TORMENTED:
for (auto const& entry : _sharedThePain)
if (entry.second > 3)
return 1;
break;
default:
break;
}
return 0;
}
private:
void EquipWeapon(uint8 equipment) const
{
switch (equipment)
{
case EQUIP_DEFAULT:
me->LoadEquipment(equipment);
me->SetCanDualWield(true);
break;
case EQUIP_INFERNO_BLADE:
case EQUIP_DECIMATION_BLADE:
me->LoadEquipment(equipment);
me->SetCanDualWield(false);
break;
default:
break;
}
}
// Our default TaskScheduler has a UNIT_STATE_CASTING validator that would get in the way of certain tasks, run them on a separate track.
TaskScheduler separateScheduler;
bool _canYellKilledPlayer;
std::unordered_map<ObjectGuid, uint32> _sharedThePain;
};
// http://www.wowhead.com/npc=53495/shard-of-torment
struct npc_shard_of_torment : public NullCreatureAI
{
npc_shard_of_torment(Creature* creature) : NullCreatureAI(creature) { }
void IsSummonedBy(Unit* /*summoner*/) override
{
DoCastAOE(SPELL_TORMENT_PRE_VISUAL);
scheduler.Schedule(Milliseconds(4400), [this](TaskContext)
{
me->RemoveAurasDueToSpell(SPELL_TORMENT_PRE_VISUAL);
DoCastAOE(SPELL_TORMENT_ACTIVE);
scheduler.Schedule(Milliseconds(1100), [this](TaskContext context)
{
DoCastAOE(SPELL_WAVE_OF_TORMENT);
context.Repeat(Seconds(1));
});
});
}
void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) override
{
if (spell->Id != SPELL_TORMENT)
return;
scheduler.CancelAll();
scheduler.Schedule(Milliseconds(1100), [this](TaskContext context)
{
DoCastAOE(SPELL_WAVE_OF_TORMENT);
context.Repeat(Seconds(1));
});
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
TaskScheduler scheduler;
};
// http://www.wowhead.com/spell=99342/blades-of-baloroc
class spell_baleroc_blades_of_baleroc : public SpellScript
{
PrepareSpellScript(spell_baleroc_blades_of_baleroc);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_INFERNO_BLADE, SPELL_DECIMATION_BLADE });
}
void ChooseBlade(SpellEffIndex /*effIndex*/)
{
Creature* caster = GetCaster()->ToCreature();
if (!caster || !caster->IsAIEnabled)
return;
switch (urand(1, 2))
{
case 1:
caster->AI()->DoCast(SPELL_INFERNO_BLADE);
caster->AI()->Talk(SAY_INFERNO_BLADE);
caster->AI()->Talk(EMOTE_INFERNO_BLADE);
break;
case 2:
caster->AI()->DoCast(SPELL_DECIMATION_BLADE);
caster->AI()->Talk(SAY_DECIMATION_BLADE);
caster->AI()->Talk(EMOTE_DECIMATION_BLADE);
break;
default:
break;
}
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_baleroc_blades_of_baleroc::ChooseBlade, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// http://www.wowhead.com/spell=99350/inferno-blade
class spell_baleroc_inferno_blade : public AuraScript
{
PrepareAuraScript(spell_baleroc_inferno_blade);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->IsAIEnabled)
GetTarget()->GetAI()->DoAction(ACTION_EQUIP_INFERNO_BLADE);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->IsAIEnabled)
GetTarget()->GetAI()->DoAction(ACTION_EQUIP_DEFAULT);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_baleroc_inferno_blade::OnApply, EFFECT_0, SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_MELEE_SPELL, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_baleroc_inferno_blade::OnRemove, EFFECT_0, SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_MELEE_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
// http://www.wowhead.com/spell=99352/decimation-blade
class spell_baleroc_decimation_blade : public AuraScript
{
PrepareAuraScript(spell_baleroc_decimation_blade);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->IsAIEnabled)
GetTarget()->GetAI()->DoAction(ACTION_EQUIP_DECIMATION_BLADE);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->IsAIEnabled)
GetTarget()->GetAI()->DoAction(ACTION_EQUIP_DEFAULT);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_baleroc_decimation_blade::OnApply, EFFECT_1, SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_MELEE_SPELL, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_baleroc_decimation_blade::OnRemove, EFFECT_1, SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_MELEE_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
// http://www.wowhead.com/spell=99353/decimating-strike
class spell_baleroc_decimating_strike : public SpellScript
{
PrepareSpellScript(spell_baleroc_decimating_strike);
bool Validate(SpellInfo const* spellInfo) override
{
if (!spellInfo->GetEffect(EFFECT_0))
return false;
SpellEffectInfo const* spellEffectInfo = spellInfo->GetEffect(EFFECT_2);
return spellEffectInfo && ValidateSpellInfo({ uint32(spellEffectInfo->BasePoints) });
}
void ChangeDamage()
{
int32 healthPctDmg = GetHitUnit()->CountPctFromMaxHealth(GetSpellInfo()->GetEffect(EFFECT_0)->BasePoints);
int32 flatDmg = GetSpellInfo()->GetEffect(EFFECT_2)->BasePoints;
SetHitDamage(healthPctDmg < flatDmg ? flatDmg : healthPctDmg);
}
void Register() override
{
OnHit += SpellHitFn(spell_baleroc_decimating_strike::ChangeDamage);
}
};
// http://www.wowhead.com/spell=99515/countdown
class spell_baleroc_countdown_aoe_dummy : public SpellScript
{
PrepareSpellScript(spell_baleroc_countdown_aoe_dummy);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_COUNTDOWN_VISUAL_LINK, SPELL_COUNTDOWN_AURA });
}
void CastSpellLink()
{
Unit* firstTarget = ObjectAccessor::GetUnit(*GetCaster(), _targets.front());
Unit* secondTarget = ObjectAccessor::GetUnit(*GetCaster(), _targets.back());
if (!firstTarget || !secondTarget)
return;
firstTarget->CastSpell(secondTarget, SPELL_COUNTDOWN_VISUAL_LINK, true);
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_COUNTDOWN_AURA);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
Creature* caster = GetCaster()->ToCreature();
if (!caster)
return;
if (WorldObject* tank = caster->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO))
targets.remove(tank);
if (targets.size() < 2)
{
FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
return;
}
Trinity::Containers::RandomResize(targets, 2);
_targets.push_back(targets.front()->GetGUID());
_targets.push_back(targets.back()->GetGUID());
}
void Register() override
{
AfterCast += SpellCastFn(spell_baleroc_countdown_aoe_dummy::CastSpellLink);
OnEffectHitTarget += SpellEffectFn(spell_baleroc_countdown_aoe_dummy::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_baleroc_countdown_aoe_dummy::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
GuidList _targets;
};
// http://www.wowhead.com/spell=99516/countdown
class spell_baleroc_countdown : public AuraScript
{
PrepareAuraScript(spell_baleroc_countdown);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_COUNTDOWN_VISUAL_LINK, SPELL_COUNTDOWN_AOE_EXPLOSION });
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetTarget()->RemoveAurasDueToSpell(SPELL_COUNTDOWN_VISUAL_LINK);
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
GetTarget()->CastSpell(static_cast<Unit*>(nullptr), SPELL_COUNTDOWN_AOE_EXPLOSION, true);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_baleroc_countdown::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
// http://www.wowhead.com/spell=99517/countdown
class spell_baleroc_countdown_proximity_check : public SpellScript
{
PrepareSpellScript(spell_baleroc_countdown_proximity_check);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_COUNTDOWN_AURA });
}
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetCaster()->RemoveAurasDueToSpell(SPELL_COUNTDOWN_AURA);
GetHitUnit()->RemoveAurasDueToSpell(SPELL_COUNTDOWN_AURA);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove(GetCaster());
targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_COUNTDOWN_AURA));
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_baleroc_countdown_proximity_check::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_baleroc_countdown_proximity_check::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
// http://www.wowhead.com/spell=99259/shards-of-torment
class spell_baleroc_shards_of_torment_target_search : public SpellScript
{
PrepareSpellScript(spell_baleroc_shards_of_torment_target_search);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SHARDS_OF_TORMENT_SUMMON });
}
bool Load() override
{
_hasTarget = false;
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void OnSpellCast()
{
if (_hasTarget)
ENSURE_AI(boss_baleroc, GetCaster()->GetAI())->Talk(SAY_SHARDS_OF_TORMENT);
}
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetCaster()->CastSpell(GetHitUnit(), SPELL_SHARDS_OF_TORMENT_SUMMON, true);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
// Shards of torment seems to target tanks if no other targets are available as of Warlords of Draenor
if (targets.size() <= 1)
{
_hasTarget = !targets.empty();
return;
}
Creature* caster = GetCaster()->ToCreature();
if (!caster || !caster->IsAIEnabled)
return;
if (WorldObject* tank = caster->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO))
targets.remove(tank);
std::list<WorldObject*> melee, ranged;
for (WorldObject* target : targets)
{
if (caster->IsWithinMeleeRange(target->ToUnit()))
melee.push_back(target);
else
ranged.push_back(target);
}
targets.clear();
if (caster->GetMap()->Is25ManRaid())
if (WorldObject* target = GetRandomContainerElement(ranged, melee))
targets.push_back(target);
if (WorldObject* target = GetRandomContainerElement(melee, ranged))
targets.push_back(target);
_hasTarget = !targets.empty();
}
WorldObject* GetRandomContainerElement(std::list<WorldObject*>& priority1, std::list<WorldObject*>& priority2) const
{
WorldObject* target = nullptr;
target = GetRandomContainerElement(&priority1);
if (target)
priority1.remove(target);
else
{
target = GetRandomContainerElement(&priority2);
priority2.remove(target);
}
return target;
}
static WorldObject* GetRandomContainerElement(std::list<WorldObject*> const* list)
{
if (!list->empty())
return Trinity::Containers::SelectRandomContainerElement(*list);
return nullptr;
}
void Register() override
{
OnCast += SpellCastFn(spell_baleroc_shards_of_torment_target_search::OnSpellCast);
OnEffectHitTarget += SpellEffectFn(spell_baleroc_shards_of_torment_target_search::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_baleroc_shards_of_torment_target_search::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
bool _hasTarget;
};
// http://www.wowhead.com/spell=99253/torment
class spell_baleroc_torment_target_search : public SpellScript
{
PrepareSpellScript(spell_baleroc_torment_target_search);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TORMENT_PERIODIC });
}
void OnHit(SpellEffIndex /*effIndex*/)
{
Spell* spell = GetCaster()->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
if (spell && spell->m_targets.GetUnitTargetGUID() == _target)
return;
if (GetHitUnit()->GetGUID() == _target)
GetCaster()->CastSpell(GetHitUnit(), SPELL_TORMENT_PERIODIC);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(PlayerCheck());
if (targets.empty())
return;
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
_target = targets.front()->GetGUID();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_baleroc_torment_target_search::OnHit, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_baleroc_torment_target_search::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
ObjectGuid _target;
};
// http://www.wowhead.com/spell=99256/torment
class spell_baleroc_torment : public SpellScript
{
PrepareSpellScript(spell_baleroc_torment);
void ModifyDamage()
{
SetHitDamage(GetHitDamage() * GetHitUnit()->GetAuraCount(GetSpellInfo()->Id));
}
void Register() override
{
OnHit += SpellHitFn(spell_baleroc_torment::ModifyDamage);
}
};
class spell_baleroc_torment_AuraScript : public AuraScript
{
PrepareAuraScript(spell_baleroc_torment_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_VITAL_FLAME, SPELL_VITAL_SPARK, SPELL_TORMENTED });
}
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
Unit* healer = eventInfo.GetProcTarget();
if (healer->HasAura(SPELL_VITAL_FLAME))
return;
bool Is25ManHeroic = healer->GetMap()->IsHeroic() && healer->GetMap()->Is25ManRaid();
uint32 stacks = healer->GetAuraCount(SPELL_VITAL_SPARK) + std::min(uint8(ceil(GetStackAmount() / (Is25ManHeroic ? 5 : 3))), uint8(255));
healer->SetAuraStack(SPELL_VITAL_SPARK, healer, stacks);
healer->GetAura(SPELL_VITAL_SPARK)->RefreshDuration();
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
GetTarget()->CastSpell(GetTarget(), SPELL_TORMENTED, true);
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_baleroc_torment_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
OnEffectRemove += AuraEffectRemoveFn(spell_baleroc_torment_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// http://www.wowhead.com/spell=99257/tormented
class spell_baleroc_tormented : public AuraScript
{
PrepareAuraScript(spell_baleroc_tormented);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (InstanceScript* instance = GetTarget()->GetInstanceScript())
if (Creature* baleroc = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_BALEROC)))
baleroc->AI()->SetGUID(GetTarget()->GetGUID(), GUID_TORMENTED);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_baleroc_tormented::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
// http://www.wowhead.com/spell=99489/tormented
class spell_baleroc_tormented_spread : public SpellScript
{
PrepareSpellScript(spell_baleroc_tormented_spread);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TORMENTED });
}
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_TORMENTED, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_baleroc_tormented_spread::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// http://www.wowhead.com/spell=99262/vital-spark
class spell_baleroc_vital_spark : public AuraScript
{
PrepareAuraScript(spell_baleroc_vital_spark);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BLAZE_OF_GLORY, SPELL_VITAL_FLAME });
}
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
if (Unit* target = eventInfo.GetProcTarget())
if (target->HasAura(SPELL_BLAZE_OF_GLORY))
GetCaster()->CastSpell(GetCaster(), SPELL_VITAL_FLAME, true);
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_baleroc_vital_spark::HandleProc, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
// http://www.wowhead.com/spell=99263/vital-flame
class spell_baleroc_vital_flame : public AuraScript
{
PrepareAuraScript(spell_baleroc_vital_flame);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_VITAL_SPARK });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (!GetCaster()->HasAura(SPELL_VITAL_SPARK))
{
stacks = 0;
return;
}
stacks = GetCaster()->GetAuraCount(SPELL_VITAL_SPARK);
int32 healingPct = sSpellMgr->AssertSpellInfo(SPELL_VITAL_SPARK)->GetEffect(EFFECT_0)->BasePoints * stacks;
if (GetAura()->GetEffect(EFFECT_0)->GetAmount() < healingPct)
GetAura()->GetEffect(EFFECT_0)->SetAmount(healingPct);
GetCaster()->RemoveAura(SPELL_VITAL_SPARK);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
GetCaster()->SetAuraStack(SPELL_VITAL_SPARK, GetCaster(), stacks);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_baleroc_vital_flame::OnApply, EFFECT_0, SPELL_AURA_359, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_baleroc_vital_flame::OnRemove, EFFECT_0, SPELL_AURA_359, AURA_EFFECT_HANDLE_REAL);
}
uint32 stacks;
};
// http://www.wowhead.com/achievement=5830/share-the-pain //17577
class achievement_share_the_pain : public AchievementCriteriaScript
{
public:
achievement_share_the_pain() : AchievementCriteriaScript("achievement_share_the_pain") { }
bool OnCheck(Player* /*source*/, Unit* target) override
{
if (!target)
return false;
return target->GetAI()->GetData(GUID_TORMENTED) == 0;
}
};
void AddSC_boss_baleroc()
{
RegisterFirelandsAI(boss_baleroc);
RegisterFirelandsAI(npc_shard_of_torment);
RegisterSpellScript(spell_baleroc_blades_of_baleroc);
RegisterAuraScript(spell_baleroc_inferno_blade);
RegisterAuraScript(spell_baleroc_decimation_blade);
RegisterSpellScript(spell_baleroc_decimating_strike);
RegisterSpellScript(spell_baleroc_countdown_aoe_dummy);
RegisterAuraScript(spell_baleroc_countdown);
RegisterSpellScript(spell_baleroc_countdown_proximity_check);
RegisterSpellScript(spell_baleroc_shards_of_torment_target_search);
RegisterSpellScript(spell_baleroc_torment_target_search);
RegisterSpellAndAuraScriptPair(spell_baleroc_torment, spell_baleroc_torment_AuraScript);
RegisterAuraScript(spell_baleroc_tormented);
RegisterSpellScript(spell_baleroc_tormented_spread);
RegisterAuraScript(spell_baleroc_vital_spark);
RegisterAuraScript(spell_baleroc_vital_flame);
new achievement_share_the_pain();
};

View File

@@ -15,12 +15,326 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "firelands.h"
#include "ScriptMgr.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "firelands.h"
#include "GridNotifiers.h"
#include "Vehicle.h"
enum Spells
{
// Baleroc Trash
SPELL_FLAME_TORRENT = 100795,
SPELL_FIERY_TORMENT = 100797,
SPELL_FIERY_TORMENT_DAMAGE = 100802,
SPELL_EARTHQUAKE = 100724,
SPELL_MAGMA_CONDUIT = 100728,
SPELL_ERUPTION = 100755,
SPELL_SUMMON_MAGMAKIN = 100746,
// Legendary questline
SPELL_SMOULDERING_QUEST_CHECK_A = 101089, // Alliance - Unverified
SPELL_SMOULDERING_QUEST_CHECK_H = 101092 // Horde - Unverified
};
bool DelayedAttackStartEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
_owner->AI()->DoZoneInCombat(_owner, 200.0f);
return true;
}
bool DelayedSpellCastEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
_owner->CastSpell(_target, _spellId, _triggered);
return true;
}
void firelands_bossAI::EnterCombat(Unit* target)
{
BossAI::EnterCombat(target);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
}
void firelands_bossAI::JustDied(Unit* killer)
{
BossAI::JustDied(killer);
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
me->m_Events.AddEvent(new DelayedSpellCastEvent(me, static_cast<Unit*>(nullptr), SPELL_SMOULDERING_1, false), me->m_Events.CalculateTime(2 * IN_MILLISECONDS));
me->m_Events.AddEvent(new DelayedSpellCastEvent(me, static_cast<Unit*>(nullptr), SPELL_SMOULDERING_2, false), me->m_Events.CalculateTime(2 * IN_MILLISECONDS));
}
void firelands_bossAI::EnterEvadeMode(EvadeReason why)
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
// Copy paste ScriptedAI::EnterEvadeMode functionality to exclude Reset function call
if (!_EnterEvadeMode(why))
return;
if (!me->GetVehicle()) // otherwise me will be in evade mode forever
{
if (Unit* owner = me->GetCharmerOrOwner())
{
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
}
else
{
// Required to prevent attacking creatures that are evading and cause them to reenter combat
// Does not apply to MoveFollow
me->AddUnitState(UNIT_STATE_EVADE);
me->GetMotionMaster()->MoveTargetedHome();
}
}
// Copy paste reason
//Reset();
if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
me->GetVehicleKit()->Reset(true);
_DespawnAtEvade();
}
// http://www.wowhead.com/npc=54161/flame-archon
struct npc_firelands_flame_archon : public ScriptedAI
{
npc_firelands_flame_archon(Creature* creature) : ScriptedAI(creature)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void EnterCombat(Unit* /*attacker*/) override
{
scheduler.Schedule(Seconds(10), Seconds(12), [this](TaskContext context)
{
DoCastAOE(SPELL_FLAME_TORRENT);
context.Repeat(Seconds(15), Seconds(17));
});
scheduler.Schedule(Seconds(25), [this](TaskContext context)
{
DoCastAOE(SPELL_FIERY_TORMENT);
context.Repeat(Seconds(45));
});
}
void JustDied(Unit* killer) override
{
scheduler.CancelAll();
ScriptedAI::JustDied(killer);
}
void EnterEvadeMode(EvadeReason why) override
{
scheduler.CancelAll();
ScriptedAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
TaskScheduler scheduler;
};
// http://www.wowhead.com/npc=54143/molten-flamefather
struct npc_firelands_molten_flamefather : public ScriptedAI
{
npc_firelands_molten_flamefather(Creature* creature) : ScriptedAI(creature)
{
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void JustSummoned(Creature* summon) override
{
if (summon->GetEntry() != NPC_MAGMA_CONDUIT)
return;
summon->CastSpell(summon, SPELL_SUMMON_MAGMAKIN);
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
if (summon->GetEntry() != NPC_MAGMA_CONDUIT)
return;
summon->DespawnOrUnsummon();
}
void EnterCombat(Unit* /*attacker*/) override
{
scheduler.Schedule(Seconds(5), [this](TaskContext context)
{
DoCastAOE(SPELL_MAGMA_CONDUIT);
if (Is25ManRaid())
DoCastAOE(SPELL_MAGMA_CONDUIT);
context.Repeat(Seconds(25));
});
scheduler.Schedule(Milliseconds(12800), [this](TaskContext context)
{
DoCastAOE(SPELL_EARTHQUAKE);
context.Repeat(Milliseconds(32500));
});
}
void JustDied(Unit* killer) override
{
scheduler.CancelAll();
ScriptedAI::JustDied(killer);
}
void EnterEvadeMode(EvadeReason why) override
{
scheduler.CancelAll();
ScriptedAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
TaskScheduler scheduler;
};
// http://www.wowhead.com/npc=54144/magmakin
struct npc_firelands_magmakin : public ScriptedAI
{
npc_firelands_magmakin(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(Unit* /*summoner*/) override
{
//Not actually sniffed behavior
Unit* target = me->SelectNearestTarget(50.0f, true);
if (!target)
return;
me->AddThreat(target, 50000000.0f);
me->TauntApply(target);
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoSpellAttackIfReady(SPELL_ERUPTION);
}
};
// http://www.wowhead.com/spell=100799/fiery-torment
class spell_firelands_fiery_torment : public SpellScript
{
PrepareSpellScript(spell_firelands_fiery_torment);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FIERY_TORMENT_DAMAGE });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_FIERY_TORMENT_DAMAGE, true);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), true));
targets.resize(1);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_firelands_fiery_torment::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_firelands_fiery_torment::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
// http://www.wowhead.com/spell=101089/smouldering
// http://www.wowhead.com/spell=101092/smouldering
class spell_firelands_smouldering : public SpellScript
{
PrepareSpellScript(spell_firelands_smouldering);
void CheckQuestStatus(std::list<WorldObject*>& targets)
{
uint32 questId = 0;
switch (GetSpellInfo()->Id)
{
case SPELL_SMOULDERING_QUEST_CHECK_A:
questId = QUEST_HEART_OF_FLAME_A;
break;
case SPELL_SMOULDERING_QUEST_CHECK_H:
questId = QUEST_HEART_OF_FLAME_H;
break;
default:
break;
}
bool raidHasQuest = targets.end() != std::find_if(targets.begin(), targets.end(), [questId](WorldObject* worldObject)
{
if (Player* player = worldObject->ToPlayer())
if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
return true;
return false;
});
targets.clear();
if (raidHasQuest)
targets.push_back(GetCaster());
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_firelands_smouldering::CheckQuestStatus, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
// http://www.wowhead.com/spell=101093/smouldering
class spell_firelands_smouldering_aura : public SpellScript
{
PrepareSpellScript(spell_firelands_smouldering_aura);
void SetTarget(WorldObject*& target)
{
target = GetCaster();
}
void Register() override
{
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_firelands_smouldering_aura::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
}
};
void AddSC_firelands()
{
RegisterFirelandsAI(npc_firelands_flame_archon);
RegisterFirelandsAI(npc_firelands_molten_flamefather);
RegisterFirelandsAI(npc_firelands_magmakin);
RegisterSpellScript(spell_firelands_fiery_torment);
RegisterSpellScript(spell_firelands_smouldering);
RegisterSpellScript(spell_firelands_smouldering_aura);
}

View File

@@ -20,6 +20,7 @@
#include "CreatureAIImpl.h"
#include "EventProcessor.h"
#include "ScriptedCreature.h"
class Creature;
@@ -41,12 +42,43 @@ enum FLDataTypes
enum FLCreatureIds
{
// Bosses
NPC_SHANNOX = 53691,
NPC_LORD_RHYOLITH = 52558,
NPC_BETH_TILAC = 52498,
NPC_ALYSRAZOR = 52530,
NPC_BALEROC = 53494,
NPC_MAJORDOMO_STAGHELM = 52571,
NPC_RAGNAROS = 52409,
// Alysrazor
NPC_BLAZING_MONSTROSITY_LEFT = 53786,
NPC_BLAZING_MONSTROSITY_RIGHT = 53791,
NPC_EGG_PILE = 53795,
NPC_HARBINGER_OF_FLAME = 53793,
NPC_MOLTEN_EGG_TRASH = 53914,
NPC_SMOULDERING_HATCHLING = 53794,
// Baleroc
NPC_MAGMA_CONDUIT = 54145,
NPC_MAGMAKIN = 54144
};
enum GameobjectIds
{
GO_BALEROC_FIREWALL = 209066
};
enum FirelandsSpells
{
SPELL_SMOULDERING_1 = 101089,
SPELL_SMOULDERING_2 = 101092,
};
enum FirelandsQuests
{
QUEST_HEART_OF_FLAME_A = 29307,
QUEST_HEART_OF_FLAME_H = 29308
};
class DelayedAttackStartEvent : public BasicEvent
@@ -60,10 +92,44 @@ class DelayedAttackStartEvent : public BasicEvent
Creature* _owner;
};
class DelayedSpellCastEvent : public BasicEvent
{
public:
DelayedSpellCastEvent(Creature* owner, Unit* target, uint32 spellId, bool triggered) : _owner(owner), _target(target), _spellId(spellId), _triggered(triggered) { }
bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override;
private:
Creature* _owner;
Unit* _target;
uint32 _spellId;
bool _triggered;
};
class PlayerCheck
{
public:
bool operator()(WorldObject* object) const
{
return object->GetTypeId() != TYPEID_PLAYER;
}
};
struct firelands_bossAI : public BossAI
{
firelands_bossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId) { }
void EnterCombat(Unit* target) override;
void JustDied(Unit* killer) override;
void EnterEvadeMode(EvadeReason why) override;
};
template<typename AI>
inline AI* GetFirelandsAI(Creature* creature)
{
return GetInstanceAI<AI>(creature, FirelandsScriptName);
}
#define RegisterFirelandsAI(AI) RegisterCreatureAIWithFactory(AI, GetFirelandsAI)
#endif // FIRELANDS_H_

View File

@@ -18,6 +18,7 @@
#include "ScriptMgr.h"
#include "Creature.h"
#include "firelands.h"
#include "GameObject.h"
#include "InstanceScript.h"
#include "Map.h"
@@ -42,8 +43,60 @@ class instance_firelands : public InstanceMapScript
// Cannot directly start attacking here as the creature is not yet on map
creature->m_Events.AddEvent(new DelayedAttackStartEvent(creature), creature->m_Events.CalculateTime(500));
break;
case NPC_BALEROC:
BalerocGUID = creature->GetGUID();
break;
default:
break;
}
}
void OnGameObjectCreate(GameObject* go) override
{
switch (go->GetEntry())
{
case GO_BALEROC_FIREWALL:
BalerocDoorGUID = go->GetGUID();
if (GetBossState(DATA_SHANNOX) == DONE || GetBossState(DATA_BALEROC) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
default:
break;
}
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
if ((type == DATA_SHANNOX && state == DONE) || (type == DATA_BALEROC && state != IN_PROGRESS))
{
if (GameObject* door = instance->GetGameObject(BalerocDoorGUID))
door->SetGoState(GO_STATE_ACTIVE);
}
else if (type == DATA_BALEROC && state == IN_PROGRESS)
if (GameObject* door = instance->GetGameObject(BalerocDoorGUID))
door->SetGoState(GO_STATE_READY);
return true;
}
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
{
case DATA_BALEROC:
return BalerocGUID;
default:
break;
}
return ObjectGuid::Empty;
}
protected:
ObjectGuid BalerocDoorGUID;
ObjectGuid BalerocGUID;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override

View File

@@ -91,7 +91,9 @@ void AddSC_boss_temple_guardian_anhuur();
void AddSC_boss_earthrager_ptah();
void AddSC_boss_anraphet();
void AddSC_instance_firelands();
void AddSC_firelands();
void AddSC_boss_alysrazor();
void AddSC_boss_baleroc();
void AddSC_ashenvale();
void AddSC_azshara();
@@ -220,5 +222,7 @@ void AddKalimdorScripts()
AddSC_boss_anraphet();
AddSC_instance_firelands();
AddSC_firelands();
AddSC_boss_alysrazor();
AddSC_boss_baleroc();
}