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_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_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_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);

View File

@@ -1386,7 +1386,26 @@ public:
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();

View File

@@ -71,22 +71,12 @@ enum Summons
enum Events
{
EVENT_DRAIN_WORLD_TREE = 1,
EVENT_SPELL_FEAR = 2,
EVENT_SPELL_AIR_BURST = 3,
EVENT_SPELL_GRIP_OF_THE_LEGION = 4,
EVENT_SPELL_UNLEASH_SOUL_CHARGES = 5,
EVENT_SPELL_DOOMFIRE = 6,
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
EVENT_ENRAGE = 0
};
enum SpellGroups
{
GROUP_FEAR = 0
};
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 };
float const DOOMFIRE_OFFSET = 25.0f;
float const DOOMFIRE_OFFSET = 15.0f;
uint8 const WISP_OFFSET = 40;
uint8 NEAR_POINT = 0;
@@ -158,14 +148,26 @@ struct npc_doomfire_spirit : public ScriptedAI
void Reset() override
{
Position randomPosition;
scheduler.CancelAll();
ScheduleTimedEvent(0s, [&]{
if (Creature* archimonde = _instance->GetCreature(DATA_ARCHIMONDE))
{
Position randomNearPosition = archimonde->GetRandomNearPosition(200.0f);
me->GetMotionMaster()->MovePoint(NEAR_POINT, randomNearPosition);
}
}, 6s);
ScheduleTimedEvent(0s, [&] {
DoomfireMovement(randomPosition, me->GetPosition());
me->GetMotionMaster()->MovePoint(NEAR_POINT, randomPosition);
}, 1500ms);
}
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
@@ -291,18 +293,15 @@ struct boss_archimonde : public BossAI
Talk(SAY_AGGRO);
ScheduleTimedEvent(25s, 35s, [&]
{
scheduler.DelayGroup(GROUP_FEAR, 5s);
Talk(SAY_AIR_BURST);
DoCastRandomTarget(SPELL_AIR_BURST, 0, 0.0f, true, false, false);
DoCastAOE(SPELL_AIR_BURST);
}, 25s, 40s);
ScheduleTimedEvent(25s, 35s, [&]
{
DoCastDoomFire();
}, 20s);
ScheduleTimedEvent(25s, 35s, [&]
{
DoCastVictim(SPELL_FEAR);
}, 42s);
ScheduleTimedEvent(25s, 35s, [&]
{
DoCastRandomTarget(SPELL_GRIP_OF_THE_LEGION);
}, 5s, 25s);
@@ -344,9 +343,14 @@ struct boss_archimonde : public BossAI
}, 3500ms);
ScheduleTimedEvent(10min, [&]
{
DoCastRandomTarget(SPELL_FINGER_OF_DEATH);
}, 3500ms);
DoCastVictim(SPELL_RED_SKY_EFFECT);
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);
}
@@ -430,8 +434,11 @@ struct boss_archimonde : public BossAI
{
// hack because spell doesn't work?
Talk(SAY_DOOMFIRE);
Position spiritPosition = me->GetRandomNearPosition(DOOMFIRE_OFFSET);
Position doomfirePosition = me->GetRandomNearPosition(DOOMFIRE_OFFSET);
float angle = 2 * M_PI * rand() / RAND_MAX;
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* 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()
{
RegisterSpellScript(spell_red_sky_effect);
RegisterSpellScript(spell_hand_of_death);
RegisterSpellScript(spell_finger_of_death);
RegisterSpellScript(spell_air_burst);
RegisterHyjalAI(boss_archimonde);
RegisterHyjalAI(npc_ancient_wisp);
RegisterHyjalAI(npc_doomfire_spirit);

View File

@@ -29,6 +29,6 @@ using namespace FourHorsemen;
void AddSC_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:
spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { }
PrepareAuraScript(spell_four_horsemen_mark_aura);
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;
switch (GetStackAmount())
{
case 1:
damage = 0;
break;
case 2:
damage = 500;
break;
case 3:
damage = 1500;
break;
case 4:
damage = 4000;
break;
case 5:
damage = 12500;
break;
case 6:
damage = 20000;
break;
default:
damage = 20000 + 1000 * (GetStackAmount() - 7);
break;
}
if (damage)
{
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
}
case 1:
damage = 0;
break;
case 2:
damage = 500;
break;
case 3:
damage = 1500;
break;
case 4:
damage = 4000;
break;
case 5:
damage = 12500;
break;
case 6:
damage = 20000;
break;
default:
damage = 20000 + 1000 * (GetStackAmount() - 7);
break;
}
if (damage)
{
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
}
}
}
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
void Register() 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()
{
new boss_gluth();
new spell_gluth_decimate();
RegisterSpellScript(spell_gluth_decimate);
}

View File

@@ -9,40 +9,41 @@
namespace Gluth {
enum GluthSpells
enum Spells
{
GLUTH_SPELL_MORTAL_WOUND = 25646,
SPELL_MORTAL_WOUND = 25646,
SPELL_ENRAGE_10 = 28371,
SPELL_ENRAGE_25 = 54427,
SPELL_DECIMATE_10 = 28374,
SPELL_DECIMATE_25 = 54426,
GLUTH_SPELL_BERSERK = 26662,
SPELL_DECIMATE_DAMAGE = 28375,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306,
SPELL_CHOW_SEARCHER = 28404
};
enum GluthEvents
enum Events
{
GLUTH_EVENT_MORTAL_WOUND = 1,
GLUTH_EVENT_ENRAGE = 2,
GLUTH_EVENT_DECIMATE = 3,
GLUTH_EVENT_BERSERK = 4,
GLUTH_EVENT_SUMMON_ZOMBIE = 5,
GLUTH_EVENT_CAN_EAT_ZOMBIE = 6
EVENT_MORTAL_WOUND = 1,
EVENT_ENRAGE = 2,
EVENT_DECIMATE = 3,
EVENT_BERSERK = 4,
EVENT_SUMMON_ZOMBIE = 5,
EVENT_CAN_EAT_ZOMBIE = 6
};
enum GluthMisc
enum Misc
{
NPC_ZOMBIE_CHOW = 16360
};
enum GluthEmotes
enum Emotes
{
EMOTE_SPOTS_ONE = 0,
EMOTE_DECIMATE = 1,
GLUTH_EMOTE_ENRAGE = 2,
EMOTE_ENRAGE = 2,
EMOTE_DEVOURS_ALL = 3,
GLUTH_EMOTE_BERSERK = 4
EMOTE_BERSERK = 4
};
const Position zombiePos[3] =
@@ -102,12 +103,12 @@ public:
{
BossAI::JustEngagedWith(who);
me->SetInCombatWithZone();
events.ScheduleEvent(GLUTH_EVENT_MORTAL_WOUND, 10s);
events.ScheduleEvent(GLUTH_EVENT_ENRAGE, 22s);
events.ScheduleEvent(GLUTH_EVENT_DECIMATE, RAID_MODE(110000, 90000));
events.ScheduleEvent(GLUTH_EVENT_BERSERK, 6min);
events.ScheduleEvent(GLUTH_EVENT_SUMMON_ZOMBIE, 10s);
events.ScheduleEvent(GLUTH_EVENT_CAN_EAT_ZOMBIE, 1s);
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10s);
events.ScheduleEvent(EVENT_ENRAGE, 22s);
events.ScheduleEvent(EVENT_DECIMATE, RAID_MODE(110000, 90000));
events.ScheduleEvent(EVENT_BERSERK, 6min);
events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10s);
events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1s);
}
void JustSummoned(Creature* summon) override
@@ -171,24 +172,24 @@ public:
switch (events.ExecuteEvent())
{
case GLUTH_EVENT_BERSERK:
me->CastSpell(me, GLUTH_SPELL_BERSERK, true);
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case GLUTH_EVENT_ENRAGE:
Talk(GLUTH_EMOTE_ENRAGE);
case EVENT_ENRAGE:
Talk(EMOTE_ENRAGE);
me->CastSpell(me, RAID_MODE(SPELL_ENRAGE_10, SPELL_ENRAGE_25), true);
events.Repeat(22s);
break;
case GLUTH_EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), GLUTH_SPELL_MORTAL_WOUND, false);
case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.Repeat(10s);
break;
case GLUTH_EVENT_DECIMATE:
case EVENT_DECIMATE:
Talk(EMOTE_DECIMATE);
me->CastSpell(me, RAID_MODE(SPELL_DECIMATE_10, SPELL_DECIMATE_25), false);
events.RepeatEvent(RAID_MODE(110000, 90000));
break;
case GLUTH_EVENT_SUMMON_ZOMBIE:
case EVENT_SUMMON_ZOMBIE:
{
uint8 rand = urand(0, 2);
for (int32 i = 0; i < RAID_MODE(1, 2); ++i)
@@ -209,7 +210,7 @@ public:
events.Repeat(10s);
break;
}
case GLUTH_EVENT_CAN_EAT_ZOMBIE:
case EVENT_CAN_EAT_ZOMBIE:
events.RepeatEvent(1000);
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:
spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { }
PrepareSpellScript(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));
if (damage <= 0)
return;
if (Creature* cTarget = unitTarget->ToCreature())
{
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);
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(SPELL_DECIMATE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, unitTarget);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
void Register() 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 npc_boss_gothik_minion();
new spell_gothik_shadow_bolt_volley();
RegisterSpellScript(spell_gothik_shadow_bolt_volley);
}

View File

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

View File

@@ -10,38 +10,38 @@
#include "naxxramas.h"
namespace Grobbulus {
enum GrobbulusSpells
enum Spells
{
GROBBULUS_SPELL_POISON_CLOUD = 28240,
GROBBULUS_SPELL_MUTATING_INJECTION = 28169,
GROBBULUS_SPELL_MUTATING_EXPLOSION = 28206,
GROBBULUS_SPELL_SLIME_SPRAY_10 = 28157,
GROBBULUS_SPELL_SLIME_SPRAY_25 = 54364,
GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158,
GROBBULUS_SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362,
GROBBULUS_SPELL_BERSERK = 26662,
GROBBULUS_SPELL_BOMBARD_SLIME = 28280
SPELL_POISON_CLOUD = 28240,
SPELL_MUTATING_INJECTION = 28169,
SPELL_MUTATING_EXPLOSION = 28206,
SPELL_SLIME_SPRAY_10 = 28157,
SPELL_SLIME_SPRAY_25 = 54364,
SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158,
SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362,
SPELL_BERSERK = 26662,
SPELL_BOMBARD_SLIME = 28280
};
enum GrobbulusEmotes
enum Emotes
{
GROBBULUS_EMOTE_SLIME = 0
EMOTE_SLIME = 0
};
enum GrobbulusEvents
enum Events
{
GROBBULUS_EVENT_BERSERK = 1,
GROBBULUS_EVENT_POISON_CLOUD = 2,
GROBBULUS_EVENT_SLIME_SPRAY = 3,
GROBBULUS_EVENT_MUTATING_INJECTION = 4
EVENT_BERSERK = 1,
EVENT_POISON_CLOUD = 2,
EVENT_SLIME_SPRAY = 3,
EVENT_MUTATING_INJECTION = 4
};
enum GrobbulusMisc
enum Misc
{
GROBBULUS_NPC_FALLOUT_SLIME = 16290,
GROBBULUS_NPC_SEWAGE_SLIME = 16375,
GROBBULUS_NPC_STICHED_GIANT = 16025
NPC_FALLOUT_SLIME = 16290,
NPC_SEWAGE_SLIME = 16375,
NPC_STICHED_GIANT = 16025
};
class boss_grobbulus : public CreatureScript
@@ -77,7 +77,7 @@ public:
void PullChamberAdds()
{
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)
{
(*itr)->ToCreature()->AI()->AttackStart(me->GetVictim());
@@ -89,23 +89,23 @@ public:
BossAI::JustEngagedWith(who);
PullChamberAdds();
me->SetInCombatWithZone();
events.ScheduleEvent(GROBBULUS_EVENT_POISON_CLOUD, 15s);
events.ScheduleEvent(GROBBULUS_EVENT_MUTATING_INJECTION, 20s);
events.ScheduleEvent(GROBBULUS_EVENT_SLIME_SPRAY, 10s);
events.ScheduleEvent(GROBBULUS_EVENT_BERSERK, RAID_MODE(720000, 540000));
events.ScheduleEvent(EVENT_POISON_CLOUD, 15s);
events.ScheduleEvent(EVENT_MUTATING_INJECTION, 20s);
events.ScheduleEvent(EVENT_SLIME_SPRAY, 10s);
events.ScheduleEvent(EVENT_BERSERK, RAID_MODE(720000, 540000));
}
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
{
if (cr->GetEntry() == GROBBULUS_NPC_FALLOUT_SLIME)
if (cr->GetEntry() == NPC_FALLOUT_SLIME)
{
cr->SetInCombatWithZone();
}
@@ -136,9 +136,9 @@ public:
dropSludgeTimer += diff;
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;
}
@@ -152,22 +152,22 @@ public:
switch (events.ExecuteEvent())
{
case GROBBULUS_EVENT_POISON_CLOUD:
me->CastSpell(me, GROBBULUS_SPELL_POISON_CLOUD, true);
case EVENT_POISON_CLOUD:
me->CastSpell(me, SPELL_POISON_CLOUD, true);
events.Repeat(15s);
break;
case GROBBULUS_EVENT_BERSERK:
me->CastSpell(me, GROBBULUS_SPELL_BERSERK, true);
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case GROBBULUS_EVENT_SLIME_SPRAY:
Talk(GROBBULUS_EMOTE_SLIME);
me->CastSpell(me->GetVictim(), RAID_MODE(GROBBULUS_SPELL_SLIME_SPRAY_10, GROBBULUS_SPELL_SLIME_SPRAY_25), false);
case EVENT_SLIME_SPRAY:
Talk(EMOTE_SLIME);
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25), false);
events.Repeat(20s);
break;
case GROBBULUS_EVENT_MUTATING_INJECTION:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, -GROBBULUS_SPELL_MUTATING_INJECTION))
case EVENT_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()));
break;
@@ -217,7 +217,7 @@ public:
auraVisualTimer += diff;
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;
}
}
@@ -227,84 +227,62 @@ public:
};
};
class spell_grobbulus_poison : public SpellScriptLoader
class spell_grobbulus_poison : public SpellScript
{
public:
spell_grobbulus_poison() : SpellScriptLoader("spell_grobbulus_poison") { }
PrepareSpellScript(spell_grobbulus_poison);
class spell_grobbulus_poison_SpellScript : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
PrepareSpellScript(spell_grobbulus_poison_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
std::list<WorldObject*> tmplist;
for (auto& target : targets)
{
std::list<WorldObject*> tmplist;
for (auto& target : targets)
if (GetCaster()->IsWithinDist3d(target, 0.0f))
{
if (GetCaster()->IsWithinDist3d(target, 0.0f))
{
tmplist.push_back(target);
}
}
targets.clear();
for (auto& itr : tmplist)
{
targets.push_back(itr);
tmplist.push_back(target);
}
}
void Register() override
targets.clear();
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:
spell_grobbulus_mutating_injection() : SpellScriptLoader("spell_grobbulus_mutating_injection") { }
PrepareAuraScript(spell_grobbulus_mutating_injection_aura);
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);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ GROBBULUS_SPELL_MUTATING_EXPLOSION });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
switch (GetTargetApplication()->GetRemoveMode())
case AURA_REMOVE_BY_ENEMY_SPELL:
case AURA_REMOVE_BY_EXPIRE:
if (auto caster = GetCaster())
{
case AURA_REMOVE_BY_ENEMY_SPELL:
case AURA_REMOVE_BY_EXPIRE:
if (auto caster = GetCaster())
{
caster->CastSpell(GetTarget(), GROBBULUS_SPELL_MUTATING_EXPLOSION, true);
}
break;
default:
return;
caster->CastSpell(GetTarget(), SPELL_MUTATING_EXPLOSION, true);
}
}
void Register() override
{
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();
break;
default:
return;
}
}
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_minion();
new spell_kelthuzad_frost_blast();
new spell_kelthuzad_detonate_mana();
RegisterSpellScript(spell_kelthuzad_frost_blast);
RegisterSpellScript(spell_kelthuzad_detonate_mana_aura);
}

View File

@@ -8,26 +8,26 @@
#include "naxxramas.h"
namespace Kelthuzad {
enum KelthuzadYells
enum Yells
{
KELTHUZAD_SAY_ANSWER_REQUEST = 3,
KELTHUZAD_SAY_TAUNT = 6,
KELTHUZAD_SAY_AGGRO = 7,
KELTHUZAD_SAY_SLAY = 8,
KELTHUZAD_SAY_DEATH = 9,
KELTHUZAD_SAY_CHAIN = 10,
KELTHUZAD_SAY_FROST_BLAST = 11,
KELTHUZAD_SAY_REQUEST_AID = 12,
KELTHUZAD_EMOTE_PHASE_TWO = 13,
KELTHUZAD_SAY_SUMMON_MINIONS = 14,
KELTHUZAD_SAY_SPECIAL = 15,
SAY_ANSWER_REQUEST = 3,
SAY_TAUNT = 6,
SAY_AGGRO = 7,
SAY_SLAY = 8,
SAY_DEATH = 9,
SAY_CHAIN = 10,
SAY_FROST_BLAST = 11,
SAY_REQUEST_AID = 12,
EMOTE_PHASE_TWO = 13,
SAY_SUMMON_MINIONS = 14,
SAY_SPECIAL = 15,
KELTHUZAD_EMOTE_GUARDIAN_FLEE = 0,
KELTHUZAD_EMOTE_GUARDIAN_APPEAR = 1
EMOTE_GUARDIAN_FLEE = 0,
EMOTE_GUARDIAN_APPEAR = 1
};
enum KelthuzadSpells
enum Spells
{
// Kel'Thzuad
SPELL_FROST_BOLT_SINGLE_10 = 28478,
@@ -40,16 +40,16 @@ enum KelthuzadSpells
SPELL_MANA_DETONATION_DAMAGE = 27820,
SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, // 28408 script effect
KELTHUZAD_SPELL_BERSERK = 28498,
SPELL_BERSERK = 28498,
SPELL_KELTHUZAD_CHANNEL = 29423,
// Minions
KELTHUZAD_SPELL_FRENZY = 28468,
KELTHUZAD_SPELL_MORTAL_WOUND = 28467,
SPELL_FRENZY = 28468,
SPELL_MORTAL_WOUND = 28467,
SPELL_BLOOD_TAP = 28470
};
enum KelthuzadMisc
enum Misc
{
NPC_SOLDIER_OF_THE_FROZEN_WASTES = 16427,
NPC_UNSTOPPABLE_ABOMINATION = 16428,
@@ -62,24 +62,24 @@ enum KelthuzadMisc
ACTION_GUARDIANS_OFF = 4
};
enum KelthuzadEvent
enum Event
{
// Kel'Thuzad
EVENT_SUMMON_SOLDIER = 1,
EVENT_SUMMON_UNSTOPPABLE_ABOMINATION = 2,
EVENT_SUMMON_SOUL_WEAVER = 3,
KELTHUZAD_EVENT_PHASE_2 = 4,
EVENT_PHASE_2 = 4,
EVENT_FROST_BOLT_SINGLE = 5,
EVENT_FROST_BOLT_MULTI = 6,
EVENT_DETONATE_MANA = 7,
KELTHUZAD_EVENT_PHASE_3 = 8,
EVENT_PHASE_3 = 8,
EVENT_P3_LICH_KING_SAY = 9,
EVENT_SHADOW_FISSURE = 10,
EVENT_FROST_BLAST = 11,
EVENT_CHAINS = 12,
EVENT_SUMMON_GUARDIAN_OF_ICECROWN = 13,
EVENT_FLOOR_CHANGE = 14,
KELTHUZAD_EVENT_ENRAGE = 15,
EVENT_ENRAGE = 15,
EVENT_SPAWN_POOL = 16,
// Minions
@@ -253,7 +253,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER)
return;
Talk(KELTHUZAD_SAY_SLAY);
Talk(SAY_SLAY);
if (pInstance)
{
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -266,9 +266,9 @@ public:
summons.DoAction(ACTION_GUARDIANS_OFF);
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 (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_GATE)))
@@ -287,7 +287,7 @@ public:
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(KELTHUZAD_SAY_SUMMON_MINIONS);
Talk(SAY_SUMMON_MINIONS);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAttackers();
me->SetTarget();
@@ -297,8 +297,8 @@ public:
events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 6400ms);
events.ScheduleEvent(EVENT_SUMMON_UNSTOPPABLE_ABOMINATION, 10s);
events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 12s);
events.ScheduleEvent(KELTHUZAD_EVENT_PHASE_2, 228s);
events.ScheduleEvent(KELTHUZAD_EVENT_ENRAGE, 15min);
events.ScheduleEvent(EVENT_PHASE_2, 228s);
events.ScheduleEvent(EVENT_ENRAGE, 15min);
if (pInstance)
{
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_KELTHUZAD_FLOOR)))
@@ -366,9 +366,9 @@ public:
SummonHelper(NPC_SOUL_WEAVER, 1);
events.Repeat(30s);
break;
case KELTHUZAD_EVENT_PHASE_2:
Talk(KELTHUZAD_EMOTE_PHASE_TWO);
Talk(KELTHUZAD_SAY_AGGRO);
case EVENT_PHASE_2:
Talk(EMOTE_PHASE_TWO);
Talk(SAY_AGGRO);
events.Reset();
summons.DoAction(ACTION_SECOND_PHASE);
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_MULTI, 15s, 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_FROST_BLAST, 45s);
if (Is25ManRaid())
@@ -386,8 +386,8 @@ public:
events.ScheduleEvent(EVENT_CHAINS, 90s);
}
break;
case KELTHUZAD_EVENT_ENRAGE:
me->CastSpell(me, KELTHUZAD_SPELL_BERSERK, true);
case EVENT_ENRAGE:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_FROST_BOLT_SINGLE:
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);
}
Talk(KELTHUZAD_SAY_FROST_BLAST);
Talk(SAY_FROST_BLAST);
events.Repeat(45s);
break;
case EVENT_CHAINS:
@@ -420,7 +420,7 @@ public:
me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true);
}
}
Talk(KELTHUZAD_SAY_CHAIN);
Talk(SAY_CHAIN);
events.Repeat(90s);
break;
case EVENT_DETONATE_MANA:
@@ -441,15 +441,15 @@ public:
auto itr = unitList.begin();
advance(itr, urand(0, unitList.size() - 1));
me->CastSpell(*itr, SPELL_DETONATE_MANA, false);
Talk(KELTHUZAD_SAY_SPECIAL);
Talk(SAY_SPECIAL);
}
events.Repeat(30s);
break;
}
case KELTHUZAD_EVENT_PHASE_3:
case EVENT_PHASE_3:
if (me->HealthBelowPct(45))
{
Talk(KELTHUZAD_SAY_REQUEST_AID);
Talk(SAY_REQUEST_AID);
events.DelayEvents(5500ms);
events.ScheduleEvent(EVENT_P3_LICH_KING_SAY, 5s);
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)))
{
cr->AI()->Talk(KELTHUZAD_SAY_ANSWER_REQUEST);
cr->AI()->Talk(SAY_ANSWER_REQUEST);
}
}
for (uint8 i = 0 ; i < RAID_MODE(2, 4); ++i)
@@ -488,7 +488,7 @@ public:
case EVENT_SUMMON_GUARDIAN_OF_ICECROWN:
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());
}
break;
@@ -631,13 +631,13 @@ public:
switch (events.ExecuteEvent())
{
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);
break;
case EVENT_MINION_FRENZY:
if (me->HealthBelowPct(35))
{
me->CastSpell(me, KELTHUZAD_SPELL_FRENZY, true);
me->CastSpell(me, SPELL_FRENZY, true);
break;
}
events.Repeat(1s);
@@ -652,82 +652,65 @@ public:
};
};
class spell_kelthuzad_frost_blast : public SpellScriptLoader
class spell_kelthuzad_frost_blast : public SpellScript
{
public:
spell_kelthuzad_frost_blast() : SpellScriptLoader("spell_kelthuzad_frost_blast") { }
PrepareSpellScript(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 (!caster || !caster->ToCreature())
return;
std::list<WorldObject*> tmplist;
for (auto& target : targets)
if (!target->ToUnit()->HasAura(SPELL_FROST_BLAST))
{
if (!target->ToUnit()->HasAura(SPELL_FROST_BLAST))
{
tmplist.push_back(target);
}
}
targets.clear();
for (auto& itr : tmplist)
{
targets.push_back(itr);
tmplist.push_back(target);
}
}
void Register() override
targets.clear();
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:
spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
PrepareAuraScript(spell_kelthuzad_detonate_mana_aura);
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
{
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
void HandleScript(AuraEffect const* aurEff)
{
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()
{
new boss_sapphiron();
new spell_sapphiron_frost_explosion();
RegisterSpellScript(spell_sapphiron_frost_explosion);
}

View File

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

View File

@@ -9,7 +9,7 @@
namespace Thaddius {
enum ThaddiusSays
enum Says
{
// Stalagg
SAY_STAL_AGGRO = 0,
@@ -26,11 +26,11 @@ enum ThaddiusSays
EMOTE_FEUG_REVIVE = 4,
// Thaddius
THADDIUS_SAY_GREET = 0,
THADDIUS_SAY_AGGRO = 1,
THADDIUS_SAY_SLAY = 2,
THADDIUS_SAY_ELECT = 3,
THADDIUS_SAY_DEATH = 4,
SAY_GREET = 0,
SAY_AGGRO = 1,
SAY_SLAY = 2,
SAY_ELECT = 3,
SAY_DEATH = 4,
EMOTE_POLARITY_SHIFTED = 6,
// Tesla Coil
@@ -38,7 +38,7 @@ enum ThaddiusSays
EMOTE_TESLA_OVERLOAD = 1
};
enum ThaddiusSpells
enum Spells
{
SPELL_MAGNETIC_PULL = 28337,
SPELL_TESLA_SHOCK = 28099,
@@ -59,7 +59,7 @@ enum ThaddiusSpells
SPELL_BALL_LIGHTNING = 28299,
SPELL_CHAIN_LIGHTNING_10 = 28167,
SPELL_CHAIN_LIGHTNING_25 = 54531,
THADDIUS_SPELL_BERSERK = 27680,
SPELL_BERSERK = 27680,
SPELL_THADDIUS_VISUAL_LIGHTNING = 28136,
SPELL_THADDIUS_SPAWN_STUN = 28160,
@@ -71,7 +71,7 @@ enum ThaddiusSpells
SPELL_NEGATIVE_POLARITY = 28084
};
enum ThaddiusEvents
enum Events
{
EVENT_MINION_POWER_SURGE = 1,
EVENT_MINION_MAGNETIC_PULL = 2,
@@ -86,7 +86,7 @@ enum ThaddiusEvents
EVENT_ALLOW_BALL_LIGHTNING = 10
};
enum ThaddiusMisc
enum Misc
{
ACTION_MAGNETIC_PULL = 1,
ACTION_SUMMON_DIED = 2,
@@ -199,7 +199,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER)
return;
Talk(THADDIUS_SAY_SLAY);
Talk(SAY_SLAY);
if (pInstance)
{
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -209,7 +209,7 @@ public:
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(THADDIUS_SAY_DEATH);
Talk(SAY_DEATH);
if (pInstance)
{
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY);
@@ -316,7 +316,7 @@ public:
break;
}
case EVENT_THADDIUS_ENTER_COMBAT:
Talk(THADDIUS_SAY_AGGRO);
Talk(SAY_AGGRO);
me->SetReactState(REACT_AGGRESSIVE);
me->SetControlled(false, UNIT_STATE_STUNNED);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
@@ -326,7 +326,7 @@ public:
events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5s);
return;
case EVENT_THADDIUS_BERSERK:
me->CastSpell(me, THADDIUS_SPELL_BERSERK, true);
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_THADDIUS_CHAIN_LIGHTNING:
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:
spell_thaddius_pos_neg_charge() : SpellScriptLoader("spell_thaddius_pos_neg_charge") { }
PrepareSpellScript(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;
for (auto& ihit : targets)
if (ihit->GetGUID() != GetCaster()->GetGUID())
{
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())
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);
}
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
}
}
void Register() override
{
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
void HandleDamage(SpellEffIndex /*effIndex*/)
{
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:
spell_thaddius_polarity_shift() : SpellScriptLoader("spell_thaddius_polarity_shift") { }
PrepareSpellScript(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 (Unit* target = GetHitUnit())
if (Creature* caster = GetCaster()->ToCreature())
{
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 HandleAfterCast()
{
if (GetCaster())
{
if (Creature* caster = GetCaster()->ToCreature())
if (caster->GetEntry() == NPC_THADDIUS)
{
if (caster->GetEntry() == NPC_THADDIUS)
{
caster->AI()->Talk(THADDIUS_SAY_ELECT);
caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
}
caster->AI()->Talk(SAY_ELECT);
caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
}
}
}
}
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
void Register() 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)))
{
thaddius->AI()->Talk(THADDIUS_SAY_GREET);
thaddius->AI()->Talk(SAY_GREET);
}
instance->SetData(DATA_HAD_THADDIUS_GREET, 1);