Ruination
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user