Fix spell

This commit is contained in:
luis
2026-09-28 13:44:34 -03:00
parent c32ecb0a1c
commit deae0f63c7
+60 -7
View File
@@ -2283,27 +2283,80 @@ class spell_dk_arctic_assault : public AuraScript
};
// 194913 - Glacial Advance
//
// Effect 0 is a bare SPELL_EFFECT_DUMMY on TARGET_DEST_CASTER_FRONT - a location with no unit behind
// it. The damage used to be driven from OnEffectHitTarget, which a dest-only effect never reaches, so
// casting Glacial Advance did nothing at all: no spikes, no damage, no Razorice. The line is built from
// the caster's own facing plus the spell's own TargetA/TargetB radii, and each spike is a scheduled
// 195975 cast so the wave advances outward instead of erupting in a single step.
class spell_dk_glacial_advance : public SpellScript
{
// How long each rank of spikes waits before the next erupts further out.
static constexpr uint8 SPIKE_DELAY = 150;
// A wave wider than a single rank is only worth splitting sideways when the spell asks for one.
static constexpr uint8 SPIKE_COLUMNS = 3;
// Keeps a mistuned radius on 195975 from producing an unbounded line.
static constexpr uint8 MAX_SPIKES = 10;
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DK_GLACIAL_ADVANCE_DAMAGE });
}
void HandleDummy(SpellEffIndex effIndex)
void HandleCast()
{
PreventHitDefaultEffect(effIndex);
Unit* caster = GetCaster();
if (!caster)
return;
if (Unit* target = GetHitUnit())
GetCaster()->CastSpell(target, SPELL_DK_GLACIAL_ADVANCE_DAMAGE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_FULL_MASK,
.TriggeringSpell = GetSpell()
SpellInfo const* spellInfo = GetSpellInfo();
SpellInfo const* damageInfo = sSpellMgr->GetSpellInfo(SPELL_DK_GLACIAL_ADVANCE_DAMAGE, spellInfo->Difficulty);
if (!damageInfo)
return;
// Reach and width are read from the spell data instead of being hardcoded, so retuning
// TargetA/TargetB reshapes the line without touching this script.
SpellEffectInfo const& effect = spellInfo->GetEffect(EFFECT_0);
float const reach = effect.CalcRadius(caster, SpellTargetIndex::TargetA).Max;
float const width = effect.CalcRadius(caster, SpellTargetIndex::TargetB).Max;
if (reach <= 0.0f)
return;
// Each spike damages everything around its eruption point, so the step along the line is that
// radius: any wider leaves gaps, any narrower makes one target take several spikes' worth.
float const step = std::max(damageInfo->GetEffect(EFFECT_0).CalcRadius(caster, SpellTargetIndex::TargetA).Max, 1.0f);
uint32 const spikeCount = std::clamp<uint32>(uint32(reach / step), 1, MAX_SPIKES);
for (uint32 i = 0; i < spikeCount; ++i)
{
float const distance = step * (i + 1);
for (uint8 column = 0; column < SPIKE_COLUMNS; ++column)
{
// Spread the ranks across TargetB, capped at half a step apart so the columns of a
// single rank stay distinct instead of stacking on the caster's facing.
float const angle = width > 1.0f ? (column - (SPIKE_COLUMNS - 1) / 2.0f) * std::min(width / 2.0f / step, 1.0f) : 0.0f;
Position const spike = caster->GetNearPosition(distance, angle);
// The scheduler dies with the caster, so a captured raw pointer cannot outlive its owner.
caster->GetScheduler().Schedule(std::chrono::milliseconds(i * SPIKE_DELAY), [caster, spike](TaskContext /*context*/)
{
if (!caster->IsAlive())
return;
caster->CastSpell(spike, SPELL_DK_GLACIAL_ADVANCE_DAMAGE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_FULL_MASK
});
});
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_dk_glacial_advance::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
AfterCast += SpellCastFn(spell_dk_glacial_advance::HandleCast);
}
};