Merge branch 'azerothcore:master' into refactor(Scripts/Ulduar)SpellScripts

This commit is contained in:
Jelle Meeus
2024-06-10 19:56:53 +02:00
committed by GitHub
16 changed files with 325 additions and 405 deletions

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

@@ -0,0 +1,5 @@
-- DB update 2024_06_09_00 -> 2024_06_09_01
--
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 22357) AND (`source_type` = 0) AND (`id` IN (2));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(22357, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 26, 11090, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Reth\'hedron the Subduer - On Just Died - Quest Credit \'Subdue the Subduer\'');

View File

@@ -0,0 +1,5 @@
-- DB update 2024_06_09_01 -> 2024_06_09_02
--
UPDATE `creature_template` SET `AIName` = '' WHERE `entry` = 18145;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18145) AND (`source_type` = 0);

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

@@ -295,7 +295,7 @@ struct boss_archimonde : public BossAI
{
scheduler.DelayGroup(GROUP_FEAR, 5s);
Talk(SAY_AIR_BURST);
DoCastAOE(SPELL_AIR_BURST);
DoCastRandomTarget(SPELL_AIR_BURST);
}, 25s, 40s);
ScheduleTimedEvent(25s, 35s, [&]
{

View File

@@ -90,6 +90,7 @@ enum HyjalCreaturesIds
NPC_ALLIANCE_RIFLEMAN = 17921,
NPC_ALLIANCE_PRIEST = 17928,
NPC_ALLIANCE_SORCERESS = 17922,
NPC_GUARDIAN_ELEMENTAL = 18001,
// Horde Base
NPC_THRALL = 17852,
@@ -102,6 +103,7 @@ enum HyjalCreaturesIds
NPC_HORDE_PEON = 17937,
NPC_INFERNAL_RELAY = 18242,
NPC_INFERNAL_TARGET = 21075,
NPC_DIRE_WOLF = 17854,
// Night Elf Base
NPC_TYRANDE = 17948,

View File

@@ -51,11 +51,6 @@ ObjectData const creatureData[] =
{ 0, 0 }
};
ObjectData const objectData[] =
{
{ 0, 0 }
};
Milliseconds hyjalWaveTimers[4][MAX_WAVES_STANDARD]
{
{ 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 130000ms, 190000ms, 0ms }, // Winterchill
@@ -92,7 +87,7 @@ public:
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
LoadObjectData(creatureData, objectData);
LoadObjectData(creatureData, nullptr);
}
void Initialize() override
@@ -203,6 +198,8 @@ public:
break;
case NPC_TOWERING_INFERNAL:
case NPC_LESSER_DOOMGUARD:
case NPC_DIRE_WOLF:
case NPC_GUARDIAN_ELEMENTAL:
if (creature->IsSummon())
{
_summonedNPCs.insert(creature->GetGUID());
@@ -243,6 +240,8 @@ public:
break;
case NPC_TOWERING_INFERNAL:
case NPC_LESSER_DOOMGUARD:
case NPC_DIRE_WOLF:
case NPC_GUARDIAN_ELEMENTAL:
_summonedNPCs.erase(creature->GetGUID());
break;
case NPC_WINTERCHILL:
@@ -250,9 +249,9 @@ public:
case NPC_KAZROGAL:
case NPC_AZGALOR:
if (Creature* jaina = GetCreature(DATA_JAINA))
jaina->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
jaina->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
if (Creature* thrall = GetCreature(DATA_THRALL))
thrall->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
thrall->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
SetData(DATA_RESET_WAVES, 1);
break;
}
@@ -290,14 +289,14 @@ public:
}
// Despawn all alliance NPCs
_scheduler.Schedule(21000ms, [this](TaskContext)
scheduler.Schedule(21000ms, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// Spawn Roaring Flame after a delay
_scheduler.Schedule(30s, [this](TaskContext)
scheduler.Schedule(30s, [this](TaskContext)
{
for (ObjectGuid const& guid : _roaringFlameAlliance)
{
@@ -338,13 +337,13 @@ public:
}
}
_scheduler.Schedule(21000ms, [this](TaskContext)
scheduler.Schedule(21000ms, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
_scheduler.Schedule(30s, [this](TaskContext)
scheduler.Schedule(30s, [this](TaskContext)
{
for (ObjectGuid const& guid : _roaringFlameHorde)
if (GameObject* flame = instance->GetGameObject(guid))
@@ -399,6 +398,10 @@ public:
_bossWave = DATA_ARCHIMONDE;
ScheduleWaves(1ms, START_WAVE_NIGHT_ELF, MAX_WAVES_NIGHT_ELF, hyjalNightElfWaveTimers[0]);
}
if (_bossWave)
DoUpdateWorldState(WORLD_STATE_WAVES, 0);
break;
case DATA_SPAWN_INFERNALS:
{
@@ -419,84 +422,46 @@ public:
}
}
break;
case DATA_RESET_ALLIANCE:
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (_bossWave && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
});
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_HORDE:
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (_bossWave && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
});
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_NIGHT_ELF:
if (Creature* archimonde = GetCreature(DATA_ARCHIMONDE))
archimonde->DespawnOrUnsummon(0s, 300s);
[[fallthrough]];
case DATA_RESET_ALLIANCE:
case DATA_RESET_HORDE:
if (GetBossState(DATA_ANETHERON) != DONE)
{
for (ObjectGuid const& guid : _baseAlliance)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon(0s, 300s);
}
if (GetBossState(DATA_AZGALOR) != DONE)
{
for (ObjectGuid const& guid : _baseHorde)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon(0s, 300s);
}
for (ObjectGuid const& guid : _baseNightElf)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
creature->DespawnOrUnsummon(0s, 300s);
for (ObjectGuid const& guid : _encounterNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
if (Creature* archimonde = GetCreature(DATA_ARCHIMONDE))
archimonde->DespawnOrUnsummon();
// also force despawn boss summons
for (ObjectGuid const& guid : _summonedNPCs)
if (Creature* creature = instance->GetCreature(guid))
creature->DespawnOrUnsummon();
_scheduler.Schedule(300s, [this](TaskContext)
{
for (ObjectGuid const& guid : _baseNightElf)
if (Creature* creature = instance->GetCreature(guid))
creature->Respawn();
if (Creature* archi = GetCreature(DATA_ARCHIMONDE))
archi->Respawn();
});
if (_bossWave && (GetBossState(_bossWave) != DONE))
SetBossState(_bossWave, NOT_STARTED);
SetData(DATA_RESET_WAVES, 0);
break;
case DATA_RESET_WAVES:
_scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
_encounterNPCs.clear();
_summonedNPCs.clear();
_currentWave = 0;
@@ -533,10 +498,10 @@ public:
void ScheduleWaves(Milliseconds /* time */, uint8 startWaves, uint8 maxWaves, Milliseconds timerptr[])
{
// No overlapping!
_scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
scheduler.CancelGroup(CONTEXT_GROUP_WAVES);
trash = 0; // Reset counter here to avoid resetting the counter from scheduled waves. Required because creatures killed for RP events counts towards the kill counter as well, confirmed in Retail.
_scheduler.Schedule(1ms, [this, startWaves, maxWaves, timerptr](TaskContext context)
scheduler.Schedule(1ms, [this, startWaves, maxWaves, timerptr](TaskContext context)
{
// If all waves reached, cancel scheduling new ones
if (_currentWave >= maxWaves)
@@ -572,7 +537,7 @@ public:
void Update(uint32 diff) override
{
_scheduler.Update(diff);
scheduler.Update(diff);
}
void OnPlayerInWaterStateUpdate(Player* player, bool inWater) override
@@ -588,7 +553,6 @@ public:
uint8 _currentWave;
uint8 _bossWave;
uint8 _retreat;
TaskScheduler _scheduler;
GuidSet _encounterNPCs;
GuidSet _summonedNPCs;
GuidSet _baseAlliance;

View File

@@ -380,66 +380,60 @@ 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);
}
};
void AddSC_boss_four_horsemen()
{
new boss_four_horsemen();
new spell_four_horsemen_mark();
RegisterSpellScript(spell_four_horsemen_mark_aura);
}

View File

@@ -29,6 +29,7 @@ enum Spells
SPELL_ENRAGE_25 = 54427,
SPELL_DECIMATE_10 = 28374,
SPELL_DECIMATE_25 = 54426,
SPELL_DECIMATE_DAMAGE = 28375,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306,
SPELL_CHOW_SEARCHER = 28404
@@ -237,50 +238,44 @@ 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);
}
};
void AddSC_boss_gluth()
{
new boss_gluth();
new spell_gluth_decimate();
RegisterSpellScript(spell_gluth_decimate);
}

View File

@@ -688,29 +688,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);
}
};
@@ -718,6 +712,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

@@ -240,91 +240,69 @@ 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({ 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(), 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);
}
};
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

@@ -665,82 +665,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);
}
};
@@ -748,7 +731,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

@@ -417,51 +417,40 @@ 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);
}
};
void AddSC_boss_sapphiron()
{
new boss_sapphiron();
new spell_sapphiron_frost_explosion();
RegisterSpellScript(spell_sapphiron_frost_explosion);
}

View File

@@ -606,121 +606,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(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);
}
};
@@ -771,7 +754,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();
}