2008-10-11 14:16:25 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-11 14:16:25 -05: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
2008-11-04 09:23:06 -06:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-11 14:16:25 -05:00
* 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
2008-11-04 09:23:06 -06:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-11 14:16:25 -05:00
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "UpdateMask.h"
#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
#include "DynamicObject.h"
#include "Group.h"
#include "UpdateData.h"
#include "ObjectAccessor.h"
#include "Policies/SingletonImp.h"
#include "Totem.h"
#include "Creature.h"
#include "Formulas.h"
#include "BattleGround.h"
2008-10-14 11:57:03 -05:00
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
2008-10-11 14:16:25 -05:00
#include "CreatureAI.h"
2009-03-16 15:46:27 -06:00
#include "ScriptCalls.h"
2008-10-11 14:16:25 -05:00
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
2009-05-05 16:56:15 -05:00
#include "Vehicle.h"
2008-10-11 14:16:25 -05:00
#include "CellImpl.h"
pAuraHandler AuraHandler [ TOTAL_AURAS ] =
{
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleNULL , // 0 SPELL_AURA_NONE
& AuraEffect :: HandleBindSight , // 1 SPELL_AURA_BIND_SIGHT
& AuraEffect :: HandleModPossess , // 2 SPELL_AURA_MOD_POSSESS
& AuraEffect :: HandlePeriodicDamage , // 3 SPELL_AURA_PERIODIC_DAMAGE
& 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 :: HandlePeriodicHeal , // 8 SPELL_AURA_PERIODIC_HEAL
& 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_STEALTH_DETECT
& AuraEffect :: HandleInvisibility , // 18 SPELL_AURA_MOD_INVISIBILITY
& AuraEffect :: HandleInvisibilityDetect , // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
& AuraEffect :: HandleAuraModTotalHealthPercentRegen , // 20 SPELL_AURA_OBS_MOD_HEALTH
& AuraEffect :: HandleAuraModTotalEnergyPercentRegen , // 21 SPELL_AURA_OBS_MOD_ENERGY
& AuraEffect :: HandleAuraModResistance , // 22 SPELL_AURA_MOD_RESISTANCE
& AuraEffect :: HandlePeriodicTriggerSpell , // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
& AuraEffect :: HandlePeriodicEnergize , // 24 SPELL_AURA_PERIODIC_ENERGIZE
& 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 :: HandleAuraProcTriggerSpell , // 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 :: HandleUnused , // 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 :: HandleAuraModCritPercent , // 52 SPELL_AURA_MOD_CRIT_PERCENT
& AuraEffect :: HandlePeriodicLeech , // 53 SPELL_AURA_PERIODIC_LEECH
& 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 :: HandlePeriodicHealthFunnel , // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
& AuraEffect :: HandleUnused , // 63 unused (3.0.8a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
& AuraEffect :: HandlePeriodicManaLeech , // 64 SPELL_AURA_PERIODIC_MANA_LEECH
& 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 :: HandleSchoolAbsorb , // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
& AuraEffect :: HandleUnused , // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
& 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 :: HandleFarSight , // 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
& AuraEffect :: HandleWaterBreathing , // 82 SPELL_AURA_WATER_BREATHING
& AuraEffect :: HandleModBaseResistance , // 83 SPELL_AURA_MOD_BASE_RESISTANCE
& AuraEffect :: HandleModRegen , // 84 SPELL_AURA_MOD_REGEN
& AuraEffect :: HandleModPowerRegen , // 85 SPELL_AURA_MOD_POWER_REGEN
& 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
& AuraEffect :: HandlePeriodicDamagePCT , // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
& AuraEffect :: HandleUnused , // 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::RegenerateAll
& AuraEffect :: HandleAuraGhost , // 95 SPELL_AURA_GHOST
2009-04-19 11:42:16 -05:00
& AuraEffect :: HandleNoImmediateEffect , // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleManaShield , // 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 :: HandleAddModifier , //107 SPELL_AURA_ADD_FLAT_MODIFIER
& AuraEffect :: HandleAddModifier , //108 SPELL_AURA_ADD_PCT_MODIFIER
2009-06-06 12:53:38 +02:00
& AuraEffect :: HandleNoImmediateEffect , //109 SPELL_AURA_ADD_TARGET_TRIGGER
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleModPowerRegenPCT , //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
2009-04-19 11:42:16 -05:00
& AuraEffect :: HandleNoImmediateEffect , //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
2009-04-06 13:31:14 +02:00
& 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 :: HandleUnused , //119 unused (3.0.8a) 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
2009-05-08 18:52:12 -05:00
& AuraEffect :: HandleAuraSafeFall , //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleAuraModPetTalentsPoints , //145 SPELL_AURA_MOD_PET_TALENT_POINTS
& AuraEffect :: HandleNoImmediateEffect , //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
2009-04-10 23:44:37 +02:00
& AuraEffect :: HandleModStateImmunityMask , //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
2009-04-06 13:31:14 +02:00
& 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 :: HandleAuraPowerBurn , //162 SPELL_AURA_POWER_BURN_MANA
& AuraEffect :: HandleNoImmediateEffect , //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
& AuraEffect :: HandleUnused , //164 unused (3.0.8a), 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 different spells that ignore transformation effects
& AuraEffect :: HandleAuraModIncreaseSpeed , //171 SPELL_AURA_MOD_SPEED_NOT_STACK
& AuraEffect :: HandleAuraModIncreaseMountedSpeed , //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
& AuraEffect :: HandleUnused , //173 unused (3.0.8a) 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 :: HandleNULL , //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
2009-04-06 21:14:51 +02:00
& AuraEffect :: HandleUnused , //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleAuraModResistenceOfStatPercent , //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
& AuraEffect :: HandleNULL , //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746
& 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
2009-05-14 20:02:10 -05:00
& AuraEffect :: HandleNoImmediateEffect , //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
& AuraEffect :: HandleAuraModUseNormalSpeed , //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
2009-04-06 13:31:14 +02:00
& AuraEffect :: HandleModMeleeRangedSpeedPct , //192 SPELL_AURA_HASTE_MELEE
& AuraEffect :: HandleModCombatSpeedPct , //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
& AuraEffect :: HandleNULL , //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
& AuraEffect :: HandleNoImmediateEffect , //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
& AuraEffect :: HandleUnused , //198 unused (3.0.8a) 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::GiveXP
& 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 vulnerable to school dmg?
2009-05-02 16:08:52 +02:00
& 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
2009-04-06 13:31:14 +02:00
& 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.0.8a)
& 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 ignored
& AuraEffect :: HandleUnused , //222 unused (3.0.8a) 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 :: HandleAuraPeriodicDummy , //226 SPELL_AURA_PERIODIC_DUMMY
& AuraEffect :: HandlePeriodicTriggerSpellWithValue , //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
& AuraEffect :: HandleNoImmediateEffect , //228 stealth detection
& AuraEffect :: HandleNULL , //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 :: HandleNULL , //233 set model id to the one of the creature with id GetMiscValue()
& AuraEffect :: HandleNoImmediateEffect , //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
2009-05-16 17:59:36 +02:00
& AuraEffect :: HandleNoImmediateEffect , //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
2009-04-06 13:31:14 +02:00
& 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 Forces the player to move forward
& AuraEffect :: HandleUnused , //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
& AuraEffect :: HandleNULL , //243 faction reaction override spells
& AuraEffect :: HandleComprehendLanguage , //244 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 :: HandleNULL , //247 target to become a clone of the 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 :: HandleNULL , //252 haste all?
& 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.0.8a)
& AuraEffect :: HandleUnused , //265 unused (3.0.8a)
& AuraEffect :: HandleUnused , //266 unused (3.0.8a)
& 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
& AuraEffect :: HandleNULL , //272 reduce spell cast time?
& 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 :: HandleNULL , //279 visual effects? 58836 and 57507
& AuraEffect :: HandleNoImmediateEffect , //280 SPELL_AURA_MOD_WEAPONTYPE_IGNORE_TARGET_RESISTANCE
& 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 :: HandleUnused , //284 not used by any spells (3.08a)
& AuraEffect :: HandleUnused , //285 not used by any spells (3.08a)
& AuraEffect :: HandleUnused , //286 not used by any spells (3.08a)
& AuraEffect :: HandleNoImmediateEffect , //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
& AuraEffect :: HandleUnused , //288 not used by any spells (3.09) except 1 test spell.
2008-10-11 14:16:25 -05:00
};
2009-05-23 22:21:26 -05:00
Aura :: Aura ( SpellEntry const * spellproto , uint32 effMask , int32 * currentBasePoints , Unit * target , WorldObject * source , Unit * caster , Item * castItem ) :
2009-04-06 13:31:14 +02:00
m_caster_guid ( 0 ), m_castItemGuid ( castItem ? castItem -> GetGUID () : 0 ), m_target ( target ),
2009-06-04 22:25:37 -05:00
m_timeCla ( 0 ), m_removeMode ( AURA_REMOVE_BY_DEFAULT ), m_AuraDRGroup ( DIMINISHING_NONE ),
2009-05-19 18:33:49 +02:00
m_auraSlot ( MAX_AURAS ), m_auraLevel ( 1 ), m_procCharges ( 0 ), m_stackAmount ( 1 ), m_auraStateMask ( 0 ), m_updated ( false ), m_isRemoved ( false )
2008-10-11 14:16:25 -05:00
{
assert ( target );
assert ( spellproto && spellproto == sSpellStore . LookupEntry ( spellproto -> Id ) && "`info` must be pointer to sSpellStore element" );
2009-04-06 13:31:14 +02:00
m_auraFlags = effMask ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
m_spellProto = spellproto ;
2008-10-11 14:16:25 -05:00
2009-06-04 22:25:37 -05:00
if ( m_spellProto -> manaPerSecond || m_spellProto -> manaPerSecondPerLevel )
m_timeCla = 1000 ;
2008-10-11 14:16:25 -05:00
m_isPassive = IsPassiveSpell ( GetId ());
2009-04-06 13:31:14 +02:00
2009-02-22 18:36:05 +01:00
m_auraStateMask = 0 ;
2008-10-11 14:16:25 -05:00
2009-04-02 16:44:18 -06:00
m_isSingleTargetAura = IsSingleTargetSpell ( m_spellProto );
2008-10-11 14:16:25 -05:00
m_applyTime = time ( NULL );
if ( ! caster )
{
m_caster_guid = target -> GetGUID ();
2008-12-24 10:57:04 -06:00
//damage = m_currentBasePoints+1; // stored value-1
2009-04-06 21:14:51 +02:00
m_maxduration = target -> CalcSpellDuration ( m_spellProto );
2008-10-11 14:16:25 -05:00
}
else
{
m_caster_guid = caster -> GetGUID ();
2008-12-24 16:22:19 -06:00
//damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
2009-02-07 22:03:29 +01:00
m_maxduration = caster -> CalcSpellDuration ( m_spellProto );
2008-10-11 14:16:25 -05:00
}
if ( m_maxduration == - 1 || m_isPassive && m_spellProto -> DurationIndex == 0 )
m_permanent = true ;
2009-04-06 13:31:14 +02:00
else
m_permanent = false ;
2008-10-11 14:16:25 -05:00
Player * modOwner = caster ? caster -> GetSpellModOwner () : NULL ;
if ( ! m_permanent && modOwner )
2009-02-17 14:52:46 -06:00
{
2008-10-11 14:16:25 -05:00
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_DURATION , m_maxduration );
2009-02-17 14:52:46 -06:00
// Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
if ( m_maxduration <= 0 )
m_maxduration = 1 ;
}
2008-10-11 14:16:25 -05:00
m_duration = m_maxduration ;
m_isDeathPersist = IsDeathPersistentSpell ( m_spellProto );
2009-01-04 23:47:58 -06:00
m_procCharges = m_spellProto -> procCharges ;
if ( modOwner )
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_CHARGES , m_procCharges );
2008-10-11 14:16:25 -05:00
2009-02-13 20:03:32 -06:00
m_isRemovedOnShapeLost = ( m_caster_guid == m_target -> GetGUID () &&
2009-01-29 19:33:39 -06:00
m_spellProto -> Stances &&
2009-02-13 20:03:32 -06:00
! ( m_spellProto -> AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT ) &&
2009-01-29 19:33:39 -06:00
! ( m_spellProto -> Attributes & SPELL_ATTR_NOT_SHAPESHIFT ));
2009-04-06 13:31:14 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( m_auraFlags & ( uint8 ( 1 ) << i ))
{
2009-05-07 17:21:07 -05:00
if ( currentBasePoints )
2009-05-23 20:50:21 -05:00
m_partAuras [ i ] = CreateAuraEffect ( this , i , currentBasePoints + i , caster , NULL , source );
2009-04-06 13:31:14 +02:00
else
2009-05-23 20:50:21 -05:00
m_partAuras [ i ] = CreateAuraEffect ( this , i , NULL , caster , NULL , source );
2009-04-06 13:31:14 +02:00
// correct flags if aura couldn't be created
2009-04-06 18:19:05 +02:00
if ( ! m_partAuras [ i ])
2009-04-08 18:32:48 +02:00
m_auraFlags &= uint8 ( ~ ( 1 << i ));
2009-04-06 13:31:14 +02:00
}
else
{
m_partAuras [ i ] = NULL ;
}
}
2009-04-06 21:14:51 +02:00
// Aura is positive when it is casted by friend and at least one aura is positive
2009-04-06 13:31:14 +02:00
// or when it is casted by enemy and at least one aura is negative
bool swap = false ;
2009-04-14 19:09:08 +02:00
if ( ! caster || caster == target ) // caster == target - 1 negative effect is enough for aura to be negative
m_positive = false ;
2009-04-06 13:31:14 +02:00
else
m_positive = ! caster -> IsHostileTo ( m_target );
2009-04-14 19:09:08 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( ! ( 1 << i & GetEffectMask ()))
continue ;
if ( m_positive == IsPositiveEffect ( GetId (), i ))
2009-04-06 13:31:14 +02:00
{
2009-04-14 19:09:08 +02:00
swap = true ;
break ;
2009-04-06 13:31:14 +02:00
}
}
2009-04-14 19:09:08 +02:00
if ( ! swap )
m_positive =! m_positive ;
2008-10-11 14:16:25 -05:00
}
Aura ::~ Aura ()
{
2009-04-06 13:31:14 +02:00
// free part auras memory
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( m_partAuras [ i ])
delete m_partAuras [ i ];
}
2009-05-23 22:21:26 -05:00
AuraEffect :: AuraEffect ( Aura * parentAura , uint8 effIndex , int32 * currentBasePoints , Unit * caster , Item * castItem , WorldObject * source ) :
2009-04-06 13:31:14 +02:00
m_parentAura ( parentAura ), m_spellmod ( NULL ), m_periodicTimer ( 0 ), m_isPeriodic ( false ), m_isAreaAura ( false ), m_isPersistent ( false ),
2009-04-15 12:05:59 -05:00
m_target ( parentAura -> GetTarget ()), m_tickNumber ( 0 )
2009-06-03 11:22:00 -05:00
, m_spellProto ( parentAura -> GetSpellProto ()), m_effIndex ( effIndex ), m_auraName ( AuraType ( m_spellProto -> EffectApplyAuraName [ m_effIndex ]))
2009-04-06 13:31:14 +02:00
{
2009-06-03 11:22:00 -05:00
assert ( m_auraName < TOTAL_AURAS );
2009-04-06 13:31:14 +02:00
2009-04-08 00:55:43 +02:00
if ( currentBasePoints )
m_currentBasePoints = * currentBasePoints ;
else
m_currentBasePoints = m_spellProto -> EffectBasePoints [ m_effIndex ];
if ( caster )
m_amount = caster -> CalculateSpellDamage ( m_spellProto , m_effIndex , m_currentBasePoints , m_target );
else
m_amount = m_currentBasePoints + 1 ;
2009-04-06 13:31:14 +02:00
if ( ! m_amount && castItem && castItem -> GetItemSuffixFactor ())
{
ItemRandomSuffixEntry const * item_rand_suffix = sItemRandomSuffixStore . LookupEntry ( abs ( castItem -> GetItemRandomPropertyId ()));
if ( item_rand_suffix )
{
for ( int k = 0 ; k < 3 ; k ++ )
{
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( item_rand_suffix -> enchant_id [ k ]);
if ( pEnchant )
{
for ( int t = 0 ; t < 3 ; t ++ )
if ( pEnchant -> spellid [ t ] == m_spellProto -> Id )
{
m_amount = uint32 (( item_rand_suffix -> prefix [ k ] * castItem -> GetItemSuffixFactor ()) / 10000 );
break ;
}
}
if ( m_amount )
break ;
}
}
}
Player * modOwner = caster ? caster -> GetSpellModOwner () : NULL ;
2009-05-23 22:21:26 -05:00
m_sourceGUID = source ? source -> GetGUID () : ( caster ? caster -> GetGUID () : 0 );
2009-04-06 13:31:14 +02:00
m_amplitude = m_spellProto -> EffectAmplitude [ m_effIndex ];
//apply casting time mods for channeled spells
if ( modOwner && m_amplitude && IsChanneledSpell ( m_spellProto ))
modOwner -> ModSpellCastTime ( m_spellProto , m_amplitude );
// Apply periodic time mod
if ( modOwner && m_amplitude )
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_ACTIVATION_TIME , m_amplitude );
// Start periodic on next tick or at aura apply
if ( ! ( m_spellProto -> AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY ))
m_periodicTimer += m_amplitude ;
2009-06-06 13:45:17 +02:00
m_isApplied = false ;
2008-10-11 14:16:25 -05:00
}
2009-05-23 20:50:21 -05:00
AreaAuraEffect :: AreaAuraEffect ( Aura * parentAura , uint32 effIndex , int32 * currentBasePoints , Unit * caster , Item * castItem , Unit * source )
2009-05-23 22:21:26 -05:00
: AuraEffect ( parentAura , effIndex , currentBasePoints , caster , castItem , source )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_removeTime = FRIENDLY_AA_REMOVE_TIME ;
2008-10-11 14:16:25 -05:00
m_isAreaAura = true ;
2009-05-24 00:05:17 -05:00
Unit * caster_ptr = caster ? caster : source ? source : m_target ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if ( m_spellProto -> Effect [ effIndex ] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY )
2009-02-14 15:56:04 +01:00
m_radius = GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( GetSpellProto () -> EffectRadiusIndex [ m_effIndex ]));
2009-04-06 21:14:51 +02:00
else
2009-02-14 15:56:04 +01:00
m_radius = GetSpellRadiusForFriend ( sSpellRadiusStore . LookupEntry ( GetSpellProto () -> EffectRadiusIndex [ m_effIndex ]));
2008-10-11 14:16:25 -05:00
if ( Player * modOwner = caster_ptr -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_RADIUS , m_radius );
2009-04-06 13:31:14 +02:00
switch ( m_spellProto -> Effect [ effIndex ])
2008-10-11 14:16:25 -05:00
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY :
m_areaAuraType = AREA_AURA_PARTY ;
2009-04-06 13:31:14 +02:00
if ( m_target -> GetTypeId () == TYPEID_UNIT && (( Creature * ) m_target ) -> isTotem ())
2009-06-03 16:20:35 -05:00
* const_cast < AuraType *> ( & m_auraName ) = SPELL_AURA_NONE ;
2008-10-11 14:16:25 -05:00
break ;
2008-12-24 09:58:26 -06:00
case SPELL_EFFECT_APPLY_AREA_AURA_RAID :
m_areaAuraType = AREA_AURA_RAID ;
2009-04-06 13:31:14 +02:00
if ( m_target -> GetTypeId () == TYPEID_UNIT && (( Creature * ) m_target ) -> isTotem ())
2009-06-03 16:20:35 -05:00
* const_cast < AuraType *> ( & m_auraName ) = SPELL_AURA_NONE ;
2008-12-24 09:58:26 -06:00
break ;
2008-10-11 14:16:25 -05:00
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND :
m_areaAuraType = AREA_AURA_FRIEND ;
break ;
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY :
m_areaAuraType = AREA_AURA_ENEMY ;
2009-04-06 13:31:14 +02:00
if ( m_target == caster_ptr )
2009-06-03 16:20:35 -05:00
* const_cast < AuraType *> ( & m_auraName ) = SPELL_AURA_NONE ; // Do not do any effect on self
2008-10-11 14:16:25 -05:00
break ;
case SPELL_EFFECT_APPLY_AREA_AURA_PET :
m_areaAuraType = AREA_AURA_PET ;
break ;
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER :
m_areaAuraType = AREA_AURA_OWNER ;
2009-04-06 13:31:14 +02:00
if ( m_target == caster_ptr )
2009-06-03 16:20:35 -05:00
* const_cast < AuraType *> ( & m_auraName ) = SPELL_AURA_NONE ;
2008-10-11 14:16:25 -05:00
break ;
default :
sLog . outError ( "Wrong spell effect in AreaAura constructor" );
ASSERT ( false );
break ;
}
}
2009-04-06 13:31:14 +02:00
AreaAuraEffect ::~ AreaAuraEffect ()
2008-10-11 14:16:25 -05:00
{
}
2009-05-23 22:21:26 -05:00
PersistentAreaAuraEffect :: PersistentAreaAuraEffect ( Aura * parentAura , uint32 effIndex , int32 * currentBasePoints , Unit * caster , Item * castItem , DynamicObject * source )
: AuraEffect ( parentAura , effIndex , currentBasePoints , caster , castItem , source )
2008-10-11 14:16:25 -05:00
{
m_isPersistent = true ;
}
2009-04-06 13:31:14 +02:00
PersistentAreaAuraEffect ::~ PersistentAreaAuraEffect ()
2008-10-11 14:16:25 -05:00
{
}
2009-05-23 22:21:26 -05:00
AuraEffect * CreateAuraEffect ( Aura * parentAura , uint32 effIndex , int32 * currentBasePoints , Unit * caster , Item * castItem , WorldObject * source )
2008-10-11 14:16:25 -05:00
{
2009-05-23 22:21:26 -05:00
// TODO: source should belong to aura, but not areaeffect. multiple areaaura/persistent aura should use one source
assert ( parentAura );
2009-04-06 13:31:14 +02:00
if ( IsAreaAuraEffect ( parentAura -> GetSpellProto () -> Effect [ effIndex ]))
2009-05-23 22:21:26 -05:00
{
2009-05-26 22:06:27 -05:00
if ( ! source )
source = caster ;
2009-05-23 22:21:26 -05:00
//TODO: determine source here
if ( source && source -> isType ( TYPEMASK_UNIT ))
return new AreaAuraEffect ( parentAura , effIndex , currentBasePoints , caster , castItem , ( Unit * ) source );
}
2009-04-06 13:31:14 +02:00
else if ( parentAura -> GetSpellProto () -> Effect [ effIndex ] == SPELL_EFFECT_APPLY_AURA )
2009-05-23 22:21:26 -05:00
return new AuraEffect ( parentAura , effIndex , currentBasePoints , caster , castItem , source );
2009-04-06 13:31:14 +02:00
else if ( parentAura -> GetSpellProto () -> Effect [ effIndex ] == SPELL_EFFECT_PERSISTENT_AREA_AURA )
return new PersistentAreaAuraEffect ( parentAura , effIndex , currentBasePoints , caster , castItem );
2009-05-23 22:21:26 -05:00
return NULL ;
2008-10-11 14:16:25 -05:00
}
Unit * Aura :: GetCaster () const
{
if ( m_caster_guid == m_target -> GetGUID ())
return m_target ;
//return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
//must return caster even if it's in another grid/map
Unit * unit = ObjectAccessor :: GetObjectInWorld ( m_caster_guid , ( Unit * ) NULL );
return unit && unit -> IsInWorld () ? unit : NULL ;
}
2009-05-23 22:21:26 -05:00
Unit * AuraEffect :: GetSource () const
2009-04-20 16:48:35 +02:00
{
2009-05-23 22:21:26 -05:00
if ( m_sourceGUID == m_target -> GetGUID ())
2009-04-20 16:48:35 +02:00
return m_target ;
//return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
//must return caster even if it's in another grid/map
2009-05-23 20:50:21 -05:00
Unit * unit = ObjectAccessor :: GetObjectInWorld ( m_sourceGUID , ( Unit * ) NULL );
2009-05-23 22:21:26 -05:00
//only player can be not in world while in objectaccessor
2009-04-20 16:48:35 +02:00
return unit && unit -> IsInWorld () ? unit : NULL ;
}
2008-10-11 14:16:25 -05:00
void Aura :: Update ( uint32 diff )
{
2009-06-06 08:27:36 +02:00
// TODO: store pointer to caster in aura class for update/mod handling code
2008-10-11 14:16:25 -05:00
if ( m_duration > 0 )
{
m_duration -= diff ;
if ( m_duration < 0 )
m_duration = 0 ;
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
2009-06-04 22:25:37 -05:00
if ( m_timeCla )
2008-10-11 14:16:25 -05:00
{
2009-06-04 22:25:37 -05:00
if ( m_timeCla > diff )
m_timeCla -= diff ;
else if ( Unit * caster = GetCaster ())
2008-10-11 14:16:25 -05:00
{
2009-04-12 17:25:12 -05:00
if ( int32 manaPerSecond = m_spellProto -> manaPerSecond + m_spellProto -> manaPerSecondPerLevel * caster -> getLevel ())
2008-10-11 14:16:25 -05:00
{
2009-06-04 22:25:37 -05:00
m_timeCla += 1000 - diff ;
2009-04-12 17:25:12 -05:00
Powers powertype = Powers ( m_spellProto -> powerType );
if ( powertype == POWER_HEALTH )
2009-03-22 11:34:34 +01:00
{
2009-04-12 17:25:12 -05:00
if ( caster -> GetHealth () > manaPerSecond )
2009-03-22 11:34:34 +01:00
caster -> ModifyHealth ( - manaPerSecond );
else
2009-04-12 17:25:12 -05:00
{
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( this );
2009-04-12 17:25:12 -05:00
return ;
}
2009-03-22 11:34:34 +01:00
}
else
2009-04-12 17:25:12 -05:00
{
if ( caster -> GetPower ( powertype ) >= manaPerSecond )
caster -> ModifyPower ( powertype , - manaPerSecond );
else
{
m_target -> RemoveAura ( this );
return ;
}
}
2008-10-11 14:16:25 -05:00
}
}
}
}
2009-06-06 08:27:36 +02:00
// Apply charged spellmods for channeled auras
// used for example when triggered spell of spell:10 is modded
Spell * modSpell = NULL ;
Unit * caster = NULL ;
2009-06-06 08:42:43 +02:00
if ( IS_PLAYER_GUID ( GetCasterGUID ()))
2009-06-06 08:27:36 +02:00
{
caster = GetCaster ();
if ( caster )
2009-06-06 15:58:50 +02:00
{
modSpell = (( Player * ) caster ) -> FindCurrentSpellBySpellId ( GetId ());
2009-06-06 08:27:36 +02:00
(( Player * ) caster ) -> SetSpellModTakingSpell ( modSpell , true );
2009-06-06 15:58:50 +02:00
}
2009-06-06 08:27:36 +02:00
}
2009-04-13 18:21:48 -05:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
if ( m_partAuras [ i ])
2009-04-13 18:21:48 -05:00
m_partAuras [ i ] -> Update ( diff );
2009-06-06 08:27:36 +02:00
if ( caster )
(( Player * ) caster ) -> SetSpellModTakingSpell ( modSpell , false );
2009-04-06 13:31:14 +02:00
}
void AuraEffect :: Update ( uint32 diff )
{
if ( m_isPeriodic && ( GetParentAura () -> GetAuraDuration () >= 0 || GetParentAura () -> IsPassive () || GetParentAura () -> IsPermanent ()))
2008-10-11 14:16:25 -05:00
{
2009-06-04 22:25:37 -05:00
if ( m_periodicTimer > diff )
m_periodicTimer -= diff ;
else // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
2008-10-11 14:16:25 -05:00
{
2009-04-13 18:15:26 -05:00
++ m_tickNumber ;
2008-10-11 14:16:25 -05:00
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
2009-06-04 22:25:37 -05:00
m_periodicTimer += m_amplitude - diff ;
2008-10-11 14:16:25 -05:00
2009-01-07 18:23:56 -06:00
if ( ! m_target -> hasUnitState ( UNIT_STAT_ISOLATED ))
2009-01-22 22:44:27 -06:00
PeriodicTick ();
2008-10-11 14:16:25 -05:00
}
}
}
2009-04-06 13:31:14 +02:00
void AreaAuraEffect :: Update ( uint32 diff )
2008-10-11 14:16:25 -05:00
{
// update for the caster of the aura
2009-05-23 20:50:21 -05:00
if ( m_sourceGUID == m_target -> GetGUID ())
2008-10-11 14:16:25 -05:00
{
2009-05-24 00:05:17 -05:00
Unit * source = m_target ;
Unit * caster = GetCaster ();
if ( ! caster )
2009-05-29 16:52:35 -05:00
{
2009-05-19 18:33:49 +02:00
m_target -> RemoveAura ( GetParentAura ());
2009-05-29 16:52:35 -05:00
return ;
}
2008-10-11 14:16:25 -05:00
2009-05-24 00:05:17 -05:00
if ( ! source -> hasUnitState ( UNIT_STAT_ISOLATED ) )
2008-10-11 14:16:25 -05:00
{
std :: list < Unit *> targets ;
switch ( m_areaAuraType )
{
case AREA_AURA_PARTY :
2009-05-24 00:05:17 -05:00
source -> GetPartyMember ( targets , m_radius );
2009-01-09 16:43:23 -06:00
break ;
2008-12-24 09:58:26 -06:00
case AREA_AURA_RAID :
2009-05-24 00:05:17 -05:00
source -> GetRaidMember ( targets , m_radius );
2008-10-11 14:16:25 -05:00
break ;
case AREA_AURA_FRIEND :
{
2009-05-24 00:05:17 -05:00
Trinity :: AnyFriendlyUnitInObjectRangeCheck u_check ( source , caster , m_radius );
Trinity :: UnitListSearcher < Trinity :: AnyFriendlyUnitInObjectRangeCheck > searcher ( source , targets , u_check );
source -> VisitNearbyObject ( m_radius , searcher );
2008-10-11 14:16:25 -05:00
break ;
}
case AREA_AURA_ENEMY :
{
2009-05-24 00:05:17 -05:00
Trinity :: AnyAoETargetUnitInObjectRangeCheck u_check ( source , caster , m_radius ); // No GetCharmer in searcher
Trinity :: UnitListSearcher < Trinity :: AnyAoETargetUnitInObjectRangeCheck > searcher ( source , targets , u_check );
source -> VisitNearbyObject ( m_radius , searcher );
2008-10-11 14:16:25 -05:00
break ;
}
case AREA_AURA_OWNER :
case AREA_AURA_PET :
{
2008-12-23 20:01:05 -06:00
if ( Unit * owner = caster -> GetCharmerOrOwner ())
2008-10-11 14:16:25 -05:00
targets . push_back ( owner );
break ;
}
}
2009-05-10 01:19:39 -05:00
for ( std :: list < Unit *>:: iterator tIter = targets . begin (); tIter != targets . end (); tIter ++ )
2008-10-11 14:16:25 -05:00
{
2009-05-19 18:33:49 +02:00
if ( Aura * aur = ( * tIter ) -> GetAura ( GetId (), GetCasterGUID ()))
2009-04-20 18:58:35 +02:00
{
2009-05-10 01:19:39 -05:00
if ( aur -> HasEffect ( GetEffIndex ()))
continue ;
}
else
{
bool skip = false ;
for ( Unit :: AuraMap :: iterator iter = ( * tIter ) -> GetAuras (). begin (); iter != ( * tIter ) -> GetAuras (). end (); ++ iter )
2009-04-20 18:58:35 +02:00
{
2009-05-19 18:33:49 +02:00
bool samecaster = iter -> second -> GetCasterGUID () == GetCasterGUID ();
2009-05-10 01:19:39 -05:00
if ( spellmgr . IsNoStackSpellDueToSpell ( GetId (), iter -> first , samecaster ))
2009-04-20 18:58:35 +02:00
{
2009-05-10 01:19:39 -05:00
skip = true ;
break ;
2009-04-20 18:58:35 +02:00
}
}
2009-05-10 01:19:39 -05:00
if ( skip )
continue ;
2009-04-20 18:58:35 +02:00
}
2008-10-11 14:16:25 -05:00
if ( SpellEntry const * actualSpellInfo = spellmgr . SelectAuraRankForPlayerLevel ( GetSpellProto (), ( * tIter ) -> getLevel ()))
{
2008-12-30 23:04:39 -06:00
//int32 actualBasePoints = m_currentBasePoints;
2008-10-11 14:16:25 -05:00
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
2008-12-30 23:04:39 -06:00
//if(actualSpellInfo != GetSpellProto())
// actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
2009-05-24 00:05:17 -05:00
( * tIter ) -> AddAuraEffect ( actualSpellInfo , GetEffIndex (), caster , & m_currentBasePoints , source );
2009-04-02 22:23:51 -06:00
if ( m_areaAuraType == AREA_AURA_ENEMY )
caster -> CombatStart ( * tIter );
2008-10-11 14:16:25 -05:00
}
}
}
2009-04-06 13:31:14 +02:00
AuraEffect :: Update ( diff );
2008-10-11 14:16:25 -05:00
}
else // aura at non-caster
{
2009-04-12 17:53:05 +02:00
// WARNING: the aura may get deleted during the update
// DO NOT access its members after update!
AuraEffect :: Update ( diff );
// Speedup - no need to do more checks
if ( GetParentAura () -> IsRemoved ())
return ;
2009-04-12 18:31:22 +02:00
// Caster may be deleted due to update
2009-05-24 00:05:17 -05:00
Unit * caster = GetCaster ();
Unit * source = GetSource ();
2008-10-11 14:16:25 -05:00
// remove aura if out-of-range from caster (after teleport for example)
// or caster is isolated or caster no longer has the aura
// or caster is (no longer) friendly
bool needFriendly = ( m_areaAuraType == AREA_AURA_ENEMY ? false : true );
2009-05-24 00:05:17 -05:00
if ( ! source || ! caster ||
source -> hasUnitState ( UNIT_STAT_ISOLATED ) || ! source -> HasAuraEffect ( GetId (), m_effIndex ) ||
2009-04-12 18:31:22 +02:00
caster -> IsFriendlyTo ( m_target ) != needFriendly
2008-10-11 14:16:25 -05:00
)
{
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2008-10-11 14:16:25 -05:00
}
2009-05-24 00:05:17 -05:00
else if ( ! source -> IsWithinDistInMap ( m_target , m_radius ))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( needFriendly )
{
m_removeTime -= diff ;
if ( m_removeTime < 0 )
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2009-04-06 13:31:14 +02:00
}
else
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2008-12-24 09:58:26 -06:00
}
2009-04-06 13:31:14 +02:00
else
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
// Reset aura remove timer
m_removeTime = FRIENDLY_AA_REMOVE_TIME ;
if ( m_areaAuraType == AREA_AURA_PARTY ) // check if in same sub group
{
2009-04-12 18:31:22 +02:00
if ( ! m_target -> IsInPartyWith ( caster ))
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2009-04-06 13:31:14 +02:00
}
else if ( m_areaAuraType == AREA_AURA_RAID )
{
2009-04-12 18:31:22 +02:00
if ( ! m_target -> IsInRaidWith ( caster ))
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2009-04-06 13:31:14 +02:00
}
else if ( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
2009-04-12 18:31:22 +02:00
if ( m_target -> GetGUID () != caster -> GetCharmerOrOwnerGUID () )
2009-04-07 20:27:34 +02:00
m_target -> RemoveAura ( GetParentAura ());
2009-04-06 13:31:14 +02:00
}
2008-10-11 14:16:25 -05:00
}
}
}
2009-04-06 13:31:14 +02:00
void PersistentAreaAuraEffect :: Update ( uint32 diff )
2008-10-11 14:16:25 -05:00
{
2009-04-20 23:08:03 +02:00
if ( Unit * caster = GetParentAura () -> GetCaster ())
2008-10-11 14:16:25 -05:00
{
2009-04-12 17:25:12 -05:00
if ( DynamicObject * dynObj = caster -> GetDynObject ( GetId (), GetEffIndex ()))
2008-10-11 14:16:25 -05:00
{
2009-04-12 17:25:12 -05:00
if ( m_target -> IsWithinDistInMap ( dynObj , dynObj -> GetRadius ()))
{
AuraEffect :: Update ( diff );
return ;
}
2008-10-11 14:16:25 -05:00
}
}
2009-04-12 17:25:12 -05:00
// remove the aura if its caster or the dynamic object causing it was removed
// or if the target moves too far from the dynamic object
m_target -> RemoveAura ( GetParentAura ());
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: ApplyModifier ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-04-07 20:27:34 +02:00
if ( GetParentAura () -> IsRemoved ())
return ;
2008-10-11 14:16:25 -05:00
2009-06-03 11:22:00 -05:00
( * this . * AuraHandler [ m_auraName ])( apply , Real , changeAmount );
2009-05-16 17:59:36 +02:00
}
2009-05-23 11:26:08 +02:00
void AuraEffect :: RecalculateAmount ( bool applied )
2009-05-16 17:59:36 +02:00
{
Unit * caster = GetParentAura () -> GetCaster ();
2009-05-23 11:17:15 -05:00
int32 amount = GetParentAura () -> GetStackAmount () * ( caster ? caster -> CalculateSpellDamage ( m_spellProto , GetEffIndex (), GetBasePoints (), NULL ) : GetBasePoints ());
2009-05-16 17:59:36 +02:00
// Reapply if amount change
if ( amount != GetAmount ())
{
// Auras which are applying spellmod should have removed spellmods for real
2009-05-23 11:26:08 +02:00
if ( applied )
ApplyModifier ( false , false , true );
2009-05-16 17:59:36 +02:00
SetAmount ( amount );
2009-05-23 11:26:08 +02:00
if ( applied )
ApplyModifier ( true , false , true );
2009-05-16 17:59:36 +02:00
}
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
void AuraEffect :: CleanupTriggeredSpells ()
{
uint32 tSpellId = m_spellProto -> EffectTriggerSpell [ GetEffIndex ()];
if ( ! tSpellId )
return ;
SpellEntry const * tProto = sSpellStore . LookupEntry ( tSpellId );
if ( ! tProto )
return ;
if ( GetSpellDuration ( tProto ) != - 1 )
return ;
// needed for spell 43680, maybe others
// TODO: is there a spell flag, which can solve this in a more sophisticated way?
if ( m_spellProto -> EffectApplyAuraName [ GetEffIndex ()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
GetSpellDuration ( m_spellProto ) == m_spellProto -> EffectAmplitude [ GetEffIndex ()])
return ;
m_target -> RemoveAurasDueToSpell ( tSpellId , GetCasterGUID ());
}
void Aura :: ApplyAllModifiers ( bool apply , bool Real )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( m_partAuras [ i ])
m_partAuras [ i ] -> ApplyModifier ( apply , Real );
}
void Aura :: SendAuraUpdate ()
{
if ( m_auraSlot >= MAX_AURAS )
return ;
WorldPacket data ( SMSG_AURA_UPDATE );
data . append ( m_target -> GetPackGUID ());
data << uint8 ( m_auraSlot );
if ( ! m_target -> GetVisibleAura ( m_auraSlot ))
{
data << uint32 ( 0 );
sLog . outDebug ( "Aura %u removed slot %u" , GetId (), m_auraSlot );
m_target -> SendMessageToSet ( & data , true );
return ;
}
data << uint32 ( GetId ());
data << uint8 ( m_auraFlags );
data << uint8 ( m_auraLevel );
2009-04-12 01:29:56 +02:00
data << uint8 ( m_stackAmount > 1 ? m_stackAmount : m_procCharges );
2009-04-06 13:31:14 +02:00
if ( ! ( m_auraFlags & AFLAG_CASTER ))
{
if ( Unit * caster = GetCaster ())
data . append ( caster -> GetPackGUID ());
else
data << uint8 ( 0 );
}
if ( m_auraFlags & AFLAG_DURATION )
{
data << uint32 ( m_maxduration );
data << uint32 ( m_duration );
}
m_target -> SendMessageToSet ( & data , true );
}
2009-05-24 00:05:17 -05:00
bool Aura :: IsVisible () const
{
// passive auras (except totem auras) do not get placed in the slots
// area auras with SPELL_AURA_NONE are not shown on target
//(m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId()))
if ( ! m_isPassive )
return true ;
bool noneAreaAura = true ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( m_partAuras [ i ])
{
if ( m_partAuras [ i ] -> IsAreaAura ())
{
if ( WorldObject * source = m_partAuras [ i ] -> GetSource ())
if ( source -> GetTypeId () == TYPEID_UNIT && (( Creature * ) source ) -> isTotem ())
return true ;
if ( m_partAuras [ i ] -> GetAuraName () != SPELL_AURA_NONE )
noneAreaAura = false ;
}
else
noneAreaAura = false ;
}
}
if ( noneAreaAura )
return false ;
return IsAuraType ( SPELL_AURA_ABILITY_IGNORE_AURASTATE );
}
2008-10-11 14:16:25 -05:00
void Aura :: _AddAura ()
{
if ( ! GetId ())
return ;
if ( ! m_target )
return ;
2009-02-06 19:42:03 +01:00
Unit * caster = GetCaster ();
2009-03-02 16:59:14 -06:00
// set infinity cooldown state for spells
if ( caster && caster -> GetTypeId () == TYPEID_PLAYER )
{
2009-04-13 20:50:52 +02:00
if ( m_spellProto -> Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
2009-03-02 16:59:14 -06:00
{
Item * castItem = m_castItemGuid ? (( Player * ) caster ) -> GetItemByGuid ( m_castItemGuid ) : NULL ;
(( Player * ) caster ) -> AddSpellAndCategoryCooldowns ( m_spellProto , castItem ? castItem -> GetEntry () : 0 , NULL , true );
}
}
2009-05-24 00:05:17 -05:00
if ( IsVisible ())
2009-04-06 13:31:14 +02:00
{
// Try find slot for aura
uint8 slot = MAX_AURAS ;
// Lookup for auras already applied from spell
if ( Aura * foundAura = m_target -> GetAura ( GetId (), GetCasterGUID ()))
2008-10-11 14:16:25 -05:00
{
// allow use single slot only by auras from same caster
2009-04-06 13:31:14 +02:00
slot = foundAura -> GetAuraSlot ();
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
else
2009-01-09 16:06:17 -06:00
{
2009-04-06 13:31:14 +02:00
Unit :: VisibleAuraMap const * visibleAuras = m_target -> GetVisibleAuras ();
// lookup for free slots in units visibleAuras
Unit :: VisibleAuraMap :: const_iterator itr = visibleAuras -> find ( 0 );
for ( uint32 freeSlot = 0 ; freeSlot < MAX_AURAS ; ++ itr , ++ freeSlot )
2009-01-09 16:06:17 -06:00
{
2009-03-13 20:24:40 +01:00
if ( itr == visibleAuras -> end () || itr -> first != freeSlot )
{
slot = freeSlot ;
break ;
}
2009-01-09 16:06:17 -06:00
}
2009-04-06 13:31:14 +02:00
}
2009-01-09 16:06:17 -06:00
2009-04-06 13:31:14 +02:00
// Register Visible Aura
if ( slot < MAX_AURAS )
{
m_auraFlags |= ( IsPositive () ? AFLAG_POSITIVE : AFLAG_NEGATIVE ) |
2009-03-15 17:01:46 -06:00
( GetCasterGUID () == m_target -> GetGUID () ? AFLAG_CASTER : AFLAG_NONE ) |
( GetAuraMaxDuration () > 0 ? AFLAG_DURATION : AFLAG_NONE );
2009-04-06 13:31:14 +02:00
m_auraLevel = ( caster ? caster -> getLevel () : sWorld . getConfig ( CONFIG_MAX_PLAYER_LEVEL ));
SetAuraSlot ( slot );
m_target -> SetVisibleAura ( slot , this );
m_target -> UpdateAuraForGroup ( slot );
SendAuraUpdate ();
sLog . outDebug ( "Aura: %u Effect: %d put to unit visible auras slot: %u" , GetId (), GetEffectMask (), slot );
2009-03-13 20:24:40 +01:00
}
2009-04-06 13:31:14 +02:00
else
sLog . outDebug ( "Aura: %u Effect: %d could not find empty unit visible slot" , GetId (), GetEffectMask ());
2009-03-15 17:01:46 -06:00
}
2009-02-06 19:42:03 +01:00
2009-04-06 13:31:14 +02:00
// Sitdown on apply aura req seated
if ( m_spellProto -> AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && ! m_target -> IsSitState ())
m_target -> SetStandState ( UNIT_STAND_STATE_SIT );
2009-02-06 19:42:03 +01:00
2009-04-06 13:31:14 +02:00
// register aura diminishing on apply
if ( getDiminishGroup () != DIMINISHING_NONE )
m_target -> ApplyDiminishingAura ( getDiminishGroup (), true );
2009-03-15 17:01:46 -06:00
2009-04-06 13:31:14 +02:00
// Apply linked auras (On first aura apply)
uint32 id = GetId ();
if ( spellmgr . GetSpellCustomAttr ( id ) & SPELL_ATTR_CU_LINK_AURA )
2009-03-22 10:53:23 +01:00
{
2009-04-06 13:31:14 +02:00
if ( const std :: vector < int32 > * spell_triggered = spellmgr . GetSpellLinked ( id + SPELL_LINK_AURA ))
for ( std :: vector < int32 >:: const_iterator itr = spell_triggered -> begin (); itr != spell_triggered -> end (); ++ itr )
2009-04-11 00:27:30 +02:00
{
2009-04-06 13:31:14 +02:00
if ( * itr < 0 )
2009-05-09 10:48:14 -05:00
m_target -> ApplySpellImmune ( id , IMMUNITY_ID , - ( * itr ), true );
2009-04-06 13:31:14 +02:00
else if ( Unit * caster = GetCaster ())
2009-04-20 16:48:35 +02:00
caster -> AddAura ( * itr , m_target );
2009-04-11 00:27:30 +02:00
}
2009-03-22 10:53:23 +01:00
}
2009-01-09 16:06:17 -06:00
2009-02-06 19:42:03 +01:00
//*****************************************************
2009-02-23 16:36:11 +01:00
// Update target aura state flag
2009-02-06 19:42:03 +01:00
//*****************************************************
2009-02-23 16:36:11 +01:00
// Update Seals information
if ( IsSealSpell ( m_spellProto ))
SetAuraState ( AURA_STATE_JUDGEMENT );
2009-01-09 16:06:17 -06:00
2009-04-25 13:58:26 +02:00
// Conflagrate aura state on Immolate or Shadowflame
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( m_spellProto -> SpellFamilyFlags [ 0 ] & 4
|| m_spellProto -> SpellFamilyFlags [ 2 ] & 2 ))
2009-02-23 16:36:11 +01:00
SetAuraState ( AURA_STATE_IMMOLATE );
2009-01-22 22:44:27 -06:00
2009-02-23 16:36:11 +01:00
// Faerie Fire (druid versions)
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x400 )
SetAuraState ( AURA_STATE_FAERIE_FIRE );
2008-10-11 14:16:25 -05:00
2009-02-23 16:36:11 +01:00
// Victorious
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto -> SpellFamilyFlags [ 1 ] & 0x00040000 )
SetAuraState ( AURA_STATE_WARRIOR_VICTORY_RUSH );
2008-10-11 14:16:25 -05:00
2009-02-23 16:36:11 +01:00
// Swiftmend state on Regrowth & Rejuvenation
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x50 )
SetAuraState ( AURA_STATE_SWIFTMEND );
2008-10-11 14:16:25 -05:00
2009-02-23 16:36:11 +01:00
// Deadly poison aura state
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto -> SpellFamilyFlags [ 0 ] & 0x10000 )
SetAuraState ( AURA_STATE_DEADLY_POISON );
2009-01-29 19:33:39 -06:00
2009-02-23 16:36:11 +01:00
// Enrage aura state
if ( m_spellProto -> Dispel == DISPEL_ENRAGE )
SetAuraState ( AURA_STATE_ENRAGE );
2009-02-22 18:36:05 +01:00
2009-04-06 13:31:14 +02:00
if ( GetSpellSchoolMask ( m_spellProto ) & SPELL_SCHOOL_MASK_FROST )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( m_spellProto -> EffectApplyAuraName [ i ] == SPELL_AURA_MOD_STUN
|| m_spellProto -> EffectApplyAuraName [ i ] == SPELL_AURA_MOD_ROOT )
{
SetAuraState ( AURA_STATE_FROZEN );
break ;
}
}
}
2009-02-23 16:36:11 +01:00
m_target -> ApplyModFlag ( UNIT_FIELD_AURASTATE , GetAuraStateMask (), true );
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
bool Aura :: SetPartAura ( AuraEffect * aurEff , uint8 effIndex )
{
2009-04-07 20:27:34 +02:00
if ( IsRemoved ())
return false ;
2009-04-06 18:19:05 +02:00
if ( m_auraFlags & ( 1 << effIndex ))
2009-04-06 13:31:14 +02:00
return false ;
m_auraFlags |= 1 << effIndex ;
m_partAuras [ effIndex ] = aurEff ;
m_target -> HandleAuraEffect ( aurEff , true );
SendAuraUpdate ();
return true ;
}
2008-10-11 14:16:25 -05:00
void Aura :: _RemoveAura ()
{
Unit * caster = GetCaster ();
uint8 slot = GetAuraSlot ();
2009-04-06 13:31:14 +02:00
if ( Aura * foundAura = m_target -> GetAura ( GetId (), GetCasterGUID ()))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
// allow use single slot only by auras from same caster
slot = foundAura -> GetAuraSlot ();
if ( slot < MAX_AURAS ) // slot not set
if ( Aura * entry = m_target -> GetVisibleAura ( slot ))
2009-03-06 18:52:39 +01:00
{
2009-04-06 13:31:14 +02:00
// set not valid slot for aura - prevent removing other visible aura
slot = MAX_AURAS ;
2009-03-06 18:52:39 +01:00
}
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
// update for out of range group members
if ( slot < MAX_AURAS )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> RemoveVisibleAura ( slot );
m_target -> UpdateAuraForGroup ( slot );
SendAuraUpdate ();
}
2009-03-13 20:24:40 +01:00
2009-04-06 13:31:14 +02:00
// unregister aura diminishing (and store last time)
if ( getDiminishGroup () != DIMINISHING_NONE )
m_target -> ApplyDiminishingAura ( getDiminishGroup (), false );
2009-01-18 19:01:41 -06:00
2009-04-06 13:31:14 +02:00
// Check needed only if aura applies aurastate
if ( GetAuraStateMask ())
{
uint32 foundMask = 0 ;
Unit :: AuraMap & Auras = m_target -> GetAuras ();
// Get mask of all aurastates from remaining auras
for ( Unit :: AuraMap :: iterator i = Auras . begin (); i != Auras . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
foundMask |= ( * i ). second -> GetAuraStateMask ();
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
// Remove only aurastates which were not found
foundMask = GetAuraStateMask () &~ foundMask ;
if ( foundMask )
m_target -> ApplyModFlag ( UNIT_FIELD_AURASTATE , foundMask , false );
}
2009-03-13 20:24:40 +01:00
2009-04-07 20:27:34 +02:00
// since now aura cannot apply/remove it's modifiers
m_isRemoved = true ;
// disable client server communication for removed aura
SetAuraSlot ( MAX_AURAS );
2009-04-06 13:31:14 +02:00
// reset cooldown state for spells
if ( caster && caster -> GetTypeId () == TYPEID_PLAYER )
{
if ( GetSpellProto () -> Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
(( Player * ) caster ) -> SendCooldownEvent ( GetSpellProto ());
}
2009-04-10 23:44:37 +02:00
uint32 id = GetId ();
// Remove Linked Auras
2009-05-23 10:57:05 +02:00
if ( m_removeMode != AURA_REMOVE_BY_STACK && m_removeMode != AURA_REMOVE_BY_DEATH && spellmgr . GetSpellCustomAttr ( id ) & SPELL_ATTR_CU_LINK_REMOVE )
2009-04-06 13:31:14 +02:00
{
2009-04-10 23:44:37 +02:00
if ( const std :: vector < int32 > * spell_triggered = spellmgr . GetSpellLinked ( - ( int32 ) id ))
for ( std :: vector < int32 >:: const_iterator itr = spell_triggered -> begin (); itr != spell_triggered -> end (); ++ itr )
2009-04-11 00:27:30 +02:00
{
2009-04-10 23:44:37 +02:00
if ( * itr < 0 )
m_target -> RemoveAurasDueToSpell ( - ( * itr ));
else if ( Unit * caster = GetCaster ())
2009-05-23 10:57:05 +02:00
if ( m_removeMode != AURA_REMOVE_BY_DEFAULT )
2009-03-13 20:24:40 +01:00
m_target -> CastSpell ( m_target , * itr , true , 0 , 0 , caster -> GetGUID ());
2009-04-11 00:27:30 +02:00
}
2009-04-06 13:31:14 +02:00
}
2009-05-23 10:57:05 +02:00
if ( m_removeMode != AURA_REMOVE_BY_STACK && m_removeMode != AURA_REMOVE_BY_DEATH && spellmgr . GetSpellCustomAttr ( id ) & SPELL_ATTR_CU_LINK_AURA )
2009-04-10 23:44:37 +02:00
{
if ( const std :: vector < int32 > * spell_triggered = spellmgr . GetSpellLinked ( id + SPELL_LINK_AURA ))
for ( std :: vector < int32 >:: const_iterator itr = spell_triggered -> begin (); itr != spell_triggered -> end (); ++ itr )
2009-04-11 00:27:30 +02:00
{
2009-04-10 23:44:37 +02:00
if ( * itr < 0 )
m_target -> ApplySpellImmune ( id , IMMUNITY_ID , - ( * itr ), false );
else
m_target -> RemoveAurasDueToSpell ( * itr );
2009-04-11 00:27:30 +02:00
}
2009-04-10 23:44:37 +02:00
}
2009-04-06 13:31:14 +02:00
// Proc on aura remove (only spell flags for now)
if ( caster )
{
uint32 procEx = 0 ;
if ( m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL )
procEx = PROC_EX_AURA_REMOVE_DESTROY ;
else if ( m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL )
procEx = PROC_EX_AURA_REMOVE_EXPIRE ;
2009-04-13 14:15:48 +02:00
if ( procEx )
{
uint32 ProcCaster , ProcVictim ;
if ( IsPositiveSpell ( GetId ()))
{
ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL ;
ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL ;
}
else
{
ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT ;
ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT ;
}
caster -> ProcDamageAndSpell ( m_target , ProcCaster , ProcVictim , procEx , m_procDamage , BASE_ATTACK , m_spellProto );
}
2009-04-06 13:31:14 +02:00
}
}
2009-05-23 11:26:08 +02:00
void Aura :: SetStackAmount ( uint8 stackAmount , bool applied )
2009-04-06 13:31:14 +02:00
{
if ( stackAmount != m_stackAmount )
{
2009-05-16 17:59:36 +02:00
m_stackAmount = stackAmount ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2009-05-16 17:59:36 +02:00
if ( AuraEffect * part = GetPartAura ( i ))
2009-04-06 13:31:14 +02:00
{
2009-05-23 11:26:08 +02:00
part -> RecalculateAmount ( applied );
2009-04-06 13:31:14 +02:00
}
}
}
RefreshAura ();
}
bool Aura :: modStackAmount ( int32 num )
{
// Can`t mod
if ( ! m_spellProto -> StackAmount )
return true ;
// Modify stack but limit it
int32 stackAmount = m_stackAmount + num ;
if ( stackAmount > m_spellProto -> StackAmount )
stackAmount = m_spellProto -> StackAmount ;
else if ( stackAmount <= 0 ) // Last aura from stack removed
{
m_stackAmount = 0 ;
return true ; // need remove aura
}
// Update stack amount
SetStackAmount ( stackAmount );
return false ;
}
2009-05-16 20:23:56 +02:00
void Aura :: SetAuraDuration ( int32 duration , bool withMods )
2009-04-06 13:31:14 +02:00
{
2009-05-16 20:23:56 +02:00
if ( withMods )
{
if ( Player * modOwner = m_target -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_DURATION , duration );
}
2009-04-06 13:31:14 +02:00
m_duration = duration ;
//if (duration<0)
//m_permanent=true;
2009-04-06 18:19:05 +02:00
//else
2009-04-06 13:31:14 +02:00
//m_permanent=false;
SendAuraUpdate ();
}
void Aura :: SetAuraCharges ( uint8 charges )
{
if ( m_procCharges == charges )
return ;
m_procCharges = charges ;
SendAuraUpdate ();
}
2009-06-06 08:27:36 +02:00
bool Aura :: DropAuraCharge ()
2009-04-06 13:31:14 +02:00
{
2009-04-19 12:10:53 -05:00
if ( m_procCharges ) //auras without charges always have charge = 0
{
2009-04-19 14:35:55 -05:00
if ( -- m_procCharges ) // Send charge change
2009-04-19 12:10:53 -05:00
SendAuraUpdate ();
else // Last charge dropped
2009-06-06 08:27:36 +02:00
{
2009-05-03 16:55:09 +02:00
m_target -> RemoveAura ( this , AURA_REMOVE_BY_EXPIRE );
2009-06-06 08:27:36 +02:00
return true ;
}
2009-04-19 12:10:53 -05:00
}
2009-06-06 08:27:36 +02:00
return false ;
2009-04-06 13:31:14 +02:00
}
bool Aura :: IsPersistent () const
{
2009-04-19 14:35:55 -05:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2009-04-19 14:35:55 -05:00
if ( m_partAuras [ i ] && m_partAuras [ i ] -> IsPersistent ())
return true ;
2009-04-06 13:31:14 +02:00
}
return false ;
}
bool Aura :: IsAreaAura () const
{
2009-04-19 14:35:55 -05:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2009-04-19 14:35:55 -05:00
if ( m_partAuras [ i ] && m_partAuras [ i ] -> IsAreaAura ())
return true ;
2009-04-06 13:31:14 +02:00
}
return false ;
}
bool Aura :: IsAuraType ( AuraType type ) const
{
2009-04-19 14:35:55 -05:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2009-04-19 14:35:55 -05:00
if ( m_partAuras [ i ] && m_partAuras [ i ] -> GetAuraName () == type )
return true ;
2009-04-06 13:31:14 +02:00
}
return false ;
}
void Aura :: SetLoadedState ( uint64 caster_guid , int32 maxduration , int32 duration , int32 charges , uint8 stackamount , int32 * amount )
{
m_caster_guid = caster_guid ;
m_maxduration = maxduration ;
m_duration = duration ;
m_procCharges = charges ;
m_stackAmount = stackamount ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( m_partAuras [ i ])
2009-04-08 00:07:32 +02:00
m_partAuras [ i ] -> SetAmount ( amount [ i ]);
2009-04-06 13:31:14 +02:00
}
void AuraEffect :: HandleShapeshiftBoosts ( bool apply )
{
uint32 spellId = 0 ;
uint32 spellId2 = 0 ;
uint32 HotWSpellId = 0 ;
switch ( GetMiscValue ())
{
case FORM_CAT :
spellId = 3025 ;
HotWSpellId = 24900 ;
break ;
case FORM_TREE :
spellId = 5420 ;
spellId2 = 34123 ;
break ;
case FORM_TRAVEL :
spellId = 5419 ;
break ;
case FORM_AQUA :
spellId = 5421 ;
break ;
case FORM_BEAR :
spellId = 1178 ;
spellId2 = 21178 ;
HotWSpellId = 24899 ;
break ;
case FORM_DIREBEAR :
spellId = 9635 ;
spellId2 = 21178 ;
HotWSpellId = 24899 ;
break ;
case FORM_BATTLESTANCE :
spellId = 21156 ;
break ;
case FORM_DEFENSIVESTANCE :
spellId = 7376 ;
break ;
case FORM_BERSERKERSTANCE :
spellId = 7381 ;
break ;
case FORM_MOONKIN :
spellId = 24905 ;
// aura from effect trigger spell
spellId2 = 24907 ;
break ;
case FORM_FLIGHT :
spellId = 33948 ;
spellId2 = 34764 ;
break ;
case FORM_FLIGHT_EPIC :
spellId = 40122 ;
spellId2 = 40121 ;
break ;
case FORM_METAMORPHOSIS :
spellId = 54817 ;
spellId2 = 54879 ;
break ;
case FORM_SPIRITOFREDEMPTION :
spellId = 27792 ;
spellId2 = 27795 ; // must be second, this important at aura remove to prevent to early iterator invalidation.
break ;
case FORM_GHOSTWOLF :
case FORM_AMBIENT :
case FORM_GHOUL :
case FORM_SHADOW :
case FORM_STEALTH :
case FORM_CREATURECAT :
case FORM_CREATUREBEAR :
spellId = 0 ;
break ;
}
uint32 form = GetMiscValue () - 1 ;
if ( apply )
{
if ( spellId ) m_target -> CastSpell ( m_target , spellId , true , NULL , this );
if ( spellId2 ) m_target -> CastSpell ( m_target , spellId2 , true , NULL , this );
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-03-13 22:48:04 +01:00
{
2009-04-06 13:31:14 +02:00
const PlayerSpellMap & sp_list = (( Player * ) m_target ) -> GetSpellMap ();
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
2009-03-13 22:48:04 +01:00
{
2009-04-06 13:31:14 +02:00
if ( itr -> second -> state == PLAYERSPELL_REMOVED ) continue ;
if ( itr -> first == spellId || itr -> first == spellId2 ) continue ;
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( itr -> first );
if ( ! spellInfo || ! ( spellInfo -> Attributes & ( SPELL_ATTR_PASSIVE | ( 1 << 7 )))) continue ;
if ( spellInfo -> Stances & ( 1 << form ))
m_target -> CastSpell ( m_target , itr -> first , true , NULL , this );
2009-03-13 22:48:04 +01:00
}
2009-04-06 13:31:14 +02:00
//LotP
if ((( Player * ) m_target ) -> HasSpell ( 17007 ))
2009-03-13 22:48:04 +01:00
{
2009-04-06 13:31:14 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( 24932 );
if ( spellInfo && spellInfo -> Stances & ( 1 << form ))
m_target -> CastSpell ( m_target , 24932 , true , NULL , this );
2009-03-13 22:48:04 +01:00
}
2009-04-06 13:31:14 +02:00
// HotW
if ( HotWSpellId )
{
Unit :: AuraEffectList const & mModTotalStatPct = m_target -> GetAurasByType ( 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 ();
if ( GetMiscValue () == FORM_CAT )
HotWMod /= 2 ;
2009-03-15 02:06:59 +01:00
2009-04-06 13:31:14 +02:00
m_target -> CastCustomSpell ( m_target , HotWSpellId , & HotWMod , NULL , NULL , true , NULL , this );
break ;
}
}
}
2009-03-13 22:48:04 +01:00
}
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
else
2009-01-09 16:06:17 -06:00
{
2009-04-06 13:31:14 +02:00
m_target -> RemoveAurasDueToSpell ( spellId );
m_target -> RemoveAurasDueToSpell ( spellId2 );
Unit :: AuraMap & tAuras = m_target -> GetAuras ();
for ( Unit :: AuraMap :: iterator itr = tAuras . begin (); itr != tAuras . end ();)
2009-01-09 16:06:17 -06:00
{
2009-04-06 13:31:14 +02:00
if ( itr -> second -> IsRemovedOnShapeLost ())
{
2009-04-07 18:05:56 +02:00
m_target -> RemoveAura ( itr );
2009-04-06 13:31:14 +02:00
}
else
{
++ itr ;
}
2009-01-09 16:06:17 -06:00
}
}
2008-12-24 09:58:26 -06:00
}
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
bool AuraEffect :: isAffectedOnSpell ( SpellEntry const * spell ) const
2008-12-24 09:58:26 -06:00
{
2009-02-05 20:28:35 +01:00
if ( ! spell )
return false ;
2008-12-24 09:58:26 -06:00
// Check family name
if ( spell -> SpellFamilyName != m_spellProto -> SpellFamilyName )
return false ;
2009-06-06 12:53:38 +02:00
// Check EffectClassMask and Spell_Affect table
flag96 const * spellAffect = spellmgr . GetSpellAffect ( GetId (), m_effIndex );
if ( ! spellAffect )
spellAffect = & m_spellProto -> EffectSpellClassMask [ m_effIndex ];
if ( * spellAffect & spell -> SpellFamilyFlags )
2008-12-24 09:58:26 -06:00
return true ;
return false ;
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void Aura :: UnregisterSingleCastAura ()
{
if ( IsSingleTarget ())
{
Unit * caster = NULL ;
caster = GetCaster ();
if ( caster )
{
caster -> GetSingleCastAuras (). remove ( this );
}
else
{
sLog . outError ( "Couldn't find the caster of the single target aura, may crash later!" );
assert ( false );
}
m_isSingleTargetAura = false ;
}
}
2008-10-11 14:16:25 -05:00
/*********************************************************/
/*** BASIC AURA FUNCTION ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAddModifier ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( m_target -> GetTypeId () != TYPEID_PLAYER || ( ! Real && ! changeAmount ))
2008-10-11 14:16:25 -05:00
return ;
2009-05-16 17:59:36 +02:00
uint32 modOp = GetMiscValue ();
if ( modOp >= MAX_SPELLMOD )
2008-10-11 14:16:25 -05:00
return ;
if ( apply )
{
2009-06-06 08:27:36 +02:00
SpellModifier * mod = new SpellModifier ( GetParentAura ());
2009-05-16 17:59:36 +02:00
mod -> op = SpellModOp ( modOp );
2009-04-06 13:31:14 +02:00
mod -> value = m_amount ;
mod -> type = SpellModType ( m_auraName ); // SpellModType value == spell aura types
2008-10-11 14:16:25 -05:00
mod -> spellId = GetId ();
2009-02-02 17:01:56 +01:00
flag96 const * spellAffect = spellmgr . GetSpellAffect ( GetId (), m_effIndex );
if ( ! spellAffect )
spellAffect = & m_spellProto -> EffectSpellClassMask [ m_effIndex ];
mod -> mask = * spellAffect ;
2009-04-06 13:31:14 +02:00
mod -> charges = GetParentAura () -> GetAuraCharges ();
2008-10-11 14:16:25 -05:00
m_spellmod = mod ;
}
(( Player * ) m_target ) -> AddSpellMod ( m_spellmod , apply );
2009-05-19 18:33:49 +02:00
// Auras with charges do not mod amount of passive auras
if ( GetParentAura () -> GetAuraCharges ())
return ;
2008-10-11 14:16:25 -05:00
// reapply some passive spells after add/remove related spellmods
2009-05-16 17:59:36 +02:00
// Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
switch ( modOp )
{
case SPELLMOD_ALL_EFFECTS :
case SPELLMOD_EFFECT1 :
case SPELLMOD_EFFECT2 :
case SPELLMOD_EFFECT3 :
{
2009-05-23 11:17:15 -05:00
uint64 guid = m_target -> GetGUID ();
2009-05-16 17:59:36 +02:00
Unit :: AuraMap & auras = m_target -> GetAuras ();
for ( Unit :: AuraMap :: iterator iter = auras . begin (); iter != auras . end (); ++ iter )
{
Aura * aur = iter -> second ;
// only passive auras-active auras should have amount set on spellcast and not be affected
2009-05-23 11:17:15 -05:00
// if aura is casted by others, it will not be affected
2009-06-06 12:53:38 +02:00
if ( aur -> IsPassive () && aur -> GetCasterGUID () == guid && spellmgr . IsAffectedByMod ( aur -> GetSpellProto (), m_spellmod ))
2009-05-16 17:59:36 +02:00
{
if ( modOp == SPELLMOD_ALL_EFFECTS )
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( AuraEffect * aurEff = aur -> GetPartAura ( i ))
aurEff -> RecalculateAmount ();
}
}
else if ( modOp == SPELLMOD_EFFECT1 )
{
if ( AuraEffect * aurEff = aur -> GetPartAura ( 0 ))
aurEff -> RecalculateAmount ();
}
else if ( modOp == SPELLMOD_EFFECT2 )
{
if ( AuraEffect * aurEff = aur -> GetPartAura ( 1 ))
aurEff -> RecalculateAmount ();
}
else //if (modOp ==SPELLMOD_EFFECT3)
{
if ( AuraEffect * aurEff = aur -> GetPartAura ( 2 ))
aurEff -> RecalculateAmount ();
}
}
}
}
default :
break ;
2008-10-11 14:16:25 -05:00
}
}
2009-01-22 22:44:27 -06:00
2009-04-06 13:31:14 +02:00
void AuraEffect :: TriggerSpell ()
2008-10-11 14:16:25 -05:00
{
Unit * caster = GetCaster ();
Unit * target = GetTriggerTarget ();
if ( ! caster || ! target )
return ;
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto () -> EffectTriggerSpell [ m_effIndex ];
2008-11-14 16:28:45 -06:00
SpellEntry const * triggeredSpellInfo = sSpellStore . LookupEntry ( trigger_spell_id );
2008-10-11 14:16:25 -05:00
SpellEntry const * auraSpellInfo = GetSpellProto ();
uint32 auraId = auraSpellInfo -> Id ;
// specific code for cases with no trigger spell provided in field
2008-11-14 16:28:45 -06:00
if ( triggeredSpellInfo == NULL )
2008-10-11 14:16:25 -05:00
{
switch ( auraSpellInfo -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
{
switch ( auraId )
{
2008-11-14 16:28:45 -06:00
// Firestone Passive (1-5 ranks)
2008-10-11 14:16:25 -05:00
case 758 :
case 17945 :
case 17947 :
case 17949 :
case 27252 :
{
if ( caster -> GetTypeId () != TYPEID_PLAYER )
return ;
Item * item = (( Player * ) caster ) -> GetWeaponForAttack ( BASE_ATTACK );
if ( ! item )
return ;
uint32 enchant_id = 0 ;
switch ( GetId ())
{
case 758 : enchant_id = 1803 ; break ; // Rank 1
case 17945 : enchant_id = 1823 ; break ; // Rank 2
case 17947 : enchant_id = 1824 ; break ; // Rank 3
case 17949 : enchant_id = 1825 ; break ; // Rank 4
case 27252 : enchant_id = 2645 ; break ; // Rank 5
default :
return ;
}
// remove old enchanting before applying new
(( Player * ) caster ) -> ApplyEnchantment ( item , TEMP_ENCHANTMENT_SLOT , false );
2009-04-06 13:31:14 +02:00
item -> SetEnchantment ( TEMP_ENCHANTMENT_SLOT , enchant_id , m_amplitude + 1000 , 0 );
2008-10-11 14:16:25 -05:00
// add new enchanting
(( Player * ) caster ) -> ApplyEnchantment ( item , TEMP_ENCHANTMENT_SLOT , true );
return ;
}
// // Periodic Mana Burn
// case 812: break;
// // Polymorphic Ray
// case 6965: break;
2008-11-14 16:28:45 -06:00
// // Fire Nova (1-7 ranks)
2008-10-11 14:16:25 -05:00
// case 8350:
// case 8508:
// case 8509:
// case 11312:
// case 11313:
// case 25540:
// case 25544:
// break;
// Thaumaturgy Channel
case 9712 : trigger_spell_id = 21029 ; break ;
// // Egan's Blaster
// case 17368: break;
// // Haunted
// case 18347: break;
// // Ranshalla Waiting
// case 18953: break;
// // Inferno
// case 19695: break;
// // Frostwolf Muzzle DND
// case 21794: break;
// // Alterac Ram Collar DND
// case 21866: break;
// // Celebras Waiting
// case 21916: break;
// Brood Affliction: Bronze
case 23170 :
{
m_target -> CastSpell ( m_target , 23171 , true , 0 , this );
return ;
}
// // Mark of Frost
// case 23184: break;
// Restoration
case 23493 :
{
int32 heal = caster -> GetMaxHealth () / 10 ;
2009-04-23 22:02:41 -05:00
caster -> DealHeal ( caster , heal , auraSpellInfo );
2008-10-11 14:16:25 -05:00
int32 mana = caster -> GetMaxPower ( POWER_MANA );
if ( mana )
{
mana /= 10 ;
caster -> ModifyPower ( POWER_MANA , mana );
caster -> SendEnergizeSpellLog ( caster , 23493 , mana , POWER_MANA );
}
2009-03-16 15:46:27 -06:00
return ;
2008-10-11 14:16:25 -05:00
}
// // Stoneclaw Totem Passive TEST
// case 23792: break;
// // Axe Flurry
// case 24018: break;
// // Mark of Arlokk
// case 24210: break;
// // Restoration
// case 24379: break;
// // Happy Pet
// case 24716: break;
// // Dream Fog
// case 24780: break;
// // Cannon Prep
// case 24832: break;
// // Shadow Bolt Whirl
// case 24834: break;
// // Stink Trap
// case 24918: break;
// // Mark of Nature
// case 25041: break;
// // Agro Drones
// case 25152: break;
// // Consume
// case 25371: break;
// // Pain Spike
// case 25572: break;
// // Rotate 360
// case 26009: break;
// // Rotate -360
// case 26136: break;
// // Consume
// case 26196: break;
// // Berserk
// case 26615: break;
// // Defile
// case 27177: break;
// // Teleport: IF/UC
// case 27601: break;
// // Five Fat Finger Exploding Heart Technique
// case 27673: break;
2008-11-22 02:10:13 -05:00
// Nitrous Boost
2009-02-04 10:33:18 -06:00
case 27746 :
2008-11-22 02:10:13 -05:00
{
if ( caster -> GetPower ( POWER_MANA ) >= 10 )
{
caster -> ModifyPower ( POWER_MANA , - 10 );
caster -> SendEnergizeSpellLog ( caster , 27746 , - 10 , POWER_MANA );
} else
{
caster -> RemoveAurasDueToSpell ( 27746 );
return ;
}
} break ;
2008-10-11 14:16:25 -05:00
// // Steam Tank Passive
// case 27747: break;
2009-03-18 20:38:42 -06:00
// Frost Blast
case 27808 :
2009-05-06 00:08:19 -05:00
caster -> CastCustomSpell ( 29879 , SPELLVALUE_BASE_POINT0 , target -> GetMaxHealth () * 0.26f , m_target , true , NULL , this );
return ;
// Detonate Mana
case 27819 :
2009-03-18 20:38:42 -06:00
{
2009-05-06 00:08:19 -05:00
int32 mana = ( uint32 ) m_target -> GetMaxPower ( POWER_MANA ) * 0.25f ;
if ( mana )
{
mana = m_target -> ModifyPower ( POWER_MANA , - mana );
m_target -> CastCustomSpell ( 27820 , SPELLVALUE_BASE_POINT0 , - mana * 4 , NULL , true , NULL , this , caster -> GetGUID ());
}
2009-03-18 20:38:42 -06:00
return ;
2009-05-06 00:08:19 -05:00
}
2008-10-11 14:16:25 -05:00
// // Controller Timer
// case 28095: break;
// // Stalagg Chain
// case 28096: break;
// // Stalagg Tesla Passive
// case 28097: break;
// // Feugen Tesla Passive
// case 28109: break;
// // Feugen Chain
// case 28111: break;
// // Mark of Didier
// case 28114: break;
// // Communique Timer, camp
// case 28346: break;
// // Icebolt
// case 28522: break;
// // Silithyst
// case 29519: break;
2009-03-16 15:50:10 -06:00
// Inoculate Nestlewood Owlkin
case 29528 :
if ( target -> GetTypeId () != TYPEID_UNIT ) // prevent error reports in case ignored player target
return ;
break ;
2008-10-11 14:16:25 -05:00
// // Overload
// case 29768: break;
// // Return Fire
// case 29788: break;
// // Return Fire
// case 29793: break;
// // Return Fire
// case 29794: break;
// // Guardian of Icecrown Passive
// case 29897: break;
// Feed Captured Animal
case 29917 : trigger_spell_id = 29916 ; break ;
// // Flame Wreath
// case 29946: break;
// // Flame Wreath
// case 29947: break;
// // Mind Exhaustion Passive
// case 30025: break;
// // Nether Beam - Serenity
// case 30401: break;
// Extract Gas
case 30427 :
{
// move loot to player inventory and despawn target
if ( caster -> GetTypeId () == TYPEID_PLAYER &&
target -> GetTypeId () == TYPEID_UNIT &&
(( Creature * ) target ) -> GetCreatureInfo () -> type == CREATURE_TYPE_GAS_CLOUD )
{
Player * player = ( Player * ) caster ;
Creature * creature = ( Creature * ) target ;
// missing lootid has been reported on startup - just return
if ( ! creature -> GetCreatureInfo () -> SkinLootId )
return ;
2009-02-08 21:54:13 -06:00
player -> AutoStoreLoot ( creature -> GetCreatureInfo () -> SkinLootId , LootTemplates_Skinning , true );
2008-10-11 14:16:25 -05:00
creature -> setDeathState ( JUST_DIED );
creature -> RemoveCorpse ();
creature -> SetHealth ( 0 ); // just for nice GM-mode view
}
return ;
}
// Quake
case 30576 : trigger_spell_id = 30571 ; break ;
// // Burning Maul
// case 30598: break;
// // Regeneration
// case 30799:
// case 30800:
// case 30801:
// break;
// // Despawn Self - Smoke cloud
// case 31269: break;
// // Time Rift Periodic
// case 31320: break;
// // Corrupt Medivh
// case 31326: break;
// Doom
case 31347 :
{
2009-05-17 18:00:33 +02:00
m_target -> CastSpell ( m_target , 31350 , true , NULL , this );
2008-10-11 14:16:25 -05:00
m_target -> DealDamage ( m_target , m_target -> GetHealth (), NULL , DIRECT_DAMAGE , SPELL_SCHOOL_MASK_NORMAL , NULL , false );
return ;
}
// Spellcloth
case 31373 :
{
// Summon Elemental after create item
caster -> SummonCreature ( 17870 , 0 , 0 , 0 , caster -> GetOrientation (), TEMPSUMMON_DEAD_DESPAWN , 0 );
return ;
}
// // Bloodmyst Tesla
// case 31611: break;
// // Doomfire
// case 31944: break;
// // Teleport Test
// case 32236: break;
// // Earthquake
// case 32686: break;
// // Possess
// case 33401: break;
// // Draw Shadows
// case 33563: break;
// // Murmur's Touch
// case 33711: break;
// Flame Quills
case 34229 :
{
// cast 24 spells 34269-34289, 34314-34316
for ( uint32 spell_id = 34269 ; spell_id != 34290 ; ++ spell_id )
2009-05-17 18:00:33 +02:00
caster -> CastSpell ( m_target , spell_id , true , NULL , this );
2008-10-11 14:16:25 -05:00
for ( uint32 spell_id = 34314 ; spell_id != 34317 ; ++ spell_id )
2009-05-17 18:00:33 +02:00
caster -> CastSpell ( m_target , spell_id , true , NULL , this );
2008-10-11 14:16:25 -05:00
return ;
}
// // Gravity Lapse
// case 34480: break;
// // Tornado
// case 34683: break;
// // Frostbite Rotate
// case 34748: break;
// // Arcane Flurry
// case 34821: break;
// // Interrupt Shutdown
// case 35016: break;
// // Interrupt Shutdown
// case 35176: break;
// // Inferno
// case 35268: break;
// // Salaadin's Tesla
// case 35515: break;
// // Ethereal Channel (Red)
// case 35518: break;
// // Nether Vapor
// case 35879: break;
// // Dark Portal Storm
// case 36018: break;
// // Burning Maul
// case 36056: break;
// // Living Grove Defender Lifespan
// case 36061: break;
// // Professor Dabiri Talks
// case 36064: break;
// // Kael Gaining Power
// case 36091: break;
// // They Must Burn Bomb Aura
// case 36344: break;
// // They Must Burn Bomb Aura (self)
// case 36350: break;
// // Stolen Ravenous Ravager Egg
// case 36401: break;
// // Activated Cannon
// case 36410: break;
// // Stolen Ravenous Ravager Egg
// case 36418: break;
// // Enchanted Weapons
// case 36510: break;
// // Cursed Scarab Periodic
// case 36556: break;
// // Cursed Scarab Despawn Periodic
// case 36561: break;
// // Vision Guide
// case 36573: break;
// // Cannon Charging (platform)
// case 36785: break;
// // Cannon Charging (self)
// case 36860: break;
// Remote Toy
case 37027 : trigger_spell_id = 37029 ; break ;
// // Mark of Death
// case 37125: break;
// // Arcane Flurry
// case 37268: break;
// // Spout
// case 37429: break;
// // Spout
// case 37430: break;
// // Karazhan - Chess NPC AI, Snapshot timer
// case 37440: break;
// // Karazhan - Chess NPC AI, action timer
// case 37504: break;
// // Karazhan - Chess: Is Square OCCUPIED aura (DND)
// case 39400: break;
// // Banish
// case 37546: break;
// // Shriveling Gaze
// case 37589: break;
// // Fake Aggro Radius (2 yd)
// case 37815: break;
// // Corrupt Medivh
// case 37853: break;
// Eye of Grillok
case 38495 :
{
2009-05-17 18:00:33 +02:00
m_target -> CastSpell ( m_target , 38530 , true , NULL , this );
2008-10-11 14:16:25 -05:00
return ;
}
// Absorb Eye of Grillok (Zezzak's Shard)
case 38554 :
{
if ( m_target -> GetTypeId () != TYPEID_UNIT )
return ;
2009-05-17 18:00:33 +02:00
caster -> CastSpell ( caster , 38495 , true , NULL , this );
2008-10-11 14:16:25 -05:00
Creature * creatureTarget = ( Creature * ) m_target ;
creatureTarget -> setDeathState ( JUST_DIED );
creatureTarget -> RemoveCorpse ();
creatureTarget -> SetHealth ( 0 ); // just for nice GM-mode view
return ;
}
// // Magic Sucker Device timer
// case 38672: break;
// // Tomb Guarding Charging
// case 38751: break;
// // Murmur's Touch
// case 38794: break;
// // Activate Nether-wraith Beacon (31742 Nether-wraith Beacon item)
// case 39105: break;
// // Drain World Tree Visual
// case 39140: break;
// // Quest - Dustin's Undead Dragon Visual aura
// case 39259: break;
// // Hellfire - The Exorcism, Jules releases darkness, aura
// case 39306: break;
// // Inferno
// case 39346: break;
// // Enchanted Weapons
// case 39489: break;
// // Shadow Bolt Whirl
// case 39630: break;
// // Shadow Bolt Whirl
// case 39634: break;
// // Shadow Inferno
// case 39645: break;
// Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
case 39857 : trigger_spell_id = 39856 ; break ;
// // Soulgrinder Ritual Visual (Smashed)
// case 39974: break;
// // Simon Game Pre-game timer
// case 40041: break;
// // Knockdown Fel Cannon: The Aggro Check Aura
// case 40113: break;
// // Spirit Lance
// case 40157: break;
// // Demon Transform 2
// case 40398: break;
// // Demon Transform 1
// case 40511: break;
// // Ancient Flames
// case 40657: break;
// // Ethereal Ring Cannon: Cannon Aura
// case 40734: break;
// // Cage Trap
// case 40760: break;
// // Random Periodic
// case 40867: break;
// // Prismatic Shield
// case 40879: break;
2008-10-18 16:25:58 -05:00
// Aura of Desire
case 41350 :
{
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & mMod = m_target -> GetAurasByType ( SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT );
for ( Unit :: AuraEffectList :: const_iterator i = mMod . begin (); i != mMod . end (); ++ i )
2008-10-18 16:25:58 -05:00
{
if (( * i ) -> GetId () == 41350 )
{
( * i ) -> ApplyModifier ( false );
2009-04-06 13:31:14 +02:00
( * i ) -> SetAmount (( * i ) -> GetAmount () - 5 );
2008-10-18 16:25:58 -05:00
( * i ) -> ApplyModifier ( true );
break ;
}
2009-02-04 10:33:18 -06:00
}
2008-10-18 16:25:58 -05:00
} break ;
2008-10-11 14:16:25 -05:00
// // Dementia
// case 41404: break;
// // Chaos Form
// case 41629: break;
// // Alert Drums
// case 42177: break;
// // Spout
// case 42581: break;
// // Spout
// case 42582: break;
// // Return to the Spirit Realm
// case 44035: break;
// // Curse of Boundless Agony
// case 45050: break;
// // Earthquake
// case 46240: break;
// Personalized Weather
case 46736 : trigger_spell_id = 46737 ; break ;
// // Stay Submerged
// case 46981: break;
// // Dragonblight Ram
// case 47015: break;
// // Party G.R.E.N.A.D.E.
// case 51510: break;
default :
break ;
}
break ;
}
case SPELLFAMILY_MAGE :
{
switch ( auraId )
{
// Invisibility
case 66 :
2009-02-17 14:52:46 -06:00
// Here need periodic triger reducing threat spell (or do it manually)
2008-10-11 14:16:25 -05:00
return ;
default :
break ;
}
break ;
}
// case SPELLFAMILY_WARRIOR:
// {
// switch(auraId)
// {
// // Wild Magic
// case 23410: break;
// // Corrupted Totems
// case 23425: break;
// default:
// break;
// }
// break;
// }
// case SPELLFAMILY_PRIEST:
// {
// switch(auraId)
// {
// // Blue Beam
// case 32930: break;
// // Fury of the Dreghood Elders
// case 35460: break;
// default:
// break;
// }
// break;
// }
case SPELLFAMILY_DRUID :
{
switch ( auraId )
{
// Cat Form
// trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
case 768 :
return ;
// Frenzied Regeneration
case 22842 :
case 22895 :
case 22896 :
case 26999 :
{
2009-04-06 13:31:14 +02:00
int32 LifePerRage = GetAmount ();
2008-10-11 14:16:25 -05:00
int32 lRage = m_target -> GetPower ( POWER_RAGE );
if ( lRage > 100 ) // rage stored as rage*10
lRage = 100 ;
m_target -> ModifyPower ( POWER_RAGE , - lRage );
int32 FRTriggerBasePoints = int32 ( lRage * LifePerRage / 10 );
m_target -> CastCustomSpell ( m_target , 22845 , & FRTriggerBasePoints , NULL , NULL , true , NULL , this );
return ;
}
default :
break ;
}
break ;
}
// case SPELLFAMILY_HUNTER:
// {
// switch(auraId)
// {
// //Frost Trap Aura
// case 13810:
// return;
// //Rizzle's Frost Trap
// case 39900:
// return;
// // Tame spells
// case 19597: // Tame Ice Claw Bear
// case 19676: // Tame Snow Leopard
// case 19677: // Tame Large Crag Boar
// case 19678: // Tame Adult Plainstrider
// case 19679: // Tame Prairie Stalker
// case 19680: // Tame Swoop
// case 19681: // Tame Dire Mottled Boar
// case 19682: // Tame Surf Crawler
// case 19683: // Tame Armored Scorpid
// case 19684: // Tame Webwood Lurker
// case 19685: // Tame Nightsaber Stalker
// case 19686: // Tame Strigid Screecher
// case 30100: // Tame Crazed Dragonhawk
// case 30103: // Tame Elder Springpaw
// case 30104: // Tame Mistbat
// case 30647: // Tame Barbed Crawler
// case 30648: // Tame Greater Timberstrider
// case 30652: // Tame Nightstalker
// return;
// default:
// 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
Unit :: AuraMap const & auras = target -> GetAuras ();
for ( Unit :: AuraMap :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
{
SpellEntry const * spell = itr -> second -> GetSpellProto ();
if ( spell -> SpellFamilyName == SPELLFAMILY_SHAMAN &&
2009-02-02 17:01:56 +01:00
spell -> SpellFamilyFlags [ 0 ] & 0x400 )
2008-10-11 14:16:25 -05:00
return ;
}
target -> RemoveAurasDueToSpell ( 28820 );
return ;
}
// Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
case 38443 :
{
bool all = true ;
2009-03-27 22:47:28 -06:00
for ( int i = SUMMON_SLOT_TOTEM ; i < MAX_TOTEM_SLOT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2009-03-27 22:47:28 -06:00
if ( ! caster -> m_SummonSlot [ i ])
2008-10-11 14:16:25 -05:00
{
all = false ;
break ;
}
}
if ( all )
2009-05-17 18:00:33 +02:00
caster -> CastSpell ( caster , 38437 , true , NULL , this );
2008-10-11 14:16:25 -05:00
else
caster -> RemoveAurasDueToSpell ( 38437 );
return ;
}
default :
break ;
}
break ;
}
default :
break ;
}
2009-03-16 15:46:27 -06:00
2008-10-11 14:16:25 -05:00
// Reget trigger spell proto
2008-11-14 16:28:45 -06:00
triggeredSpellInfo = sSpellStore . LookupEntry ( trigger_spell_id );
2008-10-11 14:16:25 -05:00
}
else
{
2008-11-14 16:28:45 -06:00
// Spell exist but require custom code
2008-10-11 14:16:25 -05:00
switch ( auraId )
{
// Curse of Idiocy
case 1010 :
{
// TODO: spell casted by result in correct way mostly
// BUT:
// 1) target show casting at each triggered cast: target don't must show casting animation for any triggered spell
// but must show affect apply like item casting
2008-11-14 16:28:45 -06:00
// 2) maybe aura must be replace by new with accumulative stat mods instead stacking
2008-10-11 14:16:25 -05:00
// prevent cast by triggered auras
2009-04-06 13:31:14 +02:00
if ( GetCasterGUID () == m_target -> GetGUID ())
2008-10-11 14:16:25 -05:00
return ;
// stop triggering after each affected stats lost > 90
2008-11-14 16:28:45 -06:00
int32 intellectLoss = 0 ;
2008-10-11 14:16:25 -05:00
int32 spiritLoss = 0 ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & mModStat = m_target -> GetAurasByType ( SPELL_AURA_MOD_STAT );
for ( Unit :: AuraEffectList :: const_iterator i = mModStat . begin (); i != mModStat . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
if (( * i ) -> GetId () == 1010 )
{
2009-04-06 13:31:14 +02:00
switch (( * i ) -> GetMiscValue ())
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
case STAT_INTELLECT : intellectLoss += ( * i ) -> GetAmount (); break ;
case STAT_SPIRIT : spiritLoss += ( * i ) -> GetAmount (); break ;
2008-10-11 14:16:25 -05:00
default : break ;
}
}
}
2008-11-14 16:28:45 -06:00
if ( intellectLoss <= - 90 && spiritLoss <= - 90 )
2008-10-11 14:16:25 -05:00
return ;
caster = target ;
break ;
}
// Mana Tide
case 16191 :
{
2009-04-06 13:31:14 +02:00
caster -> CastCustomSpell ( target , trigger_spell_id , & m_amount , NULL , NULL , true , NULL , this );
2008-10-11 14:16:25 -05:00
return ;
}
2009-04-19 01:06:06 -05:00
// Negative Energy Periodic
case 46284 :
2009-04-19 12:22:40 -05:00
caster -> CastCustomSpell ( trigger_spell_id , SPELLVALUE_MAX_TARGETS , m_tickNumber / 10 + 1 , NULL , true , NULL , this );
2009-04-19 01:06:06 -05:00
return ;
2009-04-29 00:11:15 -05:00
// Poison (Grobbulus)
case 28158 :
case 54362 :
m_target -> CastCustomSpell ( trigger_spell_id , SPELLVALUE_RADIUS_MOD , ( int32 )(((( float ) m_tickNumber / 60 ) * 0.9f + 0.1f ) * 10000 ), NULL , true , NULL , this );
2009-05-02 19:38:13 -05:00
return ;
// Mind Sear (target 76/16) if let m_target cast, will damage caster
case 48045 :
case 53023 :
2009-05-06 00:08:19 -05:00
// Curse of the Plaguebringer (22/15)
case 29213 :
case 54835 :
2009-05-17 18:00:33 +02:00
caster -> CastSpell ( m_target , trigger_spell_id , true , NULL , this );
2009-05-02 19:38:13 -05:00
return ;
2008-10-11 14:16:25 -05:00
}
}
2009-03-16 15:46:27 -06:00
if ( triggeredSpellInfo )
2009-03-16 17:21:56 -06:00
{
if ( ! caster -> GetSpellMaxRangeForTarget ( m_target , sSpellRangeStore . LookupEntry ( triggeredSpellInfo -> rangeIndex )))
target = m_target ; //for druid dispel poison
2009-03-16 15:46:27 -06:00
m_target -> CastSpell ( target , triggeredSpellInfo , true , 0 , this , GetCasterGUID ());
2009-03-16 17:21:56 -06:00
}
2009-03-16 15:46:27 -06:00
else if ( target -> GetTypeId () != TYPEID_UNIT || ! Script -> EffectDummyCreature ( caster , GetId (), GetEffIndex (), ( Creature * ) target ))
2009-04-06 13:31:14 +02:00
sLog . outError ( "AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?" , GetId (), GetEffIndex ());
2008-11-15 10:21:37 -06:00
}
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
Unit * AuraEffect :: GetTriggerTarget () const
2008-11-15 10:21:37 -06:00
{
2009-03-16 15:46:27 -06:00
Unit * target = ObjectAccessor :: GetUnit ( * m_target , m_target -> GetUInt64Value ( UNIT_FIELD_TARGET ));
2008-11-15 10:21:37 -06:00
return target ? target : m_target ;
2009-01-22 22:44:27 -06:00
}
2009-04-06 13:31:14 +02:00
void AuraEffect :: TriggerSpellWithValue ()
2009-01-22 22:44:27 -06:00
{
Unit * caster = GetCaster ();
Unit * target = GetTriggerTarget ();
if ( ! caster || ! target )
return ;
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto () -> EffectTriggerSpell [ m_effIndex ];
2009-04-06 13:31:14 +02:00
int32 basepoints0 = this -> GetAmount ();
2009-01-22 22:44:27 -06:00
caster -> CastCustomSpell ( target , trigger_spell_id , & basepoints0 , 0 , 0 , true , 0 , this );
2008-10-11 14:16:25 -05:00
}
/*********************************************************/
/*** AURA EFFECTS ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraDummy ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
Unit * caster = GetCaster ();
2009-05-16 17:59:36 +02:00
// spells required only Real aura add/remove
if ( Real )
{
2008-10-11 14:16:25 -05:00
// AT APPLY
if ( apply )
{
switch ( GetId ())
{
2009-04-14 20:04:01 +02:00
// Haunting Spirits - perdiodic trigger demon
case 7057 :
m_isPeriodic = true ;
m_amplitude = irand ( 0 , 60 ) + 30 ;
m_amplitude *= IN_MILISECONDS ;
return ;
2008-10-11 14:16:25 -05:00
case 1515 : // Tame beast
// FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
if ( caster && m_target -> CanHaveThreatList ())
m_target -> AddThreat ( caster , 10.0f );
return ;
case 13139 : // net-o-matic
// root to self part of (root_target->charge->root_self sequence
if ( caster )
caster -> CastSpell ( caster , 13138 , true , NULL , this );
return ;
2009-03-22 22:21:25 +01:00
case 34026 : // kill command
{
2009-03-27 22:47:28 -06:00
Unit * pet = m_target -> GetGuardianPet ();
2009-03-22 22:21:25 +01:00
if ( ! pet )
return ;
m_target -> CastSpell ( m_target , 34027 , true , NULL , this );
// set 3 stacks and 3 charges (to make all auras not disappear at once)
2009-04-06 13:31:14 +02:00
Aura * owner_aura = m_target -> GetAura ( 34027 , GetCasterGUID ());
Aura * pet_aura = pet -> GetAura ( 58914 , GetCasterGUID ());
2009-03-22 22:21:25 +01:00
if ( owner_aura )
{
owner_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
if ( pet_aura )
{
pet_aura -> SetAuraCharges ( 0 );
pet_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
return ;
}
case 55198 : // Tidal Force
{
m_target -> CastSpell ( m_target , 55166 , true , NULL , this );
// set 3 stacks and 3 charges (to make all auras not disappear at once)
2009-04-06 13:31:14 +02:00
Aura * owner_aura = m_target -> GetAura ( 55166 , GetCasterGUID ());
2009-03-22 22:21:25 +01:00
if ( owner_aura )
{
// This aura lasts 2 sec, need this hack to properly proc spells
// TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
2009-04-06 13:31:14 +02:00
GetParentAura () -> SetAuraDuration ( owner_aura -> GetAuraDuration ());
2009-03-22 22:21:25 +01:00
// Make aura be not charged-this prevents removing charge on not crit spells
owner_aura -> SetAuraCharges ( 0 );
owner_aura -> SetStackAmount ( owner_aura -> GetSpellProto () -> StackAmount );
}
return ;
}
2008-10-11 14:16:25 -05:00
case 39850 : // Rocket Blast
if ( roll_chance_i ( 20 )) // backfire stun
m_target -> CastSpell ( m_target , 51581 , true , NULL , this );
return ;
2008-10-19 17:27:18 -05:00
case 43873 : // Headless Horseman Laugh
2009-03-22 19:20:03 -06:00
m_target -> PlayDistanceSound ( 11965 );
2008-10-19 17:27:18 -05:00
return ;
2008-10-11 14:16:25 -05:00
case 46354 : // Blood Elf Illusion
if ( caster )
{
switch ( caster -> getGender ())
{
case GENDER_FEMALE :
caster -> CastSpell ( m_target , 46356 , true , NULL , this );
break ;
case GENDER_MALE :
caster -> CastSpell ( m_target , 46355 , true , NULL , this );
break ;
default :
break ;
}
}
return ;
case 46699 : // Requires No Ammo
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
(( Player * ) m_target ) -> RemoveAmmo (); // not use ammo and not allow use
return ;
}
// Earth Shield
2009-02-02 17:01:56 +01:00
if ( caster && GetSpellProto () -> SpellFamilyName == SPELLFAMILY_SHAMAN && ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x400 ))
2008-10-11 14:16:25 -05:00
{
// prevent double apply bonuses
if ( m_target -> GetTypeId () != TYPEID_PLAYER || ! (( Player * ) m_target ) -> GetSession () -> PlayerLoading ())
2009-04-06 13:31:14 +02:00
m_amount = caster -> SpellHealingBonus ( m_target , GetSpellProto (), m_amount , SPELL_DIRECT_DAMAGE );
2008-10-11 14:16:25 -05:00
return ;
}
2009-03-08 03:10:03 +01:00
//Druid, Survival Instincts
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x40 )
{
if ( ! m_target )
return ;
2009-04-06 13:31:14 +02:00
int32 bp0 = int32 ( m_target -> GetMaxHealth () * m_amount / 100 );
2009-03-08 03:10:03 +01:00
m_target -> CastCustomSpell ( m_target , 50322 , & bp0 , NULL , NULL , true );
}
2008-10-11 14:16:25 -05:00
}
// AT REMOVE
else
{
if ( ( IsQuestTameSpell ( GetId ())) && caster && caster -> isAlive () && m_target -> isAlive ())
{
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 ;
}
if ( finalSpelId )
caster -> CastSpell ( m_target , finalSpelId , true , NULL , this );
return ;
}
2008-11-05 20:51:05 -06:00
2008-11-18 19:40:06 -06:00
// Waiting to Resurrect
if ( GetId () == 2584 )
{
// Waiting to resurrect spell cancel, we must remove player from resurrect queue
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
if ( BattleGround * bg = (( Player * ) m_target ) -> GetBattleGround ())
bg -> RemovePlayerFromResurrectQueue ( m_target -> GetGUID ());
return ;
}
2008-12-17 20:07:25 -06:00
// Burning Winds
if ( GetId () == 46308 ) // casted only at creatures at spawn
2008-10-11 14:16:25 -05:00
{
2008-12-17 20:07:25 -06:00
m_target -> CastSpell ( m_target , 47287 , true , NULL , this );
2008-10-11 14:16:25 -05:00
return ;
}
2008-12-17 20:07:25 -06:00
// Misdirection
if ( GetId () == 34477 )
2008-10-11 14:16:25 -05:00
{
2008-12-17 20:07:25 -06:00
m_target -> SetReducedThreatPercent ( 0 , 0 );
2008-10-11 14:16:25 -05:00
return ;
}
2009-03-15 20:35:04 -06:00
2009-05-16 20:23:56 +02:00
// Wrath of the Astromancer
if ( GetId () == 42783 )
{
m_target -> CastSpell ( m_target , m_amount , true , NULL , this );
return ;
}
2009-03-12 23:20:51 +01:00
switch ( m_spellProto -> SpellFamilyName )
{
2009-03-15 20:35:04 -06:00
case SPELLFAMILY_WARLOCK :
// Haunt
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x40000 )
{
2009-04-13 19:51:37 +02:00
int32 bp0 = GetParentAura () -> GetProcDamage () * m_amount / 100 ;
2009-03-15 20:35:04 -06:00
if ( caster )
2009-04-13 19:51:37 +02:00
caster -> CastCustomSpell ( caster , 48210 , & bp0 , 0 , 0 , true , NULL , this );
2009-03-15 20:35:04 -06:00
return ;
}
break ;
2009-03-13 22:48:04 +01:00
case SPELLFAMILY_MAGE :
2009-03-12 23:20:51 +01:00
// Living Bomb
2009-03-15 20:35:04 -06:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x20000 )
2009-03-12 23:20:51 +01:00
{
2009-05-27 16:11:40 -05:00
if ( caster && ( GetParentAura () -> GetRemoveMode () == AURA_REMOVE_BY_ENEMY_SPELL || GetParentAura () -> GetRemoveMode () == AURA_REMOVE_BY_EXPIRE ))
2009-04-06 13:31:14 +02:00
caster -> CastSpell ( m_target , GetAmount (), true );
2009-03-12 23:20:51 +01:00
return ;
}
2009-03-15 20:35:04 -06:00
break ;
2009-03-12 23:20:51 +01:00
}
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
}
2008-10-11 14:16:25 -05:00
// AT APPLY & REMOVE
switch ( m_spellProto -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
{
2009-05-16 17:59:36 +02:00
if ( ! Real )
break ;
2009-04-29 16:18:07 -05:00
switch ( GetId ())
2008-10-11 14:16:25 -05:00
{
2009-04-29 16:18:07 -05:00
// Unstable Power
case 24658 :
2008-10-11 14:16:25 -05:00
{
2009-04-29 16:18:07 -05:00
uint32 spellId = 24659 ;
if ( apply && caster )
{
const SpellEntry * spell = sSpellStore . LookupEntry ( spellId );
if ( ! spell )
return ;
2009-04-27 18:42:35 -05:00
2009-04-29 16:18:07 -05:00
for ( int i = 0 ; i < spell -> StackAmount ; ++ i )
caster -> CastSpell ( m_target , spell -> Id , true , NULL , NULL , GetCasterGUID ());
return ;
}
m_target -> RemoveAurasDueToSpell ( spellId );
2008-10-11 14:16:25 -05:00
return ;
}
2009-04-29 16:18:07 -05:00
// Restless Strength
case 24661 :
2008-10-11 14:16:25 -05:00
{
2009-04-29 16:18:07 -05:00
uint32 spellId = 24662 ;
if ( apply && caster )
{
const SpellEntry * spell = sSpellStore . LookupEntry ( spellId );
if ( ! spell )
return ;
for ( int i = 0 ; i < spell -> StackAmount ; ++ i )
caster -> CastSpell ( m_target , spell -> Id , true , NULL , NULL , GetCasterGUID ());
2008-10-11 14:16:25 -05:00
return ;
2009-04-29 16:18:07 -05:00
}
m_target -> RemoveAurasDueToSpell ( spellId );
2008-10-11 14:16:25 -05:00
return ;
}
2009-04-29 16:18:07 -05:00
//Summon Fire Elemental
case 40133 :
2008-10-11 14:16:25 -05:00
{
2009-04-29 16:18:07 -05:00
if ( ! caster )
return ;
2008-10-11 14:16:25 -05:00
2009-04-29 16:18:07 -05:00
Unit * owner = caster -> GetOwner ();
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
owner -> CastSpell ( owner , 8985 , true );
else
(( Player * ) owner ) -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
}
return ;
}
//Summon Earth Elemental
case 40132 :
2008-10-11 14:16:25 -05:00
{
2009-04-29 16:18:07 -05:00
if ( ! caster )
return ;
Unit * owner = caster -> GetOwner ();
if ( owner && owner -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
owner -> CastSpell ( owner , 19704 , true );
else
(( Player * ) owner ) -> RemovePet ( NULL , PET_SAVE_NOT_IN_SLOT , true );
}
return ;
2008-10-11 14:16:25 -05:00
}
2009-04-29 16:18:07 -05:00
// LK Intro VO (1)
case 58204 :
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
// Play part 1
if ( apply )
m_target -> PlayDirectSound ( 14970 , ( Player * ) m_target );
// continue in 58205
else
m_target -> CastSpell ( m_target , 58205 , true );
}
return ;
// LK Intro VO (2)
case 58205 :
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
// Play part 2
if ( apply )
m_target -> PlayDirectSound ( 14971 , ( Player * ) m_target );
// Play part 3
else
m_target -> PlayDirectSound ( 14972 , ( Player * ) m_target );
}
return ;
2008-10-11 14:16:25 -05:00
}
2008-12-10 20:25:47 -06:00
2008-10-11 14:16:25 -05:00
break ;
}
case SPELLFAMILY_MAGE :
{
2009-05-16 17:59:36 +02:00
//if (!Real)
//break;
2008-10-11 14:16:25 -05:00
break ;
}
2009-01-25 16:35:14 -06:00
case SPELLFAMILY_PRIEST :
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
break ;
2009-01-25 16:35:14 -06:00
// Pain and Suffering
if ( m_spellProto -> SpellIconID == 2874 && m_target -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
{
// Reduce backfire damage (dot damage) from Shadow Word: Death
SpellModifier * mod = new SpellModifier ;
mod -> op = SPELLMOD_DOT ;
2009-04-06 13:31:14 +02:00
mod -> value = m_amount ;
2009-01-25 16:35:14 -06:00
mod -> type = SPELLMOD_PCT ;
mod -> spellId = GetId ();
2009-03-05 20:47:18 +01:00
mod -> mask [ 1 ] = 0x00002000 ;
2009-01-25 16:35:14 -06:00
m_spellmod = mod ;
}
(( Player * ) m_target ) -> AddSpellMod ( m_spellmod , apply );
return ;
}
break ;
}
2008-10-11 14:16:25 -05:00
case SPELLFAMILY_DRUID :
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
break ;
2009-03-17 14:53:30 -06:00
switch ( GetId ())
{
case 34246 : // Idol of the Emerald Queen
2009-05-06 16:54:53 -05:00
case 60779 : // Idol of Lush Moss
2009-03-17 14:53:30 -06:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
{
SpellModifier * mod = new SpellModifier ;
mod -> op = SPELLMOD_DOT ;
2009-04-06 13:31:14 +02:00
mod -> value = m_amount / 7 ;
2009-03-17 14:53:30 -06:00
mod -> type = SPELLMOD_FLAT ;
mod -> spellId = GetId ();
mod -> mask [ 1 ] = 0x0010 ;
m_spellmod = mod ;
}
(( Player * ) m_target ) -> AddSpellMod ( m_spellmod , apply );
return ;
}
case 61336 : // Survival Instincts
{
2009-05-16 17:59:36 +02:00
if ( ! Real )
break ;
2009-03-17 14:53:30 -06:00
if ( apply )
{
if ( ! m_target -> IsInFeralForm ())
return ;
2009-04-06 13:31:14 +02:00
int32 bp0 = int32 ( m_target -> GetMaxHealth () * m_amount / 100 );
2009-03-17 14:53:30 -06:00
m_target -> CastCustomSpell ( m_target , 50322 , & bp0 , NULL , NULL , true );
}
else
m_target -> RemoveAurasDueToSpell ( 50322 );
return ;
}
}
2008-10-11 14:16:25 -05:00
// Lifebloom
2009-02-02 17:01:56 +01:00
if ( GetSpellProto () -> SpellFamilyFlags [ 1 ] & 0x10 )
2008-10-11 14:16:25 -05:00
{
if ( apply )
{
if ( caster )
// prevent double apply bonuses
if ( m_target -> GetTypeId () != TYPEID_PLAYER || ! (( Player * ) m_target ) -> GetSession () -> PlayerLoading ())
2009-04-06 13:31:14 +02:00
m_amount = caster -> SpellHealingBonus ( m_target , GetSpellProto (), m_amount , SPELL_DIRECT_DAMAGE );
2008-10-11 14:16:25 -05:00
}
2009-01-09 16:06:17 -06:00
else
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// Final heal only on dispelled or duration end
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> GetRemoveMode () != AURA_REMOVE_BY_EXPIRE && GetParentAura () -> GetRemoveMode () != AURA_REMOVE_BY_ENEMY_SPELL )
2009-01-09 16:06:17 -06:00
return ;
// final heal
if ( m_target -> IsInWorld ())
2009-04-06 13:31:14 +02:00
m_target -> CastCustomSpell ( m_target , 33778 , & m_amount , NULL , NULL , true , NULL , this , GetCasterGUID ());
2009-01-09 16:06:17 -06:00
/*// have a look if there is still some other Lifebloom dummy aura
Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr)
if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID &&
(*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL)
return;
// final heal
if(m_target->IsInWorld() && m_stackAmount > 0)
2008-12-07 12:01:56 -06:00
{
2009-04-06 13:31:14 +02:00
int32 amount = m_amount / m_stackAmount;
2009-01-09 16:06:17 -06:00
m_target->CastCustomSpell(m_target,33778,&amount,NULL,NULL,true,NULL,this,GetCasterGUID());
}*/
2008-10-11 14:16:25 -05:00
}
return ;
}
// Predatory Strikes
if ( m_target -> GetTypeId () == TYPEID_PLAYER && GetSpellProto () -> SpellIconID == 1563 )
{
(( Player * ) m_target ) -> UpdateAttackPowerAndDamage ();
return ;
}
break ;
}
case SPELLFAMILY_HUNTER :
{
2009-05-16 17:59:36 +02:00
if ( ! Real )
break ;
2009-03-14 16:20:04 +01:00
// Glyph of Aspect of the Monkey
if ( m_spellProto -> Id == 56833 )
{
if ( apply )
{
SpellModifier * mod = new SpellModifier ;
mod -> op = SPELLMOD_CHANCE_OF_SUCCESS ;
mod -> value = 100 ;
mod -> type = SPELLMOD_FLAT ;
mod -> spellId = GetId ();
mod -> mask [ 2 ] = 8192 ;
mod -> mask [ 1 ] = 0x00000000 ;
mod -> mask [ 0 ] = 524288 ;
m_spellmod = mod ;
}
(( Player * ) m_target ) -> AddSpellMod ( m_spellmod , apply );
return ;
}
2008-10-11 14:16:25 -05:00
break ;
}
case SPELLFAMILY_SHAMAN :
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
break ;
2008-10-11 14:16:25 -05:00
// Improved Weapon Totems
if ( GetSpellProto () -> SpellIconID == 57 && m_target -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
{
SpellModifier * mod = new SpellModifier ;
mod -> op = SPELLMOD_EFFECT1 ;
2009-04-06 13:31:14 +02:00
mod -> value = m_amount ;
2008-10-11 14:16:25 -05:00
mod -> type = SPELLMOD_PCT ;
mod -> spellId = GetId ();
switch ( m_effIndex )
{
case 0 :
2009-02-02 17:01:56 +01:00
mod -> mask [ 1 ] = 0x002 ; // Windfury Totem
2008-10-11 14:16:25 -05:00
break ;
case 1 :
2009-02-02 17:01:56 +01:00
mod -> mask [ 1 ] = 0x004 ; // Flametongue Totem
2008-10-11 14:16:25 -05:00
break ;
}
m_spellmod = mod ;
}
(( Player * ) m_target ) -> AddSpellMod ( m_spellmod , apply );
return ;
}
2009-05-16 17:59:36 +02:00
if ( ! Real )
break ;
2008-11-14 20:40:35 -06:00
// Sentry Totem
if ( GetId () == 6495 && caster -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
{
2009-03-27 22:47:28 -06:00
uint64 guid = caster -> m_SummonSlot [ 3 ];
2008-11-14 20:40:35 -06:00
if ( guid )
{
2009-04-20 20:28:19 -05:00
Creature * totem = caster -> GetMap () -> GetCreature ( guid );
2008-11-14 20:40:35 -06:00
if ( totem && totem -> isTotem ())
2009-02-15 17:33:36 -06:00
(( Player * ) caster ) -> CastSpell ( totem , 6277 , true );
2008-11-14 20:40:35 -06:00
}
2009-02-04 10:33:18 -06:00
}
2008-11-14 20:40:35 -06:00
else
2009-02-15 17:33:36 -06:00
(( Player * ) caster ) -> StopCastingBindSight ();
2008-11-14 20:40:35 -06:00
return ;
}
2008-10-11 14:16:25 -05:00
break ;
}
}
2009-05-16 17:59:36 +02:00
if ( Real )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
// pet auras
if ( PetAura const * petSpell = spellmgr . GetPetAura ( GetId ()))
2009-03-03 18:41:11 -06:00
{
2009-05-16 17:59:36 +02:00
if ( apply )
m_target -> AddPetAura ( petSpell );
else
m_target -> RemovePetAura ( petSpell );
return ;
}
2009-03-03 18:41:11 -06:00
2009-05-16 17:59:36 +02:00
if ( GetEffIndex () == 0 && m_target -> GetTypeId () == TYPEID_PLAYER )
{
SpellAreaForAreaMapBounds saBounds = spellmgr . GetSpellAreaForAuraMapBounds ( GetId ());
if ( saBounds . first != saBounds . second )
2009-03-03 18:41:11 -06:00
{
2009-05-16 17:59:36 +02:00
uint32 zone , area ;
m_target -> GetZoneAndAreaId ( zone , area );
for ( SpellAreaForAreaMap :: const_iterator itr = saBounds . first ; itr != saBounds . second ; ++ itr )
2009-03-03 18:41:11 -06:00
{
2009-05-16 17:59:36 +02:00
// some auras remove at aura remove
if ( ! itr -> second -> IsFitToRequirements (( Player * ) m_target , zone , area ))
m_target -> RemoveAurasDueToSpell ( itr -> second -> spellId );
// some auras applied at aura apply
else if ( itr -> second -> autocast )
{
if ( ! m_target -> HasAuraEffect ( itr -> second -> spellId , 0 ) )
m_target -> CastSpell ( m_target , itr -> second -> spellId , true );
}
2009-03-03 18:41:11 -06:00
}
}
}
}
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraMounted ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2008-11-18 19:40:06 -06:00
// only at real add/remove aura
if ( ! Real )
return ;
2008-10-11 14:16:25 -05:00
if ( apply )
{
2009-04-06 13:31:14 +02:00
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( GetMiscValue ());
2008-10-11 14:16:25 -05:00
if ( ! ci )
{
2009-04-06 13:31:14 +02:00
sLog . outErrorDb ( "AuraMounted: `creature_template`='%u' not found in database (only need it modelid)" , GetMiscValue ());
2008-10-11 14:16:25 -05:00
return ;
}
uint32 team = 0 ;
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
team = (( Player * ) m_target ) -> GetTeam ();
uint32 display_id = objmgr . ChooseDisplayId ( team , ci );
CreatureModelInfo const * minfo = objmgr . GetCreatureModelRandomGender ( display_id );
if ( minfo )
display_id = minfo -> modelid ;
2009-04-21 14:20:00 -05:00
//some spell has one aura of mount and one of vehicle
for ( uint32 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( GetSpellProto () -> Effect [ i ] == SPELL_EFFECT_SUMMON
&& GetSpellProto () -> EffectMiscValue [ i ] == GetMiscValue ())
display_id = 0 ;
2008-10-11 14:16:25 -05:00
m_target -> Mount ( display_id );
}
else
{
m_target -> Unmount ();
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraWaterWalk ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
if ( ! Real )
return ;
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_WATER_WALK , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_LAND_WALK , 8 + 4 );
data . append ( m_target -> GetPackGUID ());
data << uint32 ( 0 );
m_target -> SendMessageToSet ( & data , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraFeatherFall ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
if ( ! Real )
return ;
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_FEATHER_FALL , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_NORMAL_FALL , 8 + 4 );
data . append ( m_target -> GetPackGUID ());
data << ( uint32 ) 0 ;
m_target -> SendMessageToSet ( & data , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraHover ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
if ( ! Real )
return ;
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_SET_HOVER , 8 + 4 );
else
data . Initialize ( SMSG_MOVE_UNSET_HOVER , 8 + 4 );
data . append ( m_target -> GetPackGUID ());
data << uint32 ( 0 );
m_target -> SendMessageToSet ( & data , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleWaterBreathing ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-03-09 18:06:19 -06:00
// update timers in client
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
(( Player * ) m_target ) -> UpdateMirrorTimers ();
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModShapeshift ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
uint32 modelid = 0 ;
Powers PowerType = POWER_MANA ;
2009-04-06 13:31:14 +02:00
ShapeshiftForm form = ShapeshiftForm ( GetMiscValue ());
2008-10-11 14:16:25 -05:00
switch ( form )
{
case FORM_CAT :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 892 ;
else
modelid = 8571 ;
PowerType = POWER_ENERGY ;
break ;
case FORM_TRAVEL :
modelid = 632 ;
break ;
case FORM_AQUA :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 2428 ;
else
modelid = 2428 ;
break ;
case FORM_BEAR :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 2281 ;
else
modelid = 2289 ;
PowerType = POWER_RAGE ;
break ;
case FORM_GHOUL :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 10045 ;
break ;
case FORM_DIREBEAR :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 2281 ;
else
modelid = 2289 ;
PowerType = POWER_RAGE ;
break ;
case FORM_CREATUREBEAR :
modelid = 902 ;
break ;
case FORM_GHOSTWOLF :
modelid = 4613 ;
break ;
case FORM_FLIGHT :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 20857 ;
else
modelid = 20872 ;
break ;
case FORM_MOONKIN :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 15374 ;
else
modelid = 15375 ;
break ;
case FORM_FLIGHT_EPIC :
if ( Player :: TeamForRace ( m_target -> getRace ()) == ALLIANCE )
modelid = 21243 ;
else
modelid = 21244 ;
break ;
2008-12-26 17:08:59 -06:00
case FORM_METAMORPHOSIS :
modelid = 25277 ;
break ;
2008-10-11 14:16:25 -05:00
case FORM_AMBIENT :
case FORM_SHADOW :
case FORM_STEALTH :
break ;
case FORM_TREE :
modelid = 864 ;
break ;
case FORM_BATTLESTANCE :
case FORM_BERSERKERSTANCE :
case FORM_DEFENSIVESTANCE :
PowerType = POWER_RAGE ;
break ;
case FORM_SPIRITOFREDEMPTION :
modelid = 16031 ;
break ;
default :
2009-04-06 13:31:14 +02:00
sLog . outError ( "Auras: Unknown Shapeshift Type: %u" , GetMiscValue ());
2008-10-11 14:16:25 -05:00
}
// remove polymorph before changing display id to keep new display id
switch ( form )
{
case FORM_CAT :
case FORM_TREE :
case FORM_TRAVEL :
case FORM_AQUA :
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_FLIGHT_EPIC :
case FORM_FLIGHT :
case FORM_MOONKIN :
// remove movement affects
2009-05-01 15:36:32 -05:00
m_target -> RemoveMovementImpairingAuras ();
2008-10-11 14:16:25 -05:00
// and polymorphic affects
if ( m_target -> IsPolymorphed ())
m_target -> RemoveAurasDueToSpell ( m_target -> getTransForm ());
break ;
default :
break ;
}
if ( apply )
{
// remove other shapeshift before applying a new one
if ( m_target -> m_ShapeShiftFormSpellId )
2009-04-06 13:31:14 +02:00
m_target -> RemoveAurasDueToSpell ( m_target -> m_ShapeShiftFormSpellId );
2008-10-11 14:16:25 -05:00
m_target -> SetByteValue ( UNIT_FIELD_BYTES_2 , 3 , form );
if ( modelid > 0 )
m_target -> SetDisplayId ( modelid );
if ( PowerType != POWER_MANA )
{
// reset power to default values only at power change
if ( m_target -> getPowerType () != PowerType )
m_target -> setPowerType ( PowerType );
switch ( form )
{
case FORM_CAT :
case FORM_BEAR :
case FORM_DIREBEAR :
{
// get furor proc chance
2009-04-26 12:30:45 +02:00
int32 FurorChance = 0 ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & mDummy = m_target -> GetAurasByType ( SPELL_AURA_DUMMY );
for ( Unit :: AuraEffectList :: const_iterator i = mDummy . begin (); i != mDummy . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
if (( * i ) -> GetSpellProto () -> SpellIconID == 238 )
{
2009-04-06 13:31:14 +02:00
FurorChance = ( * i ) -> GetAmount ();
2008-10-11 14:16:25 -05:00
break ;
}
}
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == FORM_CAT )
2008-10-11 14:16:25 -05:00
{
m_target -> SetPower ( POWER_ENERGY , 0 );
if ( urand ( 1 , 100 ) <= FurorChance )
2009-04-26 12:30:45 +02:00
m_target -> CastCustomSpell ( m_target , 17099 , & FurorChance , NULL , NULL , true , NULL , this );
2008-10-11 14:16:25 -05:00
}
else
{
m_target -> SetPower ( POWER_RAGE , 0 );
if ( urand ( 1 , 100 ) <= FurorChance )
m_target -> CastSpell ( m_target , 17057 , true , NULL , this );
}
break ;
}
case FORM_BATTLESTANCE :
case FORM_DEFENSIVESTANCE :
case FORM_BERSERKERSTANCE :
{
uint32 Rage_val = 0 ;
// Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
PlayerSpellMap const & sp_list = (( Player * ) m_target ) -> GetSpellMap ();
for ( PlayerSpellMap :: const_iterator itr = sp_list . begin (); itr != sp_list . end (); ++ itr )
{
if ( itr -> second -> state == PLAYERSPELL_REMOVED ) continue ;
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( itr -> first );
if ( spellInfo && spellInfo -> SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo -> SpellIconID == 139 )
Rage_val += m_target -> CalculateSpellDamage ( spellInfo , 0 , spellInfo -> EffectBasePoints [ 0 ], m_target ) * 10 ;
}
}
if ( m_target -> GetPower ( POWER_RAGE ) > Rage_val )
m_target -> SetPower ( POWER_RAGE , Rage_val );
break ;
}
default :
break ;
}
}
m_target -> m_ShapeShiftFormSpellId = GetId ();
m_target -> m_form = form ;
}
else
{
2008-11-14 16:28:45 -06:00
if ( modelid > 0 )
m_target -> SetDisplayId ( m_target -> GetNativeDisplayId ());
2008-10-11 14:16:25 -05:00
m_target -> SetByteValue ( UNIT_FIELD_BYTES_2 , 3 , FORM_NONE );
if ( m_target -> getClass () == CLASS_DRUID )
m_target -> setPowerType ( POWER_MANA );
m_target -> m_ShapeShiftFormSpellId = 0 ;
m_target -> m_form = FORM_NONE ;
switch ( form )
{
// Nordrassil Harness - bonus
case FORM_BEAR :
case FORM_DIREBEAR :
case FORM_CAT :
2009-04-06 13:31:14 +02:00
if ( AuraEffect * dummy = m_target -> GetDummyAura ( 37315 ) )
2008-10-11 14:16:25 -05:00
m_target -> CastSpell ( m_target , 37316 , true , NULL , dummy );
break ;
// Nordrassil Regalia - bonus
case FORM_MOONKIN :
2009-04-06 13:31:14 +02:00
if ( AuraEffect * dummy = m_target -> GetDummyAura ( 37324 ) )
2008-10-11 14:16:25 -05:00
m_target -> CastSpell ( m_target , 37325 , true , NULL , dummy );
break ;
2009-04-29 00:31:03 -05:00
default :
break ;
2008-10-11 14:16:25 -05:00
}
}
// adding/removing linked auras
// add/remove the shapeshift aura's boosts
HandleShapeshiftBoosts ( apply );
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
(( Player * ) m_target ) -> InitDataForForm ();
2009-04-19 02:32:03 +02:00
if ( m_target -> getClass () == CLASS_DRUID )
{
if ( form == FORM_CAT && apply ) // add dash if in cat-from
{
2009-06-06 13:45:17 +02:00
Unit :: AuraMap & auras = m_target -> GetAuras ();
for ( Unit :: AuraMap :: iterator iter = auras . begin (); iter != auras . end (); ++ iter )
{
Aura * aur = iter -> second ;
if ( aur -> GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID && aur -> GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x8 )
{
m_target -> HandleAuraEffect ( aur -> GetPartAura ( 0 ), true );
}
}
2009-04-19 02:32:03 +02:00
}
else // remove dash effect(not buff) if out of cat-from
{
if ( AuraEffect * aurEff = m_target -> GetAura ( SPELL_AURA_MOD_INCREASE_SPEED , SPELLFAMILY_DRUID , 0 , 0 , 0x8 ))
m_target -> HandleAuraEffect ( aurEff , false );
}
}
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraTransform ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( apply )
{
// special case (spell specific functionality)
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == 0 )
2008-10-11 14:16:25 -05:00
{
// player applied only
2009-04-13 17:27:23 -05:00
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-04-13 17:27:23 -05:00
switch ( GetId ())
2008-10-11 14:16:25 -05:00
{
// Orb of Deception
case 16739 :
{
uint32 orb_model = m_target -> GetNativeDisplayId ();
switch ( orb_model )
{
// Troll Female
case 1479 : m_target -> SetDisplayId ( 10134 ); break ;
// Troll Male
case 1478 : m_target -> SetDisplayId ( 10135 ); break ;
// Tauren Male
case 59 : m_target -> SetDisplayId ( 10136 ); break ;
// Human Male
case 49 : m_target -> SetDisplayId ( 10137 ); break ;
// Human Female
case 50 : m_target -> SetDisplayId ( 10138 ); break ;
// Orc Male
case 51 : m_target -> SetDisplayId ( 10139 ); break ;
// Orc Female
case 52 : m_target -> SetDisplayId ( 10140 ); break ;
// Dwarf Male
case 53 : m_target -> SetDisplayId ( 10141 ); break ;
// Dwarf Female
case 54 : m_target -> SetDisplayId ( 10142 ); break ;
// NightElf Male
case 55 : m_target -> SetDisplayId ( 10143 ); break ;
// NightElf Female
case 56 : m_target -> SetDisplayId ( 10144 ); break ;
// Undead Female
case 58 : m_target -> SetDisplayId ( 10145 ); break ;
// Undead Male
case 57 : m_target -> SetDisplayId ( 10146 ); break ;
// Tauren Female
case 60 : m_target -> SetDisplayId ( 10147 ); break ;
// Gnome Male
case 1563 : m_target -> SetDisplayId ( 10148 ); break ;
// Gnome Female
case 1564 : m_target -> SetDisplayId ( 10149 ); break ;
// BloodElf Female
case 15475 : m_target -> SetDisplayId ( 17830 ); break ;
// BloodElf Male
case 15476 : m_target -> SetDisplayId ( 17829 ); break ;
// Dranei Female
case 16126 : m_target -> SetDisplayId ( 17828 ); break ;
// Dranei Male
case 16125 : m_target -> SetDisplayId ( 17827 ); break ;
default : break ;
}
break ;
}
// Murloc costume
case 42365 : m_target -> SetDisplayId ( 21723 ); break ;
default : break ;
}
}
else
{
2009-04-06 13:31:14 +02:00
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( GetMiscValue ());
2008-10-11 14:16:25 -05:00
if ( ! ci )
{
//pig pink ^_^
m_target -> SetDisplayId ( 16358 );
2009-04-06 13:31:14 +02:00
sLog . outError ( "Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d" , GetMiscValue (), GetId ());
2008-10-11 14:16:25 -05:00
}
else
{
2008-11-18 19:40:06 -06:00
// Will use the default model here
if ( uint32 modelid = ci -> GetRandomValidModelId ())
m_target -> SetDisplayId ( modelid );
2008-10-11 14:16:25 -05:00
// Dragonmaw Illusion (set mount model also)
2009-05-03 00:02:02 +02:00
if ( GetId () == 42016 && m_target -> GetMountID () && ! m_target -> GetAurasByType ( SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED ). empty ())
2008-10-11 14:16:25 -05:00
m_target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
}
}
2009-04-13 17:27:23 -05:00
// update active transform spell only not set or not overwriting negative by positive case
if ( ! m_target -> getTransForm () || ! IsPositiveSpell ( GetId ()) || IsPositiveSpell ( m_target -> getTransForm ()))
m_target -> setTransForm ( GetId ());
2008-10-11 14:16:25 -05:00
// polymorph case
2009-04-13 17:27:23 -05:00
if ( Real && m_target -> GetTypeId () == TYPEID_PLAYER && m_target -> IsPolymorphed ())
2008-10-11 14:16:25 -05:00
{
// for players, start regeneration after 1s (in polymorph fast regeneration case)
// only if caster is Player (after patch 2.4.2)
2009-04-13 17:27:23 -05:00
if ( IS_PLAYER_GUID ( GetCasterGUID ()) )
(( Player * ) m_target ) -> setRegenTimer ( 1 * IN_MILISECONDS );
2008-10-11 14:16:25 -05:00
//dismount polymorphed target (after patch 2.4.2)
if ( m_target -> IsMounted ())
2009-04-06 13:31:14 +02:00
m_target -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2008-10-11 14:16:25 -05:00
}
}
else
{
2009-04-13 17:27:23 -05:00
// ApplyModifier(true) will reapply it if need
m_target -> setTransForm ( 0 );
m_target -> SetDisplayId ( m_target -> GetNativeDisplayId ());
// re-aplly some from still active with preference negative cases
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & otherTransforms = m_target -> GetAurasByType ( SPELL_AURA_TRANSFORM );
2009-04-13 17:27:23 -05:00
if ( ! otherTransforms . empty ())
2008-10-11 14:16:25 -05:00
{
// look for other transform auras
2009-04-06 13:31:14 +02:00
AuraEffect * handledAura = * otherTransforms . begin ();
for ( Unit :: AuraEffectList :: const_iterator i = otherTransforms . begin (); i != otherTransforms . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
2008-11-14 16:28:45 -06:00
// negative auras are preferred
2009-04-13 17:27:23 -05:00
if ( ! IsPositiveSpell (( * i ) -> GetSpellProto () -> Id ))
2008-10-11 14:16:25 -05:00
{
handledAura = * i ;
break ;
}
}
handledAura -> ApplyModifier ( true );
}
// Dragonmaw Illusion (restore mount model)
2009-04-13 17:27:23 -05:00
if ( GetId () == 42016 && m_target -> GetMountID () == 16314 )
2008-10-11 14:16:25 -05:00
{
2009-04-13 17:27:23 -05:00
if ( ! m_target -> GetAurasByType ( SPELL_AURA_MOUNTED ). empty ())
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
uint32 cr_id = m_target -> GetAurasByType ( SPELL_AURA_MOUNTED ). front () -> GetMiscValue ();
2008-10-11 14:16:25 -05:00
if ( CreatureInfo const * ci = objmgr . GetCreatureTemplate ( cr_id ))
{
uint32 team = 0 ;
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
team = (( Player * ) m_target ) -> GetTeam ();
uint32 display_id = objmgr . ChooseDisplayId ( team , ci );
CreatureModelInfo const * minfo = objmgr . GetCreatureModelRandomGender ( display_id );
if ( minfo )
display_id = minfo -> modelid ;
m_target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , display_id );
}
}
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleForceReaction ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
Player * player = ( Player * ) m_target ;
2009-04-06 13:31:14 +02:00
uint32 faction_id = GetMiscValue ();
uint32 faction_rank = m_amount ;
2008-10-11 14:16:25 -05:00
2009-03-26 13:53:32 -06:00
player -> GetReputationMgr (). ApplyForceReaction ( faction_id , ReputationRank ( faction_rank ), apply );
player -> GetReputationMgr (). SendForceReactions ();
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModSkill ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
uint32 prot = GetSpellProto () -> EffectMiscValue [ m_effIndex ];
2009-04-06 13:31:14 +02:00
int32 points = m_amount ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
(( Player * ) m_target ) -> ModifySkillBonus ( prot ,( apply ? points : - points ), m_auraName == SPELL_AURA_MOD_SKILL_TALENT );
2008-10-11 14:16:25 -05:00
if ( prot == SKILL_DEFENSE )
(( Player * ) m_target ) -> UpdateDefenseBonusesMod ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleChannelDeathItem ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( Real && ! apply )
{
Unit * caster = GetCaster ();
2009-04-06 13:31:14 +02:00
Unit * victim = m_target ;
2008-11-29 14:04:20 -06:00
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER || ! victim ) // || m_removeMode!=AURA_REMOVE_BY_DEATH)
return ;
//we cannot check removemode = death
//talent will remove the caster's aura->interrupt channel->remove victim aura
if ( victim -> GetHealth () > 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-01-29 19:33:39 -06:00
// Item amount
2009-04-06 13:31:14 +02:00
if ( m_amount <= 0 )
2009-01-29 19:33:39 -06:00
return ;
2008-10-11 14:16:25 -05:00
SpellEntry const * spellInfo = GetSpellProto ();
if ( spellInfo -> EffectItemType [ m_effIndex ] == 0 )
return ;
// Soul Shard only from non-grey units
if ( spellInfo -> EffectItemType [ m_effIndex ] == 6265 &&
2008-10-14 11:57:03 -05:00
( victim -> getLevel () <= Trinity :: XP :: GetGrayLevel ( caster -> getLevel ()) ||
2008-10-11 14:16:25 -05:00
victim -> GetTypeId () == TYPEID_UNIT && ! (( Player * ) caster ) -> isAllowedToLoot (( Creature * ) victim )) )
return ;
2009-01-29 19:33:39 -06:00
//Adding items
uint32 noSpaceForCount = 0 ;
2009-04-06 13:31:14 +02:00
uint32 count = m_amount ;
2009-01-29 19:33:39 -06:00
2008-10-11 14:16:25 -05:00
ItemPosCountVec dest ;
2009-01-29 19:33:39 -06:00
uint8 msg = (( Player * ) caster ) -> CanStoreNewItem ( NULL_BAG , NULL_SLOT , dest , spellInfo -> EffectItemType [ m_effIndex ], count , & noSpaceForCount );
2008-10-11 14:16:25 -05:00
if ( msg != EQUIP_ERR_OK )
{
2009-01-29 19:33:39 -06:00
count -= noSpaceForCount ;
2008-10-11 14:16:25 -05:00
(( Player * ) caster ) -> SendEquipError ( msg , NULL , NULL );
2009-01-29 19:33:39 -06:00
if ( count == 0 )
return ;
2008-10-11 14:16:25 -05:00
}
Item * newitem = (( Player * ) caster ) -> StoreNewItem ( dest , spellInfo -> EffectItemType [ m_effIndex ], true );
2009-01-29 19:33:39 -06:00
(( Player * ) caster ) -> SendNewItem ( newitem , count , true , false );
2008-10-11 14:16:25 -05:00
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleBindSight ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real )
return ;
2008-10-11 14:16:25 -05:00
Unit * caster = GetCaster ();
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-03-24 13:13:00 -06:00
(( Player * ) caster ) -> SetViewpoint ( m_target , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleFarSight ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-03-10 15:26:17 -06:00
//Handled by client
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraTrackCreatures ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-04-06 13:31:14 +02:00
m_target -> SetUInt32Value ( PLAYER_TRACK_CREATURES , apply ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraTrackResources ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-04-06 13:31:14 +02:00
m_target -> SetUInt32Value ( PLAYER_TRACK_RESOURCES , apply ? (( uint32 ) 1 ) << ( GetMiscValue () - 1 ) : 0 );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraTrackStealthed ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
m_target -> ApplyModFlag ( PLAYER_FIELD_BYTES , PLAYER_FIELD_BYTE_TRACK_STEALTHED , apply );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModScale ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyPercentModFloatValue ( OBJECT_FIELD_SCALE_X , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
/*void AuraEffect::HandleModPossess(bool apply, bool Real)
2008-10-11 14:16:25 -05:00
{
if(!Real)
return;
2009-04-06 13:31:14 +02:00
if(m_target->getLevel() > m_amount)
2008-10-11 14:16:25 -05:00
return;
// not possess yourself
if(GetCasterGUID() == m_target->GetGUID())
return;
Unit* caster = GetCaster();
if(!caster)
return;
if( apply )
{
2009-01-09 16:43:23 -06:00
m_target->SetCharmerGUID(GetCasterGUID());
2009-06-03 19:29:55 -05:00
m_target->setFaction(caster->getFaction());
2009-03-24 17:38:14 -06:00
2009-01-09 16:43:23 -06:00
caster->SetCharm(m_target);
2009-01-08 21:48:38 -06:00
2009-03-24 17:38:14 -06:00
if(caster->GetTypeId() == TYPEID_PLAYER)
{
((Player*)caster)->SetFarSightGUID(m_target->GetGUID());
((Player*)caster)->SetClientControl(m_target, 1);
}
2009-01-09 16:43:23 -06:00
m_target->CombatStop();
m_target->DeleteThreatList();
if(m_target->GetTypeId() == TYPEID_UNIT)
{
m_target->StopMoving();
m_target->GetMotionMaster()->Clear();
m_target->GetMotionMaster()->MoveIdle();
}
2009-04-03 16:42:19 -06:00
else if(m_target->GetTypeId() == TYPEID_PLAYER)
{
((Player*)m_target)->SetClientControl(m_target, 0);
}
if(CharmInfo *charmInfo = m_target->InitCharmInfo(m_target))
charmInfo->InitPossessCreateSpells();
2009-01-09 16:43:23 -06:00
if(caster->GetTypeId() == TYPEID_PLAYER)
((Player*)caster)->PossessSpellInitialize();
2008-10-11 14:16:25 -05:00
}
else
2009-01-09 16:43:23 -06:00
{
2008-12-24 09:58:26 -06:00
m_target->SetCharmerGUID(0);
2009-04-03 16:42:19 -06:00
caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
2008-12-24 09:58:26 -06:00
if(m_target->GetTypeId() == TYPEID_PLAYER)
2009-04-03 16:42:19 -06:00
{
2008-12-24 09:58:26 -06:00
((Player*)m_target)->setFactionForRace(m_target->getRace());
2009-04-03 16:42:19 -06:00
((Player*)m_target)->SetClientControl(m_target, 1);
}
2008-12-24 09:58:26 -06:00
else if(m_target->GetTypeId() == TYPEID_UNIT)
{
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
2009-06-03 19:29:55 -05:00
m_target->setFaction(cinfo->faction_A);
2008-12-24 09:58:26 -06:00
}
2009-03-24 09:44:08 -06:00
caster->SetCharm(NULL);
2008-12-24 09:58:26 -06:00
if(caster->GetTypeId() == TYPEID_PLAYER)
{
2009-03-24 17:38:14 -06:00
((Player*)caster)->SetFarSightGUID(0);
((Player*)caster)->SetClientControl(m_target,0);
2009-03-21 14:53:38 -06:00
WorldPacket data(SMSG_PET_SPELLS, 8+4);
2008-12-24 09:58:26 -06:00
data << uint64(0);
data << uint32(0);
((Player*)caster)->GetSession()->SendPacket(&data);
}
2009-03-24 17:38:14 -06:00
2008-12-24 09:58:26 -06:00
if(m_target->GetTypeId() == TYPEID_UNIT)
{
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
2009-04-14 21:07:52 -05:00
((Creature*)m_target)->AI()->AttackedBy(caster);
2008-12-24 09:58:26 -06:00
}
}
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
void AuraEffect::HandleModPossessPet(bool apply, bool Real)
2008-10-11 14:16:25 -05:00
{
if(!Real)
return;
Unit* caster = GetCaster();
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
2008-12-24 09:58:26 -06:00
2009-03-27 22:47:28 -06:00
Pet *pet = caster->GetGuardianPet();
2008-12-24 09:58:26 -06:00
if(!pet || pet != m_target)
2008-10-11 14:16:25 -05:00
return;
2008-12-24 09:58:26 -06:00
if(apply)
2009-01-16 14:17:24 -06:00
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
2008-12-24 09:58:26 -06:00
else
2009-01-16 14:17:24 -06:00
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
2008-12-24 09:58:26 -06:00
2009-03-09 17:44:59 -06:00
((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : 0);
2008-12-24 09:58:26 -06:00
((Player*)caster)->SetCharm(apply ? pet : NULL);
((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
2008-10-11 14:16:25 -05:00
if(apply)
{
2009-01-09 16:43:23 -06:00
pet->StopMoving();
pet->GetMotionMaster()->Clear();
pet->GetMotionMaster()->MoveIdle();
2008-10-11 14:16:25 -05:00
}
else
{
2008-12-24 09:58:26 -06:00
pet->AttackStop();
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
2008-10-11 14:16:25 -05:00
}
2009-01-20 19:59:43 -06:00
}*/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModPetTalentsPoints ( bool Apply , bool Real , bool changeAmount )
2009-01-20 19:59:43 -06:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2009-01-20 19:59:43 -06:00
return ;
2009-03-27 22:47:28 -06:00
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-01-20 19:59:43 -06:00
// Recalculate pet tlaent points
2009-03-27 22:47:28 -06:00
if ( Pet * pet = (( Player * ) m_target ) -> GetPet ())
2009-04-19 17:29:17 +02:00
pet -> InitTalentForLevel ();
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
/*void AuraEffect::HandleModCharm(bool apply, bool Real)
2008-10-11 14:16:25 -05:00
{
if(!Real)
return;
// not charm yourself
if(GetCasterGUID() == m_target->GetGUID())
return;
Unit* caster = GetCaster();
2009-01-09 16:43:23 -06:00
if(!caster)
2008-10-11 14:16:25 -05:00
return;
2009-04-06 13:31:14 +02:00
if(int32(m_target->getLevel()) <= m_amount)
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:43:23 -06:00
if( apply )
2008-12-11 22:22:35 -06:00
{
2009-01-09 16:43:23 -06:00
m_target->SetCharmerGUID(GetCasterGUID());
2009-06-03 19:29:55 -05:00
m_target->setFaction(caster->getFaction());
m_target->CastStop(m_target == caster ? GetId() : 0);
2009-01-09 16:43:23 -06:00
caster->SetCharm(m_target);
m_target->CombatStop();
m_target->DeleteThreatList();
2008-10-11 14:16:25 -05:00
2009-01-09 16:43:23 -06:00
if(m_target->GetTypeId() == TYPEID_UNIT)
2008-12-11 22:22:35 -06:00
{
2009-01-09 16:43:23 -06:00
((Creature*)m_target)->AIM_Initialize();
2009-04-03 16:42:19 -06:00
CharmInfo *charmInfo = m_target->InitCharmInfo(m_target);
2009-01-09 16:43:23 -06:00
charmInfo->InitCharmCreateSpells();
charmInfo->SetReactState( REACT_DEFENSIVE );
if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:43:23 -06:00
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
2009-05-29 21:24:23 -05:00
//does not appear to have relevance. Why code added initially? See note below at !apply
2009-01-09 16:43:23 -06:00
//to prevent client crash
2009-05-29 21:24:23 -05:00
//m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
2009-01-09 16:43:23 -06:00
//just to enable stat window
charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
//if charmed two demons the same session, the 2nd gets the 1st one's name
m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
}
2008-10-11 14:16:25 -05:00
}
}
2009-01-09 16:43:23 -06:00
if(caster->GetTypeId() == TYPEID_PLAYER)
{
((Player*)caster)->CharmSpellInitialize();
}
2008-10-11 14:16:25 -05:00
}
else
{
2009-01-09 16:43:23 -06:00
m_target->SetCharmerGUID(0);
2008-10-11 14:16:25 -05:00
2009-01-09 16:43:23 -06:00
if(m_target->GetTypeId() == TYPEID_PLAYER)
((Player*)m_target)->setFactionForRace(m_target->getRace());
else
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:43:23 -06:00
CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
// restore faction
if(((Creature*)m_target)->isPet())
{
if(Unit* owner = m_target->GetOwner())
2009-06-03 19:29:55 -05:00
m_target->setFaction(owner->getFaction());
2009-01-09 16:43:23 -06:00
else if(cinfo)
2009-06-03 19:29:55 -05:00
m_target->setFaction(cinfo->faction_A);
2009-01-09 16:43:23 -06:00
}
else if(cinfo) // normal creature
2009-06-03 19:29:55 -05:00
m_target->setFaction(cinfo->faction_A);
2008-10-11 14:16:25 -05:00
2009-01-09 16:43:23 -06:00
// restore UNIT_FIELD_BYTES_0
if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
{
2009-05-29 21:24:23 -05:00
//does not appear to have relevance. Why code added initially? Class, gender, powertype should be same.
//db field removed and replaced with better way to set class, restore using this if problems
/*CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
2009-01-09 16:43:23 -06:00
if(cainfo && cainfo->bytes0 != 0)
m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
else
m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
2008-10-11 14:16:25 -05:00
2009-01-09 16:43:23 -06:00
if(m_target->GetCharmInfo())
m_target->GetCharmInfo()->SetPetNumber(0, true);
else
2009-05-31 16:15:12 -05:00
sLog.outError("AuraEffect::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
2009-01-09 16:43:23 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-03-24 09:44:08 -06:00
caster->SetCharm(NULL);
2008-10-11 14:16:25 -05:00
if(caster->GetTypeId() == TYPEID_PLAYER)
{
2009-03-21 14:53:38 -06:00
WorldPacket data(SMSG_PET_SPELLS, 8+4);
2008-10-11 14:16:25 -05:00
data << uint64(0);
2008-12-24 09:58:26 -06:00
data << uint32(0);
2008-10-11 14:16:25 -05:00
((Player*)caster)->GetSession()->SendPacket(&data);
}
2009-01-09 16:43:23 -06:00
if(m_target->GetTypeId() == TYPEID_UNIT)
{
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
2009-04-14 21:07:52 -05:00
((Creature*)m_target)->AI()->AttackedBy(caster);
2009-01-09 16:43:23 -06:00
}
2008-10-11 14:16:25 -05:00
}
}
2009-01-09 16:43:23 -06:00
}*/
2008-10-11 14:16:25 -05:00
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModConfuse ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
2008-12-09 20:28:59 -06:00
//m_target->SetConfused(apply, GetCasterGUID(), GetId());
m_target -> SetControlled ( apply , UNIT_STAT_CONFUSED );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModFear ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
2008-12-09 20:28:59 -06:00
//m_target->SetFeared(apply, GetCasterGUID(), GetId());
m_target -> SetControlled ( apply , UNIT_STAT_FLEEING );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleFeignDeath ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<m_target->GetGUID();
data<<uint8(0);
m_target->SendMessageToSet(&data,true);
*/
2008-12-01 22:32:16 -06:00
2008-12-17 18:45:54 -06:00
std :: list < Unit *> targets ;
2008-12-20 17:42:40 -06:00
Trinity :: AnyUnfriendlyUnitInObjectRangeCheck u_check ( m_target , m_target , World :: GetMaxVisibleDistance ());
2009-01-31 16:38:50 -06:00
Trinity :: UnitListSearcher < Trinity :: AnyUnfriendlyUnitInObjectRangeCheck > searcher ( m_target , targets , u_check );
2008-12-20 17:42:40 -06:00
m_target -> VisitNearbyObject ( World :: GetMaxVisibleDistance (), searcher );
2008-12-17 18:45:54 -06:00
for ( std :: list < Unit *>:: iterator iter = targets . begin (); iter != targets . end (); ++ iter )
{
if ( ! ( * iter ) -> hasUnitState ( UNIT_STAT_CASTING ))
continue ;
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; i ++ )
{
if (( * iter ) -> m_currentSpells [ i ]
&& ( * iter ) -> m_currentSpells [ i ] -> m_targets . getUnitTargetGUID () == m_target -> GetGUID ())
{
( * iter ) -> InterruptSpell ( i , false );
}
}
}
2008-10-11 14:16:25 -05:00
// blizz like 2.0.x
2009-01-16 14:17:24 -06:00
m_target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_UNK_29 );
2008-10-11 14:16:25 -05:00
// blizz like 2.0.x
m_target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FEIGN_DEATH );
// blizz like 2.0.x
m_target -> SetFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_DEAD );
m_target -> addUnitState ( UNIT_STAT_DIED );
m_target -> CombatStop ();
2009-03-24 09:36:50 -06:00
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2008-10-11 14:16:25 -05:00
// prevent interrupt message
2009-04-06 13:31:14 +02:00
if ( GetCasterGUID () == m_target -> GetGUID () && m_target -> m_currentSpells [ CURRENT_GENERIC_SPELL ])
2008-10-11 14:16:25 -05:00
m_target -> m_currentSpells [ CURRENT_GENERIC_SPELL ] -> finish ();
m_target -> InterruptNonMeleeSpells ( true );
m_target -> getHostilRefManager (). deleteReferences ();
}
else
{
/*
WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
data<<m_target->GetGUID();
data<<uint8(1);
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
2009-01-16 14:17:24 -06:00
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_UNK_29 );
2008-10-11 14:16:25 -05:00
// blizz like 2.0.x
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FEIGN_DEATH );
// blizz like 2.0.x
m_target -> RemoveFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_DEAD );
m_target -> clearUnitState ( UNIT_STAT_DIED );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModDisarm ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-02-03 15:56:07 +01:00
if ( ! Real )
2008-10-11 14:16:25 -05:00
return ;
2009-04-06 13:31:14 +02:00
AuraType type = AuraType ( GetAuraName ());
2008-10-11 14:16:25 -05:00
2009-02-03 19:12:33 +01:00
//Prevent handling aura twice
2009-02-03 18:27:22 +01:00
if ( apply && m_target -> GetAurasByType ( type ). size () > 1 )
2008-10-11 14:16:25 -05:00
return ;
2009-02-03 15:56:07 +01:00
if ( ! apply && m_target -> HasAuraType ( type ))
2008-10-11 14:16:25 -05:00
return ;
2009-02-03 15:56:07 +01:00
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 ;
2009-04-27 18:36:10 -05:00
break ;
2009-02-03 15:56:07 +01:00
case SPELL_AURA_MOD_DISARM_OFFHAND :
field = UNIT_FIELD_FLAGS_2 ;
flag = UNIT_FLAG2_DISARM_OFFHAND ;
slot = EQUIPMENT_SLOT_OFFHAND ;
attType = OFF_ATTACK ;
2009-04-27 18:36:10 -05:00
break ;
2009-02-03 15:56:07 +01:00
case SPELL_AURA_MOD_DISARM_RANGED :
field = UNIT_FIELD_FLAGS_2 ;
flag = UNIT_FLAG2_DISARM_RANGED ;
slot = EQUIPMENT_SLOT_RANGED ;
attType = RANGED_ATTACK ;
2009-04-27 18:36:10 -05:00
break ;
2009-02-03 15:56:07 +01:00
}
2008-10-11 14:16:25 -05:00
if ( apply )
2009-02-03 15:56:07 +01:00
m_target -> SetFlag ( field , flag );
2008-10-11 14:16:25 -05:00
else
2009-02-03 15:56:07 +01:00
m_target -> RemoveFlag ( field , flag );
2008-10-11 14:16:25 -05:00
2008-11-22 14:28:11 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
2009-02-03 15:56:07 +01:00
Item * pItem = (( Player * ) m_target ) -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot );
if ( ! pItem )
2008-11-22 14:28:11 -06:00
return ;
2009-02-03 15:56:07 +01:00
(( Player * ) m_target ) -> _ApplyItemMods ( pItem , slot , ! apply );
2008-11-22 14:28:11 -06:00
}
2009-02-03 15:56:07 +01:00
else if ((( Creature * ) m_target ) -> GetCurrentEquipmentId ())
m_target -> UpdateDamagePhysical ( attType );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModStealth ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
if ( ! Real )
return ;
2008-10-11 14:16:25 -05:00
if ( apply )
{
2009-03-24 09:36:50 -06:00
// drop flag at stealth in bg
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
m_target -> SetStandFlags ( UNIT_STAND_FLAGS_CREEP );
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
m_target -> SetFlag ( PLAYER_FIELD_BYTES2 , 0x2000 );
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
// apply only if not in GM invisibility (and overwrite invisibility state)
if ( m_target -> GetVisibility () != VISIBILITY_OFF )
m_target -> SetVisibility ( VISIBILITY_GROUP_STEALTH );
2008-10-11 14:16:25 -05:00
}
2009-03-24 09:36:50 -06:00
else if ( ! m_target -> HasAuraType ( SPELL_AURA_MOD_STEALTH )) // if last SPELL_AURA_MOD_STEALTH
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
m_target -> RemoveStandFlags ( UNIT_STAND_FLAGS_CREEP );
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
m_target -> RemoveFlag ( PLAYER_FIELD_BYTES2 , 0x2000 );
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
if ( m_target -> GetVisibility () != VISIBILITY_OFF )
m_target -> SetVisibility ( VISIBILITY_ON );
2008-10-11 14:16:25 -05:00
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleInvisibility ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( apply )
{
2009-04-06 13:31:14 +02:00
m_target -> m_invisibilityMask |= ( 1 << GetMiscValue ());
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
if ( Real )
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2008-10-11 14:16:25 -05:00
// apply glow vision
2009-03-24 09:36:50 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
m_target -> SetFlag ( PLAYER_FIELD_BYTES2 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
m_target -> SetToNotify ();
2008-10-11 14:16:25 -05:00
}
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target -> m_invisibilityMask = 0 ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & auras = m_target -> GetAurasByType ( SPELL_AURA_MOD_INVISIBILITY );
for ( Unit :: AuraEffectList :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
m_target -> m_invisibilityMask |= ( 1 << GetMiscValue ());
2008-10-11 14:16:25 -05:00
// only at real aura remove and if not have different invisibility auras.
2009-03-24 09:36:50 -06:00
if ( Real )
2008-10-11 14:16:25 -05:00
{
// remove glow vision
2009-03-24 09:36:50 -06:00
if ( ! m_target -> m_invisibilityMask && m_target -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
m_target -> RemoveFlag ( PLAYER_FIELD_BYTES2 , PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW );
2009-03-24 09:36:50 -06:00
m_target -> SetToNotify ();
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleInvisibilityDetect ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( apply )
{
2009-04-06 13:31:14 +02:00
m_target -> m_detectInvisibilityMask |= ( 1 << GetMiscValue ());
2008-10-11 14:16:25 -05:00
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target -> m_detectInvisibilityMask = 0 ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & auras = m_target -> GetAurasByType ( SPELL_AURA_MOD_INVISIBILITY_DETECTION );
for ( Unit :: AuraEffectList :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
m_target -> m_detectInvisibilityMask |= ( 1 << GetMiscValue ());
2008-10-11 14:16:25 -05:00
}
if ( Real && m_target -> GetTypeId () == TYPEID_PLAYER )
2008-12-20 17:42:40 -06:00
//ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
m_target -> SetToNotify ();
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModSilence ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
if ( ! Real )
return ;
if ( apply )
{
m_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 ++ )
2009-04-13 17:36:37 -05:00
if ( m_target -> m_currentSpells [ i ] && m_target -> m_currentSpells [ i ] -> m_spellInfo -> PreventionType == SPELL_PREVENTION_TYPE_SILENCE )
m_target -> InterruptSpell ( i , false ); // Stop spells on prepare or casting state
2008-10-11 14:16:25 -05:00
}
else
{
// Real remove called after current aura remove from lists, check if other similar auras active
if ( m_target -> HasAuraType ( SPELL_AURA_MOD_SILENCE ))
return ;
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SILENCED );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModThreat ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( ! m_target -> isAlive ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
int level_diff = 0 ;
int multiplier = 0 ;
switch ( GetId ())
{
// Arcane Shroud
case 26400 :
level_diff = m_target -> getLevel () - 60 ;
multiplier = 2 ;
break ;
// The Eye of Diminution
case 28862 :
level_diff = m_target -> getLevel () - 60 ;
multiplier = 1 ;
break ;
}
if ( level_diff > 0 )
2009-04-06 13:31:14 +02:00
m_amount += multiplier * level_diff ;
2008-10-11 14:16:25 -05:00
for ( int8 x = 0 ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-04-21 13:58:08 -05:00
ApplyPercentModFloatVar ( m_target -> m_threatModifier [ x ], m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModTotalThreat ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( ! m_target -> isAlive () || m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive ())
return ;
float threatMod = 0.0f ;
if ( apply )
2009-04-06 13:31:14 +02:00
threatMod = float ( m_amount );
2008-10-11 14:16:25 -05:00
else
2009-04-06 13:31:14 +02:00
threatMod = float ( - m_amount );
2008-10-11 14:16:25 -05:00
m_target -> getHostilRefManager (). threatAssist ( caster , threatMod );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModTaunt ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only at real add/remove aura
if ( ! Real )
return ;
if ( ! m_target -> isAlive () || ! m_target -> CanHaveThreatList ())
return ;
Unit * caster = GetCaster ();
if ( ! caster || ! caster -> isAlive () || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
m_target -> TauntApply ( caster );
else
{
// When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
m_target -> TauntFadeOut ( caster );
}
}
/*********************************************************/
/*** MODIFY SPEED ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseSpeed ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
2009-04-19 02:32:03 +02:00
if ( apply ) // Dash wont work if you are not in cat form
if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto -> SpellFamilyFlags [ 2 ] & 0x8 && m_target -> m_form != FORM_CAT )
2009-06-06 13:45:17 +02:00
{
m_target -> HandleAuraEffect ( this , false );
2009-04-19 02:32:03 +02:00
return ;
2009-06-06 13:45:17 +02:00
}
2009-04-19 02:32:03 +02:00
2008-10-11 14:16:25 -05:00
m_target -> UpdateSpeed ( MOVE_RUN , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseMountedSpeed ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
m_target -> UpdateSpeed ( MOVE_RUN , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseFlightSpeed ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
// Enable Fly mode for flying mounts
2009-05-03 00:02:02 +02:00
if ( m_auraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED )
2008-10-11 14:16:25 -05:00
{
WorldPacket data ;
if ( apply )
data . Initialize ( SMSG_MOVE_SET_CAN_FLY , 12 );
else
data . Initialize ( SMSG_MOVE_UNSET_CAN_FLY , 12 );
data . append ( m_target -> GetPackGUID ());
data << uint32 ( 0 ); // unknown
m_target -> SendMessageToSet ( & data , true );
//Players on flying mounts must be immune to polymorph
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-04-10 23:44:37 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , MECHANIC_POLYMORPH , apply );
2008-10-11 14:16:25 -05:00
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
2009-04-06 13:31:14 +02:00
if ( apply && m_target -> HasAuraEffect ( 42016 , 0 ) && m_target -> GetMountID ())
2008-10-11 14:16:25 -05:00
m_target -> SetUInt32Value ( UNIT_FIELD_MOUNTDISPLAYID , 16314 );
}
2008-12-12 11:21:28 -06:00
m_target -> UpdateSpeed ( MOVE_FLIGHT , true );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseSwimSpeed ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
m_target -> UpdateSpeed ( MOVE_SWIM , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModDecreaseSpeed ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
m_target -> UpdateSpeed ( MOVE_RUN , true );
m_target -> UpdateSpeed ( MOVE_SWIM , true );
2008-12-12 11:21:28 -06:00
m_target -> UpdateSpeed ( MOVE_FLIGHT , true );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModUseNormalSpeed ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
m_target -> UpdateSpeed ( MOVE_RUN , true );
m_target -> UpdateSpeed ( MOVE_SWIM , true );
2008-12-12 11:21:28 -06:00
m_target -> UpdateSpeed ( MOVE_FLIGHT , true );
2008-10-11 14:16:25 -05:00
}
/*********************************************************/
/*** IMMUNITY ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModStateImmunityMask ( bool apply , bool Real , bool /*changeAmount*/ )
2009-04-10 23:44:37 +02:00
{
2009-05-19 18:33:49 +02:00
if ( ! Real )
return ;
2009-04-10 23:44:37 +02:00
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_MOD_TAUNT );
// 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 );
2009-04-19 01:32:22 +02:00
if ( GetMiscValue () & ( 1 << 2 ))
2009-04-10 23:44:37 +02:00
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
if ( apply && GetId () == 46924 )
{
m_target -> RemoveAurasByType ( SPELL_AURA_MOD_ROOT );
m_target -> RemoveAurasByType ( SPELL_AURA_MOD_DECREASE_SPEED );
}
if ( apply && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
{
2009-04-11 00:27:30 +02:00
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
2009-04-10 23:44:37 +02:00
{
m_target -> RemoveAurasByType ( * iter );
}
}
2009-04-11 00:27:30 +02:00
for ( std :: list < AuraType >:: iterator iter = immunity_list . begin (); iter != immunity_list . end (); ++ iter )
2009-04-10 23:44:37 +02:00
{
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , * iter , apply );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModMechanicImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-19 18:33:49 +02:00
if ( ! Real )
return ;
2009-02-06 23:01:07 +01:00
uint32 mechanic ;
2009-04-10 23:44:37 +02:00
mechanic = 1 << GetMiscValue ();
2008-10-11 14:16:25 -05:00
//immune movement impairment and loss of control
2009-02-17 17:41:11 -06:00
if ( GetId () == 42292 || GetId () == 59752 )
2008-10-11 14:16:25 -05:00
mechanic = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ;
2009-04-10 23:44:37 +02:00
if ( ! mechanic )
return ;
2008-10-11 14:16:25 -05:00
if ( apply && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
{
Unit :: AuraMap & Auras = m_target -> GetAuras ();
2009-04-07 20:09:15 +02:00
for ( Unit :: AuraMap :: iterator iter = Auras . begin (); iter != Auras . end ();)
2008-10-11 14:16:25 -05:00
{
SpellEntry const * spell = iter -> second -> GetSpellProto ();
2009-04-25 18:53:29 +02:00
if ( spell -> Id != GetId ())
2008-10-11 14:16:25 -05:00
{
//check for mechanic mask
2009-04-06 13:31:14 +02:00
if ( GetAllSpellMechanicMask ( spell ) & mechanic )
2008-10-11 14:16:25 -05:00
{
2009-04-07 18:05:56 +02:00
m_target -> RemoveAura ( iter );
2008-10-11 14:16:25 -05:00
}
2009-04-07 18:05:56 +02:00
else
++ iter ;
2008-10-11 14:16:25 -05:00
}
2009-04-07 20:09:15 +02:00
else
++ iter ;
2008-10-11 14:16:25 -05:00
}
}
2009-04-10 23:44:37 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_MECHANIC , GetMiscValue (), apply );
2008-10-11 14:16:25 -05:00
// Bestial Wrath
2008-10-23 09:40:37 -05:00
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto () -> Id == 19574 )
2008-10-11 14:16:25 -05:00
{
// The Beast Within cast on owner if talent present
if ( Unit * owner = m_target -> GetOwner () )
{
// Search talent
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & m_dummyAuras = owner -> GetAurasByType ( SPELL_AURA_DUMMY );
for ( Unit :: AuraEffectList :: const_iterator i = m_dummyAuras . begin (); i != m_dummyAuras . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
if ( ( * i ) -> GetSpellProto () -> SpellIconID == 2229 )
{
if ( apply )
owner -> CastSpell ( owner , 34471 , true , 0 , this );
else
owner -> RemoveAurasDueToSpell ( 34471 );
break ;
}
}
}
}
// The Beast Within and Bestial Wrath - immunity
if ( GetId () == 19574 || GetId () == 34471 )
{
if ( apply )
{
2009-05-17 18:00:33 +02:00
m_target -> CastSpell ( m_target , 24395 , true , NULL , this );
m_target -> CastSpell ( m_target , 24396 , true , NULL , this );
m_target -> CastSpell ( m_target , 24397 , true , NULL , this );
m_target -> CastSpell ( m_target , 26592 , true , NULL , this );
2008-10-11 14:16:25 -05:00
}
else
{
m_target -> RemoveAurasDueToSpell ( 24395 );
m_target -> RemoveAurasDueToSpell ( 24396 );
m_target -> RemoveAurasDueToSpell ( 24397 );
m_target -> RemoveAurasDueToSpell ( 26592 );
}
}
2009-03-03 22:26:26 +01:00
// Heroic Fury (remove Intercept cooldown)
2009-05-19 18:33:49 +02:00
else if ( apply && GetId () == 60970 && m_target -> GetTypeId () == TYPEID_PLAYER )
{
(( Player * ) m_target ) -> RemoveSpellCooldown ( 20252 , true );
}
// Demonic Empowerment -- voidwalker -- missing movement impairing effects immunity
else if ( GetId () == 54508 )
2009-03-03 22:26:26 +01:00
{
2009-05-19 18:33:49 +02:00
if ( apply )
m_target -> RemoveMovementImpairingAuras ();
2009-03-03 22:26:26 +01:00
2009-05-19 18:33:49 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , SPELL_AURA_MOD_ROOT , apply );
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , SPELL_AURA_MOD_DECREASE_SPEED , apply );
2009-03-03 22:26:26 +01:00
}
2009-06-06 22:11:33 +02:00
// Demonic Circle
else if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto -> SpellIconID == 3221 )
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
{
GameObject * obj = m_target -> GetGameObject ( 48018 );
if ( obj )
(( Player * ) m_target ) -> TeleportTo ( obj -> GetMapId (), obj -> GetPositionX (), obj -> GetPositionY (), obj -> GetPositionZ (), obj -> GetOrientation ());
}
}
2008-10-11 14:16:25 -05:00
}
2009-03-24 09:36:50 -06:00
//this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModEffectImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
// when removing flag aura, handle flag drop
if ( ! apply && m_target -> GetTypeId () == TYPEID_PLAYER
&& ( GetSpellProto () -> AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION ) )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
if ((( Player * ) m_target ) -> InBattleGround ())
{
2009-03-24 09:36:50 -06:00
if ( BattleGround * bg = (( Player * ) m_target ) -> GetBattleGround () )
bg -> EventPlayerDroppedFlag ((( Player * ) m_target ));
2008-10-11 14:16:25 -05:00
}
2008-10-14 11:57:03 -05:00
else
sOutdoorPvPMgr . HandleDropFlag (( Player * ) m_target , GetSpellProto () -> Id );
2008-10-11 14:16:25 -05:00
}
}
2009-04-06 13:31:14 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_EFFECT , GetMiscValue (), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModStateImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( apply && Real && GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY )
{
2009-04-07 22:00:32 +02:00
m_target -> RemoveAurasByType ( AuraType ( GetMiscValue ()), NULL , GetParentAura ());
2008-10-11 14:16:25 -05:00
}
2009-04-06 13:31:14 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_STATE , GetMiscValue (), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModSchoolImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( apply && GetMiscValue () == SPELL_SCHOOL_MASK_NORMAL )
2009-03-24 09:36:50 -06:00
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2009-02-04 10:33:18 -06:00
2009-04-06 13:31:14 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_SCHOOL , GetMiscValue (), apply );
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
// remove all flag auras (they are positive, but they must be removed when you are immune)
if ( this -> GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
&& this -> GetSpellProto () -> AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD )
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
// TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
if ( Real && apply
&& GetSpellProto () -> AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
&& IsPositiveSpell ( GetId ()) ) //Only positive immunity removes auras
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
uint32 school_mask = GetMiscValue ();
2009-03-24 09:36:50 -06:00
Unit :: AuraMap & Auras = m_target -> GetAuras ();
2009-04-07 22:00:32 +02:00
for ( Unit :: AuraMap :: iterator iter = Auras . begin (); iter != Auras . end ();)
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
SpellEntry const * spell = iter -> second -> GetSpellProto ();
if (( GetSpellSchoolMask ( spell ) & school_mask ) //Check for school mask
2009-04-25 18:53:29 +02:00
&& IsDispelableBySpell ( GetSpellProto (), spell -> Id , true )
2009-03-24 09:36:50 -06:00
&& ! iter -> second -> IsPositive () //Don't remove positive spells
&& spell -> Id != GetId () ) //Don't remove self
2008-10-11 14:16:25 -05:00
{
2009-04-07 22:00:32 +02:00
m_target -> RemoveAura ( iter );
2008-10-11 14:16:25 -05:00
}
2009-04-07 18:05:56 +02:00
else
++ iter ;
2008-10-11 14:16:25 -05:00
}
}
if ( Real && GetSpellProto () -> Mechanic == MECHANIC_BANISH )
{
if ( apply )
m_target -> addUnitState ( UNIT_STAT_ISOLATED );
else
m_target -> clearUnitState ( UNIT_STAT_ISOLATED );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModDmgImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplySpellImmune ( GetId (), IMMUNITY_DAMAGE , GetMiscValue (), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModDispelImmunity ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
if ( ! Real )
return ;
2009-04-06 13:31:14 +02:00
m_target -> ApplySpellDispelImmunity ( m_spellProto , DispelType ( GetMiscValue ()), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraProcTriggerSpell ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModStalked ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
if ( apply )
m_target -> SetFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
else
m_target -> RemoveFlag ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_TRACK_UNIT );
}
/*********************************************************/
/*** PERIODIC ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicTriggerSpell ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
m_isPeriodic = apply ;
2009-05-16 17:59:36 +02:00
if ( Real && m_spellProto -> Id == 66 && ! apply )
2009-02-17 14:52:46 -06:00
{
2009-04-07 20:27:34 +02:00
if ( GetParentAura () -> GetRemoveMode () == AURA_REMOVE_BY_EXPIRE )
2009-02-17 14:52:46 -06:00
m_target -> CastSpell ( m_target , 32612 , true , NULL , this );
}
2009-01-22 22:44:27 -06:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicTriggerSpellWithValue ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-22 22:44:27 -06:00
{
m_isPeriodic = apply ;
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicEnergize ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2009-01-24 11:28:00 -06:00
return ;
m_isPeriodic = apply ;
// Replenishment (0.25% from max)
// Infinite Replenishment
2009-03-08 21:29:00 +01:00
if ( m_spellProto -> SpellIconID == 3184 && m_spellProto -> SpellVisual [ 0 ] == 12495 )
2009-04-06 13:31:14 +02:00
m_amount = m_target -> GetMaxPower ( POWER_MANA ) * 25 / 10000 ;
2009-01-24 11:28:00 -06:00
}
2008-10-11 14:16:25 -05:00
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraPowerBurn ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-24 11:28:00 -06:00
{
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraPeriodicDummy ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-01-24 11:28:00 -06:00
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2009-01-24 11:28:00 -06:00
return ;
// For prevent double apply bonuses
bool loading = ( m_target -> GetTypeId () == TYPEID_PLAYER && (( Player * ) m_target ) -> GetSession () -> PlayerLoading ());
Unit * caster = GetCaster ();
SpellEntry const * spell = GetSpellProto ();
switch ( spell -> SpellFamilyName )
{
2009-06-06 22:11:33 +02:00
case SPELLFAMILY_WARLOCK :
{
switch ( spell -> Id )
{
// Demonic Circle
case 48018 :
if ( apply )
// set to false at initial cast to enable button at next enable in periodic handler
m_target -> SendAuraVisualForSelf ( false , 62388 );
else
{
// Do not remove GO when aura is removed by stack
// to prevent remove GO added by new spell
// old one is already removed
if ( GetParentAura () -> GetRemoveMode () != AURA_REMOVE_BY_STACK )
m_target -> RemoveGameObject ( spell -> Id , true );
m_target -> SendAuraVisualForSelf ( false , 62388 );
}
break ;
}
}
2009-01-24 11:28:00 -06:00
case SPELLFAMILY_HUNTER :
{
// Explosive Shot
if ( apply && ! loading && caster )
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( RANGED_ATTACK ) * 16 / 100 );
2009-01-24 11:28:00 -06:00
break ;
}
}
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
2009-01-24 11:28:00 -06:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicHeal ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-24 11:28:00 -06:00
{
m_isPeriodic = apply ;
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicDamage ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
m_isPeriodic = apply ;
// For prevent double apply bonuses
bool loading = ( m_target -> GetTypeId () == TYPEID_PLAYER && (( Player * ) m_target ) -> GetSession () -> PlayerLoading ());
2009-01-09 16:06:17 -06:00
// Custom damage calculation after
2009-01-24 11:28:00 -06:00
if ( ! apply || loading )
return ;
Unit * caster = GetCaster ();
if ( ! caster )
2009-01-09 16:06:17 -06:00
return ;
2008-10-11 14:16:25 -05:00
switch ( m_spellProto -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
{
// Pounce Bleed
2009-01-03 11:00:15 -06:00
if ( m_spellProto -> SpellIconID == 147 && m_spellProto -> SpellVisual [ 0 ] == 0 )
2008-10-11 14:16:25 -05:00
{
// $AP*0.18/6 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 3 / 100 );
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
case SPELLFAMILY_WARRIOR :
{
// Rend
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x20 )
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// $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 );
2009-04-06 13:31:14 +02:00
m_amount += int32 ((( mwb_min + mwb_max ) / 2 + ap * mws / 14000 ) * 0.2f );
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
case SPELLFAMILY_DRUID :
{
// Rake
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x1000 )
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// $AP*0.06 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 6 / 100 );
2008-10-11 14:16:25 -05:00
return ;
}
// Lacerate
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x0000000100 )
2008-10-11 14:16:25 -05:00
{
// $AP*0.05/5 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) / 100 );
2008-10-11 14:16:25 -05:00
return ;
}
// Rip
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x800000 )
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// 0.01*$AP*cp
if ( caster -> GetTypeId () != TYPEID_PLAYER )
return ;
2008-10-11 14:16:25 -05:00
2009-01-09 16:06:17 -06:00
uint8 cp = (( Player * ) caster ) -> GetComboPoints ();
// Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & dummyAuras = caster -> GetAurasByType ( SPELL_AURA_DUMMY );
for ( Unit :: AuraEffectList :: const_iterator itr = dummyAuras . begin (); itr != dummyAuras . end (); ++ itr )
2009-01-09 16:06:17 -06:00
{
if (( * itr ) -> GetId () == 34241 )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_amount += cp * ( * itr ) -> GetAmount ();
2009-01-09 16:06:17 -06:00
break ;
2008-10-11 14:16:25 -05:00
}
}
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * cp / 100 );
2009-01-09 16:06:17 -06:00
return ;
}
// Lock Jaw
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 1 ] & 0x10000000 )
2009-01-09 16:06:17 -06:00
{
// 0.15*$AP
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 15 / 100 );
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
case SPELLFAMILY_ROGUE :
{
// Rupture
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x100000 )
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
if ( caster -> GetTypeId () != TYPEID_PLAYER )
return ;
//1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
//2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
//3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
//4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
//5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
2009-05-04 17:32:39 -05:00
float AP_per_combo [ 6 ] = { 0.0f , 0.015f , 0.024f , 0.03f , 0.03428571f , 0.0375f };
2009-01-09 16:06:17 -06:00
uint8 cp = (( Player * ) caster ) -> GetComboPoints ();
if ( cp > 5 ) cp = 5 ;
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * AP_per_combo [ cp ]);
2008-10-11 14:16:25 -05:00
return ;
}
// Garrote
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x100 )
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// $AP*0.07 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 7 / 100 );
2009-01-09 16:06:17 -06:00
return ;
}
// Deadly Poison
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x10000 )
2009-01-09 16:06:17 -06:00
{
// 0.08*$AP / 4 * amount of stack
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 2 * GetParentAura () -> GetStackAmount () / 100 );
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
case SPELLFAMILY_HUNTER :
{
// Serpent Sting
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x4000 )
2008-10-11 14:16:25 -05:00
{
// $RAP*0.1/5 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( RANGED_ATTACK ) * 10 / 500 );
2008-10-11 14:16:25 -05:00
return ;
}
// Immolation Trap
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x4 && m_spellProto -> SpellIconID == 678 )
2008-10-11 14:16:25 -05:00
{
// $RAP*0.1/5 bonus per tick
2009-04-06 13:31:14 +02:00
m_amount += int32 ( caster -> GetTotalAttackPowerValue ( RANGED_ATTACK ) * 10 / 500 );
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
default :
break ;
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicDamagePCT ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicLeech ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicManaLeech ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-01-24 11:28:00 -06:00
m_isPeriodic = apply ;
}
2008-10-11 14:16:25 -05:00
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePeriodicHealthFunnel ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-24 11:28:00 -06:00
{
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
}
/*********************************************************/
/*** MODIFY STATS ***/
/*********************************************************/
/********************************/
/*** RESISTANCE ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModResistanceExclusive ( bool apply , bool Rea , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-04-06 13:31:14 +02:00
m_target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), GetParentAura () -> IsPositive (), m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModResistance ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER || (( Creature * ) m_target ) -> isPet ())
2009-04-06 13:31:14 +02:00
m_target -> ApplyResistanceBuffModsMod ( SpellSchools ( x ), GetParentAura () -> IsPositive (), m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModBaseResistancePCT ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only players have base stats
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
{
//pets only have base armor
2009-04-06 13:31:14 +02:00
if ((( Creature * ) m_target ) -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
m_target -> HandleStatModifier ( UNIT_MOD_ARMOR , BASE_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
else
{
for ( int8 x = SPELL_SCHOOL_NORMAL ; x < MAX_SPELL_SCHOOL ; x ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & int32 ( 1 << x ))
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + x ), BASE_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModResistancePercent ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
for ( int8 i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & int32 ( 1 << i ))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER || (( Creature * ) m_target ) -> isPet ())
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), true , m_amount , apply );
m_target -> ApplyResistanceBuffModsPercentMod ( SpellSchools ( i ), false , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModBaseResistance ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// only players have base stats
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
{
//only pets have base stats
2009-04-06 13:31:14 +02:00
if ((( Creature * ) m_target ) -> isPet () && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
m_target -> HandleStatModifier ( UNIT_MOD_ARMOR , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
else
{
for ( int i = SPELL_SCHOOL_NORMAL ; i < MAX_SPELL_SCHOOL ; i ++ )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << i ))
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_RESISTANCE_START + i ), TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
}
/********************************/
/*** STAT ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModStat ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < - 2 || GetMiscValue () > 4 )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
sLog . outError ( "WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT " , GetId (), GetEffIndex (), GetMiscValue ());
2008-10-11 14:16:25 -05:00
return ;
}
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
// -1 or -2 is all stats ( misc < -2 checked in function beginning )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < 0 || GetMiscValue () == i )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
//m_target->ApplyStatMod(Stats(i), m_amount,apply);
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER || (( Creature * ) m_target ) -> isPet ())
2009-04-06 13:31:14 +02:00
m_target -> ApplyStatBuffMod ( Stats ( i ), m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPercentStat ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
2008-10-11 14:16:25 -05:00
{
sLog . outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
}
// only players have base stats
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; ++ i )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), BASE_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellDamagePercentFromStat ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
(( Player * ) m_target ) -> UpdateSpellDamageAndHealingBonus ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellHealingPercentFromStat ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Recalculate bonus
(( Player * ) m_target ) -> UpdateSpellDamageAndHealingBonus ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellDamagePercentFromAttackPower ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// This information for client side use only
// Recalculate bonus
(( Player * ) m_target ) -> UpdateSpellDamageAndHealingBonus ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellHealingPercentFromAttackPower ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Recalculate bonus
(( Player * ) m_target ) -> UpdateSpellDamageAndHealingBonus ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModHealingDone ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// implemented in Unit::SpellHealingBonus
// this information is for client side only
(( Player * ) m_target ) -> UpdateSpellDamageAndHealingBonus ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModTotalPercentStat ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < - 1 || GetMiscValue () > 4 )
2008-10-11 14:16:25 -05:00
{
sLog . outError ( "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid" );
return ;
}
//save current and max HP before applying aura
uint32 curHPValue = m_target -> GetHealth ();
uint32 maxHPValue = m_target -> GetMaxHealth ();
for ( int32 i = STAT_STRENGTH ; i < MAX_STATS ; i ++ )
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == i || GetMiscValue () == - 1 )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UnitMods ( UNIT_MOD_STAT_START + i ), TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER || (( Creature * ) m_target ) -> isPet ())
2009-04-06 13:31:14 +02:00
m_target -> ApplyStatPercentBuffMod ( Stats ( i ), m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
//recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () == STAT_STAMINA ) && ( maxHPValue > 0 ) && ( m_spellProto -> Attributes & 0x10 ))
2008-10-11 14:16:25 -05:00
{
// newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
uint32 newHPValue = ( m_target -> GetMaxHealth () * curHPValue ) / maxHPValue ;
m_target -> SetHealth ( newHPValue );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModResistenceOfStatPercent ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () != SPELL_SCHOOL_MASK_NORMAL )
2008-10-11 14:16:25 -05:00
{
2008-11-14 16:28:45 -06:00
// support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
2008-10-11 14:16:25 -05:00
// and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
2008-11-14 16:28:45 -06:00
sLog . outError ( "Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistances!" );
2008-10-11 14:16:25 -05:00
return ;
}
// Recalculate Armor
m_target -> UpdateArmor ();
}
/********************************/
/*** HEAL & ENERGIZE ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModTotalHealthPercentRegen ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModTotalEnergyPercentRegen ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( m_amplitude == 0 )
m_amplitude = 1000 ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
m_periodicTimer = m_amplitude ;
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModRegen ( bool apply , bool Real , bool /*changeAmount*/ ) // eating
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
if ( m_amplitude == 0 )
m_amplitude = 5000 ;
2008-10-11 14:16:25 -05:00
2009-01-24 11:28:00 -06:00
m_periodicTimer = 5000 ;
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPowerRegen ( bool apply , bool Real , bool changeAmount ) // drinking
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2009-01-24 11:28:00 -06:00
return ;
2008-10-11 14:16:25 -05:00
2009-01-24 11:28:00 -06:00
Powers pt = m_target -> getPowerType ();
2009-04-06 13:31:14 +02:00
if ( m_amplitude == 0 )
2008-10-11 14:16:25 -05:00
{
2009-02-13 20:05:16 -06:00
// Anger Management (only spell use this aura for rage)
2009-01-24 11:28:00 -06:00
if ( pt == POWER_RAGE )
2009-04-06 13:31:14 +02:00
m_amplitude = 3000 ;
2009-01-24 11:28:00 -06:00
else
2009-04-06 13:31:14 +02:00
m_amplitude = 2000 ;
2009-01-24 11:28:00 -06:00
}
2008-10-11 14:16:25 -05:00
2009-01-24 11:28:00 -06:00
m_periodicTimer = 5000 ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER && GetMiscValue () == POWER_MANA )
2009-01-24 11:28:00 -06:00
(( Player * ) m_target ) -> UpdateManaRegen ();
2008-10-11 14:16:25 -05:00
m_isPeriodic = apply ;
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPowerRegenPCT ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Update manaregen value
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == POWER_MANA )
2008-10-11 14:16:25 -05:00
(( Player * ) m_target ) -> UpdateManaRegen ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModManaRegen ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
//Note: an increase in regen does NOT cause threat.
(( Player * ) m_target ) -> UpdateManaRegen ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleComprehendLanguage ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( apply )
m_target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
else
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_COMPREHEND_LANG );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseHealth ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( Real || changeAmount )
2008-10-11 14:16:25 -05:00
{
2008-11-04 09:23:06 -06:00
if ( apply )
2008-10-11 14:16:25 -05:00
{
2009-06-03 17:29:29 +02:00
// Vampiric Blood
if ( GetSpellProto () -> Id == 55233 )
m_amount = m_target -> GetMaxHealth () * m_amount / 100 ;
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( m_amount ), apply );
m_target -> ModifyHealth ( m_amount );
2008-11-04 09:23:06 -06:00
}
else
{
2009-04-06 13:31:14 +02:00
if ( int32 ( m_target -> GetHealth ()) > m_amount )
m_target -> ModifyHealth ( - m_amount );
2008-11-04 09:23:06 -06:00
else
m_target -> SetHealth ( 1 );
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseMaxHealth ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
uint32 oldhealth = m_target -> GetHealth ();
double healthPercentage = ( double ) oldhealth / ( double ) m_target -> GetMaxHealth ();
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
// refresh percentage
if ( oldhealth > 0 )
{
uint32 newhealth = uint32 ( ceil (( double ) m_target -> GetMaxHealth () * healthPercentage ));
if ( newhealth == 0 )
newhealth = 1 ;
m_target -> SetHealth ( newhealth );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseEnergy ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
Powers powerType = m_target -> getPowerType ();
2009-04-06 13:31:14 +02:00
if ( int32 ( powerType ) != GetMiscValue ())
2008-10-11 14:16:25 -05:00
return ;
2008-12-12 11:21:28 -06:00
UnitMods unitMod = UnitMods ( UNIT_MOD_POWER_START + powerType );
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( unitMod , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseEnergyPercent ( bool apply , bool /*Real*/ , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
Powers powerType = m_target -> getPowerType ();
2009-04-06 13:31:14 +02:00
if ( int32 ( powerType ) != GetMiscValue ())
2008-10-11 14:16:25 -05:00
return ;
2008-12-12 11:21:28 -06:00
UnitMods unitMod = UnitMods ( UNIT_MOD_POWER_START + powerType );
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( unitMod , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModIncreaseHealthPercent ( bool apply , bool /*Real*/ , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_HEALTH , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraIncreaseBaseHealthPercent ( bool apply , bool /*Real*/ , bool /*changeAmount*/ )
2008-12-24 09:58:26 -06:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_HEALTH , BASE_PCT , float ( m_amount ), apply );
2008-12-24 09:58:26 -06:00
}
2008-10-11 14:16:25 -05:00
/********************************/
/*** FIGHT ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModParryPercent ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
(( Player * ) m_target ) -> UpdateParryPercentage ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModDodgePercent ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
(( Player * ) m_target ) -> UpdateDodgePercentage ();
2009-04-06 13:31:14 +02:00
//sLog.outError("BONUS DODGE CHANCE: + %f", float(m_amount));
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModBlockPercent ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
(( Player * ) m_target ) -> UpdateBlockPercentage ();
2009-04-06 13:31:14 +02:00
//sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_amount));
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRegenInterrupt ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
(( Player * ) m_target ) -> UpdateManaRegen ();
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModCritPercent ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// apply item specific bonuses for already equipped weapon
2009-05-16 17:59:36 +02:00
if ( Real || changeAmount )
2008-10-11 14:16:25 -05:00
{
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
if ( Item * pItem = (( Player * ) m_target ) -> GetWeaponForAttack ( WeaponAttackType ( i )))
(( Player * ) m_target ) -> _ApplyWeaponDependentAuraCritMod ( pItem , WeaponAttackType ( i ), this , apply );
}
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
2009-04-06 13:31:14 +02:00
// GetMiscValue() comparison with item generated damage types
2008-10-11 14:16:25 -05:00
if ( GetSpellProto () -> EquippedItemClass == - 1 )
{
2009-04-06 13:31:14 +02:00
(( Player * ) m_target ) -> HandleBaseModValue ( CRIT_PERCENTAGE , FLAT_MOD , float ( m_amount ), apply );
(( Player * ) m_target ) -> HandleBaseModValue ( OFFHAND_CRIT_PERCENTAGE , FLAT_MOD , float ( m_amount ), apply );
(( Player * ) m_target ) -> HandleBaseModValue ( RANGED_CRIT_PERCENTAGE , FLAT_MOD , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModHitChance ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
(( Player * ) m_target ) -> UpdateMeleeHitChances ();
(( Player * ) m_target ) -> UpdateRangedHitChances ();
}
else
{
2009-04-06 13:31:14 +02:00
m_target -> m_modMeleeHitChance += apply ? m_amount : ( - m_amount );
m_target -> m_modRangedHitChance += apply ? m_amount : ( - m_amount );
2008-12-24 09:58:26 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellHitChance ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
(( Player * ) m_target ) -> UpdateSpellHitChances ();
}
else
{
2009-04-06 13:31:14 +02:00
m_target -> m_modSpellHitChance += apply ? m_amount : ( - m_amount );
2008-12-24 09:58:26 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellCritChance ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
(( Player * ) m_target ) -> UpdateAllSpellCritChances ();
}
else
{
2009-04-06 13:31:14 +02:00
m_target -> m_baseSpellCritChance += apply ? m_amount : - m_amount ;
2008-10-11 14:16:25 -05:00
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModSpellCritChanceShool ( bool /*apply*/ , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( int school = SPELL_SCHOOL_NORMAL ; school < MAX_SPELL_SCHOOL ; ++ school )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << school ))
2008-10-11 14:16:25 -05:00
(( Player * ) m_target ) -> UpdateSpellCritChance ( school );
}
/********************************/
/*** ATTACK SPEED ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModCastingSpeed ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyCastTimePercentMod ( m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModMeleeRangedSpeedPct ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyAttackTimePercentMod ( BASE_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( OFF_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModCombatSpeedPct ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyCastTimePercentMod ( m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( BASE_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( OFF_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModAttackSpeed ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! m_target -> isAlive () )
return ;
2009-04-06 13:31:14 +02:00
m_target -> ApplyAttackTimePercentMod ( BASE_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleHaste ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyAttackTimePercentMod ( BASE_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( OFF_ATTACK , m_amount , apply );
m_target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRangedHaste ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleRangedAmmoHaste ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-04-06 13:31:14 +02:00
m_target -> ApplyAttackTimePercentMod ( RANGED_ATTACK , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
/********************************/
/*** ATTACK POWER ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModAttackPower ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRangedAttackPower ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if (( m_target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
return ;
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER_RANGED , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModAttackPowerPercent ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRangedAttackPowerPercent ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if (( m_target -> getClassMask () & CLASSMASK_WAND_USERS ) != 0 )
return ;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_ATTACK_POWER_RANGED , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRangedAttackPowerOfStatPercent ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
2008-12-24 09:58:26 -06:00
// Recalculate bonus
2009-01-04 09:54:21 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER && ! ( m_target -> getClassMask () & CLASSMASK_WAND_USERS ))
(( Player * ) m_target ) -> UpdateAttackPowerAndDamage ( true );
2008-12-24 09:58:26 -06:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModAttackPowerOfStatPercent ( bool apply , bool Real , bool changeAmount )
2008-12-24 09:58:26 -06:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-12-24 09:58:26 -06:00
return ;
2008-10-11 14:16:25 -05:00
// Recalculate bonus
2009-01-04 09:54:21 -06:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
(( Player * ) m_target ) -> UpdateAttackPowerAndDamage ( false );
2008-10-11 14:16:25 -05:00
}
/********************************/
/*** DAMAGE BONUS ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModDamageDone ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// apply item specific bonuses for already equipped weapon
2009-05-16 17:59:36 +02:00
if (( Real || changeAmount ) && m_target -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
if ( Item * pItem = (( Player * ) m_target ) -> GetWeaponForAttack ( WeaponAttackType ( i )))
(( Player * ) m_target ) -> _ApplyWeaponDependentAuraDamageMod ( pItem , WeaponAttackType ( i ), this , apply );
}
2009-04-06 13:31:14 +02:00
// GetMiscValue() is bitmask of spell schools
2008-10-11 14:16:25 -05:00
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
// 127 - full bitmask any damages
//
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
2009-04-06 13:31:14 +02:00
// GetMiscValue() comparison with item generated damage types
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ) != 0 )
2008-10-11 14:16:25 -05:00
{
// apply generic physical damage bonuses including wand case
if ( GetSpellProto () -> EquippedItemClass == - 1 || m_target -> GetTypeId () != TYPEID_PLAYER )
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_MAINHAND , TOTAL_VALUE , float ( m_amount ), apply );
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_VALUE , float ( m_amount ), apply );
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_RANGED , TOTAL_VALUE , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> IsPositive ())
m_target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS , m_amount , apply );
2008-10-11 14:16:25 -05:00
else
2009-04-06 13:31:14 +02:00
m_target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
// Skip non magic case for speedup
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_MAGIC ) == 0 )
2008-10-11 14:16:25 -05:00
return ;
if ( GetSpellProto () -> EquippedItemClass != - 1 || GetSpellProto () -> EquippedItemInventoryTypeMask != 0 )
{
// 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
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> IsPositive ())
2008-10-11 14:16:25 -05:00
{
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & ( 1 << i )) != 0 )
m_target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
else
{
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; i ++ )
{
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & ( 1 << i )) != 0 )
m_target -> ApplyModUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
}
2009-03-27 22:47:28 -06:00
Pet * pet = (( Player * ) m_target ) -> GetPet ();
2008-10-11 14:16:25 -05:00
if ( pet )
pet -> UpdateAttackPowerAndDamage ();
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModDamagePercentDone ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
sLog . outDebug ( "AURA MOD DAMAGE type:%u negative:%u" , GetMiscValue (), GetParentAura () -> IsPositive () ? 0 : 1 );
2008-10-11 14:16:25 -05:00
// apply item specific bonuses for already equipped weapon
2009-05-16 17:59:36 +02:00
if (( Real || changeAmount ) && m_target -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
for ( int i = 0 ; i < MAX_ATTACK ; ++ i )
if ( Item * pItem = (( Player * ) m_target ) -> GetWeaponForAttack ( WeaponAttackType ( i )))
(( Player * ) m_target ) -> _ApplyWeaponDependentAuraDamageMod ( pItem , WeaponAttackType ( i ), this , apply );
}
2009-04-06 13:31:14 +02:00
// GetMiscValue() is bitmask of spell schools
2008-10-11 14:16:25 -05:00
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 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
2009-04-06 13:31:14 +02:00
// GetMiscValue() comparison with item generated damage types
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ) != 0 )
2008-10-11 14:16:25 -05:00
{
// apply generic physical damage bonuses including wand case
if ( GetSpellProto () -> EquippedItemClass == - 1 || m_target -> GetTypeId () != TYPEID_PLAYER )
{
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_MAINHAND , TOTAL_PCT , float ( m_amount ), apply );
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_PCT , float ( m_amount ), apply );
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_RANGED , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
else
{
// done in Player::_ApplyWeaponDependentAuraMods
}
// For show in client
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-04-06 13:31:14 +02:00
m_target -> ApplyModSignedFloatValue ( PLAYER_FIELD_MOD_DAMAGE_DONE_PCT , m_amount / 100.0f , apply );
2008-10-11 14:16:25 -05:00
}
// Skip non magic case for speedup
2009-04-06 13:31:14 +02:00
if (( GetMiscValue () & SPELL_SCHOOL_MASK_MAGIC ) == 0 )
2008-10-11 14:16:25 -05:00
return ;
if ( GetSpellProto () -> EquippedItemClass != - 1 || GetSpellProto () -> EquippedItemInventoryTypeMask != 0 )
{
// 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
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
for ( int i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; ++ i )
2009-04-06 13:31:14 +02:00
m_target -> ApplyModSignedFloatValue ( PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i , m_amount / 100.0f , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModOffhandDamagePercent ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
sLog . outDebug ( "AURA MOD OFFHAND DAMAGE" );
2009-04-06 13:31:14 +02:00
m_target -> HandleStatModifier ( UNIT_MOD_DAMAGE_OFFHAND , TOTAL_PCT , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
/********************************/
/*** POWER COST ***/
/********************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPowerCostPCT ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
2009-04-06 13:31:14 +02:00
float amount = m_amount / 100.0f ;
2008-10-11 14:16:25 -05:00
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << i ))
2008-10-11 14:16:25 -05:00
m_target -> ApplyModSignedFloatValue ( UNIT_FIELD_POWER_COST_MULTIPLIER + i , amount , apply );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPowerCost ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
for ( int i = 0 ; i < MAX_SPELL_SCHOOL ; ++ i )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << i ))
m_target -> ApplyModInt32Value ( UNIT_FIELD_POWER_COST_MODIFIER + i , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleNoReagentUseAura ( bool Apply , bool Real , bool /*changeAmount*/ )
2008-12-24 09:58:26 -06:00
{
// spells required only Real aura add/remove
if ( ! Real )
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-02-02 17:01:56 +01:00
flag96 mask ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & noReagent = m_target -> GetAurasByType ( SPELL_AURA_NO_REAGENT_USE );
for ( Unit :: AuraEffectList :: const_iterator i = noReagent . begin (); i != noReagent . end (); ++ i )
2009-02-02 17:42:05 +01:00
mask |= ( * i ) -> m_spellProto -> EffectSpellClassMask [( * i ) -> m_effIndex ];
2008-12-24 09:58:26 -06:00
m_target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 , mask [ 0 ]);
m_target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 + 1 , mask [ 1 ]);
m_target -> SetUInt32Value ( PLAYER_NO_REAGENT_COST_1 + 2 , mask [ 2 ]);
}
2008-10-11 14:16:25 -05:00
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraAllowOnlyAbility ( bool apply , bool Real , bool /*changeAmount*/ )
2009-02-05 13:38:48 +01:00
{
if ( ! Real )
return ;
if ( ! apply && m_target -> HasAuraType ( SPELL_AURA_ALLOW_ONLY_ABILITY ))
return ;
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
if ( apply )
m_target -> SetFlag ( PLAYER_FLAGS , PLAYER_ALLOW_ONLY_ABILITY );
else
m_target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_ALLOW_ONLY_ABILITY );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraEmpathy ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real || m_target -> GetTypeId () != TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
return ;
CreatureInfo const * ci = objmgr . GetCreatureTemplate ( m_target -> GetEntry ());
if ( ci && ci -> type == CREATURE_TYPE_BEAST )
m_target -> ApplyModUInt32Value ( UNIT_DYNAMIC_FLAGS , UNIT_DYNFLAG_SPECIALINFO , apply );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraUntrackable ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real )
return ;
2008-10-11 14:16:25 -05:00
if ( apply )
2009-01-31 14:41:36 -06:00
m_target -> SetByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
2008-10-11 14:16:25 -05:00
else
2009-01-31 14:41:36 -06:00
m_target -> RemoveByteFlag ( UNIT_FIELD_BYTES_1 , 3 , UNIT_BYTE1_FLAG_UNTRACKABLE );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModPacify ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real || m_target -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
if ( apply )
m_target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
else
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PACIFIED );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModPacifyAndSilence ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( m_spellProto -> Id == 45839 )
{
if ( apply )
m_target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
else
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
}
HandleAuraModPacify ( apply , Real , changeAmount );
HandleAuraModSilence ( apply , Real , changeAmount );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraGhost ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real || m_target -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
if ( apply )
{
m_target -> SetFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
}
else
{
m_target -> RemoveFlag ( PLAYER_FLAGS , PLAYER_FLAGS_GHOST );
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraAllowFlight ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// all applied/removed only at real aura add/remove
if ( ! Real )
return ;
// allow fly
WorldPacket data ;
if ( apply )
2009-03-14 19:32:34 -06:00
{
2008-10-11 14:16:25 -05:00
data . Initialize ( SMSG_MOVE_SET_CAN_FLY , 12 );
2009-03-23 15:26:13 -06:00
if ( m_target -> GetTypeId () == TYPEID_UNIT )
{
m_target -> SetByteFlag ( UNIT_FIELD_BYTES_1 , 3 , 0x02 );
m_target -> AddUnitMovementFlag ( MOVEMENTFLAG_FLYING2 );
}
2009-03-14 19:32:34 -06:00
}
2008-10-11 14:16:25 -05:00
else
2009-03-14 19:32:34 -06:00
{
2008-10-11 14:16:25 -05:00
data . Initialize ( SMSG_MOVE_UNSET_CAN_FLY , 12 );
2009-03-23 15:26:13 -06:00
if ( m_target -> GetTypeId () == TYPEID_UNIT )
{
m_target -> RemoveByteFlag ( UNIT_FIELD_BYTES_1 , 3 , 0x02 );
m_target -> RemoveUnitMovementFlag ( MOVEMENTFLAG_FLYING2 );
}
2009-03-14 19:32:34 -06:00
}
2008-10-11 14:16:25 -05:00
data . append ( m_target -> GetPackGUID ());
data << uint32 ( 0 ); // unk
m_target -> SendMessageToSet ( & data , true );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModRating ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << rating ))
(( Player * ) m_target ) -> ApplyRatingMod ( CombatRating ( rating ), m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModRatingFromStat ( bool apply , bool Real , bool changeAmount )
2008-12-24 09:58:26 -06:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-12-24 09:58:26 -06:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
// Just recalculate ratings
for ( uint32 rating = 0 ; rating < MAX_COMBAT_RATING ; ++ rating )
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () & ( 1 << rating ))
2008-12-24 09:58:26 -06:00
(( Player * ) m_target ) -> ApplyRatingMod ( CombatRating ( rating ), 0 , apply );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleForceMoveForward ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real || m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
m_target -> SetFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
else
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS_2 , UNIT_FLAG2_FORCE_MOVE );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModExpertise ( bool /*apply*/ , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
(( Player * ) m_target ) -> UpdateExpertise ( BASE_ATTACK );
(( Player * ) m_target ) -> UpdateExpertise ( OFF_ATTACK );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModTargetResistance ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
// applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
// show armor penetration
2009-04-06 13:31:14 +02:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_NORMAL ))
m_target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE , m_amount , apply );
2008-10-11 14:16:25 -05:00
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
2009-04-06 13:31:14 +02:00
if ( m_target -> GetTypeId () == TYPEID_PLAYER && ( GetMiscValue () & SPELL_SCHOOL_MASK_SPELL ) == SPELL_SCHOOL_MASK_SPELL )
m_target -> ApplyModInt32Value ( PLAYER_FIELD_MOD_TARGET_RESISTANCE , m_amount , apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleShieldBlockValue ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
BaseModType modType = FLAT_MOD ;
2009-04-06 13:31:14 +02:00
if ( m_auraName == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT )
2008-10-11 14:16:25 -05:00
modType = PCT_MOD ;
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-04-06 13:31:14 +02:00
(( Player * ) m_target ) -> HandleBaseModValue ( SHIELD_BLOCK_VALUE , modType , float ( m_amount ), apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraRetainComboPoints ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * target = ( Player * ) m_target ;
// 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)
2009-04-06 13:31:14 +02:00
if ( ! apply && GetParentAura () -> GetAuraDuration () == 0 && target -> GetComboTarget ())
2008-10-11 14:16:25 -05:00
if ( Unit * unit = ObjectAccessor :: GetUnit ( * m_target , target -> GetComboTarget ()))
2009-04-06 13:31:14 +02:00
target -> AddComboPoints ( unit , - m_amount );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModUnattackable ( bool Apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:36:50 -06:00
if ( ! Real )
return ;
if ( Apply )
2008-11-11 17:49:51 -06:00
{
2008-10-11 14:16:25 -05:00
m_target -> CombatStop ();
2009-03-24 09:36:50 -06:00
m_target -> RemoveAurasWithInterruptFlags ( AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION );
2008-11-11 17:49:51 -06:00
}
2008-10-11 14:16:25 -05:00
2009-03-24 09:36:50 -06:00
m_target -> ApplyModFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE , Apply );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleSpiritOfRedemption ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
// spells required only Real aura add/remove
if ( ! Real )
return ;
// prepare spirit state
if ( apply )
{
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
{
// disable breath/etc timers
(( Player * ) m_target ) -> StopMirrorTimers ();
// set stand state (expected in this form)
if ( ! m_target -> IsStandState ())
2009-01-31 14:41:36 -06:00
m_target -> SetStandState ( UNIT_STAND_STATE_STAND );
2008-10-11 14:16:25 -05:00
}
m_target -> SetHealth ( 1 );
}
// die at aura end
else
2008-12-05 23:31:45 -06:00
m_target -> setDeathState ( JUST_DIED );
2008-10-11 14:16:25 -05:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleSchoolAbsorb ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
// prevent double apply bonuses
if ( apply && ( m_target -> GetTypeId () != TYPEID_PLAYER || ! (( Player * ) m_target ) -> GetSession () -> PlayerLoading ()))
{
if ( Unit * caster = GetCaster ())
{
float DoneActualBenefit = 0.0f ;
switch ( m_spellProto -> SpellFamilyName )
{
case SPELLFAMILY_PRIEST :
2009-05-05 03:54:15 +02:00
// PW: S
if ( m_spellProto -> SpellFamilyFlags . IsEqual ( 0x1 , 0 , 0x400 ))
2008-10-11 14:16:25 -05:00
{
2009-05-05 03:54:15 +02:00
// +80.68% from sp bonus
DoneActualBenefit = caster -> SpellBaseHealingBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.8068f ;
2008-10-11 14:16:25 -05:00
}
break ;
case SPELLFAMILY_MAGE :
2009-05-05 03:54:15 +02:00
// ice barrier
if ( m_spellProto -> SpellFamilyFlags . IsEqual ( 0 , 0x1 , 0x8 ))
{
// +80.67% from sp bonus
DoneActualBenefit = caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.8067f ;
}
/*
TODO: find the correct spell power coefficient for frost ward and fire ward (if has)
// frost ward, fire ward
else if(m_spellProto->SpellFamilyFlags.IsEqual(0x100, 0, 0x8) || m_spellProto->SpellFamilyFlags.IsEqual(0x8, 0, 0x8))
2008-10-11 14:16:25 -05:00
{
//+10% from +spd bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
}
2009-05-05 03:54:15 +02:00
*/
2008-10-11 14:16:25 -05:00
break ;
case SPELLFAMILY_WARLOCK :
2009-05-05 03:54:15 +02:00
// shadow ward
if ( m_spellProto -> SpellFamilyFlags . IsEqual ( 0 , 0 , 0x40 ))
2008-10-11 14:16:25 -05:00
{
2009-05-05 03:54:15 +02:00
// +30% from sp bonus
DoneActualBenefit = caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.3f ;
2008-10-11 14:16:25 -05:00
}
break ;
default :
break ;
}
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellProto ());
2009-04-06 13:31:14 +02:00
m_amount += ( int32 ) DoneActualBenefit ;
2008-10-11 14:16:25 -05:00
}
}
}
2009-04-06 13:31:14 +02:00
void AuraEffect :: PeriodicTick ()
2008-10-11 14:16:25 -05:00
{
if ( ! m_target -> isAlive ())
return ;
2009-04-06 13:31:14 +02:00
switch ( GetAuraName ())
2008-10-11 14:16:25 -05:00
{
case SPELL_AURA_PERIODIC_DAMAGE :
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT :
{
Unit * pCaster = GetCaster ();
if ( ! pCaster )
return ;
2009-05-09 22:31:53 -05:00
// Consecrate ticks can miss and will not show up in the combat log
2008-10-11 14:16:25 -05:00
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
pCaster -> SpellHitResult ( m_target , GetSpellProto (), false ) != SPELL_MISS_NONE )
return ;
// Check for immune (not use charges)
2009-04-25 18:53:29 +02:00
if ( m_target -> IsImmunedToDamage ( GetSpellProto ()))
2008-10-11 14:16:25 -05:00
return ;
// some auras remove at specific health level or more
2009-04-06 13:31:14 +02:00
if ( m_auraName == SPELL_AURA_PERIODIC_DAMAGE )
2008-10-11 14:16:25 -05:00
{
switch ( GetId ())
{
case 43093 : case 31956 : case 38801 :
case 35321 : case 38363 : case 39215 :
if ( m_target -> GetHealth () == m_target -> GetMaxHealth () )
{
m_target -> RemoveAurasDueToSpell ( GetId ());
return ;
}
break ;
case 38772 :
{
uint32 percent =
GetEffIndex () < 2 && GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_DUMMY ?
pCaster -> CalculateSpellDamage ( GetSpellProto (), GetEffIndex () + 1 , GetSpellProto () -> EffectBasePoints [ GetEffIndex () + 1 ], m_target ) :
100 ;
if ( m_target -> GetHealth () * 100 >= m_target -> GetMaxHealth () * percent )
{
2009-04-07 20:27:34 +02:00
m_target -> RemoveAurasDueToSpell ( GetId ());
2008-10-11 14:16:25 -05:00
return ;
}
break ;
}
2008-10-18 16:25:58 -05:00
case 41337 : // aura of anger
2009-02-04 10:33:18 -06:00
{
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & mMod = m_target -> GetAurasByType ( SPELL_AURA_MOD_DAMAGE_PERCENT_DONE );
for ( Unit :: AuraEffectList :: const_iterator i = mMod . begin (); i != mMod . end (); ++ i )
2008-10-18 16:25:58 -05:00
{
if (( * i ) -> GetId () == 41337 )
{
( * i ) -> ApplyModifier ( false );
2009-04-06 13:31:14 +02:00
( * i ) -> SetAmount (( * i ) -> GetAmount () + 5 );
2008-10-18 16:25:58 -05:00
( * i ) -> ApplyModifier ( true );
break ;
}
2009-02-04 10:33:18 -06:00
}
2009-04-15 12:05:59 -05:00
m_amount = 100 * m_tickNumber ;
2009-05-09 22:31:53 -05:00
break ;
}
2008-10-11 14:16:25 -05:00
default :
break ;
}
}
uint32 absorb = 0 ;
uint32 resist = 0 ;
CleanDamage cleanDamage = CleanDamage ( 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
// ignore non positive values (can be result apply spellmods to aura damage
2009-01-29 19:33:39 -06:00
//uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
2009-04-06 13:31:14 +02:00
uint32 pdamage = GetAmount () > 0 ? GetAmount () : 0 ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if ( GetAuraName () == SPELL_AURA_PERIODIC_DAMAGE )
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
pdamage = pCaster -> SpellDamageBonus ( m_target , GetSpellProto (), pdamage , DOT , GetParentAura () -> GetStackAmount ());
2008-10-11 14:16:25 -05:00
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
if ( GetSpellSchoolMask ( GetSpellProto ()) & SPELL_SCHOOL_MASK_NORMAL &&
GetEffectMechanic ( GetSpellProto (), m_effIndex ) != MECHANIC_BLEED )
{
2009-02-02 22:31:11 +01:00
uint32 pdamageReductedArmor = pCaster -> CalcArmorReducedDamage ( m_target , pdamage , GetSpellProto ());
2008-10-11 14:16:25 -05:00
cleanDamage . damage += pdamage - pdamageReductedArmor ;
pdamage = pdamageReductedArmor ;
}
// Curse of Agony damage-per-tick calculation
2009-02-02 17:01:56 +01:00
if ( GetSpellProto () -> SpellFamilyName == SPELLFAMILY_WARLOCK && ( GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x400 ) && GetSpellProto () -> SpellIconID == 544 )
2008-10-11 14:16:25 -05:00
{
2009-04-15 12:05:59 -05:00
uint32 totalTick = GetParentAura () -> GetAuraMaxDuration () / m_amplitude ;
2008-10-11 14:16:25 -05:00
// 1..4 ticks, 1/2 from normal tick damage
2009-04-13 18:15:26 -05:00
if ( m_tickNumber <= totalTick / 3 )
2008-10-11 14:16:25 -05:00
pdamage = pdamage / 2 ;
// 9..12 ticks, 3/2 from normal tick damage
2009-04-13 18:15:26 -05:00
else if ( m_tickNumber > totalTick * 2 / 3 )
2008-10-11 14:16:25 -05:00
pdamage += ( pdamage + 1 ) / 2 ; // +1 prevent 0.5 damage possible lost at 1..4 ticks
// 5..8 ticks have normal tick damage
}
}
else
2009-01-29 20:43:59 -06:00
pdamage = uint32 ( m_target -> GetMaxHealth () * pdamage / 100 );
2008-10-11 14:16:25 -05:00
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
pdamage -= (( Player * ) m_target ) -> GetDotDamageReduction ( pdamage );
2009-02-03 20:42:43 +01:00
pCaster -> CalcAbsorbResist ( m_target , GetSpellSchoolMask ( GetSpellProto ()), DOT , pdamage , & absorb , & resist , m_spellProto );
2008-10-11 14:16:25 -05:00
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u" ,
2008-11-10 09:04:23 -06:00
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), pdamage , GetId (), absorb );
2008-10-11 14:16:25 -05:00
2009-05-08 19:20:28 -05:00
pCaster -> DealDamageMods ( m_target , pdamage , & absorb );
2009-05-31 15:56:51 -05:00
SpellPeriodicAuraLogInfo pInfo ( this , pdamage , 0 , absorb , resist , 0.0f );
m_target -> SendPeriodicAuraLog ( & pInfo );
2008-10-11 14:16:25 -05:00
Unit * target = m_target ; // aura can be deleted in DealDamage
SpellEntry const * spellProto = GetSpellProto ();
2008-11-26 15:14:03 -06:00
// Set trigger flag
2009-05-15 16:59:27 +02:00
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_INTERNAL_DOT | PROC_EX_NORMAL_HIT ;
2008-11-26 15:14:03 -06:00
pdamage = ( pdamage <= absorb + resist ) ? 0 : ( pdamage - absorb - resist );
if ( pdamage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
2009-05-15 16:59:27 +02:00
pCaster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , pdamage , BASE_ATTACK , spellProto );
2008-10-11 14:16:25 -05:00
2008-11-26 15:14:03 -06:00
pCaster -> DealDamage ( target , pdamage , & cleanDamage , DOT , GetSpellSchoolMask ( spellProto ), spellProto , true );
2008-10-11 14:16:25 -05:00
break ;
}
case SPELL_AURA_PERIODIC_LEECH :
2009-01-24 11:28:00 -06:00
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL :
2008-10-11 14:16:25 -05:00
{
Unit * pCaster = GetCaster ();
if ( ! pCaster )
return ;
if ( ! pCaster -> isAlive ())
return ;
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
pCaster -> SpellHitResult ( m_target , GetSpellProto (), false ) != SPELL_MISS_NONE )
return ;
2009-01-24 11:28:00 -06:00
// Check for immune
2009-04-25 18:53:29 +02:00
if ( m_target -> IsImmunedToDamage ( GetSpellProto ()))
2008-10-11 14:16:25 -05:00
return ;
uint32 absorb = 0 ;
uint32 resist = 0 ;
CleanDamage cleanDamage = CleanDamage ( 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2009-01-29 19:33:39 -06:00
//uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
2009-04-06 13:31:14 +02:00
uint32 pdamage = GetAmount () > 0 ? GetAmount () : 0 ;
pdamage = pCaster -> SpellDamageBonus ( m_target , GetSpellProto (), pdamage , DOT , GetParentAura () -> GetStackAmount ());
2008-10-11 14:16:25 -05:00
//Calculate armor mitigation if it is a physical spell
if ( GetSpellSchoolMask ( GetSpellProto ()) & SPELL_SCHOOL_MASK_NORMAL )
{
2009-02-02 22:31:11 +01:00
uint32 pdamageReductedArmor = pCaster -> CalcArmorReducedDamage ( m_target , pdamage , GetSpellProto ());
2008-10-11 14:16:25 -05:00
cleanDamage . damage += pdamage - pdamageReductedArmor ;
pdamage = pdamageReductedArmor ;
}
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
pdamage -= (( Player * ) m_target ) -> GetDotDamageReduction ( pdamage );
2009-02-03 20:42:43 +01:00
pCaster -> CalcAbsorbResist ( m_target , GetSpellSchoolMask ( GetSpellProto ()), DOT , pdamage , & absorb , & resist , m_spellProto );
2008-10-11 14:16:25 -05:00
if ( m_target -> GetHealth () < pdamage )
pdamage = uint32 ( m_target -> GetHealth ());
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u" ,
2008-11-10 09:04:23 -06:00
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), pdamage , GetId (), absorb );
2008-10-11 14:16:25 -05:00
pCaster -> SendSpellNonMeleeDamageLog ( m_target , GetId (), pdamage , GetSpellSchoolMask ( GetSpellProto ()), absorb , resist , false , 0 );
Unit * target = m_target ; // aura can be deleted in DealDamage
SpellEntry const * spellProto = GetSpellProto ();
float multiplier = spellProto -> EffectMultipleValue [ GetEffIndex ()] > 0 ? spellProto -> EffectMultipleValue [ GetEffIndex ()] : 1 ;
2009-04-06 13:31:14 +02:00
int32 stackAmount = GetParentAura () -> GetStackAmount ();
2008-10-11 14:16:25 -05:00
2008-11-26 15:14:03 -06:00
// Set trigger flag
2009-05-15 16:59:27 +02:00
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_INTERNAL_DOT | PROC_EX_NORMAL_HIT ;
2008-11-26 15:14:03 -06:00
pdamage = ( pdamage <= absorb + resist ) ? 0 : ( pdamage - absorb - resist );
if ( pdamage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
2009-05-15 16:59:27 +02:00
pCaster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , pdamage , BASE_ATTACK , spellProto );
2008-11-26 15:14:03 -06:00
int32 new_damage = pCaster -> DealDamage ( target , pdamage , & cleanDamage , DOT , GetSpellSchoolMask ( spellProto ), spellProto , false );
2008-10-11 14:16:25 -05:00
if ( ! target -> isAlive () && pCaster -> IsNonMeleeSpellCasted ( false ))
{
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; i ++ )
{
if ( pCaster -> m_currentSpells [ i ] && pCaster -> m_currentSpells [ i ] -> m_spellInfo -> Id == spellProto -> Id )
pCaster -> m_currentSpells [ i ] -> cancel ();
}
}
if ( Player * modOwner = pCaster -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( spellProto -> Id , SPELLMOD_MULTIPLE_VALUE , multiplier );
2009-05-18 21:54:11 +02:00
uint32 heal = uint32 ( pCaster -> SpellHealingBonus ( pCaster , spellProto , uint32 ( new_damage * multiplier ), DOT , stackAmount ));
2008-10-11 14:16:25 -05:00
2009-04-23 22:02:41 -05:00
int32 gain = pCaster -> DealHeal ( pCaster , heal , spellProto );
2008-10-11 14:16:25 -05:00
pCaster -> getHostilRefManager (). threatAssist ( pCaster , gain * 0.5f , spellProto );
break ;
}
case SPELL_AURA_PERIODIC_HEAL :
case SPELL_AURA_OBS_MOD_HEALTH :
{
Unit * pCaster = GetCaster ();
if ( ! pCaster )
return ;
// heal for caster damage (must be alive)
2008-12-24 09:58:26 -06:00
if ( m_target != pCaster && GetSpellProto () -> SpellVisual [ 0 ] == 163 && ! pCaster -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> GetAuraDuration () ==- 1 && m_target -> GetHealth () == m_target -> GetMaxHealth ())
2009-03-14 16:20:04 +01:00
return ;
2008-10-11 14:16:25 -05:00
// ignore non positive values (can be result apply spellmods to aura damage
2009-01-29 19:33:39 -06:00
//uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
2009-04-06 13:31:14 +02:00
int32 pdamage = GetAmount () > 0 ? GetAmount () : 0 ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
if ( m_auraName == SPELL_AURA_OBS_MOD_HEALTH )
pdamage = uint32 ( m_target -> GetMaxHealth () * pdamage * GetParentAura () -> GetStackAmount () / 100 );
2008-10-11 14:16:25 -05:00
else
2009-04-06 13:31:14 +02:00
pdamage = pCaster -> SpellHealingBonus ( m_target , GetSpellProto (), pdamage , DOT , GetParentAura () -> GetStackAmount ());
2008-10-11 14:16:25 -05:00
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), pdamage , GetId ());
2009-04-19 15:44:11 +02:00
int32 gain = m_target -> ModifyHealth ( pdamage );
2009-05-31 15:56:51 -05:00
SpellPeriodicAuraLogInfo pInfo ( this , pdamage , pdamage - gain , 0 , 0 , 0.0f );
m_target -> SendPeriodicAuraLog ( & pInfo );
2008-10-11 14:16:25 -05:00
// add HoTs to amount healed in bgs
if ( pCaster -> GetTypeId () == TYPEID_PLAYER )
if ( BattleGround * bg = (( Player * ) pCaster ) -> GetBattleGround () )
bg -> UpdatePlayerScore ((( Player * ) pCaster ), SCORE_HEALING_DONE , gain );
m_target -> getHostilRefManager (). threatAssist ( pCaster , float ( gain ) * 0.5f , GetSpellProto ());
Unit * target = m_target ; // aura can be deleted in DealDamage
SpellEntry const * spellProto = GetSpellProto ();
2009-04-06 13:31:14 +02:00
bool haveCastItem = GetParentAura () -> GetCastItemGUID () != 0 ;
2008-10-11 14:16:25 -05:00
2009-05-19 20:33:11 +02:00
// Health Funnel
2008-10-11 14:16:25 -05:00
// heal for caster damage
2008-12-24 09:58:26 -06:00
if ( m_target != pCaster && spellProto -> SpellVisual [ 0 ] == 163 )
2008-10-11 14:16:25 -05:00
{
uint32 dmg = spellProto -> manaPerSecond ;
if ( pCaster -> GetHealth () <= dmg && pCaster -> GetTypeId () == TYPEID_PLAYER )
{
pCaster -> RemoveAurasDueToSpell ( GetId ());
// finish current generic/channeling spells, don't affect autorepeat
if ( pCaster -> m_currentSpells [ CURRENT_GENERIC_SPELL ])
{
pCaster -> m_currentSpells [ CURRENT_GENERIC_SPELL ] -> finish ();
}
if ( pCaster -> m_currentSpells [ CURRENT_CHANNELED_SPELL ])
{
pCaster -> m_currentSpells [ CURRENT_CHANNELED_SPELL ] -> SendChannelUpdate ( 0 );
pCaster -> m_currentSpells [ CURRENT_CHANNELED_SPELL ] -> finish ();
}
}
else
{
2009-05-08 19:20:28 -05:00
uint32 damage = gain ;
uint32 absorb = 0 ;
pCaster -> DealDamageMods ( pCaster , damage , & absorb );
pCaster -> SendSpellNonMeleeDamageLog ( pCaster , GetId (), damage , GetSpellSchoolMask ( GetSpellProto ()), absorb , 0 , false , 0 , false );
2008-10-11 14:16:25 -05:00
CleanDamage cleanDamage = CleanDamage ( 0 , BASE_ATTACK , MELEE_HIT_NORMAL );
2009-05-08 19:20:28 -05:00
pCaster -> DealDamage ( pCaster , damage , & cleanDamage , NODAMAGE , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto (), true );
2008-10-11 14:16:25 -05:00
}
}
2009-05-15 16:59:27 +02:00
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC ;
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC ;
uint32 procEx = PROC_EX_INTERNAL_HOT | PROC_EX_NORMAL_HIT ;
2008-10-11 14:16:25 -05:00
// ignore item heals
2009-05-19 20:33:11 +02:00
if ( ! haveCastItem )
2009-05-15 16:59:27 +02:00
pCaster -> ProcDamageAndSpell ( target , procAttacker , procVictim , procEx , pdamage , BASE_ATTACK , spellProto );
2008-10-11 14:16:25 -05:00
break ;
}
case SPELL_AURA_PERIODIC_MANA_LEECH :
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < 0 || GetMiscValue () >= MAX_POWERS )
2009-03-13 18:29:38 -06:00
return ;
2009-04-06 13:31:14 +02:00
Powers power = Powers ( GetMiscValue ());
2009-03-13 18:29:38 -06:00
// power type might have changed between aura applying and tick (druid's shapeshift)
if ( m_target -> getPowerType () != power )
return ;
2008-10-11 14:16:25 -05:00
Unit * pCaster = GetCaster ();
if ( ! pCaster )
return ;
if ( ! pCaster -> isAlive ())
return ;
if ( GetSpellProto () -> Effect [ GetEffIndex ()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
pCaster -> SpellHitResult ( m_target , GetSpellProto (), false ) != SPELL_MISS_NONE )
return ;
// Check for immune (not use charges)
2009-04-25 18:53:29 +02:00
if ( m_target -> IsImmunedToDamage ( GetSpellProto ()))
2008-10-11 14:16:25 -05:00
return ;
// ignore non positive values (can be result apply spellmods to aura damage
2009-04-06 13:31:14 +02:00
uint32 pdamage = m_amount > 0 ? m_amount : 0 ;
2008-10-11 14:16:25 -05:00
2009-03-13 18:29:38 -06:00
// Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
2009-04-06 13:31:14 +02:00
// It's mana percent cost spells, m_amount is percent drain from target
2009-03-13 18:29:38 -06:00
if ( m_spellProto -> ManaCostPercentage )
{
// max value
uint32 maxmana = pCaster -> GetMaxPower ( power ) * pdamage * 2 / 100 ;
pdamage = m_target -> GetMaxPower ( power ) * pdamage / 100 ;
if ( pdamage > maxmana )
pdamage = maxmana ;
}
2008-10-11 14:16:25 -05:00
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), pdamage , GetId ());
int32 drain_amount = m_target -> GetPower ( power ) > pdamage ? pdamage : m_target -> GetPower ( power );
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( power == POWER_MANA && m_target -> GetTypeId () == TYPEID_PLAYER )
drain_amount -= (( Player * ) m_target ) -> GetSpellCritDamageReduction ( drain_amount );
m_target -> ModifyPower ( power , - drain_amount );
float gain_multiplier = 0 ;
if ( pCaster -> GetMaxPower ( power ) > 0 )
{
gain_multiplier = GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()];
if ( Player * modOwner = pCaster -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_MULTIPLE_VALUE , gain_multiplier );
}
2009-05-31 15:56:51 -05:00
SpellPeriodicAuraLogInfo pInfo ( this , drain_amount , 0 , 0 , 0 , gain_multiplier );
m_target -> SendPeriodicAuraLog ( & pInfo );
2008-10-11 14:16:25 -05:00
int32 gain_amount = int32 ( drain_amount * gain_multiplier );
if ( gain_amount )
{
int32 gain = pCaster -> ModifyPower ( power , gain_amount );
m_target -> AddThreat ( pCaster , float ( gain ) * 0.5f , GetSpellSchoolMask ( GetSpellProto ()), GetSpellProto ());
}
2009-02-17 20:10:49 -06:00
2009-02-06 19:42:03 +01:00
// Mark of Kaz'rogal
if ( GetId () == 31447 && m_target -> GetPower ( power ) == 0 )
{
m_target -> CastSpell ( m_target , 31463 , true , 0 , this );
// Remove aura
2009-04-06 13:31:14 +02:00
GetParentAura () -> SetAuraDuration ( 0 );
2009-02-06 19:42:03 +01:00
}
2009-02-12 16:24:34 +01:00
// Mark of Kazzak
if ( GetId () == 32960 )
{
int32 modifier = ( m_target -> GetPower ( power ) * 0.05f );
m_target -> ModifyPower ( power , - modifier );
if ( m_target -> GetPower ( power ) == 0 )
{
m_target -> CastSpell ( m_target , 32961 , true , 0 , this );
// Remove aura
2009-04-06 13:31:14 +02:00
GetParentAura () -> SetAuraDuration ( 0 );
2009-02-12 16:24:34 +01:00
}
}
2008-10-11 14:16:25 -05:00
break ;
}
2009-03-08 13:24:05 +01:00
case SPELL_AURA_OBS_MOD_ENERGY :
2009-03-12 23:20:51 +01:00
{
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () < 0 )
2009-03-14 16:20:04 +01:00
return ;
2009-03-12 23:20:51 +01:00
2009-03-13 16:28:36 +01:00
Powers power ;
2009-04-06 13:31:14 +02:00
if ( GetMiscValue () == POWER_ALL )
2009-03-13 16:28:36 +01:00
power = m_target -> getPowerType ();
else
2009-04-06 13:31:14 +02:00
power = Powers ( GetMiscValue ());
2009-03-12 23:20:51 +01:00
2009-03-13 16:28:36 +01:00
if ( m_target -> GetMaxPower ( power ) == 0 )
2009-03-14 16:20:04 +01:00
return ;
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> GetAuraDuration () ==- 1 && m_target -> GetPower ( power ) == m_target -> GetMaxPower ( power ))
2009-03-14 16:20:04 +01:00
return ;
2009-03-12 23:20:51 +01:00
2009-04-06 13:31:14 +02:00
uint32 amount = m_amount * m_target -> GetMaxPower ( power ) / 100 ;
2009-03-13 16:28:36 +01:00
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u" ,
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), amount , GetId ());
2009-03-12 23:20:51 +01:00
2009-05-31 15:56:51 -05:00
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f );
m_target -> SendPeriodicAuraLog ( & pInfo );
2009-03-12 23:20:51 +01:00
2009-03-13 16:28:36 +01:00
int32 gain = m_target -> ModifyPower ( power , amount );
2009-03-12 23:20:51 +01:00
2009-03-13 16:28:36 +01:00
if ( Unit * pCaster = GetCaster ())
m_target -> getHostilRefManager (). threatAssist ( pCaster , float ( gain ) * 0.5f , GetSpellProto ());
2009-03-12 23:20:51 +01:00
break ;
}
2008-10-11 14:16:25 -05:00
case SPELL_AURA_PERIODIC_ENERGIZE :
{
// ignore non positive values (can be result apply spellmods to aura damage
2009-04-06 13:31:14 +02:00
if ( m_amount < 0 || GetMiscValue () >= MAX_POWERS )
2009-03-14 16:20:04 +01:00
return ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
Powers power = Powers ( GetMiscValue ());
2008-10-11 14:16:25 -05:00
if ( m_target -> GetMaxPower ( power ) == 0 )
2009-03-14 16:20:04 +01:00
return ;
2009-04-06 13:31:14 +02:00
if ( GetParentAura () -> GetAuraDuration () ==- 1 && m_target -> GetPower ( power ) == m_target -> GetMaxPower ( power ))
2009-03-14 16:20:04 +01:00
return ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
uint32 amount = m_amount ;
2009-03-08 03:10:03 +01:00
2009-05-31 15:56:51 -05:00
SpellPeriodicAuraLogInfo pInfo ( this , amount , 0 , 0 , 0 , 0.0f );
m_target -> SendPeriodicAuraLog ( & pInfo );
2008-10-11 14:16:25 -05:00
2009-03-08 13:24:05 +01:00
sLog . outDetail ( "PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u" ,
2009-03-12 23:20:51 +01:00
GUID_LOPART ( GetCasterGUID ()), GuidHigh2TypeId ( GUID_HIPART ( GetCasterGUID ())), m_target -> GetGUIDLow (), m_target -> GetTypeId (), amount , GetId ());
2008-10-11 14:16:25 -05:00
2009-03-12 23:20:51 +01:00
int32 gain = m_target -> ModifyPower ( power , amount );
2008-10-11 14:16:25 -05:00
if ( Unit * pCaster = GetCaster ())
m_target -> getHostilRefManager (). threatAssist ( pCaster , float ( gain ) * 0.5f , GetSpellProto ());
break ;
}
case SPELL_AURA_POWER_BURN_MANA :
{
Unit * pCaster = GetCaster ();
if ( ! pCaster )
return ;
// Check for immune (not use charges)
2009-04-25 18:53:29 +02:00
if ( m_target -> IsImmunedToDamage ( GetSpellProto ()))
2008-10-11 14:16:25 -05:00
return ;
2009-04-06 13:31:14 +02:00
int32 pdamage = m_amount > 0 ? m_amount : 0 ;
2008-10-11 14:16:25 -05:00
2009-04-06 13:31:14 +02:00
Powers powerType = Powers ( GetMiscValue ());
2008-10-11 14:16:25 -05:00
if ( ! m_target -> isAlive () || m_target -> getPowerType () != powerType )
return ;
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
if ( powerType == POWER_MANA && m_target -> GetTypeId () == TYPEID_PLAYER )
pdamage -= (( Player * ) m_target ) -> GetSpellCritDamageReduction ( pdamage );
uint32 gain = uint32 ( - m_target -> ModifyPower ( powerType , - pdamage ));
gain = uint32 ( gain * GetSpellProto () -> EffectMultipleValue [ GetEffIndex ()]);
2008-11-26 15:14:03 -06:00
SpellEntry const * spellProto = GetSpellProto ();
2008-10-11 14:16:25 -05:00
//maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
2008-11-26 15:14:03 -06:00
SpellNonMeleeDamage damageInfo ( pCaster , m_target , spellProto -> Id , spellProto -> SchoolMask );
2009-01-04 10:42:53 -06:00
//no SpellDamageBonus for burn mana
pCaster -> CalculateSpellDamageTaken ( & damageInfo , gain , spellProto );
2009-05-08 19:20:28 -05:00
pCaster -> DealDamageMods ( damageInfo . target , damageInfo . damage , & damageInfo . absorb );
2008-11-26 15:14:03 -06:00
pCaster -> SendSpellNonMeleeDamageLog ( & damageInfo );
// Set trigger flag
2009-05-15 16:59:27 +02:00
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 ;
2008-11-26 15:14:03 -06:00
if ( damageInfo . damage )
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE ;
pCaster -> ProcDamageAndSpell ( damageInfo . target , procAttacker , procVictim , procEx , damageInfo . damage , BASE_ATTACK , spellProto );
pCaster -> DealSpellDamage ( & damageInfo , true );
2008-10-11 14:16:25 -05:00
break ;
}
2009-01-24 11:28:00 -06:00
case SPELL_AURA_MOD_REGEN :
{
2009-04-06 13:31:14 +02:00
int32 gain = m_target -> ModifyHealth ( m_amount );
2009-01-24 11:28:00 -06:00
if ( Unit * caster = GetCaster ())
m_target -> getHostilRefManager (). threatAssist ( caster , float ( gain ) * 0.5f , GetSpellProto ());
break ;
}
case SPELL_AURA_MOD_POWER_REGEN :
{
Powers pt = m_target -> getPowerType ();
2009-04-06 13:31:14 +02:00
if ( int32 ( pt ) != GetMiscValue ())
2009-01-24 11:28:00 -06:00
return ;
2009-02-13 20:03:32 -06:00
2009-01-24 11:28:00 -06:00
if ( GetSpellProto () -> AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
{
// eating anim
m_target -> HandleEmoteCommand ( EMOTE_ONESHOT_EAT );
}
else if ( GetId () == 20577 )
{
// cannibalize anim
m_target -> HandleEmoteCommand ( EMOTE_STATE_CANNIBALIZE );
}
2009-05-03 16:55:09 +02:00
// Butchery
else if ( m_spellProto -> SpellFamilyName == SPELLFAMILY_DEATHKNIGHT
&& m_spellProto -> SpellIconID == 2664 )
{
if ( m_target -> isInCombat ())
m_target -> ModifyPower ( pt , m_amount );
}
2009-02-13 20:03:32 -06:00
2009-02-13 20:05:16 -06:00
// Anger Management
2009-04-06 21:14:51 +02:00
// amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
2009-02-13 20:05:16 -06:00
// so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
if ( pt == POWER_RAGE )
2009-04-06 13:31:14 +02:00
m_target -> ModifyPower ( pt , m_amount * 3 / 5 );
2009-01-24 11:28:00 -06:00
break ;
}
2009-04-14 20:04:01 +02:00
case SPELL_AURA_DUMMY :
{
// Haunting Spirits
if ( GetId () == 7057 )
{
2009-04-14 20:21:16 +02:00
m_target -> CastSpell (( Unit * ) NULL , m_amount , true );
2009-04-14 20:04:01 +02:00
m_amplitude = irand ( 0 , 60 ) + 30 ;
m_amplitude *= IN_MILISECONDS ;
break ;
}
break ;
}
2008-10-11 14:16:25 -05:00
// Here tick dummy auras
case SPELL_AURA_PERIODIC_DUMMY :
{
PeriodicDummyTick ();
break ;
}
2009-01-22 22:44:27 -06:00
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
{
TriggerSpell ();
break ;
}
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE :
{
TriggerSpellWithValue ();
break ;
}
2008-10-11 14:16:25 -05:00
default :
break ;
}
}
2009-04-06 13:31:14 +02:00
void AuraEffect :: PeriodicDummyTick ()
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
Unit * caster = GetCaster ();
2008-10-11 14:16:25 -05:00
SpellEntry const * spell = GetSpellProto ();
2008-12-24 09:58:26 -06:00
switch ( spell -> SpellFamilyName )
{
case SPELLFAMILY_GENERIC :
switch ( spell -> Id )
{
// Drink
case 430 :
case 431 :
case 432 :
case 1133 :
case 1135 :
case 1137 :
case 10250 :
case 22734 :
case 27089 :
case 34291 :
case 43706 :
case 46755 :
case 49472 : // Drink Coffee
case 61830 :
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2008-12-24 09:58:26 -06:00
// Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & aura = m_target -> GetAurasByType ( SPELL_AURA_MOD_POWER_REGEN );
for ( Unit :: AuraEffectList :: const_iterator i = aura . begin (); i != aura . end (); ++ i )
2008-12-24 09:58:26 -06:00
{
if (( * i ) -> GetId () == GetId ())
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
( * i ) -> SetAmount ( m_amount );
2008-12-24 09:58:26 -06:00
(( Player * ) m_target ) -> UpdateManaRegen ();
2009-01-25 16:35:14 -06:00
// Disable continue
m_isPeriodic = false ;
return ;
2008-10-11 14:16:25 -05:00
}
}
2008-12-24 09:58:26 -06:00
return ;
}
// 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 ;
2008-10-11 14:16:25 -05:00
}
// // Panda
// case 19230: break;
// // Gossip NPC Periodic - Talk
// case 33208: break;
// // Gossip NPC Periodic - Despawn
// case 33209: break;
// // Steal Weapon
// case 36207: break;
// // Simon Game START timer, (DND)
// case 39993: break;
// // Knockdown Fel Cannon: break; The Aggro Burst
// case 40119: break;
// // Old Mount Spell
// case 40154: break;
// // Magnetic Pull
// case 40581: break;
// // Ethereal Ring: break; The Bolt Burst
// case 40801: break;
// // Crystal Prison
// case 40846: break;
// // Copy Weapon
// case 41054: break;
2008-12-24 09:58:26 -06:00
// // Dementia
// case 41404: break;
2008-10-11 14:16:25 -05:00
// // Ethereal Ring Visual, Lightning Aura
// case 41477: break;
// // Ethereal Ring Visual, Lightning Aura (Fork)
// case 41525: break;
// // Ethereal Ring Visual, Lightning Jumper Aura
// case 41567: break;
// // No Man's Land
// case 41955: break;
// // Headless Horseman - Fire
// case 42074: break;
// // Headless Horseman - Visual - Large Fire
// case 42075: break;
// // Headless Horseman - Start Fire, Periodic Aura
// case 42140: break;
// // Ram Speed Boost
// case 42152: break;
// // Headless Horseman - Fires Out Victory Aura
// case 42235: break;
// // Pumpkin Life Cycle
// case 42280: break;
// // Brewfest Request Chick Chuck Mug Aura
// case 42537: break;
// // Squashling
// case 42596: break;
// // Headless Horseman Climax, Head: Periodic
// case 42603: break;
// // Fire Bomb
// case 42621: break;
// // Headless Horseman - Conflagrate, Periodic Aura
// case 42637: break;
// // Headless Horseman - Create Pumpkin Treats Aura
// case 42774: break;
// // Headless Horseman Climax - Summoning Rhyme Aura
// case 42879: break;
// // Tricky Treat
// case 42919: break;
// // Giddyup!
// case 42924: break;
// // Ram - Trot
// case 42992: break;
// // Ram - Canter
// case 42993: break;
// // Ram - Gallop
// case 42994: break;
// // Ram Level - Neutral
// case 43310: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
// case 43884: break;
2008-12-24 09:58:26 -06:00
// // Wretched!
// case 43963: break;
2008-10-11 14:16:25 -05:00
// // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
// case 44000: break;
// // Energy Feedback
// case 44328: break;
// // Romantic Picnic
// case 45102: break;
// // Romantic Picnic
// case 45123: break;
// // Looking for Love
// case 45124: break;
// // Kite - Lightning Strike Kite Aura
// case 45197: break;
// // Rocket Chicken
// case 45202: break;
// // Copy Offhand Weapon
// case 45205: break;
// // Upper Deck - Kite - Lightning Periodic Aura
// case 45207: break;
// // Kite -Sky Lightning Strike Kite Aura
// case 45251: break;
// // Ribbon Pole Dancer Check Aura
// case 45390: break;
// // Holiday - Midsummer, Ribbon Pole Periodic Visual
// case 45406: break;
// // Parachute
// case 45472: break;
// // Alliance Flag, Extra Damage Debuff
// case 45898: break;
// // Horde Flag, Extra Damage Debuff
// case 45899: break;
// // Ahune - Summoning Rhyme Aura
// case 45926: break;
// // Ahune - Slippery Floor
// case 45945: break;
// // Ahune's Shield
// case 45954: break;
// // Nether Vapor Lightning
// case 45960: break;
// // Darkness
// case 45996: break;
// // Summon Blood Elves Periodic
// case 46041: break;
// // Transform Visual Missile Periodic
// case 46205: break;
// // Find Opening Beam End
// case 46333: break;
// // Ice Spear Control Aura
// case 46371: break;
// // Hailstone Chill
// case 46458: break;
// // Hailstone Chill, Internal
// case 46465: break;
// // Chill, Internal Shifter
// case 46549: break;
// // Summon Ice Spear Knockback Delayer
// case 46878: break;
// // Burninate Effect
// case 47214: break;
// // Fizzcrank Practice Parachute
// case 47228: break;
// // Send Mug Control Aura
// case 47369: break;
// // Direbrew's Disarm (precast)
// case 47407: break;
// // Mole Machine Port Schedule
// case 47489: break;
2008-12-24 09:58:26 -06:00
// case 47941: break; // Crystal Spike
// case 48200: break; // Healer Aura
// case 48630: break; // Summon Gauntlet Mobs Periodic
// case 49313: break; // Proximity Mine Area Aura
2008-10-11 14:16:25 -05:00
// // Mole Machine Portal Schedule
// case 49466: break;
2008-12-24 09:58:26 -06:00
// case 49555: break; // Corpse Explode
// case 49592: break; // Temporal Rift
// case 49957: break; // Cutting Laser
// case 50085: break; // Slow Fall
2008-10-11 14:16:25 -05:00
// // Listening to Music
// case 50493: break;
// // Love Rocket Barrage
// case 50530: break;
2009-05-24 17:26:44 -05:00
// Tenacity
case 58549 :
case 59911 :
GetParentAura () -> RefreshAura ();
break ;
2008-12-24 09:58:26 -06:00
// Exist more after, need add later
default :
break ;
}
break ;
case SPELLFAMILY_MAGE :
{
// Mirror Image
// if (spell->Id == 55342)
// return;
break ;
}
case SPELLFAMILY_WARRIOR :
{
// Armored to the Teeth
if ( spell -> SpellIconID == 3516 )
{
// Increases your attack power by $s1 for every $s2 armor value you have.
// Calculate AP bonus (from 1 efect of this spell)
2009-04-06 13:31:14 +02:00
int32 apBonus = m_amount * m_target -> GetArmor () / m_target -> CalculateSpellDamage ( spell , 1 , spell -> EffectBasePoints [ 1 ], m_target );
2008-12-24 09:58:26 -06:00
m_target -> CastCustomSpell ( m_target , 61217 , & apBonus , & apBonus , 0 , true , 0 , this );
return ;
}
break ;
}
2009-06-06 22:11:33 +02:00
case SPELLFAMILY_WARLOCK :
switch ( spell -> Id )
{
case 48018 :
GameObject * obj = m_target -> GetGameObject ( spell -> Id );
if ( ! obj ) return ;
// We must take a range of teleport spell, not summon.
const SpellEntry * goToCircleSpell = sSpellStore . LookupEntry ( 48020 );
if ( m_target -> IsWithinDist ( obj , GetSpellMaxRangeForFriend ( sSpellRangeStore . LookupEntry ( goToCircleSpell -> rangeIndex ))))
m_target -> SendAuraVisualForSelf ( true , 62388 , 1 );
else
m_target -> SendAuraVisualForSelf ( false , 62388 );
}
break ;
2008-12-24 09:58:26 -06:00
case SPELLFAMILY_DRUID :
{
switch ( spell -> 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
if ( m_target -> getPowerType () != POWER_RAGE )
return ;
uint32 rage = m_target -> GetPower ( POWER_RAGE );
// Nothing todo
if ( rage == 0 )
return ;
int32 mod = ( rage < 100 ) ? rage : 100 ;
int32 points = m_target -> CalculateSpellDamage ( spell , 1 , spell -> EffectBasePoints [ 1 ], m_target );
int32 regen = m_target -> GetMaxHealth () * ( mod * points / 10 ) / 1000 ;
m_target -> CastCustomSpell ( m_target , 22845 , & regen , 0 , 0 , true , 0 , this );
m_target -> SetPower ( POWER_RAGE , rage - mod );
return ;
}
// Force of Nature
case 33831 :
return ;
default :
break ;
}
break ;
}
case SPELLFAMILY_ROGUE :
{
2009-03-08 19:18:02 +01:00
switch ( spell -> Id )
{
// Master of Subtlety
case 31666 :
2009-03-19 10:40:02 +01:00
if ( ! m_target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
m_target -> RemoveAurasDueToSpell ( 31665 );
2009-03-08 19:18:02 +01:00
break ;
2009-06-04 16:18:52 -05:00
// Killing Spree
case 51690 :
{
2009-06-06 22:11:33 +02:00
// TODO: this should use effect[1] of 51690
2009-06-04 16:18:52 -05:00
std :: list < Unit *> targets ;
{
// eff_radius ==0
2009-06-04 16:32:21 -05:00
float radius = GetSpellMaxRange ( spell , false );
2009-06-04 16:18:52 -05:00
CellPair p ( MaNGOS :: ComputeCellPair ( caster -> GetPositionX (), caster -> GetPositionY ()));
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
MaNGOS :: AnyUnfriendlyVisibleUnitInObjectRangeCheck u_check ( caster , caster , radius );
MaNGOS :: UnitListSearcher < MaNGOS :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > checker ( caster , targets , u_check );
TypeContainerVisitor < MaNGOS :: UnitListSearcher < MaNGOS :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > , GridTypeMapContainer > grid_object_checker ( checker );
TypeContainerVisitor < MaNGOS :: UnitListSearcher < MaNGOS :: AnyUnfriendlyVisibleUnitInObjectRangeCheck > , WorldTypeMapContainer > world_object_checker ( checker );
CellLock < GridReadGuard > cell_lock ( cell , p );
cell_lock -> Visit ( cell_lock , grid_object_checker , * caster -> GetMap ());
cell_lock -> Visit ( cell_lock , world_object_checker , * caster -> GetMap ());
}
if ( targets . empty ())
return ;
std :: list < Unit *>:: const_iterator itr = targets . begin ();
std :: advance ( itr , rand () % targets . size ());
Unit * target = * itr ;
caster -> CastSpell ( target , 57840 , true );
caster -> CastSpell ( target , 57841 , true );
return ;
}
// Overkill
case 58428 :
if ( ! m_target -> HasAuraType ( SPELL_AURA_MOD_STEALTH ))
m_target -> RemoveAurasDueToSpell ( 58427 );
2009-03-08 19:18:02 +01:00
break ;
2009-06-04 16:18:52 -05:00
// default:
// break;
2009-03-08 19:18:02 +01:00
}
2008-12-24 09:58:26 -06:00
break ;
}
case SPELLFAMILY_HUNTER :
{
// Explosive Shot
2009-02-02 17:01:56 +01:00
if ( spell -> SpellFamilyFlags [ 1 ] & 0x80000000 )
2008-12-24 09:58:26 -06:00
{
2009-05-08 00:49:02 -05:00
if ( caster )
caster -> CastCustomSpell ( 53352 , SPELLVALUE_BASE_POINT0 , m_amount , m_target , true , NULL , this );
2008-12-24 09:58:26 -06:00
return ;
}
switch ( spell -> Id )
{
// Harpooner's Mark
// case 40084:
// return;
// Feeding Frenzy Rank 1
case 53511 :
if ( m_target -> GetHealth () * 100 < m_target -> GetMaxHealth () * 35 )
m_target -> CastSpell ( m_target , 60096 , true , 0 , this );
return ;
// Feeding Frenzy Rank 2
case 53512 :
if ( m_target -> GetHealth () * 100 < m_target -> GetMaxHealth () * 35 )
m_target -> CastSpell ( m_target , 60097 , true , 0 , this );
return ;
default :
break ;
}
break ;
}
case SPELLFAMILY_SHAMAN :
{
// Astral Shift
2009-01-10 11:30:45 -06:00
if ( spell -> Id == 52179 )
{
// Periodic need for remove visual on stun/fear/silence lost
if ( ! ( m_target -> GetUInt32Value ( UNIT_FIELD_FLAGS ) & ( UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED )))
m_target -> RemoveAurasDueToSpell ( 52179 );
return ;
}
2008-12-24 09:58:26 -06:00
break ;
}
case SPELLFAMILY_DEATHKNIGHT :
{
// Death and Decay
2009-02-02 17:01:56 +01:00
if ( spell -> SpellFamilyFlags [ 0 ] & 0x20 )
2009-01-09 16:06:17 -06:00
{
if ( caster )
2009-04-06 13:31:14 +02:00
caster -> CastCustomSpell ( m_target , 52212 , & m_amount , NULL , NULL , true , 0 , this );
2009-01-09 16:06:17 -06:00
return ;
}
2008-12-24 09:58:26 -06:00
// Raise Dead
// if (spell->SpellFamilyFlags & 0x0000000000001000LL)
// return;
// Chains of Ice
2009-02-02 17:01:56 +01:00
if ( spell -> SpellFamilyFlags [ 1 ] & 0x00004000 )
2008-12-24 09:58:26 -06:00
{
// Get 0 effect aura
2009-05-04 18:31:37 +02:00
AuraEffect * slow = GetParentAura () -> GetPartAura ( 0 );
2008-12-24 09:58:26 -06:00
if ( slow )
{
2009-05-06 19:06:07 +02:00
slow -> ApplyModifier ( false , true );
2009-05-04 18:31:37 +02:00
slow -> SetAmount ( slow -> GetAmount () + GetAmount ());
2009-04-06 13:31:14 +02:00
if ( slow -> GetAmount () > 0 ) slow -> SetAmount ( 0 );
2009-05-06 19:06:07 +02:00
slow -> ApplyModifier ( true , true );
2008-12-24 09:58:26 -06:00
}
return ;
}
// Summon Gargoyle
// if (spell->SpellFamilyFlags & 0x0000008000000000LL)
// return;
// Death Rune Mastery
// if (spell->SpellFamilyFlags & 0x0000000000004000LL)
// return;
// Bladed Armor
if ( spell -> SpellIconID == 2653 )
{
// Increases your attack power by $s1 for every $s2 armor value you have.
// Calculate AP bonus (from 1 efect of this spell)
2009-04-06 13:31:14 +02:00
int32 apBonus = m_amount * m_target -> GetArmor () / m_target -> CalculateSpellDamage ( spell , 1 , spell -> EffectBasePoints [ 1 ], m_target );
2008-12-24 09:58:26 -06:00
m_target -> CastCustomSpell ( m_target , 61217 , & apBonus , & apBonus , 0 , true , 0 , this );
return ;
}
// Reaping
// if (spell->SpellIconID == 22)
// return;
// Blood of the North
// if (spell->SpellIconID == 30412)
// return;
break ;
}
2008-10-11 14:16:25 -05:00
default :
break ;
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePreventFleeing ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
2009-04-06 13:31:14 +02:00
Unit :: AuraEffectList const & fearAuras = m_target -> GetAurasByType ( SPELL_AURA_MOD_FEAR );
2008-10-11 14:16:25 -05:00
if ( ! fearAuras . empty () )
{
2008-12-09 20:28:59 -06:00
m_target -> SetControlled ( ! apply , UNIT_STAT_FLEEING );
/*if (apply)
2008-10-11 14:16:25 -05:00
m_target->SetFeared(false, fearAuras.front()->GetCasterGUID());
else
2008-12-09 20:28:59 -06:00
m_target->SetFeared(true);*/
2008-10-11 14:16:25 -05:00
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleManaShield ( bool apply , bool Real , bool changeAmount )
2008-10-11 14:16:25 -05:00
{
2009-05-16 17:59:36 +02:00
if ( ! Real && ! changeAmount )
2008-10-11 14:16:25 -05:00
return ;
// prevent double apply bonuses
if ( apply && ( m_target -> GetTypeId () != TYPEID_PLAYER || ! (( Player * ) m_target ) -> GetSession () -> PlayerLoading ()))
{
if ( Unit * caster = GetCaster ())
{
float DoneActualBenefit = 0.0f ;
switch ( m_spellProto -> SpellFamilyName )
{
case SPELLFAMILY_MAGE :
2009-02-02 17:01:56 +01:00
if ( m_spellProto -> SpellFamilyFlags [ 0 ] & 0x8000 )
2008-10-11 14:16:25 -05:00
{
// Mana Shield
// +50% from +spd bonus
DoneActualBenefit = caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellProto )) * 0.5f ;
break ;
}
break ;
default :
break ;
}
DoneActualBenefit *= caster -> CalculateLevelPenalty ( GetSpellProto ());
2009-04-06 13:31:14 +02:00
m_amount += ( int32 ) DoneActualBenefit ;
2008-10-11 14:16:25 -05:00
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleArenaPreparation ( bool apply , bool Real , bool /*changeAmount*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! Real )
return ;
if ( apply )
m_target -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PREPARATION );
else
m_target -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_PREPARATION );
}
2008-12-03 19:42:06 -06:00
2009-05-05 16:56:15 -05:00
/**
* Such auras are applied from a caster(=player) to a vehicle.
* This has been verified using spell #49256
*/
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraControlVehicle ( bool apply , bool Real , bool /*changeAmount*/ )
2008-12-03 19:42:06 -06:00
{
if ( ! Real )
return ;
2009-05-05 16:56:15 -05:00
if ( m_target -> GetTypeId () != TYPEID_UNIT || ! (( Creature * ) m_target ) -> isVehicle ())
return ;
2009-05-23 22:21:26 -05:00
Unit * caster = GetSource ();
2009-05-23 20:40:14 -05:00
if ( ! caster || caster == m_target )
2008-12-24 09:58:26 -06:00
return ;
2009-06-03 16:20:35 -05:00
Vehicle * const vehicle = dynamic_cast < Vehicle * const > ( m_target );
2008-12-24 09:58:26 -06:00
2009-05-05 16:56:15 -05:00
if ( apply )
{
2009-05-23 20:40:14 -05:00
//if(caster->GetTypeId() == TYPEID_PLAYER)
// if(Pet *pet = ((Player*)caster)->GetPet())
// pet->Remove(PET_SAVE_AS_CURRENT);
caster -> EnterVehicle ( vehicle , 0 );
2009-05-05 16:56:15 -05:00
}
else
{
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
2009-05-23 20:40:14 -05:00
caster -> RemoveAurasDueToSpell ( GetId ());
2009-05-05 16:56:15 -05:00
caster -> ExitVehicle ();
2009-05-23 20:40:14 -05:00
}
2008-12-24 09:58:26 -06:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraConvertRune ( bool apply , bool Real , bool /*changeAmount*/ )
2008-12-24 09:58:26 -06:00
{
if ( ! Real )
return ;
if ( m_target -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * plr = ( Player * ) m_target ;
if ( plr -> getClass () != CLASS_DEATH_KNIGHT )
return ;
// how to determine what rune need to be converted?
for ( uint32 i = 0 ; i < MAX_RUNES ; ++ i )
{
if ( apply )
{
if ( ! plr -> GetRuneCooldown ( i ))
{
plr -> ConvertRune ( i , GetSpellProto () -> EffectMiscValueB [ m_effIndex ]);
break ;
}
}
else
{
if ( plr -> GetCurrentRune ( i ) == GetSpellProto () -> EffectMiscValueB [ m_effIndex ])
{
plr -> ConvertRune ( i , plr -> GetBaseRune ( i ));
break ;
}
}
}
}
2009-02-21 17:34:03 -06:00
// Control Auras
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModStun ( bool apply , bool Real , bool /*changeAmount*/ )
2009-02-21 17:34:03 -06:00
{
if ( ! Real )
return ;
m_target -> SetControlled ( apply , UNIT_STAT_STUNNED );
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraModRoot ( bool apply , bool Real , bool /*changeAmount*/ )
2009-02-21 17:34:03 -06:00
{
if ( ! Real )
return ;
m_target -> SetControlled ( apply , UNIT_STAT_ROOT );
}
// Charm Auras
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPossess ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-09 16:43:23 -06:00
{
if ( ! Real )
return ;
Unit * caster = GetCaster ();
if ( caster && caster -> GetTypeId () == TYPEID_UNIT )
{
2009-05-16 17:59:36 +02:00
HandleModCharm ( apply , Real , false );
2009-01-09 16:43:23 -06:00
return ;
}
if ( apply )
{
2009-04-06 13:31:14 +02:00
if ( m_target -> getLevel () > m_amount )
2009-01-09 16:43:23 -06:00
return ;
2009-06-03 13:51:05 -05:00
m_target -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS );
2009-01-09 16:43:23 -06:00
}
else
2009-06-03 13:51:05 -05:00
m_target -> RemoveCharmedBy ( caster );
2009-01-09 16:43:23 -06:00
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModPossessPet ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-09 16:43:23 -06:00
{
if ( ! Real )
return ;
Unit * caster = GetCaster ();
if ( ! caster || caster -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( apply )
2009-03-07 10:19:07 -06:00
{
2009-03-27 22:47:28 -06:00
if ( caster -> GetGuardianPet () != m_target )
2009-04-06 21:14:51 +02:00
return ;
2009-06-03 13:51:05 -05:00
m_target -> SetCharmedBy ( caster , CHARM_TYPE_POSSESS );
2009-03-07 10:19:07 -06:00
}
2009-01-09 16:43:23 -06:00
else
{
2009-06-03 13:51:05 -05:00
m_target -> RemoveCharmedBy ( caster );
2009-01-09 16:43:23 -06:00
// Reinitialize the pet bar and make the pet come back to the owner
(( Player * ) caster ) -> PetSpellInitialize ();
if ( ! m_target -> getVictim ())
{
m_target -> GetMotionMaster () -> MoveFollow ( caster , PET_FOLLOW_DIST , PET_FOLLOW_ANGLE );
m_target -> GetCharmInfo () -> SetCommandState ( COMMAND_FOLLOW );
}
}
}
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleModCharm ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-09 16:43:23 -06:00
{
if ( ! Real )
return ;
Unit * caster = GetCaster ();
if ( apply )
{
2009-04-06 13:31:14 +02:00
if ( int32 ( m_target -> getLevel ()) > m_amount )
2009-01-09 16:43:23 -06:00
return ;
2009-04-06 21:14:51 +02:00
2009-06-03 13:51:05 -05:00
m_target -> SetCharmedBy ( caster , CHARM_TYPE_CHARM );
2009-01-09 16:43:23 -06:00
}
else
2009-06-03 13:51:05 -05:00
m_target -> RemoveCharmedBy ( caster );
2009-01-09 16:43:23 -06:00
}
2009-01-29 18:18:33 -06:00
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandlePhase ( bool apply , bool Real , bool /*changeAmount*/ )
2009-01-29 18:18:33 -06:00
{
2009-01-31 16:38:50 -06:00
if ( ! Real )
return ;
// always non stackable
if ( apply )
{
2009-04-06 13:31:14 +02:00
m_target -> RemoveAurasByType ( SPELL_AURA_PHASE , NULL , GetParentAura ());
2009-01-31 16:38:50 -06:00
}
2009-01-29 18:18:33 -06:00
// no-phase is also phase state so same code for apply and remove
2009-01-31 16:38:50 -06:00
// phase auras normally not expected at BG but anyway better check
if ( m_target -> GetTypeId () == TYPEID_PLAYER )
2009-01-29 18:18:33 -06:00
{
// drop flag at invisible in bg
if ((( Player * ) m_target ) -> InBattleGround ())
if ( BattleGround * bg = (( Player * ) m_target ) -> GetBattleGround ())
bg -> EventPlayerDroppedFlag (( Player * ) m_target );
2009-01-31 16:38:50 -06:00
// GM-mode have mask 0xFFFFFFFF
if ( ! (( Player * ) m_target ) -> isGameMaster ())
m_target -> SetPhaseMask ( apply ? GetMiscValue () : PHASEMASK_NORMAL , false );
2009-02-15 12:13:34 -06:00
(( Player * ) m_target ) -> GetSession () -> SendSetPhaseShift ( apply ? GetMiscValue () : PHASEMASK_NORMAL );
2009-03-03 18:41:11 -06:00
if ( GetEffIndex () == 0 )
{
SpellAreaForAreaMapBounds saBounds = spellmgr . GetSpellAreaForAuraMapBounds ( GetId ());
if ( saBounds . first != saBounds . second )
{
2009-03-11 16:17:37 -06:00
uint32 zone , area ;
m_target -> GetZoneAndAreaId ( zone , area );
2009-03-03 18:41:11 -06:00
for ( SpellAreaForAreaMap :: const_iterator itr = saBounds . first ; itr != saBounds . second ; ++ itr )
{
// some auras remove at aura remove
if ( ! itr -> second -> IsFitToRequirements (( Player * ) m_target , zone , area ))
m_target -> RemoveAurasDueToSpell ( itr -> second -> spellId );
// some auras applied at aura apply
else if ( itr -> second -> autocast )
{
2009-04-20 16:48:35 +02:00
if ( ! m_target -> HasAura ( itr -> second -> spellId ) )
2009-03-03 18:41:11 -06:00
m_target -> CastSpell ( m_target , itr -> second -> spellId , true );
}
}
}
}
2009-01-29 18:18:33 -06:00
}
2009-01-31 16:38:50 -06:00
else
m_target -> SetPhaseMask ( apply ? GetMiscValue () : PHASEMASK_NORMAL , false );
2009-01-29 18:18:33 -06:00
2009-01-31 16:38:50 -06:00
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
2009-01-29 18:18:33 -06:00
if ( m_target -> GetVisibility () != VISIBILITY_OFF )
m_target -> SetVisibility ( m_target -> GetVisibility ());
}
2009-02-05 13:38:48 +01:00
2009-05-16 17:59:36 +02:00
void AuraEffect :: HandleAuraSafeFall ( bool Apply , bool Real , bool /*changeAmount*/ )
2009-05-08 18:52:12 -05:00
{
// implemented in WorldSession::HandleMovementOpcodes
// only special case
if ( Apply && Real && GetId () == 32474 && m_target -> GetTypeId () == TYPEID_PLAYER )
(( Player * ) m_target ) -> ActivateTaxiPathTo ( 506 , GetId ());
}