2010-01-10 01:23:15 +01:00
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
2010-01-16 20:19:18 +03:00
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
2010-01-10 01:23:15 +01:00
*
* 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 "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"
#include "BattleGround.h"
#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"
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:
// AURA_EFFECT_HANDLE_REAL set - aura mod is just applied/removed on the target
// AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK set - aura is just applied/removed, or aura packet request is made
// 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
& AuraEffect :: HandleNoImmediateEffect , // 17 SPELL_AURA_MOD_DETECT implement in GameObject::canDetectTrap and Unit::canDetectStealthOf
& AuraEffect :: HandleInvisibility , // 18 SPELL_AURA_MOD_INVISIBILITY
& AuraEffect :: HandleInvisibilityDetect , // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
& 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
& AuraEffect :: HandleHaste , //138 SPELL_AURA_MOD_HASTE
& 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
& AuraEffect :: HandleNoImmediateEffect , //154 SPELL_AURA_MOD_STEALTH_LEVEL
& 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
& AuraEffect :: HandleNoImmediateEffect , //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
& 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
& AuraEffect :: HandleModMeleeRangedSpeedPct , //192 SPELL_AURA_HASTE_MELEE
& 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
& AuraEffect :: HandleUnused , //217 unused (3.2.0)
& 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
& AuraEffect :: HandleForceMoveForward , //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the player to move forward
& 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
& AuraEffect :: HandlePhase , //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
& 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
& AuraEffect :: HandleNULL , //292 call stabled pet
& AuraEffect :: HandleNULL , //293 2 test spells
& AuraEffect :: HandleNoImmediateEffect , //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power)
& AuraEffect :: HandleNULL , //296 2 spells
& AuraEffect :: HandleNULL , //297 1 spell (counter spell school?)
& AuraEffect :: HandleNULL , //298 unused
& AuraEffect :: HandleNULL , //299 unused
& AuraEffect :: HandleNULL , //300 3 spells (share damage?)
& AuraEffect :: HandleNULL , //301 5 spells
& AuraEffect :: HandleNULL , //302 unused
& AuraEffect :: HandleNULL , //303 17 spells
& AuraEffect :: HandleNULL , //304 2 spells (alcohol effect?)
& AuraEffect :: HandleAuraModIncreaseSpeed , //305 SPELL_AURA_MOD_MINIMUM_SPEED
2010-02-14 19:13:14 -07:00
& AuraEffect :: HandleNULL , //306 1 spell
& AuraEffect :: HandleNULL , //307 absorb healing?
& AuraEffect :: HandleNULL , //308 new aura for hunter traps
& AuraEffect :: HandleNULL , //309 absorb healing?
& AuraEffect :: HandleNoImmediateEffect , //310 5 spells SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS implemented in Unit::MeleeDamageBonus
& AuraEffect :: HandleNULL , //311 0 spells in 3.3
& AuraEffect :: HandleNULL , //312 0 spells in 3.3
& AuraEffect :: HandleNULL , //313 0 spells in 3.3
& AuraEffect :: HandleNULL , //314 1 test spell (reduce duration of silince/magic)
& AuraEffect :: HandleNULL , //315 underwater walking
& AuraEffect :: HandleNoImmediateEffect , //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic
& AuraEffect :: HandleNULL
2010-01-10 01:23:15 +01:00
};
AuraEffect :: AuraEffect ( Aura * base , uint8 effIndex , int32 * baseAmount , Unit * caster ) :
m_base ( base ), m_spellProto ( base -> GetSpellProto ()), m_spellmod ( NULL ), m_periodicTimer ( 0 ),
m_tickNumber ( 0 ), m_effIndex ( effIndex ), m_isPeriodic ( false ), m_canBeRecalculated ( true ),
2010-04-11 11:16:42 +04:00
m_baseAmount ( baseAmount ? * baseAmount : m_spellProto -> EffectBasePoints [ m_effIndex ] + 1 )
2010-01-10 01:23:15 +01:00
{
CalculatePeriodic ( caster , true );
m_amount = CalculateAmount ( caster );
CalculateSpellMod ();
}
AuraEffect ::~ AuraEffect ()
{
if ( m_spellmod )
delete m_spellmod ;
}
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
}
int32 AuraEffect :: CalculateAmount ( Unit * caster )
{
int32 amount ;
// default amount calculation
2010-04-07 19:14:10 +02:00
if ( caster )
2010-04-13 16:24:17 +04:00
amount = caster -> CalculateSpellDamage ( NULL , m_spellProto , m_effIndex , & m_baseAmount );
2010-01-10 01:23:15 +01:00
else
2010-04-11 11:16:42 +04:00
amount = m_baseAmount + 1 ;
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 ())
if ( Player * playerCaster = dynamic_cast < Player *> ( caster ))
if ( Item * castItem = playerCaster -> GetItemByGuid ( itemGUID ))
2010-01-10 01:23:15 +01:00
if ( castItem -> GetItemSuffixFactor ())
{
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
{
for ( int k = 0 ; k < MAX_SPELL_EFFECTS ; k ++ )
{
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
{
for ( int t = 0 ; t < MAX_SPELL_EFFECTS ; t ++ )
2010-04-07 19:14:10 +02:00
if ( pEnchant -> spellid [ t ] == m_spellProto -> 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 ;
if ( ! m_spellProto -> procFlags )
break ;
amount = GetBase () -> GetUnitOwner () -> GetMaxHealth () * 0.10f ;
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 )
{
2010-04-07 19:14:10 +02:00
if (( * itr ) -> IsAffectedOnSpell ( m_spellProto ))
2010-01-10 01:23:15 +01:00
{
// Glyph of Fear, Glyph of Frost nova and similar auras
if (( * itr ) -> GetMiscValue () == 7801 )
{
amount += ( int32 )( amount * ( * itr ) -> GetAmount () / 100.0f );
break ;
}
}
}
}
break ;
case SPELL_AURA_SCHOOL_ABSORB :
m_canBeRecalculated = false ;
if ( ! caster )
break ;
switch ( GetSpellProto () -> SpellFamilyName )
{
case SPELLFAMILY_MAGE :
// Ice Barrier
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x1 && GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-01-10 01:23:15 +01:00
{
// +80.67% from sp bonus
DoneActualBenefit += caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.8067f ;
}
break ;
case SPELLFAMILY_WARLOCK :
// Shadow Ward
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> SpellFamilyFlags [ 2 ] & 0x40 )
2010-01-10 01:23:15 +01:00
{
// +30% from sp bonus
DoneActualBenefit += caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.3f ;
}
break ;
case SPELLFAMILY_PRIEST :
// Power Word: Shield
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x1 && GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x400 )
2010-01-10 01:23:15 +01:00
{
//+80.68% from sp bonus
float bonus = 0.8068f ;
2010-04-12 23:37:47 +02:00
AuraEffect const * pAurEff ;
2010-01-10 01:23:15 +01:00
// Borrowed Time
2010-04-12 23:37:47 +02:00
if ( pAurEff = caster -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_PRIEST , 2899 , 1 ))
bonus += ( float ) pAurEff -> GetAmount () / 100.0f ;
// Twin Disciplines
if ( pAurEff = caster -> GetAuraEffect ( SPELL_AURA_ADD_PCT_MODIFIER , SPELLFAMILY_PRIEST , 0x400000 , 0 , 0 , caster -> GetGUID ()))
bonus += ( float ) pAurEff -> GetAmount () / 100.0f ;
// Focused Power
if ( pAurEff = caster -> GetAuraEffect ( SPELL_AURA_MOD_HEALING_DONE_PERCENT , SPELLFAMILY_PRIEST , 2210 , 2 ))
bonus += ( float ) pAurEff -> GetAmount () / 100.0f ;
2010-04-07 18:09:10 +02:00
2010-04-12 23:37:47 +02:00
DoneActualBenefit = caster -> SpellBaseHealingBonus ( GetSpellSchoolMask ( GetSpellProto ())) * bonus ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELLFAMILY_PALADIN :
// Sacred Shield
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x80000 )
{
// 0.75 from sp bonus
DoneActualBenefit = caster -> SpellBaseHealingBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.75f ;
}
break ;
}
break ;
case SPELL_AURA_MANA_SHIELD :
m_canBeRecalculated = false ;
if ( ! caster )
break ;
// Mana Shield
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x8000 && m_spellProto -> SpellFamilyFlags [ 2 ] & 0x8 )
2010-01-10 01:23:15 +01:00
{
// +80.53% from +spd bonus
DoneActualBenefit += caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.8053f ;;
}
break ;
case SPELL_AURA_DUMMY :
if ( ! caster )
break ;
// Earth Shield
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellProto -> SpellFamilyFlags [ 1 ] & 0x400 )
amount = caster -> SpellHealingBonus ( GetBase () -> GetUnitOwner (), GetSpellProto (), amount , SPELL_DIRECT_DAMAGE );
break ;
case SPELL_AURA_DAMAGE_SHIELD :
if ( ! caster )
break ;
// Thorns
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x100 )
// 3.3% from sp bonus
DoneActualBenefit = caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.033f ;
break ;
case SPELL_AURA_PERIODIC_DAMAGE :
if ( ! caster )
break ;
// Rupture
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x100000 )
{
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
else if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x00800000 && GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
{
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
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( 34241 , 0 ))
amount += cp * aurEff -> GetAmount ();
amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * cp / 100 );
}
// Rend
else if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_WARRIOR && GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x20 )
{
m_canBeRecalculated = false ;
// $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 );
2010-03-19 08:47:03 +01:00
amount += caster -> ApplyEffectModifiers ( m_spellProto , m_effIndex , int32 ((( mwb_min + mwb_max ) / 2 + ap * mws / 14000 ) * 0.2f ));
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?)
if ( spellmgr . GetSpellRank ( m_spellProto -> Id ) >= 9 )
{
if ( GetBase () -> GetUnitOwner () -> HasAuraState ( AURA_STATE_HEALTH_ABOVE_75_PERCENT , m_spellProto , caster ))
amount += int32 ( amount * m_spellProto -> CalculateSimpleValue ( 2 ) / 100.0f );
}
}
break ;
case SPELL_AURA_PERIODIC_ENERGIZE :
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_GENERIC )
{
// Replenishment (0.25% from max)
// Infinite Replenishment
if ( m_spellProto -> SpellIconID == 3184 && m_spellProto -> SpellVisual [ 0 ] == 12495 )
amount = GetBase () -> GetUnitOwner () -> GetMaxPower ( POWER_MANA ) * 25 / 10000 ;
}
// Innervate
else if ( m_spellProto -> Id == 29166 )
amount = GetBase () -> GetUnitOwner () -> GetCreatePowers ( POWER_MANA ) * amount / ( GetTotalTicks () * 100.0f );
// Owlkin Frenzy
else if ( m_spellProto -> Id == 48391 )
amount = GetBase () -> GetUnitOwner () -> GetCreatePowers ( POWER_MANA ) * amount / 100 ;
break ;
case SPELL_AURA_PERIODIC_HEAL :
if ( ! caster )
break ;
// Lightwell Renew
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_PRIEST && m_spellProto -> SpellFamilyFlags [ 2 ] & 0x4000 )
{
if ( caster -> GetTypeId () == TYPEID_PLAYER )
// Bonus from Glyph of Lightwell
if ( AuraEffect * modHealing = caster -> GetAuraEffect ( 55673 , 0 ))
amount *= ( 100.0f + modHealing -> GetAmount ()) / 100.0f ;
}
break ;
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN :
if ( ! caster )
break ;
// Icebound Fortitude
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x00100000 )
{
if ( caster -> GetTypeId () == TYPEID_PLAYER )
{
int32 value = int32 (( amount *- 1 ) - 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-01-10 01:23:15 +01:00
value += int32 (( defva - 400 ) * 0.15 );
// Glyph of Icebound Fortitude
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( 58625 , 0 ))
{
uint32 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 ;
}
}
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 )
amount += multiplier * level_diff ;
break ;
}
case SPELL_AURA_MOD_INCREASE_HEALTH :
// Vampiric Blood
if ( GetId () == 55233 )
amount = GetBase () -> GetUnitOwner () -> GetMaxHealth () * amount / 100 ;
break ;
case SPELL_AURA_MOD_INCREASE_ENERGY :
// Hymn of Hope
if ( GetId () == 64904 )
amount = GetBase () -> GetUnitOwner () -> GetMaxPower ( GetBase () -> GetUnitOwner () -> getPowerType ()) * amount / 100 ;
break ;
case SPELL_AURA_MOD_INCREASE_SPEED :
// Dash - do not set speed if not in cat form
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x00000008 )
amount = GetBase () -> GetUnitOwner () -> m_form == FORM_CAT ? amount : 0 ;
}
if ( DoneActualBenefit != 0.0f )
{
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellProto ());
amount += ( int32 ) DoneActualBenefit ;
}
amount *= GetBase () -> GetStackAmount ();
return amount ;
}
void AuraEffect :: CalculatePeriodic ( Unit * caster , bool create )
{
m_amplitude = m_spellProto -> EffectAmplitude [ m_effIndex ];
// prepare periodics
switch ( GetAuraType ())
{
case SPELL_AURA_OBS_MOD_POWER :
// 3 spells have no amplitude set
if ( ! m_amplitude )
m_amplitude = 1 * IN_MILISECONDS ;
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 ;
m_amplitude *= IN_MILISECONDS ;
}
break ;
}
if ( ! m_isPeriodic )
return ;
Player * modOwner = caster ? caster -> GetSpellModOwner () : NULL ;
2010-02-14 19:13:14 -07:00
// Apply casting time mods
2010-04-07 19:14:10 +02:00
if ( modOwner && m_amplitude )
2010-02-14 19:13:14 -07:00
{
// For channeled spells
if ( IsChanneledSpell ( m_spellProto )) {
modOwner -> ModSpellCastTime ( m_spellProto , m_amplitude );
}
// For spells that can benefit from haste
else if ( modOwner -> HasAuraType ( SPELL_AURA_PERIODIC_HASTE )) {
const Unit :: AuraEffectList & effList = modOwner -> GetAuraEffectsByType ( SPELL_AURA_PERIODIC_HASTE );
for ( Unit :: AuraEffectList :: const_iterator itr = effList . begin (), end = effList . end (); itr != end ; ++ itr )
{
if (( * itr ) -> IsAffectedOnSpell ( m_spellProto ))
{
float hasteMod = modOwner -> GetFloatValue ( UNIT_MOD_CAST_SPEED );
m_amplitude *= hasteMod ;
GetBase () -> SetMaxDuration ( GetBase () -> GetMaxDuration () * hasteMod );
GetBase () -> SetDuration ( GetBase () -> GetDuration () * hasteMod );
break ;
}
}
}
}
2010-01-10 01:23:15 +01:00
// Apply periodic time mod
2010-04-07 19:14:10 +02:00
if ( modOwner && m_amplitude )
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_ACTIVATION_TIME , m_amplitude );
if ( create )
{
// Start periodic on next tick or at aura apply
if ( m_amplitude && ! ( m_spellProto -> AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY ))
m_periodicTimer += m_amplitude ;
}
else if ( m_amplitude ) // load aura from character_aura
{
m_tickNumber = GetBase () -> GetDuration () / m_amplitude ;
m_periodicTimer = GetBase () -> GetDuration () % m_amplitude ;
if ( m_spellProto -> AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY )
++ m_tickNumber ;
}
}
void AuraEffect :: CalculateSpellMod ()
{
switch ( GetAuraType ())
{
case SPELL_AURA_DUMMY :
switch ( GetSpellProto () -> SpellFamilyName )
{
case SPELLFAMILY_PRIEST :
// Pain and Suffering
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> 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 ;
}
case SPELL_AURA_PROC_TRIGGER_SPELL :
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 ;
}
2010-04-11 11:43:23 +04:00
m_spellmod -> value = GetBase () -> GetUnitOwner () -> CalculateSpellDamage ( GetBase () -> GetUnitOwner (), GetSpellProto (), 1 );
2010-01-10 01:23:15 +01:00
break ;
}
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 ());
assert ( m_spellmod -> op < MAX_SPELLMOD );
m_spellmod -> type = SpellModType ( GetAuraType ()); // SpellModType value == spell aura types
m_spellmod -> spellId = GetId ();
m_spellmod -> mask = GetSpellProto () -> EffectSpellClassMask [ GetEffIndex ()];
m_spellmod -> charges = GetBase () -> GetCharges ();
}
m_spellmod -> value = GetAmount ();
break ;
}
}
void AuraEffect :: ChangeAmount ( int32 newAmount , bool mark )
{
Unit * caster = GetCaster ();
// Reapply if amount change
2010-04-08 08:20:08 +02:00
if ( newAmount != GetAmount ())
2010-01-10 01:23:15 +01:00
{
UnitList targetList ;
GetTargetList ( targetList );
for ( UnitList :: iterator aurEffTarget = targetList . begin (); aurEffTarget != targetList . end (); ++ aurEffTarget )
{
HandleEffect ( * aurEffTarget , AURA_EFFECT_HANDLE_CHANGE_AMOUNT , false );
}
if ( ! mark )
m_amount = newAmount ;
else
SetAmount ( newAmount );
CalculateSpellMod ();
for ( UnitList :: iterator aurEffTarget = targetList . begin (); aurEffTarget != targetList . end (); ++ aurEffTarget )
{
HandleEffect ( * aurEffTarget , AURA_EFFECT_HANDLE_CHANGE_AMOUNT , true );
}
}
}
void AuraEffect :: HandleEffect ( AuraApplication const * aurApp , uint8 mode , bool apply )
{
// check if call is correct
assert ( ! mode
|| mode == AURA_EFFECT_HANDLE_REAL
|| mode == AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
|| mode == AURA_EFFECT_HANDLE_CHANGE_AMOUNT
|| mode == AURA_EFFECT_HANDLE_STAT );
// real aura apply/remove, handle modifier
if ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK )
ApplySpellMod ( aurApp -> GetTarget (), apply );
( * this . * AuraEffectHandler [ GetAuraType ()])( aurApp , mode , apply );
}
void AuraEffect :: HandleEffect ( Unit * target , uint8 mode , bool apply )
{
AuraApplication const * aurApp = GetBase () -> GetApplicationOfTarget ( target -> GetGUID ());
assert ( aurApp );
HandleEffect ( aurApp , mode , apply );
}
void AuraEffect :: ApplySpellMod ( Unit * target , bool apply )
{
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
if ( GetBase () -> GetCharges ())
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 )
{
Aura * aura = iter -> second -> GetBase ();
// 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
if ( aura -> IsPassive () && aura -> GetCasterGUID () == guid && spellmgr . IsAffectedByMod ( aura -> GetSpellProto (), m_spellmod ))
{
if ( GetMiscValue () == SPELLMOD_ALL_EFFECTS )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( AuraEffect * aurEff = aura -> GetEffect ( i ))
aurEff -> RecalculateAmount ();
}
}
else if ( GetMiscValue () == SPELLMOD_EFFECT1 )
{
if ( AuraEffect * aurEff = aura -> GetEffect ( 0 ))
aurEff -> RecalculateAmount ();
}
else if ( GetMiscValue () == SPELLMOD_EFFECT2 )
{
if ( AuraEffect * aurEff = aura -> GetEffect ( 1 ))
aurEff -> RecalculateAmount ();
}
2010-04-07 23:56:35 +02:00
else //if (modOp == SPELLMOD_EFFECT3)
2010-01-10 01:23:15 +01:00
{
if ( AuraEffect * aurEff = aura -> GetEffect ( 2 ))
aurEff -> RecalculateAmount ();
}
}
}
}
default :
break ;
}
}
void AuraEffect :: Update ( uint32 diff , Unit * caster )
{
if ( m_isPeriodic && ( GetBase () -> GetDuration () >= 0 || GetBase () -> IsPassive () || GetBase () -> IsPermanent ()))
{
2010-04-07 19:14:10 +02:00
if ( m_periodicTimer > 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 );
UnitList effectTargets ;
GetTargetList ( effectTargets );
// tick on targets of effects
if ( ! caster || ! caster -> hasUnitState ( UNIT_STAT_ISOLATED ))
{
for ( UnitList :: iterator targetItr = effectTargets . begin (); targetItr != effectTargets . end (); ++ targetItr )
PeriodicTick ( * targetItr , caster );
}
}
}
}
void AuraEffect :: UpdatePeriodic ( Unit * caster )
{
switch ( GetAuraType ())
{
case SPELL_AURA_PERIODIC_DAMAGE :
switch ( GetId ())
{
case 41337 : // Aura of Anger
if ( AuraEffect * aurEff = GetBase () -> GetEffect ( 1 ))
aurEff -> ChangeAmount ( aurEff -> GetAmount () + 5 );
SetAmount ( 100 * m_tickNumber );
break ;
case 46394 : // Brutallus Burn
if ( m_tickNumber % 11 == 0 )
2010-02-14 19:13:14 -07:00
SetAmount ( GetAmount () * 2 );
2010-01-10 01:23:15 +01:00
break ;
}
break ;
case SPELL_AURA_DUMMY :
// Haunting Spirits
if ( GetId () == 7057 )
{
2010-04-07 22:59:46 +02:00
m_amplitude = irand ( 0 , 60 ) + 30 ;
2010-01-10 01:23:15 +01:00
m_amplitude *= IN_MILISECONDS ;
}
break ;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
switch ( GetId ())
{
// Sniper training
case 53302 :
case 53303 :
case 53304 :
Unit * target = GetBase () -> GetUnitOwner ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
break ;
2010-03-07 15:20:19 +01:00
if ( target -> ToPlayer () -> isMoving ())
2010-04-13 16:24:17 +04:00
m_amount = target -> CalculateSpellDamage ( target , m_spellProto , m_effIndex , & m_baseAmount );
2010-01-10 01:23:15 +01:00
else
-- m_amount ;
break ;
}
break ;
case SPELL_AURA_PERIODIC_DUMMY :
switch ( GetSpellProto () -> SpellFamilyName )
{
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
if ( AuraEffect * aurEff = GetBase () -> GetEffect ( 0 ))
{
if ( aurEff -> GetAuraType () != SPELL_AURA_MOD_POWER_REGEN )
{
m_isPeriodic = false ;
sLog . outError ( "Aura %d structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN" , GetId ());
}
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
{
//**********************************************
// This feature uses only in arenas
//**********************************************
// 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 ;
}
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
if ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x00004000 )
{
// Get 0 effect aura
if ( AuraEffect * slow = GetBase () -> GetEffect ( 0 ))
{
int32 newAmount = slow -> GetAmount () + GetAmount ();
if ( newAmount > 0 )
newAmount = 0 ;
slow -> ChangeAmount ( newAmount );
}
return ;
}
}
}
}
bool AuraEffect :: IsPeriodicTickCrit ( Unit * target , Unit const * caster ) const
{
assert ( caster );
Unit :: AuraEffectList const & mPeriodicCritAuras = caster -> GetAuraEffectsByType ( SPELL_AURA_ABILITY_PERIODIC_CRIT );
for ( Unit :: AuraEffectList :: const_iterator itr = mPeriodicCritAuras . begin (); itr != mPeriodicCritAuras . end (); ++ itr )
{
if (( * itr ) -> IsAffectedOnSpell ( m_spellProto ) && caster -> isSpellCrit ( target , m_spellProto , GetSpellSchoolMask ( m_spellProto )))
return true ;
}
return false ;
}
2010-01-24 15:20:32 +01:00
void AuraEffect :: SendTickImmune ( Unit * target , Unit * caster ) const
{
WorldPacket data ( SMSG_SPELLORDAMAGE_IMMUNE , 8 + 8 + 4 + 1 );
data << uint64 ( caster ? caster -> GetGUID () : target -> GetGUID ());
data << uint64 ( target -> GetGUID ());
data << uint32 ( m_spellProto -> Id );
data << uint8 ( 1 );
target -> SendMessageToSet ( & data , true );
}
2010-01-10 01:23:15 +01:00
void AuraEffect :: PeriodicTick ( Unit * target , Unit * caster ) const
{
2010-04-07 19:14:10 +02:00
if ( ! target -> isAlive ())
2010-01-24 15:20:32 +01:00
return ;
if ( target -> hasUnitState ( UNIT_STAT_ISOLATED ))
{
SendTickImmune ( target , caster );
2010-01-10 01:23:15 +01:00
return ;
2010-01-24 15:20:32 +01:00
}
2010-01-10 01:23:15 +01:00
switch ( GetAuraType ())
{
case SPELL_AURA_PERIODIC_DAMAGE :
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT :
{
2010-04-07 19:14:10 +02:00
if ( ! caster )
2010-01-10 01:23:15 +01:00
break ;
// Consecrate ticks can miss and will not show up in the combat log
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster -> SpellHitResult ( target , GetSpellProto (), false ) != SPELL_MISS_NONE )
break ;
// Check for immune (not use charges)
if ( target -> IsImmunedToDamage ( GetSpellProto ()))
2010-01-24 15:20:32 +01:00
{
SendTickImmune ( target , caster );
2010-01-10 01:23:15 +01:00
break ;
2010-01-24 15:20:32 +01:00
}
2010-01-10 01:23:15 +01:00
// some auras remove at specific health level or more
if ( GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
{
switch ( GetId ())
{
case 43093 : case 31956 : case 38801 : // Grievous Wound
case 35321 : case 38363 : case 39215 : // Gushing Wound
2010-04-07 19:14:10 +02:00
if ( target -> GetHealth () == target -> GetMaxHealth ())
2010-01-10 01:23:15 +01:00
{
target -> RemoveAurasDueToSpell ( GetId ());
return ;
}
break ;
case 38772 : // Grievous Wound
{
uint32 percent =
2010-04-07 23:25:02 +02:00
GetEffIndex () < 2 && GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_DUMMY ?
2010-04-11 11:43:23 +04:00
caster -> CalculateSpellDamage ( target , GetSpellProto (), GetEffIndex () + 1 ) :
2010-01-10 01:23:15 +01:00
100 ;
2010-04-07 19:14:10 +02:00
if ( target -> GetHealth () * 100 >= target -> GetMaxHealth () * percent )
2010-01-10 01:23:15 +01:00
{
target -> RemoveAurasDueToSpell ( GetId ());
return ;
}
break ;
}
}
}
uint32 absorb = 0 ;
uint32 resist = 0 ;
2010-04-07 22:59:46 +02:00
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2010-01-10 01:23:15 +01:00
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = GetAmount () > 0 ? GetAmount () : 0 ;
2010-04-07 19:14:10 +02:00
if ( GetAuraType () == SPELL_AURA_PERIODIC_DAMAGE )
2010-01-10 01:23:15 +01:00
{
damage = caster -> SpellDamageBonus ( target , GetSpellProto (), damage , DOT , GetBase () -> GetStackAmount ());
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
2010-04-07 22:59:46 +02:00
if ( GetSpellSchoolMask ( GetSpellProto ()) & SPELL_SCHOOL_MASK_NORMAL &&
2010-01-10 01:23:15 +01:00
GetEffectMechanic ( GetSpellProto (), m_effIndex ) != MECHANIC_BLEED )
{
uint32 damageReductedArmor = caster -> CalcArmorReducedDamage ( target , damage , GetSpellProto ());
cleanDamage . mitigated_damage += damage - damageReductedArmor ;
damage = damageReductedArmor ;
}
// Curse of Agony damage-per-tick calculation
2010-04-07 23:25:02 +02:00
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x400 ) && GetSpellProto () -> SpellIconID == 544 )
2010-01-10 01:23:15 +01:00
{
uint32 totalTick = GetTotalTicks ();
// 1..4 ticks, 1/2 from normal tick damage
2010-04-07 19:14:10 +02:00
if ( m_tickNumber <= totalTick / 3 )
2010-01-10 01:23:15 +01:00
damage = damage / 2 ;
// 9..12 ticks, 3/2 from normal tick damage
2010-04-07 19:14:10 +02:00
else if ( m_tickNumber > totalTick * 2 / 3 )
2010-01-10 01:23:15 +01:00
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
2010-03-21 16:03:38 +01:00
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x00004000 ))
2010-01-10 01:23:15 +01:00
{
2010-03-21 16:03:38 +01:00
if ( caster -> GetTypeId () == TYPEID_PLAYER && caster -> ToPlayer () -> isHonorOrXPTarget ( target ))
{
if ( roll_chance_i ( 20 ))
{
caster -> CastSpell ( caster , 64018 , true , 0 , this );
// Glyph of Drain Soul - chance to create an additional Soul Shard
if ( AuraEffect * aur = caster -> GetAuraEffect ( 58070 , 0 ))
if ( roll_chance_i ( aur -> GetMiscValue ()))
caster -> CastSpell ( caster , 58068 , true , 0 , aur );
}
}
2010-01-10 01:23:15 +01:00
}
}
else
damage = uint32 ( target -> GetMaxHealth () * damage / 100 );
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
2010-03-19 08:30:39 +01:00
{
2010-01-10 01:23:15 +01:00
damage = caster -> SpellCriticalDamageBonus ( m_spellProto , damage , target );
2010-03-19 08:30:39 +01:00
damage -= target -> GetSpellCritDamageReduction ( damage );
}
2010-01-10 01:23:15 +01:00
// only from players
if ( IS_PLAYER_GUID ( GetCasterGUID ()))
damage -= target -> GetSpellDamageReduction ( damage );
caster -> CalcAbsorbResist ( target , GetSpellSchoolMask ( GetSpellProto ()), DOT , damage , & absorb , & resist , m_spellProto );
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_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT ;
damage = ( damage <= absorb + resist ) ? 0 : ( damage - absorb - resist );
if ( damage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
int32 overkill = damage - target -> GetHealth ();
if ( overkill < 0 )
overkill = 0 ;
SpellPeriodicAuraLogInfo pInfo ( this , damage , overkill , absorb , resist , 0.0f , crit );
target -> SendPeriodicAuraLog ( & pInfo );
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellProto ());
caster -> DealDamage ( target , damage , & cleanDamage , DOT , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto (), true );
break ;
}
case SPELL_AURA_PERIODIC_LEECH :
{
2010-04-07 19:14:10 +02:00
if ( ! caster )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! caster -> isAlive ())
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 23:25:02 +02:00
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
2010-04-08 08:20:08 +02:00
caster -> SpellHitResult ( target , GetSpellProto (), false ) != SPELL_MISS_NONE )
2010-01-10 01:23:15 +01:00
return ;
// Check for immune
2010-04-07 19:14:10 +02:00
if ( target -> IsImmunedToDamage ( GetSpellProto ()))
2010-01-24 15:20:32 +01:00
{
SendTickImmune ( target , caster );
2010-01-10 01:23:15 +01:00
return ;
2010-01-24 15:20:32 +01:00
}
2010-01-10 01:23:15 +01:00
uint32 absorb = 0 ;
uint32 resist = 0 ;
2010-04-07 22:59:46 +02:00
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2010-01-10 01:23:15 +01:00
//uint32 damage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
uint32 damage = GetAmount () > 0 ? GetAmount () : 0 ;
damage = caster -> SpellDamageBonus ( target , GetSpellProto (), damage , DOT , GetBase () -> GetStackAmount ());
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
2010-03-19 08:47:03 +01:00
{
2010-01-10 01:23:15 +01:00
damage = caster -> SpellCriticalDamageBonus ( m_spellProto , damage , target );
2010-03-19 08:47:03 +01:00
damage -= target -> GetSpellCritDamageReduction ( damage );
}
2010-01-10 01:23:15 +01:00
//Calculate armor mitigation if it is a physical spell
if ( GetSpellSchoolMask ( GetSpellProto ()) & SPELL_SCHOOL_MASK_NORMAL )
{
uint32 damageReductedArmor = caster -> CalcArmorReducedDamage ( target , damage , GetSpellProto ());
cleanDamage . mitigated_damage += damage - damageReductedArmor ;
damage = damageReductedArmor ;
}
// Reduce dot damage from resilience for players.
if ( target -> GetTypeId () == TYPEID_PLAYER )
damage -= target -> GetSpellDamageReduction ( damage );
caster -> CalcAbsorbResist ( target , GetSpellSchoolMask ( GetSpellProto ()), DOT , damage , & absorb , & resist , m_spellProto );
2010-04-07 19:14:10 +02:00
if ( target -> GetHealth () < damage )
2010-01-10 01:23:15 +01:00
damage = uint32 ( target -> GetHealth ());
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 );
caster -> SendSpellNonMeleeDamageLog ( target , GetId (), damage , GetSpellSchoolMask ( GetSpellProto ()), absorb , resist , false , 0 , crit );
// Set trigger flag
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT ;
damage = ( damage <= absorb + resist ) ? 0 : ( damage - absorb - resist );
if ( damage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellProto ());
int32 new_damage = caster -> DealDamage ( target , damage , & cleanDamage , DOT , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto (), false );
if ( ! target -> isAlive () && caster -> IsNonMeleeSpellCasted ( false ))
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; ++ i )
if ( Spell * spell = caster -> GetCurrentSpell ( CurrentSpellTypes ( i )))
if ( spell -> m_spellInfo -> Id == GetId ())
spell -> cancel ();
float multiplier = GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()];
2010-04-07 19:14:10 +02:00
if ( Player * modOwner = caster -> GetSpellModOwner ())
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( GetSpellProto () -> Id , SPELLMOD_MULTIPLE_VALUE , multiplier );
uint32 heal = uint32 ( caster -> SpellHealingBonus ( caster , GetSpellProto (), uint32 ( new_damage * multiplier ), DOT , GetBase () -> GetStackAmount ()));
int32 gain = caster -> DealHeal ( caster , heal , GetSpellProto ());
2010-03-09 11:11:10 +01:00
caster -> getHostileRefManager (). threatAssist ( caster , gain * 0.5f , GetSpellProto ());
2010-01-10 01:23:15 +01:00
break ;
}
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL : // only three spells
{
2010-04-07 19:14:10 +02:00
if ( ! caster || ! caster -> GetHealth ())
2010-01-10 01:23:15 +01:00
break ;
uint32 damage = GetAmount ();
// do not kill health donator
2010-04-07 19:14:10 +02:00
if ( caster -> GetHealth () < damage )
2010-01-10 01:23:15 +01:00
damage = caster -> GetHealth () - 1 ;
2010-04-07 19:14:10 +02:00
if ( ! damage )
2010-01-10 01:23:15 +01:00
break ;
//donator->SendSpellNonMeleeDamageLog(donator, GetId(), damage, GetSpellSchoolMask(spellProto), 0, 0, false, 0);
caster -> ModifyHealth ( - ( int32 ) damage );
sLog . outDebug ( "PeriodicTick: donator %u target %u damage %u." , target -> GetEntry (), target -> GetEntry (), damage );
float multiplier = GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()];
2010-04-07 19:14:10 +02:00
if ( Player * modOwner = caster -> GetSpellModOwner ())
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( GetSpellProto () -> Id , SPELLMOD_MULTIPLE_VALUE , multiplier );
damage *= multiplier ;
caster -> DealHeal ( target , damage , GetSpellProto ());
break ;
}
case SPELL_AURA_PERIODIC_HEAL :
case SPELL_AURA_OBS_MOD_HEALTH :
{
2010-04-07 19:14:10 +02:00
if ( ! caster )
2010-01-10 01:23:15 +01:00
break ;
// heal for caster damage (must be alive)
2010-04-07 19:14:10 +02:00
if ( target != caster && GetSpellProto () -> AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL && ! caster -> isAlive ())
2010-01-10 01:23:15 +01:00
break ;
2010-04-07 19:14:10 +02:00
if ( GetBase () -> GetDuration () == - 1 && target -> GetHealth () == target -> GetMaxHealth ())
2010-01-10 01:23:15 +01:00
break ;
// ignore non positive values (can be result apply spellmods to aura damage
int32 damage = m_amount > 0 ? m_amount : 0 ;
2010-04-07 19:14:10 +02:00
if ( GetAuraType () == SPELL_AURA_OBS_MOD_HEALTH )
2010-01-10 01:23:15 +01:00
damage = uint32 ( target -> GetMaxHealth () * damage / 100 );
else
{
// Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellIconID == 2864 )
{
damage += float ( damage * GetTotalTicks ()) * (( 6 - float ( 2 * ( GetTickNumber () - 1 ))) / 100 );
}
damage = caster -> SpellHealingBonus ( target , GetSpellProto (), damage , DOT , GetBase () -> GetStackAmount ());
}
bool crit = IsPeriodicTickCrit ( target , caster );
if ( crit )
damage = caster -> SpellCriticalHealingBonus ( m_spellProto , damage , target );
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 ());
int32 gain = target -> ModifyHealth ( damage );
SpellPeriodicAuraLogInfo pInfo ( this , damage , damage - gain , 0 , 0 , 0.0f , crit );
target -> SendPeriodicAuraLog ( & pInfo );
// add HoTs to amount healed in bgs
2010-04-07 22:59:46 +02:00
if ( caster -> GetTypeId () == TYPEID_PLAYER )
if ( BattleGround * bg = caster -> ToPlayer () -> GetBattleGround ())
2010-03-07 15:20:19 +01:00
bg -> UpdatePlayerScore ( caster -> ToPlayer (), SCORE_HEALING_DONE , gain );
2010-01-10 01:23:15 +01:00
2010-03-09 11:11:10 +01:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellProto ());
2010-01-10 01:23:15 +01:00
bool haveCastItem = GetBase () -> GetCastItemGUID () != 0 ;
// Health Funnel
// damage caster for heal amount
2010-04-07 19:14:10 +02:00
if ( target != caster && GetSpellProto () -> AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL )
2010-01-10 01:23:15 +01:00
{
uint32 damage = gain ;
uint32 absorb = 0 ;
caster -> DealDamageMods ( caster , damage , & absorb );
caster -> SendSpellNonMeleeDamageLog ( caster , GetId (), damage , GetSpellSchoolMask ( GetSpellProto ()), absorb , 0 , false , 0 , false );
2010-04-07 22:59:46 +02:00
CleanDamage cleanDamage = CleanDamage ( 0 , 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2010-01-10 01:23:15 +01:00
caster -> DealDamage ( caster , damage , & cleanDamage , NODAMAGE , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto (), true );
}
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_HOT ;
// ignore item heals
2010-04-07 19:14:10 +02:00
if ( ! haveCastItem )
2010-01-10 01:23:15 +01:00
caster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , damage , BASE_ATTACK , GetSpellProto ());
break ;
}
case SPELL_AURA_PERIODIC_MANA_LEECH :
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () < 0 || GetMiscValue () >= MAX_POWERS )
2010-01-10 01:23:15 +01:00
break ;
Powers power = Powers ( GetMiscValue ());
// power type might have changed between aura applying and tick (druid's shapeshift)
2010-04-07 19:14:10 +02:00
if ( target -> getPowerType () != power )
2010-01-10 01:23:15 +01:00
break ;
2010-04-07 19:14:10 +02:00
if ( ! caster || ! caster -> isAlive ())
2010-01-10 01:23:15 +01:00
break ;
2010-04-07 23:25:02 +02:00
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
2010-01-10 01:23:15 +01:00
caster -> SpellHitResult ( target , GetSpellProto (), false ) != SPELL_MISS_NONE )
break ;
// Check for immune (not use charges)
2010-04-07 19:14:10 +02:00
if ( target -> IsImmunedToDamage ( GetSpellProto ()))
2010-01-24 15:20:32 +01:00
{
SendTickImmune ( target , caster );
2010-01-10 01:23:15 +01:00
break ;
2010-01-24 15:20:32 +01:00
}
2010-01-10 01:23:15 +01:00
// ignore non positive values (can be result apply spellmods to aura damage
uint32 damage = m_amount > 0 ? 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
if ( m_spellProto -> ManaCostPercentage )
{
// max value
uint32 maxmana = caster -> GetMaxPower ( power ) * damage * 2 / 100 ;
damage = target -> GetMaxPower ( power ) * damage / 100 ;
2010-04-07 19:14:10 +02:00
if ( damage > maxmana )
2010-01-10 01:23:15 +01:00
damage = maxmana ;
}
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 (), damage , GetId ());
int32 drain_amount = target -> GetPower ( power ) > damage ? damage : target -> GetPower ( power );
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( power == POWER_MANA )
drain_amount -= target -> GetSpellCritDamageReduction ( drain_amount );
target -> ModifyPower ( power , - drain_amount );
float gain_multiplier = 0.0f ;
2010-04-07 19:14:10 +02:00
if ( caster -> GetMaxPower ( power ) > 0 )
2010-01-10 01:23:15 +01:00
{
gain_multiplier = GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()];
2010-04-07 19:14:10 +02:00
if ( Player * modOwner = caster -> GetSpellModOwner ())
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_MULTIPLE_VALUE , gain_multiplier );
}
SpellPeriodicAuraLogInfo pInfo ( this , drain_amount , 0 , 0 , 0 , gain_multiplier , false );
target -> SendPeriodicAuraLog ( & pInfo );
int32 gain_amount = int32 ( drain_amount * gain_multiplier );
2010-04-07 19:14:10 +02:00
if ( gain_amount )
2010-01-10 01:23:15 +01:00
{
int32 gain = caster -> ModifyPower ( power , gain_amount );
target -> AddThreat ( caster , float ( gain ) * 0.5f , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto ());
}
switch ( GetId ())
{
case 31447 : // Mark of Kaz'rogal
2010-04-07 19:14:10 +02:00
if ( target -> GetPower ( power ) == 0 )
2010-01-10 01:23:15 +01:00
{
target -> CastSpell ( target , 31463 , true , 0 , this );
// Remove aura
GetBase () -> SetDuration ( 0 );
}
break ;
case 32960 : // Mark of Kazzak
int32 modifier = ( target -> GetPower ( power ) * 0.05f );
target -> ModifyPower ( power , - modifier );
2010-04-07 19:14:10 +02:00
if ( target -> GetPower ( power ) == 0 )
2010-01-10 01:23:15 +01:00
{
target -> CastSpell ( target , 32961 , true , 0 , this );
// Remove aura
GetBase () -> SetDuration ( 0 );
}
}
// Drain Mana
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_WARLOCK
&& m_spellProto -> SpellFamilyFlags [ 0 ] & 0x00000010 )
{
int32 manaFeedVal = 0 ;
if ( AuraEffect const * aurEff = GetBase () -> GetEffect ( 1 ))
manaFeedVal = aurEff -> GetAmount ();
// Mana Feed - Drain Mana
2010-04-07 19:14:10 +02:00
if ( manaFeedVal > 0 )
2010-01-10 01:23:15 +01:00
{
manaFeedVal = manaFeedVal * gain_amount / 100 ;
caster -> CastCustomSpell ( caster , 32554 , & manaFeedVal , NULL , NULL , true , NULL , this );
}
}
break ;
}
case SPELL_AURA_OBS_MOD_POWER :
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () < 0 )
2010-01-10 01:23:15 +01:00
return ;
Powers power ;
if ( GetMiscValue () == POWER_ALL )
power = target -> getPowerType ();
else
power = Powers ( GetMiscValue ());
2010-04-07 19:14:10 +02:00
if ( target -> GetMaxPower ( power ) == 0 )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( GetBase () -> GetDuration () == - 1 && target -> GetPower ( power ) == target -> GetMaxPower ( power ))
2010-01-10 01:23:15 +01:00
return ;
uint32 amount = m_amount * target -> GetMaxPower ( power ) / 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 ());
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f , false );
target -> SendPeriodicAuraLog ( & pInfo );
int32 gain = target -> ModifyPower ( power , amount );
2010-04-07 19:14:10 +02:00
if ( caster )
2010-03-09 11:11:10 +01:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellProto ());
2010-01-10 01:23:15 +01:00
break ;
}
case SPELL_AURA_PERIODIC_ENERGIZE :
{
// ignore non positive values (can be result apply spellmods to aura damage
2010-04-07 19:14:10 +02:00
if ( m_amount < 0 || GetMiscValue () >= MAX_POWERS )
2010-01-10 01:23:15 +01:00
return ;
Powers power = Powers ( GetMiscValue ());
2010-04-07 19:14:10 +02:00
if ( target -> GetMaxPower ( power ) == 0 )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 23:56:35 +02:00
if ( GetBase () -> GetDuration () == - 1 && target -> GetPower ( power ) == target -> GetMaxPower ( power ))
2010-01-10 01:23:15 +01:00
return ;
uint32 amount = m_amount ;
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f , false );
target -> SendPeriodicAuraLog ( & pInfo );
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 ());
int32 gain = target -> ModifyPower ( power , amount );
2010-04-07 19:14:10 +02:00
if ( caster )
2010-03-09 11:11:10 +01:00
target -> getHostileRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellProto ());
2010-01-10 01:23:15 +01:00
break ;
}
case SPELL_AURA_POWER_BURN_MANA :
{
2010-04-07 19:14:10 +02:00
if ( ! caster )
2010-01-10 01:23:15 +01:00
return ;
// Check for immune (not use charges)
2010-04-07 19:14:10 +02:00
if ( target -> IsImmunedToDamage ( GetSpellProto ()))
2010-01-24 15:20:32 +01:00
{
SendTickImmune ( target , caster );
2010-01-10 01:23:15 +01:00
return ;
2010-01-24 15:20:32 +01:00
}
2010-01-10 01:23:15 +01:00
int32 damage = m_amount > 0 ? m_amount : 0 ;
Powers powerType = Powers ( GetMiscValue ());
2010-04-07 19:14:10 +02:00
if ( ! target -> isAlive () || target -> getPowerType () != powerType )
2010-01-10 01:23:15 +01:00
return ;
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( powerType == POWER_MANA )
damage -= target -> GetSpellCritDamageReduction ( damage );
uint32 gain = uint32 ( - target -> ModifyPower ( powerType , - damage ));
gain = uint32 ( gain * GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()]);
SpellEntry const * spellProto = GetSpellProto ();
//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 , gain , spellProto );
caster -> DealDamageMods ( damageInfo . target , damageInfo . damage , & damageInfo . absorb );
caster -> SendSpellNonMeleeDamageLog ( & damageInfo );
// Set trigger flag
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = createProcExtendMask ( & damageInfo , SPELL_MISS_NONE ) | PROC_EX_INTERNAL_DOT ;
if ( damageInfo . damage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
caster -> ProcDamageAndSpell ( damageInfo . target , procAttacker , procVictim , procEx , damageInfo . damage , BASE_ATTACK , spellProto );
caster -> DealSpellDamage ( & damageInfo , true );
break ;
}
case SPELL_AURA_DUMMY :
// Haunting Spirits
if ( GetId () == 7057 )
target -> CastSpell (( Unit * ) NULL , GetAmount () , true );
break ;
case SPELL_AURA_PERIODIC_DUMMY :
PeriodicDummyTick ( target , caster );
break ;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
TriggerSpell ( target , caster );
break ;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE :
TriggerSpellWithValue ( target , caster );
break ;
}
}
void AuraEffect :: PeriodicDummyTick ( Unit * target , Unit * caster ) const
{
switch ( GetSpellProto () -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
switch ( GetId ())
{
// Forsaken Skills
case 7054 :
{
// Possibly need cast one of them (but
// 7038 Forsaken Skill: Swords
// 7039 Forsaken Skill: Axes
// 7040 Forsaken Skill: Daggers
// 7041 Forsaken Skill: Maces
// 7042 Forsaken Skill: Staves
// 7043 Forsaken Skill: Bows
// 7044 Forsaken Skill: Guns
// 7045 Forsaken Skill: 2H Axes
// 7046 Forsaken Skill: 2H Maces
// 7047 Forsaken Skill: 2H Swords
// 7048 Forsaken Skill: Defense
// 7049 Forsaken Skill: Fire
// 7050 Forsaken Skill: Frost
// 7051 Forsaken Skill: Holy
// 7053 Forsaken Skill: Shadow
return ;
}
case 45472 : // Parachute
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
Player * plr = ( Player * ) target ;
if ( plr -> IsFalling ())
{
plr -> RemoveAurasDueToSpell ( 45472 );
plr -> CastSpell ( plr , 44795 , true );
}
}
break ;
2010-04-11 13:05:22 +02:00
case 51685 : // Prey on the Weak
case 51686 :
case 51687 :
case 51688 :
case 51689 :
if ( target -> getVictim () && ( target -> GetHealth () * 100 / target -> GetMaxHealth () > target -> getVictim () -> GetHealth () * 100 / target -> getVictim () -> GetMaxHealth ())) {
if ( ! target -> HasAura ( 58670 )) {
int32 basepoints = GetSpellProto () -> EffectBasePoints [ 0 ];
target -> CastCustomSpell ( target , 58670 , & basepoints , 0 , 0 , true );
}
}
else
target -> RemoveAurasDueToSpell ( 58670 );
break ;
2010-02-15 18:23:39 +01:00
case 58600 : // No fly Zone - Dalaran
2010-01-10 01:23:15 +01:00
if ( GetTickNumber () == 10 )
{
target -> RemoveAurasByType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED );
target -> RemoveAurasByType ( SPELL_AURA_FLY );
}
break ;
case 62292 : // Blaze (Pool of Tar)
// should we use custom damage?
target -> CastSpell (( Unit * ) NULL , m_spellProto -> EffectTriggerSpell [ m_effIndex ], true );
break ;
case 62399 : // Overload Circuit
2010-04-07 19:14:10 +02:00
if ( target -> GetMap () -> IsDungeon () && target -> GetAppliedAuras (). count ( 62399 ) >= ( target -> GetMap () -> IsHeroic () ? 4 : 2 ))
2010-01-10 01:23:15 +01:00
{
target -> CastSpell ( target , 62475 , true ); // System Shutdown
2010-04-07 19:14:10 +02:00
if ( Unit * veh = target -> GetVehicleBase ())
2010-01-10 01:23:15 +01:00
veh -> CastSpell ( target , 62475 , true );
}
break ;
case 64821 : // Fuse Armor (Razorscale)
2010-04-07 19:14:10 +02:00
if ( GetBase () -> GetStackAmount () == GetSpellProto () -> StackAmount )
2010-01-10 01:23:15 +01:00
{
target -> CastSpell ( target , 64774 , true , NULL , NULL , GetCasterGUID ());
target -> RemoveAura ( 64821 );
}
break ;
}
break ;
case SPELLFAMILY_MAGE :
{
// Mirror Image
if ( GetId () == 55342 )
// Set name of summons to name of caster
target -> CastSpell (( Unit * ) NULL , m_spellProto -> EffectTriggerSpell [ m_effIndex ], true );
break ;
}
case SPELLFAMILY_WARLOCK :
{
switch ( GetSpellProto () -> Id )
{
// Demonic Circle
case 48018 :
2010-04-07 19:14:10 +02:00
if ( GameObject * obj = target -> GetGameObject ( GetSpellProto () -> Id ))
2010-01-10 01:23:15 +01:00
{
if ( target -> IsWithinDist ( obj , GetSpellMaxRange ( 48020 , true )))
{
if ( ! target -> HasAura ( 62388 ))
target -> CastSpell ( target , 62388 , true );
}
else
target -> RemoveAura ( 62388 );
}
break ;
}
break ;
}
case SPELLFAMILY_DRUID :
{
switch ( GetSpellProto () -> Id )
{
// 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
2010-04-08 08:20:08 +02:00
if ( target -> getPowerType () != POWER_RAGE )
2010-01-10 01:23:15 +01:00
break ;
uint32 rage = target -> GetPower ( POWER_RAGE );
// Nothing todo
if ( rage == 0 )
break ;
int32 mod = ( rage < 100 ) ? rage : 100 ;
2010-04-11 11:43:23 +04:00
int32 points = target -> CalculateSpellDamage ( target , GetSpellProto (), 1 );
2010-01-10 01:23:15 +01: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 ;
}
// Force of Nature
case 33831 :
break ;
}
break ;
}
case SPELLFAMILY_ROGUE :
{
switch ( GetSpellProto () -> Id )
{
// Master of Subtlety
case 31666 :
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
target -> RemoveAurasDueToSpell ( 31665 );
break ;
// Killing Spree
2010-04-07 18:09:10 +02:00
case 51690 :
2010-01-10 01:23:15 +01:00
{
// TODO: this should use effect[1] of 51690
UnitList targets ;
{
2010-04-07 23:56:35 +02:00
// eff_radius == 0
2010-01-10 01:23:15 +01:00
float radius = GetSpellMaxRange ( GetSpellProto (), false );
CellPair p ( Trinity :: ComputeCellPair ( caster -> GetPositionX (), caster -> GetPositionY ()));
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
Trinity :: AnyUnfriendlyVisibleUnitInObjectRangeCheck u_check ( caster , caster , radius );
Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > checker ( caster , targets , u_check );
TypeContainerVisitor < Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > , GridTypeMapContainer > grid_object_checker ( checker );
TypeContainerVisitor < Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > , WorldTypeMapContainer > world_object_checker ( checker );
2010-01-23 22:24:41 +01:00
cell . Visit ( p , grid_object_checker , * GetBase () -> GetOwner () -> GetMap (), * caster , radius );
cell . Visit ( p , world_object_checker , * GetBase () -> GetOwner () -> GetMap (), * caster , radius );
2010-01-10 01:23:15 +01:00
}
2010-04-07 19:14:10 +02:00
if ( targets . empty ())
2010-01-10 01:23:15 +01:00
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 );
break ;
}
// Overkill
case 58428 :
if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
target -> RemoveAurasDueToSpell ( 58427 );
break ;
}
break ;
}
case SPELLFAMILY_HUNTER :
{
// Explosive Shot
if ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x80000000 )
{
2010-04-07 19:14:10 +02:00
if ( caster )
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( 53352 , SPELLVALUE_BASE_POINT0 , m_amount , target , true , NULL , this );
break ;
}
switch ( GetSpellProto () -> Id )
{
// Feeding Frenzy Rank 1
case 53511 :
2010-04-07 22:59:46 +02:00
if ( target -> getVictim () && target -> getVictim () -> GetHealth () * 100 < target -> getVictim () -> GetMaxHealth () * 35 )
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 60096 , true , 0 , this );
return ;
// Feeding Frenzy Rank 2
case 53512 :
2010-04-07 22:59:46 +02:00
if ( target -> getVictim () && target -> getVictim () -> GetHealth () * 100 < target -> getVictim () -> GetMaxHealth () * 35 )
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 60097 , true , 0 , this );
return ;
default :
break ;
}
break ;
}
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 -> GetMaxHealth () * 0.01f );
target -> DealDamage ( target , damage , NULL , DIRECT_DAMAGE , SPELL_SCHOOL_MASK_NORMAL , NULL , false );
break ;
}
// Death and Decay
if ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x20 )
{
if ( caster )
caster -> CastCustomSpell ( target , 52212 , & m_amount , NULL , NULL , true , 0 , this );
break ;
}
// Blood of the North
// Reaping
// Death Rune Mastery
if ( GetSpellProto () -> SpellIconID == 3041 || GetSpellProto () -> SpellIconID == 22 || GetSpellProto () -> SpellIconID == 2622 )
{
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-04-07 19:14:10 +02:00
if ( target -> ToPlayer () -> getClass () != CLASS_DEATH_KNIGHT )
2010-01-10 01:23:15 +01:00
return ;
// timer expired - remove death runes
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> RemoveRunesByAuraEffect ( this );
2010-01-10 01:23:15 +01:00
}
break ;
}
}
Unit * AuraEffect :: GetTriggerTarget ( Unit * target ) const
{
if ( target -> GetTypeId () == TYPEID_UNIT )
2010-02-04 18:34:46 +01:00
{
2010-03-07 18:30:53 +01:00
if ( Unit * trigger = target -> ToCreature () -> AI () -> GetAuraEffectTriggerTarget ( GetId (), GetEffIndex ()))
2010-02-04 18:34:46 +01:00
return trigger ;
}
return target ;
2010-01-10 01:23:15 +01:00
}
2010-02-04 18:34:46 +01:00
void AuraEffect :: TriggerSpell ( Unit * target , Unit * caster ) const
{
2010-04-07 19:14:10 +02:00
if ( ! caster || ! target )
2010-01-10 01:23:15 +01:00
return ;
2010-02-04 18:34:46 +01:00
Unit * triggerTarget = GetTriggerTarget ( target );
2010-01-10 01:23:15 +01:00
// generic casting code with custom spells and target/caster customs
uint32 triggerSpellId = GetSpellProto () -> EffectTriggerSpell [ GetEffIndex ()];
SpellEntry const * triggeredSpellInfo = sSpellStore . LookupEntry ( triggerSpellId );
SpellEntry const * auraSpellInfo = GetSpellProto ();
uint32 auraId = auraSpellInfo -> Id ;
// specific code for cases with no trigger spell provided in field
if ( triggeredSpellInfo == NULL )
{
switch ( auraSpellInfo -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
{
switch ( auraId )
{
// Thaumaturgy Channel
case 9712 :
triggerSpellId = 21029 ;
break ;
// Brood Affliction: Bronze
case 23170 :
2010-02-04 18:34:46 +01:00
triggerSpellId = 23171 ;
2010-01-10 01:23:15 +01:00
return ;
// Restoration
2010-02-04 18:34:46 +01:00
case 24379 :
2010-01-10 01:23:15 +01:00
case 23493 :
{
int32 heal = caster -> GetMaxHealth () / 10 ;
caster -> DealHeal ( target , heal , auraSpellInfo );
int32 mana = caster -> GetMaxPower ( POWER_MANA );
if ( mana )
{
mana /= 10 ;
caster -> EnergizeBySpell ( caster , 23493 , mana , POWER_MANA );
}
return ;
}
// Nitrous Boost
case 27746 :
if ( target -> GetPower ( POWER_MANA ) >= 10 )
{
2010-04-07 22:59:46 +02:00
target -> ModifyPower ( POWER_MANA , - 10 );
2010-01-10 01:23:15 +01:00
target -> SendEnergizeSpellLog ( caster , 27746 , - 10 , POWER_MANA );
}
else
target -> RemoveAurasDueToSpell ( 27746 );
return ;
// Frost Blast
case 27808 :
2010-01-28 19:30:15 +01:00
caster -> CastCustomSpell ( 29879 , SPELLVALUE_BASE_POINT0 , ( float ) target -> GetMaxHealth () * 0.21f , target , true , NULL , this );
2010-01-10 01:23:15 +01:00
return ;
// Detonate Mana
case 27819 :
2010-04-07 19:14:10 +02:00
if ( int32 mana = ( int32 )( target -> GetMaxPower ( POWER_MANA ) / 10 ))
2010-01-10 01:23:15 +01:00
{
mana = target -> ModifyPower ( POWER_MANA , - mana );
2010-01-28 19:30:15 +01:00
target -> CastCustomSpell ( 27820 , SPELLVALUE_BASE_POINT0 , - mana * 10 , target , true , NULL , this );
2010-01-10 01:23:15 +01:00
}
return ;
// Inoculate Nestlewood Owlkin
case 29528 :
2010-04-08 08:20:08 +02:00
if ( triggerTarget -> GetTypeId () != TYPEID_UNIT ) // prevent error reports in case ignored player target
2010-01-10 01:23:15 +01:00
return ;
break ;
// Feed Captured Animal
case 29917 :
triggerSpellId = 29916 ;
break ;
// Extract Gas
case 30427 :
{
// move loot to player inventory and despawn target
2010-04-07 23:56:35 +02:00
if ( caster -> GetTypeId () == TYPEID_PLAYER &&
2010-01-10 01:23:15 +01:00
triggerTarget -> GetTypeId () == TYPEID_UNIT &&
2010-03-07 18:30:53 +01:00
triggerTarget -> ToCreature () -> GetCreatureInfo () -> type == CREATURE_TYPE_GAS_CLOUD )
2010-01-10 01:23:15 +01:00
{
Player * player = ( Player * ) caster ;
2010-03-07 18:30:53 +01:00
Creature * creature = triggerTarget -> ToCreature ();
2010-01-10 01:23:15 +01:00
// missing lootid has been reported on startup - just return
if ( ! creature -> GetCreatureInfo () -> SkinLootId )
return ;
player -> AutoStoreLoot ( creature -> GetCreatureInfo () -> SkinLootId , LootTemplates_Skinning , true );
creature -> ForcedDespawn ();
}
return ;
}
// Quake
case 30576 : triggerSpellId = 30571 ; break ;
// Doom
2010-02-04 18:34:46 +01:00
// 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
2010-01-10 01:23:15 +01:00
case 31347 :
{
target -> CastSpell ( target , 31350 , true , NULL , this );
target -> Kill ( target );
return ;
}
// Spellcloth
case 31373 :
{
// Summon Elemental after create item
target -> SummonCreature ( 17870 , 0 , 0 , 0 , target -> GetOrientation (), TEMPSUMMON_DEAD_DESPAWN , 0 );
return ;
}
// Flame Quills
case 34229 :
{
// cast 24 spells 34269-34289, 34314-34316
for ( uint32 spell_id = 34269 ; spell_id != 34290 ; ++ spell_id )
caster -> CastSpell ( target , spell_id , true , NULL , this );
for ( uint32 spell_id = 34314 ; spell_id != 34317 ; ++ spell_id )
caster -> CastSpell ( target , spell_id , true , NULL , this );
return ;
}
// Remote Toy
case 37027 : triggerSpellId = 37029 ; break ;
// Eye of Grillok
case 38495 :
{
target -> CastSpell ( target , 38530 , true , NULL , this );
return ;
}
// Absorb Eye of Grillok (Zezzak's Shard)
case 38554 :
{
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_UNIT )
2010-01-10 01:23:15 +01:00
return ;
caster -> CastSpell ( caster , 38495 , true , NULL , this );
2010-03-07 18:30:53 +01:00
Creature * creatureTarget = target -> ToCreature ();
2010-01-10 01:23:15 +01:00
creatureTarget -> ForcedDespawn ();
return ;
}
// 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 ;
}
break ;
}
case SPELLFAMILY_MAGE :
{
switch ( auraId )
{
// Invisibility
case 66 :
// Here need periodic triger reducing threat spell (or do it manually)
return ;
}
break ;
}
case SPELLFAMILY_DRUID :
{
switch ( auraId )
{
// Cat Form
// triggerSpellId not set and unknown effect triggered in this case, ignoring for while
case 768 :
return ;
}
break ;
}
case SPELLFAMILY_HUNTER :
{
switch ( auraId )
{
// Sniper training
case 53302 :
case 53303 :
case 53304 :
// We are standing at the moment
if ( GetAmount () != - 1 )
return ;
triggerSpellId = 64418 + auraId - 53302 ;
// If aura is active - no need to continue
if ( target -> HasAura ( triggerSpellId ))
return ;
break ;
}
break ;
}
case SPELLFAMILY_SHAMAN :
{
switch ( auraId )
{
// Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
case 28820 :
{
// 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 )
{
2010-04-07 19:14:10 +02:00
if ( ! target -> m_SummonSlot [ i ])
2010-01-10 01:23:15 +01:00
{
all = false ;
break ;
}
}
2010-04-07 19:14:10 +02:00
if ( all )
2010-01-10 01:23:15 +01:00
caster -> CastSpell ( target , 38437 , true , NULL , this );
else
target -> RemoveAurasDueToSpell ( 38437 );
return ;
}
}
break ;
}
}
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore . LookupEntry ( triggerSpellId );
}
else
{
// Spell exist but require custom code
switch ( auraId )
{
// Mana Tide
case 16191 :
{
2010-02-04 18:34:46 +01:00
target -> CastCustomSpell ( triggerTarget , triggerSpellId , & m_amount , NULL , NULL , true , NULL , this );
2010-01-10 01:23:15 +01:00
return ;
}
// Negative Energy Periodic
case 46284 :
caster -> CastCustomSpell ( triggerSpellId , SPELLVALUE_MAX_TARGETS , m_tickNumber / 10 + 1 , NULL , true , NULL , this );
return ;
// Poison (Grobbulus)
case 28158 :
case 54362 :
target -> CastCustomSpell ( triggerSpellId , SPELLVALUE_RADIUS_MOD , ( int32 )(((( float ) m_tickNumber / 60 ) * 0.9f + 0.1f ) * 10000 ), NULL , true , NULL , this );
return ;
}
}
2010-04-07 19:14:10 +02:00
if ( triggeredSpellInfo )
2010-01-10 01:23:15 +01:00
{
2010-02-20 23:57:54 +01:00
Unit * triggerCaster = GetTriggeredSpellCaster ( triggeredSpellInfo , caster , triggerTarget );
triggerCaster -> CastSpell ( triggerTarget , triggeredSpellInfo , true , 0 , this );
2010-02-04 18:34:46 +01:00
sLog . outDebug ( "AuraEffect::TriggerSpell: Spell %u Trigger %u" , GetId (), triggeredSpellInfo -> Id );
2010-01-10 01:23:15 +01:00
}
2010-04-08 08:20:08 +02:00
else if ( target -> GetTypeId () != TYPEID_UNIT || ! sScriptMgr . EffectDummyCreature ( caster , GetId (), GetEffIndex (), triggerTarget -> ToCreature ()))
2010-01-10 01:23:15 +01:00
sLog . outError ( "AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?" , GetId (), GetEffIndex ());
}
void AuraEffect :: TriggerSpellWithValue ( Unit * target , Unit * caster ) const
{
2010-04-07 19:14:10 +02:00
if ( ! caster || ! target )
2010-01-10 01:23:15 +01:00
return ;
2010-02-04 18:34:46 +01:00
Unit * triggerTarget = GetTriggerTarget ( target );
2010-01-10 01:23:15 +01:00
2010-02-04 18:34:46 +01:00
uint32 triggerSpellId = GetSpellProto () -> EffectTriggerSpell [ m_effIndex ];
SpellEntry const * triggeredSpellInfo = sSpellStore . LookupEntry ( triggerSpellId );
2010-04-07 19:14:10 +02:00
if ( triggeredSpellInfo )
2010-02-04 18:34:46 +01:00
{
2010-02-20 23:57:54 +01:00
Unit * triggerCaster = GetTriggeredSpellCaster ( triggeredSpellInfo , caster , triggerTarget );
2010-02-04 18:34:46 +01:00
// generic casting code with custom spells and target/caster customs
int32 basepoints0 = GetAmount ();
triggerCaster -> CastCustomSpell ( triggerTarget , triggerSpellId , & basepoints0 , 0 , 0 , true , 0 , this );
}
else
sLog . outError ( "AuraEffect::TriggerSpellWithValue: Spell %u have 0 in EffectTriggered[%d], not handled custom case?" , GetId (), GetEffIndex ());
2010-01-10 01:23:15 +01:00
}
bool AuraEffect :: IsAffectedOnSpell ( SpellEntry const * spell ) const
{
if ( ! spell )
return false ;
// Check family name
if ( spell -> SpellFamilyName != m_spellProto -> SpellFamilyName )
return false ;
// Check EffectClassMask
if ( m_spellProto -> EffectSpellClassMask [ m_effIndex ] & spell -> SpellFamilyFlags )
return true ;
return false ;
}
void AuraEffect :: CleanupTriggeredSpells ( Unit * target )
{
uint32 tSpellId = m_spellProto -> EffectTriggerSpell [ GetEffIndex ()];
2010-04-07 19:14:10 +02:00
if ( ! tSpellId )
2010-01-10 01:23:15 +01:00
return ;
SpellEntry const * tProto = sSpellStore . LookupEntry ( tSpellId );
2010-04-07 19:14:10 +02:00
if ( ! tProto )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( GetSpellDuration ( tProto ) != - 1 )
2010-01-10 01:23:15 +01:00
return ;
// needed for spell 43680, maybe others
// TODO: is there a spell flag, which can solve this in a more sophisticated way?
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> EffectApplyAuraName [ GetEffIndex ()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
2010-01-10 01:23:15 +01:00
GetSpellDuration ( m_spellProto ) == m_spellProto -> EffectAmplitude [ GetEffIndex ()])
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 ;
2010-01-13 10:08:49 +01:00
spellId2 = 69366 ;
2010-01-10 01:23:15 +01:00
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_GHOSTWOLF :
spellId = 67116 ;
break ;
case FORM_GHOUL :
case FORM_AMBIENT :
case FORM_STEALTH :
case FORM_CREATURECAT :
case FORM_CREATUREBEAR :
break ;
}
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
// Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
if ( spellId )
{
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-11 20:51:31 +01:00
target -> ToPlayer () -> RemoveSpellCooldown ( spellId );
2010-04-07 22:59:46 +02:00
target -> CastSpell ( target , spellId , true , NULL , this );
2010-01-10 01:23:15 +01:00
}
if ( spellId2 )
{
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-11 20:51:31 +01:00
target -> ToPlayer () -> RemoveSpellCooldown ( spellId2 );
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , spellId2 , true , NULL , this );
}
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2010-03-11 20:51:31 +01:00
const PlayerSpellMap & sp_list = target -> ToPlayer () -> GetSpellMap ();
2010-01-10 01:23:15 +01:00
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
{
2010-04-07 19:14:10 +02:00
if ( itr -> second -> state == PLAYERSPELL_REMOVED || itr -> second -> disabled ) continue ;
2010-04-07 23:25:02 +02:00
if ( itr -> first == spellId || itr -> first == spellId2 ) continue ;
2010-01-10 01:23:15 +01:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( itr -> first );
if ( ! spellInfo || ! ( spellInfo -> Attributes & ( SPELL_ATTR_PASSIVE | ( 1 << 7 )))) continue ;
if ( spellInfo -> Stances & ( 1 << ( GetMiscValue () - 1 )))
target -> CastSpell ( target , itr -> first , true , NULL , this );
}
// Leader of the Pack
2010-03-07 15:20:19 +01:00
if ( target -> ToPlayer () -> HasSpell ( 17007 ))
2010-01-10 01:23:15 +01:00
{
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( 24932 );
if ( spellInfo && spellInfo -> Stances & ( 1 << ( GetMiscValue () - 1 )))
target -> CastSpell ( target , 24932 , true , NULL , this );
}
// Improved Barkskin - apply/remove armor bonus due to shapeshift
2010-03-07 15:20:19 +01:00
if ( target -> ToPlayer () -> HasSpell ( 63410 ) || target -> ToPlayer () -> HasSpell ( 63411 ))
2010-01-10 01:23:15 +01: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 )
{
Unit :: AuraEffectList const & mModTotalStatPct = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE );
for ( Unit :: AuraEffectList :: const_iterator i = mModTotalStatPct . begin (); i != mModTotalStatPct . end (); ++ i )
{
if (( * i ) -> GetSpellProto () -> SpellIconID == 240 && ( * i ) -> GetMiscValue () == 3 )
{
int32 HotWMod = ( * i ) -> GetAmount ();
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () == FORM_CAT )
2010-01-10 01:23:15 +01:00
HotWMod /= 2 ;
target -> CastCustomSpell ( target , HotWSpellId , & HotWMod , NULL , NULL , true , NULL , this );
break ;
}
}
}
switch ( GetMiscValue ())
{
case FORM_CAT :
2010-04-07 17:24:07 +02:00
// Savage Roar
2010-02-15 18:46:41 +01:00
if ( AuraEffect const * aurEff = target -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_DRUID , 0 , 0x10000000 , 0 ))
target -> CastSpell ( target , 62071 , true );
2010-01-10 01:23:15 +01:00
// Nurturing Instinct
if ( AuraEffect const * aurEff = target -> GetAuraEffect ( SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT , SPELLFAMILY_DRUID , 2254 , 0 ))
{
uint32 spellId = 0 ;
switch ( aurEff -> GetId ())
{
case 33872 :
spellId = 47179 ;
break ;
case 33873 :
spellId = 47180 ;
break ;
}
target -> CastSpell ( target , spellId , true , NULL , this );
}
// Master Shapeshifter - Cat
if ( AuraEffect const * aurEff = target -> GetDummyAuraEffect ( SPELLFAMILY_GENERIC , 2851 , 0 ))
{
int32 bp = aurEff -> GetAmount ();
target -> CastCustomSpell ( target , 48420 , & bp , NULL , NULL , true );
}
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 ))
{
2010-04-11 11:43:23 +04:00
int32 bp = target -> CalculateSpellDamage ( target , GetSpellProto (), 2 );
2010-01-10 01:23:15 +01: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 ;
}
}
}
else
{
if ( spellId )
target -> RemoveAurasDueToSpell ( spellId );
if ( spellId2 )
target -> RemoveAurasDueToSpell ( spellId2 );
// Improved Barkskin - apply/remove armor bonus due to shapeshift
2010-03-08 17:20:25 +01:00
if ( Player * pl = target -> ToPlayer ())
2010-01-10 01:23:15 +01:00
{
2010-03-08 17:20:25 +01:00
if ( pl -> HasSpell ( 63410 ) || pl -> HasSpell ( 63411 ))
{
target -> RemoveAurasDueToSpell ( 66530 );
target -> CastSpell ( target , 66530 , true );
}
2010-01-10 01:23:15 +01: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 ;
}
}
}
/*********************************************************/
/*** AURA EFFECT HANDLERS ***/
/*********************************************************/
/**************************************/
/*** VISIBILITY & PHASES ***/
/**************************************/
void AuraEffect :: HandleInvisibilityDetect ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
target -> m_detectInvisibilityMask |= ( 1 << GetMiscValue ());
}
else
{
// recalculate value at modifier remove (current aura already removed)
target -> m_detectInvisibilityMask = 0 ;
Unit :: AuraEffectList const & auras = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_INVISIBILITY_DETECTION );
for ( Unit :: AuraEffectList :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
target -> m_detectInvisibilityMask |= ( 1 << GetMiscValue ());
}
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-02-27 15:25:14 +02:00
target -> UpdateObjectVisibility ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleInvisibility ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
target -> m_invisibilityMask |= ( 1 << GetMiscValue ());
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
// drop flag at invisibiliy in bg
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
// apply glow vision
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( PLAYER_FIELD_BYTES2 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2010-02-27 15:25:14 +02:00
target -> UpdateObjectVisibility ();
2010-01-10 01:23:15 +01:00
}
else
{
// recalculate value at modifier remove (current aura already removed)
target -> m_invisibilityMask = 0 ;
Unit :: AuraEffectList const & auras = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_INVISIBILITY );
for ( Unit :: AuraEffectList :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
target -> m_invisibilityMask |= ( 1 << GetMiscValue ());
// if not have different invisibility auras.
// remove glow vision
2010-04-07 19:14:10 +02:00
if ( ! target -> m_invisibilityMask && target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
target -> RemoveFlag ( PLAYER_FIELD_BYTES2 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2010-02-27 15:25:14 +02:00
target -> UpdateObjectVisibility ();
2010-01-10 01:23:15 +01:00
}
}
void AuraEffect :: HandleModStealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
// drop flag at stealth in bg
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
target -> SetStandFlags ( UNIT_STAND_FLAGS_CREEP );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( PLAYER_FIELD_BYTES2 , 0x2000 );
// apply only if not in GM invisibility (and overwrite invisibility state)
2010-04-07 19:14:10 +02:00
if ( target -> GetVisibility () != VISIBILITY_OFF )
2010-01-10 01:23:15 +01:00
target -> SetVisibility ( VISIBILITY_GROUP_STEALTH );
}
2010-04-07 19:14:10 +02:00
else if ( ! target -> HasAuraType ( SPELL_AURA_MOD_STEALTH )) // if last SPELL_AURA_MOD_STEALTH
2010-01-10 01:23:15 +01:00
{
target -> RemoveStandFlags ( UNIT_STAND_FLAGS_CREEP );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
target -> RemoveFlag ( PLAYER_FIELD_BYTES2 , 0x2000 );
2010-04-07 19:14:10 +02:00
if ( target -> GetVisibility () != VISIBILITY_OFF )
2010-01-10 01:23:15 +01:00
target -> SetVisibility ( VISIBILITY_ON );
}
}
void AuraEffect :: HandleSpiritOfRedemption ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// prepare spirit state
2010-04-07 19:14:10 +02:00
if ( apply )
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
{
// disable breath/etc timers
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> StopMirrorTimers ();
2010-01-10 01:23:15 +01:00
// set stand state (expected in this form)
2010-04-07 19:14:10 +02:00
if ( ! target -> IsStandState ())
2010-01-10 01:23:15 +01:00
target -> SetStandState ( UNIT_STAND_STATE_STAND );
}
target -> SetHealth ( 1 );
}
// die at aura end
else
target -> setDeathState ( JUST_DIED );
}
void AuraEffect :: HandleAuraGhost ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
else
{
if ( target -> HasAuraType ( SPELL_AURA_GHOST ))
return ;
target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
}
}
void AuraEffect :: HandlePhase ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
// no-phase is also phase state so same code for apply and remove
// phase auras normally not expected at BG but anyway better check
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
// drop flag at invisible in bg
2010-04-07 19:14:10 +02:00
if ( target -> ToPlayer () -> InBattleGround ())
if ( BattleGround * bg = target -> ToPlayer () -> GetBattleGround ())
2010-04-07 17:24:07 +02:00
bg -> EventPlayerDroppedFlag ( target -> ToPlayer ());
2010-01-10 01:23:15 +01:00
// GM-mode have mask 0xFFFFFFFF
2010-04-07 19:14:10 +02:00
if ( ! target -> ToPlayer () -> isGameMaster ())
2010-01-10 01:23:15 +01:00
target -> SetPhaseMask (( apply ) ? GetMiscValue () : PHASEMASK_NORMAL , false );
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> GetSession () -> SendSetPhaseShift (( apply ) ? GetMiscValue () : PHASEMASK_NORMAL );
2010-01-10 01:23:15 +01:00
}
else
target -> SetPhaseMask (( apply ) ? GetMiscValue () : PHASEMASK_NORMAL , false );
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
2010-04-08 08:20:08 +02:00
if ( target -> GetVisibility () != VISIBILITY_OFF )
2010-01-10 01:23:15 +01:00
target -> SetVisibility ( target -> GetVisibility ());
}
/**********************/
/*** UNIT MODEL ***/
/**********************/
void AuraEffect :: HandleAuraModShapeshift ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
uint32 modelid = 0 ;
Powers PowerType = POWER_MANA ;
ShapeshiftForm form = ShapeshiftForm ( GetMiscValue ());
switch ( form )
{
case FORM_CAT :
case FORM_GHOUL :
PowerType = POWER_ENERGY ;
break ;
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_BATTLESTANCE :
case FORM_BERSERKERSTANCE :
case FORM_DEFENSIVESTANCE :
PowerType = POWER_RAGE ;
break ;
case FORM_TRAVEL :
case FORM_AQUA :
case FORM_CREATUREBEAR :
case FORM_GHOSTWOLF :
case FORM_FLIGHT :
case FORM_MOONKIN :
case FORM_FLIGHT_EPIC :
case FORM_METAMORPHOSIS :
case FORM_MASTER_ANGLER :
case FORM_AMBIENT :
case FORM_SHADOW :
case FORM_STEALTH :
case FORM_UNDEAD :
case FORM_SHADOW_DANCE :
case FORM_TREE :
case FORM_SPIRITOFREDEMPTION :
break ;
default :
sLog . outError ( "Auras: Unknown Shapeshift Type: %u" , GetMiscValue ());
}
modelid = target -> GetModelForForm ( form );
// remove polymorph before changing display id to keep new display id
2010-04-07 22:59:46 +02:00
switch ( form )
2010-01-10 01:23:15 +01:00
{
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 :
{
// remove movement affects
target -> RemoveMovementImpairingAuras ();
// and polymorphic affects
2010-04-07 19:14:10 +02:00
if ( target -> IsPolymorphed ())
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( target -> getTransForm ());
break ;
}
default :
break ;
}
if ( apply )
{
// remove other shapeshift before applying a new one
2010-04-07 19:14:10 +02:00
if ( target -> m_ShapeShiftFormSpellId )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( target -> m_ShapeShiftFormSpellId );
target -> SetByteValue ( UNIT_FIELD_BYTES_2 , 3 , form );
if ( modelid > 0 )
target -> SetDisplayId ( modelid );
if ( PowerType != POWER_MANA )
{
uint32 oldPower = target -> GetPower ( PowerType );
// reset power to default values only at power change
2010-04-07 19:14:10 +02:00
if ( target -> getPowerType () != PowerType )
2010-01-10 01:23:15 +01:00
target -> setPowerType ( PowerType );
switch ( form )
{
case FORM_CAT :
case FORM_BEAR :
case FORM_DIREBEAR :
{
// get furor proc chance
uint32 FurorChance = 0 ;
if ( AuraEffect const * dummy = target -> GetDummyAuraEffect ( SPELLFAMILY_DRUID , 238 , 0 ))
FurorChance = std :: max ( dummy -> GetAmount (), 0 );
switch ( GetMiscValue ())
{
case FORM_CAT :
{
int32 basePoints = int32 ( std :: min ( oldPower , FurorChance ));
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 ;
}
}
target -> m_ShapeShiftFormSpellId = GetId ();
target -> m_form = form ;
}
else
{
2010-04-07 19:14:10 +02:00
if ( modelid > 0 )
2010-01-10 01:23:15 +01:00
target -> SetDisplayId ( target -> GetNativeDisplayId ());
target -> SetByteValue ( UNIT_FIELD_BYTES_2 , 3 , FORM_NONE );
2010-04-07 19:14:10 +02:00
if ( target -> getClass () == CLASS_DRUID )
2010-01-10 01:23:15 +01:00
target -> setPowerType ( POWER_MANA );
target -> m_ShapeShiftFormSpellId = 0 ;
target -> m_form = FORM_NONE ;
switch ( form )
{
// Nordrassil Harness - bonus
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_CAT :
2010-04-07 22:59:46 +02:00
if ( AuraEffect * dummy = target -> GetAuraEffect ( 37315 , 0 ))
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 37316 , true , NULL , dummy );
break ;
// Nordrassil Regalia - bonus
case FORM_MOONKIN :
2010-04-07 22:59:46 +02:00
if ( AuraEffect * dummy = target -> GetAuraEffect ( 37324 , 0 ))
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 37325 , true , NULL , dummy );
break ;
case FORM_BATTLESTANCE :
case FORM_DEFENSIVESTANCE :
case FORM_BERSERKERSTANCE :
{
uint32 Rage_val = 0 ;
// Defensive Tactics
if ( form == FORM_DEFENSIVESTANCE )
{
if ( AuraEffect const * aurEff = target -> IsScriptOverriden ( m_spellProto , 831 ))
Rage_val += aurEff -> GetAmount () * 10 ;
}
// Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2010-03-11 20:51:31 +01:00
PlayerSpellMap const & sp_list = target -> ToPlayer () -> GetSpellMap ();
2010-01-10 01:23:15 +01:00
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
{
2010-04-07 19:14:10 +02:00
if ( itr -> second -> state == PLAYERSPELL_REMOVED || itr -> second -> disabled ) continue ;
2010-01-10 01:23:15 +01:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( itr -> first );
if ( spellInfo && spellInfo -> SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo -> SpellIconID == 139 )
2010-04-11 11:43:23 +04:00
Rage_val += target -> CalculateSpellDamage ( target , spellInfo , 0 ) * 10 ;
2010-01-10 01:23:15 +01:00
}
}
if ( target -> GetPower ( POWER_RAGE ) > Rage_val )
target -> SetPower ( POWER_RAGE , Rage_val );
break ;
}
default :
break ;
}
}
// adding/removing linked auras
// add/remove the shapeshift aura's boosts
HandleShapeshiftBoosts ( target , apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> InitDataForForm ();
2010-01-10 01:23:15 +01:00
2010-04-07 19:14:10 +02:00
if ( target -> getClass () == CLASS_DRUID )
2010-01-10 01:23:15 +01:00
{
// Dash
2010-04-07 19:14:10 +02:00
if ( AuraEffect * aurEff = target -> GetAuraEffect ( SPELL_AURA_MOD_INCREASE_SPEED , SPELLFAMILY_DRUID , 0 , 0 , 0x8 ))
2010-01-10 01:23:15 +01:00
aurEff -> RecalculateAmount ();
}
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
SpellShapeshiftEntry const * shapeInfo = sSpellShapeshiftStore . LookupEntry ( form );
// 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 )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> AddTemporarySpell ( shapeInfo -> stanceSpell [ i ]);
2010-01-10 01:23:15 +01:00
else
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> RemoveTemporarySpell ( shapeInfo -> stanceSpell [ i ]);
2010-01-10 01:23:15 +01:00
}
}
}
void AuraEffect :: HandleAuraTransform ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( apply )
{
// special case (spell specific functionality)
2010-04-07 23:25:02 +02:00
if ( GetMiscValue () == 0 )
2010-01-10 01:23:15 +01:00
{
// player applied only
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
switch ( GetId ())
{
// Orb of Deception
case 16739 :
{
uint32 orb_model = target -> GetNativeDisplayId ();
switch ( orb_model )
{
// Troll Female
case 1479 : target -> SetDisplayId ( 10134 ); break ;
// Troll Male
case 1478 : target -> SetDisplayId ( 10135 ); break ;
// Tauren Male
case 59 : target -> SetDisplayId ( 10136 ); break ;
// Human Male
case 49 : target -> SetDisplayId ( 10137 ); break ;
// Human Female
case 50 : target -> SetDisplayId ( 10138 ); break ;
// Orc Male
case 51 : target -> SetDisplayId ( 10139 ); break ;
// Orc Female
case 52 : target -> SetDisplayId ( 10140 ); break ;
// Dwarf Male
case 53 : target -> SetDisplayId ( 10141 ); break ;
// Dwarf Female
case 54 : target -> SetDisplayId ( 10142 ); break ;
// NightElf Male
case 55 : target -> SetDisplayId ( 10143 ); break ;
// NightElf Female
case 56 : target -> SetDisplayId ( 10144 ); break ;
// Undead Female
case 58 : target -> SetDisplayId ( 10145 ); break ;
// Undead Male
case 57 : target -> SetDisplayId ( 10146 ); break ;
// Tauren Female
case 60 : target -> SetDisplayId ( 10147 ); break ;
// Gnome Male
case 1563 : target -> SetDisplayId ( 10148 ); break ;
// Gnome Female
case 1564 : target -> SetDisplayId ( 10149 ); break ;
// BloodElf Female
case 15475 : target -> SetDisplayId ( 17830 ); break ;
// BloodElf Male
case 15476 : target -> SetDisplayId ( 17829 ); break ;
// Dranei Female
case 16126 : target -> SetDisplayId ( 17828 ); break ;
// Dranei Male
case 16125 : target -> SetDisplayId ( 17827 ); break ;
default : break ;
}
break ;
}
// Murloc costume
case 42365 : target -> SetDisplayId ( 21723 ); break ;
default : break ;
}
}
else
{
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( GetMiscValue ());
2010-04-07 19:14:10 +02:00
if ( ! ci )
2010-01-10 01:23:15 +01:00
{
target -> SetDisplayId ( 16358 ); // pig pink ^_^
sLog . outError ( "Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d" , GetMiscValue (), GetId ());
}
else
{
uint32 model_id ;
if ( uint32 modelid = ci -> GetRandomValidModelId ())
model_id = modelid ; // Will use the default model here
// Polymorph (sheep)
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto () -> SpellIconID == 82 && GetSpellProto () -> SpellVisual [ 0 ] == 12978 )
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)
2010-04-07 23:25:02 +02:00
if ( GetId () == 42016 && target -> GetMountID () && ! target -> GetAuraEffectsByType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ). empty ())
2010-01-10 01:23:15 +01:00
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
}
}
// update active transform spell only not set or not overwriting negative by positive case
if ( ! target -> getTransForm () || ! IsPositiveSpell ( GetId ()) || IsPositiveSpell ( target -> getTransForm ()))
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)
2010-04-07 22:59:46 +02:00
if ( IS_PLAYER_GUID ( GetCasterGUID ()))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> setRegenTimerCount ( 1 * IN_MILISECONDS );
2010-01-10 01:23:15 +01:00
//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
target -> setTransForm ( 0 );
target -> SetDisplayId ( target -> GetNativeDisplayId ());
// re-aplly some from still active with preference negative cases
Unit :: AuraEffectList const & otherTransforms = target -> GetAuraEffectsByType ( SPELL_AURA_TRANSFORM );
if ( ! otherTransforms . empty ())
{
// look for other transform auras
AuraEffect * handledAura = * otherTransforms . begin ();
for ( Unit :: AuraEffectList :: const_iterator i = otherTransforms . begin (); i != otherTransforms . end (); ++ i )
{
// negative auras are preferred
if ( ! IsPositiveSpell (( * i ) -> GetSpellProto () -> Id ))
{
handledAura = * i ;
break ;
}
}
handledAura -> HandleEffect ( target , AURA_EFFECT_HANDLE_SEND_FOR_CLIENT , true );
}
// Dragonmaw Illusion (restore mount model)
if ( GetId () == 42016 && target -> GetMountID () == 16314 )
{
if ( ! target -> GetAuraEffectsByType ( SPELL_AURA_MOUNTED ). empty ())
{
uint32 cr_id = target -> GetAuraEffectsByType ( SPELL_AURA_MOUNTED ). front () -> GetMiscValue ();
2010-04-07 19:14:10 +02:00
if ( CreatureInfo const * ci = objmgr . GetCreatureTemplate ( cr_id ))
2010-01-10 01:23:15 +01:00
{
uint32 team = 0 ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
team = target -> ToPlayer () -> GetTeam ();
2010-01-10 01:23:15 +01:00
uint32 display_id = objmgr . ChooseDisplayId ( team , ci );
CreatureModelInfo const * minfo = objmgr . GetCreatureModelRandomGender ( display_id );
if ( minfo )
display_id = minfo -> modelid ;
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , display_id );
}
}
}
}
}
void AuraEffect :: HandleAuraModScale ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyPercentModFloatValue ( OBJECT_FIELD_SCALE_X , GetAmount (), apply );
}
void AuraEffect :: HandleAuraCloneCaster ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( apply )
{
Unit * caster = GetCaster ();
if ( ! caster )
return ;
// Set display id (probably for portrait?)
target -> SetDisplayId ( caster -> GetDisplayId ());
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 );
}
}
/************************/
/*** FIGHT ***/
/************************/
void AuraEffect :: HandleFeignDeath ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 22:59:46 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<target->GetGUID();
data<<uint8(0);
target->SendMessageToSet(&data,true);
*/
UnitList targets ;
Trinity :: AnyUnfriendlyUnitInObjectRangeCheck u_check ( target , target , target -> GetMap () -> GetVisibilityDistance ());
Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyUnitInObjectRangeCheck > searcher ( target , targets , u_check );
target -> VisitNearbyObject ( target -> GetMap () -> GetVisibilityDistance (), searcher );
for ( UnitList :: iterator iter = targets . begin (); iter != targets . end (); ++ iter )
{
2010-04-07 19:14:10 +02:00
if ( ! ( * iter ) -> hasUnitState ( UNIT_STAT_CASTING ))
2010-01-10 01:23:15 +01:00
continue ;
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; i ++ )
{
2010-04-07 19:14:10 +02:00
if (( * iter ) -> GetCurrentSpell ( i )
2010-01-10 01:23:15 +01:00
&& ( * iter ) -> GetCurrentSpell ( i ) -> m_targets . getUnitTargetGUID () == target -> GetGUID ())
{
( * iter ) -> InterruptSpell ( CurrentSpellTypes ( i ), false );
}
}
}
// 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 );
target -> CombatStop ();
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
// prevent interrupt message
2010-04-07 23:25:02 +02:00
if ( GetCasterGUID () == target -> GetGUID () && target -> GetCurrentSpell ( CURRENT_GENERIC_SPELL ))
2010-01-10 01:23:15 +01:00
target -> FinishSpell ( CURRENT_GENERIC_SPELL , false );
target -> InterruptNonMeleeSpells ( true );
2010-03-09 11:11:10 +01:00
target -> getHostileRefManager (). deleteReferences ();
2010-01-10 01:23:15 +01:00
}
else
{
/*
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
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
target -> CombatStop ();
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
}
}
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
else if ( target -> HasAuraType ( SPELL_AURA_MOD_UNATTACKABLE ))
return ;
target -> ApplyModFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE , apply );
}
void AuraEffect :: HandleAuraModDisarm ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
AuraType type = GetAuraType ();
//Prevent handling aura twice
2010-04-07 19:14:10 +02:00
if (( apply ) ? target -> GetAuraEffectsByType ( type ). size () > 1 : target -> HasAuraType ( type ))
2010-01-10 01:23:15 +01:00
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 ;
}
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
target -> RemoveFlag ( field , flag );
if ( target -> GetTypeId () == TYPEID_PLAYER )
{
// This is between the two because there is a check in _ApplyItemMods
// we must make sure that flag is always removed when call that function
// refer to DurabilityPointsLoss
2010-04-07 22:59:46 +02:00
if ( Item * pItem = target -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> _ApplyItemMods ( pItem , slot , ! apply );
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
target -> SetFlag ( field , flag );
2010-03-07 18:30:53 +01:00
if ( target -> GetTypeId () == TYPEID_UNIT && target -> ToCreature () -> GetCurrentEquipmentId ())
2010-01-10 01:23:15 +01:00
target -> UpdateDamagePhysical ( attType );
}
void AuraEffect :: HandleAuraModSilence ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SILENCED );
// 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 )))
2010-04-07 19:14:10 +02:00
if ( spell -> m_spellInfo -> PreventionType == SPELL_PREVENTION_TYPE_SILENCE )
2010-01-10 01:23:15 +01:00
// Stop spells on prepare or casting state
target -> InterruptSpell ( CurrentSpellTypes ( i ), false );
}
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( SPELL_AURA_MOD_SILENCE ) || target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SILENCED );
}
}
void AuraEffect :: HandleAuraModPacify ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( SPELL_AURA_MOD_PACIFY ) || target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
}
}
void AuraEffect :: HandleAuraModPacifyAndSilence ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// Vengeance of the Blue Flight (TODO: REMOVE THIS!)
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> Id == 45839 )
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
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
else
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
}
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( SPELL_AURA_MOD_PACIFY_SILENCE ))
2010-01-10 01:23:15 +01:00
return ;
}
HandleAuraModPacify ( aurApp , mode , apply );
HandleAuraModSilence ( aurApp , mode , apply );
}
void AuraEffect :: HandleAuraAllowOnlyAbility ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
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
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( SPELL_AURA_ALLOW_ONLY_ABILITY ))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_ALLOW_ONLY_ABILITY );
}
}
}
/****************************/
/*** TRACKING ***/
/****************************/
void AuraEffect :: HandleAuraTrackCreatures ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 22:59:46 +02:00
target -> SetUInt32Value ( PLAYER_TRACK_CREATURES , ( apply ) ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraTrackResources ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 22:59:46 +02:00
target -> SetUInt32Value ( PLAYER_TRACK_RESOURCES , ( apply ) ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraTrackStealthed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
}
target -> ApplyModFlag ( PLAYER_FIELD_BYTES , PLAYER_FIELD_BYTE_TRACK_STEALTHED , apply );
}
void AuraEffect :: HandleAuraModStalked ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
}
}
void AuraEffect :: HandleAuraUntrackable ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
}
}
/****************************/
/*** SKILLS & TALENTS ***/
/****************************/
void AuraEffect :: HandleAuraModPetTalentsPoints ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Recalculate pet talent points
2010-03-07 15:20:19 +01:00
if ( Pet * pet = target -> ToPlayer () -> GetPet ())
2010-01-10 01:23:15 +01:00
pet -> InitTalentForLevel ();
}
void AuraEffect :: HandleAuraModSkill ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
uint32 prot = GetSpellProto () -> EffectMiscValue [ m_effIndex ];
int32 points = GetAmount ();
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> ModifySkillBonus ( prot ,(( apply ) ? points : - points ), GetAuraType () == SPELL_AURA_MOD_SKILL_TALENT );
2010-04-07 19:14:10 +02:00
if ( prot == SKILL_DEFENSE )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateDefenseBonusesMod ();
2010-01-10 01:23:15 +01:00
}
/****************************/
/*** MOVEMENT ***/
/****************************/
void AuraEffect :: HandleAuraMounted ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( GetMiscValue ());
2010-04-07 19:14:10 +02:00
if ( ! ci )
2010-01-10 01:23:15 +01:00
{
sLog . outErrorDb ( "AuraMounted: `creature_template`='%u' not found in database (only need it modelid)" , GetMiscValue ());
return ;
}
uint32 team = 0 ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
team = target -> ToPlayer () -> GetTeam ();
2010-01-10 01:23:15 +01:00
uint32 display_id = objmgr . ChooseDisplayId ( team , ci );
CreatureModelInfo const * minfo = objmgr . GetCreatureModelRandomGender ( display_id );
if ( minfo )
display_id = minfo -> modelid ;
//some spell has one aura of mount and one of vehicle
for ( uint32 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> Effect [ i ] == SPELL_EFFECT_SUMMON
2010-01-10 01:23:15 +01:00
&& GetSpellProto () -> EffectMiscValue [ i ] == GetMiscValue ())
display_id = 0 ;
2010-01-13 11:16:38 +01:00
target -> Mount ( display_id , ci -> VehicleId );
2010-01-10 01:23:15 +01:00
}
else
{
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
2010-04-07 19:14:10 +02:00
if ( mode & AURA_EFFECT_HANDLE_REAL )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
}
}
void AuraEffect :: HandleAuraAllowFlight ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( ! apply )
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()) || target -> HasAuraType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ))
2010-01-10 01:23:15 +01:00
return ;
}
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_UNIT )
2010-01-10 01:23:15 +01:00
target -> SetFlying ( apply );
2010-04-07 19:14:10 +02:00
if ( Player * plr = target -> m_movedPlayer )
2010-01-10 01:23:15 +01:00
{
// allow fly
WorldPacket data ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
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 );
}
}
void AuraEffect :: HandleAuraWaterWalk ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
}
WorldPacket data ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
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 );
}
void AuraEffect :: HandleAuraFeatherFall ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
}
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_FEATHER_FALL , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_NORMAL_FALL , 8 + 4 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 );
target -> SendMessageToSet ( & data , true );
// start fall from current height
2010-04-07 19:14:10 +02:00
if ( ! apply && target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> SetFallInformation ( 0 , target -> GetPositionZ ());
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraHover ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
}
WorldPacket data ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
data . Initialize ( SMSG_MOVE_SET_HOVER , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_UNSET_HOVER , 8 + 4 );
data . append ( target -> GetPackGUID ());
data << uint32 ( 0 );
target -> SendMessageToSet ( & data , true );
}
void AuraEffect :: HandleWaterBreathing ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// update timers in client
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateMirrorTimers ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleForceMoveForward ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
}
}
/****************************/
/*** THREAT ***/
/****************************/
void AuraEffect :: HandleModThreat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( ! target -> isAlive ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
if ( target -> GetTypeId () == TYPEID_PLAYER )
for ( int8 x = 0 ; x < MAX_SPELL_SCHOOL ; x ++ )
if ( GetMiscValue () & int32 ( 1 << x ))
ApplyPercentModFloatVar ( target -> m_threatModifier [ x ], GetAmount (), apply );
}
void AuraEffect :: HandleAuraModTotalThreat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( ! target -> isAlive () || target -> GetTypeId () != TYPEID_PLAYER )
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
2010-03-09 11:11:10 +01:00
target -> getHostileRefManager (). addTempThreat ( GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModTaunt ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( ! target -> isAlive () || ! target -> CanHaveThreatList ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
if ( apply )
target -> TauntApply ( caster );
else
{
// When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
target -> TauntFadeOut ( caster );
}
}
/*****************************/
/*** CONTROL ***/
/*****************************/
void AuraEffect :: HandleModConfuse ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> SetControlled ( apply , UNIT_STAT_CONFUSED );
}
void AuraEffect :: HandleModFear ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> SetControlled ( apply , UNIT_STAT_FLEEING );
}
void AuraEffect :: HandleAuraModStun ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> SetControlled ( apply , UNIT_STAT_STUNNED );
}
void AuraEffect :: HandleAuraModRoot ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> SetControlled ( apply , UNIT_STAT_ROOT );
}
void AuraEffect :: HandlePreventFleeing ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit :: AuraEffectList const & fearAuras = target -> GetAuraEffectsByType ( SPELL_AURA_MOD_FEAR );
2010-04-07 22:59:46 +02:00
if ( ! fearAuras . empty ())
2010-01-10 01:23:15 +01:00
target -> SetControlled ( ! ( apply ), UNIT_STAT_FLEEING );
}
/***************************/
/*** CHARM ***/
/***************************/
void AuraEffect :: HandleModPossess ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( caster && caster -> GetTypeId () == TYPEID_UNIT )
2010-01-10 01:23:15 +01:00
{
HandleModCharm ( aurApp , mode , apply );
return ;
}
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS );
else
target -> RemoveCharmedBy ( caster );
}
// only one spell has this aura
void AuraEffect :: HandleModPossessPet ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
//seems it may happen that when removing it is no longer owner's pet
2010-04-07 19:14:10 +02:00
//if (caster->ToPlayer()->GetPet() != target)
2010-01-10 01:23:15 +01:00
// return;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( caster -> ToPlayer () -> GetPet () != target )
2010-01-10 01:23:15 +01:00
return ;
target -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS );
}
else
{
target -> RemoveCharmedBy ( caster );
// Reinitialize the pet bar and make the pet come back to the owner
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> PetSpellInitialize ();
2010-04-07 19:14:10 +02:00
if ( ! target -> getVictim ())
2010-01-10 01:23:15 +01:00
{
target -> GetMotionMaster () -> MoveFollow ( caster , PET_FOLLOW_DIST , target -> GetFollowAngle ());
2010-04-07 19:14:10 +02:00
//if (target->GetCharmInfo())
2010-01-10 01:23:15 +01:00
// target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
}
}
}
void AuraEffect :: HandleModCharm ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetCharmedBy ( caster , CHARM_TYPE_CHARM );
else
target -> RemoveCharmedBy ( caster );
}
void AuraEffect :: HandleCharmConvert ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetCharmedBy ( caster , CHARM_TYPE_CONVERT );
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
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( ! target -> IsVehicle ())
2010-01-10 01:23:15 +01:00
return ;
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( ! caster || caster == target )
2010-01-10 01:23:15 +01:00
return ;
if ( apply )
{
2010-04-07 19:14:10 +02:00
//if (caster->GetTypeId() == TYPEID_PLAYER)
// if (Pet *pet = caster->ToPlayer()->GetPet())
2010-01-10 01:23:15 +01:00
// pet->Remove(PET_SAVE_AS_CURRENT);
caster -> EnterVehicle ( target -> GetVehicleKit (), m_amount - 1 );
}
else
{
2010-04-07 19:14:10 +02:00
if ( GetId () == 53111 ) // Devour Humanoid
2010-01-10 01:23:15 +01:00
{
target -> Kill ( caster );
2010-04-07 19:14:10 +02:00
if ( caster -> GetTypeId () == TYPEID_UNIT )
2010-03-07 18:30:53 +01:00
caster -> ToCreature () -> RemoveCorpse ();
2010-01-10 01:23:15 +01:00
}
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
caster -> RemoveAurasDueToSpell ( GetId ());
caster -> ExitVehicle ();
}
}
/*********************************************************/
/*** MODIFY SPEED ***/
/*********************************************************/
void AuraEffect :: HandleAuraModIncreaseSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> UpdateSpeed ( MOVE_RUN , true );
}
void AuraEffect :: HandleAuraModIncreaseMountedSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> UpdateSpeed ( MOVE_RUN , true );
}
void AuraEffect :: HandleAuraModIncreaseFlightSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
// Enable Fly mode for flying mounts
if ( GetAuraType () == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED )
{
// 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-04-07 19:14:10 +02:00
if ( Player * plr = target -> m_movedPlayer )
2010-04-06 23:52:08 +02:00
{
WorldPacket data ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-04-06 23:52:08 +02:00
data . Initialize ( SMSG_MOVE_SET_CAN_FLY , 12 );
else
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
}
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
//Players on flying mounts must be immune to polymorph
if ( target -> GetTypeId () == TYPEID_PLAYER )
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_POLYMORPH , apply );
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
2010-04-07 22:59:46 +02:00
if ( apply && target -> HasAuraEffect ( 42016 , 0 ) && target -> GetMountID ())
2010-01-10 01:23:15 +01:00
target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
}
}
2010-04-07 19:14:10 +02:00
if ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK )
2010-01-10 01:23:15 +01:00
target -> UpdateSpeed ( MOVE_FLIGHT , true );
}
void AuraEffect :: HandleAuraModIncreaseSwimSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> UpdateSpeed ( MOVE_SWIM , true );
}
void AuraEffect :: HandleAuraModDecreaseSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
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 );
}
void AuraEffect :: HandleAuraModUseNormalSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> UpdateSpeed ( MOVE_RUN , true );
target -> UpdateSpeed ( MOVE_SWIM , true );
target -> UpdateSpeed ( MOVE_FLIGHT , true );
}
/*********************************************************/
/*** IMMUNITY ***/
/*********************************************************/
void AuraEffect :: HandleModStateImmunityMask ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
std :: list < AuraType > immunity_list ;
if ( GetMiscValue () & ( 1 << 10 ))
immunity_list . push_back ( SPELL_AURA_MOD_STUN );
if ( GetMiscValue () & ( 1 << 7 ))
immunity_list . push_back ( SPELL_AURA_MOD_DISARM );
if ( GetMiscValue () & ( 1 << 1 ))
immunity_list . push_back ( SPELL_AURA_TRANSFORM );
// 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 );
// Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
// however not all mechanic specified in immunity
2010-04-07 23:25:02 +02:00
if ( apply && GetId () == 46924 )
2010-01-10 01:23:15 +01:00
{
target -> RemoveAurasByType ( SPELL_AURA_MOD_ROOT );
target -> RemoveAurasByType ( SPELL_AURA_MOD_DECREASE_SPEED );
}
2010-04-07 19:14:10 +02:00
if ( apply && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
2010-01-10 01:23:15 +01:00
{
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
{
target -> RemoveAurasByType ( * iter );
}
}
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
{
target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , * iter , apply );
}
}
void AuraEffect :: HandleModMechanicImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
uint32 mechanic ;
2010-03-24 20:35:04 +01:00
switch ( GetId ())
2010-01-10 01:23:15 +01:00
{
2010-03-24 20:35:04 +01: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_STATE , SPELL_AURA_MOD_ROOT , apply );
target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , SPELL_AURA_MOD_DECREASE_SPEED , apply );
break ;
default :
if ( GetMiscValue () < 1 )
return ;
mechanic = 1 << GetMiscValue ();
target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , GetMiscValue (), apply );
break ;
2010-01-10 01:23:15 +01:00
}
2010-04-07 18:09:10 +02:00
2010-03-24 20:35:04 +01:00
if ( apply && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
target -> RemoveAurasWithMechanic ( mechanic , AURA_REMOVE_BY_DEFAULT , GetId ());
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModEffectImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
// when removing flag aura, handle flag drop
2010-04-07 22:59:46 +02:00
if ( ! ( apply ) && target -> GetTypeId () == TYPEID_PLAYER
&& ( GetSpellProto () -> AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION ))
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
{
2010-04-07 19:14:10 +02:00
if ( target -> ToPlayer () -> InBattleGround ())
2010-01-10 01:23:15 +01:00
{
2010-04-07 22:59:46 +02:00
if ( BattleGround * bg = target -> ToPlayer () -> GetBattleGround ())
2010-03-07 15:20:19 +01:00
bg -> EventPlayerDroppedFlag ( target -> ToPlayer ());
2010-01-10 01:23:15 +01:00
}
else
sOutdoorPvPMgr . HandleDropFlag (( Player * ) target , GetSpellProto () -> Id );
}
}
target -> ApplySpellImmune ( GetId (), IMMUNITY_EFFECT , GetMiscValue (), apply );
}
void AuraEffect :: HandleAuraModStateImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if (( apply ) && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
2010-01-10 01:23:15 +01:00
{
target -> RemoveAurasByType ( AuraType ( GetMiscValue ()), NULL , GetBase ());
}
target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , GetMiscValue (), apply );
}
void AuraEffect :: HandleAuraModSchoolImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if (( apply ) && GetMiscValue () == SPELL_SCHOOL_MASK_NORMAL )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
target -> ApplySpellImmune ( GetId (), IMMUNITY_SCHOOL , GetMiscValue (),( apply ));
// remove all flag auras (they are positive, but they must be removed when you are immune)
2010-04-07 22:59:46 +02:00
if ( GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
&& GetSpellProto () -> AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
// TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
2010-04-07 19:14:10 +02:00
if (( apply )
2010-01-10 01:23:15 +01:00
&& GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
2010-04-07 22:59:46 +02:00
&& IsPositiveSpell ( GetId ())) //Only positive immunity removes auras
2010-01-10 01:23:15 +01:00
{
uint32 school_mask = GetMiscValue ();
Unit :: AuraApplicationMap & Auras = target -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator iter = Auras . begin (); iter != Auras . end ();)
{
SpellEntry const * spell = iter -> second -> GetBase () -> GetSpellProto ();
2010-04-07 19:14:10 +02:00
if (( GetSpellSchoolMask ( spell ) & school_mask ) //Check for school mask
2010-01-10 01:23:15 +01:00
&& IsDispelableBySpell ( GetSpellProto (), spell -> Id , true )
&& ! iter -> second -> IsPositive () //Don't remove positive spells
2010-04-07 22:59:46 +02:00
&& spell -> Id != GetId ()) //Don't remove self
2010-01-10 01:23:15 +01:00
{
target -> RemoveAura ( iter );
}
else
++ iter ;
}
}
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> Mechanic == MECHANIC_BANISH )
2010-01-10 01:23:15 +01:00
{
2010-04-07 22:59:46 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> addUnitState ( UNIT_STAT_ISOLATED );
else
{
bool banishFound = false ;
Unit :: AuraEffectList const & banishAuras = target -> GetAuraEffectsByType ( GetAuraType ());
for ( Unit :: AuraEffectList :: const_iterator i = banishAuras . begin (); i != banishAuras . end (); ++ i )
if (( * i ) -> GetSpellProto () -> Mechanic == MECHANIC_BANISH )
{
banishFound = true ;
break ;
}
if ( ! banishFound )
target -> clearUnitState ( UNIT_STAT_ISOLATED );
}
}
}
void AuraEffect :: HandleAuraModDmgImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> ApplySpellImmune ( GetId (), IMMUNITY_DAMAGE , GetMiscValue (), apply );
}
void AuraEffect :: HandleAuraModDispelImmunity ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
target -> ApplySpellDispelImmunity ( m_spellProto , DispelType ( GetMiscValue ()), ( apply ));
}
/*********************************************************/
/*** MODIFY STATS ***/
/*********************************************************/
/********************************/
/*** RESISTANCE ***/
/********************************/
void AuraEffect :: HandleAuraModResistanceExclusive ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2010-01-10 01:23:15 +01:00
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_VALUE , float ( GetAmount ()), apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), aurApp -> IsPositive (), GetAmount (), apply );
}
}
}
void AuraEffect :: HandleAuraModResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2010-01-10 01:23:15 +01:00
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), TOTAL_VALUE , float ( GetAmount ()), apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
2010-01-10 01:23:15 +01:00
target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), GetAmount () > 0 , GetAmount (), apply );
}
}
}
void AuraEffect :: HandleAuraModBaseResistancePCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// only players have base stats
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
//pets only have base armor
2010-04-07 19:14:10 +02:00
if ( target -> ToCreature () -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
2010-01-10 01:23:15 +01:00
target -> HandleStatModifier ( UNIT_MOD_ARMOR , BASE_PCT , float ( GetAmount ()), apply );
}
else
{
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2010-01-10 01:23:15 +01:00
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_PCT , float ( GetAmount ()), apply );
}
}
}
void AuraEffect :: HandleModResistancePercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
for ( int8 i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & int32 ( 1 << i ))
2010-01-10 01:23:15 +01:00
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_PCT , float ( GetAmount ()), apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
2010-01-10 01:23:15 +01:00
{
target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), true , GetAmount (), apply );
target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), false , GetAmount (), apply );
}
}
}
}
void AuraEffect :: HandleModBaseResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// only players have base stats
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
//only pets have base stats
2010-04-07 19:14:10 +02:00
if ( target -> ToCreature () -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
2010-01-10 01:23:15 +01:00
target -> HandleStatModifier ( UNIT_MOD_ARMOR , TOTAL_VALUE , float ( GetAmount ()), apply );
}
else
{
for ( int i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & ( 1 << i ))
2010-01-10 01:23:15 +01:00
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_VALUE , float ( GetAmount ()), apply );
}
}
void AuraEffect :: HandleModTargetResistance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
// show armor penetration
if ( target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE , GetAmount (), apply );
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
2010-04-07 23:25:02 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_SPELL ) == SPELL_SCHOOL_MASK_SPELL )
2010-01-10 01:23:15 +01:00
target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_RESISTANCE , GetAmount (), apply );
}
/********************************/
/*** STAT ***/
/********************************/
void AuraEffect :: HandleAuraModStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( GetMiscValue () < - 2 || GetMiscValue () > 4 )
{
sLog . outError ( "WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT " , GetId (), GetEffIndex (), GetMiscValue ());
return ;
}
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
2010-04-07 22:59:46 +02:00
// -1 or -2 is all stats (misc < -2 checked in function beginning)
2010-01-10 01:23:15 +01:00
if ( GetMiscValue () < 0 || GetMiscValue () == i )
{
//target->ApplyStatMod(Stats(i), m_amount,apply);
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_VALUE , float ( GetAmount ()), apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
2010-01-10 01:23:15 +01:00
target -> ApplyStatBuffMod ( Stats ( i ), GetAmount (), apply );
}
}
}
void AuraEffect :: HandleModPercentStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
{
sLog . outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
}
// only players have base stats
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; ++ i )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
2010-01-10 01:23:15 +01:00
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), BASE_PCT , float ( m_amount ), apply );
}
}
void AuraEffect :: HandleModSpellDamagePercentFromStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModSpellHealingPercentFromStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Recalculate bonus
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModSpellDamagePercentFromAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModSpellHealingPercentFromAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Recalculate bonus
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModHealingDone ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// implemented in Unit::SpellHealingBonus
// this information is for client side only
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellDamageAndHealingBonus ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModTotalPercentStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
{
sLog . outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
}
//save current and max HP before applying aura
uint32 curHPValue = target -> GetHealth ();
uint32 maxHPValue = target -> GetMaxHealth ();
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
2010-01-10 01:23:15 +01:00
{
target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_PCT , float ( GetAmount ()), apply );
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER || target -> ToCreature () -> isPet ())
2010-04-07 22:59:46 +02:00
target -> ApplyStatPercentBuffMod ( Stats ( i ), GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
}
//recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
if (( GetMiscValue () == STAT_STAMINA ) && ( maxHPValue > 0 ) && ( m_spellProto -> Attributes & 0x10 ))
{
// newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
uint32 newHPValue = ( target -> GetMaxHealth () * curHPValue ) / maxHPValue ;
target -> SetHealth ( newHPValue );
}
}
void AuraEffect :: HandleAuraModResistenceOfStatPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () != SPELL_SCHOOL_MASK_NORMAL )
2010-01-10 01:23:15 +01:00
{
// 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) need adding support for non-armor resistances!" );
return ;
}
// Recalculate Armor
target -> UpdateArmor ();
}
void AuraEffect :: HandleAuraModExpertise ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateExpertise ( BASE_ATTACK );
target -> ToPlayer () -> UpdateExpertise ( OFF_ATTACK );
2010-01-10 01:23:15 +01:00
}
/********************************/
/*** HEAL & ENERGIZE ***/
/********************************/
void AuraEffect :: HandleModPowerRegen ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Update manaregen value
if ( GetMiscValue () == POWER_MANA )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateManaRegen ();
2010-01-10 01:23:15 +01:00
// other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
}
void AuraEffect :: HandleModPowerRegenPCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Update manaregen value
if ( GetMiscValue () == POWER_MANA )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateManaRegen ();
2010-01-10 01:23:15 +01:00
// other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
}
void AuraEffect :: HandleModManaRegen ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
//Note: an increase in regen does NOT cause threat.
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateManaRegen ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModIncreaseHealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
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 );
}
}
void AuraEffect :: HandleAuraModIncreaseMaxHealth ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
uint32 oldhealth = target -> GetHealth ();
double healthPercentage = ( double ) oldhealth / ( double ) target -> GetMaxHealth ();
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( GetAmount ()), apply );
// refresh percentage
2010-04-07 19:14:10 +02:00
if ( oldhealth > 0 )
2010-01-10 01:23:15 +01:00
{
uint32 newhealth = uint32 ( ceil (( double ) target -> GetMaxHealth () * healthPercentage ));
2010-04-07 23:25:02 +02:00
if ( newhealth == 0 )
2010-01-10 01:23:15 +01:00
newhealth = 1 ;
target -> SetHealth ( newhealth );
}
}
void AuraEffect :: HandleAuraModIncreaseEnergy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
Powers powerType = target -> getPowerType ();
2010-04-07 19:14:10 +02:00
if ( int32 ( powerType ) != GetMiscValue ())
2010-01-10 01:23:15 +01:00
return ;
UnitMods unitMod = UnitMods ( UNIT_MOD_POWER_START + powerType );
// Special case with temporary increase max/current power (percent)
2010-04-07 23:25:02 +02:00
if ( GetId () == 64904 ) // Hymn of Hope
2010-01-10 01:23:15 +01:00
{
2010-04-03 08:22:04 +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
}
// generic flat case
target -> HandleStatModifier ( unitMod , TOTAL_VALUE , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModIncreaseEnergyPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
Powers powerType = target -> getPowerType ();
2010-04-07 19:14:10 +02:00
if ( int32 ( powerType ) != GetMiscValue ())
2010-01-10 01:23:15 +01:00
return ;
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
{
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 ;
Unit * target = aurApp -> GetTarget ();
// Unit will keep hp% after MaxHealth being modified if unit is alive.
float percent = (( float ) target -> GetHealth ()) / target -> GetMaxHealth ();
target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_PCT , float ( GetAmount ()), apply );
if ( target -> isAlive ())
target -> SetHealth ( uint32 ( target -> GetMaxHealth () * percent ));
}
void AuraEffect :: HandleAuraIncreaseBaseHealthPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> HandleStatModifier ( UNIT_MOD_HEALTH , BASE_PCT , float ( GetAmount ()), apply );
}
/********************************/
/*** FIGHT ***/
/********************************/
void AuraEffect :: HandleAuraModParryPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateParryPercentage ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModDodgePercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateDodgePercentage ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModBlockPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateBlockPercentage ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModRegenInterrupt ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateManaRegen ();
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModWeaponCritPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
2010-04-07 19:14:10 +02:00
if ( Item * pItem = target -> ToPlayer () -> GetWeaponForAttack ( WeaponAttackType ( i ), true ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> _ApplyWeaponDependentAuraCritMod ( pItem , WeaponAttackType ( i ), this , apply );
2010-01-10 01:23:15 +01:00
// 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 ( GetSpellProto () -> EquippedItemClass == - 1 )
{
2010-03-07 15:20:19 +01: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
{
// done in Player::_ApplyWeaponDependentAuraMods
}
}
void AuraEffect :: HandleModHitChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateMeleeHitChances ();
target -> ToPlayer () -> UpdateRangedHitChances ();
2010-01-10 01:23:15 +01:00
}
else
{
target -> m_modMeleeHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
target -> m_modRangedHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
}
}
void AuraEffect :: HandleModSpellHitChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellHitChances ();
2010-01-10 01:23:15 +01:00
else
target -> m_modSpellHitChance += ( apply ) ? GetAmount () : ( - GetAmount ());
}
void AuraEffect :: HandleModSpellCritChance ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAllSpellCritChances ();
2010-01-10 01:23:15 +01:00
else
target -> m_baseSpellCritChance += ( apply ) ? GetAmount () :- GetAmount ();
}
void AuraEffect :: HandleModSpellCritChanceShool ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
for ( int school = SPELL_SCHOOL_NORMAL ; school < MAX_SPELL_SCHOOL ; ++ school )
if ( GetMiscValue () & ( 1 << school ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateSpellCritChance ( school );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModCritPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
target -> m_baseSpellCritChance += ( apply ) ? GetAmount () :- GetAmount ();
return ;
}
2010-03-07 15:20:19 +01: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
// included in Player::UpdateSpellCritChance calculation
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAllSpellCritChances ();
2010-01-10 01:23:15 +01:00
}
/********************************/
/*** ATTACK SPEED ***/
/********************************/
void AuraEffect :: HandleModCastingSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyCastTimePercentMod ( GetAmount (), apply );
}
void AuraEffect :: HandleModMeleeRangedSpeedPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , GetAmount (), apply );
}
void AuraEffect :: HandleModCombatSpeedPct ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyCastTimePercentMod ( m_amount , apply );
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , GetAmount (), apply );
}
void AuraEffect :: HandleModAttackSpeed ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , GetAmount (), apply );
target -> UpdateDamagePhysical ( BASE_ATTACK );
}
void AuraEffect :: HandleHaste ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( BASE_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( OFF_ATTACK , GetAmount (), apply );
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , GetAmount (), apply );
}
void AuraEffect :: HandleAuraModRangedHaste ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , GetAmount (), apply );
}
void AuraEffect :: HandleRangedAmmoHaste ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , GetAmount (), apply );
}
/********************************/
/*** COMBAT RATING ***/
/********************************/
void AuraEffect :: HandleModRating ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
if ( GetMiscValue () & ( 1 << rating ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> ApplyRatingMod ( CombatRating ( rating ), GetAmount (), apply );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleModRatingFromStat ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// Just recalculate ratings
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
if ( GetMiscValue () & ( 1 << rating ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> ApplyRatingMod ( CombatRating ( rating ), 0 , apply );
2010-01-10 01:23:15 +01:00
}
/********************************/
/*** ATTACK POWER ***/
/********************************/
void AuraEffect :: HandleAuraModAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_VALUE , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModRangedAttackPower ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-08 08:20:08 +02:00
if (( target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
2010-01-10 01:23:15 +01:00
return ;
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER_RANGED , TOTAL_VALUE , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModAttackPowerPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_PCT , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleAuraModRangedAttackPowerPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-08 08:20:08 +02:00
if (( target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
2010-01-10 01:23:15 +01:00
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-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 ;
Unit * target = aurApp -> GetTarget ();
// Recalculate bonus
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER && ! ( target -> getClassMask () & CLASSMASK_WAND_USERS ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAttackPowerAndDamage ( true );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModAttackPowerOfStatPercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// Recalculate bonus
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAttackPowerAndDamage ( false );
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleAuraModAttackPowerOfArmor ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// Recalculate bonus
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAttackPowerAndDamage ( false );
2010-01-10 01:23:15 +01:00
}
/********************************/
/*** DAMAGE BONUS ***/
/********************************/
void AuraEffect :: HandleModDamageDone ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
// apply item specific bonuses for already equipped weapon
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
2010-04-07 19:14:10 +02:00
if ( Item * pItem = target -> ToPlayer () -> GetWeaponForAttack ( WeaponAttackType ( i ), true ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> _ApplyWeaponDependentAuraDamageMod ( pItem , WeaponAttackType ( i ), this , apply );
2010-01-10 01:23:15 +01:00
}
// GetMiscValue() is bitmask of spell schools
2010-04-07 22:59:46 +02:00
// 1 (0-bit) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
2010-01-10 01:23:15 +01:00
// 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
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ) != 0 )
2010-01-10 01:23:15 +01:00
{
// apply generic physical damage bonuses including wand case
if ( GetSpellProto () -> EquippedItemClass == - 1 || target -> GetTypeId () != TYPEID_PLAYER )
{
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 );
2010-01-13 11:56:20 +01:00
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-13 11:56:20 +01:00
{
2010-04-07 19:14:10 +02:00
if ( GetAmount () > 0 )
2010-01-13 11:56:20 +01:00
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS , GetAmount (), apply );
else
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG , GetAmount (), apply );
}
2010-01-10 01:23:15 +01:00
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
}
// Skip non magic case for speedup
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_MAGIC ) == 0 )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 22:59:46 +02:00
if ( GetSpellProto () -> EquippedItemClass != - 1 || GetSpellProto () -> EquippedItemInventoryTypeMask != 0 )
2010-01-10 01:23:15 +01:00
{
// wand magic case (skip generic to all item spell bonuses)
// done in Player::_ApplyWeaponDependentAuraMods
// Skip item specific requirements for not wand magic damage
return ;
}
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( GetAmount () > 0 )
2010-01-10 01:23:15 +01:00
{
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & ( 1 << i )) != 0 )
2010-01-10 01:23:15 +01:00
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i , GetAmount (), apply );
}
}
else
{
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & ( 1 << i )) != 0 )
2010-01-10 01:23:15 +01:00
target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i , GetAmount (), apply );
}
}
2010-04-07 19:14:10 +02:00
if ( Guardian * pet = target -> ToPlayer () -> GetGuardianPet ())
2010-01-10 01:23:15 +01:00
pet -> UpdateAttackPowerAndDamage ();
}
}
void AuraEffect :: HandleModDamagePercentDone ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
sLog . outDebug ( "AURA MOD DAMAGE type:%u negative:%u" , GetMiscValue (), GetAmount () > 0 );
// apply item specific bonuses for already equipped weapon
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
2010-04-07 19:14:10 +02:00
if ( Item * pItem = target -> ToPlayer () -> GetWeaponForAttack ( WeaponAttackType ( i ), true ))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> _ApplyWeaponDependentAuraDamageMod ( pItem , WeaponAttackType ( i ), this , apply );
2010-01-10 01:23:15 +01:00
}
// GetMiscValue() is bitmask of spell schools
2010-04-07 22:59:46 +02:00
// 1 (0-bit) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
2010-01-10 01:23:15 +01:00
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
// 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
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ) != 0 )
2010-01-10 01:23:15 +01:00
{
// apply generic physical damage bonuses including wand case
if ( GetSpellProto () -> EquippedItemClass == - 1 || target -> GetTypeId () != TYPEID_PLAYER )
{
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_MAINHAND , TOTAL_PCT , float ( GetAmount ()), apply );
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_PCT , float ( GetAmount ()), apply );
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_RANGED , TOTAL_PCT , float ( GetAmount ()), apply );
2010-01-13 11:56:20 +01:00
// For show in client
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-13 11:56:20 +01:00
target -> ApplyModSignedFloatValue ( PLAYER_FIELD_MOD_DAMAGE_DONE_PCT , GetAmount () / 100.0f , apply );
2010-01-10 01:23:15 +01:00
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
}
// Skip non magic case for speedup
2010-04-07 19:14:10 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_MAGIC ) == 0 )
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 22:59:46 +02:00
if ( GetSpellProto () -> EquippedItemClass != - 1 || GetSpellProto () -> EquippedItemInventoryTypeMask != 0 )
2010-01-10 01:23:15 +01:00
{
// wand magic case (skip generic to all item spell bonuses)
// done in Player::_ApplyWeaponDependentAuraMods
// Skip item specific requirements for not wand magic damage
return ;
}
// Magic damage percent modifiers implemented in Unit::SpellDamageBonus
// Send info to client
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; ++ i )
target -> ApplyModSignedFloatValue ( PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i , GetAmount () / 100.0f , apply );
}
void AuraEffect :: HandleModOffhandDamagePercent ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_PCT , float ( GetAmount ()), apply );
}
void AuraEffect :: HandleShieldBlockValue ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
BaseModType modType = FLAT_MOD ;
2010-04-07 19:14:10 +02:00
if ( GetAuraType () == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT )
2010-01-10 01:23:15 +01:00
modType = PCT_MOD ;
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> HandleBaseModValue ( SHIELD_BLOCK_VALUE , modType , float ( GetAmount ()), apply );
2010-01-10 01:23:15 +01:00
}
/********************************/
/*** POWER COST ***/
/********************************/
void AuraEffect :: HandleModPowerCostPCT ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
float amount = GetAmount () / 100.0f ;
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & ( 1 << i ))
2010-01-10 01:23:15 +01:00
target -> ApplyModSignedFloatValue ( UNIT_FIELD_POWER_COST_MULTIPLIER + i , amount , apply );
}
void AuraEffect :: HandleModPowerCost ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
2010-04-07 19:14:10 +02:00
if ( GetMiscValue () & ( 1 << i ))
2010-01-10 01:23:15 +01:00
target -> ApplyModInt32Value ( UNIT_FIELD_POWER_COST_MODIFIER + i , GetAmount (), apply );
}
void AuraEffect :: HandleArenaPreparation ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
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
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PREPARATION );
}
}
void AuraEffect :: HandleNoReagentUseAura ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
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 )
mask |= ( * i ) -> m_spellProto -> EffectSpellClassMask [( * i ) -> m_effIndex ];
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 ]);
}
void AuraEffect :: HandleAuraRetainComboPoints ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
// 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)
2010-04-07 23:25:02 +02:00
if ( ! ( apply ) && GetBase () -> GetDuration () == 0 && target -> ToPlayer () -> GetComboTarget ())
2010-04-07 19:14:10 +02:00
if ( Unit * unit = ObjectAccessor :: GetUnit ( * target , target -> ToPlayer () -> GetComboTarget ()))
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> AddComboPoints ( unit , - GetAmount ());
2010-01-10 01:23:15 +01:00
}
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
void AuraEffect :: HandleAuraDummy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
// AT APPLY
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
// Overpower
if ( caster && m_spellProto -> SpellFamilyName == SPELLFAMILY_WARRIOR &&
m_spellProto -> SpellFamilyFlags [ 0 ] & 0x4 )
{
2010-01-23 16:37:06 +01:00
// In addition, if you strike a player..
if ( target -> GetTypeId () != TYPEID_PLAYER )
return ;
// ..while they are casting
2010-01-10 01:23:15 +01:00
if ( target -> IsNonMeleeSpellCasted ( false , false , true ))
{
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( SPELL_AURA_ADD_FLAT_MODIFIER , SPELLFAMILY_WARRIOR , 2775 , 0 ))
{
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
2010-04-07 22:59:46 +02:00
if ( caster && target -> CanHaveThreatList ())
2010-01-10 01:23:15 +01:00
target -> AddThreat ( caster , 10.0f );
break ;
case 13139 : // net-o-matic
// root to self part of (root_target->charge->root_self sequence
2010-04-07 19:14:10 +02:00
if ( caster )
2010-01-10 01:23:15 +01:00
caster -> CastSpell ( caster , 13138 , true , NULL , this );
break ;
case 34026 : // kill command
{
Unit * pet = target -> GetGuardianPet ();
if ( ! pet )
break ;
target -> CastSpell ( target , 34027 , true , NULL , this );
// set 3 stacks and 3 charges (to make all auras not disappear at once)
Aura * owner_aura = target -> GetAura ( 34027 , GetCasterGUID ());
Aura * pet_aura = pet -> GetAura ( 58914 , GetCasterGUID ());
2010-04-07 22:59:46 +02:00
if ( owner_aura )
2010-01-10 01:23:15 +01:00
{
owner_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
2010-04-07 22:59:46 +02:00
if ( pet_aura )
2010-01-10 01:23:15 +01:00
{
pet_aura -> SetCharges ( 0 );
pet_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
break ;
}
case 37096 : // Blood Elf Illusion
{
2010-04-07 19:14:10 +02:00
if ( caster )
2010-01-10 01:23:15 +01:00
{
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)
Aura * owner_aura = target -> GetAura ( 55166 , GetCasterGUID ());
2010-04-07 22:59:46 +02:00
if ( owner_aura )
2010-01-10 01:23:15 +01:00
{
// 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 );
owner_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
break ;
}
case 39850 : // Rocket Blast
2010-04-07 19:14:10 +02:00
if ( roll_chance_i ( 20 )) // backfire stun
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 51581 , true , NULL , this );
break ;
case 43873 : // Headless Horseman Laugh
target -> PlayDistanceSound ( 11965 );
break ;
case 46354 : // Blood Elf Illusion
2010-04-07 19:14:10 +02:00
if ( caster )
2010-01-10 01:23:15 +01:00
{
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 ;
2010-02-01 21:25:10 +01:00
case 46361 : // Reinforced Net
if ( caster )
{
float currentGroundLevel = target -> GetBaseMap () -> GetHeight ( target -> GetPositionX (), target -> GetPositionY (), MAX_HEIGHT );
if ( target -> GetPositionZ () > currentGroundLevel )
2010-04-07 18:09:10 +02:00
target -> GetMotionMaster () -> MoveFall ( currentGroundLevel );
2010-02-01 21:25:10 +01:00
}
break ;
2010-01-10 01:23:15 +01:00
case 46699 : // Requires No Ammo
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> RemoveAmmo (); // not use ammo and not allow use
2010-01-10 01:23:15 +01:00
break ;
case 49028 :
2010-04-12 11:34:57 +02:00
if ( caster )
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( 63330 , 0 )) // glyph of Dancing Rune Weapon
GetBase () -> SetDuration ( GetBase () -> GetDuration () + aurEff -> GetAmount ());
2010-01-10 01:23:15 +01:00
break ;
case 62061 : // Festive Holiday Mount
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( SPELL_AURA_MOUNTED ))
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 25860 , true , NULL , this ); // Reindeer Transformation
break ;
case 52916 : // Honor Among Thieves
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
if ( Unit * spellTarget = ObjectAccessor :: GetUnit ( * target , target -> ToPlayer () -> GetComboTarget ()))
2010-01-10 01:23:15 +01:00
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
2010-04-07 19:14:10 +02:00
if ( caster ) // actually we can also use cast(this, originalcasterguid)
2010-01-10 01:23:15 +01:00
{
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 ;
}
2010-04-07 19:14:10 +02:00
if ( damage )
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( 28836 , SPELLVALUE_BASE_POINT0 , damage , target );
}
break ;
}
}
// AT REMOVE
else
{
2010-04-07 22:59:46 +02:00
if (( IsQuestTameSpell ( GetId ())) && caster && caster -> isAlive () && target -> isAlive ())
2010-01-10 01:23:15 +01: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-04-07 19:14:10 +02:00
if ( finalSpelId )
2010-01-10 01:23:15 +01:00
caster -> CastSpell ( target , finalSpelId , true , NULL , this );
}
switch ( m_spellProto -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
switch ( GetId ())
{
case 2584 : // Waiting to Resurrect
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
if ( BattleGround * bg = target -> ToPlayer () -> GetBattleGround ())
2010-01-10 01:23:15 +01:00
bg -> RemovePlayerFromResurrectQueue ( target -> GetGUID ());
break ;
case 28169 : // Mutating Injection
{
// Mutagen Explosion
target -> CastSpell ( target , 28206 , true , NULL , this );
// Poison Cloud
target -> CastSpell ( target , 28240 , true , NULL , this );
return ;
}
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 ;
target -> CastSpell ( target , spellId , true , NULL , this );
}
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 ;
}
break ;
case SPELLFAMILY_MAGE :
// Living Bomb
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x20000 )
2010-01-10 01:23:15 +01:00
{
AuraRemoveMode mode = aurApp -> GetRemoveMode ();
2010-04-07 19:14:10 +02:00
if ( caster && ( mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE ))
2010-01-10 01:23:15 +01:00
caster -> CastSpell ( target , GetAmount (), true );
}
break ;
case SPELLFAMILY_WARLOCK :
// Haunt
2010-04-07 19:14:10 +02:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x40000 )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( caster )
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( caster , 48210 , & m_amount , 0 , 0 , true , NULL , this );
}
break ;
case SPELLFAMILY_DRUID :
// Lifebloom
2010-04-07 22:59:46 +02:00
if ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x10 )
2010-01-10 01:23:15 +01:00
{
if ( ! apply )
{
// Final heal only on dispelled or duration end
if ( aurApp -> GetRemoveMode () != AURA_REMOVE_BY_EXPIRE && aurApp -> GetRemoveMode () != AURA_REMOVE_BY_ENEMY_SPELL )
return ;
// final heal
target -> CastCustomSpell ( target , 33778 , & m_amount , NULL , NULL , true , NULL , this , GetCasterGUID ());
// restore mana
if ( caster )
{
int32 returnmana = ( GetSpellProto () -> ManaCostPercentage * caster -> GetCreateMana () / 100 ) * GetBase () -> GetStackAmount () / 2 ;
caster -> CastCustomSpell ( caster , 64372 , & returnmana , NULL , NULL , true , NULL , this , GetCasterGUID ());
}
}
}
break ;
case SPELLFAMILY_PRIEST :
// Vampiric Touch
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x0400 && aurApp -> GetRemoveMode () == AURA_REMOVE_BY_ENEMY_SPELL )
{
if ( AuraEffect const * aurEff = GetBase () -> GetEffect ( 1 ))
{
int32 damage = aurEff -> GetAmount () * 4 ;
// backfire damage
target -> CastCustomSpell ( target , 64085 , & damage , NULL , NULL , true , NULL , NULL , GetCasterGUID ());
}
}
break ;
case SPELLFAMILY_HUNTER :
// Misdirection
2010-04-07 23:25:02 +02:00
if ( GetId () == 34477 )
2010-01-10 01:23:15 +01:00
target -> SetReducedThreatPercent ( 0 , 0 );
break ;
case SPELLFAMILY_DEATHKNIGHT :
2010-04-07 22:59:46 +02:00
// Summon Gargoyle (will start feeding gargoyle)
2010-04-07 23:25:02 +02:00
if ( GetId () == 61777 )
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , m_spellProto -> EffectTriggerSpell [ m_effIndex ], true );
break ;
default :
break ;
}
}
}
// AT APPLY & REMOVE
switch ( m_spellProto -> SpellFamilyName )
{
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 )
{
SpellEntry const * spell = sSpellStore . LookupEntry ( spellId );
for ( int 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 )
{
SpellEntry const * spell = sSpellStore . LookupEntry ( spellId );
for ( int i = 0 ; i < spell -> StackAmount ; ++ i )
caster -> CastSpell ( target , spell -> Id , true , NULL , NULL , GetCasterGUID ());
break ;
}
target -> RemoveAurasDueToSpell ( spellId );
break ;
}
2010-01-10 22:37:31 +03:00
// Tag Murloc
case 30877 :
{
// Tag/untag Blacksilt Scout
target -> SetEntry ( apply ? 17654 : 17326 );
break ;
}
2010-01-10 01:23:15 +01:00
//Summon Fire Elemental
case 40133 :
{
if ( ! caster )
break ;
Unit * owner = caster -> GetOwner ();
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
owner -> CastSpell ( owner , 8985 , true );
else
2010-03-07 15:20:19 +01:00
owner -> ToPlayer () -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
2010-01-10 01:23:15 +01:00
}
break ;
}
//Summon Earth Elemental
case 40132 :
{
if ( ! caster )
break ;
Unit * owner = caster -> GetOwner ();
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
owner -> CastSpell ( owner , 19704 , true );
else
2010-03-07 15:20:19 +01:00
owner -> ToPlayer () -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
2010-01-10 01:23:15 +01:00
}
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
{
2010-04-07 19:14:10 +02:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
break ;
uint32 FactionID = 0 ;
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
switch ( m_spellProto -> Id )
{
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
}
}
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> SetChampioningFaction ( FactionID );
2010-01-10 01:23:15 +01:00
break ;
}
// LK Intro VO (1)
case 58204 :
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
// Play part 1
2010-04-07 19:14:10 +02:00
if ( apply )
2010-03-11 20:51:31 +01:00
target -> PlayDirectSound ( 14970 , target -> ToPlayer ());
2010-01-10 01:23:15 +01:00
// continue in 58205
else
target -> CastSpell ( target , 58205 , true );
}
break ;
// LK Intro VO (2)
case 58205 :
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
{
// Play part 2
2010-04-07 19:14:10 +02:00
if ( apply )
2010-03-11 20:51:31 +01:00
target -> PlayDirectSound ( 14971 , target -> ToPlayer ());
2010-01-10 01:23:15 +01:00
// Play part 3
else
2010-03-11 20:51:31 +01:00
target -> PlayDirectSound ( 14972 , target -> ToPlayer ());
2010-01-10 01:23:15 +01:00
}
break ;
}
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 ())
{
2010-02-15 18:46:41 +01:00
case 52610 : // Savage Roar
{
uint32 spellId = 62071 ;
if ( apply )
{
if ( target -> m_form != FORM_CAT )
break ;
2010-04-07 18:09:10 +02:00
2010-02-15 18:46:41 +01:00
target -> CastSpell ( target , spellId , true , NULL , NULL , GetCasterGUID ());
break ;
}
target -> RemoveAurasDueToSpell ( spellId );
break ;
}
2010-01-10 01:23:15 +01:00
case 61336 : // Survival Instincts
{
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
break ;
2010-02-15 18:46:41 +01:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
if ( ! target -> IsInFeralForm ())
break ;
int32 bp0 = int32 ( target -> GetMaxHealth () * GetAmount () / 100 );
target -> CastCustomSpell ( target , 50322 , & bp0 , NULL , NULL , true );
}
else
target -> RemoveAurasDueToSpell ( 50322 );
break ;
}
}
// Predatory Strikes
2010-02-15 18:46:41 +01:00
if ( target -> GetTypeId () == TYPEID_PLAYER && GetSpellProto () -> SpellIconID == 1563 )
2010-01-10 01:23:15 +01:00
{
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> UpdateAttackPowerAndDamage ();
2010-01-10 01:23:15 +01:00
}
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 )
{
Creature * totem = caster -> GetMap () -> GetCreature ( guid );
if ( totem && totem -> isTotem ())
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> CastSpell ( totem , 6277 , true );
2010-01-10 01:23:15 +01:00
}
}
else
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> StopCastingBindSight ();
2010-01-10 01:23:15 +01:00
return ;
}
break ;
}
case SPELLFAMILY_PALADIN :
2010-01-10 14:51:34 +01:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
break ;
2010-01-10 01:23:15 +01:00
switch ( GetSpellProto () -> SpellIconID )
{
// Blessing of Sanctuary
// Greater Blessing of Sanctuary
case 19 :
case 1804 :
{
2010-01-10 14:51:34 +01:00
if ( ! caster )
break ;
2010-01-10 01:23:15 +01:00
if ( apply )
{
// Greater Blessing of Sanctuary does not provide strength bonus
int32 bp1 = 0 ;
caster -> CastCustomSpell ( target , 67480 , NULL , ( GetSpellProto () -> SpellIconID == 1804 ) ? & bp1 : NULL , NULL , true );
}
else
target -> RemoveAura ( 67480 , GetCasterGUID ());
2010-01-10 14:51:34 +01:00
break ;
2010-01-10 01:23:15 +01:00
}
}
break ;
}
if ( mode & AURA_EFFECT_HANDLE_REAL )
{
// pet auras
2010-04-07 19:14:10 +02:00
if ( PetAura const * petSpell = spellmgr . GetPetAura ( GetId (), m_effIndex ))
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
target -> AddPetAura ( petSpell );
else
target -> RemovePetAura ( petSpell );
}
}
}
void AuraEffect :: HandleChannelDeathItem ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-21 16:03:38 +01:00
Player * plCaster = caster -> ToPlayer ();
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> getDeathState () != JUST_DIED )
2010-01-10 01:23:15 +01:00
return ;
2010-03-15 02:59:21 +01:00
2010-01-10 01:23:15 +01:00
// Item amount
if ( GetAmount () <= 0 )
return ;
2010-04-07 19:14:10 +02:00
if ( GetSpellProto () -> EffectItemType [ m_effIndex ] == 0 )
2010-01-10 01:23:15 +01:00
return ;
2010-03-21 16:03:38 +01:00
// Soul Shard
if ( GetSpellProto () -> EffectItemType [ m_effIndex ] == 6265 )
{
// Soul Shard only from units that grant XP or honor
if ( ! plCaster -> isHonorOrXPTarget ( target ) ||
( target -> GetTypeId () == TYPEID_UNIT && ! target -> ToCreature () -> isTappedBy ( plCaster )))
return ;
// If this is Drain Soul, check for Glyph of Drain Soul
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x00004000 ))
{
// Glyph of Drain Soul - chance to create an additional Soul Shard
if ( AuraEffect * aur = caster -> GetAuraEffect ( 58070 , 0 ))
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-03-15 02:59:21 +01:00
2010-01-10 01:23:15 +01:00
//Adding items
uint32 noSpaceForCount = 0 ;
uint32 count = m_amount ;
2010-04-07 18:09:10 +02:00
2010-01-10 01:23:15 +01:00
ItemPosCountVec dest ;
2010-03-21 16:03:38 +01:00
uint8 msg = plCaster -> CanStoreNewItem ( NULL_BAG , NULL_SLOT , dest , GetSpellProto () -> EffectItemType [ m_effIndex ], count , & noSpaceForCount );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2010-01-10 01:23:15 +01:00
{
count -= noSpaceForCount ;
2010-03-21 16:03:38 +01:00
plCaster -> SendEquipError ( msg , NULL , NULL );
2010-04-07 23:25:02 +02:00
if ( count == 0 )
2010-01-10 01:23:15 +01:00
return ;
}
2010-03-21 16:03:38 +01:00
Item * newitem = plCaster -> StoreNewItem ( dest , GetSpellProto () -> EffectItemType [ m_effIndex ], true );
if ( ! newitem )
{
plCaster -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
return ;
}
plCaster -> SendNewItem ( newitem , count , true , true );
2010-01-10 01:23:15 +01:00
}
}
void AuraEffect :: HandleBindSight ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
Unit * caster = GetCaster ();
2010-04-07 19:14:10 +02:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> SetViewpoint ( target , ( apply ));
2010-01-10 01:23:15 +01:00
}
void AuraEffect :: HandleForceReaction ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
Player * player = ( Player * ) target ;
uint32 faction_id = GetMiscValue ();
ReputationRank faction_rank = ReputationRank ( m_amount );
player -> GetReputationMgr (). ApplyForceReaction ( faction_id , faction_rank , apply );
player -> GetReputationMgr (). SendForceReactions ();
// 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 );
}
void AuraEffect :: HandleAuraEmpathy ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( target -> GetTypeId () != TYPEID_UNIT )
return ;
2010-04-07 19:14:10 +02:00
if ( ! ( apply ))
2010-01-10 01:23:15 +01:00
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
2010-04-07 19:14:10 +02:00
if ( target -> HasAuraType ( GetAuraType ()))
2010-01-10 01:23:15 +01:00
return ;
}
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( target -> GetEntry ());
2010-04-07 19:14:10 +02:00
if ( ci && ci -> type == CREATURE_TYPE_BEAST )
2010-01-10 01:23:15 +01:00
target -> ApplyModUInt32Value ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_SPECIALINFO , apply );
}
2010-01-13 18:22:31 +01:00
void AuraEffect :: HandleAuraModFaction ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-13 18:22:31 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-13 18:22:31 +01:00
{
target -> setFaction ( GetMiscValue ());
2010-04-07 23:25:02 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-13 18:22:31 +01:00
target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PVP_ATTACKABLE );
}
else
{
target -> RestoreFaction ();
2010-04-07 23:25:02 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-01-13 18:22:31 +01:00
target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PVP_ATTACKABLE );
}
}
2010-01-13 10:45:34 +01:00
2010-01-10 01:23:15 +01:00
void AuraEffect :: HandleComprehendLanguage ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
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 ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
else
{
if ( target -> HasAuraType ( GetAuraType ()))
return ;
target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
}
}
void AuraEffect :: HandleAuraConvertRune ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
return ;
Player * plr = ( Player * ) target ;
2010-04-07 19:14:10 +02:00
if ( plr -> getClass () != CLASS_DEATH_KNIGHT )
2010-01-10 01:23:15 +01:00
return ;
uint32 runes = m_amount ;
// convert number of runes specified in aura amount of rune type in miscvalue to runetype in miscvalueb
2010-04-07 19:14:10 +02:00
if ( apply )
2010-01-10 01:23:15 +01:00
{
for ( uint32 i = 0 ; i < MAX_RUNES && runes ; ++ i )
{
if ( GetMiscValue () != plr -> GetCurrentRune ( i ))
continue ;
2010-04-07 19:14:10 +02:00
if ( ! plr -> GetRuneCooldown ( i ))
2010-01-10 01:23:15 +01:00
{
2010-04-07 18:09:10 +02:00
// ConvertRune(i,
2010-01-10 01:23:15 +01:00
plr -> AddRuneByAuraEffect ( i , RuneType ( GetMiscValueB ()), this );
-- runes ;
}
}
}
else
plr -> RemoveRunesByAuraEffect ( this );
}
void AuraEffect :: HandleAuraLinked ( AuraApplication const * aurApp , uint8 mode , bool apply ) const
{
2010-04-07 19:14:10 +02:00
if ( ! ( mode & AURA_EFFECT_HANDLE_REAL ))
2010-01-10 01:23:15 +01:00
return ;
Unit * target = aurApp -> GetTarget ();
if ( apply )
{
Unit * caster = GetCaster ();
if ( ! caster )
return ;
// If amount avalible cast with basepoints (Crypt Fever for example)
if ( GetAmount ())
caster -> CastCustomSpell ( target , m_spellProto -> EffectTriggerSpell [ m_effIndex ], & m_amount , NULL , NULL , true , NULL , this );
else
caster -> CastSpell ( target , m_spellProto -> EffectTriggerSpell [ m_effIndex ], true , NULL , this );
}
else
target -> RemoveAura ( m_spellProto -> EffectTriggerSpell [ m_effIndex ], GetCasterGUID (), 0 , AuraRemoveMode ( aurApp -> GetRemoveMode ()));
}