mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-13 11:43:18 -04:00
599 lines
22 KiB
C++
599 lines
22 KiB
C++
/*
|
|
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* Scripts for spells with SPELLFAMILY_MONK and SPELLFAMILY_GENERIC spells used by monk players.
|
|
* Scriptnames of files in this file should be prefixed with "spell_monk_".
|
|
*/
|
|
|
|
#include "ScriptMgr.h"
|
|
#include "DB2Stores.h"
|
|
#include "Player.h"
|
|
#include "Spell.h"
|
|
#include "SpellAuraEffects.h"
|
|
#include "SpellInfo.h"
|
|
#include "SpellMgr.h"
|
|
#include "SpellScript.h"
|
|
|
|
enum MonkSpells
|
|
{
|
|
SPELL_MONK_CALMING_COALESCENCE = 388220,
|
|
SPELL_MONK_COMBAT_CONDITIONING = 128595,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL = 117952,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC = 123333,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK = 117962,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD = 117953,
|
|
SPELL_MONK_MORTAL_WOUNDS = 115804,
|
|
SPELL_MONK_POWER_STRIKE_PROC = 129914,
|
|
SPELL_MONK_POWER_STRIKE_ENERGIZE = 121283,
|
|
SPELL_MONK_PROVOKE_SINGLE_TARGET = 116189,
|
|
SPELL_MONK_PROVOKE_AOE = 118635,
|
|
SPELL_MONK_NO_FEATHER_FALL = 79636,
|
|
SPELL_MONK_OPEN_PALM_STRIKES_TALENT = 392970,
|
|
SPELL_MONK_ROLL_BACKWARD = 109131,
|
|
SPELL_MONK_ROLL_FORWARD = 107427,
|
|
SPELL_MONK_SOOTHING_MIST = 115175,
|
|
SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE = 154436,
|
|
SPELL_MONK_STAGGER_DAMAGE_AURA = 124255,
|
|
SPELL_MONK_STAGGER_HEAVY = 124273,
|
|
SPELL_MONK_STAGGER_LIGHT = 124275,
|
|
SPELL_MONK_STAGGER_MODERATE = 124274,
|
|
SPELL_MONK_SURGING_MIST_HEAL = 116995,
|
|
};
|
|
|
|
// 117952 - Crackling Jade Lightning
|
|
class spell_monk_crackling_jade_lightning : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo(
|
|
{
|
|
SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC
|
|
});
|
|
}
|
|
|
|
void OnTick(AuraEffect const* /*aurEff*/)
|
|
{
|
|
if (Unit* caster = GetCaster())
|
|
if (caster->HasAura(SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE))
|
|
caster->CastSpell(caster, SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC, TRIGGERED_FULL_MASK);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_crackling_jade_lightning::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
|
}
|
|
};
|
|
|
|
// 117959 - Crackling Jade Lightning
|
|
class spell_monk_crackling_jade_lightning_knockback_proc_aura : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo(
|
|
{
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK,
|
|
SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD
|
|
});
|
|
}
|
|
|
|
bool CheckProc(ProcEventInfo& eventInfo)
|
|
{
|
|
if (GetTarget()->HasAura(SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD))
|
|
return false;
|
|
|
|
if (eventInfo.GetActor()->HasAura(SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL, GetTarget()->GetGUID()))
|
|
return false;
|
|
|
|
Spell* currentChanneledSpell = GetTarget()->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
|
if (!currentChanneledSpell || currentChanneledSpell->GetSpellInfo()->Id != SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& eventInfo)
|
|
{
|
|
GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK, TRIGGERED_FULL_MASK);
|
|
GetTarget()->CastSpell(GetTarget(), SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD, TRIGGERED_FULL_MASK);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
DoCheckProc += AuraCheckProcFn(spell_monk_crackling_jade_lightning_knockback_proc_aura::CheckProc);
|
|
OnEffectProc += AuraEffectProcFn(spell_monk_crackling_jade_lightning_knockback_proc_aura::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 116849 - Life Cocoon
|
|
class spell_monk_life_cocoon : public SpellScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_CALMING_COALESCENCE });
|
|
}
|
|
|
|
void CalculateAbsorb(SpellEffIndex /*effIndex*/)
|
|
{
|
|
int32 absorb = GetCaster()->CountPctFromMaxHealth(GetEffectValue());
|
|
if (Player* player = GetCaster()->ToPlayer())
|
|
AddPct(absorb, player->GetRatingBonusValue(CR_VERSATILITY_HEALING_DONE));
|
|
|
|
if (AuraEffect* calmingCoalescence = GetCaster()->GetAuraEffect(SPELL_MONK_CALMING_COALESCENCE, EFFECT_0, GetCaster()->GetGUID()))
|
|
{
|
|
AddPct(absorb, calmingCoalescence->GetAmount());
|
|
calmingCoalescence->GetBase()->Remove();
|
|
}
|
|
|
|
GetSpell()->SetSpellValue(SPELLVALUE_BASE_POINT0, absorb);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectLaunch += SpellEffectFn(spell_monk_life_cocoon::CalculateAbsorb, EFFECT_2, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 392972 - Open Palm Strikes
|
|
class spell_monk_open_palm_strikes : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellEffect({ { SPELL_MONK_OPEN_PALM_STRIKES_TALENT, EFFECT_1} });
|
|
}
|
|
|
|
bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*procInfo*/)
|
|
{
|
|
AuraEffect const* talent = GetTarget()->GetAuraEffect(SPELL_MONK_OPEN_PALM_STRIKES_TALENT, EFFECT_1);
|
|
return talent && roll_chance_i(talent->GetAmount());
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
DoCheckEffectProc += AuraCheckEffectProcFn(spell_monk_open_palm_strikes::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
|
|
}
|
|
};
|
|
|
|
// 121817 - Power Strike
|
|
class spell_monk_power_strike_periodic : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_POWER_STRIKE_PROC });
|
|
}
|
|
|
|
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
|
{
|
|
GetTarget()->CastSpell(GetTarget(), SPELL_MONK_POWER_STRIKE_PROC, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_power_strike_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 129914 - Power Strike Proc
|
|
class spell_monk_power_strike_proc : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_POWER_STRIKE_ENERGIZE });
|
|
}
|
|
|
|
void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
|
|
{
|
|
GetTarget()->CastSpell(GetTarget(), SPELL_MONK_POWER_STRIKE_ENERGIZE, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectProc += AuraEffectProcFn(spell_monk_power_strike_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 115546 - Provoke
|
|
class spell_monk_provoke : public SpellScript
|
|
{
|
|
static uint32 const BlackOxStatusEntry = 61146;
|
|
|
|
bool Validate(SpellInfo const* spellInfo) override
|
|
{
|
|
if (!(spellInfo->GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK)) // ensure GetExplTargetUnit() will return something meaningful during CheckCast
|
|
return false;
|
|
return ValidateSpellInfo(
|
|
{
|
|
SPELL_MONK_PROVOKE_SINGLE_TARGET,
|
|
SPELL_MONK_PROVOKE_AOE
|
|
});
|
|
}
|
|
|
|
SpellCastResult CheckExplicitTarget()
|
|
{
|
|
if (GetExplTargetUnit()->GetEntry() != BlackOxStatusEntry)
|
|
{
|
|
SpellInfo const* singleTarget = sSpellMgr->AssertSpellInfo(SPELL_MONK_PROVOKE_SINGLE_TARGET, GetCastDifficulty());
|
|
SpellCastResult singleTargetExplicitResult = singleTarget->CheckExplicitTarget(GetCaster(), GetExplTargetUnit());
|
|
if (singleTargetExplicitResult != SPELL_CAST_OK)
|
|
return singleTargetExplicitResult;
|
|
}
|
|
else if (GetExplTargetUnit()->GetOwnerGUID() != GetCaster()->GetGUID())
|
|
return SPELL_FAILED_BAD_TARGETS;
|
|
|
|
return SPELL_CAST_OK;
|
|
}
|
|
|
|
void HandleDummy(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
if (GetHitUnit()->GetEntry() != BlackOxStatusEntry)
|
|
GetCaster()->CastSpell(GetHitUnit(), SPELL_MONK_PROVOKE_SINGLE_TARGET, true);
|
|
else
|
|
GetCaster()->CastSpell(GetHitUnit(), SPELL_MONK_PROVOKE_AOE, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_monk_provoke::CheckExplicitTarget);
|
|
OnEffectHitTarget += SpellEffectFn(spell_monk_provoke::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 107428 - Rising Sun Kick
|
|
class spell_monk_rising_sun_kick : public SpellScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_COMBAT_CONDITIONING, SPELL_MONK_MORTAL_WOUNDS });
|
|
}
|
|
|
|
bool Load() override
|
|
{
|
|
return GetCaster()->HasAura(SPELL_MONK_COMBAT_CONDITIONING);
|
|
}
|
|
|
|
void HandleOnHit(SpellEffIndex /*effIndex*/) const
|
|
{
|
|
GetCaster()->CastSpell(GetHitUnit(), SPELL_MONK_MORTAL_WOUNDS, CastSpellExtraArgsInit{
|
|
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
|
|
.TriggeringSpell = GetSpell()
|
|
});
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectLaunchTarget += SpellEffectFn(spell_monk_rising_sun_kick::HandleOnHit, EFFECT_0, SPELL_EFFECT_TRIGGER_SPELL);
|
|
}
|
|
};
|
|
|
|
// 109132 - Roll
|
|
class spell_monk_roll : public SpellScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_ROLL_BACKWARD, SPELL_MONK_ROLL_FORWARD, SPELL_MONK_NO_FEATHER_FALL });
|
|
}
|
|
|
|
SpellCastResult CheckCast()
|
|
{
|
|
if (GetCaster()->HasUnitState(UNIT_STATE_ROOT))
|
|
return SPELL_FAILED_ROOTED;
|
|
return SPELL_CAST_OK;
|
|
}
|
|
|
|
void HandleDummy(SpellEffIndex /*effIndex*/)
|
|
{
|
|
GetCaster()->CastSpell(GetCaster(), GetCaster()->HasUnitMovementFlag(MOVEMENTFLAG_BACKWARD) ? SPELL_MONK_ROLL_BACKWARD : SPELL_MONK_ROLL_FORWARD,
|
|
TRIGGERED_IGNORE_CAST_IN_PROGRESS);
|
|
GetCaster()->CastSpell(GetCaster(), SPELL_MONK_NO_FEATHER_FALL, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_monk_roll::CheckCast);
|
|
OnEffectHitTarget += SpellEffectFn(spell_monk_roll::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
// 107427 - Roll
|
|
// 109131 - Roll (backward)
|
|
class spell_monk_roll_aura : public AuraScript
|
|
{
|
|
void CalcMovementAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
|
|
{
|
|
amount += 100;
|
|
}
|
|
|
|
void CalcImmunityAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
|
|
{
|
|
amount -= 100;
|
|
}
|
|
|
|
void ChangeRunBackSpeed(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetTarget()->SetSpeed(MOVE_RUN_BACK, GetTarget()->GetSpeed(MOVE_RUN));
|
|
}
|
|
|
|
void RestoreRunBackSpeed(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetTarget()->UpdateSpeed(MOVE_RUN_BACK);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
// Values need manual correction
|
|
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcMovementAmount, EFFECT_0, SPELL_AURA_MOD_SPEED_NO_CONTROL);
|
|
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcMovementAmount, EFFECT_2, SPELL_AURA_MOD_MINIMUM_SPEED);
|
|
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcImmunityAmount, EFFECT_5, SPELL_AURA_MECHANIC_IMMUNITY);
|
|
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcImmunityAmount, EFFECT_6, SPELL_AURA_MECHANIC_IMMUNITY);
|
|
|
|
// This is a special aura that sets backward run speed equal to forward speed
|
|
AfterEffectApply += AuraEffectApplyFn(spell_monk_roll_aura::ChangeRunBackSpeed, EFFECT_4, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, AURA_EFFECT_HANDLE_REAL);
|
|
AfterEffectRemove += AuraEffectApplyFn(spell_monk_roll_aura::RestoreRunBackSpeed, EFFECT_4, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
// Utility for stagger scripts
|
|
Aura* FindExistingStaggerEffect(Unit* unit)
|
|
{
|
|
if (Aura* auraLight = unit->GetAura(SPELL_MONK_STAGGER_LIGHT))
|
|
return auraLight;
|
|
|
|
if (Aura* auraModerate = unit->GetAura(SPELL_MONK_STAGGER_MODERATE))
|
|
return auraModerate;
|
|
|
|
if (Aura* auraHeavy = unit->GetAura(SPELL_MONK_STAGGER_HEAVY))
|
|
return auraHeavy;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
static constexpr SpellEffIndex AuraStaggerEffectTick = EFFECT_0;
|
|
static constexpr SpellEffIndex AuraStaggerEffectTotal = EFFECT_1;
|
|
|
|
// 115069 - Stagger
|
|
class spell_monk_stagger : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_STAGGER_LIGHT, SPELL_MONK_STAGGER_MODERATE, SPELL_MONK_STAGGER_HEAVY });
|
|
}
|
|
|
|
void AbsorbNormal(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/)
|
|
{
|
|
Absorb(dmgInfo, 1.0f);
|
|
}
|
|
|
|
void AbsorbMagic(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/)
|
|
{
|
|
AuraEffect const* effect = GetEffect(EFFECT_4);
|
|
if (!effect)
|
|
return;
|
|
|
|
Absorb(dmgInfo, float(effect->GetAmount()) / 100.0f);
|
|
}
|
|
|
|
void Absorb(DamageInfo& dmgInfo, float multiplier)
|
|
{
|
|
// Prevent default action (which would remove the aura)
|
|
PreventDefaultAction();
|
|
|
|
// make sure damage doesn't come from stagger damage spell SPELL_MONK_STAGGER_DAMAGE_AURA
|
|
if (SpellInfo const* dmgSpellInfo = dmgInfo.GetSpellInfo())
|
|
if (dmgSpellInfo->Id == SPELL_MONK_STAGGER_DAMAGE_AURA)
|
|
return;
|
|
|
|
AuraEffect const* effect = GetEffect(AuraStaggerEffectTick);
|
|
if (!effect)
|
|
return;
|
|
|
|
Unit* target = GetTarget();
|
|
float agility = target->GetStat(STAT_AGILITY);
|
|
float base = CalculatePct(agility, float(effect->GetAmount()));
|
|
float K = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::ArmorConstant, target->GetLevel(), -2, 0, Classes(target->GetClass()), 0);
|
|
|
|
float newAmount = (base / (base + K));
|
|
newAmount *= multiplier;
|
|
|
|
// Absorb X percentage of the damage
|
|
float absorbAmount = float(dmgInfo.GetDamage()) * newAmount;
|
|
if (absorbAmount > 0)
|
|
{
|
|
dmgInfo.AbsorbDamage(absorbAmount);
|
|
|
|
// Cast stagger and make it tick on each tick
|
|
AddAndRefreshStagger(absorbAmount);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectAbsorb += AuraEffectAbsorbFn(spell_monk_stagger::AbsorbNormal, EFFECT_1);
|
|
OnEffectAbsorb += AuraEffectAbsorbFn(spell_monk_stagger::AbsorbMagic, EFFECT_2);
|
|
}
|
|
|
|
private:
|
|
void AddAndRefreshStagger(float amount)
|
|
{
|
|
Unit* target = GetTarget();
|
|
if (Aura* auraStagger = FindExistingStaggerEffect(target))
|
|
{
|
|
AuraEffect* effStaggerRemaining = auraStagger->GetEffect(AuraStaggerEffectTotal);
|
|
if (!effStaggerRemaining)
|
|
return;
|
|
|
|
float newAmount = effStaggerRemaining->GetAmount() + amount;
|
|
uint32 spellId = GetStaggerSpellId(target, newAmount);
|
|
if (spellId == effStaggerRemaining->GetSpellInfo()->Id)
|
|
{
|
|
auraStagger->RefreshDuration();
|
|
effStaggerRemaining->ChangeAmount(newAmount, false, true /* reapply */);
|
|
}
|
|
else
|
|
{
|
|
// amount changed the stagger type so we need to change the stagger amount (e.g. from medium to light)
|
|
GetTarget()->RemoveAura(auraStagger);
|
|
AddNewStagger(target, spellId, newAmount);
|
|
}
|
|
}
|
|
else
|
|
AddNewStagger(target, GetStaggerSpellId(target, amount), amount);
|
|
}
|
|
|
|
uint32 GetStaggerSpellId(Unit* unit, float amount)
|
|
{
|
|
const float StaggerHeavy = 0.6f;
|
|
const float StaggerModerate = 0.3f;
|
|
|
|
float staggerPct = amount / float(unit->GetMaxHealth());
|
|
return (staggerPct >= StaggerHeavy) ? SPELL_MONK_STAGGER_HEAVY :
|
|
(staggerPct >= StaggerModerate) ? SPELL_MONK_STAGGER_MODERATE :
|
|
SPELL_MONK_STAGGER_LIGHT;
|
|
}
|
|
|
|
void AddNewStagger(Unit* unit, uint32 staggerSpellId, float staggerAmount)
|
|
{
|
|
// We only set the total stagger amount. The amount per tick will be set by the stagger spell script
|
|
unit->CastSpell(unit, staggerSpellId, CastSpellExtraArgs(SPELLVALUE_BASE_POINT1, staggerAmount).SetTriggerFlags(TRIGGERED_FULL_MASK));
|
|
}
|
|
};
|
|
|
|
// 124255 - Stagger - SPELL_MONK_STAGGER_DAMAGE_AURA
|
|
class spell_monk_stagger_damage_aura : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_STAGGER_LIGHT, SPELL_MONK_STAGGER_MODERATE, SPELL_MONK_STAGGER_HEAVY });
|
|
}
|
|
|
|
void OnPeriodicDamage(AuraEffect const* aurEff)
|
|
{
|
|
// Update our light/medium/heavy stagger with the correct stagger amount left
|
|
if (Aura* auraStagger = FindExistingStaggerEffect(GetTarget()))
|
|
{
|
|
if (AuraEffect* auraEff = auraStagger->GetEffect(AuraStaggerEffectTotal))
|
|
{
|
|
float total = float(auraEff->GetAmount());
|
|
float tickDamage = float(aurEff->GetAmount());
|
|
auraEff->ChangeAmount(total - tickDamage);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_stagger_damage_aura::OnPeriodicDamage, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
|
}
|
|
};
|
|
|
|
// 124273, 124274, 124275 - Light/Moderate/Heavy Stagger - SPELL_MONK_STAGGER_LIGHT / SPELL_MONK_STAGGER_MODERATE / SPELL_MONK_STAGGER_HEAVY
|
|
class spell_monk_stagger_debuff_aura : public AuraScript
|
|
{
|
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_MONK_STAGGER_DAMAGE_AURA })
|
|
&& ValidateSpellEffect({ { SPELL_MONK_STAGGER_DAMAGE_AURA, EFFECT_0 } });
|
|
}
|
|
|
|
bool Load() override
|
|
{
|
|
_period = float(sSpellMgr->AssertSpellInfo(SPELL_MONK_STAGGER_DAMAGE_AURA, GetCastDifficulty())->GetEffect(EFFECT_0).ApplyAuraPeriod);
|
|
return true;
|
|
}
|
|
|
|
void OnReapply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
// Calculate damage per tick
|
|
float total = float(aurEff->GetAmount());
|
|
float perTick = total * _period / float(GetDuration()); // should be same as GetMaxDuration() TODO: verify
|
|
|
|
// Set amount on effect for tooltip
|
|
AuraEffect* effInfo = GetAura()->GetEffect(AuraStaggerEffectTick);
|
|
if (effInfo)
|
|
effInfo->ChangeAmount(perTick);
|
|
|
|
// Set amount on damage aura (or cast it if needed)
|
|
CastOrChangeTickDamage(perTick);
|
|
}
|
|
|
|
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode)
|
|
{
|
|
if (mode != AURA_EFFECT_HANDLE_REAL)
|
|
return;
|
|
|
|
// Remove damage aura
|
|
GetTarget()->RemoveAura(SPELL_MONK_STAGGER_DAMAGE_AURA);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
AfterEffectApply += AuraEffectRemoveFn(spell_monk_stagger_debuff_aura::OnReapply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
|
|
AfterEffectRemove += AuraEffectRemoveFn(spell_monk_stagger_debuff_aura::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
|
|
private:
|
|
float _period = 0.0f;
|
|
|
|
void CastOrChangeTickDamage(float tickDamage)
|
|
{
|
|
Unit* unit = GetTarget();
|
|
Aura* auraDamage = unit->GetAura(SPELL_MONK_STAGGER_DAMAGE_AURA);
|
|
if (!auraDamage)
|
|
{
|
|
unit->CastSpell(unit, SPELL_MONK_STAGGER_DAMAGE_AURA, true);
|
|
auraDamage = unit->GetAura(SPELL_MONK_STAGGER_DAMAGE_AURA);
|
|
}
|
|
|
|
if (auraDamage)
|
|
if (AuraEffect* eff = auraDamage->GetEffect(AuraStaggerEffectTick))
|
|
eff->ChangeAmount(tickDamage);
|
|
}
|
|
};
|
|
|
|
// 116841 - Tiger's Lust
|
|
class spell_monk_tigers_lust : public SpellScript
|
|
{
|
|
void HandleRemoveImpairingAuras(SpellEffIndex /*effIndex*/)
|
|
{
|
|
GetHitUnit()->RemoveMovementImpairingAuras(true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_monk_tigers_lust::HandleRemoveImpairingAuras, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
|
}
|
|
};
|
|
|
|
void AddSC_monk_spell_scripts()
|
|
{
|
|
RegisterSpellScript(spell_monk_crackling_jade_lightning);
|
|
RegisterSpellScript(spell_monk_crackling_jade_lightning_knockback_proc_aura);
|
|
RegisterSpellScript(spell_monk_life_cocoon);
|
|
RegisterSpellScript(spell_monk_open_palm_strikes);
|
|
RegisterSpellScript(spell_monk_power_strike_periodic);
|
|
RegisterSpellScript(spell_monk_power_strike_proc);
|
|
RegisterSpellScript(spell_monk_provoke);
|
|
RegisterSpellScript(spell_monk_rising_sun_kick);
|
|
RegisterSpellScript(spell_monk_roll);
|
|
RegisterSpellScript(spell_monk_roll_aura);
|
|
RegisterSpellScript(spell_monk_stagger);
|
|
RegisterSpellScript(spell_monk_stagger_damage_aura);
|
|
RegisterSpellScript(spell_monk_stagger_debuff_aura);
|
|
RegisterSpellScript(spell_monk_tigers_lust);
|
|
}
|