Files
TCPlayerbotCore/src/server/scripts/Spells/spell_paladin.cpp
T

583 lines
22 KiB
C++
Raw Normal View History

/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
*
* 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_PALADIN and SPELLFAMILY_GENERIC spells used by paladin players.
* Ordered alphabetically using scriptname.
* Scriptnames of files in this file should be prefixed with "spell_pal_".
*/
2012-02-19 16:57:07 +01:00
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
enum PaladinSpells
{
PALADIN_SPELL_DIVINE_PLEA = 54428,
PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF = 67480,
PALADIN_SPELL_HOLY_SHOCK_R1 = 20473,
PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE = 25912,
PALADIN_SPELL_HOLY_SHOCK_R1_HEALING = 25914,
SPELL_BLESSING_OF_LOWER_CITY_DRUID = 37878,
SPELL_BLESSING_OF_LOWER_CITY_PALADIN = 37879,
SPELL_BLESSING_OF_LOWER_CITY_PRIEST = 37880,
SPELL_BLESSING_OF_LOWER_CITY_SHAMAN = 37881,
2011-10-11 22:32:36 -03:00
SPELL_DIVINE_STORM = 53385,
SPELL_DIVINE_STORM_DUMMY = 54171,
SPELL_DIVINE_STORM_HEAL = 54172,
SPELL_FORBEARANCE = 25771,
SPELL_AVENGING_WRATH_MARKER = 61987,
SPELL_IMMUNE_SHIELD_MARKER = 61988,
};
// 31850 - Ardent Defender
class spell_pal_ardent_defender : public SpellScriptLoader
{
public:
spell_pal_ardent_defender() : SpellScriptLoader("spell_pal_ardent_defender") { }
class spell_pal_ardent_defender_AuraScript : public AuraScript
{
PrepareAuraScript(spell_pal_ardent_defender_AuraScript);
uint32 absorbPct, healPct;
enum Spell
{
PAL_SPELL_ARDENT_DEFENDER_HEAL = 66235,
};
bool Load()
{
healPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue();
return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
// Set absorbtion amount to unlimited
amount = -1;
}
void Absorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
{
Unit* victim = GetTarget();
int32 remainingHealth = victim->GetHealth() - dmgInfo.GetDamage();
uint32 allowedHealth = victim->CountPctFromMaxHealth(35);
// If damage kills us
if (remainingHealth <= 0 && !victim->ToPlayer()->HasSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL))
{
// Cast healing spell, completely avoid damage
absorbAmount = dmgInfo.GetDamage();
uint32 defenseSkillValue = victim->GetDefenseSkillValue();
// Max heal when defense skill denies critical hits from raid bosses
// Formula: max defense at level + 140 (raiting from gear)
uint32 reqDefForMaxHeal = victim->getLevel() * 5 + 140;
float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal)
? 1.0f
: float(defenseSkillValue) / float(reqDefForMaxHeal);
int32 healAmount = int32(victim->CountPctFromMaxHealth(uint32(healPct * pctFromDefense)));
victim->CastCustomSpell(victim, PAL_SPELL_ARDENT_DEFENDER_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff);
victim->ToPlayer()->AddSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 0, time(NULL) + 120);
}
else if (remainingHealth < int32(allowedHealth))
{
// Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
uint32 damageToReduce = (victim->GetHealth() < allowedHealth)
? dmgInfo.GetDamage()
: allowedHealth - remainingHealth;
absorbAmount = CalculatePctN(damageToReduce, absorbPct);
}
}
void Register()
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_ardent_defender_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
OnEffectAbsorb += AuraEffectAbsorbFn(spell_pal_ardent_defender_AuraScript::Absorb, EFFECT_0);
}
};
AuraScript* GetAuraScript() const
{
return new spell_pal_ardent_defender_AuraScript();
}
};
class spell_pal_blessing_of_faith : public SpellScriptLoader
{
public:
spell_pal_blessing_of_faith() : SpellScriptLoader("spell_pal_blessing_of_faith") { }
2010-08-06 11:35:39 -07:00
class spell_pal_blessing_of_faith_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_blessing_of_faith_SpellScript);
bool Validate(SpellInfo const* /*spellEntry*/)
2010-08-06 11:35:39 -07:00
{
if (!sSpellMgr->GetSpellInfo(SPELL_BLESSING_OF_LOWER_CITY_DRUID) || !sSpellMgr->GetSpellInfo(SPELL_BLESSING_OF_LOWER_CITY_PALADIN) || !sSpellMgr->GetSpellInfo(SPELL_BLESSING_OF_LOWER_CITY_PRIEST) || !sSpellMgr->GetSpellInfo(SPELL_BLESSING_OF_LOWER_CITY_SHAMAN))
return false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
2010-08-06 11:35:39 -07:00
{
uint32 spell_id = 0;
switch (unitTarget->getClass())
{
case CLASS_DRUID: spell_id = SPELL_BLESSING_OF_LOWER_CITY_DRUID; break;
case CLASS_PALADIN: spell_id = SPELL_BLESSING_OF_LOWER_CITY_PALADIN; break;
case CLASS_PRIEST: spell_id = SPELL_BLESSING_OF_LOWER_CITY_PRIEST; break;
case CLASS_SHAMAN: spell_id = SPELL_BLESSING_OF_LOWER_CITY_SHAMAN; break;
default: return; // ignore for non-healing classes
}
Unit* caster = GetCaster();
caster->CastSpell(caster, spell_id, true);
2010-08-06 11:35:39 -07:00
}
}
2010-08-06 11:35:39 -07:00
void Register()
{
// add dummy effect spell handler to Blessing of Faith
OnEffectHitTarget += SpellEffectFn(spell_pal_blessing_of_faith_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
2010-08-06 11:35:39 -07:00
}
};
SpellScript* GetSpellScript() const
2010-08-06 11:35:39 -07:00
{
return new spell_pal_blessing_of_faith_SpellScript();
2010-08-06 11:35:39 -07:00
}
};
// 20911 Blessing of Sanctuary
// 25899 Greater Blessing of Sanctuary
class spell_pal_blessing_of_sanctuary : public SpellScriptLoader
{
public:
spell_pal_blessing_of_sanctuary() : SpellScriptLoader("spell_pal_blessing_of_sanctuary") { }
class spell_pal_blessing_of_sanctuary_AuraScript : public AuraScript
{
PrepareAuraScript(spell_pal_blessing_of_sanctuary_AuraScript);
bool Validate(SpellInfo const* /*entry*/)
{
if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF))
return false;
return true;
}
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
if (Unit* caster = GetCaster())
caster->CastSpell(target, PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF, true);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->RemoveAura(PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF, GetCasterGUID());
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
AfterEffectRemove += AuraEffectRemoveFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_pal_blessing_of_sanctuary_AuraScript();
}
};
// 63521 Guarded by The Light
class spell_pal_guarded_by_the_light : public SpellScriptLoader
{
public:
spell_pal_guarded_by_the_light() : SpellScriptLoader("spell_pal_guarded_by_the_light") { }
class spell_pal_guarded_by_the_light_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_guarded_by_the_light_SpellScript);
bool Validate(SpellInfo const* /*spellEntry*/)
{
if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_DIVINE_PLEA))
return false;
return true;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
// Divine Plea
if (Aura* aura = GetCaster()->GetAura(PALADIN_SPELL_DIVINE_PLEA))
aura->RefreshDuration();
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_pal_guarded_by_the_light_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_pal_guarded_by_the_light_SpellScript();
}
};
class spell_pal_holy_shock : public SpellScriptLoader
{
public:
spell_pal_holy_shock() : SpellScriptLoader("spell_pal_holy_shock") { }
class spell_pal_holy_shock_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_holy_shock_SpellScript);
bool Validate(SpellInfo const* spell)
{
if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_HOLY_SHOCK_R1))
return false;
2010-08-06 11:35:39 -07:00
// can't use other spell than holy shock due to spell_ranks dependency
if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spell->Id))
return false;
2010-08-06 11:35:39 -07:00
uint8 rank = sSpellMgr->GetSpellRank(spell->Id);
if (!sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank, true) || !sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank, true))
return false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
2010-08-06 11:35:39 -07:00
{
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
{
uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id);
if (caster->IsFriendlyTo(unitTarget))
caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank), true, 0);
else
caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank), true, 0);
}
}
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
{
if (!caster->IsFriendlyTo(target))
{
if (!caster->IsValidAttackTarget(target))
return SPELL_FAILED_BAD_TARGETS;
if (!caster->isInFront(target))
return SPELL_FAILED_UNIT_NOT_INFRONT;
}
}
else
return SPELL_FAILED_BAD_TARGETS;
return SPELL_CAST_OK;
}
void Register()
{
// add dummy effect spell handler to Holy Shock
OnCheckCast += SpellCheckCastFn(spell_pal_holy_shock_SpellScript::CheckCast);
OnEffectHitTarget += SpellEffectFn(spell_pal_holy_shock_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
2010-08-06 11:35:39 -07:00
}
};
2010-08-06 11:35:39 -07:00
SpellScript* GetSpellScript() const
2010-08-06 11:35:39 -07:00
{
return new spell_pal_holy_shock_SpellScript();
2010-08-06 11:35:39 -07:00
}
};
class spell_pal_judgement_of_command : public SpellScriptLoader
{
public:
spell_pal_judgement_of_command() : SpellScriptLoader("spell_pal_judgement_of_command") { }
2010-08-06 11:35:39 -07:00
class spell_pal_judgement_of_command_SpellScript : public SpellScript
2010-08-06 11:35:39 -07:00
{
PrepareSpellScript(spell_pal_judgement_of_command_SpellScript)
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
if (SpellInfo const* spell_proto = sSpellMgr->GetSpellInfo(GetEffectValue()))
GetCaster()->CastSpell(unitTarget, spell_proto, true, NULL);
}
void Register()
{
// add dummy effect spell handler to Judgement of Command
OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_of_command_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
2010-08-06 11:35:39 -07:00
SpellScript* GetSpellScript() const
2010-08-06 11:35:39 -07:00
{
return new spell_pal_judgement_of_command_SpellScript();
2010-08-06 11:35:39 -07:00
}
};
2011-10-11 22:32:36 -03:00
class spell_pal_divine_storm : public SpellScriptLoader
{
public:
spell_pal_divine_storm() : SpellScriptLoader("spell_pal_divine_storm") { }
class spell_pal_divine_storm_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_divine_storm_SpellScript);
uint32 healPct;
bool Validate(SpellInfo const* /* spell */)
{
if (!sSpellMgr->GetSpellInfo(SPELL_DIVINE_STORM_DUMMY))
return false;
return true;
}
2011-10-11 22:32:36 -03:00
bool Load()
{
healPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster());
return true;
}
2011-10-11 22:32:36 -03:00
void TriggerHeal()
{
Unit* caster = GetCaster();
caster->CastCustomSpell(SPELL_DIVINE_STORM_DUMMY, SPELLVALUE_BASE_POINT0, (GetHitDamage() * healPct) / 100, caster, true);
}
2011-10-11 22:32:36 -03:00
void Register()
{
AfterHit += SpellHitFn(spell_pal_divine_storm_SpellScript::TriggerHeal);
}
};
SpellScript* GetSpellScript() const
2011-10-11 22:32:36 -03:00
{
return new spell_pal_divine_storm_SpellScript();
2011-10-11 22:32:36 -03:00
}
};
2011-10-11 22:32:36 -03:00
class spell_pal_divine_storm_dummy : public SpellScriptLoader
{
public:
spell_pal_divine_storm_dummy() : SpellScriptLoader("spell_pal_divine_storm_dummy") { }
class spell_pal_divine_storm_dummy_SpellScript : public SpellScript
2011-10-11 22:32:36 -03:00
{
PrepareSpellScript(spell_pal_divine_storm_dummy_SpellScript);
2011-10-11 22:32:36 -03:00
bool Validate(SpellInfo const* /* spell */)
{
if (!sSpellMgr->GetSpellInfo(SPELL_DIVINE_STORM_HEAL))
return false;
return true;
}
void CountTargets(std::list<WorldObject*>& targetList)
{
_targetCount = targetList.size();
}
void HandleDummy(SpellEffIndex /* effIndex */)
{
if (!_targetCount || ! GetHitUnit())
return;
int32 heal = GetEffectValue() / _targetCount;
GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_DIVINE_STORM_HEAL, &heal, NULL, NULL, true);
}
private:
uint32 _targetCount;
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_pal_divine_storm_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
}
};
SpellScript* GetSpellScript() const
2011-10-11 22:32:36 -03:00
{
return new spell_pal_divine_storm_dummy_SpellScript();
2011-10-11 22:32:36 -03:00
}
};
class spell_pal_lay_on_hands : public SpellScriptLoader
{
public:
spell_pal_lay_on_hands() : SpellScriptLoader("spell_pal_lay_on_hands") { }
class spell_pal_lay_on_hands_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_lay_on_hands_SpellScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_FORBEARANCE))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_AVENGING_WRATH_MARKER))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_IMMUNE_SHIELD_MARKER))
return false;
return true;
}
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
if (caster == target)
if (target->HasAura(SPELL_FORBEARANCE) || target->HasAura(SPELL_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_IMMUNE_SHIELD_MARKER))
return SPELL_FAILED_TARGET_AURASTATE;
return SPELL_CAST_OK;
}
void HandleScript()
{
Unit* caster = GetCaster();
if (caster == GetHitUnit())
{
caster->CastSpell(caster, SPELL_FORBEARANCE, true);
caster->CastSpell(caster, SPELL_AVENGING_WRATH_MARKER, true);
caster->CastSpell(caster, SPELL_IMMUNE_SHIELD_MARKER, true);
}
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_pal_lay_on_hands_SpellScript::CheckCast);
AfterHit += SpellHitFn(spell_pal_lay_on_hands_SpellScript::HandleScript);
}
};
SpellScript* GetSpellScript() const
{
return new spell_pal_lay_on_hands_SpellScript();
}
};
2012-06-03 02:35:00 +02:00
class spell_pal_righteous_defense : public SpellScriptLoader
{
public:
spell_pal_righteous_defense() : SpellScriptLoader("spell_pal_righteous_defense") { }
class spell_pal_righteous_defense_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_righteous_defense_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_DONT_REPORT;
if (Unit* target = GetExplTargetUnit())
{
if (!target->IsFriendlyTo(caster) || target->getAttackers().empty())
return SPELL_FAILED_BAD_TARGETS;
}
else
return SPELL_FAILED_BAD_TARGETS;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const
{
return new spell_pal_righteous_defense_SpellScript();
}
};
class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader
{
public:
spell_pal_exorcism_and_holy_wrath_damage() : SpellScriptLoader("spell_pal_exorcism_and_holy_wrath_damage") { }
class spell_pal_exorcism_and_holy_wrath_damage_AuraScript : public AuraScript
{
PrepareAuraScript(spell_pal_exorcism_and_holy_wrath_damage_AuraScript);
void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
{
if (!spellMod)
{
spellMod = new SpellModifier(aurEff->GetBase());
spellMod->op = SPELLMOD_DAMAGE;
spellMod->type = SPELLMOD_FLAT;
spellMod->spellId = GetId();
spellMod->mask[1] = 0x200002;
}
spellMod->value = aurEff->GetAmount();
}
void Register()
{
DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_pal_exorcism_and_holy_wrath_damage_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const
{
return new spell_pal_exorcism_and_holy_wrath_damage_AuraScript();
}
};
void AddSC_paladin_spell_scripts()
{
new spell_pal_ardent_defender();
new spell_pal_blessing_of_faith();
new spell_pal_blessing_of_sanctuary();
new spell_pal_guarded_by_the_light();
new spell_pal_holy_shock();
new spell_pal_judgement_of_command();
2011-10-11 22:32:36 -03:00
new spell_pal_divine_storm();
new spell_pal_divine_storm_dummy();
new spell_pal_lay_on_hands();
2012-06-03 02:35:00 +02:00
new spell_pal_righteous_defense();
new spell_pal_exorcism_and_holy_wrath_damage();
}