Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-06-10 00:03:20 +08:00
21 changed files with 499 additions and 522 deletions

View File

@@ -0,0 +1,2 @@
-- DB update 2024_06_07_03 -> 2024_06_08_00
UPDATE `creature_template` SET `speed_run` = 1.5 WHERE (`entry` = 18104);

View File

@@ -0,0 +1,5 @@
-- DB update 2024_06_08_00 -> 2024_06_08_01
--
DELETE FROM `spell_script_names` WHERE `spell_id` = 32014;
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(32014, 'spell_air_burst');

View File

@@ -0,0 +1,4 @@
-- DB update 2024_06_08_01 -> 2024_06_08_02
UPDATE `creature_model_info` SET `BoundingRadius` = 4.5, `CombatReach` = 7.875 WHERE `DisplayID` = 17886;
UPDATE `creature_model_info` SET `BoundingRadius` = 4.2 WHERE `DisplayID` = 20939;
UPDATE `creature_model_info` SET `BoundingRadius` = 5, `CombatReach` = 7.5 WHERE `DisplayID` = 21069;

View File

@@ -0,0 +1,5 @@
-- DB update 2024_06_08_02 -> 2024_06_09_00
--
UPDATE `spell_script_names` SET `ScriptName`='spell_four_horsemen_mark_aura' WHERE `spell_id` IN (28832, 28833, 28834, 28835);
UPDATE `spell_script_names` SET `ScriptName`='spell_grobbulus_mutating_injection_aura' WHERE `spell_id`=28169;
UPDATE `spell_script_names` SET `ScriptName`='spell_kelthuzad_detonate_mana_aura' WHERE `spell_id`=27819;

View File

@@ -95,7 +95,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_MAIL_SERVER_CHARACTER, "SELECT mailId from mail_server_character WHERE guid = ? and mailId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_MAIL_SERVER_CHARACTER, "SELECT mailId from mail_server_character WHERE guid = ? and mailId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_MAIL_SERVER_CHARACTER, "REPLACE INTO mail_server_character (guid, mailId) values (?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_REP_MAIL_SERVER_CHARACTER, "REPLACE INTO mail_server_character (guid, mailId) values (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ, posO FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ, posO FROM character_homebind WHERE guid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, category, item, time, needSend FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, category, item, time, needSend FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC);

View File

@@ -1386,7 +1386,26 @@ public:
if (!target || !target->IsConnected()) if (!target || !target->IsConnected())
{ {
return false; if (handler->HasLowerSecurity(nullptr, target->GetGUID()))
return false;
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_HOMEBIND);
stmt->SetData(0, target->GetGUID().GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
{
Field* fieldsDB = result->Fetch();
WorldLocation loc(fieldsDB[0].Get<uint16>(), fieldsDB[2].Get<float>(), fieldsDB[3].Get<float>(), fieldsDB[4].Get<float>(), 0.0f);
uint32 zoneId = fieldsDB[1].Get<uint16>();
Player::SavePositionInDB(loc, zoneId, target->GetGUID(), nullptr);
handler->PSendSysMessage(LANG_SUMMONING, target->GetName(), handler->GetAcoreString(LANG_OFFLINE));
}
return true;
} }
Player* player = target->GetConnectedPlayer(); Player* player = target->GetConnectedPlayer();

View File

@@ -71,22 +71,12 @@ enum Summons
enum Events enum Events
{ {
EVENT_DRAIN_WORLD_TREE = 1, EVENT_ENRAGE = 0
EVENT_SPELL_FEAR = 2, };
EVENT_SPELL_AIR_BURST = 3,
EVENT_SPELL_GRIP_OF_THE_LEGION = 4, enum SpellGroups
EVENT_SPELL_UNLEASH_SOUL_CHARGES = 5, {
EVENT_SPELL_DOOMFIRE = 6, GROUP_FEAR = 0
EVENT_SPELL_FINGER_OF_DEATH = 7,
EVENT_SPELL_HAND_OF_DEATH = 8,
EVENT_SPELL_PROTECTION_OF_ELUNE = 9,
EVENT_ENRAGE = 10,
EVENT_CHECK_WORLD_TREE_DISTANCE = 11, // Enrage if too close to the tree
EVENT_BELOW_10_PERCENT_HP = 12,
EVENT_SUMMON_WISPS = 13,
EVENT_TOO_CLOSE_TO_WORLD_TREE = 14,
EVENT_ENRAGE_ROOT = 15,
EVENT_SPELL_FINGER_OF_DEATH_PHASE_4 = 16
}; };
uint32 const availableChargeAurasAndSpells[3][2] = { uint32 const availableChargeAurasAndSpells[3][2] = {
@@ -97,7 +87,7 @@ uint32 const availableChargeAurasAndSpells[3][2] = {
Position const nordrassilPosition = { 5503.713f, -3523.436f, 1608.781f, 0.0f }; Position const nordrassilPosition = { 5503.713f, -3523.436f, 1608.781f, 0.0f };
float const DOOMFIRE_OFFSET = 25.0f; float const DOOMFIRE_OFFSET = 15.0f;
uint8 const WISP_OFFSET = 40; uint8 const WISP_OFFSET = 40;
uint8 NEAR_POINT = 0; uint8 NEAR_POINT = 0;
@@ -158,14 +148,26 @@ struct npc_doomfire_spirit : public ScriptedAI
void Reset() override void Reset() override
{ {
Position randomPosition;
scheduler.CancelAll(); scheduler.CancelAll();
ScheduleTimedEvent(0s, [&]{ ScheduleTimedEvent(0s, [&] {
if (Creature* archimonde = _instance->GetCreature(DATA_ARCHIMONDE)) DoomfireMovement(randomPosition, me->GetPosition());
{
Position randomNearPosition = archimonde->GetRandomNearPosition(200.0f); me->GetMotionMaster()->MovePoint(NEAR_POINT, randomPosition);
me->GetMotionMaster()->MovePoint(NEAR_POINT, randomNearPosition); }, 1500ms);
} }
}, 6s);
void DoomfireMovement(Position& targetPos, Position mePos)
{
float angle = mePos.GetOrientation();
float distance = 100.0f;
float newAngle = angle + ((rand() % 181) - 90) * M_PI / 180;
float x = mePos.GetPositionX() + distance * cos(newAngle);
float y = mePos.GetPositionY() + distance * sin(newAngle);
targetPos = Position(x, y, me->GetPositionZ());
return;
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
@@ -291,18 +293,15 @@ struct boss_archimonde : public BossAI
Talk(SAY_AGGRO); Talk(SAY_AGGRO);
ScheduleTimedEvent(25s, 35s, [&] ScheduleTimedEvent(25s, 35s, [&]
{ {
scheduler.DelayGroup(GROUP_FEAR, 5s);
Talk(SAY_AIR_BURST); Talk(SAY_AIR_BURST);
DoCastRandomTarget(SPELL_AIR_BURST, 0, 0.0f, true, false, false); DoCastAOE(SPELL_AIR_BURST);
}, 25s, 40s); }, 25s, 40s);
ScheduleTimedEvent(25s, 35s, [&] ScheduleTimedEvent(25s, 35s, [&]
{ {
DoCastDoomFire(); DoCastDoomFire();
}, 20s); }, 20s);
ScheduleTimedEvent(25s, 35s, [&] ScheduleTimedEvent(25s, 35s, [&]
{
DoCastVictim(SPELL_FEAR);
}, 42s);
ScheduleTimedEvent(25s, 35s, [&]
{ {
DoCastRandomTarget(SPELL_GRIP_OF_THE_LEGION); DoCastRandomTarget(SPELL_GRIP_OF_THE_LEGION);
}, 5s, 25s); }, 5s, 25s);
@@ -344,9 +343,14 @@ struct boss_archimonde : public BossAI
}, 3500ms); }, 3500ms);
ScheduleTimedEvent(10min, [&] ScheduleTimedEvent(10min, [&]
{ {
DoCastRandomTarget(SPELL_FINGER_OF_DEATH); DoCastVictim(SPELL_RED_SKY_EFFECT);
}, 3500ms); DoCastVictim(SPELL_HAND_OF_DEATH);
}, 3s);
scheduler.Schedule(25s, 35s, GROUP_FEAR, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
context.Repeat(42s);
});
instance->SetData(DATA_SPAWN_WAVES, 1); instance->SetData(DATA_SPAWN_WAVES, 1);
} }
@@ -430,8 +434,11 @@ struct boss_archimonde : public BossAI
{ {
// hack because spell doesn't work? // hack because spell doesn't work?
Talk(SAY_DOOMFIRE); Talk(SAY_DOOMFIRE);
Position spiritPosition = me->GetRandomNearPosition(DOOMFIRE_OFFSET); float angle = 2 * M_PI * rand() / RAND_MAX;
Position doomfirePosition = me->GetRandomNearPosition(DOOMFIRE_OFFSET); float x = me->GetPositionX() + DOOMFIRE_OFFSET * cos(angle);
float y = me->GetPositionY() + DOOMFIRE_OFFSET * sin(angle);
Position spiritPosition = Position(x, y, me->GetPositionZ());
Position doomfirePosition = Position(x, y, me->GetPositionZ());
if (Creature* doomfireSpirit = me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, spiritPosition, TEMPSUMMON_TIMED_DESPAWN, 27000)) if (Creature* doomfireSpirit = me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, spiritPosition, TEMPSUMMON_TIMED_DESPAWN, 27000))
{ {
if (Creature* doomfire = me->SummonCreature(CREATURE_DOOMFIRE, doomfirePosition, TEMPSUMMON_TIMED_DESPAWN, 27000)) if (Creature* doomfire = me->SummonCreature(CREATURE_DOOMFIRE, doomfirePosition, TEMPSUMMON_TIMED_DESPAWN, 27000))
@@ -536,11 +543,30 @@ class spell_hand_of_death : public SpellScript
} }
}; };
class spell_air_burst : public SpellScript
{
PrepareSpellScript(spell_air_burst);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (Unit* victim = GetCaster()->GetVictim())
{
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_air_burst::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
void AddSC_boss_archimonde() void AddSC_boss_archimonde()
{ {
RegisterSpellScript(spell_red_sky_effect); RegisterSpellScript(spell_red_sky_effect);
RegisterSpellScript(spell_hand_of_death); RegisterSpellScript(spell_hand_of_death);
RegisterSpellScript(spell_finger_of_death); RegisterSpellScript(spell_finger_of_death);
RegisterSpellScript(spell_air_burst);
RegisterHyjalAI(boss_archimonde); RegisterHyjalAI(boss_archimonde);
RegisterHyjalAI(npc_ancient_wisp); RegisterHyjalAI(npc_ancient_wisp);
RegisterHyjalAI(npc_doomfire_spirit); RegisterHyjalAI(npc_doomfire_spirit);

View File

@@ -29,6 +29,6 @@ using namespace FourHorsemen;
void AddSC_boss_four_horsemen() void AddSC_boss_four_horsemen()
{ {
new boss_four_horsemen(); new boss_four_horsemen();
new spell_four_horsemen_mark(); RegisterSpellScript(spell_four_horsemen_mark_aura);
} }

View File

@@ -368,60 +368,54 @@ public:
}; };
}; };
class spell_four_horsemen_mark : public SpellScriptLoader class spell_four_horsemen_mark_aura : public AuraScript
{ {
public: PrepareAuraScript(spell_four_horsemen_mark_aura);
spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { }
class spell_four_horsemen_mark_AuraScript : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
PrepareAuraScript(spell_four_horsemen_mark_AuraScript); return ValidateSpellInfo({ SPELL_MARK_DAMAGE });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{ {
if (Unit* caster = GetCaster()) int32 damage;
switch (GetStackAmount())
{ {
int32 damage; case 1:
switch (GetStackAmount()) damage = 0;
{ break;
case 1: case 2:
damage = 0; damage = 500;
break; break;
case 2: case 3:
damage = 500; damage = 1500;
break; break;
case 3: case 4:
damage = 1500; damage = 4000;
break; break;
case 4: case 5:
damage = 4000; damage = 12500;
break; break;
case 5: case 6:
damage = 12500; damage = 20000;
break; break;
case 6: default:
damage = 20000; damage = 20000 + 1000 * (GetStackAmount() - 7);
break; break;
default: }
damage = 20000 + 1000 * (GetStackAmount() - 7); if (damage)
break; {
} caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
if (damage)
{
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
}
} }
} }
}
void Register() override void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const override
{ {
return new spell_four_horsemen_mark_AuraScript(); AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_aura::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
} }
}; };

View File

@@ -28,6 +28,6 @@ using namespace Gluth;
void AddSC_boss_gluth() void AddSC_boss_gluth()
{ {
new boss_gluth(); new boss_gluth();
new spell_gluth_decimate(); RegisterSpellScript(spell_gluth_decimate);
} }

View File

@@ -9,40 +9,41 @@
namespace Gluth { namespace Gluth {
enum GluthSpells enum Spells
{ {
GLUTH_SPELL_MORTAL_WOUND = 25646, SPELL_MORTAL_WOUND = 25646,
SPELL_ENRAGE_10 = 28371, SPELL_ENRAGE_10 = 28371,
SPELL_ENRAGE_25 = 54427, SPELL_ENRAGE_25 = 54427,
SPELL_DECIMATE_10 = 28374, SPELL_DECIMATE_10 = 28374,
SPELL_DECIMATE_25 = 54426, SPELL_DECIMATE_25 = 54426,
GLUTH_SPELL_BERSERK = 26662, SPELL_DECIMATE_DAMAGE = 28375,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306, SPELL_INFECTED_WOUND = 29306,
SPELL_CHOW_SEARCHER = 28404 SPELL_CHOW_SEARCHER = 28404
}; };
enum GluthEvents enum Events
{ {
GLUTH_EVENT_MORTAL_WOUND = 1, EVENT_MORTAL_WOUND = 1,
GLUTH_EVENT_ENRAGE = 2, EVENT_ENRAGE = 2,
GLUTH_EVENT_DECIMATE = 3, EVENT_DECIMATE = 3,
GLUTH_EVENT_BERSERK = 4, EVENT_BERSERK = 4,
GLUTH_EVENT_SUMMON_ZOMBIE = 5, EVENT_SUMMON_ZOMBIE = 5,
GLUTH_EVENT_CAN_EAT_ZOMBIE = 6 EVENT_CAN_EAT_ZOMBIE = 6
}; };
enum GluthMisc enum Misc
{ {
NPC_ZOMBIE_CHOW = 16360 NPC_ZOMBIE_CHOW = 16360
}; };
enum GluthEmotes enum Emotes
{ {
EMOTE_SPOTS_ONE = 0, EMOTE_SPOTS_ONE = 0,
EMOTE_DECIMATE = 1, EMOTE_DECIMATE = 1,
GLUTH_EMOTE_ENRAGE = 2, EMOTE_ENRAGE = 2,
EMOTE_DEVOURS_ALL = 3, EMOTE_DEVOURS_ALL = 3,
GLUTH_EMOTE_BERSERK = 4 EMOTE_BERSERK = 4
}; };
const Position zombiePos[3] = const Position zombiePos[3] =
@@ -102,12 +103,12 @@ public:
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
me->SetInCombatWithZone(); me->SetInCombatWithZone();
events.ScheduleEvent(GLUTH_EVENT_MORTAL_WOUND, 10s); events.ScheduleEvent(EVENT_MORTAL_WOUND, 10s);
events.ScheduleEvent(GLUTH_EVENT_ENRAGE, 22s); events.ScheduleEvent(EVENT_ENRAGE, 22s);
events.ScheduleEvent(GLUTH_EVENT_DECIMATE, RAID_MODE(110000, 90000)); events.ScheduleEvent(EVENT_DECIMATE, RAID_MODE(110000, 90000));
events.ScheduleEvent(GLUTH_EVENT_BERSERK, 6min); events.ScheduleEvent(EVENT_BERSERK, 6min);
events.ScheduleEvent(GLUTH_EVENT_SUMMON_ZOMBIE, 10s); events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10s);
events.ScheduleEvent(GLUTH_EVENT_CAN_EAT_ZOMBIE, 1s); events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1s);
} }
void JustSummoned(Creature* summon) override void JustSummoned(Creature* summon) override
@@ -171,24 +172,24 @@ public:
switch (events.ExecuteEvent()) switch (events.ExecuteEvent())
{ {
case GLUTH_EVENT_BERSERK: case EVENT_BERSERK:
me->CastSpell(me, GLUTH_SPELL_BERSERK, true); me->CastSpell(me, SPELL_BERSERK, true);
break; break;
case GLUTH_EVENT_ENRAGE: case EVENT_ENRAGE:
Talk(GLUTH_EMOTE_ENRAGE); Talk(EMOTE_ENRAGE);
me->CastSpell(me, RAID_MODE(SPELL_ENRAGE_10, SPELL_ENRAGE_25), true); me->CastSpell(me, RAID_MODE(SPELL_ENRAGE_10, SPELL_ENRAGE_25), true);
events.Repeat(22s); events.Repeat(22s);
break; break;
case GLUTH_EVENT_MORTAL_WOUND: case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), GLUTH_SPELL_MORTAL_WOUND, false); me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.Repeat(10s); events.Repeat(10s);
break; break;
case GLUTH_EVENT_DECIMATE: case EVENT_DECIMATE:
Talk(EMOTE_DECIMATE); Talk(EMOTE_DECIMATE);
me->CastSpell(me, RAID_MODE(SPELL_DECIMATE_10, SPELL_DECIMATE_25), false); me->CastSpell(me, RAID_MODE(SPELL_DECIMATE_10, SPELL_DECIMATE_25), false);
events.RepeatEvent(RAID_MODE(110000, 90000)); events.RepeatEvent(RAID_MODE(110000, 90000));
break; break;
case GLUTH_EVENT_SUMMON_ZOMBIE: case EVENT_SUMMON_ZOMBIE:
{ {
uint8 rand = urand(0, 2); uint8 rand = urand(0, 2);
for (int32 i = 0; i < RAID_MODE(1, 2); ++i) for (int32 i = 0; i < RAID_MODE(1, 2); ++i)
@@ -209,7 +210,7 @@ public:
events.Repeat(10s); events.Repeat(10s);
break; break;
} }
case GLUTH_EVENT_CAN_EAT_ZOMBIE: case EVENT_CAN_EAT_ZOMBIE:
events.RepeatEvent(1000); events.RepeatEvent(1000);
if (me->GetVictim()->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinMeleeRange(me->GetVictim())) if (me->GetVictim()->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinMeleeRange(me->GetVictim()))
{ {
@@ -224,44 +225,38 @@ public:
}; };
}; };
class spell_gluth_decimate : public SpellScriptLoader class spell_gluth_decimate : public SpellScript
{ {
public: PrepareSpellScript(spell_gluth_decimate);
spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { }
class spell_gluth_decimate_SpellScript : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
PrepareSpellScript(spell_gluth_decimate_SpellScript); return ValidateSpellInfo({ SPELL_DECIMATE_DAMAGE });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/) void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
{ {
if (Unit* unitTarget = GetHitUnit()) int32 damage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5));
if (damage <= 0)
return;
if (Creature* cTarget = unitTarget->ToCreature())
{ {
int32 damage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5)); cTarget->SetWalk(true);
if (damage <= 0) cTarget->GetMotionMaster()->MoveFollow(GetCaster(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
return; cTarget->SetReactState(REACT_PASSIVE);
Unit::DealDamage(GetCaster(), cTarget, damage);
if (Creature* cTarget = unitTarget->ToCreature()) return;
{
cTarget->SetWalk(true);
cTarget->GetMotionMaster()->MoveFollow(GetCaster(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
cTarget->SetReactState(REACT_PASSIVE);
Unit::DealDamage(GetCaster(), cTarget, damage);
return;
}
GetCaster()->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, damage, unitTarget);
} }
GetCaster()->CastCustomSpell(SPELL_DECIMATE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, unitTarget);
} }
}
void Register() override void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{ {
return new spell_gluth_decimate_SpellScript(); OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
} }
}; };

View File

@@ -30,6 +30,6 @@ void AddSC_boss_gothik()
{ {
new boss_gothik(); new boss_gothik();
new npc_boss_gothik_minion(); new npc_boss_gothik_minion();
new spell_gothik_shadow_bolt_volley(); RegisterSpellScript(spell_gothik_shadow_bolt_volley);
} }

View File

@@ -10,21 +10,21 @@
namespace Gothik { namespace Gothik {
enum GothikYells enum Yells
{ {
GOTHIK_SAY_INTRO_1 = 0, SAY_INTRO_1 = 0,
GOTHIK_SAY_INTRO_2 = 1, SAY_INTRO_2 = 1,
GOTHIK_SAY_INTRO_3 = 2, SAY_INTRO_3 = 2,
GOTHIK_SAY_INTRO_4 = 3, SAY_INTRO_4 = 3,
GOTHIK_SAY_PHASE_TWO = 4, SAY_PHASE_TWO = 4,
GOTHIK_SAY_DEATH = 5, SAY_DEATH = 5,
GOTHIK_SAY_KILL = 6, SAY_KILL = 6,
GOTHIK_EMOTE_PHASE_TWO = 7, EMOTE_PHASE_TWO = 7,
GOTHIK_EMOTE_GATE_OPENED = 8 EMOTE_GATE_OPENED = 8
}; };
enum GothikSpells enum Spells
{ {
// Gothik // Gothik
SPELL_HARVEST_SOUL = 28679, SPELL_HARVEST_SOUL = 28679,
@@ -60,7 +60,7 @@ enum GothikSpells
SPELL_STOMP = 27993 SPELL_STOMP = 27993
}; };
enum GothikMisc enum Misc
{ {
NPC_LIVING_TRAINEE = 16124, NPC_LIVING_TRAINEE = 16124,
NPC_LIVING_KNIGHT = 16125, NPC_LIVING_KNIGHT = 16125,
@@ -72,7 +72,7 @@ enum GothikMisc
//NPC_TRIGGER = 16137, fix me //NPC_TRIGGER = 16137, fix me
}; };
enum GothikEvents enum Events
{ {
// Gothik // Gothik
EVENT_SUMMON_ADDS = 1, EVENT_SUMMON_ADDS = 1,
@@ -241,7 +241,7 @@ public:
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
me->SetInCombatWithZone(); me->SetInCombatWithZone();
Talk(GOTHIK_SAY_INTRO_1); Talk(SAY_INTRO_1);
events.ScheduleEvent(EVENT_INTRO_2, 4s); events.ScheduleEvent(EVENT_INTRO_2, 4s);
events.ScheduleEvent(EVENT_INTRO_3, 9s); events.ScheduleEvent(EVENT_INTRO_3, 9s);
events.ScheduleEvent(EVENT_INTRO_4, 14s); events.ScheduleEvent(EVENT_INTRO_4, 14s);
@@ -303,7 +303,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER) if (who->GetTypeId() != TYPEID_PLAYER)
return; return;
Talk(GOTHIK_SAY_KILL); Talk(SAY_KILL);
if (pInstance) if (pInstance)
{ {
pInstance->SetData(DATA_IMMORTAL_FAIL, 0); pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -313,7 +313,7 @@ public:
void JustDied(Unit* killer) override void JustDied(Unit* killer) override
{ {
BossAI::JustDied(killer); BossAI::JustDied(killer);
Talk(GOTHIK_SAY_DEATH); Talk(SAY_DEATH);
summons.DespawnAll(); summons.DespawnAll();
if (pInstance) if (pInstance)
{ {
@@ -433,13 +433,13 @@ public:
switch (events.ExecuteEvent()) switch (events.ExecuteEvent())
{ {
case EVENT_INTRO_2: case EVENT_INTRO_2:
Talk(GOTHIK_SAY_INTRO_2); Talk(SAY_INTRO_2);
break; break;
case EVENT_INTRO_3: case EVENT_INTRO_3:
Talk(GOTHIK_SAY_INTRO_3); Talk(SAY_INTRO_3);
break; break;
case EVENT_INTRO_4: case EVENT_INTRO_4:
Talk(GOTHIK_SAY_INTRO_4); Talk(SAY_INTRO_4);
break; break;
case EVENT_SHADOW_BOLT: case EVENT_SHADOW_BOLT:
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SHADOW_BOLT_10, SPELL_SHADOW_BOLT_25), false); me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SHADOW_BOLT_10, SPELL_SHADOW_BOLT_25), false);
@@ -488,8 +488,8 @@ public:
else else
{ {
secondPhase = true; secondPhase = true;
Talk(GOTHIK_SAY_PHASE_TWO); Talk(SAY_PHASE_TWO);
Talk(GOTHIK_EMOTE_PHASE_TWO); Talk(EMOTE_PHASE_TWO);
me->CastSpell(me, SPELL_TELEPORT_LIVE, false); me->CastSpell(me, SPELL_TELEPORT_LIVE, false);
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE); me->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE);
@@ -510,7 +510,7 @@ public:
go->SetGoState(GO_STATE_ACTIVE); go->SetGoState(GO_STATE_ACTIVE);
} }
gateOpened = true; gateOpened = true;
Talk(GOTHIK_EMOTE_GATE_OPENED); Talk(EMOTE_GATE_OPENED);
} }
break; break;
} }
@@ -675,29 +675,23 @@ public:
}; };
}; };
class spell_gothik_shadow_bolt_volley : public SpellScriptLoader class spell_gothik_shadow_bolt_volley : public SpellScript
{ {
public: PrepareSpellScript(spell_gothik_shadow_bolt_volley);
spell_gothik_shadow_bolt_volley() : SpellScriptLoader("spell_gothik_shadow_bolt_volley") { }
class spell_gothik_shadow_bolt_volley_SpellScript : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
PrepareSpellScript(spell_gothik_shadow_bolt_volley_SpellScript); return ValidateSpellInfo({ SPELL_SHADOW_MARK });
}
void FilterTargets(std::list<WorldObject*>& targets) void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Acore::UnitAuraCheck(false, SPELL_SHADOW_MARK));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
{ {
return new spell_gothik_shadow_bolt_volley_SpellScript(); targets.remove_if(Acore::UnitAuraCheck(false, SPELL_SHADOW_MARK));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
} }
}; };

View File

@@ -31,7 +31,7 @@ void AddSC_boss_grobbulus()
{ {
new boss_grobbulus(); new boss_grobbulus();
new boss_grobbulus_poison_cloud(); new boss_grobbulus_poison_cloud();
new spell_grobbulus_mutating_injection(); RegisterSpellScript(spell_grobbulus_mutating_injection_aura);
new spell_grobbulus_poison(); RegisterSpellScript(spell_grobbulus_poison);
} }

View File

@@ -11,37 +11,37 @@
namespace Grobbulus { namespace Grobbulus {
enum GrobbulusSpells enum Spells
{ {
GROBBULUS_SPELL_POISON_CLOUD = 28240, SPELL_POISON_CLOUD = 28240,
GROBBULUS_SPELL_MUTATING_INJECTION = 28169, SPELL_MUTATING_INJECTION = 28169,
GROBBULUS_SPELL_MUTATING_EXPLOSION = 28206, SPELL_MUTATING_EXPLOSION = 28206,
GROBBULUS_SPELL_SLIME_SPRAY_10 = 28157, SPELL_SLIME_SPRAY_10 = 28157,
GROBBULUS_SPELL_SLIME_SPRAY_25 = 54364, SPELL_SLIME_SPRAY_25 = 54364,
GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158, SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158,
GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362, SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362,
GROBBULUS_SPELL_BERSERK = 26662, SPELL_BERSERK = 26662,
GROBBULUS_SPELL_BOMBARD_SLIME = 28280 SPELL_BOMBARD_SLIME = 28280
}; };
enum GrobbulusEmotes enum Emotes
{ {
GROBBULUS_EMOTE_SLIME = 0 EMOTE_SLIME = 0
}; };
enum GrobbulusEvents enum Events
{ {
GROBBULUS_EVENT_BERSERK = 1, EVENT_BERSERK = 1,
GROBBULUS_EVENT_POISON_CLOUD = 2, EVENT_POISON_CLOUD = 2,
GROBBULUS_EVENT_SLIME_SPRAY = 3, EVENT_SLIME_SPRAY = 3,
GROBBULUS_EVENT_MUTATING_INJECTION = 4 EVENT_MUTATING_INJECTION = 4
}; };
enum GrobbulusMisc enum Misc
{ {
GROBBULUS_NPC_FALLOUT_SLIME = 16290, NPC_FALLOUT_SLIME = 16290,
GROBBULUS_NPC_SEWAGE_SLIME = 16375, NPC_SEWAGE_SLIME = 16375,
GROBBULUS_NPC_STICHED_GIANT = 16025 NPC_STICHED_GIANT = 16025
}; };
class boss_grobbulus : public CreatureScript class boss_grobbulus : public CreatureScript
@@ -77,7 +77,7 @@ public:
void PullChamberAdds() void PullChamberAdds()
{ {
std::list<Creature*> StichedGiants; std::list<Creature*> StichedGiants;
me->GetCreaturesWithEntryInRange(StichedGiants, 300.0f, GROBBULUS_NPC_STICHED_GIANT); me->GetCreaturesWithEntryInRange(StichedGiants, 300.0f, NPC_STICHED_GIANT);
for (std::list<Creature*>::const_iterator itr = StichedGiants.begin(); itr != StichedGiants.end(); ++itr) for (std::list<Creature*>::const_iterator itr = StichedGiants.begin(); itr != StichedGiants.end(); ++itr)
{ {
(*itr)->ToCreature()->AI()->AttackStart(me->GetVictim()); (*itr)->ToCreature()->AI()->AttackStart(me->GetVictim());
@@ -89,23 +89,23 @@ public:
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
PullChamberAdds(); PullChamberAdds();
me->SetInCombatWithZone(); me->SetInCombatWithZone();
events.ScheduleEvent(GROBBULUS_EVENT_POISON_CLOUD, 15s); events.ScheduleEvent(EVENT_POISON_CLOUD, 15s);
events.ScheduleEvent(GROBBULUS_EVENT_MUTATING_INJECTION, 20s); events.ScheduleEvent(EVENT_MUTATING_INJECTION, 20s);
events.ScheduleEvent(GROBBULUS_EVENT_SLIME_SPRAY, 10s); events.ScheduleEvent(EVENT_SLIME_SPRAY, 10s);
events.ScheduleEvent(GROBBULUS_EVENT_BERSERK, RAID_MODE(720000, 540000)); events.ScheduleEvent(EVENT_BERSERK, RAID_MODE(720000, 540000));
} }
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{ {
if (spellInfo->Id == RAID_MODE(GROBBULUS_SPELL_SLIME_SPRAY_10, GROBBULUS_SPELL_SLIME_SPRAY_25) && target->GetTypeId() == TYPEID_PLAYER) if (spellInfo->Id == RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25) && target->GetTypeId() == TYPEID_PLAYER)
{ {
me->SummonCreature(GROBBULUS_NPC_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); me->SummonCreature(NPC_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
} }
} }
void JustSummoned(Creature* cr) override void JustSummoned(Creature* cr) override
{ {
if (cr->GetEntry() == GROBBULUS_NPC_FALLOUT_SLIME) if (cr->GetEntry() == NPC_FALLOUT_SLIME)
{ {
cr->SetInCombatWithZone(); cr->SetInCombatWithZone();
} }
@@ -136,9 +136,9 @@ public:
dropSludgeTimer += diff; dropSludgeTimer += diff;
if (!me->IsInCombat() && dropSludgeTimer >= 5000) if (!me->IsInCombat() && dropSludgeTimer >= 5000)
{ {
if (me->IsWithinDist3d(3178, -3305, 319, 5.0f) && !summons.HasEntry(GROBBULUS_NPC_SEWAGE_SLIME)) if (me->IsWithinDist3d(3178, -3305, 319, 5.0f) && !summons.HasEntry(NPC_SEWAGE_SLIME))
{ {
me->CastSpell(3128.96f + irand(-20, 20), -3312.96f + irand(-20, 20), 293.25f, GROBBULUS_SPELL_BOMBARD_SLIME, false); me->CastSpell(3128.96f + irand(-20, 20), -3312.96f + irand(-20, 20), 293.25f, SPELL_BOMBARD_SLIME, false);
} }
dropSludgeTimer = 0; dropSludgeTimer = 0;
} }
@@ -152,22 +152,22 @@ public:
switch (events.ExecuteEvent()) switch (events.ExecuteEvent())
{ {
case GROBBULUS_EVENT_POISON_CLOUD: case EVENT_POISON_CLOUD:
me->CastSpell(me, GROBBULUS_SPELL_POISON_CLOUD, true); me->CastSpell(me, SPELL_POISON_CLOUD, true);
events.Repeat(15s); events.Repeat(15s);
break; break;
case GROBBULUS_EVENT_BERSERK: case EVENT_BERSERK:
me->CastSpell(me, GROBBULUS_SPELL_BERSERK, true); me->CastSpell(me, SPELL_BERSERK, true);
break; break;
case GROBBULUS_EVENT_SLIME_SPRAY: case EVENT_SLIME_SPRAY:
Talk(GROBBULUS_EMOTE_SLIME); Talk(EMOTE_SLIME);
me->CastSpell(me->GetVictim(), RAID_MODE(GROBBULUS_SPELL_SLIME_SPRAY_10, GROBBULUS_SPELL_SLIME_SPRAY_25), false); me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25), false);
events.Repeat(20s); events.Repeat(20s);
break; break;
case GROBBULUS_EVENT_MUTATING_INJECTION: case EVENT_MUTATING_INJECTION:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, -GROBBULUS_SPELL_MUTATING_INJECTION)) if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, -SPELL_MUTATING_INJECTION))
{ {
me->CastSpell(target, GROBBULUS_SPELL_MUTATING_INJECTION, false); me->CastSpell(target, SPELL_MUTATING_INJECTION, false);
} }
events.RepeatEvent(6000 + uint32(120 * me->GetHealthPct())); events.RepeatEvent(6000 + uint32(120 * me->GetHealthPct()));
break; break;
@@ -217,7 +217,7 @@ public:
auraVisualTimer += diff; auraVisualTimer += diff;
if (auraVisualTimer >= 1000) if (auraVisualTimer >= 1000)
{ {
me->CastSpell(me, (me->GetMap()->Is25ManRaid() ? GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_25 : GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_10), true); me->CastSpell(me, (me->GetMap()->Is25ManRaid() ? SPELL_POISON_CLOUD_DAMAGE_AURA_25 : SPELL_POISON_CLOUD_DAMAGE_AURA_10), true);
auraVisualTimer = 0; auraVisualTimer = 0;
} }
} }
@@ -227,84 +227,62 @@ public:
}; };
}; };
class spell_grobbulus_poison : public SpellScriptLoader class spell_grobbulus_poison : public SpellScript
{ {
public: PrepareSpellScript(spell_grobbulus_poison);
spell_grobbulus_poison() : SpellScriptLoader("spell_grobbulus_poison") { }
class spell_grobbulus_poison_SpellScript : public SpellScript void FilterTargets(std::list<WorldObject*>& targets)
{ {
PrepareSpellScript(spell_grobbulus_poison_SpellScript); std::list<WorldObject*> tmplist;
for (auto& target : targets)
void FilterTargets(std::list<WorldObject*>& targets)
{ {
std::list<WorldObject*> tmplist; if (GetCaster()->IsWithinDist3d(target, 0.0f))
for (auto& target : targets)
{ {
if (GetCaster()->IsWithinDist3d(target, 0.0f)) tmplist.push_back(target);
{
tmplist.push_back(target);
}
}
targets.clear();
for (auto& itr : tmplist)
{
targets.push_back(itr);
} }
} }
targets.clear();
void Register() override for (auto& itr : tmplist)
{ {
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_grobbulus_poison_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); targets.push_back(itr);
} }
}; }
SpellScript* GetSpellScript() const override void Register() override
{ {
return new spell_grobbulus_poison_SpellScript(); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_grobbulus_poison::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
} }
}; };
class spell_grobbulus_mutating_injection : public SpellScriptLoader class spell_grobbulus_mutating_injection_aura : public AuraScript
{ {
public: PrepareAuraScript(spell_grobbulus_mutating_injection_aura);
spell_grobbulus_mutating_injection() : SpellScriptLoader("spell_grobbulus_mutating_injection") { }
class spell_grobbulus_mutating_injection_AuraScript : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_MUTATING_EXPLOSION });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
switch (GetTargetApplication()->GetRemoveMode())
{ {
PrepareAuraScript(spell_grobbulus_mutating_injection_AuraScript); case AURA_REMOVE_BY_ENEMY_SPELL:
case AURA_REMOVE_BY_EXPIRE:
bool Validate(SpellInfo const* /*spellInfo*/) override if (auto caster = GetCaster())
{
return ValidateSpellInfo({ GROBBULUS_SPELL_MUTATING_EXPLOSION });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
switch (GetTargetApplication()->GetRemoveMode())
{ {
case AURA_REMOVE_BY_ENEMY_SPELL: caster->CastSpell(GetTarget(), SPELL_MUTATING_EXPLOSION, true);
case AURA_REMOVE_BY_EXPIRE:
if (auto caster = GetCaster())
{
caster->CastSpell(GetTarget(), GROBBULUS_SPELL_MUTATING_EXPLOSION, true);
}
break;
default:
return;
} }
} break;
default:
void Register() override return;
{
AfterEffectRemove += AuraEffectRemoveFn(spell_grobbulus_mutating_injection_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_grobbulus_mutating_injection_AuraScript();
} }
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_grobbulus_mutating_injection_aura::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
}; };
} }

View File

@@ -29,7 +29,7 @@ void AddSC_boss_kelthuzad()
{ {
new boss_kelthuzad(); new boss_kelthuzad();
new boss_kelthuzad_minion(); new boss_kelthuzad_minion();
new spell_kelthuzad_frost_blast(); RegisterSpellScript(spell_kelthuzad_frost_blast);
new spell_kelthuzad_detonate_mana(); RegisterSpellScript(spell_kelthuzad_detonate_mana_aura);
} }

View File

@@ -9,25 +9,25 @@
namespace Kelthuzad { namespace Kelthuzad {
enum KelthuzadYells enum Yells
{ {
KELTHUZAD_SAY_ANSWER_REQUEST = 3, SAY_ANSWER_REQUEST = 3,
KELTHUZAD_SAY_TAUNT = 6, SAY_TAUNT = 6,
KELTHUZAD_SAY_AGGRO = 7, SAY_AGGRO = 7,
KELTHUZAD_SAY_SLAY = 8, SAY_SLAY = 8,
KELTHUZAD_SAY_DEATH = 9, SAY_DEATH = 9,
KELTHUZAD_SAY_CHAIN = 10, SAY_CHAIN = 10,
KELTHUZAD_SAY_FROST_BLAST = 11, SAY_FROST_BLAST = 11,
KELTHUZAD_SAY_REQUEST_AID = 12, SAY_REQUEST_AID = 12,
KELTHUZAD_EMOTE_PHASE_TWO = 13, EMOTE_PHASE_TWO = 13,
KELTHUZAD_SAY_SUMMON_MINIONS = 14, SAY_SUMMON_MINIONS = 14,
KELTHUZAD_SAY_SPECIAL = 15, SAY_SPECIAL = 15,
KELTHUZAD_EMOTE_GUARDIAN_FLEE = 0, EMOTE_GUARDIAN_FLEE = 0,
KELTHUZAD_EMOTE_GUARDIAN_APPEAR = 1 EMOTE_GUARDIAN_APPEAR = 1
}; };
enum KelthuzadSpells enum Spells
{ {
// Kel'Thzuad // Kel'Thzuad
SPELL_FROST_BOLT_SINGLE_10 = 28478, SPELL_FROST_BOLT_SINGLE_10 = 28478,
@@ -40,16 +40,16 @@ enum KelthuzadSpells
SPELL_MANA_DETONATION_DAMAGE = 27820, SPELL_MANA_DETONATION_DAMAGE = 27820,
SPELL_FROST_BLAST = 27808, SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, // 28408 script effect SPELL_CHAINS_OF_KELTHUZAD = 28410, // 28408 script effect
KELTHUZAD_SPELL_BERSERK = 28498, SPELL_BERSERK = 28498,
SPELL_KELTHUZAD_CHANNEL = 29423, SPELL_KELTHUZAD_CHANNEL = 29423,
// Minions // Minions
KELTHUZAD_SPELL_FRENZY = 28468, SPELL_FRENZY = 28468,
KELTHUZAD_SPELL_MORTAL_WOUND = 28467, SPELL_MORTAL_WOUND = 28467,
SPELL_BLOOD_TAP = 28470 SPELL_BLOOD_TAP = 28470
}; };
enum KelthuzadMisc enum Misc
{ {
NPC_SOLDIER_OF_THE_FROZEN_WASTES = 16427, NPC_SOLDIER_OF_THE_FROZEN_WASTES = 16427,
NPC_UNSTOPPABLE_ABOMINATION = 16428, NPC_UNSTOPPABLE_ABOMINATION = 16428,
@@ -62,24 +62,24 @@ enum KelthuzadMisc
ACTION_GUARDIANS_OFF = 4 ACTION_GUARDIANS_OFF = 4
}; };
enum KelthuzadEvent enum Event
{ {
// Kel'Thuzad // Kel'Thuzad
EVENT_SUMMON_SOLDIER = 1, EVENT_SUMMON_SOLDIER = 1,
EVENT_SUMMON_UNSTOPPABLE_ABOMINATION = 2, EVENT_SUMMON_UNSTOPPABLE_ABOMINATION = 2,
EVENT_SUMMON_SOUL_WEAVER = 3, EVENT_SUMMON_SOUL_WEAVER = 3,
KELTHUZAD_EVENT_PHASE_2 = 4, EVENT_PHASE_2 = 4,
EVENT_FROST_BOLT_SINGLE = 5, EVENT_FROST_BOLT_SINGLE = 5,
EVENT_FROST_BOLT_MULTI = 6, EVENT_FROST_BOLT_MULTI = 6,
EVENT_DETONATE_MANA = 7, EVENT_DETONATE_MANA = 7,
KELTHUZAD_EVENT_PHASE_3 = 8, EVENT_PHASE_3 = 8,
EVENT_P3_LICH_KING_SAY = 9, EVENT_P3_LICH_KING_SAY = 9,
EVENT_SHADOW_FISSURE = 10, EVENT_SHADOW_FISSURE = 10,
EVENT_FROST_BLAST = 11, EVENT_FROST_BLAST = 11,
EVENT_CHAINS = 12, EVENT_CHAINS = 12,
EVENT_SUMMON_GUARDIAN_OF_ICECROWN = 13, EVENT_SUMMON_GUARDIAN_OF_ICECROWN = 13,
EVENT_FLOOR_CHANGE = 14, EVENT_FLOOR_CHANGE = 14,
KELTHUZAD_EVENT_ENRAGE = 15, EVENT_ENRAGE = 15,
EVENT_SPAWN_POOL = 16, EVENT_SPAWN_POOL = 16,
// Minions // Minions
@@ -253,7 +253,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER) if (who->GetTypeId() != TYPEID_PLAYER)
return; return;
Talk(KELTHUZAD_SAY_SLAY); Talk(SAY_SLAY);
if (pInstance) if (pInstance)
{ {
pInstance->SetData(DATA_IMMORTAL_FAIL, 0); pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -266,9 +266,9 @@ public:
summons.DoAction(ACTION_GUARDIANS_OFF); summons.DoAction(ACTION_GUARDIANS_OFF);
if (Creature* guardian = summons.GetCreatureWithEntry(NPC_GUARDIAN_OF_ICECROWN)) if (Creature* guardian = summons.GetCreatureWithEntry(NPC_GUARDIAN_OF_ICECROWN))
{ {
guardian->AI()->Talk(KELTHUZAD_EMOTE_GUARDIAN_FLEE); guardian->AI()->Talk(EMOTE_GUARDIAN_FLEE);
} }
Talk(KELTHUZAD_SAY_DEATH); Talk(SAY_DEATH);
if (pInstance) if (pInstance)
{ {
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE))) if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE)))
@@ -287,7 +287,7 @@ public:
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
Talk(KELTHUZAD_SAY_SUMMON_MINIONS); Talk(SAY_SUMMON_MINIONS);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAttackers(); me->RemoveAllAttackers();
me->SetTarget(); me->SetTarget();
@@ -297,8 +297,8 @@ public:
events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 6400ms); events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 6400ms);
events.ScheduleEvent(EVENT_SUMMON_UNSTOPPABLE_ABOMINATION, 10s); events.ScheduleEvent(EVENT_SUMMON_UNSTOPPABLE_ABOMINATION, 10s);
events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 12s); events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 12s);
events.ScheduleEvent(KELTHUZAD_EVENT_PHASE_2, 228s); events.ScheduleEvent(EVENT_PHASE_2, 228s);
events.ScheduleEvent(KELTHUZAD_EVENT_ENRAGE, 15min); events.ScheduleEvent(EVENT_ENRAGE, 15min);
if (pInstance) if (pInstance)
{ {
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR))) if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR)))
@@ -366,9 +366,9 @@ public:
SummonHelper(NPC_SOUL_WEAVER, 1); SummonHelper(NPC_SOUL_WEAVER, 1);
events.Repeat(30s); events.Repeat(30s);
break; break;
case KELTHUZAD_EVENT_PHASE_2: case EVENT_PHASE_2:
Talk(KELTHUZAD_EMOTE_PHASE_TWO); Talk(EMOTE_PHASE_TWO);
Talk(KELTHUZAD_SAY_AGGRO); Talk(SAY_AGGRO);
events.Reset(); events.Reset();
summons.DoAction(ACTION_SECOND_PHASE); summons.DoAction(ACTION_SECOND_PHASE);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
@@ -378,7 +378,7 @@ public:
events.ScheduleEvent(EVENT_FROST_BOLT_SINGLE, 2s, 10s); events.ScheduleEvent(EVENT_FROST_BOLT_SINGLE, 2s, 10s);
events.ScheduleEvent(EVENT_FROST_BOLT_MULTI, 15s, 30s); events.ScheduleEvent(EVENT_FROST_BOLT_MULTI, 15s, 30s);
events.ScheduleEvent(EVENT_DETONATE_MANA, 30s); events.ScheduleEvent(EVENT_DETONATE_MANA, 30s);
events.ScheduleEvent(KELTHUZAD_EVENT_PHASE_3, 1s); events.ScheduleEvent(EVENT_PHASE_3, 1s);
events.ScheduleEvent(EVENT_SHADOW_FISSURE, 25s); events.ScheduleEvent(EVENT_SHADOW_FISSURE, 25s);
events.ScheduleEvent(EVENT_FROST_BLAST, 45s); events.ScheduleEvent(EVENT_FROST_BLAST, 45s);
if (Is25ManRaid()) if (Is25ManRaid())
@@ -386,8 +386,8 @@ public:
events.ScheduleEvent(EVENT_CHAINS, 90s); events.ScheduleEvent(EVENT_CHAINS, 90s);
} }
break; break;
case KELTHUZAD_EVENT_ENRAGE: case EVENT_ENRAGE:
me->CastSpell(me, KELTHUZAD_SPELL_BERSERK, true); me->CastSpell(me, SPELL_BERSERK, true);
break; break;
case EVENT_FROST_BOLT_SINGLE: case EVENT_FROST_BOLT_SINGLE:
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_FROST_BOLT_SINGLE_10, SPELL_FROST_BOLT_SINGLE_25), false); me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_FROST_BOLT_SINGLE_10, SPELL_FROST_BOLT_SINGLE_25), false);
@@ -409,7 +409,7 @@ public:
{ {
me->CastSpell(target, SPELL_FROST_BLAST, false); me->CastSpell(target, SPELL_FROST_BLAST, false);
} }
Talk(KELTHUZAD_SAY_FROST_BLAST); Talk(SAY_FROST_BLAST);
events.Repeat(45s); events.Repeat(45s);
break; break;
case EVENT_CHAINS: case EVENT_CHAINS:
@@ -420,7 +420,7 @@ public:
me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true); me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true);
} }
} }
Talk(KELTHUZAD_SAY_CHAIN); Talk(SAY_CHAIN);
events.Repeat(90s); events.Repeat(90s);
break; break;
case EVENT_DETONATE_MANA: case EVENT_DETONATE_MANA:
@@ -441,15 +441,15 @@ public:
auto itr = unitList.begin(); auto itr = unitList.begin();
advance(itr, urand(0, unitList.size() - 1)); advance(itr, urand(0, unitList.size() - 1));
me->CastSpell(*itr, SPELL_DETONATE_MANA, false); me->CastSpell(*itr, SPELL_DETONATE_MANA, false);
Talk(KELTHUZAD_SAY_SPECIAL); Talk(SAY_SPECIAL);
} }
events.Repeat(30s); events.Repeat(30s);
break; break;
} }
case KELTHUZAD_EVENT_PHASE_3: case EVENT_PHASE_3:
if (me->HealthBelowPct(45)) if (me->HealthBelowPct(45))
{ {
Talk(KELTHUZAD_SAY_REQUEST_AID); Talk(SAY_REQUEST_AID);
events.DelayEvents(5500ms); events.DelayEvents(5500ms);
events.ScheduleEvent(EVENT_P3_LICH_KING_SAY, 5s); events.ScheduleEvent(EVENT_P3_LICH_KING_SAY, 5s);
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_1))) if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_PORTAL_1)))
@@ -477,7 +477,7 @@ public:
{ {
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_LICH_KING_BOSS))) if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_LICH_KING_BOSS)))
{ {
cr->AI()->Talk(KELTHUZAD_SAY_ANSWER_REQUEST); cr->AI()->Talk(SAY_ANSWER_REQUEST);
} }
} }
for (uint8 i = 0 ; i < RAID_MODE(2, 4); ++i) for (uint8 i = 0 ; i < RAID_MODE(2, 4); ++i)
@@ -488,7 +488,7 @@ public:
case EVENT_SUMMON_GUARDIAN_OF_ICECROWN: case EVENT_SUMMON_GUARDIAN_OF_ICECROWN:
if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SpawnPool[RAND(0, 1, 3, 4)])) if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SpawnPool[RAND(0, 1, 3, 4)]))
{ {
cr->AI()->Talk(KELTHUZAD_EMOTE_GUARDIAN_APPEAR); cr->AI()->Talk(EMOTE_GUARDIAN_APPEAR);
cr->AI()->AttackStart(me->GetVictim()); cr->AI()->AttackStart(me->GetVictim());
} }
break; break;
@@ -631,13 +631,13 @@ public:
switch (events.ExecuteEvent()) switch (events.ExecuteEvent())
{ {
case EVENT_MINION_MORTAL_WOUND: case EVENT_MINION_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), KELTHUZAD_SPELL_MORTAL_WOUND, false); me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.Repeat(15s); events.Repeat(15s);
break; break;
case EVENT_MINION_FRENZY: case EVENT_MINION_FRENZY:
if (me->HealthBelowPct(35)) if (me->HealthBelowPct(35))
{ {
me->CastSpell(me, KELTHUZAD_SPELL_FRENZY, true); me->CastSpell(me, SPELL_FRENZY, true);
break; break;
} }
events.Repeat(1s); events.Repeat(1s);
@@ -652,82 +652,65 @@ public:
}; };
}; };
class spell_kelthuzad_frost_blast : public SpellScriptLoader class spell_kelthuzad_frost_blast : public SpellScript
{ {
public: PrepareSpellScript(spell_kelthuzad_frost_blast);
spell_kelthuzad_frost_blast() : SpellScriptLoader("spell_kelthuzad_frost_blast") { }
class spell_kelthuzad_frost_blast_SpellScript : public SpellScript bool Validate(SpellInfo const* /*spell*/) override
{ {
PrepareSpellScript(spell_kelthuzad_frost_blast_SpellScript); return ValidateSpellInfo({ SPELL_FROST_BLAST });
}
void FilterTargets(std::list<WorldObject*>& targets) void FilterTargets(std::list<WorldObject*>& targets)
{
Unit* caster = GetCaster();
if (!caster || !caster->ToCreature())
return;
std::list<WorldObject*> tmplist;
for (auto& target : targets)
{ {
Unit* caster = GetCaster(); if (!target->ToUnit()->HasAura(SPELL_FROST_BLAST))
if (!caster || !caster->ToCreature())
return;
std::list<WorldObject*> tmplist;
for (auto& target : targets)
{ {
if (!target->ToUnit()->HasAura(SPELL_FROST_BLAST)) tmplist.push_back(target);
{
tmplist.push_back(target);
}
}
targets.clear();
for (auto& itr : tmplist)
{
targets.push_back(itr);
} }
} }
targets.clear();
void Register() override for (auto& itr : tmplist)
{ {
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kelthuzad_frost_blast_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY); targets.push_back(itr);
} }
}; }
SpellScript* GetSpellScript() const override void Register() override
{ {
return new spell_kelthuzad_frost_blast_SpellScript(); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kelthuzad_frost_blast::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
} }
}; };
class spell_kelthuzad_detonate_mana : public SpellScriptLoader class spell_kelthuzad_detonate_mana_aura : public AuraScript
{ {
public: PrepareAuraScript(spell_kelthuzad_detonate_mana_aura);
spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
class spell_kelthuzad_detonate_mana_AuraScript : public AuraScript bool Validate(SpellInfo const* /*spell*/) override
{ {
PrepareAuraScript(spell_kelthuzad_detonate_mana_AuraScript); return ValidateSpellInfo({ SPELL_MANA_DETONATION_DAMAGE });
}
bool Validate(SpellInfo const* /*spell*/) override void HandleScript(AuraEffect const* aurEff)
{
return ValidateSpellInfo({ SPELL_MANA_DETONATION_DAMAGE });
}
void HandleScript(AuraEffect const* aurEff)
{
PreventDefaultAction();
Unit* target = GetTarget();
if (auto mana = int32(target->GetMaxPower(POWER_MANA) / 10))
{
mana = target->ModifyPower(POWER_MANA, -mana);
target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, nullptr, aurEff);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{ {
return new spell_kelthuzad_detonate_mana_AuraScript(); PreventDefaultAction();
Unit* target = GetTarget();
if (auto mana = int32(target->GetMaxPower(POWER_MANA) / 10))
{
mana = target->ModifyPower(POWER_MANA, -mana);
target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, nullptr, aurEff);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_aura::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
} }
}; };

View File

@@ -28,6 +28,6 @@ using namespace Sapphiron;
void AddSC_boss_sapphiron() void AddSC_boss_sapphiron()
{ {
new boss_sapphiron(); new boss_sapphiron();
new spell_sapphiron_frost_explosion(); RegisterSpellScript(spell_sapphiron_frost_explosion);
} }

View File

@@ -9,15 +9,15 @@
namespace Sapphiron { namespace Sapphiron {
enum SapphironYells enum Yells
{ {
EMOTE_AIR_PHASE = 0, EMOTE_AIR_PHASE = 0,
EMOTE_GROUND_PHASE = 1, EMOTE_GROUND_PHASE = 1,
EMOTE_BREATH = 2, EMOTE_BREATH = 2,
SAPPHIRON_EMOTE_ENRAGE = 3 EMOTE_ENRAGE = 3
}; };
enum SapphironSpells enum Spells
{ {
// Fight // Fight
SPELL_FROST_AURA_10 = 28531, SPELL_FROST_AURA_10 = 28531,
@@ -40,7 +40,7 @@ enum SapphironSpells
SPELL_SAPPHIRON_DIES = 29357 SPELL_SAPPHIRON_DIES = 29357
}; };
enum SapphironMisc enum Misc
{ {
GO_ICE_BLOCK = 181247, GO_ICE_BLOCK = 181247,
NPC_BLIZZARD = 16474, NPC_BLIZZARD = 16474,
@@ -48,9 +48,9 @@ enum SapphironMisc
POINT_CENTER = 1 POINT_CENTER = 1
}; };
enum SapphironEvents enum Events
{ {
SAPPHIRON_EVENT_BERSERK = 1, EVENT_BERSERK = 1,
EVENT_CLEAVE = 2, EVENT_CLEAVE = 2,
EVENT_TAIL_SWEEP = 3, EVENT_TAIL_SWEEP = 3,
EVENT_LIFE_DRAIN = 4, EVENT_LIFE_DRAIN = 4,
@@ -151,7 +151,7 @@ public:
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
EnterCombatSelfFunction(); EnterCombatSelfFunction();
me->CastSpell(me, RAID_MODE(SPELL_FROST_AURA_10, SPELL_FROST_AURA_25), true); me->CastSpell(me, RAID_MODE(SPELL_FROST_AURA_10, SPELL_FROST_AURA_25), true);
events.ScheduleEvent(SAPPHIRON_EVENT_BERSERK, 15min); events.ScheduleEvent(EVENT_BERSERK, 15min);
events.ScheduleEvent(EVENT_CLEAVE, 5s); events.ScheduleEvent(EVENT_CLEAVE, 5s);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 10s); events.ScheduleEvent(EVENT_TAIL_SWEEP, 10s);
events.ScheduleEvent(EVENT_LIFE_DRAIN, 17s); events.ScheduleEvent(EVENT_LIFE_DRAIN, 17s);
@@ -241,8 +241,8 @@ public:
switch (events.ExecuteEvent()) switch (events.ExecuteEvent())
{ {
case SAPPHIRON_EVENT_BERSERK: case EVENT_BERSERK:
Talk(SAPPHIRON_EMOTE_ENRAGE); Talk(EMOTE_ENRAGE);
me->CastSpell(me, SPELL_BERSERK, true); me->CastSpell(me, SPELL_BERSERK, true);
return; return;
case EVENT_CLEAVE: case EVENT_CLEAVE:
@@ -404,45 +404,34 @@ public:
}; };
}; };
class spell_sapphiron_frost_explosion : public SpellScriptLoader class spell_sapphiron_frost_explosion : public SpellScript
{ {
public: PrepareSpellScript(spell_sapphiron_frost_explosion);
spell_sapphiron_frost_explosion() : SpellScriptLoader("spell_sapphiron_frost_explosion") { }
class spell_sapphiron_frost_explosion_SpellScript : public SpellScript void FilterTargets(std::list<WorldObject*>& targets)
{ {
PrepareSpellScript(spell_sapphiron_frost_explosion_SpellScript); Unit* caster = GetCaster();
if (!caster || !caster->ToCreature())
return;
void FilterTargets(std::list<WorldObject*>& targets) std::list<WorldObject*> tmplist;
for (auto& target : targets)
{ {
Unit* caster = GetCaster(); if (CAST_AI(boss_sapphiron::boss_sapphironAI, caster->ToCreature()->AI())->IsValidExplosionTarget(target))
if (!caster || !caster->ToCreature())
return;
std::list<WorldObject*> tmplist;
for (auto& target : targets)
{ {
if (CAST_AI(boss_sapphiron::boss_sapphironAI, caster->ToCreature()->AI())->IsValidExplosionTarget(target)) tmplist.push_back(target);
{
tmplist.push_back(target);
}
}
targets.clear();
for (auto& itr : tmplist)
{
targets.push_back(itr);
} }
} }
targets.clear();
void Register() override for (auto& itr : tmplist)
{ {
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sapphiron_frost_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); targets.push_back(itr);
} }
}; }
SpellScript* GetSpellScript() const override void Register() override
{ {
return new spell_sapphiron_frost_explosion_SpellScript(); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sapphiron_frost_explosion::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
} }
}; };

View File

@@ -31,7 +31,7 @@ void AddSC_boss_thaddius()
new boss_thaddius(); new boss_thaddius();
new boss_thaddius_summon(); new boss_thaddius_summon();
new npc_tesla(); new npc_tesla();
new spell_thaddius_pos_neg_charge(); RegisterSpellScript(spell_thaddius_pos_neg_charge);
new spell_thaddius_polarity_shift(); RegisterSpellScript(spell_thaddius_polarity_shift);
new at_thaddius_entrance(); new at_thaddius_entrance();
} }

View File

@@ -9,7 +9,7 @@
namespace Thaddius { namespace Thaddius {
enum ThaddiusSays enum Says
{ {
// Stalagg // Stalagg
SAY_STAL_AGGRO = 0, SAY_STAL_AGGRO = 0,
@@ -26,11 +26,11 @@ enum ThaddiusSays
EMOTE_FEUG_REVIVE = 4, EMOTE_FEUG_REVIVE = 4,
// Thaddius // Thaddius
THADDIUS_SAY_GREET = 0, SAY_GREET = 0,
THADDIUS_SAY_AGGRO = 1, SAY_AGGRO = 1,
THADDIUS_SAY_SLAY = 2, SAY_SLAY = 2,
THADDIUS_SAY_ELECT = 3, SAY_ELECT = 3,
THADDIUS_SAY_DEATH = 4, SAY_DEATH = 4,
EMOTE_POLARITY_SHIFTED = 6, EMOTE_POLARITY_SHIFTED = 6,
// Tesla Coil // Tesla Coil
@@ -38,7 +38,7 @@ enum ThaddiusSays
EMOTE_TESLA_OVERLOAD = 1 EMOTE_TESLA_OVERLOAD = 1
}; };
enum ThaddiusSpells enum Spells
{ {
SPELL_MAGNETIC_PULL = 28337, SPELL_MAGNETIC_PULL = 28337,
SPELL_TESLA_SHOCK = 28099, SPELL_TESLA_SHOCK = 28099,
@@ -59,7 +59,7 @@ enum ThaddiusSpells
SPELL_BALL_LIGHTNING = 28299, SPELL_BALL_LIGHTNING = 28299,
SPELL_CHAIN_LIGHTNING_10 = 28167, SPELL_CHAIN_LIGHTNING_10 = 28167,
SPELL_CHAIN_LIGHTNING_25 = 54531, SPELL_CHAIN_LIGHTNING_25 = 54531,
THADDIUS_SPELL_BERSERK = 27680, SPELL_BERSERK = 27680,
SPELL_THADDIUS_VISUAL_LIGHTNING = 28136, SPELL_THADDIUS_VISUAL_LIGHTNING = 28136,
SPELL_THADDIUS_SPAWN_STUN = 28160, SPELL_THADDIUS_SPAWN_STUN = 28160,
@@ -71,7 +71,7 @@ enum ThaddiusSpells
SPELL_NEGATIVE_POLARITY = 28084 SPELL_NEGATIVE_POLARITY = 28084
}; };
enum ThaddiusEvents enum Events
{ {
EVENT_MINION_POWER_SURGE = 1, EVENT_MINION_POWER_SURGE = 1,
EVENT_MINION_MAGNETIC_PULL = 2, EVENT_MINION_MAGNETIC_PULL = 2,
@@ -86,7 +86,7 @@ enum ThaddiusEvents
EVENT_ALLOW_BALL_LIGHTNING = 10 EVENT_ALLOW_BALL_LIGHTNING = 10
}; };
enum ThaddiusMisc enum Misc
{ {
ACTION_MAGNETIC_PULL = 1, ACTION_MAGNETIC_PULL = 1,
ACTION_SUMMON_DIED = 2, ACTION_SUMMON_DIED = 2,
@@ -199,7 +199,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER) if (who->GetTypeId() != TYPEID_PLAYER)
return; return;
Talk(THADDIUS_SAY_SLAY); Talk(SAY_SLAY);
if (pInstance) if (pInstance)
{ {
pInstance->SetData(DATA_IMMORTAL_FAIL, 0); pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -209,7 +209,7 @@ public:
void JustDied(Unit* killer) override void JustDied(Unit* killer) override
{ {
BossAI::JustDied(killer); BossAI::JustDied(killer);
Talk(THADDIUS_SAY_DEATH); Talk(SAY_DEATH);
if (pInstance) if (pInstance)
{ {
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY); pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY);
@@ -316,7 +316,7 @@ public:
break; break;
} }
case EVENT_THADDIUS_ENTER_COMBAT: case EVENT_THADDIUS_ENTER_COMBAT:
Talk(THADDIUS_SAY_AGGRO); Talk(SAY_AGGRO);
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
me->SetControlled(false, UNIT_STATE_STUNNED); me->SetControlled(false, UNIT_STATE_STUNNED);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
@@ -326,7 +326,7 @@ public:
events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5s); events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5s);
return; return;
case EVENT_THADDIUS_BERSERK: case EVENT_THADDIUS_BERSERK:
me->CastSpell(me, THADDIUS_SPELL_BERSERK, true); me->CastSpell(me, SPELL_BERSERK, true);
break; break;
case EVENT_THADDIUS_CHAIN_LIGHTNING: case EVENT_THADDIUS_CHAIN_LIGHTNING:
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25), false); me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25), false);
@@ -592,121 +592,104 @@ public:
}; };
}; };
class spell_thaddius_pos_neg_charge : public SpellScriptLoader class spell_thaddius_pos_neg_charge : public SpellScript
{ {
public: PrepareSpellScript(spell_thaddius_pos_neg_charge);
spell_thaddius_pos_neg_charge() : SpellScriptLoader("spell_thaddius_pos_neg_charge") { }
class spell_thaddius_pos_neg_charge_SpellScript : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
PrepareSpellScript(spell_thaddius_pos_neg_charge_SpellScript); return ValidateSpellInfo({ SPELL_POSITIVE_CHARGE, SPELL_POSITIVE_CHARGE_STACK });
}
void HandleTargets(std::list<WorldObject*>& targets) void HandleTargets(std::list<WorldObject*>& targets)
{
uint8 count = 0;
for (auto& ihit : targets)
{ {
uint8 count = 0; if (ihit->GetGUID() != GetCaster()->GetGUID())
for (auto& ihit : targets)
{ {
if (ihit->GetGUID() != GetCaster()->GetGUID()) if (Player* target = ihit->ToPlayer())
{ {
if (Player* target = ihit->ToPlayer()) if (target->HasAura(GetTriggeringSpell()->Id))
{ {
if (target->HasAura(GetTriggeringSpell()->Id)) ++count;
{
++count;
}
} }
} }
} }
if (count)
{
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
}
} }
void HandleDamage(SpellEffIndex /*effIndex*/) if (count)
{ {
if (!GetTriggeringSpell()) uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
return; GetCaster()->SetAuraStack(spellId, GetCaster(), count);
Unit* target = GetHitUnit();
if (!target)
return;
if (target->HasAura(GetTriggeringSpell()->Id) || target->GetTypeId() != TYPEID_PLAYER)
{
SetHitDamage(0);
}
else if (target->GetInstanceScript())
{
target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0);
}
} }
}
void Register() override void HandleDamage(SpellEffIndex /*effIndex*/)
{
OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
SpellScript* GetSpellScript() const override
{ {
return new spell_thaddius_pos_neg_charge_SpellScript(); if (!GetTriggeringSpell())
return;
Unit* target = GetHitUnit();
if (!target)
return;
if (target->HasAura(GetTriggeringSpell()->Id) || target->GetTypeId() != TYPEID_PLAYER)
{
SetHitDamage(0);
}
else if (target->GetInstanceScript())
{
target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
} }
}; };
class spell_thaddius_polarity_shift : public SpellScriptLoader class spell_thaddius_polarity_shift : public SpellScript
{ {
public: PrepareSpellScript(spell_thaddius_polarity_shift);
spell_thaddius_polarity_shift() : SpellScriptLoader("spell_thaddius_polarity_shift") { }
class spell_thaddius_polarity_shift_SpellScript : public SpellScript bool Validate(SpellInfo const* /*spell*/) override
{ {
PrepareSpellScript(spell_thaddius_polarity_shift_SpellScript); return ValidateSpellInfo({ SPELL_POSITIVE_POLARITY, SPELL_NEGATIVE_POLARITY });
}
bool Validate(SpellInfo const* /*spell*/) override void HandleDummy(SpellEffIndex /* effIndex */)
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
{ {
return ValidateSpellInfo({ SPELL_POSITIVE_POLARITY, SPELL_NEGATIVE_POLARITY }); target->RemoveAurasDueToSpell(SPELL_POSITIVE_CHARGE_STACK);
target->RemoveAurasDueToSpell(SPELL_NEGATIVE_CHARGE_STACK);
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, caster->GetGUID());
} }
}
void HandleDummy(SpellEffIndex /* effIndex */) void HandleAfterCast()
{
if (GetCaster())
{ {
Unit* caster = GetCaster(); if (Creature* caster = GetCaster()->ToCreature())
if (Unit* target = GetHitUnit())
{ {
target->RemoveAurasDueToSpell(SPELL_POSITIVE_CHARGE_STACK); if (caster->GetEntry() == NPC_THADDIUS)
target->RemoveAurasDueToSpell(SPELL_NEGATIVE_CHARGE_STACK);
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, caster->GetGUID());
}
}
void HandleAfterCast()
{
if (GetCaster())
{
if (Creature* caster = GetCaster()->ToCreature())
{ {
if (caster->GetEntry() == NPC_THADDIUS) caster->AI()->Talk(SAY_ELECT);
{ caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
caster->AI()->Talk(THADDIUS_SAY_ELECT);
caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
}
} }
} }
} }
}
void Register() override void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
AfterCast += SpellCastFn(spell_thaddius_polarity_shift_SpellScript::HandleAfterCast);
}
};
SpellScript* GetSpellScript() const override
{ {
return new spell_thaddius_polarity_shift_SpellScript(); OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
AfterCast += SpellCastFn(spell_thaddius_polarity_shift::HandleAfterCast);
} }
}; };
@@ -744,7 +727,7 @@ public:
if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS_BOSS))) if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS_BOSS)))
{ {
thaddius->AI()->Talk(THADDIUS_SAY_GREET); thaddius->AI()->Talk(SAY_GREET);
} }
instance->SetData(DATA_HAD_THADDIUS_GREET, 1); instance->SetData(DATA_HAD_THADDIUS_GREET, 1);