/*
* Copyright (C) 2005-2009 MaNGOS
*
* Copyright (C) 2008-2009 Trinity
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "UpdateMask.h"
#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
#include "DynamicObject.h"
#include "Group.h"
#include "UpdateData.h"
#include "ObjectAccessor.h"
#include "Policies/SingletonImp.h"
#include "Totem.h"
#include "Creature.h"
#include "Formulas.h"
#include "BattleGround.h"
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
#include "CreatureAI.h"
#include "ScriptCalls.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Vehicle.h"
#include "CellImpl.h"
#define Aura AuraEffect
pAuraHandler AuraHandler[TOTAL_AURAS]=
{
&Aura::HandleNULL, // 0 SPELL_AURA_NONE
&Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
&Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
&Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
&Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
&Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
&Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
&Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
&Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
&Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
&Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
&Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
&Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
&Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
&Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
&Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
&Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
&Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
&Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
&Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
&Aura::HandleAuraModTotalEnergyPercentRegen, // 21 SPELL_AURA_OBS_MOD_ENERGY
&Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
&Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
&Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
&Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
&Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
&Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
&Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
&Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
&Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
&Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
&Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
&Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
&Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
&Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
&Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
&Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
&Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
&Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
&Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
&Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
&Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
&Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
&Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
&Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
&Aura::HandleUnused, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
&Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
&Aura::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
&Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
&Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
&Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
&Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
&Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
&Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
&Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
&Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
&Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
&Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
&Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
&Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
&Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
&Aura::HandleUnused, // 63 unused (3.0.8a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
&Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
&Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
&Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
&Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
&Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
&Aura::HandleNoImmediateEffect, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
&Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
&Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
&Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
&Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
&Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
&Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
&Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
&Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
&Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
&Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
&Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
&Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
&Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
&Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
&Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
&Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
&Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
&Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
&Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
&Aura::HandleUnused, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
&Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
&Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
&Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
&Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
&Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
&Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
&Aura::HandleNoImmediateEffect, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
&Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
&Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
&Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
&Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
&Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
&Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
&Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
&Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
&Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
&Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
&Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
&Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
&Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
&Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
&Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
&Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
&Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
&Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
&Aura::HandleUnused, //119 unused (3.0.8a) old SPELL_AURA_SHARE_PET_TRACKING
&Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
&Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
&Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
&Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
&Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
&Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
&Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
&Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
&Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
&Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
&Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
&Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
&Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
&Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
&Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
&Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
&Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
&Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
&Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
&Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
&Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
&Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
&Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
&Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
&Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
&Aura::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
&Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
&Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
&Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
&Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
&Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
&Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
&Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
&Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
&Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
&Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
&Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
&Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
&Aura::HandleUnused, //164 unused (3.0.8a), only one test spell
&Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
&Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
&Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
&Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
&Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
&Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE various spells that change visual of units for aura target (clientside?)
&Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
&Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
&Aura::HandleUnused, //173 unused (3.0.8a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
&Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
&Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
&Aura::HandleCharmConvert, //177 SPELL_AURA_AOE_CHARM
&Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
&Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
&Aura::HandleUnused, //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
&Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
&Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 - miscvalue - spell school
&Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
&Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
&Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
&Aura::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
&Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
&Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
&Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
&Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
&Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN - flat mod of spell cooldowns
&Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
&Aura::HandleUnused, //198 unused (3.0.8a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
&Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
&Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
&Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
&Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
&Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
&Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
&Aura::HandleNULL, //205 SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN
&Aura::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
&Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
&Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
&Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
&Aura::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
&Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
&Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
&Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
&Aura::HandleNULL, //214 Tamed Pet Passive
&Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
&Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
&Aura::HandleUnused, //217 unused (3.0.8a)
&Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
&Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
&Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&Aura::HandleNULL, //221 SPELL_AURA_MOD_DETAUNT
&Aura::HandleUnused, //222 unused (3.0.8a) only for spell 44586 that not used in real spell cast
&Aura::HandleNoImmediateEffect, //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
&Aura::HandleUnused, //224 unused (3.0.8a)
&Aura::HandleNoImmediateEffect, //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
&Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
&Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
&Aura::HandleNoImmediateEffect, //228 SPELL_AURA_DETECT_STEALTH stealth detection
&Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
&Aura::HandleAuraModIncreaseHealth, //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
&Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
&Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
&Aura::HandleUnused, //233 set model id to the one of the creature with id GetMiscValue() - clientside
&Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
&Aura::HandleNoImmediateEffect, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
&Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
&Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
&Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
&Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
&Aura::HandleForceMoveForward, //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the player to move forward
&Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING - 2 test spells: 44183 and 44182
&Aura::HandleNULL, //243 faction reaction override spells
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
&Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
&Aura::HandleAuraCloneCaster, //247 SPELL_AURA_CLONE_CASTER
&Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
&Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
&Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
&Aura::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE
&Aura::HandleModCombatSpeedPct, //252 SPELL_AURA_252 Is there any difference between this and SPELL_AURA_MELEE_SLOW ? maybe not stacking mod?
&Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
&Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
&Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
&Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
&Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
&Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
&Aura::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
&Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
&Aura::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
&Aura::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
&Aura::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
&Aura::HandleUnused, //264 unused (3.0.8a)
&Aura::HandleUnused, //265 unused (3.0.8a)
&Aura::HandleUnused, //266 unused (3.0.8a)
&Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
&Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
&Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
&Aura::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
&Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
&Aura::HandleNULL, //272 unknown
&Aura::HandleUnused, //273 clientside
&Aura::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
&Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
&Aura::HandleNULL, //276 mod damage % mechanic?
&Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
&Aura::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
&Aura::HandleAuraInitializeImages, //279 SPELL_AURA_INITIALIZE_IMAGES
&Aura::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_ARMOR_PENETRATION_PCT
&Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
&Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
&Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
&Aura::HandleNULL, //284 SPELL_AURA_LINKED - probably not sent to client
&Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage
&Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in AuraEffect::PeriodicTick
&Aura::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
&Aura::HandleUnused, //288 unused
&Aura::HandleUnused, //289 unused
&Aura::HandleNULL, //290 mod all critical hit chances?
&Aura::HandleNULL, //291 SPELL_AURA_MOD_XP_QUEST_PCT
&Aura::HandleNULL, //292 call stabled pet
&Aura::HandleNULL, //293 2 test spells
&Aura::HandleNULL //294 2 spells, possible prevent mana regen
};
#undef Aura
Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, WorldObject *source, Unit *caster, Item* castItem) :
m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), m_updated(false), m_isRemoved(false)
{
assert(target);
assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
m_auraFlags = effMask;
m_spellProto = spellproto;
if(m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
m_timeCla = 1000;
m_isPassive = IsPassiveSpell(GetId());
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
m_applyTime = time(NULL);
if(!caster)
{
m_caster_guid = target->GetGUID();
//damage = m_currentBasePoints+1; // stored value-1
m_maxduration = target->CalcSpellDuration(m_spellProto);
}
else
{
m_caster_guid = caster->GetGUID();
//damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
m_maxduration = caster->CalcSpellDuration(m_spellProto);
}
if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
m_permanent = true;
else
m_permanent = false;
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
if(!m_permanent && modOwner)
{
modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
// Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
if (m_maxduration<=0)
m_maxduration = 1;
}
m_duration = m_maxduration;
m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
m_procCharges = m_spellProto->procCharges;
if(modOwner)
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() &&
m_spellProto->Stances &&
!(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
!(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
for (uint8 i=0 ;iIsHostileTo(m_target);
for (uint8 i=0;iGetTarget()), m_tickNumber(0)
, m_spellProto(parentAura->GetSpellProto()), m_effIndex(effIndex), m_auraName(AuraType(m_spellProto->EffectApplyAuraName[m_effIndex]))
{
assert(m_auraName < TOTAL_AURAS);
if(currentBasePoints)
m_currentBasePoints = *currentBasePoints;
else
m_currentBasePoints = m_spellProto->EffectBasePoints[m_effIndex];
if(caster)
m_amount = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
else
m_amount = m_currentBasePoints + m_spellProto->EffectBaseDice[m_effIndex];
if (int32 amount = CalculateCrowdControlAuraAmount(caster))
m_amount = amount;
if (!m_amount && castItem && castItem->GetItemSuffixFactor())
{
ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
if(item_rand_suffix)
{
for (int k=0; k<3; k++)
{
SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
if(pEnchant)
{
for (int t=0; t<3; t++)
if(pEnchant->spellid[t] == m_spellProto->Id)
{
m_amount = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
break;
}
}
if(m_amount)
break;
}
}
}
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
m_sourceGUID = source ? source->GetGUID() : (caster ? caster->GetGUID() : 0);
m_amplitude = m_spellProto->EffectAmplitude[m_effIndex];
//apply casting time mods for channeled spells
if (modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
// Apply periodic time mod
if(modOwner && m_amplitude)
modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude);
// Start periodic on next tick or at aura apply
if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
m_periodicTimer += m_amplitude;
m_isApplied = false;
}
AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster, Item * castItem, Unit * source)
: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source)
{
m_removeTime = FRIENDLY_AA_REMOVE_TIME;
m_isAreaAura = true;
Unit* caster_ptr = caster ? caster : source ? source : m_target;
if (m_spellProto->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
m_radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
else
m_radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
if(Player* modOwner = caster_ptr->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
switch(m_spellProto->Effect[effIndex])
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
m_areaAuraType = AREA_AURA_PARTY;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
*const_cast(&m_auraName) = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
m_areaAuraType = AREA_AURA_RAID;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
*const_cast(&m_auraName) = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
m_areaAuraType = AREA_AURA_ENEMY;
if(m_target == caster_ptr)
*const_cast(&m_auraName) = SPELL_AURA_NONE; // Do not do any effect on self
break;
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
m_areaAuraType = AREA_AURA_PET;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
m_areaAuraType = AREA_AURA_OWNER;
if(m_target == caster_ptr)
*const_cast(&m_auraName) = SPELL_AURA_NONE;
break;
default:
sLog.outError("Wrong spell effect in AreaAura constructor");
ASSERT(false);
break;
}
}
AreaAuraEffect::~AreaAuraEffect()
{
}
PersistentAreaAuraEffect::PersistentAreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster,Item * castItem, DynamicObject *source)
: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source)
{
m_isPersistent = true;
}
PersistentAreaAuraEffect::~PersistentAreaAuraEffect()
{
}
AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints, Unit * caster, Item * castItem, WorldObject* source)
{
// TODO: source should belong to aura, but not areaeffect. multiple areaaura/persistent aura should use one source
assert(parentAura);
if (IsAreaAuraEffect(parentAura->GetSpellProto()->Effect[effIndex]))
{
if(!source)
source = caster;
//TODO: determine source here
if(source && source->isType(TYPEMASK_UNIT))
return new AreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, (Unit*)source);
}
else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AURA)
return new AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source);
else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
return new PersistentAreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem);
return NULL;
}
Unit* Aura::GetCaster() const
{
if(m_caster_guid==m_target->GetGUID())
return m_target;
//return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
//must return caster even if it's in another grid/map
Unit *unit = ObjectAccessor::GetObjectInWorld(m_caster_guid, (Unit*)NULL);
return unit && unit->IsInWorld() ? unit : NULL;
}
Unit* AuraEffect::GetSource() const
{
if(m_sourceGUID == m_target->GetGUID())
return m_target;
//return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
//must return caster even if it's in another grid/map
Unit *unit = ObjectAccessor::GetObjectInWorld(m_sourceGUID, (Unit*)NULL);
//only player can be not in world while in objectaccessor
return unit && unit->IsInWorld() ? unit : NULL;
}
void Aura::Update(uint32 diff)
{
// TODO: store pointer to caster in aura class for update/mod handling code
if (m_duration > 0)
{
m_duration -= diff;
if (m_duration < 0)
m_duration = 0;
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
if(m_timeCla)
{
if(m_timeCla > diff)
m_timeCla -= diff;
else if(Unit* caster = GetCaster())
{
if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
m_timeCla += 1000 - diff;
Powers powertype = Powers(m_spellProto->powerType);
if(powertype == POWER_HEALTH)
{
if (caster->GetHealth() > manaPerSecond)
caster->ModifyHealth(-manaPerSecond);
else
{
m_target->RemoveAura(this);
return;
}
}
else
{
if (caster->GetPower(powertype) >= manaPerSecond)
caster->ModifyPower(powertype, -manaPerSecond);
else
{
m_target->RemoveAura(this);
return;
}
}
}
}
}
}
// Apply charged spellmods for channeled auras
// used for example when triggered spell of spell:10 is modded
Spell * modSpell = NULL;
Unit* caster = NULL;
if (IS_PLAYER_GUID(GetCasterGUID()))
{
caster = GetCaster();
if (caster)
{
modSpell = ((Player*)caster)->FindCurrentSpellBySpellId(GetId());
((Player*)caster)->SetSpellModTakingSpell(modSpell, true);
}
}
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_partAuras[i])
m_partAuras[i]->Update(diff);
if (caster)
((Player*)caster)->SetSpellModTakingSpell(modSpell, false);
}
void AuraEffect::Update(uint32 diff)
{
if (m_isPeriodic && (GetParentAura()->GetAuraDuration() >=0 || GetParentAura()->IsPassive() || GetParentAura()->IsPermanent()))
{
if(m_periodicTimer > diff)
m_periodicTimer -= diff;
else // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
{
++m_tickNumber;
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
m_periodicTimer += m_amplitude - diff;
if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
PeriodicTick();
}
}
}
void AreaAuraEffect::Update(uint32 diff)
{
// update for the caster of the aura
if(m_sourceGUID == m_target->GetGUID())
{
Unit *source = m_target;
Unit *caster = GetCaster();
if (!caster)
{
m_target->RemoveAura(GetParentAura());
return;
}
if( !source->hasUnitState(UNIT_STAT_ISOLATED) )
{
std::list targets;
switch(m_areaAuraType)
{
case AREA_AURA_PARTY:
source->GetPartyMemberInDist(targets, m_radius);
break;
case AREA_AURA_RAID:
source->GetRaidMember(targets, m_radius);
break;
case AREA_AURA_FRIEND:
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(source, caster, m_radius);
Trinity::UnitListSearcher searcher(source, targets, u_check);
source->VisitNearbyObject(m_radius, searcher);
break;
}
case AREA_AURA_ENEMY:
{
Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(source, caster, m_radius); // No GetCharmer in searcher
Trinity::UnitListSearcher searcher(source, targets, u_check);
source->VisitNearbyObject(m_radius, searcher);
break;
}
case AREA_AURA_OWNER:
case AREA_AURA_PET:
{
if(Unit *owner = caster->GetCharmerOrOwner())
if (owner->IsWithinDistInMap(source, m_radius))
targets.push_back(owner);
break;
}
}
for(std::list::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
{
// Unit has aura from self - do not replace it
if ((*tIter)->HasAura(GetId(), m_target->GetGUID()))
continue;
if(Aura *aur = (*tIter)->GetAura(GetId(), GetCasterGUID()))
{
if(aur->HasEffect(GetEffIndex()))
continue;
}
else
{
bool skip = false;
for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter)
{
bool samecaster = iter->second->GetCasterGUID() == GetCasterGUID();
if(spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first, samecaster))
{
skip = true;
break;
}
}
if(skip)
continue;
}
// Select lower rank of aura if needed
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
{
int32 newBp = m_currentBasePoints;
// Check if basepoints can be safely reduced
if (newBp == m_spellProto->EffectBasePoints[m_effIndex])
newBp = actualSpellInfo->EffectBasePoints[m_effIndex];
(*tIter)->AddAuraEffect(actualSpellInfo, GetEffIndex(), caster, &newBp, source);
if(m_areaAuraType == AREA_AURA_ENEMY)
caster->CombatStart(*tIter);
}
}
}
AuraEffect::Update(diff);
}
else // aura at non-caster
{
// WARNING: the aura may get deleted during the update
// DO NOT access its members after update!
AuraEffect::Update(diff);
// Speedup - no need to do more checks
if (GetParentAura()->IsRemoved())
return;
// Caster may be deleted due to update
Unit *caster = GetCaster();
Unit *source = GetSource();
// remove aura if out-of-range from caster (after teleport for example)
// or caster is isolated or caster no longer has the aura
// or caster is (no longer) friendly
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
if( !source || !caster ||
source->hasUnitState(UNIT_STAT_ISOLATED) || !source->HasAuraEffect(GetId(), m_effIndex) ||
caster->IsFriendlyTo(m_target) != needFriendly
)
{
m_target->RemoveAura(GetParentAura());
}
else if (!source->IsWithinDistInMap(m_target, m_radius))
{
if (needFriendly && source->isMoving())
{
m_removeTime -= diff;
if (m_removeTime < 0)
m_target->RemoveAura(GetParentAura());
}
else
m_target->RemoveAura(GetParentAura());
}
else
{
// Reset aura remove timer
m_removeTime = FRIENDLY_AA_REMOVE_TIME;
if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
{
if(!m_target->IsInPartyWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_RAID)
{
if(!m_target->IsInRaidWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
m_target->RemoveAura(GetParentAura());
}
}
}
}
void PersistentAreaAuraEffect::Update(uint32 diff)
{
if(Unit *caster = GetParentAura()->GetCaster())
{
if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
{
if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
{
AuraEffect::Update(diff);
return;
}
}
}
// remove the aura if its caster or the dynamic object causing it was removed
// or if the target moves too far from the dynamic object
m_target->RemoveAura(GetParentAura());
}
void AuraEffect::ApplyModifier(bool apply, bool Real, bool changeAmount)
{
if (GetParentAura()->IsRemoved())
return;
if (apply)
HandleAuraEffectSpecificMods(true, Real, changeAmount);
(*this.*AuraHandler [m_auraName])(apply,Real, changeAmount);
if (!apply)
HandleAuraEffectSpecificMods(false, Real, changeAmount);
}
void AuraEffect::RecalculateAmount(bool applied)
{
Unit *caster = GetParentAura()->GetCaster();
int32 amount = GetParentAura()->GetStackAmount() * (caster ? (caster->CalculateSpellDamage(m_spellProto, GetEffIndex(), GetBasePoints(), NULL)) : (m_currentBasePoints + m_spellProto->EffectBaseDice[m_effIndex]));
// Reapply if amount change
if (amount!=GetAmount())
{
// Auras which are applying spellmod should have removed spellmods for real
if (applied)
ApplyModifier(false,false,true);
SetAmount(amount);
if (applied)
ApplyModifier(true,false,true);
}
}
void AuraEffect::CleanupTriggeredSpells()
{
uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
if(!tSpellId)
return;
SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
if(!tProto)
return;
if(GetSpellDuration(tProto) != -1)
return;
// needed for spell 43680, maybe others
// TODO: is there a spell flag, which can solve this in a more sophisticated way?
if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
return;
m_target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
}
void Aura::ApplyAllModifiers(bool apply, bool Real)
{
for (uint8 i = 0; iApplyModifier(apply, Real);
}
void Aura::HandleAuraSpecificMods(bool apply)
{
//**************************************************************************************
// Function called after applying all mods from aura or after removing all mods from it
//**************************************************************************************
//********************
// MODS AT AURA APPLY
//********************
if (apply)
{
// Update auras for specific phase
if(IsAuraType(SPELL_AURA_PHASE))
{
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
if(saBounds.first != saBounds.second)
{
uint32 zone, area;
m_target->GetZoneAndAreaId(zone,area);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
// some auras remove at aura remove
if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
m_target->RemoveAurasDueToSpell(itr->second->spellId);
// some auras applied at aura apply
else if(itr->second->autocast)
{
if( !m_target->HasAura(itr->second->spellId) )
m_target->CastSpell(m_target,itr->second->spellId,true);
}
}
}
}
// Buffeting Winds of Susurrus
if(GetId()==32474 && m_target->GetTypeId()==TYPEID_PLAYER)
((Player*)m_target)->ActivateTaxiPathTo(506,GetId());
if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE)
{
if (m_spellProto->SpellFamilyFlags[0] & 0x00000001 && m_spellProto->SpellFamilyFlags[2] & 0x00000008)
{
// Glyph of Fireball
if (Unit * caster = GetCaster())
if (caster->HasAura(56368))
SetAuraDuration(0);
}
else if (m_spellProto->SpellFamilyFlags[0] & 0x00000020 && m_spellProto->SpellVisual[0] == 13)
{
// Glyph of Frostbolt
if (Unit * caster = GetCaster())
if (caster->HasAura(56370))
SetAuraDuration(0);
}
// Todo: This should be moved to similar function in spell::hit
else if (m_spellProto->SpellFamilyFlags[0] & 0x01000000)
{
Unit * caster = GetCaster();
if (!caster)
return;
// Polymorph Sound - Sheep && Penguin
if (m_spellProto->SpellIconID == 82 && m_spellProto->SpellVisual[0] == 12978)
{
// Glyph of the Penguin
if (caster->HasAura(52648))
caster->CastSpell(m_target,61635,true);
else
caster->CastSpell(m_target,61634,true);
}
}
}
// Gronn Lord's Grasp, becomes stoned
else if (GetId() == 33572)
{
if (GetStackAmount() >= 5 && !m_target->HasAura(33652))
m_target->CastSpell(m_target, 33652, true);
}
// Heroic Fury (remove Intercept cooldown)
else if(GetId() == 60970 && m_target->GetTypeId() == TYPEID_PLAYER )
{
((Player*)m_target)->RemoveSpellCooldown(20252, true);
}
// Demonic Circle
else if (GetId() == 48020 && m_target->GetTypeId() == TYPEID_PLAYER )
{
GameObject* obj = m_target->GetGameObject(48018);
if (obj)
((Player*)m_target)->TeleportTo(obj->GetMapId(),obj->GetPositionX(),obj->GetPositionY(),obj->GetPositionZ(),obj->GetOrientation());
}
}
//*******************************
// MODS AT AURA APPLY AND REMOVE
//*******************************
// Aura Mastery Triggered Spell Handler
// If apply Concentration Aura -> trigger -> apply Aura Mastery Immunity
// If remove Concentration Aura -> trigger -> remove Aura Mastery Immunity
// If remove Aura Mastery -> trigger -> remove Aura Mastery Immunity
if (m_spellProto->Id == 19746 || m_spellProto->Id == 31821)
{
if (GetCasterGUID() != m_target->GetGUID())
return;
if (apply)
{
if ((m_spellProto->Id == 31821 && m_target->HasAura(19746, GetCasterGUID())) || (m_spellProto->Id == 19746 && m_target->HasAura(31821)))
{
m_target->CastSpell(m_target,64364,true);
return;
}
}
else
{
m_target->RemoveAurasDueToSpell(64364, GetCasterGUID());
return;
}
}
// Bestial Wrath
if (GetSpellProto()->Id == 19574)
{
// The Beast Within cast on owner if talent present
if ( Unit* owner = m_target->GetOwner() )
{
// Search talent
if (owner->HasAura(34692))
{
if (apply)
owner->CastSpell(owner, 34471, true, 0, GetPartAura(0));
else
owner->RemoveAurasDueToSpell(34471);
}
}
}
if (GetSpellSpecific(m_spellProto->Id) == SPELL_PRESENCE)
{
AuraEffect *bloodPresenceAura=0; // healing by damage done
AuraEffect *frostPresenceAura=0; // increased health
AuraEffect *unholyPresenceAura=0; // increased movement speed, faster rune recovery
// Improved Presences
Unit::AuraEffectList const& vDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
{
switch((*itr)->GetId())
{
// Improved Blood Presence
case 50365:
case 50371:
{
bloodPresenceAura = (*itr);
break;
}
// Improved Frost Presence
case 50384:
case 50385:
{
frostPresenceAura = (*itr);
break;
}
// Improved Unholy Presence
case 50391:
case 50392:
{
unholyPresenceAura = (*itr);
break;
}
}
}
uint32 presence=GetId();
if (apply)
{
// Blood Presence bonus
if (presence == SPELL_ID_BLOOD_PRESENCE)
m_target->CastSpell(m_target,63611,true);
else if (bloodPresenceAura)
{
int32 basePoints1=bloodPresenceAura->GetAmount();
m_target->CastCustomSpell(m_target,63611,NULL,&basePoints1,NULL,true,0,bloodPresenceAura);
}
// Frost Presence bonus
if (presence == SPELL_ID_FROST_PRESENCE)
m_target->CastSpell(m_target,61261,true);
else if (frostPresenceAura)
{
int32 basePoints0=frostPresenceAura->GetAmount();
m_target->CastCustomSpell(m_target,61261,&basePoints0,NULL,NULL,true,0,frostPresenceAura);
}
// Unholy Presence bonus
if (presence == SPELL_ID_UNHOLY_PRESENCE)
{
if(unholyPresenceAura)
{
// Not listed as any effect, only base points set
int32 basePoints0 = unholyPresenceAura->GetSpellProto()->EffectBasePoints[1];
//m_target->CastCustomSpell(m_target,63622,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
m_target->CastCustomSpell(m_target,65095,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
}
m_target->CastSpell(m_target,49772, true);
}
else if (unholyPresenceAura)
{
int32 basePoints0=unholyPresenceAura->GetAmount();
m_target->CastCustomSpell(m_target,49772,&basePoints0,NULL,NULL,true,0,unholyPresenceAura);
}
}
else
{
// Remove passive auras
if (presence == SPELL_ID_BLOOD_PRESENCE || bloodPresenceAura)
m_target->RemoveAurasDueToSpell(63611);
if (presence == SPELL_ID_FROST_PRESENCE || frostPresenceAura)
m_target->RemoveAurasDueToSpell(61261);
if (presence == SPELL_ID_UNHOLY_PRESENCE || unholyPresenceAura)
{
if(presence == SPELL_ID_UNHOLY_PRESENCE && unholyPresenceAura)
{
//m_target->RemoveAurasDueToSpell(63622);
m_target->RemoveAurasDueToSpell(65095);
}
m_target->RemoveAurasDueToSpell(49772);
}
}
}
//*********************
// MODS AT AURA REMOVE
//*********************
if(!apply)
{
// Spell Reflection
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x2
&& GetRemoveMode() != AURA_REMOVE_BY_DEFAULT)
{
if (Unit * caster = GetCaster())
{
// Improved Spell Reflection
if (caster->GetDummyAura(SPELLFAMILY_WARRIOR,1935, 1))
{
// aura remove - remove auras from all party members
std::list PartyMembers;
m_target->GetPartyMembers(PartyMembers);
for (std::list::iterator itr = PartyMembers.begin();itr!=PartyMembers.end();++itr)
{
if ((*itr)!= m_target)
(*itr)->RemoveAurasWithFamily(SPELLFAMILY_WARRIOR, 0, 0x2, 0, GetCasterGUID());
}
}
}
}
// Guardian Spirit
else if(m_spellProto->Id == 47788)
{
if (GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
Unit *caster = GetCaster();
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
Player *player = ((Player*)caster);
// Glyph of Guardian Spirit
if(AuraEffect * aurEff = player->GetAuraEffect(63231, 0))
{
if (!player->HasSpellCooldown(47788))
return;
player->RemoveSpellCooldown(m_spellProto->Id, true);
player->AddSpellCooldown(m_spellProto->Id, 0, uint32(time(NULL) + aurEff->GetAmount()));
WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4);
data << uint64(player->GetGUID());
data << uint8(0x0); // flags (0x1, 0x2)
data << uint32(m_spellProto->Id);
data << uint32(aurEff->GetAmount()*IN_MILISECONDS);
player->SendDirectMessage(&data);
}
}
// Invisibility
else if (m_spellProto->Id == 66)
{
if (GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
m_target->CastSpell(m_target, 32612, true, NULL, GetPartAura(1));
}
// Curse of Doom
else if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[1] & 0x02)
{
if (GetRemoveMode()==AURA_REMOVE_BY_DEATH)
{
if (Unit * caster = GetCaster())
{
if (caster->GetTypeId()==TYPEID_PLAYER && ((Player*)caster)->isHonorOrXPTarget(m_target))
caster->CastSpell(m_target, 18662, true, NULL, GetPartAura(0));
}
}
}
}
}
void AuraEffect::HandleAuraEffectSpecificMods(bool apply, bool Real, bool changeAmount)
{
//***********************************************************************
// Function called before aura effect handler apply or after it's remove
//***********************************************************************
if(!Real && !changeAmount)
return;
if(apply)
{
// prevent double apply bonuses
if (!m_target->isBeingLoaded())
if(Unit* caster = GetCaster())
{
float DoneActualBenefit = 0.0f;
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
// Replenishment (0.25% from max)
// Infinite Replenishment
if (m_spellProto->SpellIconID == 3184 && m_spellProto->SpellVisual[0] == 12495 && GetAuraName() == SPELL_AURA_PERIODIC_ENERGIZE)
m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000;
break;
case SPELLFAMILY_MAGE:
// Mana Shield
if(m_spellProto->SpellFamilyFlags[0] & 0x8000 && m_spellProto->SpellFamilyFlags[2] & 0x8 && GetAuraName() == SPELL_AURA_MANA_SHIELD)
{
// +80.53% from +spd bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8053f;;
}
// Ice Barrier
else if(m_spellProto->SpellFamilyFlags[1] & 0x1 && m_spellProto->SpellFamilyFlags[2] & 0x8 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
{
// +80.67% from sp bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8067f;
}
break;
case SPELLFAMILY_WARRIOR:
{
// Rend
if (m_spellProto->SpellFamilyFlags[0] & 0x20 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
// $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
int32 mws = caster->GetAttackTime(BASE_ATTACK);
float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
// "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?)
if (spellmgr.GetSpellRank(m_spellProto->Id) >= 9)
{
if (m_target->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, m_spellProto, caster))
m_amount += int32(m_amount*0.35);
}
}
break;
}
case SPELLFAMILY_WARLOCK:
// shadow ward
if(m_spellProto->SpellFamilyFlags[2]& 0x40 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
{
// +30% from sp bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
}
// Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
else if (m_spellProto->SpellFamilyFlags[0] & 0x00004000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
// if victim is below 25% of hp
if (m_target->GetMaxHealth() / 4 > m_target->GetHealth())
m_amount *= 4;
}
break;
case SPELLFAMILY_PRIEST:
// Power Word: Shield
if(m_spellProto->SpellFamilyFlags[0] & 0x1 && m_spellProto->SpellFamilyFlags[2] & 0x400 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
{
// +80.68% from sp bonus
DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f;
}
break;
case SPELLFAMILY_DRUID:
{
// Rip
if (m_spellProto->SpellFamilyFlags[0] & 0x00800000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
// 0.01*$AP*cp
if (caster->GetTypeId() != TYPEID_PLAYER)
return;
uint8 cp = ((Player*)caster)->GetComboPoints();
// Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
if (AuraEffect const * aurEff = caster->GetAuraEffect(34241,0))
m_amount += cp * aurEff->GetAmount();
m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
}
// Lifebloom
else if (m_spellProto->SpellFamilyFlags[1] & 0x10 && GetAuraName() == SPELL_AURA_PERIODIC_HEAL)
m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
// Innervate
else if (m_spellProto->Id == 29166 && GetAuraName() == SPELL_AURA_PERIODIC_ENERGIZE)
m_amount = m_target->GetCreatePowers(POWER_MANA) * m_amount / (GetTotalTicks() * 100.0f);
break;
}
case SPELLFAMILY_ROGUE:
{
// Rupture
if (m_spellProto->SpellFamilyFlags[0] & 0x100000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
if (caster->GetTypeId() != TYPEID_PLAYER)
return;
//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};
uint8 cp = ((Player*)caster)->GetComboPoints();
if (cp > 5) cp = 5;
m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
}
break;
}
case SPELLFAMILY_PALADIN:
// Sacred Shield
if (m_spellProto->SpellFamilyFlags[1] & 0x80000 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
{
// 0.75 from sp bonus
DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f;
}
break;
case SPELLFAMILY_SHAMAN:
// Earth Shield
if (m_spellProto->SpellFamilyFlags[1] & 0x400 && GetAuraName() == SPELL_AURA_DUMMY)
m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
break;
case SPELLFAMILY_DEATHKNIGHT:
{
// Vampiric Blood
if(GetSpellProto()->Id == 55233 && GetAuraName() == SPELL_AURA_MOD_INCREASE_HEALTH)
m_amount = m_target->GetMaxHealth() * m_amount / 100;
// Icebound Fortitude
else if (m_spellProto->SpellFamilyFlags[0] & 0x00100000 && GetAuraName() == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
{
if (caster->GetTypeId() == TYPEID_PLAYER)
{
int32 value = int32((m_amount*-1)-10);
uint32 defva = uint32(((Player*)caster)->GetSkillValue(SKILL_DEFENSE) + ((Player*)caster)->GetRatingBonusValue(CR_DEFENSE_SKILL));
if(defva > 400)
value += int32((defva-400)*0.15);
// Glyph of Icebound Fortitude
if (AuraEffect *auradummy = caster->GetAuraEffect(58625,0))
{
uint32 valmax = auradummy->GetAmount();
if(value < valmax)
value = valmax;
}
m_amount = -value;
}
}
break;
}
default:
break;
}
if (DoneActualBenefit != 0.0f)
{
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
m_amount += (int32)DoneActualBenefit;
}
}
}
}
void Aura::SendAuraUpdate()
{
if (m_auraSlot>=MAX_AURAS)
return;
WorldPacket data(SMSG_AURA_UPDATE);
data.append(m_target->GetPackGUID());
data << uint8(m_auraSlot);
if(!m_target->GetVisibleAura(m_auraSlot))
{
data << uint32(0);
sLog.outDebug("Aura %u removed slot %u",GetId(), m_auraSlot);
m_target->SendMessageToSet(&data, true);
return;
}
data << uint32(GetId());
data << uint8(m_auraFlags);
data << uint8(m_auraLevel);
data << uint8(m_stackAmount > 1 ? m_stackAmount : (m_procCharges) ? m_procCharges : 1);
if(!(m_auraFlags & AFLAG_CASTER))
{
if (Unit * caster = GetCaster())
data.append(caster->GetPackGUID());
else
data << uint8(0);
}
if(m_auraFlags & AFLAG_DURATION)
{
data << uint32(m_maxduration);
data << uint32(m_duration);
}
m_target->SendMessageToSet(&data, true);
}
bool Aura::IsVisible() const
{
// passive auras (except totem auras) do not get placed in the slots
// area auras with SPELL_AURA_NONE are not shown on target
//(m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId()))
if(!m_isPassive)
return true;
bool noneAreaAura = true;
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if(m_partAuras[i])
{
if(m_partAuras[i]->IsAreaAura())
{
if(WorldObject *source = m_partAuras[i]->GetSource())
if(source->GetTypeId() == TYPEID_UNIT && ((Creature*)source)->isTotem())
return true;
if(m_partAuras[i]->GetAuraName() != SPELL_AURA_NONE)
noneAreaAura = false;
}
else
noneAreaAura = false;
}
}
if(noneAreaAura)
return false;
return IsAuraType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
}
void Aura::_AddAura()
{
if (!GetId())
return;
if(!m_target)
return;
Unit* caster = GetCaster();
// set infinity cooldown state for spells
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
{
Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL;
((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true);
}
}
if(IsVisible())
{
// Try find slot for aura
uint8 slot = MAX_AURAS;
// Lookup for auras already applied from spell
if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
{
// allow use single slot only by auras from same caster
slot = foundAura->GetAuraSlot();
}
else
{
Unit::VisibleAuraMap const * visibleAuras= m_target->GetVisibleAuras();
// lookup for free slots in units visibleAuras
Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0);
for(uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr , ++freeSlot)
{
if(itr == visibleAuras->end() || itr->first != freeSlot)
{
slot = freeSlot;
break;
}
}
}
// Register Visible Aura
if(slot < MAX_AURAS)
{
m_auraFlags |= (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) |
(GetCasterGUID() == m_target->GetGUID() ? AFLAG_CASTER : AFLAG_NONE) |
(GetAuraMaxDuration() > 0 ? AFLAG_DURATION : AFLAG_NONE);
m_auraLevel = (caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
SetAuraSlot( slot );
m_target->SetVisibleAura(slot, this);
m_target->UpdateAuraForGroup(slot);
SendAuraUpdate();
sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffectMask(), slot);
}
else
sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffectMask());
}
// Sitdown on apply aura req seated
if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
m_target->SetStandState(UNIT_STAND_STATE_SIT);
// register aura diminishing on apply
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),true);
// Apply linked auras (On first aura apply)
uint32 id = GetId();
if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
{
if(const std::vector *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
for(std::vector::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
if(*itr < 0)
m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), true);
else if(Unit* caster = GetCaster())
caster->AddAura(*itr, m_target);
}
}
HandleAuraSpecificMods(true);
}
bool Aura::SetPartAura(AuraEffect* aurEff, uint8 effIndex)
{
if (IsRemoved())
return false;
if (m_auraFlags & (1<HandleAuraEffect(aurEff, true);
SendAuraUpdate();
return true;
}
void Aura::_RemoveAura()
{
Unit* caster = GetCaster();
uint8 slot = GetAuraSlot();
if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
{
// allow use single slot only by auras from same caster
slot = foundAura->GetAuraSlot();
if(slot < MAX_AURAS) // slot not set
if (Aura *entry = m_target->GetVisibleAura(slot))
{
// set not valid slot for aura - prevent removing other visible aura
slot = MAX_AURAS;
}
}
// update for out of range group members
if (slot < MAX_AURAS)
{
m_target->RemoveVisibleAura(slot);
m_target->UpdateAuraForGroup(slot);
SendAuraUpdate();
}
// unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),false);
// since now aura cannot apply/remove it's modifiers
m_isRemoved = true;
// disable client server communication for removed aura
SetAuraSlot(MAX_AURAS);
// reset cooldown state for spells
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto());
}
uint32 id = GetId();
// Remove Linked Auras
if(m_removeMode != AURA_REMOVE_BY_STACK && m_removeMode != AURA_REMOVE_BY_DEATH)
{
if(uint32 customAttr = spellmgr.GetSpellCustomAttr(id))
{
if(customAttr & SPELL_ATTR_CU_LINK_REMOVE)
{
if(const std::vector *spell_triggered = spellmgr.GetSpellLinked(-(int32)id))
for(std::vector::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
if(*itr < 0)
m_target->RemoveAurasDueToSpell(-(*itr));
else if (m_removeMode != AURA_REMOVE_BY_DEFAULT)
m_target->CastSpell(m_target, *itr, true, 0, 0, GetCasterGUID());
}
}
if(customAttr & SPELL_ATTR_CU_LINK_AURA)
{
if(const std::vector *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
for(std::vector::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
if(*itr < 0)
m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), false);
else
m_target->RemoveAurasDueToSpell(*itr);
}
}
}
}
// Proc on aura remove (only spell flags for now)
if (caster)
{
uint32 procEx=0;
if (m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL)
procEx = PROC_EX_AURA_REMOVE_DESTROY;
else if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL)
procEx = PROC_EX_AURA_REMOVE_EXPIRE;
if (procEx)
{
uint32 ProcCaster, ProcVictim;
if (IsPositive())
{
ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_MAGIC_SPELL | PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL_HIT;
ProcVictim = PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL | PROC_FLAG_TAKEN_POSITIVE_SPELL;
}
else
{
ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL | PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_MAGIC_SPELL | PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
}
caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
}
}
HandleAuraSpecificMods(false);
}
void Aura::SetStackAmount(uint8 stackAmount, bool applied)
{
bool refresh = stackAmount >= m_stackAmount;
if (stackAmount != m_stackAmount)
{
m_stackAmount = stackAmount;
for (uint8 i=0;iRecalculateAmount(applied);
}
}
}
if (refresh)
RefreshAura();
else
SendAuraUpdate();
}
bool Aura::modStackAmount(int32 num)
{
// Can`t mod
if (!m_spellProto->StackAmount)
return true;
// Modify stack but limit it
int32 stackAmount = m_stackAmount + num;
if (stackAmount > m_spellProto->StackAmount)
stackAmount = m_spellProto->StackAmount;
else if (stackAmount <=0) // Last aura from stack removed
{
m_stackAmount = 0;
return true; // need remove aura
}
// Update stack amount
SetStackAmount(stackAmount);
return false;
}
void Aura::SetAuraDuration(int32 duration, bool withMods)
{
if (withMods)
{
if (Player * modOwner = m_target->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration);
}
m_duration = duration;
//if (duration<0)
//m_permanent=true;
//else
//m_permanent=false;
SendAuraUpdate();
}
void Aura::SetAuraCharges(uint8 charges)
{
if (m_procCharges == charges)
return;
m_procCharges = charges;
SendAuraUpdate();
}
bool Aura::DropAuraCharge()
{
if(m_procCharges) //auras without charges always have charge = 0
{
if(--m_procCharges) // Send charge change
SendAuraUpdate();
else // Last charge dropped
{
m_target->RemoveAura(this, AURA_REMOVE_BY_EXPIRE);
return true;
}
}
return false;
}
bool Aura::CanBeSaved() const
{
if (IsPassive())
return false;
if (GetCasterGUID() != m_target->GetGUID())
if (IsSingleTargetSpell(GetSpellProto()) || IsAreaAura())
return false;
// Can't be saved - aura handler relies on calculated amount and changes it
if (IsAuraType(SPELL_AURA_CONVERT_RUNE))
return false;
return true;
}
bool Aura::IsPersistent() const
{
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if(m_partAuras[i] && m_partAuras[i]->IsPersistent())
return true;
}
return false;
}
bool Aura::IsAreaAura() const
{
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if(m_partAuras[i] && m_partAuras[i]->IsAreaAura())
return true;
}
return false;
}
bool Aura::IsAuraType(AuraType type) const
{
for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if(m_partAuras[i] && m_partAuras[i]->GetAuraName() == type)
return true;
}
return false;
}
void Aura::SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount)
{
m_caster_guid = caster_guid;
m_maxduration = maxduration;
m_duration = duration;
m_procCharges = charges;
m_stackAmount = stackamount;
for (uint8 i=0; iSetAmount(amount[i]);
}
void AuraEffect::HandleShapeshiftBoosts(bool apply)
{
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;
// aura from effect trigger spell
spellId2 = 24907;
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;
break;
case FORM_GHOUL:
case FORM_GHOSTWOLF:
case FORM_AMBIENT:
case FORM_STEALTH:
case FORM_CREATURECAT:
case FORM_CREATUREBEAR:
break;
}
uint32 form = GetMiscValue()-1;
if(apply)
{
// Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
if (spellId)
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
((Player *)m_target)->RemoveSpellCooldown(spellId);
m_target->CastSpell(m_target, spellId, true, NULL, this );
}
if (spellId2)
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
((Player *)m_target)->RemoveSpellCooldown(spellId2);
m_target->CastSpell(m_target, spellId2, true, NULL, this);
}
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
{
if(itr->second->state == PLAYERSPELL_REMOVED) continue;
if(itr->first==spellId || itr->first==spellId2) continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
if (spellInfo->Stances & (1<