Ruination

This commit is contained in:
luis
2026-09-15 23:28:14 -03:00
parent 18ed96f0b5
commit 1221562029
+116 -2
View File
@@ -146,6 +146,9 @@ enum WarlockSpells
SPELL_WARLOCK_SHARD_INSTABILITY = 1260269,
SPELL_WARLOCK_DARK_HARVEST = 1257052,
SPELL_WARLOCK_SHADOWBOLT_VOLLEY_AREA = 453176,
//WowCommunity
SPELL_WARLOCK_RUINATION = 428522,
SPELL_WARLOCK_RUINATION_AOE = 434635,
};
enum MiscSpells
@@ -159,6 +162,84 @@ enum WarlockSpellVisuals
SPELL_VISUAL_WARLOCK_BILESCOURGE_BOMBERS_CRASH = 75806
};
//WowCommunity
// 428522 - Ruination (passive)
// 434635 - Ruination
// Summoning a Pit Lord (228574) makes the warlock's next Chaos Bolt (Destruction) or
// Hand of Gul'dan (Demonology) become Ruination, replacing the cast with the meteor
// 434635. "Ruination ready" is derived from the presence of a freshly summoned, still
// alive Pit Lord among the caster's controlled units; each Pit Lord grants exactly one
// empowered cast before it is marked as consumed.
namespace
{
constexpr uint32 NPC_WARLOCK_PIT_LORD = 228574;
std::unordered_map<ObjectGuid, GuidUnorderedSet> sRuinationConsumedPitLords;
bool IsUnconsumedPitLord(Unit* unit, GuidUnorderedSet const& consumed)
{
return unit && unit->GetEntry() == NPC_WARLOCK_PIT_LORD && unit->IsAlive()
&& !consumed.contains(unit->GetGUID());
}
Unit* GetPendingPitLord(Unit* caster)
{
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return nullptr;
Player* player = caster->ToPlayer();
GuidUnorderedSet const& consumed = sRuinationConsumedPitLords[player->GetGUID()];
for (Unit* controlled : caster->m_Controlled)
if (IsUnconsumedPitLord(controlled, consumed))
return controlled;
Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*player, player->GetPetGUID());
return IsUnconsumedPitLord(pet, consumed) ? pet : nullptr;
}
bool IsRuinationReady(Unit* caster)
{
return caster && caster->HasAura(SPELL_WARLOCK_RUINATION) && GetPendingPitLord(caster);
}
void ConsumeRuination(Unit* caster)
{
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
Player* player = caster->ToPlayer();
GuidUnorderedSet& consumed = sRuinationConsumedPitLords[player->GetGUID()];
auto consume = [&consumed](Unit* unit)
{
if (unit && unit->GetEntry() == NPC_WARLOCK_PIT_LORD && unit->IsAlive() && !consumed.contains(unit->GetGUID()))
{
consumed.insert(unit->GetGUID());
return true;
}
return false;
};
for (Unit* controlled : caster->m_Controlled)
if (consume(controlled))
return;
consume(ObjectAccessor::GetCreatureOrPetOrVehicle(*player, player->GetPetGUID()));
}
}
class player_script_warl_ruination : public PlayerScript
{
public:
player_script_warl_ruination() : PlayerScript("player_script_warl_ruination") { }
void OnLogout(Player* player) override
{
sRuinationConsumedPitLords.erase(player->GetGUID());
}
};
// 146739 - Corruption
// 445474 - Wither
class spell_warl_absolute_corruption : public SpellScript
@@ -478,9 +559,25 @@ class spell_warl_chaos_bolt : public SpellScript
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
void HandleDummy(SpellEffIndex effIndex)
{
SetHitDamage(GetHitDamage() + CalculatePct(GetHitDamage(), GetCaster()->ToPlayer()->m_activePlayerData->SpellCritPercentage));
Unit* caster = GetCaster();
Unit* target = GetHitUnit();
if (target && IsRuinationReady(caster))
{
ConsumeRuination(caster);
PreventHitEffect(effIndex);
if (SpellInfo const* ruination = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_RUINATION_AOE, DIFFICULTY_NONE))
caster->CastSpell(target, SPELL_WARLOCK_RUINATION_AOE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_TIME | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
return;
}
SetHitDamage(GetHitDamage() + CalculatePct(GetHitDamage(), caster->ToPlayer()->m_activePlayerData->SpellCritPercentage));
}
void CalcCritChance(Unit const* /*victim*/, float& critChance)
@@ -1773,6 +1870,22 @@ class spell_warl_hand_of_guldan : public SpellScript
if (!caster || !target)
return;
if (IsRuinationReady(caster))
{
ConsumeRuination(caster);
// Suppress every database driven effect of Hand of Gul'dan (damage/summoning)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
PreventHitEffect(SpellEffIndex(i));
if (SpellInfo const* ruination = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_RUINATION_AOE, DIFFICULTY_NONE))
caster->CastSpell(target, SPELL_WARLOCK_RUINATION_AOE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_TIME | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
return;
}
SpellInfo const* summonSpellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_WILD_IMP_SUMMON, DIFFICULTY_NONE);
if (!summonSpellInfo)
return;
@@ -2554,6 +2667,7 @@ class spell_warl_mayhem : public AuraScript
void AddSC_warlock_spell_scripts()
{
new player_script_warl_ruination();
RegisterSpellScript(spell_warl_absolute_corruption);
RegisterSpellScript(spell_warl_backdraft);
RegisterSpellScript(spell_warl_banish);