mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 02:25:38 +01:00
Scripts/Halls of Lightning: reworked General Bjarngrim Encounter (#28457)
* handle missing visuals * reworked all AI scripts * handle missing mechanic of Arc Weld * reworked the whole waypoint and tempoary electrical charge handling * moved Stormforged Lieutenants to their own spawn group to handle their spawning/despawning via boss * moved the Tempoary Electrical Charge mechanic from spell_linked_spell to spell script instead * replaced hacky virtual items for Bjarngrim's stances with sniffed ones
This commit is contained in:
78
sql/updates/world/3.3.5/2022_11_04_05_world.sql
Normal file
78
sql/updates/world/3.3.5/2022_11_04_05_world.sql
Normal file
@@ -0,0 +1,78 @@
|
||||
--
|
||||
UPDATE `creature_template` SET `ScriptName`= 'boss_general_bjarngrim' WHERE `entry`= 28586;
|
||||
UPDATE `creature_template` SET `ScriptName`= 'npc_bjarngrim_stormforged_lieutenant' WHERE `entry`= 29240;
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
|
||||
('spell_bjarngrim_defensive_stance_dummy',
|
||||
'spell_bjarngrim_battle_stance_dummy',
|
||||
'spell_bjarngrim_berserker_stance_dummy',
|
||||
'spell_bjarngrim_charge_up',
|
||||
'spell_bjarngrim_arc_weld');
|
||||
|
||||
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
|
||||
(53790, 'spell_bjarngrim_defensive_stance_dummy'),
|
||||
(53791, 'spell_bjarngrim_berserker_stance_dummy'),
|
||||
(53792, 'spell_bjarngrim_battle_stance_dummy'),
|
||||
(52098, 'spell_bjarngrim_charge_up'),
|
||||
(59085, 'spell_bjarngrim_arc_weld');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID`= 28586;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(28586, 0, 0, 'I am the greatest of my father\'s sons! Your end has come!', 14, 0, 100, 0, 0, 14149, 31407, 0, 'General Bjarngrim - Aggro'),
|
||||
(28586, 1, 0, '%s switches to Defensive Stance!', 41, 0, 100, 0, 0, 0, 29834, 0, 'General Bjarngrim - Announce Defensive Stance'),
|
||||
(28586, 2, 0, 'Give me your worst!', 14, 0, 100, 0, 0, 14150, 31408, 0, 'General Bjarngrim - Defensive Stance'),
|
||||
(28586, 3, 0, '%s switches to Berserker Stance!', 41, 0, 100, 0, 0, 0, 29833, 0, 'General Bjarngrim - Announce Berserker Stance'),
|
||||
(28586, 4, 0, 'GRAAAAAH! Behold the fury of iron and steel!', 14, 0, 100, 0, 0, 14152, 31410, 0, 'General Bjarngrim - Berserker Stance'),
|
||||
(28586, 5, 0, '%s switches to Battle Stance!', 41, 0, 100, 0, 0, 0, 29832, 0, 'General Bjarngrim - Announce Battle Stance'),
|
||||
(28586, 6, 0, 'Defend yourself, for all the good it will do!', 14, 0, 100, 0, 0, 14151, 31409, 0, 'General Bjarngrim - Battle Stance'),
|
||||
(28586, 7, 0, 'So ends your curse.', 14, 0, 100, 0, 0, 14153, 31411, 0, 'General Bjarngrim - Slay 1'),
|
||||
(28586, 7, 1, 'Flesh... is... weak!', 14, 0, 100, 0, 0, 14154, 31412, 0, 'General Bjarngrim - Slay 2'),
|
||||
(28586, 7, 2, 'Bolvin umyol marnjar.', 14, 0, 100, 0, 0, 14155, 31413, 0, 'General Bjarngrim - Slay 3'),
|
||||
(28586, 8, 0, 'How can it be...? Flesh is not... stronger!', 14, 0, 100, 0, 0, 14156, 31414, 0, 'General Bjarngrim - Death');
|
||||
|
||||
DELETE FROM `conditions` WHERE `SourceEntry` IN (56458) AND `SourceTypeOrReferenceId`= 13;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
|
||||
(13, 1, 56458, 0, 0, 31, 0, 3, 28586, 0, 0, 0, '', 'Charge Up - Target General Bjarngrim');
|
||||
|
||||
SET @CGUID := 126981;
|
||||
SET @PATH := @CGUID * 10;
|
||||
DELETE FROM `waypoint_data` WHERE `id`= @PATH;
|
||||
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`) VALUES
|
||||
(@PATH, 0, 1262.023, 9.344401, 33.21593, NULL, 0),
|
||||
(@PATH, 1, 1262.031, 53.14377, 33.17394, NULL, 0),
|
||||
(@PATH, 2, 1261.928, 98.94911, 33.50209, NULL, 6000),
|
||||
(@PATH, 3, 1261.893, 60.51574, 33.17393, NULL, 0),
|
||||
(@PATH, 4, 1261.886, 21.39475, 33.17399, NULL, 0),
|
||||
(@PATH, 5, 1262.132, -26.1173, 33.50208, NULL, 6000),
|
||||
(@PATH, 6, 1298.901, -26.74544, 37.24462, NULL, 0),
|
||||
(@PATH, 7, 1331.648, -27.02919, 40.17395, NULL, 10000),
|
||||
(@PATH, 8, 1354.665, -4.239692, 41.1354, NULL, 0),
|
||||
(@PATH, 9, 1371.601, 12.65864, 48.57853, NULL, 0),
|
||||
(@PATH, 10, 1394.671, 35.86361, 50.03335, NULL, 6000),
|
||||
(@PATH, 11, 1370.748, 12.2143, 48.29315, NULL, 0),
|
||||
(@PATH, 12, 1355.246, -3.361762, 41.45641, NULL, 0),
|
||||
(@PATH, 13, 1332.481, -26.59397, 40.17395, NULL, 0),
|
||||
(@PATH, 14, 1295.831, -26.50022, 36.55395, NULL, 0),
|
||||
(@PATH, 15, 1262.658, -26.88303, 33.50208, NULL, 10000);
|
||||
|
||||
DELETE FROM `waypoint_scripts` WHERE `id` IN (12698102, 12698101);
|
||||
|
||||
UPDATE `creature` SET `position_x`= 1262.2057, `position_y`= -1.0628986, `position_z`= 33.50208, `orientation`= 5.140983, `wander_distance`= 0, `MovementType`= 2 WHERE `guid`= @CGUID;
|
||||
DELETE FROM `creature_addon` WHERE `guid`= @CGUID;
|
||||
INSERT INTO `creature_addon` (`guid`, `path_id`, `bytes2`) VALUES
|
||||
(@CGUID, @PATH, 1);
|
||||
|
||||
UPDATE `creature` SET `position_x`= 1265.8042, `position_y`= -4.6208167, `position_z`= 33.502056, `orientation`= 5.258189 WHERE `guid`= 126863;
|
||||
UPDATE `creature` SET `position_x`= 1258.7352, `position_y`= -4.746479, `position_z`= 33.50209, `orientation`= 5.122859 WHERE `guid`= 126864;
|
||||
|
||||
DELETE FROM `spell_linked_spell` WHERE `spell_trigger`= -52098;
|
||||
|
||||
DELETE FROM `spawn_group_template` WHERE `groupId`= 325;
|
||||
INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES
|
||||
(325, 'Halls of Lightning - General Bjarngrim - Stormforged Lieutenants', 4);
|
||||
|
||||
DELETE FROM `spawn_group` WHERE `spawnId` IN (126863, 126864);
|
||||
DELETE FROM `spawn_group` WHERE `groupId`= 325;
|
||||
INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES
|
||||
(325, 0, 126863),
|
||||
(325, 0, 126864);
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss General Bjarngrim
|
||||
SD%Complete: 70%
|
||||
SDComment: Waypoint needed, we expect boss to always have 2x Stormforged Lieutenant following
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "halls_of_lightning.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEFENSIVE_STANCE = 1,
|
||||
SAY_BATTLE_STANCE = 2,
|
||||
SAY_BERSEKER_STANCE = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_DEATH = 5,
|
||||
EMOTE_DEFENSIVE_STANCE = 6,
|
||||
EMOTE_BATTLE_STANCE = 7,
|
||||
EMOTE_BERSEKER_STANCE = 8
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DEFENSIVE_STANCE = 53790,
|
||||
//SPELL_DEFENSIVE_AURA = 41105,
|
||||
SPELL_SPELL_REFLECTION = 36096,
|
||||
SPELL_PUMMEL = 12555,
|
||||
SPELL_KNOCK_AWAY = 52029,
|
||||
SPELL_IRONFORM = 52022,
|
||||
|
||||
SPELL_BERSEKER_STANCE = 53791,
|
||||
//SPELL_BERSEKER_AURA = 41107,
|
||||
SPELL_INTERCEPT = 58769,
|
||||
SPELL_WHIRLWIND = 52027,
|
||||
SPELL_CLEAVE = 15284,
|
||||
|
||||
SPELL_BATTLE_STANCE = 53792,
|
||||
//SPELL_BATTLE_AURA = 41106,
|
||||
SPELL_MORTAL_STRIKE = 16856,
|
||||
SPELL_SLAM = 52026,
|
||||
|
||||
//OTHER SPELLS
|
||||
//SPELL_CHARGE_UP = 52098, // only used when starting walk from one platform to the other
|
||||
SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
|
||||
|
||||
SPELL_ARC_WELD = 59085,
|
||||
SPELL_RENEW_STEEL_N = 52774,
|
||||
SPELL_RENEW_STEEL_H = 59160
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_STORMFORGED_LIEUTENANT = 29240
|
||||
};
|
||||
|
||||
enum Equips
|
||||
{
|
||||
EQUIP_SWORD = 37871,
|
||||
EQUIP_SHIELD = 35642,
|
||||
EQUIP_MACE = 43623
|
||||
};
|
||||
|
||||
enum Stanges
|
||||
{
|
||||
STANCE_DEFENSIVE = 0,
|
||||
STANCE_BERSERKER = 1,
|
||||
STANCE_BATTLE = 2
|
||||
};
|
||||
|
||||
/*######
|
||||
## boss_bjarngrim
|
||||
######*/
|
||||
|
||||
struct boss_bjarngrim : public BossAI
|
||||
{
|
||||
boss_bjarngrim(Creature* creature) : BossAI(creature, DATA_GENERAL_BJARNGRIM)
|
||||
{
|
||||
Initialize();
|
||||
m_uiStance = STANCE_DEFENSIVE;
|
||||
canBuff = true;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_bIsChangingStance = false;
|
||||
|
||||
m_uiChargingStatus = 0;
|
||||
m_uiCharge_Timer = 1000;
|
||||
|
||||
m_uiChangeStance_Timer = urand(20000, 25000);
|
||||
|
||||
m_uiReflection_Timer = 8000;
|
||||
m_uiKnockAway_Timer = 20000;
|
||||
m_uiPummel_Timer = 10000;
|
||||
m_uiIronform_Timer = 25000;
|
||||
|
||||
m_uiIntercept_Timer = 5000;
|
||||
m_uiWhirlwind_Timer = 10000;
|
||||
m_uiCleave_Timer = 8000;
|
||||
|
||||
m_uiMortalStrike_Timer = 8000;
|
||||
m_uiSlam_Timer = 10000;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
if (canBuff)
|
||||
if (!me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE))
|
||||
me->AddAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE, me);
|
||||
|
||||
Initialize();
|
||||
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
// @todo: move this to spawn groups.
|
||||
if (Creature* pStormforgedLieutenant = ObjectAccessor::GetCreature(*me, m_auiStormforgedLieutenantGUID[i]))
|
||||
if (!pStormforgedLieutenant->IsAlive())
|
||||
pStormforgedLieutenant->Respawn();
|
||||
}
|
||||
|
||||
if (m_uiStance != STANCE_DEFENSIVE)
|
||||
{
|
||||
DoRemoveStanceAura(m_uiStance);
|
||||
DoCast(me, SPELL_DEFENSIVE_STANCE);
|
||||
m_uiStance = STANCE_DEFENSIVE;
|
||||
}
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE))
|
||||
canBuff = true;
|
||||
else
|
||||
canBuff = false;
|
||||
|
||||
BossAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
//must get both lieutenants here and make sure they are with him
|
||||
me->CallForHelp(30.0f);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
/// @todo remove when removal is done by the core
|
||||
void DoRemoveStanceAura(uint8 uiStance)
|
||||
{
|
||||
switch (uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
me->RemoveAurasDueToSpell(SPELL_DEFENSIVE_STANCE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
me->RemoveAurasDueToSpell(SPELL_BERSEKER_STANCE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
me->RemoveAurasDueToSpell(SPELL_BATTLE_STANCE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Change stance
|
||||
if (m_uiChangeStance_Timer <= uiDiff)
|
||||
{
|
||||
//wait for current spell to finish before change stance
|
||||
if (me->IsNonMeleeSpellCast(false))
|
||||
return;
|
||||
|
||||
DoRemoveStanceAura(m_uiStance);
|
||||
|
||||
int uiTempStance = rand32() % (3 - 1);
|
||||
|
||||
if (uiTempStance >= m_uiStance)
|
||||
++uiTempStance;
|
||||
|
||||
m_uiStance = uiTempStance;
|
||||
|
||||
switch (m_uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
Talk(SAY_DEFENSIVE_STANCE);
|
||||
Talk(EMOTE_DEFENSIVE_STANCE);
|
||||
DoCast(me, SPELL_DEFENSIVE_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
Talk(SAY_BERSEKER_STANCE);
|
||||
Talk(EMOTE_BERSEKER_STANCE);
|
||||
DoCast(me, SPELL_BERSEKER_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
Talk(SAY_BATTLE_STANCE);
|
||||
Talk(EMOTE_BATTLE_STANCE);
|
||||
DoCast(me, SPELL_BATTLE_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
m_uiChangeStance_Timer = urand(20000, 25000);
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_uiChangeStance_Timer -= uiDiff;
|
||||
|
||||
switch (m_uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
{
|
||||
if (m_uiReflection_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_SPELL_REFLECTION);
|
||||
m_uiReflection_Timer = urand(8000, 9000);
|
||||
}
|
||||
else
|
||||
m_uiReflection_Timer -= uiDiff;
|
||||
|
||||
if (m_uiKnockAway_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_KNOCK_AWAY);
|
||||
m_uiKnockAway_Timer = urand(20000, 21000);
|
||||
}
|
||||
else
|
||||
m_uiKnockAway_Timer -= uiDiff;
|
||||
|
||||
if (m_uiPummel_Timer <= uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_PUMMEL);
|
||||
m_uiPummel_Timer = urand(10000, 11000);
|
||||
}
|
||||
else
|
||||
m_uiPummel_Timer -= uiDiff;
|
||||
|
||||
if (m_uiIronform_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_IRONFORM);
|
||||
m_uiIronform_Timer = urand(25000, 26000);
|
||||
}
|
||||
else
|
||||
m_uiIronform_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
case STANCE_BERSERKER:
|
||||
{
|
||||
if (m_uiIntercept_Timer <= uiDiff)
|
||||
{
|
||||
//not much point is this, better random target and more often?
|
||||
DoCastVictim(SPELL_INTERCEPT);
|
||||
m_uiIntercept_Timer = urand(45000, 46000);
|
||||
}
|
||||
else
|
||||
m_uiIntercept_Timer -= uiDiff;
|
||||
|
||||
if (m_uiWhirlwind_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(me, SPELL_WHIRLWIND);
|
||||
m_uiWhirlwind_Timer = urand(10000, 11000);
|
||||
}
|
||||
else
|
||||
m_uiWhirlwind_Timer -= uiDiff;
|
||||
|
||||
if (m_uiCleave_Timer <= uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
m_uiCleave_Timer = urand(8000, 9000);
|
||||
}
|
||||
else
|
||||
m_uiCleave_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
case STANCE_BATTLE:
|
||||
{
|
||||
if (m_uiMortalStrike_Timer <= uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
m_uiMortalStrike_Timer = urand(20000, 21000);
|
||||
}
|
||||
else
|
||||
m_uiMortalStrike_Timer -= uiDiff;
|
||||
|
||||
if (m_uiSlam_Timer <= uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_SLAM);
|
||||
m_uiSlam_Timer = urand(15000, 16000);
|
||||
}
|
||||
else
|
||||
m_uiSlam_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bIsChangingStance;
|
||||
bool canBuff;
|
||||
|
||||
uint8 m_uiChargingStatus;
|
||||
uint8 m_uiStance;
|
||||
|
||||
uint32 m_uiCharge_Timer;
|
||||
uint32 m_uiChangeStance_Timer;
|
||||
|
||||
uint32 m_uiReflection_Timer;
|
||||
uint32 m_uiKnockAway_Timer;
|
||||
uint32 m_uiPummel_Timer;
|
||||
uint32 m_uiIronform_Timer;
|
||||
|
||||
uint32 m_uiIntercept_Timer;
|
||||
uint32 m_uiWhirlwind_Timer;
|
||||
uint32 m_uiCleave_Timer;
|
||||
|
||||
uint32 m_uiMortalStrike_Timer;
|
||||
uint32 m_uiSlam_Timer;
|
||||
|
||||
ObjectGuid m_auiStormforgedLieutenantGUID[2];
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_stormforged_lieutenant
|
||||
######*/
|
||||
|
||||
struct npc_stormforged_lieutenant : public ScriptedAI
|
||||
{
|
||||
npc_stormforged_lieutenant(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
_instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_uiArcWeld_Timer = urand(20000, 21000);
|
||||
m_uiRenewSteel_Timer = urand(10000, 11000);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (Creature* bjarngrim = _instance->GetCreature(DATA_GENERAL_BJARNGRIM))
|
||||
{
|
||||
if (bjarngrim->IsAlive() && !bjarngrim->IsEngaged())
|
||||
bjarngrim->EngageWithTarget(who);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (m_uiArcWeld_Timer <= uiDiff)
|
||||
{
|
||||
DoCastVictim(SPELL_ARC_WELD);
|
||||
m_uiArcWeld_Timer = urand(20000, 21000);
|
||||
}
|
||||
else
|
||||
m_uiArcWeld_Timer -= uiDiff;
|
||||
|
||||
if (m_uiRenewSteel_Timer <= uiDiff)
|
||||
{
|
||||
if (Creature* bjarngrim = _instance->GetCreature(DATA_GENERAL_BJARNGRIM))
|
||||
{
|
||||
if (bjarngrim->IsAlive())
|
||||
DoCast(bjarngrim, SPELL_RENEW_STEEL_N);
|
||||
}
|
||||
m_uiRenewSteel_Timer = urand(10000, 14000);
|
||||
}
|
||||
else
|
||||
m_uiRenewSteel_Timer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
uint32 m_uiArcWeld_Timer;
|
||||
uint32 m_uiRenewSteel_Timer;
|
||||
};
|
||||
|
||||
void AddSC_boss_bjarngrim()
|
||||
{
|
||||
RegisterHallsOfLightningCreatureAI(boss_bjarngrim);
|
||||
RegisterHallsOfLightningCreatureAI(npc_stormforged_lieutenant);
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* 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 "halls_of_lightning.h"
|
||||
#include "SpellScript.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "MovementDefines.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellHistory.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// General Bjarngrim
|
||||
SPELL_CHARGE_UP = 52098,
|
||||
SPELL_TEMPOARY_ELECTRICAL_CHARGE = 52092,
|
||||
SPELL_STANCE_COOLDOWN = 41102,
|
||||
SPELL_DEFENSIVE_STANCE = 53790,
|
||||
SPELL_DEFENSIVE_AURA = 41105,
|
||||
SPELL_KNOCK_AWAY = 52029,
|
||||
SPELL_SPELL_REFLECTION = 36096,
|
||||
SPELL_BERSERKER_STANCE = 53791,
|
||||
SPELL_BERSERKER_AURA = 41107,
|
||||
SPELL_WHIRLWIND = 52027,
|
||||
SPELL_INTERCEPT = 58769,
|
||||
SPELL_CLEAVE = 15284,
|
||||
SPELL_BATTLE_STANCE = 53792,
|
||||
SPELL_BATTLE_AURA = 41106,
|
||||
SPELL_MORTAL_STRIKE = 16856,
|
||||
SPELL_SLAM = 52026,
|
||||
|
||||
// Stormforged Lieutenant
|
||||
SPELL_ARC_WELD = 59085,
|
||||
SPELL_ARC_WELD_DAMAGE = 59097,
|
||||
SPELL_RENEW_STEEL = 52774,
|
||||
|
||||
// Invisible Stalker
|
||||
SPELL_CHARGE_UP_DUMMY = 56458
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
// General Bjarngrim
|
||||
EVENT_CHARGE_UP = 1,
|
||||
EVENT_CHECK_STANCE_COOLDOWN,
|
||||
EVENT_KNOCK_AWAY,
|
||||
EVENT_SPELL_REFLECTION,
|
||||
EVENT_WHIRLWIND,
|
||||
EVENT_INTERCEPT,
|
||||
EVENT_CLEAVE,
|
||||
EVENT_MORTAL_STRIKE,
|
||||
EVENT_SLAM,
|
||||
|
||||
// Stormforged Lieutenant
|
||||
EVENT_ARC_WELD = 1,
|
||||
EVENT_CHECK_BJARNGRIMS_HEALTH
|
||||
};
|
||||
|
||||
enum EventGroups
|
||||
{
|
||||
EVENT_GROUP_DEFENSIVE_STANCE = 1,
|
||||
EVENT_GROUP_BERSERKER_STANCE,
|
||||
EVENT_GROUP_BATTLE_STANCE
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_SWITCH_STANCE = 0
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_OUT_OF_COMBAT = 1
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// General Bjarngrim
|
||||
SAY_AGGRO = 0,
|
||||
SAY_ANNOUNCE_DEFENSIVE_STANCE = 1,
|
||||
SAY_DEFENSIVE_STANCE = 2,
|
||||
SAY_ANNOUNCE_BERSERKER_STANCE = 3,
|
||||
SAY_BERSERKER_STANCE = 4,
|
||||
SAY_ANNOUNCE_BATTLE_STANCE = 5,
|
||||
SAY_BATTLE_STANCE = 6,
|
||||
SAY_SLAY = 7,
|
||||
SAY_DEATH = 8
|
||||
};
|
||||
|
||||
enum VirtualItemIds
|
||||
{
|
||||
ITEM_ID_AXE = 43625,
|
||||
ITEM_ID_SHIELD = 39384,
|
||||
ITEM_ID_GREATAXE = 43623
|
||||
};
|
||||
|
||||
enum Stances
|
||||
{
|
||||
STANCE_DEFENSIVE = 0,
|
||||
STANCE_BERSERKER = 1,
|
||||
STANCE_BATTLE = 2,
|
||||
|
||||
MAX_STANCE
|
||||
};
|
||||
|
||||
// These values must be sync with the data in waypoint_data.
|
||||
// Each of these points is going to trigger a Charge Up sequence
|
||||
static std::array<uint8, 2> const ChargeUpWaypointIds = { 7, 15 };
|
||||
// Each of these points is going to remove the Tempoary Electrical Charge buff from General Bjarngrim
|
||||
static std::array<uint8, 2> const ClearTempoaryChargeWaypointIds = { 5, 13 };
|
||||
|
||||
// This value must be sync with the data in spawngroup_template
|
||||
static constexpr uint32 SPAWN_GROUP_ID_STORMFORGED_LIEUTENANTS = 325;
|
||||
|
||||
struct StanceTextInfo
|
||||
{
|
||||
StanceTextInfo(uint32 announceTextId, uint32 sayTextId) :
|
||||
AnnounceTextId(announceTextId), SayTextId(sayTextId) { }
|
||||
|
||||
uint32 AnnounceTextId;
|
||||
uint32 SayTextId;
|
||||
};
|
||||
|
||||
struct StanceInfo
|
||||
{
|
||||
StanceInfo(StanceTextInfo textInfo, uint32 stanceSpellId) :
|
||||
TextInfo(textInfo), StanceSpellId(stanceSpellId) { }
|
||||
|
||||
StanceTextInfo TextInfo;
|
||||
uint32 StanceSpellId;
|
||||
};
|
||||
|
||||
static std::array<StanceInfo, MAX_STANCE> const StanceData =
|
||||
{
|
||||
StanceInfo(StanceTextInfo(SAY_ANNOUNCE_DEFENSIVE_STANCE, SAY_DEFENSIVE_STANCE), SPELL_DEFENSIVE_STANCE),
|
||||
StanceInfo(StanceTextInfo(SAY_ANNOUNCE_BERSERKER_STANCE, SAY_BERSERKER_STANCE), SPELL_BERSERKER_STANCE),
|
||||
StanceInfo(StanceTextInfo(SAY_ANNOUNCE_BATTLE_STANCE, SAY_BATTLE_STANCE), SPELL_BATTLE_STANCE)
|
||||
};
|
||||
|
||||
struct boss_general_bjarngrim : public BossAI
|
||||
{
|
||||
boss_general_bjarngrim(Creature* creature) : BossAI(creature, DATA_GENERAL_BJARNGRIM), _currentStanceId(STANCE_BATTLE) { }
|
||||
|
||||
void JustAppeared() override
|
||||
{
|
||||
events.SetPhase(PHASE_OUT_OF_COMBAT);
|
||||
instance->instance->SpawnGroupSpawn(SPAWN_GROUP_ID_STORMFORGED_LIEUTENANTS, true, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO, who);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_CHECK_STANCE_COOLDOWN, 1s);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
_DespawnAtEvade();
|
||||
instance->instance->SpawnGroupDespawn(SPAWN_GROUP_ID_STORMFORGED_LIEUTENANTS, true);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
Talk(SAY_SLAY, victim);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH, killer);
|
||||
instance->instance->SpawnGroupDespawn(SPAWN_GROUP_ID_STORMFORGED_LIEUTENANTS, true);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 motionType, uint32 pointId) override
|
||||
{
|
||||
if (motionType != WAYPOINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (std::find(ChargeUpWaypointIds.begin(), ChargeUpWaypointIds.end(), pointId) != ChargeUpWaypointIds.end())
|
||||
events.ScheduleEvent(EVENT_CHARGE_UP, 4s, 0, PHASE_OUT_OF_COMBAT);
|
||||
else if (std::find(ClearTempoaryChargeWaypointIds.begin(), ClearTempoaryChargeWaypointIds.end(), pointId) != ClearTempoaryChargeWaypointIds.end())
|
||||
me->RemoveAurasDueToSpell(SPELL_TEMPOARY_ELECTRICAL_CHARGE);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_SWITCH_STANCE:
|
||||
{
|
||||
me->RemoveAurasDueToSpell(StanceData[_currentStanceId].StanceSpellId);
|
||||
|
||||
// @todo: figure out if the stances just cycle or if they are random
|
||||
_currentStanceId = (_currentStanceId + 1) % StanceData.size();
|
||||
|
||||
DoCastSelf(StanceData[_currentStanceId].StanceSpellId);
|
||||
Talk(StanceData[_currentStanceId].TextInfo.AnnounceTextId);
|
||||
Talk(StanceData[_currentStanceId].TextInfo.SayTextId);
|
||||
|
||||
switch (_currentStanceId)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
events.CancelEventGroup(EVENT_GROUP_BERSERKER_STANCE);
|
||||
events.CancelEventGroup(EVENT_GROUP_BATTLE_STANCE);
|
||||
events.ScheduleEvent(EVENT_KNOCK_AWAY, 5s, EVENT_GROUP_DEFENSIVE_STANCE);
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 7s, EVENT_GROUP_DEFENSIVE_STANCE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
events.CancelEventGroup(EVENT_GROUP_DEFENSIVE_STANCE);
|
||||
events.CancelEventGroup(EVENT_GROUP_BATTLE_STANCE);
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 7s, EVENT_GROUP_BERSERKER_STANCE);
|
||||
events.ScheduleEvent(EVENT_INTERCEPT, 16s, EVENT_GROUP_BERSERKER_STANCE);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 19s + 500ms, EVENT_GROUP_BERSERKER_STANCE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
events.CancelEventGroup(EVENT_GROUP_DEFENSIVE_STANCE);
|
||||
events.CancelEventGroup(EVENT_GROUP_BERSERKER_STANCE);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 5s, EVENT_GROUP_BATTLE_STANCE);
|
||||
events.ScheduleEvent(EVENT_SLAM, 9s, EVENT_GROUP_BATTLE_STANCE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() && !events.IsInPhase(PHASE_OUT_OF_COMBAT))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHARGE_UP:
|
||||
DoCastSelf(SPELL_CHARGE_UP);
|
||||
if (Creature* stalker = instance->GetCreature(DATA_INVISIBLE_STALKER))
|
||||
stalker->m_Events.AddEventAtOffset([stalker]() { stalker->CastSpell(nullptr, SPELL_CHARGE_UP_DUMMY); }, 4s);
|
||||
break;
|
||||
case EVENT_CHECK_STANCE_COOLDOWN:
|
||||
// General Bjarngrim uses a category cooldown to handle the stance switching, so we do as well.
|
||||
if (!me->GetSpellHistory()->GetRemainingCooldown(sSpellMgr->AssertSpellInfo(SPELL_STANCE_COOLDOWN)))
|
||||
DoAction(ACTION_SWITCH_STANCE);
|
||||
events.Repeat(1s);
|
||||
break;
|
||||
case EVENT_KNOCK_AWAY:
|
||||
DoCastAOE(SPELL_KNOCK_AWAY);
|
||||
events.Repeat(11s);
|
||||
break;
|
||||
case EVENT_SPELL_REFLECTION:
|
||||
DoCastSelf(SPELL_SPELL_REFLECTION);
|
||||
events.Repeat(8s + 500ms);
|
||||
break;
|
||||
case EVENT_WHIRLWIND:
|
||||
DoCastSelf(SPELL_WHIRLWIND);
|
||||
break;
|
||||
case EVENT_INTERCEPT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, -8.f, true, true))
|
||||
DoCast(target, SPELL_INTERCEPT);
|
||||
break;
|
||||
case EVENT_CLEAVE:
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
break;
|
||||
case EVENT_MORTAL_STRIKE:
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
break;
|
||||
case EVENT_SLAM:
|
||||
DoCastVictim(SPELL_SLAM);
|
||||
events.Repeat(5s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _currentStanceId;
|
||||
};
|
||||
|
||||
struct npc_bjarngrim_stormforged_lieutenant : public ScriptedAI
|
||||
{
|
||||
npc_bjarngrim_stormforged_lieutenant(Creature* creature) : ScriptedAI(creature), _instance(nullptr) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
_instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_ARC_WELD, 5s, 6s);
|
||||
_events.ScheduleEvent(EVENT_CHECK_BJARNGRIMS_HEALTH, 10s);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ARC_WELD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.f, true))
|
||||
DoCast(target, SPELL_ARC_WELD);
|
||||
_events.Repeat(22s);
|
||||
break;
|
||||
case EVENT_CHECK_BJARNGRIMS_HEALTH:
|
||||
if (Creature* bjarngrim = _instance->GetCreature(DATA_GENERAL_BJARNGRIM))
|
||||
if (bjarngrim->GetHealthPct() <= 75.f) // @todo: validate
|
||||
DoCast(bjarngrim, SPELL_RENEW_STEEL);
|
||||
|
||||
_events.Repeat(10s, 14s); // @todo: these are just taken from the old code. We know that these heals are pct based so we need the cooldown rather than a timer
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
// 53790 - Defensive Stance
|
||||
// 53791 - Berserker Stance
|
||||
// 53792 - Battle Stance
|
||||
class spell_bjarngrim_stance_dummy : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_bjarngrim_stance_dummy);
|
||||
|
||||
public:
|
||||
spell_bjarngrim_stance_dummy(uint8 stanceId) : AuraScript(), _stanceId(stanceId) { }
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_DEFENSIVE_AURA, SPELL_BERSERKER_AURA, SPELL_BATTLE_AURA, SPELL_STANCE_COOLDOWN });
|
||||
}
|
||||
|
||||
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
switch (_stanceId)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
target->SetVirtualItem(0, ITEM_ID_AXE);
|
||||
target->SetVirtualItem(1, ITEM_ID_SHIELD);
|
||||
target->CastSpell(nullptr, SPELL_DEFENSIVE_AURA);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
target->SetVirtualItem(0, ITEM_ID_AXE);
|
||||
target->SetVirtualItem(1, ITEM_ID_AXE);
|
||||
target->CastSpell(nullptr, SPELL_BERSERKER_AURA);
|
||||
target->SetCanDualWield(true);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
target->SetVirtualItem(0, ITEM_ID_GREATAXE);
|
||||
target->SetVirtualItem(1, 0);
|
||||
target->CastSpell(nullptr, SPELL_BATTLE_AURA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
target->CastSpell(nullptr, SPELL_STANCE_COOLDOWN);
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
switch (_stanceId)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
target->RemoveAurasDueToSpell(SPELL_DEFENSIVE_AURA);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
target->RemoveAurasDueToSpell(SPELL_BERSERKER_AURA);
|
||||
target->SetCanDualWield(false);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
target->RemoveAurasDueToSpell(SPELL_BATTLE_AURA);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_bjarngrim_stance_dummy::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_bjarngrim_stance_dummy::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
private:
|
||||
uint8 _stanceId;
|
||||
};
|
||||
|
||||
// 52098 - Charge Up
|
||||
class spell_bjarngrim_charge_up : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_bjarngrim_charge_up);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_TEMPOARY_ELECTRICAL_CHARGE });
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Creature* target = GetTarget()->ToCreature())
|
||||
target->CastSpell(nullptr, SPELL_TEMPOARY_ELECTRICAL_CHARGE);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_bjarngrim_charge_up::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 59085 - Arc Weld
|
||||
class spell_bjarngrim_arc_weld : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_bjarngrim_arc_weld);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_ARC_WELD_DAMAGE });
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (GetTarget()->isMoving())
|
||||
GetTarget()->CastSpell(nullptr, SPELL_ARC_WELD_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_bjarngrim_arc_weld::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_general_bjarngrim()
|
||||
{
|
||||
RegisterHallsOfLightningCreatureAI(boss_general_bjarngrim);
|
||||
RegisterHallsOfLightningCreatureAI(npc_bjarngrim_stormforged_lieutenant);
|
||||
RegisterSpellScriptWithArgs(spell_bjarngrim_stance_dummy, "spell_bjarngrim_defensive_stance_dummy", STANCE_DEFENSIVE);
|
||||
RegisterSpellScriptWithArgs(spell_bjarngrim_stance_dummy, "spell_bjarngrim_battle_stance_dummy", STANCE_BATTLE);
|
||||
RegisterSpellScriptWithArgs(spell_bjarngrim_stance_dummy, "spell_bjarngrim_berserker_stance_dummy", STANCE_BERSERKER);
|
||||
RegisterSpellScript(spell_bjarngrim_charge_up);
|
||||
RegisterSpellScript(spell_bjarngrim_arc_weld);
|
||||
}
|
||||
@@ -34,6 +34,9 @@ enum HOLDataTypes
|
||||
DATA_LOKEN = 3,
|
||||
|
||||
// Additional Data
|
||||
/*General Bjarngrim*/
|
||||
DATA_INVISIBLE_STALKER,
|
||||
|
||||
/*Volkhan*/
|
||||
DATA_VOLKHAN_TEMPER_VISUAL,
|
||||
DATA_VOLKHANS_ANVIL,
|
||||
@@ -45,14 +48,17 @@ enum HOLDataTypes
|
||||
enum HOLCreaturesIds
|
||||
{
|
||||
// Bosses
|
||||
NPC_GENERAL_BJARNGRIM = 28586,
|
||||
NPC_VOLKHAN = 28587,
|
||||
NPC_IONAR = 28546,
|
||||
NPC_LOKEN = 28923,
|
||||
NPC_GENERAL_BJARNGRIM = 28586,
|
||||
NPC_VOLKHAN = 28587,
|
||||
NPC_IONAR = 28546,
|
||||
NPC_LOKEN = 28923,
|
||||
|
||||
/*General Bjarngrim*/
|
||||
NPC_INVISIBLE_STALKER = 30298,
|
||||
|
||||
/*Volkhan*/
|
||||
NPC_VOLKHANS_ANVIL = 28823,
|
||||
NPC_MOLTEN_GOLEM = 28695
|
||||
NPC_VOLKHANS_ANVIL = 28823,
|
||||
NPC_MOLTEN_GOLEM = 28695
|
||||
};
|
||||
|
||||
enum HOLGameObjectIds
|
||||
|
||||
@@ -37,6 +37,7 @@ ObjectData const creatureData[] =
|
||||
{ NPC_VOLKHAN, DATA_VOLKHAN },
|
||||
{ NPC_IONAR, DATA_IONAR },
|
||||
{ NPC_LOKEN, DATA_LOKEN },
|
||||
{ NPC_INVISIBLE_STALKER, DATA_INVISIBLE_STALKER },
|
||||
{ NPC_VOLKHANS_ANVIL, DATA_VOLKHANS_ANVIL },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
@@ -97,7 +97,7 @@ void AddSC_boss_sartharion();
|
||||
void AddSC_obsidian_sanctum();
|
||||
void AddSC_instance_obsidian_sanctum();
|
||||
// Ulduar: Halls of Lightning
|
||||
void AddSC_boss_bjarngrim();
|
||||
void AddSC_boss_general_bjarngrim();
|
||||
void AddSC_boss_loken();
|
||||
void AddSC_boss_ionar();
|
||||
void AddSC_boss_volkhan();
|
||||
@@ -295,7 +295,7 @@ void AddNorthrendScripts()
|
||||
AddSC_obsidian_sanctum();
|
||||
AddSC_instance_obsidian_sanctum();
|
||||
// Halls of Lightning
|
||||
AddSC_boss_bjarngrim();
|
||||
AddSC_boss_general_bjarngrim();
|
||||
AddSC_boss_loken();
|
||||
AddSC_boss_ionar();
|
||||
AddSC_boss_volkhan();
|
||||
|
||||
Reference in New Issue
Block a user