2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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/>.
2010-01-10 01:23:15 +01:00
*/
#include "Common.h"
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "Unit.h"
#include "ObjectAccessor.h"
#include "Util.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
2010-08-08 04:37:24 +02:00
#include "Battleground.h"
2010-01-10 01:23:15 +01:00
#include "OutdoorPvPMgr.h"
#include "Formulas.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
2010-01-19 11:36:05 +01:00
#include "ScriptMgr.h"
2011-08-03 12:28:42 +02:00
#include "Vehicle.h"
2010-01-10 01:23:15 +01:00
class Aura ;
//
// EFFECT HANDLER NOTES
2010-04-07 18:09:10 +02:00
//
2010-01-10 01:23:15 +01:00
// in aura handler there should be check for modes:
2011-05-29 13:18:47 +02:00
// AURA_EFFECT_HANDLE_REAL set
2011-06-23 09:13:58 +02:00
// AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK set
2010-01-10 01:23:15 +01:00
// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK set - aura is recalculated or is just applied/removed - need to redo all things related to m_amount
// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK - logical or of above conditions
// AURA_EFFECT_HANDLE_STAT - set when stats are reapplied
// such checks will speedup trinity change amount/send for client operations
// because for change amount operation packets will not be send
// aura effect handlers shouldn't contain any AuraEffect or Aura object modifications
pAuraEffectHandler AuraEffectHandler [ TOTAL_AURAS ] =
{
& AuraEffect :: HandleNULL , // 0 SPELL_AURA_NONE
& AuraEffect :: HandleBindSight , // 1 SPELL_AURA_BIND_SIGHT
& AuraEffect :: HandleModPossess , // 2 SPELL_AURA_MOD_POSSESS
& AuraEffect :: HandleNoImmediateEffect , // 3 SPELL_AURA_PERIODIC_DAMAGE implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleAuraDummy , // 4 SPELL_AURA_DUMMY
& AuraEffect :: HandleModConfuse , // 5 SPELL_AURA_MOD_CONFUSE
& AuraEffect :: HandleModCharm , // 6 SPELL_AURA_MOD_CHARM
& AuraEffect :: HandleModFear , // 7 SPELL_AURA_MOD_FEAR
& AuraEffect :: HandleNoImmediateEffect , // 8 SPELL_AURA_PERIODIC_HEAL implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleModAttackSpeed , // 9 SPELL_AURA_MOD_ATTACKSPEED
& AuraEffect :: HandleModThreat , // 10 SPELL_AURA_MOD_THREAT
& AuraEffect :: HandleModTaunt , // 11 SPELL_AURA_MOD_TAUNT
& AuraEffect :: HandleAuraModStun , // 12 SPELL_AURA_MOD_STUN
& AuraEffect :: HandleModDamageDone , // 13 SPELL_AURA_MOD_DAMAGE_DONE
& AuraEffect :: HandleNoImmediateEffect , // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
& AuraEffect :: HandleNoImmediateEffect , // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
& AuraEffect :: HandleModStealth , // 16 SPELL_AURA_MOD_STEALTH
2010-11-13 17:18:09 +01:00
& AuraEffect :: HandleModStealthDetect , // 17 SPELL_AURA_MOD_DETECT
& AuraEffect :: HandleModInvisibility , // 18 SPELL_AURA_MOD_INVISIBILITY
& AuraEffect :: HandleModInvisibilityDetect , // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNoImmediateEffect , // 20 SPELL_AURA_OBS_MOD_HEALTH implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNoImmediateEffect , // 21 SPELL_AURA_OBS_MOD_POWER implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleAuraModResistance , // 22 SPELL_AURA_MOD_RESISTANCE
& AuraEffect :: HandleNoImmediateEffect , // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNoImmediateEffect , // 24 SPELL_AURA_PERIODIC_ENERGIZE implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleAuraModPacify , // 25 SPELL_AURA_MOD_PACIFY
& AuraEffect :: HandleAuraModRoot , // 26 SPELL_AURA_MOD_ROOT
& AuraEffect :: HandleAuraModSilence , // 27 SPELL_AURA_MOD_SILENCE
& AuraEffect :: HandleNoImmediateEffect , // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
& AuraEffect :: HandleAuraModStat , // 29 SPELL_AURA_MOD_STAT
& AuraEffect :: HandleAuraModSkill , // 30 SPELL_AURA_MOD_SKILL
& AuraEffect :: HandleAuraModIncreaseSpeed , // 31 SPELL_AURA_MOD_INCREASE_SPEED
& AuraEffect :: HandleAuraModIncreaseMountedSpeed , // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
& AuraEffect :: HandleAuraModDecreaseSpeed , // 33 SPELL_AURA_MOD_DECREASE_SPEED
& AuraEffect :: HandleAuraModIncreaseHealth , // 34 SPELL_AURA_MOD_INCREASE_HEALTH
& AuraEffect :: HandleAuraModIncreaseEnergy , // 35 SPELL_AURA_MOD_INCREASE_ENERGY
& AuraEffect :: HandleAuraModShapeshift , // 36 SPELL_AURA_MOD_SHAPESHIFT
& AuraEffect :: HandleAuraModEffectImmunity , // 37 SPELL_AURA_EFFECT_IMMUNITY
& AuraEffect :: HandleAuraModStateImmunity , // 38 SPELL_AURA_STATE_IMMUNITY
& AuraEffect :: HandleAuraModSchoolImmunity , // 39 SPELL_AURA_SCHOOL_IMMUNITY
& AuraEffect :: HandleAuraModDmgImmunity , // 40 SPELL_AURA_DAMAGE_IMMUNITY
& AuraEffect :: HandleAuraModDispelImmunity , // 41 SPELL_AURA_DISPEL_IMMUNITY
& AuraEffect :: HandleNoImmediateEffect , // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
& AuraEffect :: HandleNoImmediateEffect , // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
& AuraEffect :: HandleAuraTrackCreatures , // 44 SPELL_AURA_TRACK_CREATURES
& AuraEffect :: HandleAuraTrackResources , // 45 SPELL_AURA_TRACK_RESOURCES
& AuraEffect :: HandleNULL , // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
& AuraEffect :: HandleAuraModParryPercent , // 47 SPELL_AURA_MOD_PARRY_PERCENT
& AuraEffect :: HandleNULL , // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
& AuraEffect :: HandleAuraModDodgePercent , // 49 SPELL_AURA_MOD_DODGE_PERCENT
& AuraEffect :: HandleNoImmediateEffect , // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
& AuraEffect :: HandleAuraModBlockPercent , // 51 SPELL_AURA_MOD_BLOCK_PERCENT
& AuraEffect :: HandleAuraModWeaponCritPercent , // 52 SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
& AuraEffect :: HandleNoImmediateEffect , // 53 SPELL_AURA_PERIODIC_LEECH implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleModHitChance , // 54 SPELL_AURA_MOD_HIT_CHANCE
& AuraEffect :: HandleModSpellHitChance , // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
& AuraEffect :: HandleAuraTransform , // 56 SPELL_AURA_TRANSFORM
& AuraEffect :: HandleModSpellCritChance , // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
& AuraEffect :: HandleAuraModIncreaseSwimSpeed , // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
& AuraEffect :: HandleNoImmediateEffect , // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
& AuraEffect :: HandleAuraModPacifyAndSilence , // 60 SPELL_AURA_MOD_PACIFY_SILENCE
& AuraEffect :: HandleAuraModScale , // 61 SPELL_AURA_MOD_SCALE
& AuraEffect :: HandleNoImmediateEffect , // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNULL , // 63 unused (3.2.0) old SPELL_AURA_PERIODIC_MANA_FUNNEL
& AuraEffect :: HandleNoImmediateEffect , // 64 SPELL_AURA_PERIODIC_MANA_LEECH implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleModCastingSpeed , // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
& AuraEffect :: HandleFeignDeath , // 66 SPELL_AURA_FEIGN_DEATH
& AuraEffect :: HandleAuraModDisarm , // 67 SPELL_AURA_MOD_DISARM
& AuraEffect :: HandleAuraModStalked , // 68 SPELL_AURA_MOD_STALKED
& AuraEffect :: HandleNoImmediateEffect , // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleUnused , // 70 SPELL_AURA_EXTRA_ATTACKS clientside
& AuraEffect :: HandleModSpellCritChanceShool , // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
& AuraEffect :: HandleModPowerCostPCT , // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
& AuraEffect :: HandleModPowerCost , // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
& AuraEffect :: HandleNoImmediateEffect , // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
& AuraEffect :: HandleNoImmediateEffect , // 75 SPELL_AURA_MOD_LANGUAGE
& AuraEffect :: HandleNoImmediateEffect , // 76 SPELL_AURA_FAR_SIGHT
& AuraEffect :: HandleModMechanicImmunity , // 77 SPELL_AURA_MECHANIC_IMMUNITY
& AuraEffect :: HandleAuraMounted , // 78 SPELL_AURA_MOUNTED
& AuraEffect :: HandleModDamagePercentDone , // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
& AuraEffect :: HandleModPercentStat , // 80 SPELL_AURA_MOD_PERCENT_STAT
& AuraEffect :: HandleNoImmediateEffect , // 81 SPELL_AURA_SPLIT_DAMAGE_PCT implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleWaterBreathing , // 82 SPELL_AURA_WATER_BREATHING
& AuraEffect :: HandleModBaseResistance , // 83 SPELL_AURA_MOD_BASE_RESISTANCE
& AuraEffect :: HandleNoImmediateEffect , // 84 SPELL_AURA_MOD_REGEN implemented in Player::RegenerateHealth
& AuraEffect :: HandleModPowerRegen , // 85 SPELL_AURA_MOD_POWER_REGEN implemented in Player::Regenerate
& AuraEffect :: HandleChannelDeathItem , // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
& AuraEffect :: HandleNoImmediateEffect , // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
& AuraEffect :: HandleNoImmediateEffect , // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth
& AuraEffect :: HandleNoImmediateEffect , // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
& AuraEffect :: HandleNULL , // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
& AuraEffect :: HandleNoImmediateEffect , // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
& AuraEffect :: HandlePreventFleeing , // 92 SPELL_AURA_PREVENTS_FLEEING
& AuraEffect :: HandleModUnattackable , // 93 SPELL_AURA_MOD_UNATTACKABLE
& AuraEffect :: HandleNoImmediateEffect , // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::Regenerate
& AuraEffect :: HandleAuraGhost , // 95 SPELL_AURA_GHOST
& AuraEffect :: HandleNoImmediateEffect , // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
& AuraEffect :: HandleNoImmediateEffect , // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleAuraModSkill , // 98 SPELL_AURA_MOD_SKILL_TALENT
& AuraEffect :: HandleAuraModAttackPower , // 99 SPELL_AURA_MOD_ATTACK_POWER
& AuraEffect :: HandleUnused , //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
& AuraEffect :: HandleModResistancePercent , //101 SPELL_AURA_MOD_RESISTANCE_PCT
& AuraEffect :: HandleNoImmediateEffect , //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleAuraModTotalThreat , //103 SPELL_AURA_MOD_TOTAL_THREAT
& AuraEffect :: HandleAuraWaterWalk , //104 SPELL_AURA_WATER_WALK
& AuraEffect :: HandleAuraFeatherFall , //105 SPELL_AURA_FEATHER_FALL
& AuraEffect :: HandleAuraHover , //106 SPELL_AURA_HOVER
& AuraEffect :: HandleNoImmediateEffect , //107 SPELL_AURA_ADD_FLAT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
& AuraEffect :: HandleNoImmediateEffect , //108 SPELL_AURA_ADD_PCT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
& AuraEffect :: HandleNoImmediateEffect , //109 SPELL_AURA_ADD_TARGET_TRIGGER
& AuraEffect :: HandleModPowerRegenPCT , //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT implemented in Player::Regenerate, Creature::Regenerate
& AuraEffect :: HandleNoImmediateEffect , //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
& AuraEffect :: HandleNoImmediateEffect , //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
& AuraEffect :: HandleNoImmediateEffect , //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleNoImmediateEffect , //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleNoImmediateEffect , //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
& AuraEffect :: HandleNoImmediateEffect , //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
& AuraEffect :: HandleNoImmediateEffect , //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
& AuraEffect :: HandleNULL , //119 unused (3.2.0) old SPELL_AURA_SHARE_PET_TRACKING
& AuraEffect :: HandleAuraUntrackable , //120 SPELL_AURA_UNTRACKABLE
& AuraEffect :: HandleAuraEmpathy , //121 SPELL_AURA_EMPATHY
& AuraEffect :: HandleModOffhandDamagePercent , //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
& AuraEffect :: HandleModTargetResistance , //123 SPELL_AURA_MOD_TARGET_RESISTANCE
& AuraEffect :: HandleAuraModRangedAttackPower , //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
& AuraEffect :: HandleNoImmediateEffect , //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleNoImmediateEffect , //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleNoImmediateEffect , //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleModPossessPet , //128 SPELL_AURA_MOD_POSSESS_PET
& AuraEffect :: HandleAuraModIncreaseSpeed , //129 SPELL_AURA_MOD_SPEED_ALWAYS
& AuraEffect :: HandleAuraModIncreaseMountedSpeed , //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
& AuraEffect :: HandleNoImmediateEffect , //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleAuraModIncreaseEnergyPercent , //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
& AuraEffect :: HandleAuraModIncreaseHealthPercent , //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
& AuraEffect :: HandleAuraModRegenInterrupt , //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
& AuraEffect :: HandleModHealingDone , //135 SPELL_AURA_MOD_HEALING_DONE
& AuraEffect :: HandleNoImmediateEffect , //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
& AuraEffect :: HandleModTotalPercentStat , //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
2010-12-09 14:40:59 +06:00
& AuraEffect :: HandleModMeleeSpeedPct , //138 SPELL_AURA_MOD_MELEE_HASTE
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleForceReaction , //139 SPELL_AURA_FORCE_REACTION
& AuraEffect :: HandleAuraModRangedHaste , //140 SPELL_AURA_MOD_RANGED_HASTE
& AuraEffect :: HandleRangedAmmoHaste , //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
& AuraEffect :: HandleAuraModBaseResistancePCT , //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
& AuraEffect :: HandleAuraModResistanceExclusive , //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
& AuraEffect :: HandleNoImmediateEffect , //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
& AuraEffect :: HandleAuraModPetTalentsPoints , //145 SPELL_AURA_MOD_PET_TALENT_POINTS
& AuraEffect :: HandleNoImmediateEffect , //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
& AuraEffect :: HandleModStateImmunityMask , //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
& AuraEffect :: HandleAuraRetainComboPoints , //148 SPELL_AURA_RETAIN_COMBO_POINTS
& AuraEffect :: HandleNoImmediateEffect , //149 SPELL_AURA_REDUCE_PUSHBACK
& AuraEffect :: HandleShieldBlockValue , //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
& AuraEffect :: HandleAuraTrackStealthed , //151 SPELL_AURA_TRACK_STEALTHED
& AuraEffect :: HandleNoImmediateEffect , //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
& AuraEffect :: HandleNoImmediateEffect , //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
2010-11-13 17:18:09 +01:00
& AuraEffect :: HandleModStealthLevel , //154 SPELL_AURA_MOD_STEALTH_LEVEL
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNoImmediateEffect , //155 SPELL_AURA_MOD_WATER_BREATHING
& AuraEffect :: HandleNoImmediateEffect , //156 SPELL_AURA_MOD_REPUTATION_GAIN
& AuraEffect :: HandleNULL , //157 SPELL_AURA_PET_DAMAGE_MULTI
& AuraEffect :: HandleShieldBlockValue , //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
& AuraEffect :: HandleNoImmediateEffect , //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
& AuraEffect :: HandleNoImmediateEffect , //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
& AuraEffect :: HandleNoImmediateEffect , //162 SPELL_AURA_POWER_BURN_MANA implemented in AuraEffect::PeriodicTick
2011-07-23 06:11:26 +07:00
& AuraEffect :: HandleNoImmediateEffect , //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleUnused , //164 unused (3.2.0), only one test spell
& AuraEffect :: HandleNoImmediateEffect , //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleAuraModAttackPowerPercent , //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
& AuraEffect :: HandleAuraModRangedAttackPowerPercent , //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
& AuraEffect :: HandleNoImmediateEffect , //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
& AuraEffect :: HandleNoImmediateEffect , //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
& AuraEffect :: HandleNULL , //170 SPELL_AURA_DETECT_AMORE various spells that change visual of units for aura target (clientside?)
& AuraEffect :: HandleAuraModIncreaseSpeed , //171 SPELL_AURA_MOD_SPEED_NOT_STACK
& AuraEffect :: HandleAuraModIncreaseMountedSpeed , //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
& AuraEffect :: HandleNULL , //173 unused (3.2.0) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
& AuraEffect :: HandleModSpellDamagePercentFromStat , //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
& AuraEffect :: HandleModSpellHealingPercentFromStat , //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
& AuraEffect :: HandleSpiritOfRedemption , //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
& AuraEffect :: HandleCharmConvert , //177 SPELL_AURA_AOE_CHARM
& AuraEffect :: HandleNoImmediateEffect , //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
& AuraEffect :: HandleNoImmediateEffect , //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
& AuraEffect :: HandleNULL , //181 unused (3.2.0) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
& AuraEffect :: HandleAuraModResistenceOfStatPercent , //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
& AuraEffect :: HandleNULL , //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 - miscvalue - spell school
& AuraEffect :: HandleNoImmediateEffect , //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
& AuraEffect :: HandleNoImmediateEffect , //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
& AuraEffect :: HandleNoImmediateEffect , //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
& AuraEffect :: HandleNoImmediateEffect , //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
& AuraEffect :: HandleModRating , //189 SPELL_AURA_MOD_RATING
& AuraEffect :: HandleNoImmediateEffect , //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
& AuraEffect :: HandleAuraModUseNormalSpeed , //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
2010-12-09 14:40:59 +06:00
& AuraEffect :: HandleModMeleeRangedSpeedPct , //192 SPELL_AURA_MOD_MELEE_RANGED_HASTE
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleModCombatSpeedPct , //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
& AuraEffect :: HandleNoImmediateEffect , //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleNoImmediateEffect , //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleNULL , //196 SPELL_AURA_MOD_COOLDOWN - flat mod of spell cooldowns
& AuraEffect :: HandleNoImmediateEffect , //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
& AuraEffect :: HandleNULL , //198 unused (3.2.0) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
& AuraEffect :: HandleNoImmediateEffect , //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //200 SPELL_AURA_MOD_XP_PCT implemented in Player::RewardPlayerAndGroupAtKill
& AuraEffect :: HandleAuraAllowFlight , //201 SPELL_AURA_FLY this aura enable flight mode...
& AuraEffect :: HandleNoImmediateEffect , //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
& AuraEffect :: HandleNoImmediateEffect , //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
& AuraEffect :: HandleNoImmediateEffect , //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
& AuraEffect :: HandleNULL , //205 SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
& AuraEffect :: HandleAuraModIncreaseFlightSpeed , //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
& AuraEffect :: HandleAuraModRangedAttackPowerOfStatPercent , //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
& AuraEffect :: HandleNoImmediateEffect , //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
& AuraEffect :: HandleNULL , //214 Tamed Pet Passive
& AuraEffect :: HandleArenaPreparation , //215 SPELL_AURA_ARENA_PREPARATION
& AuraEffect :: HandleModCastingSpeed , //216 SPELL_AURA_HASTE_SPELLS
2010-07-16 01:08:06 +02:00
& AuraEffect :: HandleNULL , //217 69106 - killing spree helper - unknown use
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleAuraModRangedHaste , //218 SPELL_AURA_HASTE_RANGED
& AuraEffect :: HandleModManaRegen , //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
& AuraEffect :: HandleModRatingFromStat , //220 SPELL_AURA_MOD_RATING_FROM_STAT
& AuraEffect :: HandleNULL , //221 SPELL_AURA_MOD_DETAUNT
& AuraEffect :: HandleUnused , //222 unused (3.2.0) only for spell 44586 that not used in real spell cast
& AuraEffect :: HandleNoImmediateEffect , //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
& AuraEffect :: HandleUnused , //224 unused (3.0.8a)
& AuraEffect :: HandleNoImmediateEffect , //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
& AuraEffect :: HandleNoImmediateEffect , //226 SPELL_AURA_PERIODIC_DUMMY implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNoImmediateEffect , //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNoImmediateEffect , //228 SPELL_AURA_DETECT_STEALTH stealth detection
& AuraEffect :: HandleNoImmediateEffect , //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
& AuraEffect :: HandleAuraModIncreaseHealth , //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
& AuraEffect :: HandleNoImmediateEffect , //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
& AuraEffect :: HandleNoImmediateEffect , //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
& AuraEffect :: HandleUnused , //233 set model id to the one of the creature with id GetMiscValue() - clientside
& AuraEffect :: HandleNoImmediateEffect , //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
& AuraEffect :: HandleNoImmediateEffect , //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
& AuraEffect :: HandleAuraControlVehicle , //236 SPELL_AURA_CONTROL_VEHICLE
& AuraEffect :: HandleModSpellDamagePercentFromAttackPower , //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
& AuraEffect :: HandleModSpellHealingPercentFromAttackPower , //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
& AuraEffect :: HandleAuraModScale , //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
& AuraEffect :: HandleAuraModExpertise , //240 SPELL_AURA_MOD_EXPERTISE
2011-02-14 19:18:05 -03:00
& AuraEffect :: HandleForceMoveForward , //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the caster to move forward
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNULL , //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING - 2 test spells: 44183 and 44182
2010-01-13 10:45:34 +01:00
& AuraEffect :: HandleAuraModFaction , //243 SPELL_AURA_MOD_FACTION
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleComprehendLanguage , //244 SPELL_AURA_COMPREHEND_LANGUAGE
& AuraEffect :: HandleNoImmediateEffect , //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
& AuraEffect :: HandleNoImmediateEffect , //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
& AuraEffect :: HandleAuraCloneCaster , //247 SPELL_AURA_CLONE_CASTER
& AuraEffect :: HandleNoImmediateEffect , //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
& AuraEffect :: HandleAuraConvertRune , //249 SPELL_AURA_CONVERT_RUNE
& AuraEffect :: HandleAuraModIncreaseHealth , //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
& AuraEffect :: HandleNoImmediateEffect , //251 SPELL_AURA_MOD_ENEMY_DODGE
& AuraEffect :: HandleModCombatSpeedPct , //252 SPELL_AURA_252 Is there any difference between this and SPELL_AURA_MELEE_SLOW ? maybe not stacking mod?
& AuraEffect :: HandleNoImmediateEffect , //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
& AuraEffect :: HandleAuraModDisarm , //254 SPELL_AURA_MOD_DISARM_OFFHAND
& AuraEffect :: HandleNoImmediateEffect , //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
& AuraEffect :: HandleNoReagentUseAura , //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
& AuraEffect :: HandleNULL , //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
& AuraEffect :: HandleNULL , //258 SPELL_AURA_MOD_SPELL_VISUAL
& AuraEffect :: HandleNoImmediateEffect , //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
& AuraEffect :: HandleNoImmediateEffect , //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
2011-06-16 20:08:28 +07:00
& AuraEffect :: HandlePhase , //261 SPELL_AURA_PHASE
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNoImmediateEffect , //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
& AuraEffect :: HandleAuraAllowOnlyAbility , //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
& AuraEffect :: HandleUnused , //264 unused (3.2.0)
& AuraEffect :: HandleUnused , //265 unused (3.2.0)
& AuraEffect :: HandleUnused , //266 unused (3.2.0)
& AuraEffect :: HandleNoImmediateEffect , //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
& AuraEffect :: HandleAuraModAttackPowerOfStatPercent , //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
& AuraEffect :: HandleNoImmediateEffect , //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
& AuraEffect :: HandleNoImmediateEffect , //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
& AuraEffect :: HandleNoImmediateEffect , //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
2010-01-24 15:43:58 +01:00
& AuraEffect :: HandleNoImmediateEffect , //272 SPELL_AURA_IGNORE_MELEE_RESET
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleUnused , //273 clientside
& AuraEffect :: HandleNoImmediateEffect , //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
& AuraEffect :: HandleNoImmediateEffect , //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
& AuraEffect :: HandleNULL , //276 mod damage % mechanic?
& AuraEffect :: HandleNoImmediateEffect , //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
& AuraEffect :: HandleAuraModDisarm , //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
& AuraEffect :: HandleNoImmediateEffect , //279 SPELL_AURA_INITIALIZE_IMAGES
& AuraEffect :: HandleNoImmediateEffect , //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
& AuraEffect :: HandleNoImmediateEffect , //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
& AuraEffect :: HandleAuraIncreaseBaseHealthPercent , //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
& AuraEffect :: HandleNoImmediateEffect , //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
& AuraEffect :: HandleAuraLinked , //284 SPELL_AURA_LINKED
& AuraEffect :: HandleAuraModAttackPowerOfArmor , //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage
& AuraEffect :: HandleNoImmediateEffect , //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in AuraEffect::PeriodicTick
& AuraEffect :: HandleNoImmediateEffect , //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
& AuraEffect :: HandleNoImmediateEffect , //288 SPELL_AURA_IGNORE_HIT_DIRECTION implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult Unit::RollMeleeOutcomeAgainst
& AuraEffect :: HandleNULL , //289 unused (3.2.0)
& AuraEffect :: HandleAuraModCritPct , //290 SPELL_AURA_MOD_CRIT_PCT
& AuraEffect :: HandleNoImmediateEffect , //291 SPELL_AURA_MOD_XP_QUEST_PCT implemented in Player::RewardQuest
2010-07-22 03:12:28 +02:00
& AuraEffect :: HandleAuraOpenStable , //292 SPELL_AURA_OPEN_STABLE
2010-11-30 21:32:00 +01:00
& AuraEffect :: HandleAuraOverrideSpells , //293 auras which probably add set of abilities to their target based on it's miscvalue
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNoImmediateEffect , //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power)
2010-07-17 00:48:31 +02:00
& AuraEffect :: HandleNULL , //295 0 spells in 3.3.5
2010-11-10 12:23:36 +01:00
& AuraEffect :: HandleAuraSetVehicle , //296 SPELL_AURA_SET_VEHICLE_ID sets vehicle on target
2010-07-16 01:08:06 +02:00
& AuraEffect :: HandleNULL , //297 Spirit Burst spells
& AuraEffect :: HandleNULL , //298 70569 - Strangulating, maybe prevents talk or cast
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleNULL , //299 unused
2010-07-16 01:08:06 +02:00
& AuraEffect :: HandleNoImmediateEffect , //300 SPELL_AURA_SHARE_DAMAGE_PCT implemented in Unit::DealDamage
2010-06-29 14:20:49 +02:00
& AuraEffect :: HandleNoImmediateEffect , //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb
2010-07-16 13:20:50 +02:00
& AuraEffect :: HandleNULL , //302 0 spells in 3.3.5
2010-09-05 12:05:49 +02:00
& AuraEffect :: HandleNoImmediateEffect , //303 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
2010-11-13 17:18:09 +01:00
& AuraEffect :: HandleAuraModFakeInebriation , //304 SPELL_AURA_MOD_DRUNK
2010-01-10 01:23:15 +01:00
& AuraEffect :: HandleAuraModIncreaseSpeed , //305 SPELL_AURA_MOD_MINIMUM_SPEED
2010-07-16 13:20:50 +02:00
& AuraEffect :: HandleNULL , //306 0 spells in 3.3.5
& AuraEffect :: HandleNULL , //307 0 spells in 3.3.5
2010-02-14 19:13:14 -07:00
& AuraEffect :: HandleNULL , //308 new aura for hunter traps
2010-07-16 13:20:50 +02:00
& AuraEffect :: HandleNULL , //309 0 spells in 3.3.5
& AuraEffect :: HandleNoImmediateEffect , //310 SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE implemented in Spell::CalculateDamageDone
& AuraEffect :: HandleNULL , //311 0 spells in 3.3.5
& AuraEffect :: HandleNULL , //312 0 spells in 3.3.5
& AuraEffect :: HandleNULL , //313 0 spells in 3.3.5
& AuraEffect :: HandleNoImmediateEffect , //314 SPELL_AURA_PREVENT_RESSURECTION todo
& AuraEffect :: HandleNoImmediateEffect , //315 SPELL_AURA_UNDERWATER_WALKING todo
2010-02-14 19:13:14 -07:00
& AuraEffect :: HandleNoImmediateEffect , //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic
2010-01-10 01:23:15 +01:00
};
2011-06-11 22:35:29 +02:00
AuraEffect :: AuraEffect ( Aura * base , uint8 effIndex , int32 * baseAmount , Unit * caster ) :
2011-07-26 23:09:28 +02:00
m_base ( base ), m_spellInfo ( base -> GetSpellInfo ()), m_effIndex ( effIndex ),
m_baseAmount ( baseAmount ? * baseAmount : m_spellInfo -> Effects [ m_effIndex ]. BasePoints ),
2010-09-12 01:40:27 +02:00
m_canBeRecalculated ( true ), m_spellmod ( NULL ), m_isPeriodic ( false ),
2010-08-21 20:08:47 +02:00
m_periodicTimer ( 0 ), m_tickNumber ( 0 )
2010-01-10 01:23:15 +01:00
{
2011-06-09 17:04:52 +02:00
CalculatePeriodic ( caster , true , false );
2010-01-10 01:23:15 +01:00
m_amount = CalculateAmount ( caster );
CalculateSpellMod ();
}
AuraEffect ::~ AuraEffect ()
{
2010-06-21 23:20:58 +02:00
delete m_spellmod ;
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: GetTargetList ( std :: list < Unit *> & targetList ) const
{
Aura :: ApplicationMap const & targetMap = GetBase () -> GetApplicationMap ();
// remove all targets which were not added to new list - they no longer deserve area aura
2010-01-24 13:08:25 +01:00
for ( Aura :: ApplicationMap :: const_iterator appIter = targetMap . begin (); appIter != targetMap . end (); ++ appIter )
2010-01-10 02:12:02 +01:00
{
2010-04-07 19:14:10 +02:00
if ( appIter -> second -> HasEffect ( GetEffIndex ()))
2010-01-10 01:23:15 +01:00
targetList . push_back ( appIter -> second -> GetTarget ());
2010-01-10 02:12:02 +01:00
}
2010-01-10 01:23:15 +01:00
}
2011-05-31 16:03:27 +02:00
void AuraEffect :: GetApplicationList ( std :: list < AuraApplication *> & applicationList ) const
2010-12-05 21:38:52 +01:00
{
Aura :: ApplicationMap const & targetMap = GetBase () -> GetApplicationMap ();
for ( Aura :: ApplicationMap :: const_iterator appIter = targetMap . begin (); appIter != targetMap . end (); ++ appIter )
{
if ( appIter -> second -> HasEffect ( GetEffIndex ()))
applicationList . push_back ( appIter -> second );
}
}
2011-06-11 22:35:29 +02:00
int32 AuraEffect :: CalculateAmount ( Unit * caster )
2010-01-10 01:23:15 +01:00
{
int32 amount ;
// default amount calculation
2011-07-26 23:09:28 +02:00
amount = m_spellInfo -> Effects [ m_effIndex ]. CalcValue ( caster , & m_baseAmount , NULL );
2010-01-10 01:23:15 +01:00
2010-01-10 02:12:02 +01:00
// check item enchant aura cast
2010-04-07 19:14:10 +02:00
if ( ! amount && caster )
if ( uint64 itemGUID = GetBase () -> GetCastItemGUID ())
2011-06-29 13:09:32 +02:00
if ( Player * playerCaster = caster -> ToPlayer ())
2011-07-15 07:12:54 +07:00
if ( Item * castItem = playerCaster -> GetItemByGuid ( itemGUID ))
2010-01-10 01:23:15 +01:00
if ( castItem -> GetItemSuffixFactor ())
{
2011-06-29 13:09:32 +02:00
ItemRandomSuffixEntry const * item_rand_suffix = sItemRandomSuffixStore . LookupEntry ( abs ( castItem -> GetItemRandomPropertyId ()));
2010-04-07 19:14:10 +02:00
if ( item_rand_suffix )
2010-01-10 01:23:15 +01:00
{
2010-09-28 08:21:51 +03:00
for ( int k = 0 ; k < MAX_ITEM_ENCHANTMENT_EFFECTS ; k ++ )
2010-01-10 01:23:15 +01:00
{
2011-06-29 13:09:32 +02:00
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( item_rand_suffix -> enchant_id [ k ]);
2010-04-07 19:14:10 +02:00
if ( pEnchant )
2010-01-10 01:23:15 +01:00
{
2010-09-28 08:21:51 +03:00
for ( int t = 0 ; t < MAX_ITEM_ENCHANTMENT_EFFECTS ; t ++ )
2011-07-26 23:09:28 +02:00
if ( pEnchant -> spellid [ t ] == m_spellInfo -> Id )
2010-01-10 01:23:15 +01:00
{
2010-04-07 22:59:46 +02:00
amount = uint32 (( item_rand_suffix -> prefix [ k ] * castItem -> GetItemSuffixFactor ()) / 10000 );
2010-01-10 01:23:15 +01:00
break ;
}
}
2010-04-07 19:14:10 +02:00
if ( amount )
2010-01-10 01:23:15 +01:00
break ;
}
}
}
float DoneActualBenefit = 0.0f ;
// custom amount calculations go here
switch ( GetAuraType ())
{
// crowd control auras
case SPELL_AURA_MOD_CONFUSE :
case SPELL_AURA_MOD_FEAR :
case SPELL_AURA_MOD_STUN :
case SPELL_AURA_MOD_ROOT :
case SPELL_AURA_TRANSFORM :
m_canBeRecalculated = false ;
2011-07-26 23:09:28 +02:00
if ( ! m_spellInfo -> ProcFlags )
2010-01-10 01:23:15 +01:00
break ;
2010-08-26 01:20:57 +06:00
amount = int32 ( GetBase () -> GetUnitOwner () -> CountPctFromMaxHealth ( 10 ));
2010-01-10 01:23:15 +01:00
if ( caster )
{
// Glyphs increasing damage cap
Unit :: AuraEffectList const & overrideClassScripts = caster -> GetAuraEffectsByType ( SPELL_AURA_OVERRIDE_CLASS_SCRIPTS );
for ( Unit :: AuraEffectList :: const_iterator itr = overrideClassScripts . begin (); itr != overrideClassScripts . end (); ++ itr )
{
2011-07-26 23:09:28 +02:00
if (( * itr ) -> IsAffectedOnSpell ( m_spellInfo ))
2010-01-10 01:23:15 +01:00
{
// Glyph of Fear, Glyph of Frost nova and similar auras
if (( * itr ) -> GetMiscValue () == 7801 )
{
2010-12-11 20:37:38 +06:00
AddPctN ( amount , ( * itr ) -> GetAmount ());
2010-01-10 01:23:15 +01:00
break ;
}
}
}
}
break ;
case SPELL_AURA_SCHOOL_ABSORB :
m_canBeRecalculated = false ;
if ( ! caster )
break ;
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2010-01-10 01:23:15 +01:00
{
case SPELLFAMILY_MAGE :
// Ice Barrier
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x1 && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-01-10 01:23:15 +01:00
{
2010-06-24 15:05:55 +02:00
// +80.68% from sp bonus
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseDamageBonus ( m_spellInfo -> GetSchoolMask ()) * 0.8068f ;
2010-06-24 15:05:55 +02:00
// Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
// Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage
2011-07-26 23:09:28 +02:00
DoneActualBenefit = caster -> ApplyEffectModifiers ( GetSpellInfo (), m_effIndex , DoneActualBenefit );
2010-06-24 15:05:55 +02:00
}
// Fire Ward
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x8 && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-06-24 15:05:55 +02:00
{
// +80.68% from sp bonus
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseDamageBonus ( m_spellInfo -> GetSchoolMask ()) * 0.8068f ;
2010-06-24 15:05:55 +02:00
}
// Frost Ward
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x100 && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-06-24 15:05:55 +02:00
{
// +80.68% from sp bonus
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseDamageBonus ( m_spellInfo -> GetSchoolMask ()) * 0.8068f ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELLFAMILY_WARLOCK :
// Shadow Ward
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 2 ] & 0x40 )
2010-01-10 01:23:15 +01:00
{
2010-06-24 15:12:01 +02:00
// +80.68% from sp bonus
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseDamageBonus ( m_spellInfo -> GetSchoolMask ()) * 0.8068f ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELLFAMILY_PRIEST :
// Power Word: Shield
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x1 && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x400 )
2010-01-10 01:23:15 +01:00
{
2010-12-11 20:37:38 +06:00
// +80.68% from sp bonus
2010-01-10 01:23:15 +01:00
float bonus = 0.8068f ;
2010-04-12 23:37:47 +02:00
2010-01-10 01:23:15 +01:00
// Borrowed Time
2011-07-15 07:12:54 +07:00
if ( AuraEffect const * pAurEff = caster -> GetDummyAuraEffect ( SPELLFAMILY_PRIEST , 2899 , 1 ))
2010-12-11 20:37:38 +06:00
bonus += CalculatePctN ( 1.0f , pAurEff -> GetAmount ());
2010-04-12 23:37:47 +02:00
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseHealingBonus ( m_spellInfo -> GetSchoolMask ()) * bonus ;
2010-12-02 23:50:36 +01:00
// Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
// Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
2011-07-26 23:09:28 +02:00
DoneActualBenefit = caster -> ApplyEffectModifiers ( GetSpellInfo (), m_effIndex , DoneActualBenefit );
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellInfo ());
2010-12-02 23:50:36 +01:00
2010-12-11 20:37:38 +06:00
amount += int32 ( DoneActualBenefit );
2010-12-02 23:50:36 +01:00
2010-04-12 23:37:47 +02:00
// Twin Disciplines
2010-12-02 23:50:36 +01:00
if ( AuraEffect const * pAurEff = caster -> GetAuraEffect ( SPELL_AURA_ADD_PCT_MODIFIER , SPELLFAMILY_PRIEST , 0x400000 , 0 , 0 , caster -> GetGUID ()))
2010-12-11 20:37:38 +06:00
AddPctN ( amount , pAurEff -> GetAmount ());
2010-04-12 23:37:47 +02:00
2010-12-13 22:37:56 +01:00
// Focused Power
2010-12-16 23:16:14 +01:00
// Reuse variable, not sure if this code below can be moved before Twin Disciplines
DoneActualBenefit = float ( amount );
DoneActualBenefit *= caster -> GetTotalAuraMultiplier ( SPELL_AURA_MOD_HEALING_DONE_PERCENT );
amount = int32 ( DoneActualBenefit );
2010-04-07 18:09:10 +02:00
2010-12-02 23:50:36 +01:00
return amount ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELLFAMILY_PALADIN :
// Sacred Shield
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x80000 )
2010-01-10 01:23:15 +01:00
{
2010-12-02 23:50:36 +01:00
//+75.00% from sp bonus
float bonus = 0.75f ;
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseHealingBonus ( m_spellInfo -> GetSchoolMask ()) * bonus ;
2010-12-02 23:50:36 +01:00
// Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
2011-07-26 23:09:28 +02:00
DoneActualBenefit = caster -> ApplyEffectModifiers ( GetSpellInfo (), m_effIndex , DoneActualBenefit );
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellInfo ());
2010-12-02 23:50:36 +01:00
amount += ( int32 ) DoneActualBenefit ;
2010-12-13 22:37:56 +01:00
2010-12-02 23:50:36 +01:00
// Arena - Dampening
if ( AuraEffect const * pAurEff = caster -> GetAuraEffect ( 74410 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( amount , pAurEff -> GetAmount ());
2010-12-02 23:50:36 +01:00
// Battleground - Dampening
else if ( AuraEffect const * pAurEff = caster -> GetAuraEffect ( 74411 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( amount , pAurEff -> GetAmount ());
2010-12-02 23:50:36 +01:00
return amount ;
2010-01-10 01:23:15 +01:00
}
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELL_AURA_MANA_SHIELD :
m_canBeRecalculated = false ;
if ( ! caster )
break ;
// Mana Shield
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_MAGE && GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x8000 && m_spellInfo -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-01-10 01:23:15 +01:00
{
// +80.53% from +spd bonus
2011-07-26 23:09:28 +02:00
DoneActualBenefit += caster -> SpellBaseDamageBonus ( m_spellInfo -> GetSchoolMask ()) * 0.8053f ;;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELL_AURA_DUMMY :
if ( ! caster )
break ;
// Earth Shield
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x400 )
amount = caster -> SpellHealingBonus ( GetBase () -> GetUnitOwner (), GetSpellInfo (), amount , SPELL_DIRECT_DAMAGE );
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_PERIODIC_DAMAGE :
if ( ! caster )
break ;
// Rupture
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_ROGUE && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x100000 )
2010-01-10 01:23:15 +01:00
{
m_canBeRecalculated = false ;
if ( caster -> GetTypeId () != TYPEID_PLAYER )
break ;
//1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
//2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
//3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
//4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
//5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
float AP_per_combo [ 6 ] = { 0.0f , 0.015f , 0.024f , 0.03f , 0.03428571f , 0.0375f };
2010-03-07 15:20:19 +01:00
uint8 cp = caster -> ToPlayer () -> GetComboPoints ();
2010-01-10 01:23:15 +01:00
if ( cp > 5 ) cp = 5 ;
amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * AP_per_combo [ cp ]);
}
// Rip
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00800000 && GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
2010-01-10 01:23:15 +01:00
{
m_canBeRecalculated = false ;
// 0.01*$AP*cp
if ( caster -> GetTypeId () != TYPEID_PLAYER )
break ;
2010-03-07 15:20:19 +01:00
uint8 cp = caster -> ToPlayer () -> GetComboPoints ();
2010-01-10 01:23:15 +01:00
// Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( 34241 , 0 ))
2010-01-10 01:23:15 +01:00
amount += cp * aurEff -> GetAmount ();
2011-01-28 12:02:51 +01:00
amount += uint32 ( CalculatePctU ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ), cp ));
2010-01-10 01:23:15 +01:00
}
// Rend
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_WARRIOR && GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x20 )
2010-01-10 01:23:15 +01:00
{
m_canBeRecalculated = false ;
2010-12-11 20:37:38 +06:00
// $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick
2010-01-10 01:23:15 +01:00
float ap = caster -> GetTotalAttackPowerValue ( BASE_ATTACK );
int32 mws = caster -> GetAttackTime ( BASE_ATTACK );
2011-04-29 20:47:02 +02:00
float mwb_min = caster -> GetWeaponDamageRange ( BASE_ATTACK , MINDAMAGE );
float mwb_max = caster -> GetWeaponDamageRange ( BASE_ATTACK , MAXDAMAGE );
2010-12-11 20:37:38 +06:00
float mwb = (( mwb_min + mwb_max ) / 2 + ap * mws / 14000 ) * 0.2f ;
2011-07-26 23:09:28 +02:00
amount += int32 ( caster -> ApplyEffectModifiers ( m_spellInfo , m_effIndex , mwb ));
2010-01-10 01:23:15 +01:00
// "If used while your target is above 75% health, Rend does 35% more damage."
// as for 3.1.3 only ranks above 9 (wrong tooltip?)
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> GetRank () >= 9 )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
if ( GetBase () -> GetUnitOwner () -> HasAuraState ( AURA_STATE_HEALTH_ABOVE_75_PERCENT , m_spellInfo , caster ))
AddPctN ( amount , m_spellInfo -> Effects [ EFFECT_2 ]. CalcValue ( caster ));
2010-01-10 01:23:15 +01:00
}
}
2010-07-31 20:31:40 +02:00
// Unholy Blight damage over time effect
else if ( GetId () == 50536 )
{
m_canBeRecalculated = false ;
// we're getting total damage on aura apply, change it to be damage per tick
2010-08-22 12:39:39 -07:00
amount = int32 (( float ) amount / GetTotalTicks ());
2010-07-31 20:31:40 +02:00
}
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_PERIODIC_ENERGIZE :
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_GENERIC )
2010-01-10 01:23:15 +01:00
{
// Replenishment (0.25% from max)
// Infinite Replenishment
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellIconID == 3184 && m_spellInfo -> SpellVisual [ 0 ] == 12495 )
2010-01-10 01:23:15 +01:00
amount = GetBase () -> GetUnitOwner () -> GetMaxPower ( POWER_MANA ) * 25 / 10000 ;
}
// Innervate
2011-07-26 23:09:28 +02:00
else if ( m_spellInfo -> Id == 29166 )
2010-12-11 20:37:38 +06:00
ApplyPctF ( amount , float ( GetBase () -> GetUnitOwner () -> GetCreatePowers ( POWER_MANA )) / GetTotalTicks ());
2010-01-10 01:23:15 +01:00
// Owlkin Frenzy
2011-07-26 23:09:28 +02:00
else if ( m_spellInfo -> Id == 48391 )
2010-12-11 20:37:38 +06:00
ApplyPctU ( amount , GetBase () -> GetUnitOwner () -> GetCreatePowers ( POWER_MANA ));
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_PERIODIC_HEAL :
if ( ! caster )
break ;
// Lightwell Renew
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo -> SpellFamilyFlags [ 2 ] & 0x4000 )
2010-01-10 01:23:15 +01:00
{
if ( caster -> GetTypeId () == TYPEID_PLAYER )
// Bonus from Glyph of Lightwell
if ( AuraEffect * modHealing = caster -> GetAuraEffect ( 55673 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( amount , modHealing -> GetAmount ());
2010-01-10 01:23:15 +01:00
}
break ;
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN :
if ( ! caster )
break ;
// Icebound Fortitude
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00100000 )
2010-01-10 01:23:15 +01:00
{
if ( caster -> GetTypeId () == TYPEID_PLAYER )
{
2010-08-26 15:54:56 +06:00
int32 value = ( - 1 * amount ) - 10 ;
2010-03-07 15:20:19 +01:00
uint32 defva = uint32 ( caster -> ToPlayer () -> GetSkillValue ( SKILL_DEFENSE ) + caster -> ToPlayer () -> GetRatingBonusValue ( CR_DEFENSE_SKILL ));
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( defva > 400 )
2010-08-26 15:54:56 +06:00
value += int32 (( defva - 400 ) * 0.15 );
2010-01-10 01:23:15 +01:00
// Glyph of Icebound Fortitude
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( 58625 , 0 ))
2010-01-10 01:23:15 +01:00
{
2010-08-26 15:54:56 +06:00
int32 valMax = aurEff -> GetAmount ();
2010-04-07 19:14:10 +02:00
if ( value < valMax )
2010-01-10 01:23:15 +01:00
value = valMax ;
}
amount = - value ;
}
}
2010-07-31 20:51:53 +02:00
// Hand of Salvation
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_PALADIN && GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000100 )
2010-07-31 20:51:53 +02:00
{
//Glyph of Salvation
if ( caster -> GetGUID () == GetBase () -> GetUnitOwner () -> GetGUID ())
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( 63225 , 0 ))
2010-07-31 20:51:53 +02:00
amount = - aurEff -> GetAmount ();
}
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_MOD_THREAT :
{
uint8 level_diff = 0 ;
float multiplier = 0.0 ;
switch ( GetId ())
{
// Arcane Shroud
case 26400 :
level_diff = GetBase () -> GetUnitOwner () -> getLevel () - 60 ;
multiplier = 2 ;
break ;
// The Eye of Diminution
case 28862 :
level_diff = GetBase () -> GetUnitOwner () -> getLevel () - 60 ;
multiplier = 1 ;
break ;
}
if ( level_diff > 0 )
2010-08-22 12:39:39 -07:00
amount += int32 ( multiplier * level_diff );
2010-01-10 01:23:15 +01:00
break ;
}
case SPELL_AURA_MOD_INCREASE_HEALTH :
// Vampiric Blood
if ( GetId () == 55233 )
2010-08-26 01:20:57 +06:00
amount = GetBase () -> GetUnitOwner () -> CountPctFromMaxHealth ( amount );
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_MOD_INCREASE_ENERGY :
// Hymn of Hope
if ( GetId () == 64904 )
2010-12-11 20:37:38 +06:00
ApplyPctU ( amount , GetBase () -> GetUnitOwner () -> GetMaxPower ( GetBase () -> GetUnitOwner () -> getPowerType ()));
2010-01-10 01:23:15 +01:00
break ;
case SPELL_AURA_MOD_INCREASE_SPEED :
// Dash - do not set speed if not in cat form
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x00000008 )
2010-12-09 17:03:42 +06:00
amount = GetBase () -> GetUnitOwner () -> GetShapeshiftForm () == FORM_CAT ? amount : 0 ;
2010-08-21 20:08:47 +02:00
break ;
default :
break ;
2010-01-10 01:23:15 +01:00
}
if ( DoneActualBenefit != 0.0f )
{
2011-07-26 23:09:28 +02:00
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellInfo ());
2010-01-10 01:23:15 +01:00
amount += ( int32 ) DoneActualBenefit ;
}
2010-08-24 00:10:49 +02:00
2011-06-29 13:09:32 +02:00
GetBase () -> CallScriptEffectCalcAmountHandlers ( const_cast < AuraEffect const *> ( this ), amount , m_canBeRecalculated );
2010-01-10 01:23:15 +01:00
amount *= GetBase () -> GetStackAmount ();
return amount ;
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: CalculatePeriodic ( Unit * caster , bool create , bool load )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
m_amplitude = m_spellInfo -> Effects [ m_effIndex ]. Amplitude ;
2010-01-10 01:23:15 +01:00
// prepare periodics
switch ( GetAuraType ())
{
case SPELL_AURA_OBS_MOD_POWER :
// 3 spells have no amplitude set
if ( ! m_amplitude )
2010-07-12 00:30:17 +02:00
m_amplitude = 1 * IN_MILLISECONDS ;
2010-01-10 01:23:15 +01:00
case SPELL_AURA_PERIODIC_DAMAGE :
case SPELL_AURA_PERIODIC_HEAL :
case SPELL_AURA_PERIODIC_ENERGIZE :
case SPELL_AURA_OBS_MOD_HEALTH :
case SPELL_AURA_PERIODIC_LEECH :
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL :
case SPELL_AURA_PERIODIC_MANA_LEECH :
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT :
case SPELL_AURA_POWER_BURN_MANA :
2010-02-23 23:48:50 +01:00
m_isPeriodic = true ;
break ;
2010-01-10 01:23:15 +01:00
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
2010-02-23 23:48:50 +01:00
if ( GetId () == 51912 )
m_amplitude = 3000 ;
m_isPeriodic = true ;
break ;
2010-01-10 01:23:15 +01:00
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE :
case SPELL_AURA_PERIODIC_DUMMY :
m_isPeriodic = true ;
break ;
case SPELL_AURA_DUMMY :
// Haunting Spirits - perdiodic trigger demon
if ( GetId () == 7057 )
{
m_isPeriodic = true ;
m_amplitude = irand ( 0 , 60 ) + 30 ;
2010-07-12 00:30:17 +02:00
m_amplitude *= IN_MILLISECONDS ;
2010-01-10 01:23:15 +01:00
}
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-29 13:09:32 +02:00
GetBase () -> CallScriptEffectCalcPeriodicHandlers ( const_cast < AuraEffect const *> ( this ), m_isPeriodic , m_amplitude );
2010-08-24 00:10:49 +02:00
2010-01-10 01:23:15 +01:00
if ( ! m_isPeriodic )
return ;
Player * modOwner = caster ? caster -> GetSpellModOwner () : NULL ;
2010-04-25 22:20:59 +02:00
2010-02-14 19:13:14 -07:00
// Apply casting time mods
2010-08-01 01:22:13 +02:00
if ( m_amplitude )
2010-02-14 19:13:14 -07:00
{
2010-04-25 22:20:59 +02:00
// Apply periodic time mod
2010-08-01 01:22:13 +02:00
if ( modOwner )
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_ACTIVATION_TIME , m_amplitude );
2010-04-25 22:20:59 +02:00
2010-08-01 01:22:13 +02:00
if ( caster )
2010-07-16 13:20:50 +02:00
{
2010-08-01 01:22:13 +02:00
// Haste modifies periodic time of channeled spells
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> IsChanneled ())
2011-05-15 04:24:49 +07:00
{
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION )
caster -> ModSpellCastTime ( m_spellInfo , m_amplitude );
2011-05-15 04:24:49 +07:00
}
2010-08-01 01:22:13 +02:00
// and periodic time of auras affected by SPELL_AURA_PERIODIC_HASTE
2011-07-26 23:09:28 +02:00
else if ( caster -> HasAuraTypeWithAffectMask ( SPELL_AURA_PERIODIC_HASTE , m_spellInfo ) || m_spellInfo -> AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION )
2010-08-22 12:39:39 -07:00
m_amplitude = int32 ( m_amplitude * caster -> GetFloatValue ( UNIT_MOD_CAST_SPEED ));
2010-02-14 19:13:14 -07:00
}
}
2010-01-10 01:23:15 +01:00
2011-06-09 17:04:52 +02:00
if ( load ) // aura loaded from db
2010-01-10 01:23:15 +01:00
{
2011-06-09 17:04:52 +02:00
m_tickNumber = m_amplitude ? GetBase () -> GetDuration () / m_amplitude : 0 ;
m_periodicTimer = m_amplitude ? GetBase () -> GetDuration () % m_amplitude : 0 ;
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> AttributesEx5 & SPELL_ATTR5_START_PERIODIC_AT_APPLY )
2010-01-10 01:23:15 +01:00
++ m_tickNumber ;
}
2011-06-09 17:04:52 +02:00
else // aura just created or reapplied
{
m_tickNumber = 0 ;
// reset periodic timer on aura create or on reapply when aura isn't dot
// possibly we should not reset periodic timers only when aura is triggered by proc
// or maybe there's a spell attribute somewhere
2011-06-23 09:13:58 +02:00
bool resetPeriodicTimer = create
2011-06-09 17:04:52 +02:00
|| (( GetAuraType () != SPELL_AURA_PERIODIC_DAMAGE ) && ( GetAuraType () != SPELL_AURA_PERIODIC_DAMAGE_PERCENT ));
if ( resetPeriodicTimer )
{
m_periodicTimer = 0 ;
// Start periodic on next tick or at aura apply
2011-07-26 23:09:28 +02:00
if ( m_amplitude && ! ( m_spellInfo -> AttributesEx5 & SPELL_ATTR5_START_PERIODIC_AT_APPLY ))
2011-06-09 17:04:52 +02:00
m_periodicTimer += m_amplitude ;
}
}
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: CalculateSpellMod ()
{
switch ( GetAuraType ())
{
case SPELL_AURA_DUMMY :
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2010-01-10 01:23:15 +01:00
{
case SPELLFAMILY_PRIEST :
// Pain and Suffering
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellIconID == 2874 )
2010-01-10 01:23:15 +01:00
{
if ( ! m_spellmod )
{
m_spellmod = new SpellModifier ( GetBase ());
m_spellmod -> op = SPELLMOD_DOT ;
m_spellmod -> type = SPELLMOD_PCT ;
m_spellmod -> spellId = GetId ();
m_spellmod -> mask [ 1 ] = 0x00002000 ;
}
m_spellmod -> value = GetAmount ();
}
break ;
case SPELLFAMILY_DRUID :
switch ( GetId ())
{
case 34246 : // Idol of the Emerald Queen
case 60779 : // Idol of Lush Moss
{
if ( ! m_spellmod )
{
m_spellmod = new SpellModifier ( GetBase ());
m_spellmod -> op = SPELLMOD_DOT ;
m_spellmod -> type = SPELLMOD_FLAT ;
m_spellmod -> spellId = GetId ();
m_spellmod -> mask [ 1 ] = 0x0010 ;
}
m_spellmod -> value = GetAmount () / 7 ;
}
break ;
}
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2010-09-23 22:35:05 +02:00
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE :
2010-01-10 01:23:15 +01:00
switch ( GetId ())
{
case 51466 : // Elemental oath
case 51470 : // Elemental oath
// "while Clearcasting from Elemental Focus is active, you deal 5%/10% more spell damage."
if ( ! m_spellmod )
{
m_spellmod = new SpellModifier ( GetBase ());
m_spellmod -> op = SPELLMOD_EFFECT2 ;
m_spellmod -> type = SPELLMOD_FLAT ;
m_spellmod -> spellId = GetId ();
m_spellmod -> mask [ 1 ] = 0x0004000 ;
}
2011-07-26 23:09:28 +02:00
m_spellmod -> value = GetBase () -> GetUnitOwner () -> CalculateSpellDamage ( GetBase () -> GetUnitOwner (), GetSpellInfo (), 1 );
2010-01-10 01:23:15 +01:00
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELL_AURA_ADD_FLAT_MODIFIER :
case SPELL_AURA_ADD_PCT_MODIFIER :
if ( ! m_spellmod )
{
m_spellmod = new SpellModifier ( GetBase ());
m_spellmod -> op = SpellModOp ( GetMiscValue ());
2010-07-30 20:04:28 +02:00
ASSERT ( m_spellmod -> op < MAX_SPELLMOD );
2010-01-10 01:23:15 +01:00
m_spellmod -> type = SpellModType ( GetAuraType ()); // SpellModType value == spell aura types
m_spellmod -> spellId = GetId ();
2011-07-26 23:09:28 +02:00
m_spellmod -> mask = GetSpellInfo () -> Effects [ GetEffIndex ()]. SpellClassMask ;
2010-01-10 01:23:15 +01:00
m_spellmod -> charges = GetBase () -> GetCharges ();
}
m_spellmod -> value = GetAmount ();
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-29 13:09:32 +02:00
GetBase () -> CallScriptEffectCalcSpellModHandlers ( const_cast < AuraEffect const *> ( this ), m_spellmod );
2010-01-10 01:23:15 +01:00
}
2011-05-29 13:18:47 +02:00
void AuraEffect :: ChangeAmount ( int32 newAmount , bool mark , bool onStackOrReapply )
2010-01-10 01:23:15 +01:00
{
// Reapply if amount change
2011-05-29 13:18:47 +02:00
uint8 handleMask = 0 ;
2010-04-08 08:20:08 +02:00
if ( newAmount != GetAmount ())
2011-05-29 13:18:47 +02:00
handleMask |= AURA_EFFECT_HANDLE_CHANGE_AMOUNT ;
if ( onStackOrReapply )
handleMask |= AURA_EFFECT_HANDLE_REAPPLY ;
if ( ! handleMask )
return ;
2011-05-31 14:50:54 +02:00
2011-05-31 16:03:27 +02:00
std :: list < AuraApplication *> effectApplications ;
2011-05-31 14:50:54 +02:00
GetApplicationList ( effectApplications );
2011-05-31 16:03:27 +02:00
for ( std :: list < AuraApplication *>:: const_iterator apptItr = effectApplications . begin (); apptItr != effectApplications . end (); ++ apptItr )
2011-05-31 14:50:54 +02:00
if (( * apptItr ) -> HasEffect ( GetEffIndex ()))
HandleEffect ( * apptItr , handleMask , false );
2011-05-31 16:20:27 +02:00
if ( handleMask & AURA_EFFECT_HANDLE_CHANGE_AMOUNT )
2010-01-10 01:23:15 +01:00
{
if ( ! mark )
m_amount = newAmount ;
else
SetAmount ( newAmount );
CalculateSpellMod ();
2011-05-29 13:18:47 +02:00
}
2011-05-31 14:50:54 +02:00
2011-05-31 16:03:27 +02:00
for ( std :: list < AuraApplication *>:: const_iterator apptItr = effectApplications . begin (); apptItr != effectApplications . end (); ++ apptItr )
2011-05-31 14:50:54 +02:00
if (( * apptItr ) -> HasEffect ( GetEffIndex ()))
HandleEffect ( * apptItr , handleMask , true );
2010-01-10 01:23:15 +01:00
}
2011-05-31 16:03:27 +02:00
void AuraEffect :: HandleEffect ( AuraApplication * aurApp , uint8 mode , bool apply )
2010-01-10 01:23:15 +01:00
{
2011-05-29 13:18:47 +02:00
// check if call is correct, we really don't want using bitmasks here (with 1 exception)
2011-06-08 09:19:34 +02:00
ASSERT ( mode == AURA_EFFECT_HANDLE_REAL
2010-01-10 01:23:15 +01:00
|| mode == AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
|| mode == AURA_EFFECT_HANDLE_CHANGE_AMOUNT
2011-05-29 13:18:47 +02:00
|| mode == AURA_EFFECT_HANDLE_STAT
2011-06-08 09:19:34 +02:00
|| mode == AURA_EFFECT_HANDLE_SKILL
2011-05-29 13:18:47 +02:00
|| mode == AURA_EFFECT_HANDLE_REAPPLY
|| mode == ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAPPLY ));
2010-01-10 01:23:15 +01:00
2011-05-25 17:13:32 +02:00
// register/unregister effect in lists in case of real AuraEffect apply/remove
// registration/unregistration is done always before real effect handling (some effect handlers code is depending on this)
if ( mode & AURA_EFFECT_HANDLE_REAL )
aurApp -> GetTarget () -> _RegisterAuraEffect ( this , apply );
2010-01-10 01:23:15 +01:00
// real aura apply/remove, handle modifier
if ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK )
ApplySpellMod ( aurApp -> GetTarget (), apply );
2011-05-25 17:13:32 +02:00
// call scripts helping/replacing effect handlers
2010-08-24 00:10:49 +02:00
bool prevented = false ;
if ( apply )
2011-06-29 13:09:32 +02:00
prevented = GetBase () -> CallScriptEffectApplyHandlers ( const_cast < AuraEffect const *> ( this ), const_cast < AuraApplication const *> ( aurApp ), ( AuraEffectHandleModes ) mode );
2010-08-24 00:10:49 +02:00
else
2011-06-29 13:09:32 +02:00
prevented = GetBase () -> CallScriptEffectRemoveHandlers ( const_cast < AuraEffect const *> ( this ), const_cast < AuraApplication const *> ( aurApp ), ( AuraEffectHandleModes ) mode );
2010-08-24 00:10:49 +02:00
2010-12-31 14:39:18 +01:00
// check if script events have removed the aura or if default effect prevention was requested
if (( apply && aurApp -> GetRemoveMode ()) || prevented )
return ;
2011-06-29 13:09:32 +02:00
( * this . * AuraEffectHandler [ GetAuraType ()])( const_cast < AuraApplication const *> ( aurApp ), mode , apply );
2011-05-25 17:13:32 +02:00
// check if script events have removed the aura or if default effect prevention was requested
if ( apply && aurApp -> GetRemoveMode ())
return ;
// call scripts triggering additional events after apply/remove
if ( apply )
2011-06-29 13:09:32 +02:00
GetBase () -> CallScriptAfterEffectApplyHandlers ( const_cast < AuraEffect const *> ( this ), const_cast < AuraApplication const *> ( aurApp ), ( AuraEffectHandleModes ) mode );
2011-05-25 17:13:32 +02:00
else
2011-06-29 13:09:32 +02:00
GetBase () -> CallScriptAfterEffectRemoveHandlers ( const_cast < AuraEffect const *> ( this ), const_cast < AuraApplication const *> ( aurApp ), ( AuraEffectHandleModes ) mode );
2010-01-10 01:23:15 +01:00
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: HandleEffect ( Unit * target , uint8 mode , bool apply )
2010-01-10 01:23:15 +01:00
{
2011-07-15 07:12:54 +07:00
AuraApplication * aurApp = GetBase () -> GetApplicationOfTarget ( target -> GetGUID ());
2010-07-30 20:04:28 +02:00
ASSERT ( aurApp );
2010-01-10 01:23:15 +01:00
HandleEffect ( aurApp , mode , apply );
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: ApplySpellMod ( Unit * target , bool apply )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! m_spellmod || target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> AddSpellMod ( m_spellmod , apply );
2010-01-10 01:23:15 +01:00
// Auras with charges do not mod amount of passive auras
2011-07-10 13:13:02 +02:00
if ( GetBase () -> IsUsingCharges ())
2010-01-10 01:23:15 +01:00
return ;
// reapply some passive spells after add/remove related spellmods
// Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
switch ( GetMiscValue ())
{
case SPELLMOD_ALL_EFFECTS :
case SPELLMOD_EFFECT1 :
case SPELLMOD_EFFECT2 :
case SPELLMOD_EFFECT3 :
{
uint64 guid = target -> GetGUID ();
Unit :: AuraApplicationMap & auras = target -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator iter = auras . begin (); iter != auras . end (); ++ iter )
{
2011-07-15 07:12:54 +07:00
Aura * aura = iter -> second -> GetBase ();
2010-01-10 01:23:15 +01:00
// only passive auras-active auras should have amount set on spellcast and not be affected
// if aura is casted by others, it will not be affected
2011-07-26 23:09:28 +02:00
if (( aura -> IsPassive () || aura -> GetSpellInfo () -> AttributesEx2 & SPELL_ATTR2_ALWAYS_APPLY_MODIFIERS ) && aura -> GetCasterGUID () == guid && aura -> GetSpellInfo () -> IsAffectedBySpellMod ( m_spellmod ))
2010-01-10 01:23:15 +01:00
{
if ( GetMiscValue () == SPELLMOD_ALL_EFFECTS )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = aura -> GetEffect ( i ))
2010-01-10 01:23:15 +01:00
aurEff -> RecalculateAmount ();
}
}
else if ( GetMiscValue () == SPELLMOD_EFFECT1 )
{
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = aura -> GetEffect ( 0 ))
2010-01-10 01:23:15 +01:00
aurEff -> RecalculateAmount ();
}
else if ( GetMiscValue () == SPELLMOD_EFFECT2 )
{
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = aura -> GetEffect ( 1 ))
2010-01-10 01:23:15 +01:00
aurEff -> RecalculateAmount ();
}
2010-04-07 23:56:35 +02:00
else //if (modOp == SPELLMOD_EFFECT3)
2010-01-10 01:23:15 +01:00
{
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = aura -> GetEffect ( 2 ))
2010-01-10 01:23:15 +01:00
aurEff -> RecalculateAmount ();
}
}
}
}
default :
break ;
}
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: Update ( uint32 diff , Unit * caster )
2010-01-10 01:23:15 +01:00
{
if ( m_isPeriodic && ( GetBase () -> GetDuration () >= 0 || GetBase () -> IsPassive () || GetBase () -> IsPermanent ()))
{
2010-07-26 14:27:22 +02:00
if ( m_periodicTimer > int32 ( diff ))
2010-01-10 01:23:15 +01:00
m_periodicTimer -= diff ;
2010-04-07 23:25:02 +02:00
else // tick also at m_periodicTimer == 0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
2010-01-10 01:23:15 +01:00
{
++ m_tickNumber ;
// update before tick (aura can be removed in TriggerSpell or PeriodicTick calls)
m_periodicTimer += m_amplitude - diff ;
UpdatePeriodic ( caster );
2011-05-31 16:03:27 +02:00
std :: list < AuraApplication *> effectApplications ;
2010-12-05 21:38:52 +01:00
GetApplicationList ( effectApplications );
2010-01-10 01:23:15 +01:00
// tick on targets of effects
2011-05-31 16:03:27 +02:00
for ( std :: list < AuraApplication *>:: const_iterator apptItr = effectApplications . begin (); apptItr != effectApplications . end (); ++ apptItr )
2011-05-31 14:50:54 +02:00
if (( * apptItr ) -> HasEffect ( GetEffIndex ()))
PeriodicTick ( * apptItr , caster );
2010-01-10 01:23:15 +01:00
}
}
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: UpdatePeriodic ( Unit * caster )
2010-01-10 01:23:15 +01:00
{
switch ( GetAuraType ())
{
case SPELL_AURA_DUMMY :
// Haunting Spirits
if ( GetId () == 7057 )
{
2010-04-07 22:59:46 +02:00
m_amplitude = irand ( 0 , 60 ) + 30 ;
2010-07-12 00:30:17 +02:00
m_amplitude *= IN_MILLISECONDS ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELL_AURA_PERIODIC_DUMMY :
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2010-01-10 01:23:15 +01:00
{
case SPELLFAMILY_GENERIC :
switch ( GetId ())
{
// Drink
case 430 :
case 431 :
case 432 :
case 1133 :
case 1135 :
case 1137 :
case 10250 :
case 22734 :
case 27089 :
case 34291 :
case 43182 :
case 43183 :
case 46755 :
case 49472 : // Drink Coffee
case 57073 :
case 61830 :
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
// Get SPELL_AURA_MOD_POWER_REGEN aura from spell
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = GetBase () -> GetEffect ( 0 ))
2010-01-10 01:23:15 +01:00
{
if ( aurEff -> GetAuraType () != SPELL_AURA_MOD_POWER_REGEN )
{
m_isPeriodic = false ;
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Aura %d structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN" , GetId ());
2010-01-10 01:23:15 +01:00
}
else
{
// default case - not in arena
2010-03-07 15:20:19 +01:00
if ( ! caster -> ToPlayer () -> InArena ())
2010-01-10 01:23:15 +01:00
{
aurEff -> ChangeAmount ( GetAmount ());
m_isPeriodic = false ;
}
else
{
2011-01-16 12:23:17 +01:00
// **********************************************
2010-01-10 01:23:15 +01:00
// This feature uses only in arenas
2011-01-16 12:23:17 +01:00
// **********************************************
2010-01-10 01:23:15 +01:00
// Here need increase mana regen per tick (6 second rule)
// on 0 tick - 0 (handled in 2 second)
// on 1 tick - 166% (handled in 4 second)
// on 2 tick - 133% (handled in 6 second)
// Apply bonus for 1 - 4 tick
switch ( m_tickNumber )
{
case 1 : // 0%
aurEff -> ChangeAmount ( 0 );
break ;
case 2 : // 166%
aurEff -> ChangeAmount ( GetAmount () * 5 / 3 );
break ;
case 3 : // 133%
aurEff -> ChangeAmount ( GetAmount () * 4 / 3 );
break ;
default : // 100% - normal regen
aurEff -> ChangeAmount ( GetAmount ());
// No need to update after 4th tick
m_isPeriodic = false ;
break ;
}
}
}
}
break ;
case 58549 : // Tenacity
case 59911 : // Tenacity (vehicle)
GetBase () -> RefreshDuration ();
break ;
2010-08-21 01:02:38 -03:00
case 66823 : case 67618 : case 67619 : case 67620 : // Paralytic Toxin
// Get 0 effect aura
2011-07-15 07:12:54 +07:00
if ( AuraEffect * slow = GetBase () -> GetEffect ( 0 ))
2010-08-21 01:02:38 -03:00
{
int32 newAmount = slow -> GetAmount () - 10 ;
if ( newAmount < - 100 )
newAmount = - 100 ;
slow -> ChangeAmount ( newAmount );
}
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
break ;
2010-04-07 18:09:10 +02:00
case SPELLFAMILY_MAGE :
2010-01-10 01:23:15 +01:00
if ( GetId () == 55342 ) // Mirror Image
m_isPeriodic = false ;
break ;
case SPELLFAMILY_DEATHKNIGHT :
// Chains of Ice
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x00004000 )
2010-01-10 01:23:15 +01:00
{
// Get 0 effect aura
2011-07-15 07:12:54 +07:00
if ( AuraEffect * slow = GetBase () -> GetEffect ( 0 ))
2010-01-10 01:23:15 +01:00
{
int32 newAmount = slow -> GetAmount () + GetAmount ();
if ( newAmount > 0 )
newAmount = 0 ;
slow -> ChangeAmount ( newAmount );
}
return ;
}
2010-08-21 20:08:47 +02:00
break ;
default :
break ;
2010-01-10 01:23:15 +01:00
}
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2010-08-24 00:10:49 +02:00
GetBase () -> CallScriptEffectUpdatePeriodicHandlers ( this );
2010-01-10 01:23:15 +01:00
}
2011-06-11 22:35:29 +02:00
bool AuraEffect :: IsPeriodicTickCrit ( Unit * target , Unit const * caster ) const
2010-01-10 01:23:15 +01:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( caster );
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & mPeriodicCritAuras = caster -> GetAuraEffectsByType ( SPELL_AURA_ABILITY_PERIODIC_CRIT );
for ( Unit :: AuraEffectList :: const_iterator itr = mPeriodicCritAuras . begin (); itr != mPeriodicCritAuras . end (); ++ itr )
{
2011-07-26 23:09:28 +02:00
if (( * itr ) -> IsAffectedOnSpell ( m_spellInfo ) && caster -> isSpellCrit ( target , m_spellInfo , m_spellInfo -> GetSchoolMask ()))
2010-01-10 01:23:15 +01:00
return true ;
}
2010-05-18 23:48:26 +02:00
// Rupture - since 3.3.3 can crit
2010-08-30 15:25:15 +02:00
if ( target -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_ROGUE , 0x100000 , 0x0 , 0x0 , caster -> GetGUID ()))
2010-05-18 23:48:26 +02:00
{
2011-07-26 23:09:28 +02:00
if ( caster -> isSpellCrit ( target , m_spellInfo , m_spellInfo -> GetSchoolMask ()))
2010-05-18 23:48:26 +02:00
return true ;
}
2010-01-10 01:23:15 +01:00
return false ;
}
2011-07-26 23:09:28 +02:00
bool AuraEffect :: IsAffectedOnSpell ( SpellInfo const * spell ) const
2011-07-10 13:13:02 +02:00
{
if ( ! spell )
return false ;
// Check family name
2011-07-26 23:09:28 +02:00
if ( spell -> SpellFamilyName != m_spellInfo -> SpellFamilyName )
2011-07-10 13:13:02 +02:00
return false ;
// Check EffectClassMask
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> Effects [ m_effIndex ]. SpellClassMask & spell -> SpellFamilyFlags )
2011-07-10 13:13:02 +02:00
return true ;
return false ;
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: SendTickImmune ( Unit * target , Unit * caster ) const
2010-01-24 15:20:32 +01:00
{
2010-08-29 03:38:21 +02:00
if ( caster )
2011-07-26 23:09:28 +02:00
caster -> SendSpellDamageImmune ( target , m_spellInfo -> Id );
2010-01-24 15:20:32 +01:00
}
2011-06-11 22:35:29 +02:00
void AuraEffect :: PeriodicTick ( AuraApplication * aurApp , Unit * caster ) const
2010-01-10 01:23:15 +01:00
{
2010-12-19 00:01:22 +01:00
bool prevented = GetBase () -> CallScriptEffectPeriodicHandlers ( this , aurApp );
2010-08-24 00:10:49 +02:00
if ( prevented )
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-12-05 21:38:52 +01:00
2010-01-10 01:23:15 +01:00
switch ( GetAuraType ())
{
2011-06-19 13:13:41 +02:00
case SPELL_AURA_PERIODIC_DUMMY :
HandlePeriodicDummyAuraTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
HandlePeriodicTriggerSpellAuraTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE :
HandlePeriodicTriggerSpellWithValueAuraTick ( target , caster );
break ;
2010-01-10 01:23:15 +01:00
case SPELL_AURA_PERIODIC_DAMAGE :
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT :
2011-06-19 13:13:41 +02:00
HandlePeriodicDamageAurasTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_LEECH :
HandlePeriodicHealthLeechAuraTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL :
HandlePeriodicHealthFunnelAuraTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_HEAL :
case SPELL_AURA_OBS_MOD_HEALTH :
HandlePeriodicHealAurasTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_MANA_LEECH :
HandlePeriodicManaLeechAuraTick ( target , caster );
break ;
case SPELL_AURA_OBS_MOD_POWER :
HandleObsModPowerAuraTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_ENERGIZE :
HandlePeriodicEnergizeAuraTick ( target , caster );
break ;
case SPELL_AURA_POWER_BURN_MANA :
HandlePeriodicPowerBurnManaAuraTick ( target , caster );
break ;
case SPELL_AURA_DUMMY :
// Haunting Spirits
if ( GetId () == 7057 )
target -> CastSpell (( Unit * ) NULL , GetAmount (), true );
break ;
default :
break ;
}
}
2011-07-10 13:13:02 +02:00
void AuraEffect :: HandleProc ( AuraApplication * aurApp , ProcEventInfo & eventInfo )
2011-06-19 13:13:41 +02:00
{
2011-07-10 13:13:02 +02:00
// TODO: effect script handlers here
switch ( GetAuraType ())
{
case SPELL_AURA_PROC_TRIGGER_SPELL :
HandleProcTriggerSpellAuraProc ( aurApp , eventInfo );
break ;
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE :
HandleProcTriggerSpellWithValueAuraProc ( aurApp , eventInfo );
break ;
case SPELL_AURA_PROC_TRIGGER_DAMAGE :
HandleProcTriggerDamageAuraProc ( aurApp , eventInfo );
break ;
case SPELL_AURA_RAID_PROC_FROM_CHARGE :
HandleRaidProcFromChargeAuraProc ( aurApp , eventInfo );
break ;
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE :
HandleRaidProcFromChargeWithValueAuraProc ( aurApp , eventInfo );
break ;
default :
break ;
}
2011-06-19 13:13:41 +02:00
}
void AuraEffect :: CleanupTriggeredSpells ( Unit * target )
{
2011-07-26 23:09:28 +02:00
uint32 tSpellId = m_spellInfo -> Effects [ GetEffIndex ()]. TriggerSpell ;
2011-06-19 13:13:41 +02:00
if ( ! tSpellId )
return ;
2011-07-26 23:09:28 +02:00
SpellInfo const * tProto = sSpellMgr -> GetSpellInfo ( tSpellId );
2011-06-19 13:13:41 +02:00
if ( ! tProto )
return ;
2011-07-26 23:09:28 +02:00
if ( tProto -> GetDuration () != - 1 )
2011-06-19 13:13:41 +02:00
return ;
// needed for spell 43680, maybe others
// TODO: is there a spell flag, which can solve this in a more sophisticated way?
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> Effects [ GetEffIndex ()]. ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
uint32 ( m_spellInfo -> GetDuration ()) == m_spellInfo -> Effects [ GetEffIndex ()]. Amplitude )
2011-06-19 13:13:41 +02:00
return ;
target -> RemoveAurasDueToSpell ( tSpellId , GetCasterGUID ());
}
void AuraEffect :: HandleShapeshiftBoosts ( Unit * target , bool apply ) const
{
uint32 spellId = 0 ;
uint32 spellId2 = 0 ;
//uint32 spellId3 = 0;
uint32 HotWSpellId = 0 ;
switch ( GetMiscValue ())
{
case FORM_CAT :
spellId = 3025 ;
HotWSpellId = 24900 ;
break ;
case FORM_TREE :
spellId = 34123 ;
break ;
case FORM_TRAVEL :
spellId = 5419 ;
break ;
case FORM_AQUA :
spellId = 5421 ;
break ;
case FORM_BEAR :
spellId = 1178 ;
spellId2 = 21178 ;
HotWSpellId = 24899 ;
break ;
case FORM_DIREBEAR :
spellId = 9635 ;
spellId2 = 21178 ;
HotWSpellId = 24899 ;
break ;
case FORM_BATTLESTANCE :
spellId = 21156 ;
break ;
case FORM_DEFENSIVESTANCE :
spellId = 7376 ;
break ;
case FORM_BERSERKERSTANCE :
spellId = 7381 ;
break ;
case FORM_MOONKIN :
spellId = 24905 ;
spellId2 = 69366 ;
break ;
case FORM_FLIGHT :
spellId = 33948 ;
spellId2 = 34764 ;
break ;
case FORM_FLIGHT_EPIC :
spellId = 40122 ;
spellId2 = 40121 ;
break ;
case FORM_METAMORPHOSIS :
spellId = 54817 ;
spellId2 = 54879 ;
break ;
case FORM_SPIRITOFREDEMPTION :
spellId = 27792 ;
spellId2 = 27795 ; // must be second, this important at aura remove to prevent to early iterator invalidation.
break ;
case FORM_SHADOW :
spellId = 49868 ;
spellId2 = 71167 ;
break ;
case FORM_GHOSTWOLF :
spellId = 67116 ;
break ;
case FORM_GHOUL :
case FORM_AMBIENT :
case FORM_STEALTH :
case FORM_CREATURECAT :
case FORM_CREATUREBEAR :
break ;
default :
break ;
}
if ( apply )
{
// Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
if ( spellId )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> RemoveSpellCooldown ( spellId );
target -> CastSpell ( target , spellId , true , NULL , this );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( spellId2 )
{
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> RemoveSpellCooldown ( spellId2 );
target -> CastSpell ( target , spellId2 , true , NULL , this );
}
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
const PlayerSpellMap & sp_list = target -> ToPlayer () -> GetSpellMap ();
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
2010-08-30 17:32:51 +02:00
{
2011-06-19 13:13:41 +02:00
if ( itr -> second -> state == PLAYERSPELL_REMOVED || itr -> second -> disabled ) continue ;
if ( itr -> first == spellId || itr -> first == spellId2 ) continue ;
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( itr -> first );
2011-06-19 13:13:41 +02:00
if ( ! spellInfo || ! ( spellInfo -> Attributes & ( SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE ))) continue ;
if ( spellInfo -> Stances & ( 1 << ( GetMiscValue () - 1 )))
target -> CastSpell ( target , itr -> first , true , NULL , this );
2010-08-30 17:32:51 +02:00
}
2011-06-19 13:13:41 +02:00
// Leader of the Pack
if ( target -> ToPlayer () -> HasSpell ( 17007 ))
2010-01-24 15:20:32 +01:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( 24932 );
2011-06-19 13:13:41 +02:00
if ( spellInfo && spellInfo -> Stances & ( 1 << ( GetMiscValue () - 1 )))
target -> CastSpell ( target , 24932 , true , NULL , this );
2010-01-24 15:20:32 +01:00
}
2011-06-19 13:13:41 +02:00
// Improved Barkskin - apply/remove armor bonus due to shapeshift
if ( target -> ToPlayer () -> HasSpell ( 63410 ) || target -> ToPlayer () -> HasSpell ( 63411 ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> RemoveAurasDueToSpell ( 66530 );
if ( GetMiscValue () == FORM_TRAVEL || GetMiscValue () == FORM_NONE ) // "while in Travel Form or while not shapeshifted"
target -> CastSpell ( target , 66530 , true );
}
// Heart of the Wild
if ( HotWSpellId )
{ // hacky, but the only way as spell family is not SPELLFAMILY_DRUID
Unit :: AuraEffectList const & mModTotalStatPct = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE );
for ( Unit :: AuraEffectList :: const_iterator i = mModTotalStatPct . begin (); i != mModTotalStatPct . end (); ++ i )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Heart of the Wild
2011-07-26 23:09:28 +02:00
if (( * i ) -> GetSpellInfo () -> SpellIconID == 240 && ( * i ) -> GetMiscValue () == 3 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
int32 HotWMod = ( * i ) -> GetAmount ();
target -> CastCustomSpell ( target , HotWSpellId , & HotWMod , NULL , NULL , true , NULL , this );
2010-01-10 01:23:15 +01:00
break ;
}
}
}
2011-06-19 13:13:41 +02:00
switch ( GetMiscValue ())
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
case FORM_CAT :
// Savage Roar
if ( target -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_DRUID , 0 , 0x10000000 , 0 ))
target -> CastSpell ( target , 62071 , true );
// Nurturing Instinct
if ( AuraEffect const * aurEff = target -> GetAuraEffect ( SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT , SPELLFAMILY_DRUID , 2254 , 0 ))
2010-03-21 16:03:38 +01:00
{
2011-06-19 13:13:41 +02:00
uint32 spellId = 0 ;
switch ( aurEff -> GetId ())
2010-03-21 16:03:38 +01:00
{
2011-06-19 13:13:41 +02:00
case 33872 :
spellId = 47179 ;
break ;
case 33873 :
spellId = 47180 ;
break ;
2010-03-21 16:03:38 +01:00
}
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , spellId , true , NULL , this );
2010-03-21 16:03:38 +01:00
}
2011-06-19 13:13:41 +02:00
// Master Shapeshifter - Cat
if ( AuraEffect const * aurEff = target -> GetDummyAuraEffect ( SPELLFAMILY_GENERIC , 2851 , 0 ))
2010-10-16 16:34:21 +02:00
{
2011-06-19 13:13:41 +02:00
int32 bp = aurEff -> GetAmount ();
target -> CastCustomSpell ( target , 48420 , & bp , NULL , NULL , true );
2010-10-16 16:34:21 +02:00
}
2011-06-19 13:13:41 +02:00
break ;
case FORM_DIREBEAR :
case FORM_BEAR :
// Master Shapeshifter - Bear
if ( AuraEffect const * aurEff = target -> GetDummyAuraEffect ( SPELLFAMILY_GENERIC , 2851 , 0 ))
{
int32 bp = aurEff -> GetAmount ();
target -> CastCustomSpell ( target , 48418 , & bp , NULL , NULL , true );
}
// Survival of the Fittest
if ( AuraEffect const * aurEff = target -> GetAuraEffect ( SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE , SPELLFAMILY_DRUID , 961 , 0 ))
{
2011-07-26 23:09:28 +02:00
int32 bp = 100 + aurEff -> GetSpellInfo () -> Effects [ EFFECT_2 ]. CalcValue ();
2011-06-19 13:13:41 +02:00
target -> CastCustomSpell ( target , 62069 , & bp , NULL , NULL , true , 0 , this );
}
break ;
case FORM_MOONKIN :
// Master Shapeshifter - Moonkin
if ( AuraEffect const * aurEff = target -> GetDummyAuraEffect ( SPELLFAMILY_GENERIC , 2851 , 0 ))
{
int32 bp = aurEff -> GetAmount ();
target -> CastCustomSpell ( target , 48421 , & bp , NULL , NULL , true );
}
break ;
// Master Shapeshifter - Tree of Life
case FORM_TREE :
if ( AuraEffect const * aurEff = target -> GetDummyAuraEffect ( SPELLFAMILY_GENERIC , 2851 , 0 ))
{
int32 bp = aurEff -> GetAmount ();
target -> CastCustomSpell ( target , 48422 , & bp , NULL , NULL , true );
}
break ;
2010-08-30 17:32:51 +02:00
}
2011-06-19 13:13:41 +02:00
}
}
else
{
if ( spellId )
target -> RemoveAurasDueToSpell ( spellId );
if ( spellId2 )
target -> RemoveAurasDueToSpell ( spellId2 );
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
// Improved Barkskin - apply/remove armor bonus due to shapeshift
2011-06-29 13:09:32 +02:00
if ( Player * pl = target -> ToPlayer ())
2011-06-19 13:13:41 +02:00
{
if ( pl -> HasSpell ( 63410 ) || pl -> HasSpell ( 63411 ))
2010-01-24 15:20:32 +01:00
{
2011-06-19 13:13:41 +02:00
target -> RemoveAurasDueToSpell ( 66530 );
target -> CastSpell ( target , 66530 , true );
2010-01-24 15:20:32 +01:00
}
2011-06-19 13:13:41 +02:00
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit :: AuraApplicationMap & tAuras = target -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator itr = tAuras . begin (); itr != tAuras . end ();)
{
if ( itr -> second -> GetBase () -> IsRemovedOnShapeLost ( target ))
target -> RemoveAura ( itr );
else
++ itr ;
}
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/*********************************************************/
/*** AURA EFFECT HANDLERS ***/
/*********************************************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/**************************************/
/*** VISIBILITY & PHASES ***/
/**************************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModInvisibilityDetect ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
InvisibilityType type = InvisibilityType ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> m_invisibilityDetect . AddFlag ( type );
target -> m_invisibilityDetect . AddValue ( type , GetAmount ());
}
else
{
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_INVISIBILITY_DETECT ))
target -> m_invisibilityDetect . DelFlag ( type );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> m_invisibilityDetect . AddValue ( type , - GetAmount ());
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
target -> UpdateObjectVisibility ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModInvisibility ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
InvisibilityType type = InvisibilityType ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
// apply glow vision
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> SetByteFlag ( PLAYER_FIELD_BYTES2 , 3 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> m_invisibility . AddFlag ( type );
target -> m_invisibility . AddValue ( type , GetAmount ());
}
else
{
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_INVISIBILITY ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// if not have different invisibility auras.
// remove glow vision
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> RemoveByteFlag ( PLAYER_FIELD_BYTES2 , 3 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> m_invisibility . DelFlag ( type );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
else
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
bool found = false ;
Unit :: AuraEffectList const & invisAuras = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_INVISIBILITY );
for ( Unit :: AuraEffectList :: const_iterator i = invisAuras . begin (); i != invisAuras . end (); ++ i )
2010-08-30 17:32:51 +02:00
{
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () == ( * i ) -> GetMiscValue ())
{
found = true ;
break ;
}
2010-08-30 17:32:51 +02:00
}
2011-06-19 13:13:41 +02:00
if ( ! found )
target -> m_invisibility . DelFlag ( type );
}
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
target -> m_invisibility . AddValue ( type , - GetAmount ());
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
if ( apply && ( mode & AURA_EFFECT_HANDLE_REAL ))
{
// drop flag at invisibiliy in bg
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
target -> UpdateObjectVisibility ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModStealthDetect ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
StealthType type = StealthType ( GetMiscValue ());
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> m_stealthDetect . AddFlag ( type );
target -> m_stealthDetect . AddValue ( type , GetAmount ());
}
else
{
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH_DETECT ))
target -> m_stealthDetect . DelFlag ( type );
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
target -> m_stealthDetect . AddValue ( type , - GetAmount ());
}
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
target -> UpdateObjectVisibility ();
}
2010-08-08 19:45:53 +02:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModStealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
return ;
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
StealthType type = StealthType ( GetMiscValue ());
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> m_stealth . AddFlag ( type );
target -> m_stealth . AddValue ( type , GetAmount ());
2010-07-04 19:28:40 +02:00
2011-06-19 13:13:41 +02:00
target -> SetStandFlags ( UNIT_STAND_FLAGS_CREEP );
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> SetByteFlag ( PLAYER_FIELD_BYTES2 , 3 , PLAYER_FIELD_BYTE2_STEALTH );
}
else
{
target -> m_stealth . AddValue ( type , - GetAmount ());
2011-05-13 22:48:57 +07:00
2011-06-19 13:13:41 +02:00
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH )) // if last SPELL_AURA_MOD_STEALTH
{
target -> m_stealth . DelFlag ( type );
2011-05-13 22:48:57 +07:00
2011-06-19 13:13:41 +02:00
target -> RemoveStandFlags ( UNIT_STAND_FLAGS_CREEP );
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> RemoveByteFlag ( PLAYER_FIELD_BYTES2 , 3 , PLAYER_FIELD_BYTE2_STEALTH );
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
if ( apply && ( mode & AURA_EFFECT_HANDLE_REAL ))
{
// drop flag at stealth in bg
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
target -> UpdateObjectVisibility ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModStealthLevel ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
StealthType type = StealthType ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
target -> m_stealth . AddValue ( type , GetAmount ());
else
target -> m_stealth . AddValue ( type , - GetAmount ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
target -> UpdateObjectVisibility ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleSpiritOfRedemption ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// prepare spirit state
if ( apply )
{
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// disable breath/etc timers
target -> ToPlayer () -> StopMirrorTimers ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// set stand state (expected in this form)
if ( ! target -> IsStandState ())
target -> SetStandState ( UNIT_STAND_STATE_STAND );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> SetHealth ( 1 );
}
// die at aura end
else if ( target -> isAlive ())
// call functions which may have additional effects after chainging state of unit
target -> setDeathState ( JUST_DIED );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraGhost ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> SetFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
target -> m_serverSideVisibility . SetValue ( SERVERSIDE_VISIBILITY_GHOST , GHOST_VISIBILITY_GHOST );
target -> m_serverSideVisibilityDetect . SetValue ( SERVERSIDE_VISIBILITY_GHOST , GHOST_VISIBILITY_GHOST );
}
else
{
if ( target -> HasAuraType ( SPELL_AURA_GHOST ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
target -> m_serverSideVisibility . SetValue ( SERVERSIDE_VISIBILITY_GHOST , GHOST_VISIBILITY_ALIVE );
target -> m_serverSideVisibilityDetect . SetValue ( SERVERSIDE_VISIBILITY_GHOST , GHOST_VISIBILITY_ALIVE );
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePhase ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// no-phase is also phase state so same code for apply and remove
uint32 newPhase = 0 ;
Unit :: AuraEffectList const & phases = target -> GetAuraEffectsByType ( SPELL_AURA_PHASE );
if ( ! phases . empty ())
for ( Unit :: AuraEffectList :: const_iterator itr = phases . begin (); itr != phases . end (); ++ itr )
newPhase |= ( * itr ) -> GetMiscValue ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( Player * player = target -> ToPlayer ())
{
if ( ! newPhase )
newPhase = PHASEMASK_NORMAL ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// GM-mode have mask 0xFFFFFFFF
if ( player -> isGameMaster ())
newPhase = 0xFFFFFFFF ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
player -> SetPhaseMask ( newPhase , false );
player -> GetSession () -> SendSetPhaseShift ( newPhase );
}
else
{
if ( ! newPhase )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
newPhase = PHASEMASK_NORMAL ;
if ( Creature * creature = target -> ToCreature ())
if ( CreatureData const * data = sObjectMgr -> GetCreatureData ( creature -> GetDBTableGUIDLow ()))
newPhase = data -> phaseMask ;
}
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
target -> SetPhaseMask ( newPhase , false );
}
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
// call functions which may have additional effects after chainging state of unit
// phase auras normally not expected at BG but anyway better check
if ( apply && ( mode & AURA_EFFECT_HANDLE_REAL ))
{
// drop flag at invisibiliy in bg
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
if ( target -> IsVisible ())
target -> UpdateObjectVisibility ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/**********************/
/*** UNIT MODEL ***/
/**********************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModShapeshift ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 modelid = 0 ;
Powers PowerType = POWER_MANA ;
ShapeshiftForm form = ShapeshiftForm ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
switch ( form )
{
case FORM_CAT : // 0x01
case FORM_GHOUL : // 0x07
PowerType = POWER_ENERGY ;
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
case FORM_BEAR : // 0x05
case FORM_DIREBEAR : // 0x08
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
case FORM_BATTLESTANCE : // 0x11
case FORM_DEFENSIVESTANCE : // 0x12
case FORM_BERSERKERSTANCE : // 0x13
PowerType = POWER_RAGE ;
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
case FORM_TREE : // 0x02
case FORM_TRAVEL : // 0x03
case FORM_AQUA : // 0x04
case FORM_AMBIENT : // 0x06
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
case FORM_STEVES_GHOUL : // 0x09
case FORM_THARONJA_SKELETON : // 0x0A
case FORM_TEST_OF_STRENGTH : // 0x0B
case FORM_BLB_PLAYER : // 0x0C
case FORM_SHADOW_DANCE : // 0x0D
case FORM_CREATUREBEAR : // 0x0E
case FORM_CREATURECAT : // 0x0F
case FORM_GHOSTWOLF : // 0x10
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
case FORM_TEST : // 0x14
case FORM_ZOMBIE : // 0x15
case FORM_METAMORPHOSIS : // 0x16
case FORM_UNDEAD : // 0x19
case FORM_MASTER_ANGLER : // 0x1A
case FORM_FLIGHT_EPIC : // 0x1B
case FORM_SHADOW : // 0x1C
case FORM_FLIGHT : // 0x1D
case FORM_STEALTH : // 0x1E
case FORM_MOONKIN : // 0x1F
case FORM_SPIRITOFREDEMPTION : // 0x20
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
default :
sLog -> outError ( "Auras: Unknown Shapeshift Type: %u" , GetMiscValue ());
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
modelid = target -> GetModelForForm ( form );
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
// remove polymorph before changing display id to keep new display id
switch ( form )
{
case FORM_CAT :
case FORM_TREE :
case FORM_TRAVEL :
case FORM_AQUA :
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_FLIGHT_EPIC :
case FORM_FLIGHT :
case FORM_MOONKIN :
2010-08-30 17:32:51 +02:00
{
2011-06-19 13:13:41 +02:00
// remove movement affects
target -> RemoveMovementImpairingAuras ();
2010-08-30 17:32:51 +02:00
2011-06-19 13:13:41 +02:00
// and polymorphic affects
if ( target -> IsPolymorphed ())
target -> RemoveAurasDueToSpell ( target -> getTransForm ());
break ;
2010-01-24 15:20:32 +01:00
}
2011-06-19 13:13:41 +02:00
default :
break ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// remove other shapeshift before applying a new one
target -> RemoveAurasByType ( SPELL_AURA_MOD_SHAPESHIFT , 0 , GetBase ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// stop handling the effect if it was removed by linked event
if ( aurApp -> GetRemoveMode ())
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( modelid > 0 )
target -> SetDisplayId ( modelid );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( PowerType != POWER_MANA )
{
uint32 oldPower = target -> GetPower ( PowerType );
// reset power to default values only at power change
if ( target -> getPowerType () != PowerType )
target -> setPowerType ( PowerType );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
switch ( form )
{
case FORM_CAT :
case FORM_BEAR :
case FORM_DIREBEAR :
{
// get furor proc chance
uint32 FurorChance = 0 ;
2011-07-15 07:12:54 +07:00
if ( AuraEffect const * dummy = target -> GetDummyAuraEffect ( SPELLFAMILY_DRUID , 238 , 0 ))
2011-06-19 13:13:41 +02:00
FurorChance = std :: max ( dummy -> GetAmount (), 0 );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
switch ( GetMiscValue ())
{
case FORM_CAT :
{
int32 basePoints = int32 ( std :: min ( oldPower , FurorChance ));
target -> SetPower ( POWER_ENERGY , 0 );
target -> CastCustomSpell ( target , 17099 , & basePoints , NULL , NULL , true , NULL , this );
}
break ;
case FORM_BEAR :
case FORM_DIREBEAR :
if ( urand ( 0 , 99 ) < FurorChance )
target -> CastSpell ( target , 17057 , true );
default :
{
uint32 newEnergy = std :: min ( target -> GetPower ( POWER_ENERGY ), FurorChance );
target -> SetPower ( POWER_ENERGY , newEnergy );
}
break ;
}
break ;
}
default :
break ;
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// stop handling the effect if it was removed by linked event
if ( aurApp -> GetRemoveMode ())
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> SetShapeshiftForm ( form );
}
else
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// reset model id if no other auras present
// may happen when aura is applied on linked event on aura removal
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_SHAPESHIFT ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> SetShapeshiftForm ( FORM_NONE );
if ( target -> getClass () == CLASS_DRUID )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> setPowerType ( POWER_MANA );
// Remove movement impairing effects also when shifting out
target -> RemoveMovementImpairingAuras ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
2011-01-06 20:25:51 +01:00
2011-06-19 13:13:41 +02:00
if ( modelid > 0 )
target -> RestoreDisplayId ();
2011-01-06 20:25:51 +01:00
2011-06-19 13:13:41 +02:00
switch ( form )
{
// Nordrassil Harness - bonus
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_CAT :
if ( AuraEffect * dummy = target -> GetAuraEffect ( 37315 , 0 ))
target -> CastSpell ( target , 37316 , true , NULL , dummy );
2011-01-06 20:25:51 +01:00
break ;
2011-06-19 13:13:41 +02:00
// Nordrassil Regalia - bonus
case FORM_MOONKIN :
if ( AuraEffect * dummy = target -> GetAuraEffect ( 37324 , 0 ))
target -> CastSpell ( target , 37325 , true , NULL , dummy );
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
case FORM_BATTLESTANCE :
case FORM_DEFENSIVESTANCE :
case FORM_BERSERKERSTANCE :
{
uint32 Rage_val = 0 ;
// Defensive Tactics
if ( form == FORM_DEFENSIVESTANCE )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
if ( AuraEffect const * aurEff = target -> IsScriptOverriden ( m_spellInfo , 831 ))
2011-06-19 13:13:41 +02:00
Rage_val += aurEff -> GetAmount () * 10 ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
PlayerSpellMap const & sp_list = target -> ToPlayer () -> GetSpellMap ();
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( itr -> second -> state == PLAYERSPELL_REMOVED || itr -> second -> disabled ) continue ;
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( itr -> first );
2011-06-19 13:13:41 +02:00
if ( spellInfo && spellInfo -> SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo -> SpellIconID == 139 )
Rage_val += target -> CalculateSpellDamage ( target , spellInfo , 0 ) * 10 ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
if ( target -> GetPower ( POWER_RAGE ) > Rage_val )
target -> SetPower ( POWER_RAGE , Rage_val );
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
// adding/removing linked auras
// add/remove the shapeshift aura's boosts
HandleShapeshiftBoosts ( target , apply );
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> InitDataForForm ();
if ( target -> getClass () == CLASS_DRUID )
{
// Dash
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = target -> GetAuraEffect ( SPELL_AURA_MOD_INCREASE_SPEED , SPELLFAMILY_DRUID , 0 , 0 , 0x8 ))
2011-06-19 13:13:41 +02:00
aurEff -> RecalculateAmount ();
// Disarm handling
// If druid shifts while being disarmed we need to deal with that since forms aren't affected by disarm
// and also HandleAuraModDisarm is not triggered
if ( ! target -> CanUseAttackType ( BASE_ATTACK ))
2010-01-10 01:23:15 +01:00
{
2011-07-15 07:12:54 +07:00
if ( Item * pItem = target -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_MAINHAND ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> _ApplyWeaponDamage ( EQUIPMENT_SLOT_MAINHAND , pItem -> GetTemplate (), NULL , apply );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// stop handling the effect if it was removed by linked event
if ( apply && aurApp -> GetRemoveMode ())
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
2011-06-29 13:09:32 +02:00
SpellShapeshiftEntry const * shapeInfo = sSpellShapeshiftStore . LookupEntry ( form );
2011-06-19 13:13:41 +02:00
// Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
for ( uint8 i = 0 ; i < MAX_SHAPESHIFT_SPELLS ; ++ i )
{
if ( ! shapeInfo -> stanceSpell [ i ])
continue ;
if ( apply )
target -> ToPlayer () -> AddTemporarySpell ( shapeInfo -> stanceSpell [ i ]);
else
target -> ToPlayer () -> RemoveTemporarySpell ( shapeInfo -> stanceSpell [ i ]);
}
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraTransform ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
// update active transform spell only when transform or shapeshift not set or not overwriting negative by positive case
2011-07-26 23:09:28 +02:00
if ( ! target -> GetModelForForm ( target -> GetShapeshiftForm ()) || ! GetSpellInfo () -> IsPositive ())
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// special case (spell specific functionality)
if ( GetMiscValue () == 0 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
switch ( GetId ())
{
// Orb of Deception
case 16739 :
{
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
switch ( target -> getRace ())
{
// Blood Elf
case RACE_BLOODELF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 17829 : 17830 );
break ;
// Orc
case RACE_ORC :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10139 : 10140 );
break ;
// Troll
case RACE_TROLL :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10135 : 10134 );
break ;
// Tauren
case RACE_TAUREN :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10136 : 10147 );
break ;
// Undead
case RACE_UNDEAD_PLAYER :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10146 : 10145 );
break ;
// Draenei
case RACE_DRAENEI :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 17827 : 17828 );
break ;
// Dwarf
case RACE_DWARF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10141 : 10142 );
break ;
// Gnome
case RACE_GNOME :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10148 : 10149 );
break ;
// Human
case RACE_HUMAN :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10137 : 10138 );
break ;
// Night Elf
case RACE_NIGHTELF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 10143 : 10144 );
break ;
default :
break ;
}
break ;
}
// Murloc costume
case 42365 :
target -> SetDisplayId ( 21723 );
break ;
// Dread Corsair
case 50517 :
// Corsair Costume
case 51926 :
{
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
switch ( target -> getRace ())
{
// Blood Elf
case RACE_BLOODELF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25032 : 25043 );
break ;
// Orc
case RACE_ORC :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25039 : 25050 );
break ;
// Troll
case RACE_TROLL :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25041 : 25052 );
break ;
// Tauren
case RACE_TAUREN :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25040 : 25051 );
break ;
// Undead
case RACE_UNDEAD_PLAYER :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25042 : 25053 );
break ;
// Draenei
case RACE_DRAENEI :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25033 : 25044 );
break ;
// Dwarf
case RACE_DWARF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25034 : 25045 );
break ;
// Gnome
case RACE_GNOME :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25035 : 25046 );
break ;
// Human
case RACE_HUMAN :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25037 : 25048 );
break ;
// Night Elf
case RACE_NIGHTELF :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 25038 : 25049 );
break ;
default :
break ;
}
break ;
}
// Pygmy Oil
case 53806 :
target -> SetDisplayId ( 22512 );
break ;
// Honor the Dead
case 65386 :
case 65495 :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 29203 : 29204 );
break ;
// Darkspear Pride
case 75532 :
target -> SetDisplayId ( target -> getGender () == GENDER_MALE ? 31737 : 31738 );
break ;
default :
break ;
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
else
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
CreatureTemplate const * ci = sObjectMgr -> GetCreatureTemplate ( GetMiscValue ());
if ( ! ci )
{
target -> SetDisplayId ( 16358 ); // pig pink ^_^
sLog -> outError ( "Auras: unknown creature id = %d (only need its modelid) From Spell Aura Transform in Spell ID = %d" , GetMiscValue (), GetId ());
}
else
{
uint32 model_id = 0 ;
if ( uint32 modelid = ci -> GetRandomValidModelId ())
model_id = modelid ; // Will use the default model here
// Polymorph (sheep)
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_MAGE && GetSpellInfo () -> SpellIconID == 82 && GetSpellInfo () -> SpellVisual [ 0 ] == 12978 )
2011-06-19 13:13:41 +02:00
if ( Unit * caster = GetCaster ())
if ( caster -> HasAura ( 52648 )) // Glyph of the Penguin
model_id = 26452 ;
target -> SetDisplayId ( model_id );
// Dragonmaw Illusion (set mount model also)
if ( GetId () == 42016 && target -> GetMountID () && ! target -> GetAuraEffectsByType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ). empty ())
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
// update active transform spell only when transform or shapeshift not set or not overwriting negative by positive case
2011-07-26 23:09:28 +02:00
SpellInfo const * transformSpellInfo = sSpellMgr -> GetSpellInfo ( target -> getTransForm ());
if ( ! transformSpellInfo || ! GetSpellInfo () -> IsPositive () || transformSpellInfo -> IsPositive ())
2011-06-19 13:13:41 +02:00
target -> setTransForm ( GetId ());
// polymorph case
if (( mode & AURA_EFFECT_HANDLE_REAL ) && target -> GetTypeId () == TYPEID_PLAYER && target -> IsPolymorphed ())
{
// for players, start regeneration after 1s (in polymorph fast regeneration case)
// only if caster is Player (after patch 2.4.2)
if ( IS_PLAYER_GUID ( GetCasterGUID ()))
target -> ToPlayer () -> setRegenTimerCount ( 1 * IN_MILLISECONDS );
//dismount polymorphed target (after patch 2.4.2)
if ( target -> IsMounted ())
target -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
}
}
else
{
// HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true) will reapply it if need
if ( target -> getTransForm () == GetId ())
target -> setTransForm ( 0 );
target -> RestoreDisplayId ();
// Dragonmaw Illusion (restore mount model)
if ( GetId () == 42016 && target -> GetMountID () == 16314 )
{
if ( ! target -> GetAuraEffectsByType ( SPELL_AURA_MOUNTED ). empty ())
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
uint32 cr_id = target -> GetAuraEffectsByType ( SPELL_AURA_MOUNTED ). front () -> GetMiscValue ();
if ( CreatureTemplate const * ci = sObjectMgr -> GetCreatureTemplate ( cr_id ))
{
uint32 team = 0 ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
team = target -> ToPlayer () -> GetTeam ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 displayID = sObjectMgr -> ChooseDisplayId ( team , ci );
sObjectMgr -> GetCreatureModelRandomGender ( & displayID );
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , displayID );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModScale ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-02-04 18:34:46 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-02-04 18:34:46 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplyPercentModFloatValue ( OBJECT_FIELD_SCALE_X , ( float ) GetAmount (), apply );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraCloneCaster ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
Unit * caster = GetCaster ();
if ( ! caster || caster == target )
return ;
2011-07-31 16:43:54 +02:00
2011-06-19 13:13:41 +02:00
// What must be cloned? at least display and scale
target -> SetDisplayId ( caster -> GetDisplayId ());
//target->SetFloatValue(OBJECT_FIELD_SCALE_X, caster->GetFloatValue(OBJECT_FIELD_SCALE_X)); // we need retail info about how scaling is handled (aura maybe?)
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_MIRROR_IMAGE );
}
else
{
target -> SetDisplayId ( target -> GetNativeDisplayId ());
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_MIRROR_IMAGE );
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/************************/
/*** FIGHT ***/
/************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleFeignDeath ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<target->GetGUID();
data<<uint8(0);
target->SendMessageToSet(&data, true);
*/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
UnitList targets ;
Trinity :: AnyUnfriendlyUnitInObjectRangeCheck u_check ( target , target , target -> GetMap () -> GetVisibilityRange ());
Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyUnitInObjectRangeCheck > searcher ( target , targets , u_check );
target -> VisitNearbyObject ( target -> GetMap () -> GetVisibilityRange (), searcher );
for ( UnitList :: iterator iter = targets . begin (); iter != targets . end (); ++ iter )
{
if ( ! ( * iter ) -> HasUnitState ( UNIT_STAT_CASTING ))
continue ;
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; i ++ )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if (( * iter ) -> GetCurrentSpell ( i )
2011-07-28 23:44:39 +02:00
&& ( * iter ) -> GetCurrentSpell ( i ) -> m_targets . GetUnitTargetGUID () == target -> GetGUID ())
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
( * iter ) -> InterruptSpell ( CurrentSpellTypes ( i ), false );
2010-01-10 01:23:15 +01:00
}
}
}
2011-06-19 13:13:41 +02:00
target -> CombatStop ();
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
// prevent interrupt message
if ( GetCasterGUID () == target -> GetGUID () && target -> GetCurrentSpell ( CURRENT_GENERIC_SPELL ))
target -> FinishSpell ( CURRENT_GENERIC_SPELL , false );
target -> InterruptNonMeleeSpells ( true );
target -> getHostileRefManager (). deleteReferences ();
// stop handling the effect if it was removed by linked event
if ( aurApp -> GetRemoveMode ())
return ;
// blizz like 2.0.x
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_UNK_29 );
// blizz like 2.0.x
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FEIGN_DEATH );
// blizz like 2.0.x
target -> SetFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_DEAD );
target -> AddUnitState ( UNIT_STAT_DIED );
2010-01-10 01:23:15 +01:00
}
else
{
2011-06-19 13:13:41 +02:00
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<target->GetGUID();
data<<uint8(1);
target->SendMessageToSet(&data, true);
*/
// blizz like 2.0.x
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_UNK_29 );
// blizz like 2.0.x
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FEIGN_DEATH );
// blizz like 2.0.x
target -> RemoveFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_DEAD );
target -> ClearUnitState ( UNIT_STAT_DIED );
}
}
void AuraEffect :: HandleModUnattackable ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( ! apply && target -> HasAuraType ( SPELL_AURA_MOD_UNATTACKABLE ))
return ;
target -> ApplyModFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE , apply );
// call functions which may have additional effects after chainging state of unit
if ( apply && ( mode & AURA_EFFECT_HANDLE_REAL ))
{
target -> CombatStop ();
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
}
void AuraEffect :: HandleAuraModDisarm ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
AuraType type = GetAuraType ();
//Prevent handling aura twice
if (( apply ) ? target -> GetAuraEffectsByType ( type ). size () > 1 : target -> HasAuraType ( type ))
return ;
uint32 field , flag , slot ;
WeaponAttackType attType ;
switch ( type )
{
case SPELL_AURA_MOD_DISARM :
field = UNIT_FIELD_FLAGS ;
flag = UNIT_FLAG_DISARMED ;
slot = EQUIPMENT_SLOT_MAINHAND ;
attType = BASE_ATTACK ;
break ;
case SPELL_AURA_MOD_DISARM_OFFHAND :
field = UNIT_FIELD_FLAGS_2 ;
flag = UNIT_FLAG2_DISARM_OFFHAND ;
slot = EQUIPMENT_SLOT_OFFHAND ;
attType = OFF_ATTACK ;
break ;
case SPELL_AURA_MOD_DISARM_RANGED :
field = UNIT_FIELD_FLAGS_2 ;
flag = UNIT_FLAG2_DISARM_RANGED ;
slot = EQUIPMENT_SLOT_RANGED ;
attType = RANGED_ATTACK ;
break ;
default :
return ;
}
if ( ! apply )
target -> RemoveFlag ( field , flag );
if ( apply )
target -> SetFlag ( field , flag );
2011-06-29 13:09:32 +02:00
// Handle damage modification, shapeshifted druids are not affected
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER && ! target -> IsInFeralForm ())
{
2011-07-15 07:12:54 +07:00
if ( Item * pItem = target -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot ))
2011-06-19 13:13:41 +02:00
{
uint8 attacktype = Player :: GetAttackBySlot ( slot );
if ( attacktype < MAX_ATTACK )
target -> ToPlayer () -> _ApplyWeaponDamage ( slot , pItem -> GetTemplate (), NULL , ! apply );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_UNIT && target -> ToCreature () -> GetCurrentEquipmentId ())
target -> UpdateDamagePhysical ( attType );
}
void AuraEffect :: HandleAuraModSilence ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
2010-08-22 05:55:54 -03:00
2011-06-19 13:13:41 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SILENCED );
// call functions which may have additional effects after chainging state of unit
// Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
for ( uint32 i = CURRENT_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; ++ i )
if ( Spell * spell = target -> GetCurrentSpell ( CurrentSpellTypes ( i )))
if ( spell -> m_spellInfo -> PreventionType == SPELL_PREVENTION_TYPE_SILENCE )
// Stop spells on prepare or casting state
target -> InterruptSpell ( CurrentSpellTypes ( i ), false );
2010-01-10 01:23:15 +01:00
}
2010-12-18 22:04:19 +01:00
else
2010-11-17 23:24:21 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( SPELL_AURA_MOD_SILENCE ) || target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SILENCED );
2010-11-17 23:24:21 +01:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModPacify ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
else
2010-02-04 18:34:46 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( SPELL_AURA_MOD_PACIFY ) || target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
}
}
void AuraEffect :: HandleAuraModPacifyAndSilence ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
2010-02-04 18:34:46 +01:00
2011-06-19 13:13:41 +02:00
// Vengeance of the Blue Flight (TODO: REMOVE THIS!)
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> Id == 45839 )
2011-06-19 13:13:41 +02:00
{
if ( apply )
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
else
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
2010-02-04 18:34:46 +01:00
}
2011-06-19 13:13:41 +02:00
if ( ! ( apply ))
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
return ;
}
HandleAuraModPacify ( aurApp , mode , apply );
HandleAuraModSilence ( aurApp , mode , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraAllowOnlyAbility ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
target -> SetFlag ( PLAYER_FLAGS , PLAYER_ALLOW_ONLY_ABILITY );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( SPELL_AURA_ALLOW_ONLY_ABILITY ))
return ;
target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_ALLOW_ONLY_ABILITY );
}
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/****************************/
/*** TRACKING ***/
/****************************/
void AuraEffect :: HandleAuraTrackCreatures ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
target -> SetUInt32Value ( PLAYER_TRACK_CREATURES , ( apply ) ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
}
void AuraEffect :: HandleAuraTrackResources ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
target -> SetUInt32Value ( PLAYER_TRACK_RESOURCES , ( apply ) ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraTrackStealthed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
target -> ApplyModFlag ( PLAYER_FIELD_BYTES , PLAYER_FIELD_BYTE_TRACK_STEALTHED , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModStalked ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
2010-04-07 19:14:10 +02:00
if ( apply )
2011-06-19 13:13:41 +02:00
target -> SetFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
2010-01-10 01:23:15 +01:00
else
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( ! target -> HasAuraType ( GetAuraType ()))
target -> RemoveFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
2010-01-10 01:23:15 +01:00
}
2010-11-13 17:18:09 +01:00
2011-05-25 15:13:55 +02:00
// call functions which may have additional effects after chainging state of unit
2010-11-13 17:18:09 +01:00
target -> UpdateObjectVisibility ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraUntrackable ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( apply )
2011-06-19 13:13:41 +02:00
target -> SetByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
2010-11-13 17:18:09 +01:00
else
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
target -> RemoveByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
2011-05-25 15:13:55 +02:00
}
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
/****************************/
/*** SKILLS & TALENTS ***/
/****************************/
void AuraEffect :: HandleAuraModPetTalentsPoints ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-11-13 17:18:09 +01:00
{
2011-06-08 09:19:34 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-11-13 17:18:09 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate pet talent points
2011-07-15 07:12:54 +07:00
if ( Pet * pet = target -> ToPlayer () -> GetPet ())
2011-06-19 13:13:41 +02:00
pet -> InitTalentForLevel ();
}
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModSkill ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SKILL )))
return ;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
uint32 prot = GetMiscValue ();
int32 points = GetAmount ();
target -> ToPlayer () -> ModifySkillBonus ( prot , (( apply ) ? points : - points ), GetAuraType () == SPELL_AURA_MOD_SKILL_TALENT );
if ( prot == SKILL_DEFENSE )
target -> ToPlayer () -> UpdateDefenseBonusesMod ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/****************************/
/*** MOVEMENT ***/
/****************************/
void AuraEffect :: HandleAuraMounted ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
uint32 creatureEntry = GetMiscValue ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Festive Holiday Mount
if ( target -> HasAura ( 62061 ))
2010-11-13 17:18:09 +01:00
{
2011-06-19 13:13:41 +02:00
if ( GetBase () -> HasEffectType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ))
creatureEntry = 24906 ;
else
creatureEntry = 15665 ;
}
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
CreatureTemplate const * ci = sObjectMgr -> GetCreatureTemplate ( creatureEntry );
if ( ! ci )
{
sLog -> outErrorDb ( "AuraMounted: `creature_template`='%u' not found in database (only need its modelid)" , GetMiscValue ());
return ;
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
uint32 team = 0 ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
team = target -> ToPlayer () -> GetTeam ();
uint32 displayID = sObjectMgr -> ChooseDisplayId ( team , ci );
sObjectMgr -> GetCreatureModelRandomGender ( & displayID );
//some spell has one aura of mount and one of vehicle
for ( uint32 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ i ]. Effect == SPELL_EFFECT_SUMMON
&& GetSpellInfo () -> Effects [ i ]. MiscValue == GetMiscValue ())
2011-06-19 13:13:41 +02:00
displayID = 0 ;
target -> Mount ( displayID , ci -> VehicleId , GetMiscValue ());
}
else
2011-05-25 15:13:55 +02:00
{
2011-06-19 13:13:41 +02:00
target -> Unmount ();
//some mounts like Headless Horseman's Mount or broom stick are skill based spell
// need to remove ALL arura related to mounts, this will stop client crash with broom stick
// and never endless flying after using Headless Horseman's Mount
if ( mode & AURA_EFFECT_HANDLE_REAL )
target -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2011-05-25 15:13:55 +02:00
}
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraAllowFlight ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-11-13 17:18:09 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-11-13 17:18:09 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
if ( ! apply )
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()) || target -> HasAuraType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ))
return ;
}
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_UNIT )
target -> SetFlying ( apply );
2011-06-29 13:09:32 +02:00
if ( Player * plr = target -> m_movedPlayer )
2011-06-19 13:13:41 +02:00
{
// allow flying
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_SET_CAN_FLY , 12 );
else
data . Initialize ( SMSG_MOVE_UNSET_CAN_FLY , 12 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 ); // unk
plr -> SendDirectMessage ( & data );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraWaterWalk ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_WATER_WALK , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_LAND_WALK , 8 + 4 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 );
target -> SendMessageToSet ( & data , true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraFeatherFall ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! apply )
2010-11-13 17:18:09 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_FEATHER_FALL , 8 + 4 );
2010-01-10 01:23:15 +01:00
else
2011-06-19 13:13:41 +02:00
data . Initialize ( SMSG_MOVE_NORMAL_FALL , 8 + 4 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 );
target -> SendMessageToSet ( & data , true );
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
// start fall from current height
if ( ! apply && target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> SetFallInformation ( 0 , target -> GetPositionZ ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraHover ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
2010-11-24 16:58:57 +01:00
}
2011-06-19 13:13:41 +02:00
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_SET_HOVER , 8 + 4 );
2010-11-24 16:58:57 +01:00
else
2011-06-19 13:13:41 +02:00
data . Initialize ( SMSG_MOVE_UNSET_HOVER , 8 + 4 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 );
target -> SendMessageToSet ( & data , true );
}
2010-09-12 01:40:27 +02:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleWaterBreathing ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
// update timers in client
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> UpdateMirrorTimers ();
}
void AuraEffect :: HandleForceMoveForward ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
if ( apply )
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
else
2011-05-25 15:13:55 +02:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
2011-05-25 15:13:55 +02:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/****************************/
/*** THREAT ***/
/****************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModThreat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2011-06-29 13:09:32 +02:00
for ( int8 i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () & ( 1 << i ))
ApplyPercentModFloatVar ( target -> m_threatModifier [ i ], float ( GetAmount ()), apply );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModTotalThreat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
2010-11-17 18:15:49 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-12-26 01:55:48 +01:00
2011-06-19 13:13:41 +02:00
if ( ! target -> isAlive () || target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-12-26 01:55:48 +01:00
2011-06-19 13:13:41 +02:00
Unit * caster = GetCaster ();
2011-06-29 13:09:32 +02:00
if ( caster && caster -> isAlive ())
target -> getHostileRefManager (). addTempThreat (( float ) GetAmount (), apply );
2011-06-19 13:13:41 +02:00
}
2010-12-26 01:55:48 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModTaunt ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-12-26 01:55:48 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! target -> isAlive () || ! target -> CanHaveThreatList ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
2010-01-10 01:23:15 +01:00
2010-12-31 18:12:20 +01:00
if ( apply )
2011-06-19 13:13:41 +02:00
target -> TauntApply ( caster );
else
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
target -> TauntFadeOut ( caster );
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/*****************************/
/*** CONTROL ***/
/*****************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModConfuse ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-12-31 14:39:18 +01:00
2011-06-19 13:13:41 +02:00
target -> SetControlled ( apply , UNIT_STAT_CONFUSED );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModFear ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> SetControlled ( apply , UNIT_STAT_FLEEING );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModStun ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-12-26 17:58:41 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-12-31 18:12:20 +01:00
2011-06-19 13:13:41 +02:00
target -> SetControlled ( apply , UNIT_STAT_STUNNED );
}
void AuraEffect :: HandleAuraModRoot ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
target -> SetControlled ( apply , UNIT_STAT_ROOT );
}
void AuraEffect :: HandlePreventFleeing ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
if ( target -> HasAuraType ( SPELL_AURA_MOD_FEAR ))
target -> SetControlled ( ! ( apply ), UNIT_STAT_FLEEING );
}
/***************************/
/*** CHARM ***/
/***************************/
void AuraEffect :: HandleModPossess ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
// no support for posession AI yet
if ( caster && caster -> GetTypeId () == TYPEID_UNIT )
{
HandleModCharm ( aurApp , mode , apply );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
if ( apply )
target -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS , aurApp );
else
target -> RemoveCharmedBy ( caster );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// only one spell has this aura
void AuraEffect :: HandleModPossessPet ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * caster = GetCaster ();
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
//seems it may happen that when removing it is no longer owner's pet
//if (caster->ToPlayer()->GetPet() != target)
// return;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_UNIT || ! target -> ToCreature () -> isPet ())
return ;
Pet * pet = target -> ToPet ();
if ( apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( caster -> ToPlayer () -> GetPet () != pet )
return ;
2010-12-29 17:18:29 +01:00
2011-06-19 13:13:41 +02:00
pet -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS , aurApp );
}
else
{
pet -> RemoveCharmedBy ( caster );
if ( ! pet -> IsWithinDistInMap ( caster , pet -> GetMap () -> GetVisibilityRange ()))
pet -> Remove ( PET_SAVE_NOT_IN_SLOT , true );
else
2010-12-29 17:18:29 +01:00
{
2011-06-19 13:13:41 +02:00
// Reinitialize the pet bar and make the pet come back to the owner
caster -> ToPlayer () -> PetSpellInitialize ();
if ( ! pet -> getVictim ())
2010-12-29 17:18:29 +01:00
{
2011-06-19 13:13:41 +02:00
pet -> GetMotionMaster () -> MoveFollow ( caster , PET_FOLLOW_DIST , pet -> GetFollowAngle ());
//if (target->GetCharmInfo())
// target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
2010-12-29 17:18:29 +01:00
}
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
2010-12-29 17:18:29 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModCharm ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-12-31 14:39:18 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
if ( apply )
target -> SetCharmedBy ( caster , CHARM_TYPE_CHARM , aurApp );
else
target -> RemoveCharmedBy ( caster );
}
void AuraEffect :: HandleCharmConvert ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
if ( apply )
target -> SetCharmedBy ( caster , CHARM_TYPE_CONVERT , aurApp );
else
target -> RemoveCharmedBy ( caster );
}
/**
* Such auras are applied from a caster(=player) to a vehicle.
* This has been verified using spell #49256
*/
void AuraEffect :: HandleAuraControlVehicle ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2011-06-28 16:48:03 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2011-06-19 13:13:41 +02:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( ! target -> IsVehicle ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || caster == target )
return ;
if ( apply )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
caster -> _EnterVehicle ( target -> GetVehicleKit (), m_amount - 1 , aurApp );
}
else
{
if ( GetId () == 53111 ) // Devour Humanoid
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> Kill ( caster );
if ( caster -> GetTypeId () == TYPEID_UNIT )
caster -> ToCreature () -> RemoveCorpse ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
caster -> _ExitVehicle ();
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
caster -> RemoveAurasDueToSpell ( GetId ());
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
/*********************************************************/
/*** MODIFY SPEED ***/
/*********************************************************/
void AuraEffect :: HandleAuraModIncreaseSpeed ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> UpdateSpeed ( MOVE_RUN , true );
}
void AuraEffect :: HandleAuraModIncreaseMountedSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
HandleAuraModIncreaseSpeed ( aurApp , mode , apply );
}
void AuraEffect :: HandleAuraModIncreaseFlightSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
// Enable Fly mode for flying mounts
if ( GetAuraType () == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK && ( apply || ( ! target -> HasAuraType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ) && ! target -> HasAuraType ( SPELL_AURA_FLY ))))
2010-01-10 01:23:15 +01:00
{
2011-06-29 13:09:32 +02:00
if ( Player * plr = target -> m_movedPlayer )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_SET_CAN_FLY , 12 );
2010-12-26 17:58:41 +01:00
else
2011-06-19 13:13:41 +02:00
data . Initialize ( SMSG_MOVE_UNSET_CAN_FLY , 12 );
data . append ( plr -> GetPackGUID ());
data << uint32 ( 0 ); // unknown
plr -> SendDirectMessage ( & data );
2010-01-10 01:23:15 +01:00
}
2010-12-31 18:12:20 +01:00
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( mode & AURA_EFFECT_HANDLE_REAL )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
//Players on flying mounts must be immune to polymorph
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_POLYMORPH , apply );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
if ( apply && target -> HasAuraEffect ( 42016 , 0 ) && target -> GetMountID ())
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
2010-01-10 01:23:15 +01:00
}
}
2011-04-28 22:11:45 +02:00
2011-06-19 13:13:41 +02:00
if ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK )
target -> UpdateSpeed ( MOVE_FLIGHT , true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModIncreaseSwimSpeed ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> UpdateSpeed ( MOVE_SWIM , true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModDecreaseSpeed ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> UpdateSpeed ( MOVE_RUN , true );
target -> UpdateSpeed ( MOVE_SWIM , true );
target -> UpdateSpeed ( MOVE_FLIGHT , true );
target -> UpdateSpeed ( MOVE_RUN_BACK , true );
target -> UpdateSpeed ( MOVE_SWIM_BACK , true );
target -> UpdateSpeed ( MOVE_FLIGHT_BACK , true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModUseNormalSpeed ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> UpdateSpeed ( MOVE_RUN , true );
target -> UpdateSpeed ( MOVE_SWIM , true );
target -> UpdateSpeed ( MOVE_FLIGHT , true );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
/*********************************************************/
/*** IMMUNITY ***/
/*********************************************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModStateImmunityMask ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
std :: list < AuraType > immunity_list ;
if ( GetMiscValue () & ( 1 << 10 ))
immunity_list . push_back ( SPELL_AURA_MOD_STUN );
if ( GetMiscValue () & ( 1 << 1 ))
immunity_list . push_back ( SPELL_AURA_TRANSFORM );
2010-12-31 14:39:18 +01:00
2011-06-19 13:13:41 +02:00
// These flag can be recognized wrong:
if ( GetMiscValue () & ( 1 << 6 ))
immunity_list . push_back ( SPELL_AURA_MOD_DECREASE_SPEED );
if ( GetMiscValue () & ( 1 << 0 ))
immunity_list . push_back ( SPELL_AURA_MOD_ROOT );
if ( GetMiscValue () & ( 1 << 2 ))
immunity_list . push_back ( SPELL_AURA_MOD_CONFUSE );
if ( GetMiscValue () & ( 1 << 9 ))
immunity_list . push_back ( SPELL_AURA_MOD_FEAR );
2010-12-31 14:39:18 +01:00
2011-06-19 13:13:41 +02:00
// an exception for Bladestorm
if (( GetMiscValue () & ( 1 << 7 )) && ( GetId () != 46924 ))
immunity_list . push_back ( SPELL_AURA_MOD_DISARM );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// apply immunities
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , * iter , apply );
// Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
if ( apply && GetId () == 46924 )
{
target -> RemoveAurasByType ( SPELL_AURA_MOD_ROOT );
target -> RemoveAurasByType ( SPELL_AURA_MOD_DECREASE_SPEED );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
if ( apply && GetSpellInfo () -> AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY )
2011-06-19 13:13:41 +02:00
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
target -> RemoveAurasByType ( * iter );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModMechanicImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2011-06-19 13:13:41 +02:00
uint32 mechanic ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
switch ( GetId ())
2011-05-25 15:13:55 +02:00
{
2011-06-19 13:13:41 +02:00
case 42292 : // PvP trinket
case 59752 : // Every Man for Himself
mechanic = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ;
// Actually we should apply immunities here, too, but the aura has only 100 ms duration, so there is practically no point
break ;
case 54508 : // Demonic Empowerment
mechanic = ( 1 << MECHANIC_SNARE ) | ( 1 << MECHANIC_ROOT );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_SNARE , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_ROOT , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_STUN , apply );
break ;
case 34471 : // The Beast Within
case 19574 : // Bestial Wrath
2011-06-29 13:09:32 +02:00
mechanic = ( 1 << MECHANIC_SNARE ) | ( 1 << MECHANIC_ROOT )
| ( 1 << MECHANIC_FEAR ) | ( 1 << MECHANIC_STUN )
| ( 1 << MECHANIC_SLEEP ) | ( 1 << MECHANIC_CHARM )
| ( 1 << MECHANIC_SAPPED ) | ( 1 << MECHANIC_HORROR )
| ( 1 << MECHANIC_POLYMORPH ) | ( 1 << MECHANIC_DISORIENTED )
| ( 1 << MECHANIC_FREEZE ) | ( 1 << MECHANIC_TURN );
2011-06-19 13:13:41 +02:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_SNARE , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_ROOT , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_FEAR , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_STUN , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_SLEEP , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_CHARM , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_SAPPED , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_HORROR , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_POLYMORPH , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_DISORIENTED , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_FREEZE , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_TURN , apply );
break ;
default :
if ( GetMiscValue () < 1 )
return ;
mechanic = 1 << GetMiscValue ();
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , GetMiscValue (), apply );
break ;
2011-05-25 15:13:55 +02:00
}
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
if ( apply && GetSpellInfo () -> AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY )
2011-06-19 13:13:41 +02:00
target -> RemoveAurasWithMechanic ( mechanic , AURA_REMOVE_BY_DEFAULT , GetId ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModEffectImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_EFFECT , GetMiscValue (), apply );
2010-12-29 17:18:29 +01:00
2011-06-19 13:13:41 +02:00
// when removing flag aura, handle flag drop
if ( ! apply && target -> GetTypeId () == TYPEID_PLAYER
2011-07-26 23:09:28 +02:00
&& ( GetSpellInfo () -> AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-12-29 17:18:29 +01:00
{
2011-06-19 13:13:41 +02:00
if ( target -> ToPlayer () -> InBattleground ())
{
2011-07-15 07:12:54 +07:00
if ( Battleground * bg = target -> ToPlayer () -> GetBattleground ())
2011-06-19 13:13:41 +02:00
bg -> EventPlayerDroppedFlag ( target -> ToPlayer ());
}
else
2011-07-26 23:09:28 +02:00
sOutdoorPvPMgr -> HandleDropFlag (( Player * ) target , GetSpellInfo () -> Id );
2010-12-29 17:18:29 +01:00
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModStateImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , GetMiscValue (), apply );
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
if ( apply && GetSpellInfo () -> AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY )
2011-06-19 13:13:41 +02:00
target -> RemoveAurasByType ( AuraType ( GetMiscValue ()), 0 , GetBase ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModSchoolImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_SCHOOL , GetMiscValue (), ( apply ));
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Mechanic == MECHANIC_BANISH )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( apply )
2011-06-19 13:13:41 +02:00
target -> AddUnitState ( UNIT_STAT_ISOLATED );
2010-01-10 01:23:15 +01:00
else
2011-06-19 13:13:41 +02:00
{
bool banishFound = false ;
Unit :: AuraEffectList const & banishAuras = target -> GetAuraEffectsByType ( GetAuraType ());
for ( Unit :: AuraEffectList :: const_iterator i = banishAuras . begin (); i != banishAuras . end (); ++ i )
2011-07-26 23:09:28 +02:00
if (( * i ) -> GetSpellInfo () -> Mechanic == MECHANIC_BANISH )
2011-06-19 13:13:41 +02:00
{
banishFound = true ;
break ;
}
if ( ! banishFound )
target -> ClearUnitState ( UNIT_STAT_ISOLATED );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
if ( apply && GetMiscValue () == SPELL_SCHOOL_MASK_NORMAL )
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// remove all flag auras (they are positive, but they must be removed when you are immune)
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY
&& GetSpellInfo () -> AttributesEx2 & SPELL_ATTR2_DAMAGE_REDUCED_SHIELD )
2011-06-19 13:13:41 +02:00
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
if (( apply )
2011-07-26 23:09:28 +02:00
&& GetSpellInfo () -> AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY
&& GetSpellInfo () -> IsPositive ()) //Only positive immunity removes auras
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
uint32 school_mask = GetMiscValue ();
Unit :: AuraApplicationMap & Auras = target -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator iter = Auras . begin (); iter != Auras . end ();)
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spell = iter -> second -> GetBase () -> GetSpellInfo ();
if (( spell -> GetSchoolMask () & school_mask ) //Check for school mask
&& GetSpellInfo () -> CanDispelAura ( spell )
2011-06-19 13:13:41 +02:00
&& ! iter -> second -> IsPositive () //Don't remove positive spells
&& spell -> Id != GetId ()) //Don't remove self
{
target -> RemoveAura ( iter );
}
else
++ iter ;
2010-01-10 01:23:15 +01:00
}
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModDmgImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_DAMAGE , GetMiscValue (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModDispelImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
target -> ApplySpellDispelImmunity ( m_spellInfo , DispelType ( GetMiscValue ()), ( apply ));
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/*********************************************************/
/*** MODIFY STATS ***/
/*********************************************************/
/********************************/
/*** RESISTANCE ***/
/********************************/
void AuraEffect :: HandleAuraModResistanceExclusive ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
if ( GetMiscValue () & int32 ( 1 << x ))
{
int32 amount = target -> GetMaxPositiveAuraModifierByMiscMask ( SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE , 1 << x , this );
if ( amount < GetAmount ())
{
2011-06-29 13:09:32 +02:00
float value = float ( GetAmount () - amount );
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_VALUE , value , apply );
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2011-06-29 13:09:32 +02:00
target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), aurApp -> IsPositive (), value , apply );
2011-06-19 13:13:41 +02:00
}
}
}
}
void AuraEffect :: HandleAuraModResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), TOTAL_VALUE , float ( GetAmount ()), apply );
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), GetAmount () > 0 , ( float ) GetAmount (), apply );
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModBaseResistancePCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// only players have base stats
if ( target -> GetTypeId () != TYPEID_PLAYER )
{
//pets only have base armor
if ( target -> ToCreature () -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
target -> HandleStatModifier ( UNIT_MOD_ARMOR , BASE_PCT , float ( GetAmount ()), apply );
}
2010-01-10 01:23:15 +01:00
else
{
2011-06-19 13:13:41 +02:00
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
if ( GetMiscValue () & int32 ( 1 << x ))
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_PCT , float ( GetAmount ()), apply );
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModResistancePercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
for ( int8 i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () & int32 ( 1 << i ))
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_PCT , float ( GetAmount ()), apply );
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
{
target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), true , ( float ) GetAmount (), apply );
target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), false , ( float ) GetAmount (), apply );
}
}
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModBaseResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// only players have base stats
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2011-06-19 13:13:41 +02:00
{
//only pets have base stats
if ( target -> ToCreature () -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
target -> HandleStatModifier ( UNIT_MOD_ARMOR , TOTAL_VALUE , float ( GetAmount ()), apply );
}
else
{
for ( int i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
if ( GetMiscValue () & ( 1 << i ))
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_VALUE , float ( GetAmount ()), apply );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModTargetResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2011-06-08 09:19:34 +02:00
return ;
2011-06-19 13:13:41 +02:00
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// show armor penetration
if ( target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE , GetAmount (), apply );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
if ( target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_SPELL ) == SPELL_SCHOOL_MASK_SPELL )
target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_RESISTANCE , GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** STAT ***/
/********************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () < - 2 || GetMiscValue () > 4 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
sLog -> outError ( "WARNING: Spell %u effect %u has an unsupported misc value (%i) for SPELL_AURA_MOD_STAT " , GetId (), GetEffIndex (), GetMiscValue ());
return ;
}
2010-12-17 19:03:12 +01:00
2011-06-19 13:13:41 +02:00
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
// -1 or -2 is all stats (misc < -2 checked in function beginning)
if ( GetMiscValue () < 0 || GetMiscValue () == i )
2010-12-17 19:03:12 +01:00
{
2011-06-19 13:13:41 +02:00
//target->ApplyStatMod(Stats(i), m_amount, apply);
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_VALUE , float ( GetAmount ()), apply );
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
target -> ApplyStatBuffMod ( Stats ( i ), ( float ) GetAmount (), apply );
2010-12-17 19:03:12 +01:00
}
2011-06-19 13:13:41 +02:00
}
}
2010-12-17 19:03:12 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModPercentStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
{
sLog -> outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// only players have base stats
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-12-17 19:03:12 +01:00
2011-06-19 13:13:41 +02:00
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; ++ i )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), BASE_PCT , float ( m_amount ), apply );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellDamagePercentFromStat ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellHealingPercentFromStat ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate bonus
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellDamagePercentFromAttackPower ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellHealingPercentFromAttackPower ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate bonus
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModHealingDone ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
// implemented in Unit::SpellHealingBonus
// this information is for client side only
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModTotalPercentStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
sLog -> outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// save current health state
float healthPct = target -> GetHealthPct ();
bool alive = target -> isAlive ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_PCT , float ( GetAmount ()), apply );
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
target -> ApplyStatPercentBuffMod ( Stats ( i ), float ( GetAmount ()), apply );
}
}
2010-01-10 01:23:15 +01:00
2011-06-30 01:47:09 +02:00
// recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_UNK4 0x00000010 flag)
// this check is total bullshit i think
2011-07-26 23:09:28 +02:00
if ( GetMiscValue () == STAT_STAMINA && ( m_spellInfo -> Attributes & SPELL_ATTR0_ABILITY ))
2011-06-19 13:13:41 +02:00
target -> SetHealth ( std :: max < uint32 > ( uint32 ( healthPct * target -> GetMaxHealth () * 0.01f ), ( alive ? 1 : 0 )));
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModResistenceOfStatPercent ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
if ( GetMiscValue () != SPELL_SCHOOL_MASK_NORMAL )
{
// support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
// and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
sLog -> outError ( "Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) does not work for non-armor type resistances!" );
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate Armor
target -> UpdateArmor ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModExpertise ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> UpdateExpertise ( BASE_ATTACK );
target -> ToPlayer () -> UpdateExpertise ( OFF_ATTACK );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** HEAL & ENERGIZE ***/
/********************************/
void AuraEffect :: HandleModPowerRegen ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
// Update manaregen value
if ( GetMiscValue () == POWER_MANA )
target -> ToPlayer () -> UpdateManaRegen ();
2011-07-15 04:58:14 +07:00
else if ( GetMiscValue () == POWER_RUNE )
target -> ToPlayer () -> UpdateRuneRegen ( RuneType ( GetMiscValueB ()));
2011-06-19 13:13:41 +02:00
// other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModPowerRegenPCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
HandleModPowerRegen ( aurApp , mode , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModManaRegen ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
//Note: an increase in regen does NOT cause threat.
target -> ToPlayer () -> UpdateManaRegen ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModIncreaseHealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( GetAmount ()), apply );
target -> ModifyHealth ( GetAmount ());
}
else
{
if ( int32 ( target -> GetHealth ()) > GetAmount ())
target -> ModifyHealth ( - GetAmount ());
else
target -> SetHealth ( 1 );
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( GetAmount ()), apply );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModIncreaseMaxHealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 oldhealth = target -> GetHealth ();
double healthPercentage = ( double ) oldhealth / ( double ) target -> GetMaxHealth ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// refresh percentage
if ( oldhealth > 0 )
{
uint32 newhealth = uint32 ( ceil (( double ) target -> GetMaxHealth () * healthPercentage ));
if ( newhealth == 0 )
newhealth = 1 ;
target -> SetHealth ( newhealth );
}
}
void AuraEffect :: HandleAuraModIncreaseEnergy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Powers powerType = Powers ( GetMiscValue ());
// do not check power type, we can always modify the maximum
// as the client will not see any difference
// also, placing conditions that may change during the aura duration
// inside effect handlers is not a good idea
//if (int32(powerType) != GetMiscValue())
// return;
2011-05-25 15:13:55 +02:00
2011-06-19 13:13:41 +02:00
UnitMods unitMod = UnitMods ( UNIT_MOD_POWER_START + powerType );
// Special case with temporary increase max/current power (percent)
if ( GetId () == 64904 ) // Hymn of Hope
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK )
{
int32 change = target -> GetPower ( powerType ) + ( apply ? GetAmount () : - GetAmount ());
if ( change < 0 )
change = 0 ;
target -> SetPower ( powerType , change );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// generic flat case
target -> HandleStatModifier ( unitMod , TOTAL_VALUE , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModIncreaseEnergyPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Powers powerType = Powers ( GetMiscValue ());
// do not check power type, we can always modify the maximum
// as the client will not see any difference
// also, placing conditions that may change during the aura duration
// inside effect handlers is not a good idea
//if (int32(powerType) != GetMiscValue())
2010-01-10 01:23:15 +01:00
// return;
2011-06-19 13:13:41 +02:00
UnitMods unitMod = UnitMods ( UNIT_MOD_POWER_START + powerType );
target -> HandleStatModifier ( unitMod , TOTAL_PCT , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModIncreaseHealthPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-08-12 12:14:32 +06:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-08-12 12:14:32 +06:00
2011-06-19 13:13:41 +02:00
// Unit will keep hp% after MaxHealth being modified if unit is alive.
float percent = target -> GetHealthPct ();
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_PCT , float ( GetAmount ()), apply );
if ( target -> isAlive ())
target -> SetHealth ( target -> CountPctFromMaxHealth ( int32 ( percent )));
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraIncreaseBaseHealthPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
target -> HandleStatModifier ( UNIT_MOD_HEALTH , BASE_PCT , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** FIGHT ***/
/********************************/
void AuraEffect :: HandleAuraModParryPercent ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> UpdateParryPercentage ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModDodgePercent ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> UpdateDodgePercentage ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModBlockPercent ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> UpdateBlockPercentage ();
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModRegenInterrupt ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
HandleModManaRegen ( aurApp , mode , apply );
}
void AuraEffect :: HandleAuraModWeaponCritPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
if ( Item * pItem = target -> ToPlayer () -> GetWeaponForAttack ( WeaponAttackType ( i ), true ))
target -> ToPlayer () -> _ApplyWeaponDependentAuraCritMod ( pItem , WeaponAttackType ( i ), this , apply );
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
// GetMiscValue() comparison with item generated damage types
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> EquippedItemClass == - 1 )
2011-01-26 01:03:35 +01:00
{
2011-06-19 13:13:41 +02:00
target -> ToPlayer () -> HandleBaseModValue ( CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
target -> ToPlayer () -> HandleBaseModValue ( OFFHAND_CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
target -> ToPlayer () -> HandleBaseModValue ( RANGED_CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
else
{
2011-06-19 13:13:41 +02:00
// done in Player::_ApplyWeaponDependentAuraMods
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModHitChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
target -> ToPlayer () -> UpdateMeleeHitChances ();
target -> ToPlayer () -> UpdateRangedHitChances ();
}
else
{
target -> m_modMeleeHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
target -> m_modRangedHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellHitChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> UpdateSpellHitChances ();
else
target -> m_modSpellHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellCritChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> UpdateAllSpellCritChances ();
else
target -> m_baseSpellCritChance += ( apply ) ? GetAmount () :- GetAmount ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModSpellCritChanceShool ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( int school = SPELL_SCHOOL_NORMAL ; school < MAX_SPELL_SCHOOL ; ++ school )
if ( GetMiscValue () & ( 1 << school ))
target -> ToPlayer () -> UpdateSpellCritChance ( school );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModCritPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
{
target -> m_baseSpellCritChance += ( apply ) ? GetAmount () :- GetAmount ();
return ;
}
target -> ToPlayer () -> HandleBaseModValue ( CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
target -> ToPlayer () -> HandleBaseModValue ( OFFHAND_CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
target -> ToPlayer () -> HandleBaseModValue ( RANGED_CRIT_PERCENTAGE , FLAT_MOD , float ( GetAmount ()), apply );
// included in Player::UpdateSpellCritChance calculation
target -> ToPlayer () -> UpdateAllSpellCritChances ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** ATTACK SPEED ***/
/********************************/
void AuraEffect :: HandleModCastingSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplyCastTimePercentMod (( float ) GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModMeleeRangedSpeedPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , ( float ) GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , ( float ) GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , ( float ) GetAmount (), apply );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModCombatSpeedPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-08-23 17:11:50 -07:00
2011-06-19 13:13:41 +02:00
target -> ApplyCastTimePercentMod ( float ( m_amount ), apply );
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , float ( GetAmount ()), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , float ( GetAmount ()), apply );
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , float ( GetAmount ()), apply );
}
2011-05-25 15:13:55 +02:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModAttackSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , ( float ) GetAmount (), apply );
target -> UpdateDamagePhysical ( BASE_ATTACK );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModMeleeSpeedPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , ( float ) GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , ( float ) GetAmount (), apply );
}
2010-04-07 18:09:10 +02:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModRangedHaste ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , ( float ) GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleRangedAmmoHaste ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2011-05-25 15:13:55 +02:00
2011-06-19 13:13:41 +02:00
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , ( float ) GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** COMBAT RATING ***/
/********************************/
void AuraEffect :: HandleModRating ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2011-05-25 15:13:55 +02:00
2011-06-19 13:13:41 +02:00
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
if ( GetMiscValue () & ( 1 << rating ))
target -> ToPlayer () -> ApplyRatingMod ( CombatRating ( rating ), GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModRatingFromStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Just recalculate ratings
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
if ( GetMiscValue () & ( 1 << rating ))
target -> ToPlayer () -> ApplyRatingMod ( CombatRating ( rating ), 0 , apply );
}
2010-12-31 14:39:18 +01:00
2011-06-19 13:13:41 +02:00
/********************************/
/*** ATTACK POWER ***/
/********************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_VALUE , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModRangedAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if (( target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
return ;
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER_RANGED , TOTAL_VALUE , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModAttackPowerPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_PCT , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModRangedAttackPowerPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if (( target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
return ;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER_RANGED , TOTAL_PCT , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModRangedAttackPowerOfStatPercent ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate bonus
if ( target -> GetTypeId () == TYPEID_PLAYER && ! ( target -> getClassMask () & CLASSMASK_WAND_USERS ))
target -> ToPlayer () -> UpdateAttackPowerAndDamage ( true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModAttackPowerOfStatPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
HandleAuraModAttackPowerOfArmor ( aurApp , mode , apply );
}
void AuraEffect :: HandleAuraModAttackPowerOfArmor ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Recalculate bonus
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> UpdateAttackPowerAndDamage ( false );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** DAMAGE BONUS ***/
/********************************/
void AuraEffect :: HandleModDamageDone ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// apply item specific bonuses for already equipped weapon
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
if ( Item * pItem = target -> ToPlayer () -> GetWeaponForAttack ( WeaponAttackType ( i ), true ))
target -> ToPlayer () -> _ApplyWeaponDependentAuraDamageMod ( pItem , WeaponAttackType ( i ), this , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// GetMiscValue() is bitmask of spell schools
// 1 (0-bit) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
// 127 - full bitmask any damages
//
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
// GetMiscValue() comparison with item generated damage types
if (( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ) != 0 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// apply generic physical damage bonuses including wand case
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> EquippedItemClass == - 1 || target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_MAINHAND , TOTAL_VALUE , float ( GetAmount ()), apply );
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_VALUE , float ( GetAmount ()), apply );
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_RANGED , TOTAL_VALUE , float ( GetAmount ()), apply );
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
if ( GetAmount () > 0 )
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS , GetAmount (), apply );
else
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG , GetAmount (), apply );
}
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
// Skip non magic case for speedup
if (( GetMiscValue () & SPELL_SCHOOL_MASK_MAGIC ) == 0 )
2010-01-10 01:23:15 +01:00
return ;
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> EquippedItemClass != - 1 || GetSpellInfo () -> EquippedItemInventoryTypeMask != 0 )
2011-06-19 13:13:41 +02:00
{
// wand magic case (skip generic to all item spell bonuses)
// done in Player::_ApplyWeaponDependentAuraMods
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Skip item specific requirements for not wand magic damage
return ;
}
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( GetAmount () > 0 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if (( GetMiscValue () & ( 1 << i )) != 0 )
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i , GetAmount (), apply );
}
}
else
{
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
{
if (( GetMiscValue () & ( 1 << i )) != 0 )
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i , GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
if ( Guardian * pet = target -> ToPlayer () -> GetGuardianPet ())
pet -> UpdateAttackPowerAndDamage ();
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModDamagePercentDone ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Player * target = aurApp -> GetTarget () -> ToPlayer ();
if ( ! target )
return ;
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
if ( target -> HasItemFitToSpellRequirements ( GetSpellInfo ()))
2011-06-29 13:09:32 +02:00
target -> ApplyModSignedFloatValue ( PLAYER_FIELD_MOD_DAMAGE_DONE_PCT , GetAmount () / 100.0f , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModOffhandDamagePercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_PCT , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleShieldBlockValue ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
BaseModType modType = FLAT_MOD ;
if ( GetAuraType () == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT )
modType = PCT_MOD ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> HandleBaseModValue ( SHIELD_BLOCK_VALUE , modType , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/********************************/
/*** POWER COST ***/
/********************************/
void AuraEffect :: HandleModPowerCostPCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
float amount = CalculatePctN ( 1.0f , GetAmount ());
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
if ( GetMiscValue () & ( 1 << i ))
target -> ApplyModSignedFloatValue ( UNIT_FIELD_POWER_COST_MULTIPLIER + i , amount , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleModPowerCost ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
if ( GetMiscValue () & ( 1 << i ))
target -> ApplyModInt32Value ( UNIT_FIELD_POWER_COST_MODIFIER + i , GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleArenaPreparation ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PREPARATION );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PREPARATION );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleNoReagentUseAura ( AuraApplication const * aurApp , uint8 mode , bool /*apply*/ ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
flag96 mask ;
Unit :: AuraEffectList const & noReagent = target -> GetAuraEffectsByType ( SPELL_AURA_NO_REAGENT_USE );
for ( Unit :: AuraEffectList :: const_iterator i = noReagent . begin (); i != noReagent . end (); ++ i )
2011-07-26 23:09:28 +02:00
mask |= ( * i ) -> m_spellInfo -> Effects [( * i ) -> m_effIndex ]. SpellClassMask ;
2011-06-19 13:13:41 +02:00
target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 , mask [ 0 ]);
target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 + 1 , mask [ 1 ]);
target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 + 2 , mask [ 2 ]);
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraRetainComboPoints ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
// combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
// remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
if ( ! ( apply ) && GetBase () -> GetDuration () == 0 && target -> ToPlayer () -> GetComboTarget ())
if ( Unit * unit = ObjectAccessor :: GetUnit ( * target , target -> ToPlayer () -> GetComboTarget ()))
target -> ToPlayer () -> AddComboPoints ( unit , - GetAmount ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraDummy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & ( AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_REAPPLY )))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * caster = GetCaster ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( mode & AURA_EFFECT_HANDLE_REAL )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// pet auras
if ( PetAura const * petSpell = sSpellMgr -> GetPetAura ( GetId (), m_effIndex ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( apply )
target -> AddPetAura ( petSpell );
else
target -> RemovePetAura ( petSpell );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
if ( mode & ( AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// AT APPLY
if ( apply )
{
// Overpower
2011-07-26 23:09:28 +02:00
if ( caster && m_spellInfo -> SpellFamilyName == SPELLFAMILY_WARRIOR &&
m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x4 )
2011-06-19 13:13:41 +02:00
{
// In addition, if you strike a player..
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
// ..while they are casting
if ( target -> IsNonMeleeSpellCasted ( false , false , true , false , false ))
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( SPELL_AURA_ADD_FLAT_MODIFIER , SPELLFAMILY_WARRIOR , 2775 , 0 ))
2011-06-19 13:13:41 +02:00
switch ( aurEff -> GetId ())
{
// Unrelenting Assault, rank 1
case 46859 :
target -> CastSpell ( target , 64849 , true , NULL , aurEff );
break ;
// Unrelenting Assault, rank 2
case 46860 :
target -> CastSpell ( target , 64850 , true , NULL , aurEff );
break ;
}
}
switch ( GetId ())
{
case 1515 : // Tame beast
// FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
if ( caster && target -> CanHaveThreatList ())
target -> AddThreat ( caster , 10.0f );
break ;
case 13139 : // net-o-matic
// root to self part of (root_target->charge->root_self sequence
if ( caster )
caster -> CastSpell ( caster , 13138 , true , NULL , this );
break ;
case 34026 : // kill command
{
Unit * pet = target -> GetGuardianPet ();
if ( ! pet )
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , 34027 , true , NULL , this );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// set 3 stacks and 3 charges (to make all auras not disappear at once)
2011-07-15 07:12:54 +07:00
Aura * owner_aura = target -> GetAura ( 34027 , GetCasterGUID ());
Aura * pet_aura = pet -> GetAura ( 58914 , GetCasterGUID ());
2011-06-19 13:13:41 +02:00
if ( owner_aura )
{
2011-07-26 23:09:28 +02:00
owner_aura -> SetStackAmount ( owner_aura -> GetSpellInfo () -> StackAmount );
2011-06-19 13:13:41 +02:00
}
if ( pet_aura )
{
pet_aura -> SetCharges ( 0 );
2011-07-26 23:09:28 +02:00
pet_aura -> SetStackAmount ( owner_aura -> GetSpellInfo () -> StackAmount );
2011-06-19 13:13:41 +02:00
}
break ;
}
case 37096 : // Blood Elf Illusion
{
if ( caster )
{
switch ( caster -> getGender ())
{
case GENDER_FEMALE :
caster -> CastSpell ( target , 37095 , true , NULL , this ); // Blood Elf Disguise
break ;
case GENDER_MALE :
caster -> CastSpell ( target , 37093 , true , NULL , this );
break ;
default :
break ;
}
}
break ;
}
case 55198 : // Tidal Force
{
target -> CastSpell ( target , 55166 , true , NULL , this );
// set 3 stacks and 3 charges (to make all auras not disappear at once)
2011-07-15 07:12:54 +07:00
Aura * owner_aura = target -> GetAura ( 55166 , GetCasterGUID ());
2011-06-19 13:13:41 +02:00
if ( owner_aura )
{
// This aura lasts 2 sec, need this hack to properly proc spells
// TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
GetBase () -> SetDuration ( owner_aura -> GetDuration ());
// Make aura be not charged-this prevents removing charge on not crit spells
owner_aura -> SetCharges ( 0 );
2011-07-26 23:09:28 +02:00
owner_aura -> SetStackAmount ( owner_aura -> GetSpellInfo () -> StackAmount );
2011-06-19 13:13:41 +02:00
}
break ;
}
case 39850 : // Rocket Blast
if ( roll_chance_i ( 20 )) // backfire stun
target -> CastSpell ( target , 51581 , true , NULL , this );
break ;
case 43873 : // Headless Horseman Laugh
target -> PlayDistanceSound ( 11965 );
break ;
case 46354 : // Blood Elf Illusion
if ( caster )
{
switch ( caster -> getGender ())
{
case GENDER_FEMALE :
caster -> CastSpell ( target , 46356 , true , NULL , this );
break ;
case GENDER_MALE :
caster -> CastSpell ( target , 46355 , true , NULL , this );
break ;
}
}
break ;
case 46361 : // Reinforced Net
if ( caster )
{
float currentGroundLevel = target -> GetBaseMap () -> GetHeight ( target -> GetPositionX (), target -> GetPositionY (), MAX_HEIGHT );
if ( target -> GetPositionZ () > currentGroundLevel )
target -> GetMotionMaster () -> MoveFall ( currentGroundLevel );
}
break ;
case 46699 : // Requires No Ammo
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ToPlayer () -> RemoveAmmo (); // not use ammo and not allow use
break ;
case 49028 :
if ( caster )
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( 63330 , 0 )) // glyph of Dancing Rune Weapon
2011-06-19 13:13:41 +02:00
GetBase () -> SetDuration ( GetBase () -> GetDuration () + aurEff -> GetAmount ());
break ;
case 52916 : // Honor Among Thieves
if ( target -> GetTypeId () == TYPEID_PLAYER )
if ( Unit * spellTarget = ObjectAccessor :: GetUnit ( * target , target -> ToPlayer () -> GetComboTarget ()))
target -> CastSpell ( spellTarget , 51699 , true );
break ;
case 28832 : // Mark of Korth'azz
case 28833 : // Mark of Blaumeux
case 28834 : // Mark of Rivendare
case 28835 : // Mark of Zeliek
if ( caster ) // actually we can also use cast(this, originalcasterguid)
{
int32 damage ;
switch ( GetBase () -> GetStackAmount ())
{
case 1 : damage = 0 ; break ;
case 2 : damage = 500 ; break ;
case 3 : damage = 1000 ; break ;
case 4 : damage = 1500 ; break ;
case 5 : damage = 4000 ; break ;
case 6 : damage = 12000 ; break ;
default : damage = 20000 + 1000 * ( GetBase () -> GetStackAmount () - 7 ); break ;
}
if ( damage )
caster -> CastCustomSpell ( 28836 , SPELLVALUE_BASE_POINT0 , damage , target );
}
break ;
case 63322 : // Saronite Vapors
{
int32 mana = int32 ( GetAmount () * pow ( 2.0f , GetBase () -> GetStackAmount ())); // mana restore - bp * 2^stackamount
int32 damage = mana * 2 ; // damage
caster -> CastCustomSpell ( target , 63337 , & mana , NULL , NULL , true );
caster -> CastCustomSpell ( target , 63338 , & damage , NULL , NULL , true );
break ;
}
case 71563 :
if ( Aura * newAura = target -> AddAura ( 71564 , target ))
2011-07-26 23:09:28 +02:00
newAura -> SetStackAmount ( newAura -> GetSpellInfo () -> StackAmount );
2011-06-19 13:13:41 +02:00
}
}
// AT REMOVE
2010-01-10 01:23:15 +01:00
else
2010-04-03 08:22:04 +02:00
{
2011-07-26 23:09:28 +02:00
if (( GetSpellInfo () -> IsQuestTame ()) && caster && caster -> isAlive () && target -> isAlive ())
2011-06-19 13:13:41 +02:00
{
uint32 finalSpelId = 0 ;
switch ( GetId ())
{
case 19548 : finalSpelId = 19597 ; break ;
case 19674 : finalSpelId = 19677 ; break ;
case 19687 : finalSpelId = 19676 ; break ;
case 19688 : finalSpelId = 19678 ; break ;
case 19689 : finalSpelId = 19679 ; break ;
case 19692 : finalSpelId = 19680 ; break ;
case 19693 : finalSpelId = 19684 ; break ;
case 19694 : finalSpelId = 19681 ; break ;
case 19696 : finalSpelId = 19682 ; break ;
case 19697 : finalSpelId = 19683 ; break ;
case 19699 : finalSpelId = 19685 ; break ;
case 19700 : finalSpelId = 19686 ; break ;
case 30646 : finalSpelId = 30647 ; break ;
case 30653 : finalSpelId = 30648 ; break ;
case 30654 : finalSpelId = 30652 ; break ;
case 30099 : finalSpelId = 30100 ; break ;
case 30102 : finalSpelId = 30103 ; break ;
case 30105 : finalSpelId = 30104 ; break ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( finalSpelId )
caster -> CastSpell ( target , finalSpelId , true , NULL , this );
}
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
switch ( m_spellInfo -> SpellFamilyName )
2011-06-19 13:13:41 +02:00
{
case SPELLFAMILY_GENERIC :
switch ( GetId ())
{
case 2584 : // Waiting to Resurrect
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
if ( target -> GetTypeId () == TYPEID_PLAYER )
2011-07-15 07:12:54 +07:00
if ( Battleground * bg = target -> ToPlayer () -> GetBattleground ())
2011-06-19 13:13:41 +02:00
bg -> RemovePlayerFromResurrectQueue ( target -> GetGUID ());
break ;
case 36730 : // Flame Strike
{
target -> CastSpell ( target , 36731 , true , NULL , this );
break ;
}
case 44191 : // Flame Strike
{
if ( target -> GetMap () -> IsDungeon ())
{
uint32 spellId = target -> GetMap () -> IsHeroic () ? 46163 : 44190 ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , spellId , true , NULL , this );
}
break ;
}
case 43681 : // Inactive
{
if ( ! target || target -> GetTypeId () != TYPEID_PLAYER || aurApp -> GetRemoveMode () != AURA_REMOVE_BY_EXPIRE )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetMap () -> IsBattleground ())
target -> ToPlayer () -> LeaveBattleground ();
break ;
}
case 42783 : // Wrath of the Astromancer
target -> CastSpell ( target , GetAmount (), true , NULL , this );
break ;
case 46308 : // Burning Winds casted only at creatures at spawn
target -> CastSpell ( target , 47287 , true , NULL , this );
break ;
case 52172 : // Coyote Spirit Despawn Aura
case 60244 : // Blood Parrot Despawn Aura
target -> CastSpell (( Unit * ) NULL , GetAmount (), true , NULL , this );
break ;
case 58600 : // Restricted Flight Area
if ( aurApp -> GetRemoveMode () == AURA_REMOVE_BY_EXPIRE )
target -> CastSpell ( target , 58601 , true );
break ;
}
break ;
case SPELLFAMILY_MAGE :
// Living Bomb
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x20000 )
2011-06-19 13:13:41 +02:00
{
AuraRemoveMode mode = aurApp -> GetRemoveMode ();
if ( caster && ( mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE ))
caster -> CastSpell ( target , GetAmount (), true );
}
break ;
case SPELLFAMILY_WARLOCK :
// Haunt
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x40000 )
2011-06-19 13:13:41 +02:00
{
if ( caster )
target -> CastCustomSpell ( caster , 48210 , & m_amount , 0 , 0 , true , NULL , this , GetCasterGUID ());
}
break ;
case SPELLFAMILY_DRUID :
// Lifebloom
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x10 )
2011-06-19 13:13:41 +02:00
{
// Final heal only on duration end
if ( aurApp -> GetRemoveMode () != AURA_REMOVE_BY_EXPIRE )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// final heal
int32 stack = GetBase () -> GetStackAmount ();
target -> CastCustomSpell ( target , 33778 , & m_amount , & stack , NULL , true , NULL , this , GetCasterGUID ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// restore mana
if ( caster )
{
2011-07-26 23:09:28 +02:00
int32 returnmana = CalculatePctU ( caster -> GetCreateMana (), GetSpellInfo () -> ManaCostPercentage ) * stack / 2 ;
2011-06-19 13:13:41 +02:00
caster -> CastCustomSpell ( caster , 64372 , & returnmana , NULL , NULL , true , NULL , this , GetCasterGUID ());
}
}
break ;
case SPELLFAMILY_PRIEST :
// Vampiric Touch
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x0400 && aurApp -> GetRemoveMode () == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex () == 0 )
2011-06-19 13:13:41 +02:00
{
if ( AuraEffect const * aurEff = GetBase () -> GetEffect ( 1 ))
{
int32 damage = aurEff -> GetAmount () * 8 ;
// backfire damage
target -> CastCustomSpell ( target , 64085 , & damage , NULL , NULL , true , NULL , NULL , GetCasterGUID ());
}
}
break ;
case SPELLFAMILY_HUNTER :
// Misdirection
if ( GetId () == 34477 )
target -> SetReducedThreatPercent ( 0 , 0 );
break ;
case SPELLFAMILY_DEATHKNIGHT :
// Summon Gargoyle (Dismiss Gargoyle at remove)
if ( GetId () == 61777 )
target -> CastSpell ( target , GetAmount (), true );
break ;
default :
break ;
}
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// AT APPLY & REMOVE
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
switch ( m_spellInfo -> SpellFamilyName )
2011-06-19 13:13:41 +02:00
{
case SPELLFAMILY_GENERIC :
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
break ;
switch ( GetId ())
{
// Recently Bandaged
case 11196 :
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , GetMiscValue (), apply );
break ;
// Unstable Power
case 24658 :
{
uint32 spellId = 24659 ;
if ( apply && caster )
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spell = sSpellMgr -> GetSpellInfo ( spellId );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
for ( uint32 i = 0 ; i < spell -> StackAmount ; ++ i )
caster -> CastSpell ( target , spell -> Id , true , NULL , NULL , GetCasterGUID ());
break ;
}
target -> RemoveAurasDueToSpell ( spellId );
break ;
}
// Restless Strength
case 24661 :
{
uint32 spellId = 24662 ;
if ( apply && caster )
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spell = sSpellMgr -> GetSpellInfo ( spellId );
2011-06-19 13:13:41 +02:00
for ( uint32 i = 0 ; i < spell -> StackAmount ; ++ i )
caster -> CastSpell ( target , spell -> Id , true , NULL , NULL , GetCasterGUID ());
break ;
}
target -> RemoveAurasDueToSpell ( spellId );
break ;
}
// Tag Murloc
case 30877 :
{
// Tag/untag Blacksilt Scout
target -> SetEntry ( apply ? 17654 : 17326 );
break ;
}
//Summon Fire Elemental
case 40133 :
{
if ( ! caster )
break ;
2010-01-10 01:23:15 +01:00
2011-07-15 07:12:54 +07:00
Unit * owner = caster -> GetOwner ();
2011-06-19 13:13:41 +02:00
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
owner -> CastSpell ( owner , 8985 , true );
else
owner -> ToPlayer () -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
}
break ;
}
//Summon Earth Elemental
case 40132 :
{
if ( ! caster )
break ;
2010-01-10 01:23:15 +01:00
2011-07-15 07:12:54 +07:00
Unit * owner = caster -> GetOwner ();
2011-06-19 13:13:41 +02:00
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
owner -> CastSpell ( owner , 19704 , true );
else
owner -> ToPlayer () -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
}
break ;
}
case 57723 : // Exhaustion
case 57724 : // Sated
{
switch ( GetId ())
{
case 57723 : target -> ApplySpellImmune ( GetId (), IMMUNITY_ID , 32182 , apply ); break ; // Heroism
case 57724 : target -> ApplySpellImmune ( GetId (), IMMUNITY_ID , 2825 , apply ); break ; // Bloodlust
}
break ;
}
case 57819 : // Argent Champion
case 57820 : // Ebon Champion
case 57821 : // Champion of the Kirin Tor
case 57822 : // Wyrmrest Champion
{
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 FactionID = 0 ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
2011-07-26 23:09:28 +02:00
switch ( m_spellInfo -> Id )
2011-06-19 13:13:41 +02:00
{
case 57819 : FactionID = 1106 ; break ; // Argent Crusade
case 57820 : FactionID = 1098 ; break ; // Knights of the Ebon Blade
case 57821 : FactionID = 1090 ; break ; // Kirin Tor
case 57822 : FactionID = 1091 ; break ; // The Wyrmrest Accord
}
}
caster -> ToPlayer () -> SetChampioningFaction ( FactionID );
break ;
}
// LK Intro VO (1)
case 58204 :
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
// Play part 1
if ( apply )
target -> PlayDirectSound ( 14970 , target -> ToPlayer ());
// continue in 58205
else
target -> CastSpell ( target , 58205 , true );
}
break ;
// LK Intro VO (2)
case 58205 :
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
// Play part 2
if ( apply )
target -> PlayDirectSound ( 14971 , target -> ToPlayer ());
// Play part 3
else
target -> PlayDirectSound ( 14972 , target -> ToPlayer ());
}
break ;
case 62061 : // Festive Holiday Mount
if ( target -> HasAuraType ( SPELL_AURA_MOUNTED ))
{
uint32 creatureEntry = 0 ;
if ( apply )
{
if ( target -> HasAuraType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ))
creatureEntry = 24906 ;
else
creatureEntry = 15665 ;
}
else
creatureEntry = target -> GetAuraEffectsByType ( SPELL_AURA_MOUNTED ). front () -> GetMiscValue ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( CreatureTemplate const * creatureInfo = sObjectMgr -> GetCreatureTemplate ( creatureEntry ))
{
uint32 team = 0 ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
team = target -> ToPlayer () -> GetTeam ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 displayID = sObjectMgr -> ChooseDisplayId ( team , creatureInfo );
sObjectMgr -> GetCreatureModelRandomGender ( & displayID );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , displayID );
}
}
break ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
break ;
}
case SPELLFAMILY_MAGE :
{
//if (!(mode & AURA_EFFECT_HANDLE_REAL))
//break;
break ;
}
case SPELLFAMILY_PRIEST :
{
//if (!(mode & AURA_EFFECT_HANDLE_REAL))
//break;
break ;
}
case SPELLFAMILY_DRUID :
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
break ;
switch ( GetId ())
{
case 52610 : // Savage Roar
{
uint32 spellId = 62071 ;
if ( apply )
{
if ( target -> GetShapeshiftForm () != FORM_CAT )
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , spellId , true , NULL , NULL , GetCasterGUID ());
break ;
}
target -> RemoveAurasDueToSpell ( spellId );
break ;
}
case 61336 : // Survival Instincts
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
if ( ! target -> IsInFeralForm ())
break ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
int32 bp0 = int32 ( target -> CountPctFromMaxHealth ( GetAmount ()));
target -> CastCustomSpell ( target , 50322 , & bp0 , NULL , NULL , true );
}
else
target -> RemoveAurasDueToSpell ( 50322 );
break ;
}
}
// Predatory Strikes
2011-07-26 23:09:28 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER && GetSpellInfo () -> SpellIconID == 1563 )
2011-06-19 13:13:41 +02:00
{
target -> ToPlayer () -> UpdateAttackPowerAndDamage ();
}
break ;
}
case SPELLFAMILY_SHAMAN :
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
break ;
// Sentry Totem
if ( GetId () == 6495 && caster -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
{
uint64 guid = caster -> m_SummonSlot [ 3 ];
if ( guid )
{
2011-07-15 07:12:54 +07:00
Creature * totem = caster -> GetMap () -> GetCreature ( guid );
2011-06-19 13:13:41 +02:00
if ( totem && totem -> isTotem ())
caster -> ToPlayer () -> CastSpell ( totem , 6277 , true );
}
}
else
caster -> ToPlayer () -> StopCastingBindSight ();
return ;
}
break ;
}
case SPELLFAMILY_PALADIN :
// if (!(mode & AURA_EFFECT_HANDLE_REAL))
// break;
break ;
2011-07-15 07:01:33 +07:00
case SPELLFAMILY_DEATHKNIGHT :
{
2011-07-16 00:46:58 +07:00
//if (!(mode & AURA_EFFECT_HANDLE_REAL))
// break;
2011-07-15 07:01:33 +07:00
break ;
}
2011-06-19 13:13:41 +02:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleChannelDeathItem ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
if ( ! apply )
{
Unit * caster = GetCaster ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-01-10 01:23:15 +01:00
2011-06-29 13:09:32 +02:00
Player * plCaster = caster -> ToPlayer ();
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> getDeathState () != JUST_DIED )
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Item amount
if ( GetAmount () <= 0 )
return ;
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ m_effIndex ]. ItemType == 0 )
2011-06-19 13:13:41 +02:00
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Soul Shard
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ m_effIndex ]. ItemType == 6265 )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Soul Shard only from units that grant XP or honor
if ( ! plCaster -> isHonorOrXPTarget ( target ) ||
( target -> GetTypeId () == TYPEID_UNIT && ! target -> ToCreature () -> isTappedBy ( plCaster )))
return ;
2010-01-13 11:56:20 +01:00
2011-06-19 13:13:41 +02:00
// If this is Drain Soul, check for Glyph of Drain Soul
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00004000 ))
2010-01-13 11:56:20 +01:00
{
2011-06-19 13:13:41 +02:00
// Glyph of Drain Soul - chance to create an additional Soul Shard
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aur = caster -> GetAuraEffect ( 58070 , 0 ))
2011-06-19 13:13:41 +02:00
if ( roll_chance_i ( aur -> GetMiscValue ()))
caster -> CastSpell ( caster , 58068 , true , 0 , aur ); // We _could_ simply do ++count here, but Blizz does it this way :)
2010-01-13 11:56:20 +01:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
//Adding items
uint32 noSpaceForCount = 0 ;
uint32 count = m_amount ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
ItemPosCountVec dest ;
2011-07-26 23:09:28 +02:00
InventoryResult msg = plCaster -> CanStoreNewItem ( NULL_BAG , NULL_SLOT , dest , GetSpellInfo () -> Effects [ m_effIndex ]. ItemType , count , & noSpaceForCount );
2011-06-19 13:13:41 +02:00
if ( msg != EQUIP_ERR_OK )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
count -= noSpaceForCount ;
2011-07-26 23:09:28 +02:00
plCaster -> SendEquipError ( msg , NULL , NULL , GetSpellInfo () -> Effects [ m_effIndex ]. ItemType );
2011-06-19 13:13:41 +02:00
if ( count == 0 )
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
Item * newitem = plCaster -> StoreNewItem ( dest , GetSpellInfo () -> Effects [ m_effIndex ]. ItemType , true );
2011-06-19 13:13:41 +02:00
if ( ! newitem )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
plCaster -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
plCaster -> SendNewItem ( newitem , count , true , true );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleBindSight ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-01-28 20:41:03 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
2011-01-28 20:41:03 +01:00
return ;
2011-06-19 13:13:41 +02:00
caster -> ToPlayer () -> SetViewpoint ( target , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleForceReaction ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
Player * player = ( Player * ) target ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 faction_id = GetMiscValue ();
ReputationRank faction_rank = ReputationRank ( m_amount );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
player -> GetReputationMgr (). ApplyForceReaction ( faction_id , faction_rank , apply );
player -> GetReputationMgr (). SendForceReactions ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// stop fighting if at apply forced rank friendly or at remove real rank friendly
if (( apply && faction_rank >= REP_FRIENDLY ) || ( ! apply && player -> GetReputationRank ( faction_id ) >= REP_FRIENDLY ))
player -> StopAttackFaction ( faction_id );
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraEmpathy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_UNIT )
return ;
if ( ! apply )
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if ( target -> HasAuraType ( GetAuraType ()))
return ;
}
CreatureTemplate const * ci = sObjectMgr -> GetCreatureTemplate ( target -> GetEntry ());
if ( ci && ci -> type == CREATURE_TYPE_BEAST )
target -> ApplyModUInt32Value ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_SPECIALINFO , apply );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModFaction ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> setFaction ( GetMiscValue ());
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PVP_ATTACKABLE );
}
else
{
target -> RestoreFaction ();
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PVP_ATTACKABLE );
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleComprehendLanguage ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( apply )
2011-06-19 13:13:41 +02:00
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
2010-01-10 01:23:15 +01:00
else
{
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraConvertRune ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2011-06-29 13:09:32 +02:00
Player * plr = ( Player * ) target ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( plr -> getClass () != CLASS_DEATH_KNIGHT )
return ;
uint32 runes = m_amount ;
// convert number of runes specified in aura amount of rune type in miscvalue to runetype in miscvalueb
if ( apply )
{
for ( uint32 i = 0 ; i < MAX_RUNES && runes ; ++ i )
{
if ( GetMiscValue () != plr -> GetCurrentRune ( i ))
continue ;
if ( ! plr -> GetRuneCooldown ( i ))
{
plr -> AddRuneByAuraEffect ( i , RuneType ( GetMiscValueB ()), this );
-- runes ;
}
}
}
else
plr -> RemoveRunesByAuraEffect ( this );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraLinked ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
Unit * target = aurApp -> GetTarget ();
2011-07-26 23:09:28 +02:00
uint32 triggeredSpellId = m_spellInfo -> Effects [ m_effIndex ]. TriggerSpell ;
SpellInfo const * triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggeredSpellId );
if ( ! triggeredSpellInfo )
return ;
2011-06-19 13:13:41 +02:00
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
if ( apply )
{
2011-07-26 23:09:28 +02:00
Unit * caster = triggeredSpellInfo -> IsRequiringSelectedTarget () ? GetCaster () : target ;
2011-06-19 13:13:41 +02:00
if ( ! caster )
return ;
// If amount avalible cast with basepoints (Crypt Fever for example)
if ( GetAmount ())
caster -> CastCustomSpell ( target , triggeredSpellId , & m_amount , NULL , NULL , true , NULL , this );
else
caster -> CastSpell ( target , triggeredSpellId , true , NULL , this );
}
else
{
2011-07-26 23:09:28 +02:00
uint64 casterGUID = triggeredSpellInfo -> IsRequiringSelectedTarget () ? GetCasterGUID () : target -> GetGUID ();
2011-06-19 13:13:41 +02:00
target -> RemoveAura ( triggeredSpellId , casterGUID , 0 , aurApp -> GetRemoveMode ());
}
}
else if ( mode & AURA_EFFECT_HANDLE_REAPPLY && apply )
{
2011-07-26 23:09:28 +02:00
uint64 casterGUID = triggeredSpellInfo -> IsRequiringSelectedTarget () ? GetCasterGUID () : target -> GetGUID ();
2011-06-19 13:13:41 +02:00
// change the stack amount to be equal to stack amount of our aura
if ( Aura * triggeredAura = target -> GetAura ( triggeredSpellId , casterGUID ))
triggeredAura -> ModStackAmount ( GetBase () -> GetStackAmount () - triggeredAura -> GetStackAmount ());
}
}
void AuraEffect :: HandleAuraOpenStable ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER || ! target -> IsInWorld ())
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
if ( apply )
target -> ToPlayer () -> GetSession () -> SendStablePet ( target -> GetGUID ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// client auto close stable dialog at !apply aura
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraModFakeInebriation ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
target -> m_invisibilityDetect . AddFlag ( INVISIBILITY_DRUNK );
target -> m_invisibilityDetect . AddValue ( INVISIBILITY_DRUNK , GetAmount ());
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
int32 oldval = target -> ToPlayer () -> GetInt32Value ( PLAYER_FAKE_INEBRIATION );
target -> ToPlayer () -> SetInt32Value ( PLAYER_FAKE_INEBRIATION , oldval + GetAmount ());
}
}
else
{
bool removeDetect = ! target -> HasAuraType ( SPELL_AURA_MOD_FAKE_INEBRIATE );
target -> m_invisibilityDetect . AddValue ( INVISIBILITY_DRUNK , - GetAmount ());
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
int32 oldval = target -> ToPlayer () -> GetInt32Value ( PLAYER_FAKE_INEBRIATION );
target -> ToPlayer () -> SetInt32Value ( PLAYER_FAKE_INEBRIATION , oldval - GetAmount ());
if ( removeDetect )
removeDetect = ! target -> ToPlayer () -> GetDrunkValue ();
}
if ( removeDetect )
target -> m_invisibilityDetect . DelFlag ( INVISIBILITY_DRUNK );
}
// call functions which may have additional effects after chainging state of unit
target -> UpdateObjectVisibility ();
}
void AuraEffect :: HandleAuraOverrideSpells ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Player * target = aurApp -> GetTarget () -> ToPlayer ();
if ( ! target || ! target -> IsInWorld ())
return ;
uint32 overrideId = uint32 ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( apply )
2011-05-25 15:13:55 +02:00
{
2011-06-19 13:13:41 +02:00
target -> SetUInt16Value ( PLAYER_FIELD_BYTES2 , 0 , overrideId );
if ( OverrideSpellDataEntry const * overrideSpells = sOverrideSpellDataStore . LookupEntry ( overrideId ))
for ( uint8 i = 0 ; i < MAX_OVERRIDE_SPELL ; ++ i )
if ( uint32 spellId = overrideSpells -> spellId [ i ])
target -> AddTemporarySpell ( spellId );
2011-05-25 15:13:55 +02:00
}
2011-06-19 13:13:41 +02:00
else
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> SetUInt16Value ( PLAYER_FIELD_BYTES2 , 0 , 0 );
if ( OverrideSpellDataEntry const * overrideSpells = sOverrideSpellDataStore . LookupEntry ( overrideId ))
for ( uint8 i = 0 ; i < MAX_OVERRIDE_SPELL ; ++ i )
if ( uint32 spellId = overrideSpells -> spellId [ i ])
target -> RemoveTemporarySpell ( spellId );
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleAuraSetVehicle ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER || ! target -> IsInWorld ())
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 vehicleId = GetMiscValue ();
if ( apply )
{
if ( ! target -> CreateVehicleKit ( vehicleId , 0 ))
return ;
}
else if ( target -> GetVehicleKit ())
target -> RemoveVehicleKit ();
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
WorldPacket data ( SMSG_PLAYER_VEHICLE_DATA , target -> GetPackGUID (). size () + 4 );
data . appendPackGUID ( target -> GetGUID ());
data << uint32 ( apply ? vehicleId : 0 );
target -> SendMessageToSet ( & data , true );
2011-05-11 12:08:08 +02:00
2011-06-19 13:13:41 +02:00
if ( apply )
{
data . Initialize ( SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA , 0 );
target -> ToPlayer () -> GetSession () -> SendPacket ( & data );
}
}
void AuraEffect :: HandlePeriodicDummyAuraTick ( Unit * target , Unit * caster ) const
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2011-06-19 13:13:41 +02:00
{
case SPELLFAMILY_GENERIC :
switch ( GetId ())
{
case 54798 : // FLAMING Arrow Triggered Effect
{
if ( ! caster || ! target || ! target -> ToCreature () || ! caster -> IsVehicle () || target -> HasAura ( 54683 ))
break ;
if ( Unit * rider = caster -> GetVehicleKit () -> GetPassenger ( 0 ))
{
target -> CastSpell ( target , 54683 , true );
// Credit Frostworgs
if ( target -> GetEntry () == 29358 )
rider -> CastSpell ( rider , 54896 , true );
// Credit Frost Giants
else if ( target -> GetEntry () == 29351 )
rider -> CastSpell ( rider , 54893 , true );
2010-01-10 01:23:15 +01:00
}
break ;
2011-06-19 13:13:41 +02:00
}
case 62292 : // Blaze (Pool of Tar)
// should we use custom damage?
2011-07-26 23:09:28 +02:00
target -> CastSpell (( Unit * ) NULL , m_spellInfo -> Effects [ m_effIndex ]. TriggerSpell , true );
2011-06-19 13:13:41 +02:00
break ;
case 62399 : // Overload Circuit
if ( target -> GetMap () -> IsDungeon () && int ( target -> GetAppliedAuras (). count ( 62399 )) >= ( target -> GetMap () -> IsHeroic () ? 4 : 2 ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , 62475 , true ); // System Shutdown
2011-07-15 07:12:54 +07:00
if ( Unit * veh = target -> GetVehicleBase ())
2011-06-19 13:13:41 +02:00
veh -> CastSpell ( target , 62475 , true );
2010-01-10 01:23:15 +01:00
}
break ;
2011-06-19 13:13:41 +02:00
case 64821 : // Fuse Armor (Razorscale)
2011-07-26 23:09:28 +02:00
if ( GetBase () -> GetStackAmount () == GetSpellInfo () -> StackAmount )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , 64774 , true , NULL , NULL , GetCasterGUID ());
target -> RemoveAura ( 64821 );
2010-01-10 01:23:15 +01:00
}
break ;
2011-06-19 13:13:41 +02:00
}
break ;
case SPELLFAMILY_MAGE :
{
// Mirror Image
if ( GetId () == 55342 )
// Set name of summons to name of caster
2011-07-26 23:09:28 +02:00
target -> CastSpell (( Unit * ) NULL , m_spellInfo -> Effects [ m_effIndex ]. TriggerSpell , true );
2011-06-19 13:13:41 +02:00
break ;
}
case SPELLFAMILY_WARLOCK :
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> Id )
2011-06-19 13:13:41 +02:00
{
// Demonic Circle
case 48018 :
2011-07-26 23:09:28 +02:00
if ( GameObject * obj = target -> GetGameObject ( GetSpellInfo () -> Id ))
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( 48020 );
if ( target -> IsWithinDist ( obj , spellInfo -> GetMaxRange ( true )))
2010-07-28 12:57:00 +02:00
{
2011-06-19 13:13:41 +02:00
if ( ! target -> HasAura ( 62388 ))
target -> CastSpell ( target , 62388 , true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
else
target -> RemoveAura ( 62388 );
2010-01-10 01:23:15 +01:00
}
break ;
2011-06-19 13:13:41 +02:00
}
break ;
}
case SPELLFAMILY_DRUID :
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> Id )
2011-06-19 13:13:41 +02:00
{
// Frenzied Regeneration
case 22842 :
{
// Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
// Should be manauser
if ( target -> getPowerType () != POWER_RAGE )
break ;
uint32 rage = target -> GetPower ( POWER_RAGE );
// Nothing todo
if ( rage == 0 )
break ;
int32 mod = ( rage < 100 ) ? rage : 100 ;
2011-07-26 23:09:28 +02:00
int32 points = target -> CalculateSpellDamage ( target , GetSpellInfo (), 1 );
2011-06-19 13:13:41 +02:00
int32 regen = target -> GetMaxHealth () * ( mod * points / 10 ) / 1000 ;
target -> CastCustomSpell ( target , 22845 , & regen , 0 , 0 , true , 0 , this );
target -> SetPower ( POWER_RAGE , rage - mod );
break ;
}
}
break ;
}
case SPELLFAMILY_ROGUE :
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> Id )
2011-06-19 13:13:41 +02:00
{
// Master of Subtlety
case 31666 :
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
target -> RemoveAurasDueToSpell ( 31665 );
break ;
// Killing Spree
case 51690 :
{
// TODO: this should use effect[1] of 51690
UnitList targets ;
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// eff_radius == 0
2011-07-26 23:09:28 +02:00
float radius = GetSpellInfo () -> GetMaxRange ( false );
2011-06-19 13:13:41 +02:00
CellPair p ( Trinity :: ComputeCellPair ( target -> GetPositionX (), target -> GetPositionY ()));
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
2011-07-12 13:30:33 +02:00
Trinity :: AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck u_check ( target , radius );
2011-06-26 16:06:23 +03:00
Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck > checker ( target , targets , u_check );
2011-06-19 13:13:41 +02:00
2011-06-26 16:06:23 +03:00
TypeContainerVisitor < Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck > , GridTypeMapContainer > grid_object_checker ( checker );
TypeContainerVisitor < Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck > , WorldTypeMapContainer > world_object_checker ( checker );
2011-06-19 13:13:41 +02:00
cell . Visit ( p , grid_object_checker , * GetBase () -> GetOwner () -> GetMap (), * target , radius );
cell . Visit ( p , world_object_checker , * GetBase () -> GetOwner () -> GetMap (), * target , radius );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
if ( targets . empty ())
return ;
UnitList :: const_iterator itr = targets . begin ();
std :: advance ( itr , rand () % targets . size ());
Unit * spellTarget = * itr ;
target -> CastSpell ( spellTarget , 57840 , true );
target -> CastSpell ( spellTarget , 57841 , true );
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
}
// Overkill
case 58428 :
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
target -> RemoveAurasDueToSpell ( 58427 );
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
}
break ;
}
case SPELLFAMILY_HUNTER :
{
// Explosive Shot
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x80000000 )
2011-06-19 13:13:41 +02:00
{
if ( caster )
caster -> CastCustomSpell ( 53352 , SPELLVALUE_BASE_POINT0 , m_amount , target , true , NULL , this );
break ;
}
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> Id )
2011-06-19 13:13:41 +02:00
{
// Feeding Frenzy Rank 1
case 53511 :
if ( target -> getVictim () && target -> getVictim () -> HealthBelowPct ( 35 ))
target -> CastSpell ( target , 60096 , true , 0 , this );
return ;
// Feeding Frenzy Rank 2
case 53512 :
if ( target -> getVictim () && target -> getVictim () -> HealthBelowPct ( 35 ))
target -> CastSpell ( target , 60097 , true , 0 , this );
return ;
2010-01-10 01:23:15 +01:00
default :
break ;
}
2011-06-19 13:13:41 +02:00
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
case SPELLFAMILY_SHAMAN :
if ( GetId () == 52179 ) // Astral Shift
{
// Periodic need for remove visual on stun/fear/silence lost
if ( ! ( target -> GetUInt32Value ( UNIT_FIELD_FLAGS ) & ( UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED )))
target -> RemoveAurasDueToSpell ( 52179 );
break ;
}
break ;
case SPELLFAMILY_DEATHKNIGHT :
switch ( GetId ())
{
case 49016 : // Hysteria
uint32 damage = uint32 ( target -> CountPctFromMaxHealth ( 1 ));
target -> DealDamage ( target , damage , NULL , NODAMAGE , SPELL_SCHOOL_MASK_NORMAL , NULL , false );
break ;
}
// Death and Decay
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x20 )
2011-06-19 13:13:41 +02:00
{
if ( caster )
caster -> CastCustomSpell ( target , 52212 , & m_amount , NULL , NULL , true , 0 , this );
break ;
}
// Blood of the North
// Reaping
// Death Rune Mastery
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellIconID == 3041 || GetSpellInfo () -> SpellIconID == 22 || GetSpellInfo () -> SpellIconID == 2622 )
2011-06-19 13:13:41 +02:00
{
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( target -> ToPlayer () -> getClass () != CLASS_DEATH_KNIGHT )
return ;
// timer expired - remove death runes
target -> ToPlayer () -> RemoveRunesByAuraEffect ( this );
}
break ;
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
void AuraEffect :: HandlePeriodicTriggerSpellAuraTick ( Unit * target , Unit * caster ) const
{
// generic casting code with custom spells and target/caster customs
2011-07-26 23:09:28 +02:00
uint32 triggerSpellId = GetSpellInfo () -> Effects [ GetEffIndex ()]. TriggerSpell ;
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
SpellInfo const * triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggerSpellId );
SpellInfo const * auraSpellInfo = GetSpellInfo ();
2011-06-19 13:13:41 +02:00
uint32 auraId = auraSpellInfo -> Id ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// specific code for cases with no trigger spell provided in field
if ( triggeredSpellInfo == NULL )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
switch ( auraSpellInfo -> SpellFamilyName )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
case SPELLFAMILY_GENERIC :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
switch ( auraId )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Thaumaturgy Channel
case 9712 :
triggerSpellId = 21029 ;
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
// Brood Affliction: Bronze
case 23170 :
triggerSpellId = 23171 ;
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
// Restoration
case 24379 :
case 23493 :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( caster )
{
int32 heal = caster -> CountPctFromMaxHealth ( 10 );
caster -> HealBySpell ( target , auraSpellInfo , heal );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( int32 mana = caster -> GetMaxPower ( POWER_MANA ))
{
mana /= 10 ;
caster -> EnergizeBySpell ( caster , 23493 , mana , POWER_MANA );
}
}
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Nitrous Boost
case 27746 :
if ( caster && target -> GetPower ( POWER_MANA ) >= 10 )
{
target -> ModifyPower ( POWER_MANA , - 10 );
target -> SendEnergizeSpellLog ( caster , 27746 , 10 , POWER_MANA );
}
else
target -> RemoveAurasDueToSpell ( 27746 );
return ;
// Frost Blast
case 27808 :
if ( caster )
caster -> CastCustomSpell ( 29879 , SPELLVALUE_BASE_POINT0 , int32 ( target -> CountPctFromMaxHealth ( 21 )), target , true , NULL , this );
return ;
// Detonate Mana
case 27819 :
if ( int32 mana = ( int32 )( target -> GetMaxPower ( POWER_MANA ) / 10 ))
{
mana = target -> ModifyPower ( POWER_MANA , - mana );
target -> CastCustomSpell ( 27820 , SPELLVALUE_BASE_POINT0 , - mana * 10 , target , true , NULL , this );
}
return ;
// Inoculate Nestlewood Owlkin
case 29528 :
if ( target -> GetTypeId () != TYPEID_UNIT ) // prevent error reports in case ignored player target
return ;
2010-01-10 01:23:15 +01:00
break ;
2011-06-19 13:13:41 +02:00
// Feed Captured Animal
case 29917 :
triggerSpellId = 29916 ;
break ;
// Extract Gas
case 30427 :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// move loot to player inventory and despawn target
if ( caster && caster -> GetTypeId () == TYPEID_PLAYER &&
target -> GetTypeId () == TYPEID_UNIT &&
target -> ToCreature () -> GetCreatureInfo () -> type == CREATURE_TYPE_GAS_CLOUD )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
Player * player = caster -> ToPlayer ();
Creature * creature = target -> ToCreature ();
// missing lootid has been reported on startup - just return
if ( ! creature -> GetCreatureInfo () -> SkinLootId )
return ;
player -> AutoStoreLoot ( creature -> GetCreatureInfo () -> SkinLootId , LootTemplates_Skinning , true );
creature -> DespawnOrUnsummon ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Quake
case 30576 :
triggerSpellId = 30571 ;
break ;
// Doom
// TODO: effect trigger spell may be independant on spell targets, and executed in spell finish phase
// so instakill will be naturally done before trigger spell
case 31347 :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
target -> CastSpell ( target , 31350 , true , NULL , this );
target -> Kill ( target );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Spellcloth
case 31373 :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Summon Elemental after create item
target -> SummonCreature ( 17870 , 0 , 0 , 0 , target -> GetOrientation (), TEMPSUMMON_DEAD_DESPAWN , 0 );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Flame Quills
case 34229 :
2010-12-17 19:03:12 +01:00
{
2011-06-19 13:13:41 +02:00
// cast 24 spells 34269-34289, 34314-34316
for ( uint32 spell_id = 34269 ; spell_id != 34290 ; ++ spell_id )
target -> CastSpell ( target , spell_id , true , NULL , this );
for ( uint32 spell_id = 34314 ; spell_id != 34317 ; ++ spell_id )
target -> CastSpell ( target , spell_id , true , NULL , this );
return ;
2010-12-17 19:03:12 +01:00
}
2011-06-19 13:13:41 +02:00
// Remote Toy
2011-07-10 13:13:02 +02:00
case 37027 :
triggerSpellId = 37029 ;
break ;
2011-06-19 13:13:41 +02:00
// Eye of Grillok
case 38495 :
2011-07-10 13:13:02 +02:00
triggerSpellId = 38530 ;
break ;
2011-06-19 13:13:41 +02:00
// Absorb Eye of Grillok (Zezzak's Shard)
case 38554 :
{
if ( ! caster || target -> GetTypeId () != TYPEID_UNIT )
return ;
2010-04-07 18:09:10 +02:00
2011-06-19 13:13:41 +02:00
caster -> CastSpell ( caster , 38495 , true , NULL , this );
Creature * creatureTarget = target -> ToCreature ();
creatureTarget -> DespawnOrUnsummon ();
return ;
2010-02-15 18:46:41 +01:00
}
2011-06-19 13:13:41 +02:00
// Tear of Azzinoth Summon Channel - it's not really supposed to do anything, and this only prevents the console spam
case 39857 :
triggerSpellId = 39856 ;
break ;
// Personalized Weather
case 46736 :
triggerSpellId = 46737 ;
break ;
2010-02-15 18:46:41 +01:00
}
2011-06-19 13:13:41 +02:00
break ;
}
case SPELLFAMILY_SHAMAN :
{
switch ( auraId )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
case 28820 :
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Need remove self if Lightning Shield not active
if ( ! target -> GetAuraEffect ( SPELL_AURA_PROC_TRIGGER_SPELL , SPELLFAMILY_SHAMAN , 0x400 ))
target -> RemoveAurasDueToSpell ( 28820 );
return ;
}
// Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
case 38443 :
{
bool all = true ;
for ( int i = SUMMON_SLOT_TOTEM ; i < MAX_TOTEM_SLOT ; ++ i )
{
if ( ! target -> m_SummonSlot [ i ])
{
all = false ;
break ;
}
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( all )
target -> CastSpell ( target , 38437 , true , NULL , this );
else
target -> RemoveAurasDueToSpell ( 38437 );
return ;
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
else
{
// Spell exist but require custom code
switch ( auraId )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// Pursuing Spikes (Anub'arak)
case 65920 :
case 65922 :
case 65923 :
2011-06-29 13:09:32 +02:00
{
Unit * permafrostCaster = NULL ;
if ( Aura * permafrostAura = target -> GetAura ( 66193 ))
permafrostCaster = permafrostAura -> GetCaster ();
else if ( Aura * permafrostAura = target -> GetAura ( 67855 ))
permafrostCaster = permafrostAura -> GetCaster ();
else if ( Aura * permafrostAura = target -> GetAura ( 67856 ))
permafrostCaster = permafrostAura -> GetCaster ();
else if ( Aura * permafrostAura = target -> GetAura ( 67857 ))
permafrostCaster = permafrostAura -> GetCaster ();
if ( permafrostCaster )
2010-01-10 01:23:15 +01:00
{
2011-06-29 13:09:32 +02:00
if ( Creature * permafrostCasterCreature = permafrostCaster -> ToCreature ())
permafrostCasterCreature -> DespawnOrUnsummon ( 3000 );
2011-06-19 13:13:41 +02:00
2011-06-29 13:09:32 +02:00
target -> CastSpell ( target , 66181 , false );
target -> RemoveAllAuras ();
if ( Creature * targetCreature = target -> ToCreature ())
targetCreature -> DisappearAndDie ();
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
break ;
2011-06-29 13:09:32 +02:00
}
2011-06-19 13:13:41 +02:00
// Mana Tide
case 16191 :
target -> CastCustomSpell ( target , triggerSpellId , & m_amount , NULL , NULL , true , NULL , this );
return ;
// Negative Energy Periodic
case 46284 :
target -> CastCustomSpell ( triggerSpellId , SPELLVALUE_MAX_TARGETS , m_tickNumber / 10 + 1 , NULL , true , NULL , this );
return ;
// Poison (Grobbulus)
case 28158 :
case 54362 :
// Slime Pool (Dreadscale & Acidmaw)
case 66882 :
target -> CastCustomSpell ( triggerSpellId , SPELLVALUE_RADIUS_MOD , ( int32 )(((( float ) m_tickNumber / 60 ) * 0.9f + 0.1f ) * 10000 * 2 / 3 ), NULL , true , NULL , this );
return ;
// Beacon of Light
case 53563 :
{
// area aura owner casts the spell
GetBase () -> GetUnitOwner () -> CastSpell ( target , triggeredSpellInfo , true , 0 , this , GetBase () -> GetUnitOwner () -> GetGUID ());
return ;
}
// Slime Spray - temporary here until preventing default effect works again
// added on 9.10.2010
case 69508 :
{
if ( caster )
caster -> CastSpell ( target , triggerSpellId , true , NULL , NULL , caster -> GetGUID ());
2010-01-10 01:23:15 +01:00
return ;
}
2011-07-05 22:07:40 +01:00
case 24745 : // Summon Templar, Trigger
case 24747 : // Summon Templar Fire, Trigger
case 24757 : // Summon Templar Air, Trigger
case 24759 : // Summon Templar Earth, Trigger
case 24761 : // Summon Templar Water, Trigger
case 24762 : // Summon Duke, Trigger
case 24766 : // Summon Duke Fire, Trigger
case 24769 : // Summon Duke Air, Trigger
case 24771 : // Summon Duke Earth, Trigger
case 24773 : // Summon Duke Water, Trigger
case 24785 : // Summon Royal, Trigger
case 24787 : // Summon Royal Fire, Trigger
case 24791 : // Summon Royal Air, Trigger
case 24792 : // Summon Royal Earth, Trigger
case 24793 : // Summon Royal Water, Trigger
{
// All this spells trigger a spell that requires reagents; if the
// triggered spell is cast as "triggered", reagents are not consumed
if ( caster )
caster -> CastSpell ( target , triggerSpellId , false );
return ;
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
}
// Reget trigger spell proto
2011-07-26 23:09:28 +02:00
triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggerSpellId );
2011-06-29 13:09:32 +02:00
if ( triggeredSpellInfo )
2011-06-19 13:13:41 +02:00
{
2011-07-26 23:09:28 +02:00
if ( Unit * triggerCaster = triggeredSpellInfo -> IsRequiringSelectedTarget () ? caster : target )
2011-06-19 13:13:41 +02:00
{
triggerCaster -> CastSpell ( target , triggeredSpellInfo , true , NULL , this );
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u" , GetId (), triggeredSpellInfo -> Id );
}
}
else
{
Creature * c = target -> ToCreature ();
2011-07-30 15:26:42 +02:00
if ( ! c || ! caster || ! sScriptMgr -> OnDummyEffect ( caster , GetId (), SpellEffIndex ( GetEffIndex ()), target -> ToCreature ()) ||
2011-06-20 04:04:20 +07:00
! c -> AI () -> sOnDummyEffect ( caster , GetId (), SpellEffIndex ( GetEffIndex ())))
2011-06-19 13:13:41 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered." , GetId (), triggerSpellId , GetEffIndex ());
2010-01-10 01:23:15 +01:00
}
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicTriggerSpellWithValueAuraTick ( Unit * target , Unit * caster ) const
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
uint32 triggerSpellId = GetSpellInfo () -> Effects [ m_effIndex ]. TriggerSpell ;
if ( SpellInfo const * triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggerSpellId ))
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
if ( Unit * triggerCaster = triggeredSpellInfo -> IsRequiringSelectedTarget () ? caster : target )
2011-06-19 13:13:41 +02:00
{
int32 basepoints0 = GetAmount ();
triggerCaster -> CastCustomSpell ( target , triggerSpellId , & basepoints0 , 0 , 0 , true , 0 , this );
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u" , GetId (), triggeredSpellInfo -> Id );
}
}
else
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered." , GetId (), triggerSpellId , GetEffIndex ());
}
2010-03-21 16:03:38 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicDamageAurasTick ( Unit * target , Unit * caster ) const
{
if ( ! caster || ! target -> isAlive ())
return ;
2010-03-15 02:59:21 +01:00
2011-07-26 23:09:28 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ) || target -> IsImmunedToDamage ( GetSpellInfo ()))
2011-06-19 13:13:41 +02:00
{
SendTickImmune ( target , caster );
return ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// Consecrate ticks can miss and will not show up in the combat log
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ GetEffIndex ()]. Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster -> SpellHitResult ( target , GetSpellInfo (), false ) != SPELL_MISS_NONE )
2011-06-19 13:13:41 +02:00
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// some auras remove at specific health level or more
if ( GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> Id )
2010-03-21 16:03:38 +01:00
{
2011-06-19 13:13:41 +02:00
case 43093 : case 31956 : case 38801 : // Grievous Wound
case 35321 : case 38363 : case 39215 : // Gushing Wound
if ( target -> IsFullHealth ())
{
2011-07-26 23:09:28 +02:00
target -> RemoveAurasDueToSpell ( GetSpellInfo () -> Id );
2011-06-19 13:13:41 +02:00
return ;
}
break ;
case 38772 : // Grievous Wound
2010-03-21 16:03:38 +01:00
{
2011-07-26 23:09:28 +02:00
uint32 percent = GetSpellInfo () -> Effects [ EFFECT_1 ]. CalcValue ( caster );
2011-06-19 13:13:41 +02:00
if ( ! target -> HealthBelowPct ( percent ))
{
2011-07-26 23:09:28 +02:00
target -> RemoveAurasDueToSpell ( GetSpellInfo () -> Id );
2011-06-19 13:13:41 +02:00
return ;
}
break ;
2010-03-21 16:03:38 +01:00
}
}
2011-06-19 13:13:41 +02:00
}
2010-03-15 02:59:21 +01:00
2011-06-19 13:13:41 +02:00
uint32 absorb = 0 ;
uint32 resist = 0 ;
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2010-04-07 18:09:10 +02:00
2011-06-19 13:13:41 +02:00
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = std :: max ( GetAmount (), 0 );
if ( GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
{
2011-07-26 23:09:28 +02:00
damage = caster -> SpellDamageBonus ( target , GetSpellInfo (), damage , DOT , GetBase () -> GetStackAmount ());
2011-06-19 13:13:41 +02:00
// Calculate armor mitigation
2011-07-26 23:09:28 +02:00
if ( Unit :: IsDamageReducedByArmor ( GetSpellInfo () -> GetSchoolMask (), GetSpellInfo (), GetEffIndex ()))
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
uint32 damageReductedArmor = caster -> CalcArmorReducedDamage ( target , damage , GetSpellInfo ());
2011-06-19 13:13:41 +02:00
cleanDamage . mitigated_damage += damage - damageReductedArmor ;
damage = damageReductedArmor ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// Curse of Agony damage-per-tick calculation
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x400 ) && GetSpellInfo () -> SpellIconID == 544 )
2010-03-21 16:03:38 +01:00
{
2011-06-19 13:13:41 +02:00
uint32 totalTick = GetTotalTicks ();
// 1..4 ticks, 1/2 from normal tick damage
if ( m_tickNumber <= totalTick / 3 )
damage = damage / 2 ;
// 9..12 ticks, 3/2 from normal tick damage
else if ( m_tickNumber > totalTick * 2 / 3 )
damage += ( damage + 1 ) / 2 ; // +1 prevent 0.5 damage possible lost at 1..4 ticks
// 5..8 ticks have normal tick damage
}
// There is a Chance to make a Soul Shard when Drain soul does damage
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00004000 ))
2011-06-19 13:13:41 +02:00
{
if ( caster -> GetTypeId () == TYPEID_PLAYER && caster -> ToPlayer () -> isHonorOrXPTarget ( target ))
{
if ( roll_chance_i ( 20 ))
{
caster -> CastSpell ( caster , 43836 , true , 0 , this );
// Glyph of Drain Soul - chance to create an additional Soul Shard
2011-07-15 07:12:54 +07:00
if ( AuraEffect * aur = caster -> GetAuraEffect ( 58070 , 0 ))
2011-06-19 13:13:41 +02:00
if ( roll_chance_i ( aur -> GetMiscValue ()))
caster -> CastSpell ( caster , 58068 , true , 0 , aur );
}
}
}
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_GENERIC )
2011-06-19 13:13:41 +02:00
{
switch ( GetId ())
{
case 70911 : // Unbound Plague
case 72854 : // Unbound Plague
case 72855 : // Unbound Plague
case 72856 : // Unbound Plague
damage *= uint32 ( pow ( 1.25f , int32 ( m_tickNumber )));
break ;
default :
break ;
}
2010-03-21 16:03:38 +01:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
else
damage = uint32 ( target -> CountPctFromMaxHealth ( damage ));
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
2011-07-26 23:09:28 +02:00
damage = caster -> SpellCriticalDamageBonus ( m_spellInfo , damage , target );
2011-06-19 13:13:41 +02:00
int32 dmg = damage ;
caster -> ApplyResilience ( target , NULL , & dmg , crit , CR_CRIT_TAKEN_SPELL );
damage = dmg ;
2011-07-26 23:09:28 +02:00
caster -> CalcAbsorbResist ( target , GetSpellInfo () -> GetSchoolMask (), DOT , damage , & absorb , & resist , GetSpellInfo ());
2011-06-19 13:13:41 +02:00
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), damage , GetId (), absorb );
caster -> DealDamageMods ( target , damage , & absorb );
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC ;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC ;
uint32 procEx = ( crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT ) | PROC_EX_INTERNAL_DOT ;
damage = ( damage <= absorb + resist ) ? 0 : ( damage - absorb - resist );
if ( damage )
procVictim |= PROC_FLAG_TAKEN_DAMAGE ;
int32 overkill = damage - target -> GetHealth ();
if ( overkill < 0 )
overkill = 0 ;
SpellPeriodicAuraLogInfo pInfo ( this , damage , overkill , absorb , resist , 0.0f , crit );
target -> SendPeriodicAuraLog ( & pInfo );
2011-07-26 23:09:28 +02:00
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellInfo ());
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
caster -> DealDamage ( target , damage , & cleanDamage , DOT , GetSpellInfo () -> GetSchoolMask (), GetSpellInfo (), true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicHealthLeechAuraTick ( Unit * target , Unit * caster ) const
{
if ( ! caster || ! caster -> isAlive () || ! target -> isAlive ())
return ;
2011-07-26 23:09:28 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ) || target -> IsImmunedToDamage ( GetSpellInfo ()))
2011-06-19 13:13:41 +02:00
{
SendTickImmune ( target , caster );
return ;
}
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ GetEffIndex ()]. Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster -> SpellHitResult ( target , GetSpellInfo (), false ) != SPELL_MISS_NONE )
2011-06-19 13:13:41 +02:00
return ;
uint32 absorb = 0 ;
uint32 resist = 0 ;
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
uint32 damage = std :: max ( GetAmount (), 0 );
2011-07-26 23:09:28 +02:00
damage = caster -> SpellDamageBonus ( target , GetSpellInfo (), damage , DOT , GetBase () -> GetStackAmount ());
2011-06-19 13:13:41 +02:00
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
2011-07-26 23:09:28 +02:00
damage = caster -> SpellCriticalDamageBonus ( m_spellInfo , damage , target );
2011-06-19 13:13:41 +02:00
// Calculate armor mitigation
2011-07-26 23:09:28 +02:00
if ( Unit :: IsDamageReducedByArmor ( GetSpellInfo () -> GetSchoolMask (), GetSpellInfo (), m_effIndex ))
2011-06-19 13:13:41 +02:00
{
2011-07-26 23:09:28 +02:00
uint32 damageReductedArmor = caster -> CalcArmorReducedDamage ( target , damage , GetSpellInfo ());
2011-06-19 13:13:41 +02:00
cleanDamage . mitigated_damage += damage - damageReductedArmor ;
damage = damageReductedArmor ;
}
int32 dmg = damage ;
caster -> ApplyResilience ( target , NULL , & dmg , crit , CR_CRIT_TAKEN_SPELL );
damage = dmg ;
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
caster -> CalcAbsorbResist ( target , GetSpellInfo () -> GetSchoolMask (), DOT , damage , & absorb , & resist , m_spellInfo );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetHealth () < damage )
damage = uint32 ( target -> GetHealth ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), damage , GetId (), absorb );
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
caster -> SendSpellNonMeleeDamageLog ( target , GetId (), damage , GetSpellInfo () -> GetSchoolMask (), absorb , resist , false , 0 , crit );
2011-06-19 13:13:41 +02:00
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC ;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC ;
uint32 procEx = ( crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT ) | PROC_EX_INTERNAL_DOT ;
damage = ( damage <= absorb + resist ) ? 0 : ( damage - absorb - resist );
if ( damage )
procVictim |= PROC_FLAG_TAKEN_DAMAGE ;
2011-07-26 23:09:28 +02:00
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellInfo ());
int32 new_damage = caster -> DealDamage ( target , damage , & cleanDamage , DOT , GetSpellInfo () -> GetSchoolMask (), GetSpellInfo (), false );
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
float gainMultiplier = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcValueMultiplier ( caster );
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
uint32 heal = uint32 ( caster -> SpellHealingBonus ( caster , GetSpellInfo (), uint32 ( new_damage * gainMultiplier ), DOT , GetBase () -> GetStackAmount ()));
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
int32 gain = caster -> HealBySpell ( caster , GetSpellInfo (), heal );
caster -> getHostileRefManager (). threatAssist ( caster , gain * 0.5f , GetSpellInfo ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicHealthFunnelAuraTick ( Unit * target , Unit * caster ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! caster || ! caster -> isAlive () || ! target -> isAlive ())
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ))
{
SendTickImmune ( target , caster );
return ;
}
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 damage = std :: max ( GetAmount (), 0 );
// do not kill health donator
if ( caster -> GetHealth () < damage )
damage = caster -> GetHealth () - 1 ;
if ( ! damage )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
caster -> ModifyHealth ( - ( int32 ) damage );
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "PeriodicTick: donator %u target %u damage %u." , caster -> GetEntry (), target -> GetEntry (), damage );
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
float gainMultiplier = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcValueMultiplier ( caster );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
damage = int32 ( damage * gainMultiplier );
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
caster -> HealBySpell ( target , GetSpellInfo (), damage );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicHealAurasTick ( Unit * target , Unit * caster ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
if ( ! caster || ! target -> isAlive ())
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ))
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
SendTickImmune ( target , caster );
return ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
// heal for caster damage (must be alive)
2011-07-26 23:09:28 +02:00
if ( target != caster && GetSpellInfo () -> AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL && ! caster -> isAlive ())
2011-06-19 13:13:41 +02:00
return ;
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// don't regen when permanent aura target has full power
if ( GetBase () -> IsPermanent () && target -> IsFullHealth ())
2010-01-13 18:22:31 +01:00
return ;
2011-06-19 13:13:41 +02:00
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = std :: max ( m_amount , 0 );
2010-01-13 18:22:31 +01:00
2011-06-19 13:13:41 +02:00
if ( GetAuraType () == SPELL_AURA_OBS_MOD_HEALTH )
2010-01-13 18:22:31 +01:00
{
2011-06-19 13:13:41 +02:00
// Taken mods
float TakenTotalMod = 1.0f ;
// Tenacity increase healing % taken
if ( AuraEffect const * Tenacity = target -> GetAuraEffect ( 58549 , 0 ))
AddPctN ( TakenTotalMod , Tenacity -> GetAmount ());
// Healing taken percent
float minval = ( float ) target -> GetMaxNegativeAuraModifier ( SPELL_AURA_MOD_HEALING_PCT );
if ( minval )
AddPctF ( TakenTotalMod , minval );
float maxval = ( float ) target -> GetMaxPositiveAuraModifier ( SPELL_AURA_MOD_HEALING_PCT );
if ( maxval )
AddPctF ( TakenTotalMod , maxval );
// Healing over time taken percent
float minval_hot = ( float ) target -> GetMaxNegativeAuraModifier ( SPELL_AURA_MOD_HOT_PCT );
if ( minval_hot )
AddPctF ( TakenTotalMod , minval_hot );
float maxval_hot = ( float ) target -> GetMaxPositiveAuraModifier ( SPELL_AURA_MOD_HOT_PCT );
if ( maxval_hot )
AddPctF ( TakenTotalMod , maxval_hot );
TakenTotalMod = std :: max ( TakenTotalMod , 0.0f );
damage = uint32 ( target -> CountPctFromMaxHealth ( damage ));
damage = uint32 ( damage * TakenTotalMod );
2010-01-13 18:22:31 +01:00
}
else
{
2011-06-19 13:13:41 +02:00
// Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo -> SpellIconID == 2864 )
2011-06-19 13:13:41 +02:00
{
int32 addition = int32 ( float ( damage * GetTotalTicks ()) * (( 6 - float ( 2 * ( GetTickNumber () - 1 ))) / 100 ));
// Item - Druid T10 Restoration 2P Bonus
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( 70658 , 0 ))
// divided by 50 instead of 100 because calculated as for every 2 tick
addition += abs ( int32 (( addition * aurEff -> GetAmount ()) / 50 ));
damage += addition ;
}
2011-07-26 23:09:28 +02:00
damage = caster -> SpellHealingBonus ( target , GetSpellInfo (), damage , DOT , GetBase () -> GetStackAmount ());
2010-01-13 18:22:31 +01:00
}
2010-01-13 10:45:34 +01:00
2011-06-19 13:13:41 +02:00
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
2011-07-26 23:09:28 +02:00
damage = caster -> SpellCriticalHealingBonus ( m_spellInfo , damage , target );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), damage , GetId ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
uint32 absorb = 0 ;
uint32 heal = uint32 ( damage );
2011-07-26 23:09:28 +02:00
caster -> CalcHealAbsorb ( target , GetSpellInfo (), heal , absorb );
2011-06-19 13:13:41 +02:00
int32 gain = caster -> DealHeal ( target , heal );
SpellPeriodicAuraLogInfo pInfo ( this , damage , damage - gain , absorb , 0 , 0.0f , crit );
target -> SendPeriodicAuraLog ( & pInfo );
2011-07-26 23:09:28 +02:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellInfo ());
2011-06-19 13:13:41 +02:00
bool haveCastItem = GetBase () -> GetCastItemGUID () != 0 ;
// Health Funnel
// damage caster for heal amount
2011-07-26 23:09:28 +02:00
if ( target != caster && GetSpellInfo () -> AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
uint32 damage = GetSpellInfo () -> Effects [ EFFECT_0 ]. CalcValue (); // damage is not affected by spell power
2011-06-19 13:13:41 +02:00
if (( int32 ) damage > gain )
damage = gain ;
uint32 absorb = 0 ;
caster -> DealDamageMods ( caster , damage , & absorb );
2011-07-26 23:09:28 +02:00
caster -> SendSpellNonMeleeDamageLog ( caster , GetId (), damage , GetSpellInfo () -> GetSchoolMask (), absorb , 0 , false , 0 , false );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2011-07-26 23:09:28 +02:00
caster -> DealDamage ( caster , damage , & cleanDamage , NODAMAGE , GetSpellInfo () -> GetSchoolMask (), GetSpellInfo (), true );
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC ;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC ;
uint32 procEx = ( crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT ) | PROC_EX_INTERNAL_HOT ;
// ignore item heals
if ( ! haveCastItem )
2011-07-26 23:09:28 +02:00
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellInfo ());
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicManaLeechAuraTick ( Unit * target , Unit * caster ) const
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
Powers powerType = Powers ( GetMiscValue ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( ! caster || ! caster -> isAlive () || ! target -> isAlive () || target -> getPowerType () != powerType )
2010-01-10 01:23:15 +01:00
return ;
2011-07-26 23:09:28 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ) || target -> IsImmunedToDamage ( GetSpellInfo ()))
2011-06-19 13:13:41 +02:00
{
SendTickImmune ( target , caster );
return ;
}
2010-01-10 01:23:15 +01:00
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ GetEffIndex ()]. Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster -> SpellHitResult ( target , GetSpellInfo (), false ) != SPELL_MISS_NONE )
2010-01-10 01:23:15 +01:00
return ;
2011-06-19 13:13:41 +02:00
// ignore negative values (can be result apply spellmods to aura damage
int32 drainAmount = std :: max ( m_amount , 0 );
// Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
// It's mana percent cost spells, m_amount is percent drain from target
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> ManaCostPercentage )
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
// max value
int32 maxmana = CalculatePctF ( caster -> GetMaxPower ( powerType ), drainAmount * 2.0f );
ApplyPctU ( drainAmount , target -> GetMaxPower ( powerType ));
if ( drainAmount > maxmana )
drainAmount = maxmana ;
2010-01-10 01:23:15 +01:00
}
2011-06-19 13:13:41 +02:00
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), drainAmount , GetId ());
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( powerType == POWER_MANA )
drainAmount -= target -> GetSpellCritDamageReduction ( drainAmount );
2011-05-29 15:46:14 +02:00
2011-06-23 15:51:14 +02:00
int32 drainedAmount = - target -> ModifyPower ( powerType , - drainAmount );
2011-06-19 13:13:41 +02:00
2011-07-26 23:09:28 +02:00
float gainMultiplier = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcValueMultiplier ( caster );
2011-06-19 13:13:41 +02:00
SpellPeriodicAuraLogInfo pInfo ( this , drainedAmount , 0 , 0 , 0 , gainMultiplier , false );
target -> SendPeriodicAuraLog ( & pInfo );
2011-06-29 15:43:48 +03:00
int32 gainAmount = int32 ( drainedAmount * gainMultiplier );
2011-06-29 16:49:55 +03:00
int32 gainedAmount = 0 ;
if ( gainAmount )
{
gainedAmount = caster -> ModifyPower ( powerType , gainAmount );
2011-07-26 23:09:28 +02:00
target -> AddThreat ( caster , float ( gainedAmount ) * 0.5f , GetSpellInfo () -> GetSchoolMask (), GetSpellInfo ());
2011-06-29 16:49:55 +03:00
}
2011-06-19 13:13:41 +02:00
// spell-specific code
switch ( GetId ())
2010-01-10 01:23:15 +01:00
{
2011-06-19 13:13:41 +02:00
case 31447 : // Mark of Kaz'rogal
if ( target -> GetPower ( powerType ) == 0 )
{
target -> CastSpell ( target , 31463 , true , 0 , this );
// Remove aura
GetBase () -> SetDuration ( 0 );
}
break ;
case 32960 : // Mark of Kazzak
2011-05-29 15:46:14 +02:00
{
2011-06-19 13:13:41 +02:00
int32 modifier = int32 ( target -> GetPower ( powerType ) * 0.05f );
target -> ModifyPower ( powerType , - modifier );
2010-01-10 01:23:15 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> GetPower ( powerType ) == 0 )
{
target -> CastSpell ( target , 32961 , true , 0 , this );
// Remove aura
GetBase () -> SetDuration ( 0 );
}
break ;
2011-05-29 15:46:14 +02:00
}
2011-06-19 13:13:41 +02:00
default :
break ;
2011-05-29 15:46:14 +02:00
}
2011-06-19 13:13:41 +02:00
// Drain Mana
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_WARLOCK
&& m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00000010 )
2011-05-29 15:46:14 +02:00
{
2011-06-19 13:13:41 +02:00
int32 manaFeedVal = 0 ;
if ( AuraEffect const * aurEff = GetBase () -> GetEffect ( 1 ))
manaFeedVal = aurEff -> GetAmount ();
// Mana Feed - Drain Mana
if ( manaFeedVal > 0 )
{
int32 feedAmount = CalculatePctN ( gainedAmount , manaFeedVal );
caster -> CastCustomSpell ( caster , 32554 , & feedAmount , NULL , NULL , true , NULL , this );
}
2010-01-10 01:23:15 +01:00
}
}
2010-07-22 03:12:28 +02:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandleObsModPowerAuraTick ( Unit * target , Unit * caster ) const
2010-07-22 03:12:28 +02:00
{
2011-06-19 13:13:41 +02:00
Powers powerType ;
if ( GetMiscValue () == POWER_ALL )
powerType = target -> getPowerType ();
else
powerType = Powers ( GetMiscValue ());
2011-06-29 13:09:32 +02:00
if ( ! target -> isAlive () || ! target -> GetMaxPower ( powerType ))
2010-07-22 03:12:28 +02:00
return ;
2011-06-19 13:13:41 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ))
{
SendTickImmune ( target , caster );
return ;
}
2010-07-22 03:12:28 +02:00
2011-06-19 13:13:41 +02:00
// don't regen when permanent aura target has full power
if ( GetBase () -> IsPermanent () && target -> GetPower ( powerType ) == target -> GetMaxPower ( powerType ))
2010-07-22 03:12:28 +02:00
return ;
2011-06-19 13:13:41 +02:00
// ignore negative values (can be result apply spellmods to aura damage
uint32 amount = std :: max ( m_amount , 0 ) * target -> GetMaxPower ( powerType ) / 100 ;
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), amount , GetId ());
2010-07-22 03:12:28 +02:00
2011-06-19 13:13:41 +02:00
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f , false );
target -> SendPeriodicAuraLog ( & pInfo );
int32 gain = target -> ModifyPower ( powerType , amount );
if ( caster )
2011-07-26 23:09:28 +02:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellInfo ());
2010-07-22 03:12:28 +02:00
}
2010-11-10 12:18:43 +01:00
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicEnergizeAuraTick ( Unit * target , Unit * caster ) const
2010-11-13 17:18:09 +01:00
{
2011-06-19 13:13:41 +02:00
Powers powerType = Powers ( GetMiscValue ());
2010-11-13 17:18:09 +01:00
2011-06-29 13:09:32 +02:00
if ( ! target -> isAlive () || ! target -> GetMaxPower ( powerType ))
2011-06-19 13:13:41 +02:00
return ;
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ))
2010-11-13 17:18:09 +01:00
{
2011-06-19 13:13:41 +02:00
SendTickImmune ( target , caster );
return ;
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
// don't regen when permanent aura target has full power
if ( GetBase () -> IsPermanent () && target -> GetPower ( powerType ) == target -> GetMaxPower ( powerType ))
return ;
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
// ignore negative values (can be result apply spellmods to aura damage
int32 amount = std :: max ( m_amount , 0 );
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f , false );
target -> SendPeriodicAuraLog ( & pInfo );
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
sLog -> outDetail ( "PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), target -> GetGUIDLow (), target -> GetTypeId (), amount , GetId ());
2010-11-13 17:18:09 +01:00
2011-06-19 13:13:41 +02:00
int32 gain = target -> ModifyPower ( powerType , amount );
if ( caster )
2011-07-26 23:09:28 +02:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellInfo ());
2010-11-13 17:18:09 +01:00
}
2011-06-19 13:13:41 +02:00
void AuraEffect :: HandlePeriodicPowerBurnManaAuraTick ( Unit * target , Unit * caster ) const
2010-11-30 21:32:00 +01:00
{
2011-06-19 13:13:41 +02:00
Powers powerType = Powers ( GetMiscValue ());
2010-11-30 21:32:00 +01:00
2011-06-19 13:13:41 +02:00
if ( ! caster || ! target -> isAlive () || target -> getPowerType () != powerType )
2010-11-30 21:32:00 +01:00
return ;
2011-07-26 23:09:28 +02:00
if ( target -> HasUnitState ( UNIT_STAT_ISOLATED ) || target -> IsImmunedToDamage ( GetSpellInfo ()))
2010-11-30 21:32:00 +01:00
{
2011-06-19 13:13:41 +02:00
SendTickImmune ( target , caster );
return ;
2010-11-30 21:32:00 +01:00
}
2011-06-19 13:13:41 +02:00
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = std :: max ( m_amount , 0 );
2010-11-10 12:18:43 +01:00
2011-06-19 13:13:41 +02:00
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( powerType == POWER_MANA )
damage -= target -> GetSpellCritDamageReduction ( damage );
2010-11-10 12:18:43 +01:00
2011-06-19 13:13:41 +02:00
uint32 gain = uint32 ( - target -> ModifyPower ( powerType , - damage ));
2010-11-10 12:18:43 +01:00
2011-07-26 23:09:28 +02:00
float dmgMultiplier = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcValueMultiplier ( caster );
2010-11-10 12:18:43 +01:00
2011-07-26 23:09:28 +02:00
SpellInfo const * spellProto = GetSpellInfo ();
2011-06-19 13:13:41 +02:00
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
SpellNonMeleeDamage damageInfo ( caster , target , spellProto -> Id , spellProto -> SchoolMask );
// no SpellDamageBonus for burn mana
caster -> CalculateSpellDamageTaken ( & damageInfo , int32 ( gain * dmgMultiplier ), spellProto );
2010-11-10 12:18:43 +01:00
2011-06-19 13:13:41 +02:00
caster -> DealDamageMods ( damageInfo . target , damageInfo . damage , & damageInfo . absorb );
2010-11-10 12:18:43 +01:00
2011-06-19 13:13:41 +02:00
caster -> SendSpellNonMeleeDamageLog ( & damageInfo );
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC ;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC ;
uint32 procEx = createProcExtendMask ( & damageInfo , SPELL_MISS_NONE ) | PROC_EX_INTERNAL_DOT ;
if ( damageInfo . damage )
procVictim |= PROC_FLAG_TAKEN_DAMAGE ;
caster -> ProcDamageAndSpell ( damageInfo . target , procAttacker , procVictim , procEx , damageInfo . damage , BASE_ATTACK , spellProto );
caster -> DealSpellDamage ( & damageInfo , true );
2010-11-10 12:18:43 +01:00
}
2011-07-10 13:13:02 +02:00
void AuraEffect :: HandleProcTriggerSpellAuraProc ( AuraApplication * aurApp , ProcEventInfo & eventInfo )
{
Unit * triggerCaster = aurApp -> GetTarget ();
Unit * triggerTarget = eventInfo . GetProcTarget ();
2011-07-26 23:09:28 +02:00
uint32 triggerSpellId = GetSpellInfo () -> Effects [ GetEffIndex ()]. TriggerSpell ;
if ( SpellInfo const * triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggerSpellId ))
2011-07-10 13:13:02 +02:00
{
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc" , triggeredSpellInfo -> Id , GetId ());
triggerCaster -> CastSpell ( triggerTarget , triggeredSpellInfo , true , NULL , this );
}
else
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleProcTriggerSpellAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc." , triggerSpellId , GetId ());
}
void AuraEffect :: HandleProcTriggerSpellWithValueAuraProc ( AuraApplication * aurApp , ProcEventInfo & eventInfo )
{
Unit * triggerCaster = aurApp -> GetTarget ();
Unit * triggerTarget = eventInfo . GetProcTarget ();
2011-07-26 23:09:28 +02:00
uint32 triggerSpellId = GetSpellInfo () -> Effects [ m_effIndex ]. TriggerSpell ;
if ( SpellInfo const * triggeredSpellInfo = sSpellMgr -> GetSpellInfo ( triggerSpellId ))
2011-07-10 13:13:02 +02:00
{
int32 basepoints0 = GetAmount ();
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Triggering spell %u with value %d from aura %u proc" , triggeredSpellInfo -> Id , basepoints0 , GetId ());
triggerCaster -> CastCustomSpell ( triggerTarget , triggerSpellId , & basepoints0 , NULL , NULL , true , NULL , this );
}
else
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc." , triggerSpellId , GetId ());
}
void AuraEffect :: HandleProcTriggerDamageAuraProc ( AuraApplication * aurApp , ProcEventInfo & eventInfo )
{
Unit * target = aurApp -> GetTarget ();
Unit * triggerTarget = eventInfo . GetProcTarget ();
2011-07-26 23:09:28 +02:00
SpellNonMeleeDamage damageInfo ( target , triggerTarget , GetId (), GetSpellInfo () -> SchoolMask );
uint32 damage = target -> SpellDamageBonus ( triggerTarget , GetSpellInfo (), GetAmount (), SPELL_DIRECT_DAMAGE );
target -> CalculateSpellDamageTaken ( & damageInfo , damage , GetSpellInfo ());
2011-07-10 13:13:02 +02:00
target -> DealDamageMods ( damageInfo . target , damageInfo . damage , & damageInfo . absorb );
target -> SendSpellNonMeleeDamageLog ( & damageInfo );
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleProcTriggerDamageAuraProc: Triggering %u spell damage from aura %u proc" , damage , GetId ());
target -> DealSpellDamage ( & damageInfo , true );
}
void AuraEffect :: HandleRaidProcFromChargeAuraProc ( AuraApplication * aurApp , ProcEventInfo & /*eventInfo*/ )
{
Unit * target = aurApp -> GetTarget ();
uint32 triggerSpellId ;
switch ( GetId ())
{
case 57949 : // Shiver
triggerSpellId = 57952 ;
//animationSpellId = 57951; dummy effects for jump spell have unknown use (see also 41637)
break ;
case 59978 : // Shiver
triggerSpellId = 59979 ;
break ;
case 43593 : // Cold Stare
triggerSpellId = 43594 ;
break ;
default :
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleRaidProcFromChargeAuraProc: received not handled spell: %u" , GetId ());
return ;
}
int32 jumps = GetBase () -> GetCharges ();
// current aura expire on proc finish
GetBase () -> SetCharges ( 0 );
GetBase () -> SetUsingCharges ( true );
// next target selection
if ( jumps > 0 )
{
2011-07-26 23:09:28 +02:00
if ( Unit * caster = GetCaster ())
2011-07-10 13:13:02 +02:00
{
2011-07-26 23:09:28 +02:00
float radius = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcRadius ( caster );
2011-07-10 13:13:02 +02:00
if ( Unit * triggerTarget = target -> GetNextRandomRaidMemberOrPet ( radius ))
{
2011-07-26 23:09:28 +02:00
target -> CastSpell ( triggerTarget , GetSpellInfo (), true , NULL , this , GetCasterGUID ());
2011-07-10 13:13:02 +02:00
if ( Aura * aura = triggerTarget -> GetAura ( GetId (), GetCasterGUID ()))
aura -> SetCharges ( jumps );
}
}
}
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleRaidProcFromChargeAuraProc: Triggering spell %u from aura %u proc" , triggerSpellId , GetId ());
target -> CastSpell ( target , triggerSpellId , true , NULL , this , GetCasterGUID ());
}
void AuraEffect :: HandleRaidProcFromChargeWithValueAuraProc ( AuraApplication * aurApp , ProcEventInfo & /*eventInfo*/ )
{
Unit * target = aurApp -> GetTarget ();
// Currently only Prayer of Mending
2011-07-26 23:09:28 +02:00
if ( ! ( GetSpellInfo () -> SpellFamilyName == SPELLFAMILY_PRIEST && GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x20 ))
2011-07-10 13:13:02 +02:00
{
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: received not handled spell: %u" , GetId ());
return ;
}
uint32 triggerSpellId = 33110 ;
int32 value = GetAmount ();
int32 jumps = GetBase () -> GetCharges ();
// current aura expire on proc finish
GetBase () -> SetCharges ( 0 );
GetBase () -> SetUsingCharges ( true );
// next target selection
if ( jumps > 0 )
{
2011-07-26 23:09:28 +02:00
if ( Unit * caster = GetCaster ())
2011-07-10 13:13:02 +02:00
{
2011-07-26 23:09:28 +02:00
float radius = GetSpellInfo () -> Effects [ GetEffIndex ()]. CalcRadius ( caster );
2011-07-10 13:13:02 +02:00
if ( Unit * triggerTarget = target -> GetNextRandomRaidMemberOrPet ( radius ))
{
target -> CastCustomSpell ( triggerTarget , GetId (), & value , NULL , NULL , true , NULL , this , GetCasterGUID ());
if ( Aura * aura = triggerTarget -> GetAura ( GetId (), GetCasterGUID ()))
aura -> SetCharges ( jumps );
}
}
}
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: Triggering spell %u from aura %u proc" , triggerSpellId , GetId ());
target -> CastCustomSpell ( target , triggerSpellId , & value , NULL , NULL , true , NULL , this , GetCasterGUID ());
}