aboutsummaryrefslogtreecommitdiff
path: root/src/game/SpellAuras.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/SpellAuras.cpp')
-rw-r--r--src/game/SpellAuras.cpp5845
1 files changed, 3380 insertions, 2465 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index dc8616e2fa7..b6c44b8cc60 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,11 +31,9 @@
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
-#include "SpellAuras.h"
#include "DynamicObject.h"
#include "Group.h"
#include "UpdateData.h"
-#include "MapManager.h"
#include "ObjectAccessor.h"
#include "Policies/SingletonImp.h"
#include "Totem.h"
@@ -45,425 +43,522 @@
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
#include "CreatureAI.h"
+#include "ScriptCalls.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "Vehicle.h"
#include "CellImpl.h"
-#define NULL_AURA_SLOT 0xFF
-
pAuraHandler AuraHandler[TOTAL_AURAS]=
{
- &Aura::HandleNULL, // 0 SPELL_AURA_NONE
- &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
- &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
- &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
- &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
- &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
- &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
- &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
- &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
- &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
- &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
- &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
- &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
- &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
- &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
- &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
- &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
- &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
- &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
- &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
- &Aura::HandleAuraModTotalManaPercentRegen, // 21 SPELL_AURA_OBS_MOD_MANA
- &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
- &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
- &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
- &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
- &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
- &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
- &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
- &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
- &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
- &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
- &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
- &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
- &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
- &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
- &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
- &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
- &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
- &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
- &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
- &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
- &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
- &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
- &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
- &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
- &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
- &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
- &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
- &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
- &Aura::HandleUnused, // 50 SPELL_AURA_MOD_BLOCK_SKILL obsolete?
- &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
- &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT
- &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
- &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
- &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
- &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
- &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
- &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
- &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
- &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
- &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
- &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
- &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
- &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
- &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
- &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
- &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
- &Aura::HandleSchoolAbsorb, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
- &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
- &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
- &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
- &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
- &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
- &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
- &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
- &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
- &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
- &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
- &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
- &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
- &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
- &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
- &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
- &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
- &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
- &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
- &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
- &Aura::HandleUnused, // 90 SPELL_AURA_MOD_RESIST_CHANCE Useless
- &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
- &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
- &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
- &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
- &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Spell::SelectMagnetTarget
- &Aura::HandleManaShield, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
- &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
- &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
- &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now
- &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
- &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
- &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
- &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
- &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
- &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
- &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
- &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
- &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
- &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER
- &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
- &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
- &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
- &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
- &Aura::HandleUnused, //119 SPELL_AURA_SHARE_PET_TRACKING useless
- &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
- &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
- &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
- &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
- &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
- &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
- &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
- &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
- &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
- &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
- &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
- &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
- &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
- &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
- &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
- &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
- &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
- &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
- &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
- &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
- &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
- &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete?
- &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete?
- &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
- &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
- &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
- &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
- &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
- &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
- &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
- &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
- &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
- &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
- &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
- &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
- &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
- &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
- &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
- &Aura::HandleUnused, //164 useless, only one test spell
- &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
- &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
- &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
- &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE only for Detect Amore spell
- &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
- &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
- &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
- &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
- &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
- &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM
- &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
- &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
- &Aura::HandleUnused, //181 SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS unused
- &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
- &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT
- &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
- &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN
- &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
- &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
- &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
- &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT)
- &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
- &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
- &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
- &Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
- &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
- &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
- &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNULL, //205 vulnerable to school dmg?
- &Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
- &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
- &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_SPEED_FLIGHT, used only in spell: Flight Form (Passive)
- &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS
- &Aura::HandleNULL, //210 Commentator's Command
- &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
- &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
- &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
- &Aura::HandleNULL, //214 Tamed Pet Passive
- &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
- &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
- &Aura::HandleUnused, //217 unused
- &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
- &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
- &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT
- &Aura::HandleNULL, //221 ignored
- &Aura::HandleUnused, //222 unused
- &Aura::HandleNULL, //223 Cold Stare
- &Aura::HandleUnused, //224 unused
- &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
- &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
- &Aura::HandleNULL, //227 periodic trigger spell
- &Aura::HandleNoImmediateEffect, //228 stealth detection
- &Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
- &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
- &Aura::HandleNULL, //231
- &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
- &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
- &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
- &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
- &Aura::HandleUnused, //236 unused
- &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
- &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
- &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
- &Aura::HandleForceMoveForward, //241 Forces the player to move forward
- &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING
- &Aura::HandleUnused, //243 used by two test spells
- &Aura::HandleComprehendLanguage, //244 Comprehend language
- &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS
- &Aura::HandleUnused, //246 unused
- &Aura::HandleUnused, //247 unused
- &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNULL, //249
- &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
- &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
- &Aura::HandleUnused, //252 unused
- &Aura::HandleUnused, //253 unused
- &Aura::HandleUnused, //254 unused
- &Aura::HandleUnused, //255 unused
- &Aura::HandleUnused, //256 unused
- &Aura::HandleUnused, //257 unused
- &Aura::HandleUnused, //258 unused
- &Aura::HandleUnused, //259 unused
- &Aura::HandleUnused, //260 unused
- &Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell)
+ &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
+ &AuraEffect::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
+ &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
+ &AuraEffect::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
+ &AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
+ &AuraEffect::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
+ &AuraEffect::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
+ &AuraEffect::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
+ &AuraEffect::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::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
+ &AuraEffect::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
+ &AuraEffect::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
+ &AuraEffect::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
+ &AuraEffect::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
+ &AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
+ &AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
+ &AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
+ &AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
+ &AuraEffect::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
+ &AuraEffect::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
+ &AuraEffect::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
+ &AuraEffect::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
+ &AuraEffect::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
+ &AuraEffect::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
+ &AuraEffect::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
+ &AuraEffect::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
+ &AuraEffect::HandleUnused, //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
+ &AuraEffect::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
+ &AuraEffect::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746
+ &AuraEffect::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleModRating, //189 SPELL_AURA_MOD_RATING
+ &AuraEffect::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
+ &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
+ &AuraEffect::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
+ &AuraEffect::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
+ &AuraEffect::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?
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
+ &AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
+ &AuraEffect::HandleNULL, //214 Tamed Pet Passive
+ &AuraEffect::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
+ &AuraEffect::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
+ &AuraEffect::HandleUnused, //217 unused (3.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
+ &AuraEffect::HandleNoImmediateEffect, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
+ &AuraEffect::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
+ &AuraEffect::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
+ &AuraEffect::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
+ &AuraEffect::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
+ &AuraEffect::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
+ &AuraEffect::HandleForceMoveForward, //241 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.
};
-Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
-m_procCharges(0), m_stackAmount(1), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
-m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
-m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
-m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
-m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
-,m_tickNumber(0)
+Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, WorldObject *source, Unit *caster, Item* castItem) :
+m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
+m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
+m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false)
{
assert(target);
assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
+ m_auraFlags = effMask;
+
m_spellProto = spellproto;
- int32 damage;
- if(currentBasePoints)
- {
- damage = *currentBasePoints;
- m_currentBasePoints = damage - 1;
- }
- else
- {
- m_currentBasePoints = m_spellProto->EffectBasePoints[eff];
- if(caster)
- damage = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
- else
- damage = m_currentBasePoints + 1;
- }
+ if(m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
+ m_timeCla = 1000;
m_isPassive = IsPassiveSpell(GetId());
- m_positive = IsPositiveEffect(GetId(), m_effIndex);
- m_applyTime = time(NULL);
+ m_auraStateMask = 0;
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
+ m_applyTime = time(NULL);
+
if(!caster)
{
m_caster_guid = target->GetGUID();
//damage = m_currentBasePoints+1; // stored value-1
- m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target);
+ m_maxduration = target->CalcSpellDuration(m_spellProto);
}
else
{
m_caster_guid = caster->GetGUID();
//damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
- m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target);
-
- if (!damage && 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)
- {
- damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
- break;
- }
- }
-
- if(damage)
- break;
- }
- }
- }
+ m_maxduration = caster->CalcSpellDuration(m_spellProto);
}
if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
m_permanent = true;
+ else
+ m_permanent = false;
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
if(!m_permanent && modOwner)
+ {
modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
+ // Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
+ if (m_maxduration<=0)
+ m_maxduration = 1;
+ }
m_duration = m_maxduration;
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
-
- sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
+ m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
- m_effIndex = eff;
- SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
+ m_procCharges = m_spellProto->procCharges;
+ if(modOwner)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
+ m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() &&
+ m_spellProto->Stances &&
+ !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
+ !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
- if(m_spellProto->procCharges)
+ for (uint8 i=0 ;i<MAX_SPELL_EFFECTS;++i)
{
- m_procCharges = m_spellProto->procCharges;
-
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
+ if (m_auraFlags & (uint8(1) << i))
+ {
+ if (currentBasePoints)
+ m_partAuras[i] = CreateAuraEffect(this, i, currentBasePoints + i, caster, NULL, source);
+ else
+ m_partAuras[i] = CreateAuraEffect(this, i, NULL, caster, NULL, source);
+ // correct flags if aura couldn't be created
+ if (!m_partAuras[i])
+ m_auraFlags &= uint8(~(1<< i));
+ }
+ else
+ {
+ m_partAuras[i]=NULL;
+ }
}
- else
- m_procCharges = -1;
- m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
- !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
+ // Aura is positive when it is casted by friend and at least one aura is positive
+ // or when it is casted by enemy and at least one aura is negative
+ bool swap=false;
+ if (!caster || caster==target) // caster == target - 1 negative effect is enough for aura to be negative
+ m_positive = false;
+ else
+ m_positive = !caster->IsHostileTo(m_target);
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (!(1<<i & GetEffectMask()))
+ continue;
+ if (m_positive == IsPositiveEffect(GetId(), i))
+ {
+ swap = true;
+ break;
+ }
+ }
+ if (!swap)
+ m_positive=!m_positive;
}
Aura::~Aura()
{
+ // free part auras memory
+ for (uint8 i=0 ; i<MAX_SPELL_EFFECTS;++i)
+ if (m_partAuras[i])
+ delete m_partAuras[i];
}
-AreaAura::AreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
-Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
+AuraEffect::AuraEffect(Aura * parentAura, uint8 effIndex, int32 * currentBasePoints , Unit *caster, Item* castItem, WorldObject *source) :
+m_parentAura(parentAura), m_spellmod(NULL), m_periodicTimer(0), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
+m_target(parentAura->GetTarget()), m_tickNumber(0)
+, m_spellProto(parentAura->GetSpellProto()), m_effIndex(effIndex), m_auraName(AuraType(m_spellProto->EffectApplyAuraName[m_effIndex]))
{
+ assert(m_auraName < TOTAL_AURAS);
+
+ if(currentBasePoints)
+ m_currentBasePoints = *currentBasePoints;
+ else
+ m_currentBasePoints = m_spellProto->EffectBasePoints[m_effIndex];
+
+ if(caster)
+ m_amount = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
+ else
+ m_amount = m_currentBasePoints + 1;
+
+ if (!m_amount && castItem && castItem->GetItemSuffixFactor())
+ {
+ ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
+ if(item_rand_suffix)
+ {
+ for (int k=0; k<3; k++)
+ {
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
+ if(pEnchant)
+ {
+ for (int t=0; t<3; t++)
+ if(pEnchant->spellid[t] == m_spellProto->Id)
+ {
+ m_amount = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
+ }
+
+ if(m_amount)
+ break;
+ }
+ }
+ }
+
+ Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
+ m_sourceGUID = source ? source->GetGUID() : (caster ? caster->GetGUID() : 0);
+ m_amplitude = m_spellProto->EffectAmplitude[m_effIndex];
+
+ //apply casting time mods for channeled spells
+ if (modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
+ modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
+
+ // Apply periodic time mod
+ if(modOwner && m_amplitude)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude);
+
+ // Start periodic on next tick or at aura apply
+ if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
+ m_periodicTimer += m_amplitude;
+
+ m_isApplied = false;
+}
+
+AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster, Item * castItem, Unit * source)
+: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source)
+{
+ m_removeTime = FRIENDLY_AA_REMOVE_TIME;
m_isAreaAura = true;
- // caster==NULL in constructor args if target==caster in fact
- Unit* caster_ptr = caster ? caster : target;
+ Unit* caster_ptr = caster ? caster : source ? source : m_target;
+
+ if (m_spellProto->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
+ m_radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
+ else
+ m_radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
- m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
if(Player* modOwner = caster_ptr->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
- switch(spellproto->Effect[eff])
+ switch(m_spellProto->Effect[effIndex])
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
m_areaAuraType = AREA_AURA_PARTY;
- if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
- m_modifier.m_auraname = SPELL_AURA_NONE;
+ if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
+ *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
+ break;
+ case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
+ m_areaAuraType = AREA_AURA_RAID;
+ if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
+ *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
m_areaAuraType = AREA_AURA_ENEMY;
- if(target == caster_ptr)
- m_modifier.m_auraname = SPELL_AURA_NONE; // Do not do any effect on self
+ if(m_target == caster_ptr)
+ *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE; // Do not do any effect on self
break;
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
m_areaAuraType = AREA_AURA_PET;
break;
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
m_areaAuraType = AREA_AURA_OWNER;
- if(target == caster_ptr)
- m_modifier.m_auraname = SPELL_AURA_NONE;
+ if(m_target == caster_ptr)
+ *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
break;
default:
sLog.outError("Wrong spell effect in AreaAura constructor");
@@ -472,26 +567,37 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,
}
}
-AreaAura::~AreaAura()
+AreaAuraEffect::~AreaAuraEffect()
{
}
-PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target,
-Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem)
+PersistentAreaAuraEffect::PersistentAreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster,Item * castItem, DynamicObject *source)
+: AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source)
{
m_isPersistent = true;
}
-PersistentAreaAura::~PersistentAreaAura()
+PersistentAreaAuraEffect::~PersistentAreaAuraEffect()
{
}
-Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem)
+AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints, Unit * caster, Item * castItem, WorldObject* source)
{
- if (IsAreaAuraEffect(spellproto->Effect[eff]))
- return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem);
-
- return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem);
+ // TODO: source should belong to aura, but not areaeffect. multiple areaaura/persistent aura should use one source
+ assert(parentAura);
+ if (IsAreaAuraEffect(parentAura->GetSpellProto()->Effect[effIndex]))
+ {
+ if(!source)
+ source = caster;
+ //TODO: determine source here
+ if(source && source->isType(TYPEMASK_UNIT))
+ return new AreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, (Unit*)source);
+ }
+ else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AURA)
+ return new AuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem, source);
+ else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ return new PersistentAreaAuraEffect(parentAura, effIndex, currentBasePoints, caster, castItem);
+ return NULL;
}
Unit* Aura::GetCaster() const
@@ -505,137 +611,142 @@ Unit* Aura::GetCaster() const
return unit && unit->IsInWorld() ? unit : NULL;
}
-void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
+Unit* AuraEffect::GetSource() const
{
- m_modifier.m_auraname = t;
- m_modifier.m_amount = a;
- m_modifier.m_miscvalue = miscValue;
- m_modifier.periodictime = pt;
+ if(m_sourceGUID == m_target->GetGUID())
+ return m_target;
+
+ //return ObjectAccessor::GetUnit(*m_target,m_caster_guid);
+ //must return caster even if it's in another grid/map
+ Unit *unit = ObjectAccessor::GetObjectInWorld(m_sourceGUID, (Unit*)NULL);
+ //only player can be not in world while in objectaccessor
+ return unit && unit->IsInWorld() ? unit : NULL;
}
void Aura::Update(uint32 diff)
{
+ // TODO: store pointer to caster in aura class for update/mod handling code
+
if (m_duration > 0)
{
m_duration -= diff;
if (m_duration < 0)
m_duration = 0;
- m_timeCla -= diff;
- // GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
- if(GetEffIndex()==0 && m_timeCla <= 0)
+ if(m_timeCla)
{
- if(Unit* caster = GetCaster())
+ if(m_timeCla > diff)
+ m_timeCla -= diff;
+ else if(Unit* caster = GetCaster())
{
- Powers powertype = Powers(m_spellProto->powerType);
- int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
- m_timeCla = 1000;
- if (manaPerSecond)
+ if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
- if(powertype==POWER_HEALTH)
- caster->ModifyHealth(-manaPerSecond);
+ m_timeCla += 1000 - diff;
+
+ Powers powertype = Powers(m_spellProto->powerType);
+ if(powertype == POWER_HEALTH)
+ {
+ if (caster->GetHealth() > manaPerSecond)
+ caster->ModifyHealth(-manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
else
- caster->ModifyPower(powertype,-manaPerSecond);
+ {
+ if (caster->GetPower(powertype) >= manaPerSecond)
+ caster->ModifyPower(powertype, -manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
}
}
}
}
- // Channeled aura required check distance from caster except in possessed cases
- Unit *pRealTarget = (GetSpellProto()->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL) ? GetTriggerTarget() : m_target;
- if(!pRealTarget)
- return;
-
- if(IsChanneledSpell(m_spellProto) && !pRealTarget->isPossessed() && pRealTarget->GetGUID() != GetCasterGUID())
+ // Apply charged spellmods for channeled auras
+ // used for example when triggered spell of spell:10 is modded
+ Spell * modSpell = NULL;
+ Unit* caster = NULL;
+ if (IS_PLAYER_GUID(GetCasterGUID()))
{
- Unit* caster = GetCaster();
- if(!caster)
- {
- m_target->RemoveAura(GetId(),GetEffIndex());
- return;
- }
-
- // Get spell range
- float radius;
- SpellModOp mod;
- if (m_spellProto->EffectRadiusIndex[GetEffIndex()])
- {
- radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()]));
- mod = SPELLMOD_RADIUS;
- }
- else
+ caster = GetCaster();
+ if (caster)
{
- radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
- mod = SPELLMOD_RANGE;
+ modSpell = ((Player*)caster)->FindCurrentSpellBySpellId(GetId());
+ ((Player*)caster)->SetSpellModTakingSpell(modSpell, true);
}
-
- if(Player* modOwner = caster->GetSpellModOwner())
- modOwner->ApplySpellMod(GetId(), mod, radius,NULL);
-
- if(!caster->IsWithinDistInMap(pRealTarget, radius))
- return;
}
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (m_partAuras[i])
+ m_partAuras[i]->Update(diff);
+
+ if (caster)
+ ((Player*)caster)->SetSpellModTakingSpell(modSpell, false);
+}
- if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
+void AuraEffect::Update(uint32 diff)
+{
+ if (m_isPeriodic && (GetParentAura()->GetAuraDuration() >=0 || GetParentAura()->IsPassive() || GetParentAura()->IsPermanent()))
{
- m_periodicTimer -= diff;
- if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
+ if(m_periodicTimer > diff)
+ m_periodicTimer -= diff;
+ else // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
{
++m_tickNumber;
- if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
- m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
- // Cannibalize, eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
- // Eating items and other spells
- m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
- {
- ApplyModifier(true);
- return;
- }
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
- m_periodicTimer += m_modifier.periodictime;
+ m_periodicTimer += m_amplitude - diff;
if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
- {
- if(m_isTrigger)
- TriggerSpell();
- else
- PeriodicTick();
- }
+ PeriodicTick();
}
}
}
-void AreaAura::Update(uint32 diff)
+void AreaAuraEffect::Update(uint32 diff)
{
// update for the caster of the aura
- if(m_caster_guid == m_target->GetGUID())
+ if(m_sourceGUID == m_target->GetGUID())
{
- Unit* caster = m_target;
+ Unit *source = m_target;
+ Unit *caster = GetCaster();
+ if (!caster)
+ {
+ m_target->RemoveAura(GetParentAura());
+ return;
+ }
- if( !caster->hasUnitState(UNIT_STAT_ISOLATED) )
+ if( !source->hasUnitState(UNIT_STAT_ISOLATED) )
{
std::list<Unit *> targets;
switch(m_areaAuraType)
{
case AREA_AURA_PARTY:
- caster->GetPartyMember(targets, m_radius);
+ source->GetPartyMember(targets, m_radius);
+ break;
+ case AREA_AURA_RAID:
+ source->GetRaidMember(targets, m_radius);
break;
case AREA_AURA_FRIEND:
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(caster, caster, m_radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
- caster->VisitNearbyObject(m_radius, searcher);
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(source, caster, m_radius);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(source, targets, u_check);
+ source->VisitNearbyObject(m_radius, searcher);
break;
}
case AREA_AURA_ENEMY:
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(caster, caster, m_radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(targets, u_check);
- caster->VisitNearbyObject(m_radius, searcher);
+ 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);
break;
}
case AREA_AURA_OWNER:
@@ -647,10 +758,28 @@ void AreaAura::Update(uint32 diff)
}
}
- for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
+ for(std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
{
- if((*tIter)->HasAura(GetId(), m_effIndex))
- continue;
+ if(Aura *aur = (*tIter)->GetAura(GetId(), GetCasterGUID()))
+ {
+ if(aur->HasEffect(GetEffIndex()))
+ continue;
+ }
+ else
+ {
+ bool skip = false;
+ for(Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end();++iter)
+ {
+ bool samecaster = iter->second->GetCasterGUID() == GetCasterGUID();
+ if(spellmgr.IsNoStackSpellDueToSpell(GetId(), iter->first, samecaster))
+ {
+ skip = true;
+ break;
+ }
+ }
+ if(skip)
+ continue;
+ }
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
{
@@ -658,152 +787,217 @@ void AreaAura::Update(uint32 diff)
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
//if(actualSpellInfo != GetSpellProto())
// actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
- AreaAura *aur;
- if(actualSpellInfo == GetSpellProto())
- aur = new AreaAura(actualSpellInfo, m_effIndex, &m_modifier.m_amount, (*tIter), caster, NULL);
- else
- aur = new AreaAura(actualSpellInfo, m_effIndex, NULL, (*tIter), caster, NULL);
- (*tIter)->AddAura(aur);
+ (*tIter)->AddAuraEffect(actualSpellInfo, GetEffIndex(), caster, &m_currentBasePoints, source);
if(m_areaAuraType == AREA_AURA_ENEMY)
caster->CombatStart(*tIter);
}
}
}
- Aura::Update(diff);
+ AuraEffect::Update(diff);
}
else // aura at non-caster
{
- Unit * tmp_target = m_target;
- Unit* caster = GetCaster();
- uint32 tmp_spellId = GetId(), tmp_effIndex = m_effIndex;
-
// WARNING: the aura may get deleted during the update
// DO NOT access its members after update!
- Aura::Update(diff);
+ AuraEffect::Update(diff);
+
+ // Speedup - no need to do more checks
+ if (GetParentAura()->IsRemoved())
+ return;
+
+ // Caster may be deleted due to update
+ Unit *caster = GetCaster();
+ Unit *source = GetSource();
// remove aura if out-of-range from caster (after teleport for example)
// or caster is isolated or caster no longer has the aura
// or caster is (no longer) friendly
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
- if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
- !caster->IsWithinDistInMap(tmp_target, m_radius) ||
- !caster->HasAura(tmp_spellId, tmp_effIndex) ||
- caster->IsFriendlyTo(tmp_target) != needFriendly
+ if( !source || !caster ||
+ source->hasUnitState(UNIT_STAT_ISOLATED) || !source->HasAuraEffect(GetId(), m_effIndex) ||
+ caster->IsFriendlyTo(m_target) != needFriendly
)
{
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ m_target->RemoveAura(GetParentAura());
}
- else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
+ else if (!source->IsWithinDistInMap(m_target, m_radius))
{
- if(!tmp_target->IsInPartyWith(caster))
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ if (needFriendly)
+ {
+ m_removeTime -= diff;
+ if (m_removeTime < 0)
+ m_target->RemoveAura(GetParentAura());
+ }
+ else
+ m_target->RemoveAura(GetParentAura());
}
- else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
+ else
{
- if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
+ // Reset aura remove timer
+ m_removeTime = FRIENDLY_AA_REMOVE_TIME;
+ if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
+ {
+ if(!m_target->IsInPartyWith(caster))
+ m_target->RemoveAura(GetParentAura());
+ }
+ else if( m_areaAuraType == AREA_AURA_RAID)
+ {
+ if(!m_target->IsInRaidWith(caster))
+ m_target->RemoveAura(GetParentAura());
+ }
+ else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
+ {
+ if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
+ m_target->RemoveAura(GetParentAura());
+ }
}
}
}
-void PersistentAreaAura::Update(uint32 diff)
+void PersistentAreaAuraEffect::Update(uint32 diff)
{
- bool remove = false;
-
- // 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
- Unit *caster = GetCaster();
- if (caster)
+ if(Unit *caster = GetParentAura()->GetCaster())
{
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
+ if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
{
- if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- remove = true;
+ if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
+ {
+ AuraEffect::Update(diff);
+ return;
+ }
}
- else
- remove = true;
}
- else
- remove = true;
- Unit *tmp_target = m_target;
- uint32 tmp_id = GetId(), tmp_index = GetEffIndex();
+ // remove the aura if its caster or the dynamic object causing it was removed
+ // or if the target moves too far from the dynamic object
+ m_target->RemoveAura(GetParentAura());
+}
+
+void AuraEffect::ApplyModifier(bool apply, bool Real, bool changeAmount)
+{
+ if (GetParentAura()->IsRemoved())
+ return;
- // WARNING: the aura may get deleted during the update
- // DO NOT access its members after update!
- Aura::Update(diff);
+ (*this.*AuraHandler [m_auraName])(apply,Real, changeAmount);
+}
- if(remove)
- tmp_target->RemoveAura(tmp_id, tmp_index);
+void AuraEffect::RecalculateAmount(bool applied)
+{
+ Unit *caster = GetParentAura()->GetCaster();
+ int32 amount = GetParentAura()->GetStackAmount() * (caster ? caster->CalculateSpellDamage(m_spellProto, GetEffIndex(), GetBasePoints(), NULL) : GetBasePoints());
+ // Reapply if amount change
+ if (amount!=GetAmount())
+ {
+ // Auras which are applying spellmod should have removed spellmods for real
+ if (applied)
+ ApplyModifier(false,false,true);
+ SetAmount(amount);
+ if (applied)
+ ApplyModifier(true,false,true);
+ }
}
-void Aura::ApplyModifier(bool apply, bool Real)
+void AuraEffect::CleanupTriggeredSpells()
{
- AuraType aura = m_modifier.m_auraname;
+ 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_in_use = true;
- if(aura<TOTAL_AURAS)
- (*this.*AuraHandler [aura])(apply,Real);
- m_in_use = false;
+ m_target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
}
-void Aura::UpdateAuraDuration()
+void Aura::ApplyAllModifiers(bool apply, bool Real)
{
- if(m_auraSlot >= MAX_AURAS || m_isPassive)
+ 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);
- if( m_target->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
- data << (uint8)m_auraSlot << (uint32)m_duration;
- ((Player*)m_target)->SendDirectMessage(&data);
+ data.append(m_target->GetPackGUID());
+ data << uint8(m_auraSlot);
- data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4));
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
- data << uint32(GetId());
- data << uint32(GetAuraMaxDuration());
- data << uint32(GetAuraDuration());
- ((Player*)m_target)->SendDirectMessage(&data);
+ 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;
}
- // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
- if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading())
- return;
+ data << uint32(GetId());
+ data << uint8(m_auraFlags);
+ data << uint8(m_auraLevel);
+ data << uint8(m_stackAmount>1 ? m_stackAmount : m_procCharges);
- Unit* caster = GetCaster();
+ if(!(m_auraFlags & AFLAG_CASTER))
+ {
+ if (Unit * caster = GetCaster())
+ data.append(caster->GetPackGUID());
+ else
+ data << uint8(0);
+ }
- if(caster && caster->GetTypeId() == TYPEID_PLAYER)
+ if(m_auraFlags & AFLAG_DURATION)
{
- SendAuraDurationForCaster((Player*)caster);
+ data << uint32(m_maxduration);
+ data << uint32(m_duration);
+ }
+
+ m_target->SendMessageToSet(&data, true);
+}
- Group* CasterGroup = ((Player*)caster)->GetGroup();
- if (CasterGroup && (spellmgr.GetSpellCustomAttr(GetId()) & SPELL_ATTR_CU_AURA_CC))
+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])
{
- for (GroupReference *itr = CasterGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ if(m_partAuras[i]->IsAreaAura())
{
- Player* player = itr->getSource();
- if(player && player != caster)
- SendAuraDurationForCaster(player);
+ 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;
}
}
-}
-void Aura::SendAuraDurationForCaster(Player* caster)
-{
- if (caster == m_target)
- return;
+ if(noneAreaAura)
+ return false;
- WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4));
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
- data << uint32(GetId());
- data << uint32(GetAuraMaxDuration()); // full
- data << uint32(GetAuraDuration()); // remain
- caster->GetSession()->SendPacket(&data);
+ return IsAuraType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
}
void Aura::_AddAura()
@@ -813,334 +1007,631 @@ void Aura::_AddAura()
if(!m_target)
return;
- // we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
- bool secondaura = false;
- uint8 slot = NULL_AURA_SLOT;
+ Unit* caster = GetCaster();
+
+ // set infinity cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ {
+ Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL;
+ ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true);
+ }
+ }
- for(uint8 i = 0; i < 3; i++)
+ if(IsVisible())
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ // Try find slot for aura
+ uint8 slot = MAX_AURAS;
+ // Lookup for auras already applied from spell
+ if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
{
// allow use single slot only by auras from same caster
- if(itr->second->GetCasterGUID()==GetCasterGUID())
+ slot = foundAura->GetAuraSlot();
+ }
+ else
+ {
+ Unit::VisibleAuraMap const * visibleAuras= m_target->GetVisibleAuras();
+ // lookup for free slots in units visibleAuras
+ Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0);
+ for(uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr , ++freeSlot)
{
- secondaura = true;
- slot = itr->second->GetAuraSlot();
- break;
+ if(itr == visibleAuras->end() || itr->first != freeSlot)
+ {
+ slot = freeSlot;
+ break;
+ }
}
}
- if(secondaura)
- break;
+ // Register Visible Aura
+ if(slot < MAX_AURAS)
+ {
+ m_auraFlags |= (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) |
+ (GetCasterGUID() == m_target->GetGUID() ? AFLAG_CASTER : AFLAG_NONE) |
+ (GetAuraMaxDuration() > 0 ? AFLAG_DURATION : AFLAG_NONE);
+ m_auraLevel = (caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ SetAuraSlot( slot );
+ m_target->SetVisibleAura(slot, this);
+ m_target->UpdateAuraForGroup(slot);
+ SendAuraUpdate();
+ sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffectMask(), slot);
+ }
+ else
+ sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffectMask());
}
- Unit* caster = GetCaster();
-
- // not call total regen auras at adding
- switch (m_modifier.m_auraname)
- {
- /*case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- if(caster)
- m_modifier.m_amount = caster->SpellDamageBonus(m_target, m_spellProto, m_modifier.m_amount, DOT);
- break;
- case SPELL_AURA_PERIODIC_HEAL:
- if(caster)
- m_modifier.m_amount = caster->SpellHealingBonus(m_spellProto, m_modifier.m_amount, DOT, m_target);
- break;*/
- case SPELL_AURA_OBS_MOD_HEALTH:
- case SPELL_AURA_OBS_MOD_MANA:
- m_periodicTimer = m_modifier.periodictime;
- break;
- case SPELL_AURA_MOD_REGEN:
- case SPELL_AURA_MOD_POWER_REGEN:
- case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
- m_periodicTimer = 5000;
- break;
- }
+ // Sitdown on apply aura req seated
+ if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
+ m_target->SetStandState(UNIT_STAND_STATE_SIT);
- // register aura
+ // register aura diminishing on apply
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),true);
- // passive auras (except totem auras) do not get placed in the slots
- // area auras with SPELL_AURA_NONE are not shown on target
- if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
- (m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
+ // Apply linked auras (On first aura apply)
+ uint32 id = GetId();
+ if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
{
- if(!secondaura) // new slot need
- {
- if (IsPositive()) // empty positive slot
+ 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)
{
- for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
- }
- else // empty negative slot
- {
- for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
- {
- if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
- {
- slot = i;
- break;
- }
- }
+ if(*itr < 0)
+ m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), true);
+ else if(Unit* caster = GetCaster())
+ caster->AddAura(*itr, m_target);
}
+ }
- SetAuraSlot( slot );
+ //*****************************************************
+ // Update target aura state flag
+ //*****************************************************
- // Not update fields for not first spell's aura, all data already in fields
- if(slot < MAX_AURAS) // slot found
- {
- SetAura(slot, false);
- SetAuraFlag(slot, true);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- UpdateAuraCharges();
+ // Update Seals information
+ if (IsSealSpell(m_spellProto))
+ SetAuraState(AURA_STATE_JUDGEMENT);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
- }
- }
- else // use found slot
- {
- SetAuraSlot( slot );
- }
+ // Conflagrate aura state on Immolate or Shadowflame
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (m_spellProto->SpellFamilyFlags[0] & 4
+ || m_spellProto->SpellFamilyFlags[2] & 2))
+ SetAuraState(AURA_STATE_IMMOLATE);
- UpdateSlotCounterAndDuration();
+ // Faerie Fire (druid versions)
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x400)
+ SetAuraState(AURA_STATE_FAERIE_FIRE);
+
+ // Victorious
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x00040000)
+ SetAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH);
- // Update Seals information
- if( IsSealSpell(GetSpellProto()) )
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
+ // Swiftmend state on Regrowth & Rejuvenation
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x50 )
+ SetAuraState(AURA_STATE_SWIFTMEND);
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
+ // Deadly poison aura state
+ if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x10000)
+ SetAuraState(AURA_STATE_DEADLY_POISON);
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+ // Enrage aura state
+ if(m_spellProto->Dispel == DISPEL_ENRAGE)
+ SetAuraState(AURA_STATE_ENRAGE);
+
+ if(GetSpellSchoolMask(m_spellProto) & SPELL_SCHOOL_MASK_FROST)
+ {
+ for (uint8 i = 0;i<MAX_SPELL_EFFECTS;++i)
{
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
+ if (m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_STUN
+ || m_spellProto->EffectApplyAuraName[i]==SPELL_AURA_MOD_ROOT)
+ {
+ SetAuraState(AURA_STATE_FROZEN);
+ break;
+ }
}
}
+
+ m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, GetAuraStateMask(), true);
+}
+
+bool Aura::SetPartAura(AuraEffect* aurEff, uint8 effIndex)
+{
+ if (IsRemoved())
+ return false;
+ if (m_auraFlags & (1<<effIndex))
+ return false;
+ m_auraFlags |= 1<<effIndex;
+ m_partAuras[effIndex]=aurEff;
+ m_target->HandleAuraEffect(aurEff, true);
+ SendAuraUpdate();
+ return true;
}
void Aura::_RemoveAura()
{
Unit* caster = GetCaster();
- if(caster && IsPersistent())
+ uint8 slot = GetAuraSlot();
+
+ if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
+ {
+ // allow use single slot only by auras from same caster
+ slot = foundAura->GetAuraSlot();
+ if(slot < MAX_AURAS) // slot not set
+ if (Aura *entry = m_target->GetVisibleAura(slot))
+ {
+ // set not valid slot for aura - prevent removing other visible aura
+ slot = MAX_AURAS;
+ }
+ }
+
+ // update for out of range group members
+ if (slot < MAX_AURAS)
{
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
- dynObj->RemoveAffected(m_target);
+ m_target->RemoveVisibleAura(slot);
+ m_target->UpdateAuraForGroup(slot);
+ SendAuraUpdate();
}
- // unregister aura
+ // unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),false);
- //passive auras do not get put in slots
- // Note: but totem can be not accessible for aura target in time remove (to far for find in grid)
- //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
- // return;
-
- uint8 slot = GetAuraSlot();
-
- if(slot >= MAX_AURAS) // slot not set
- return;
+ // 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)
+ {
+ foundMask|=(*i).second->GetAuraStateMask();
+ }
+ // Remove only aurastates which were not found
+ foundMask = GetAuraStateMask() &~foundMask;
+ if (foundMask)
+ m_target->ApplyModFlag(UNIT_FIELD_AURASTATE, foundMask, false);
+ }
- if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
- return;
+ // since now aura cannot apply/remove it's modifiers
+ m_isRemoved = true;
+ // disable client server communication for removed aura
+ SetAuraSlot(MAX_AURAS);
- bool samespell = false;
+ // reset cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ ((Player*)caster)->SendCooldownEvent(GetSpellProto());
+ }
+ uint32 id = GetId();
+ // Remove Linked Auras
+ if(m_removeMode!=AURA_REMOVE_BY_STACK && m_removeMode!=AURA_REMOVE_BY_DEATH && spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_REMOVE)
+ {
+ 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)
+ {
+ if(*itr < 0)
+ m_target->RemoveAurasDueToSpell(-(*itr));
+ else if(Unit* caster = GetCaster())
+ if (m_removeMode!=AURA_REMOVE_BY_DEFAULT)
+ m_target->CastSpell(m_target, *itr, true, 0, 0, caster->GetGUID());
+ }
+ }
+ if(m_removeMode!=AURA_REMOVE_BY_STACK && m_removeMode!=AURA_REMOVE_BY_DEATH && spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
+ {
+ 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)
+ {
+ if(*itr < 0)
+ m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), false);
+ else
+ m_target->RemoveAurasDueToSpell(*itr);
+ }
+ }
- // find other aura in same slot (current already removed from list)
- for(uint8 i = 0; i < 3; i++)
+ // Proc on aura remove (only spell flags for now)
+ if (caster)
{
- Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
- for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
+ uint32 procEx=0;
+ if (m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL)
+ procEx = PROC_EX_AURA_REMOVE_DESTROY;
+ else if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL)
+ procEx = PROC_EX_AURA_REMOVE_EXPIRE;
+ if (procEx)
{
- if(itr->second->GetAuraSlot()==slot)
+ uint32 ProcCaster, ProcVictim;
+ if (IsPositiveSpell(GetId()))
{
- samespell = true;
+ 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);
+ }
+ }
+}
- break;
+void Aura::SetStackAmount(uint8 stackAmount, bool applied)
+{
+ if (stackAmount != m_stackAmount)
+ {
+ m_stackAmount = stackAmount;
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (AuraEffect * part = GetPartAura(i))
+ {
+ part->RecalculateAmount(applied);
}
}
- if(samespell)
- break;
}
+ RefreshAura();
+}
- // only remove icon when the last aura of the spell is removed (current aura already removed from list)
- if (!samespell)
+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
{
- SetAura(slot, true);
- SetAuraFlag(slot, false);
- SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ m_stackAmount = 0;
+ return true; // need remove aura
+ }
- SetAuraApplication(slot, 0);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
+ // Update stack amount
+ SetStackAmount(stackAmount);
+ return false;
+}
- if( IsSealSpell(GetSpellProto()) )
- m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
+void Aura::SetAuraDuration(int32 duration, bool withMods)
+{
+ if (withMods)
+ {
+ if (Player * modOwner = m_target->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration);
+ }
+ m_duration = duration;
+ //if (duration<0)
+ //m_permanent=true;
+ //else
+ //m_permanent=false;
+ SendAuraUpdate();
+}
- // Conflagrate aura state
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
- m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
+void Aura::SetAuraCharges(uint8 charges)
+{
+ if (m_procCharges == charges)
+ return;
+ m_procCharges = charges;
+ SendAuraUpdate();
+}
- // Swiftmend aura state
- if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+bool Aura::DropAuraCharge()
+{
+ if(m_procCharges) //auras without charges always have charge = 0
+ {
+ if(--m_procCharges) // Send charge change
+ SendAuraUpdate();
+ else // Last charge dropped
{
- bool found = false;
- Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
- for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
- {
- if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
- && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
- {
- found = true;
- break;
- }
- }
- if(!found)
- m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
+ m_target->RemoveAura(this, AURA_REMOVE_BY_EXPIRE);
+ return true;
}
+ }
+ return false;
+}
- // reset cooldown state for spells
- if(caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
- ((Player*)caster)->SendCooldownEvent(GetSpellProto());
- }
+bool Aura::IsPersistent() const
+{
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if(m_partAuras[i] && m_partAuras[i]->IsPersistent())
+ return true;
}
+ return false;
}
-void Aura::SetAuraFlag(uint32 slot, bool add)
+bool Aura::IsAreaAura() const
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index);
- val &= ~((uint32)AFLAG_MASK << byte);
- if(add)
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (IsPositive())
- val |= ((uint32)AFLAG_POSITIVE << byte);
- else
- val |= ((uint32)AFLAG_NEGATIVE << byte);
+ if(m_partAuras[i] && m_partAuras[i]->IsAreaAura())
+ return true;
}
- m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val);
+ return false;
}
-void Aura::SetAuraLevel(uint32 slot,uint32 level)
+bool Aura::IsAuraType(AuraType type) const
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index);
- val &= ~(0xFF << byte);
- val |= (level << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val);
+ for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if(m_partAuras[i] && m_partAuras[i]->GetAuraName() == type)
+ return true;
+ }
+ return false;
}
-void Aura::SetAuraApplication(uint32 slot, int8 count)
+void Aura::SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount)
{
- uint32 index = slot / 4;
- uint32 byte = (slot % 4) * 8;
- uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index);
- val &= ~(0xFF << byte);
- val |= ((uint8(count)) << byte);
- m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val);
+ 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])
+ m_partAuras[i]->SetAmount(amount[i]);
}
-void Aura::UpdateSlotCounterAndDuration()
+void AuraEffect::HandleShapeshiftBoosts(bool apply)
{
- uint8 slot = GetAuraSlot();
- if(slot >= MAX_AURAS)
- return;
+ 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)
+ {
+ const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ if(itr->second->state == PLAYERSPELL_REMOVED) continue;
+ if(itr->first==spellId || itr->first==spellId2) continue;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
+ if (spellInfo->Stances & (1<<form))
+ m_target->CastSpell(m_target, itr->first, true, NULL, this);
+ }
+ //LotP
+ if (((Player*)m_target)->HasSpell(17007))
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
+ if (spellInfo && spellInfo->Stances & (1<<form))
+ m_target->CastSpell(m_target, 24932, true, NULL, this);
+ }
+ // 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;
+
+ m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ m_target->RemoveAurasDueToSpell(spellId);
+ m_target->RemoveAurasDueToSpell(spellId2);
+
+ Unit::AuraMap& tAuras = m_target->GetAuras();
+ for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
+ {
+ if (itr->second->IsRemovedOnShapeLost())
+ {
+ m_target->RemoveAura(itr);
+ }
+ else
+ {
+ ++itr;
+ }
+ }
+ }
+}
+
+bool AuraEffect::isAffectedOnSpell(SpellEntry const *spell) const
+{
+ if (!spell)
+ return false;
+ // Check family name
+ if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
+ return false;
+
+ // Check EffectClassMask and Spell_Affect table
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
- // Three possibilities:
- // Charge = 0; Stack >= 0
- // Charge = 1; Stack >= 0
- // Charge > 1; Stack = 0
- if(m_procCharges < 2)
- SetAuraApplication(slot, m_stackAmount-1);
+ if (*spellAffect & spell->SpellFamilyFlags)
+ return true;
+ return false;
+}
- UpdateAuraDuration();
+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;
+ }
}
/*********************************************************/
/*** BASIC AURA FUNCTION ***/
/*********************************************************/
-void Aura::HandleAddModifier(bool apply, bool Real)
+void AuraEffect::HandleAddModifier(bool apply, bool Real, bool changeAmount)
{
- if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)
+ if(m_target->GetTypeId() != TYPEID_PLAYER || (!Real && !changeAmount))
return;
- SpellEntry const *spellInfo = GetSpellProto();
- if(!spellInfo)
- return;
+ uint32 modOp = GetMiscValue();
- if(m_modifier.m_miscvalue >= MAX_SPELLMOD)
+ if(modOp >= MAX_SPELLMOD)
return;
if (apply)
{
- // Add custom charges for some mod aura
- switch (m_spellProto->Id)
- {
- case 17941: // Shadow Trance
- case 22008: // Netherwind Focus
- case 34936: // Backlash
- m_procCharges = 1;
- break;
- }
-
- SpellModifier *mod = new SpellModifier;
- mod->op = SpellModOp(m_modifier.m_miscvalue);
- mod->value = GetModifierValue();
- mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types
+ SpellModifier *mod = new SpellModifier(GetParentAura());
+ mod->op = SpellModOp(modOp);
+ mod->value = m_amount;
+ mod->type = SpellModType(m_auraName); // SpellModType value == spell aura types
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
-
- uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex);
-
- if (spellAffectMask)
- mod->mask = spellAffectMask;
- else
- mod->mask = spellInfo->EffectItemType[m_effIndex];
- if (m_procCharges > 0)
- mod->charges = m_procCharges;
- else
- mod->charges = 0;
+ flag96 const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex);
+ if (!spellAffect)
+ spellAffect = &m_spellProto->EffectSpellClassMask[m_effIndex];
+ mod->mask = *spellAffect;
+ mod->charges = GetParentAura()->GetAuraCharges();
m_spellmod = mod;
}
- uint64 spellFamilyMask = m_spellmod->mask;
-
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
+ // Auras with charges do not mod amount of passive auras
+ if (GetParentAura()->GetAuraCharges())
+ return;
// reapply some passive spells after add/remove related spellmods
- if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))
+ // Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
+ switch (modOp)
{
- m_target->RemoveAurasDueToSpell(45471);
-
- if(apply)
- m_target->CastSpell(m_target,45471,true);
+ case SPELLMOD_ALL_EFFECTS:
+ case SPELLMOD_EFFECT1:
+ case SPELLMOD_EFFECT2:
+ case SPELLMOD_EFFECT3:
+ {
+ uint64 guid = m_target->GetGUID();
+ 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
+ // if aura is casted by others, it will not be affected
+ if (aur->IsPassive() && aur->GetCasterGUID() == guid && spellmgr.IsAffectedByMod(aur->GetSpellProto(), m_spellmod))
+ {
+ 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;
}
}
-void Aura::TriggerSpell()
+void AuraEffect::TriggerSpell()
{
Unit* caster = GetCaster();
Unit* target = GetTriggerTarget();
@@ -1151,8 +1642,6 @@ void Aura::TriggerSpell()
// generic casting code with custom spells and target/caster customs
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
- uint64 originalCasterGUID = GetCasterGUID();
-
SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
SpellEntry const *auraSpellInfo = GetSpellProto();
uint32 auraId = auraSpellInfo->Id;
@@ -1191,7 +1680,7 @@ void Aura::TriggerSpell()
}
// remove old enchanting before applying new
((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false);
- item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_modifier.periodictime+1000, 0);
+ item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_amplitude+1000, 0);
// add new enchanting
((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true);
return;
@@ -1237,8 +1726,7 @@ void Aura::TriggerSpell()
case 23493:
{
int32 heal = caster->GetMaxHealth() / 10;
- caster->ModifyHealth( heal );
- caster->SendHealSpellLog(caster, 23493, heal);
+ caster->DealHeal(caster, heal, auraSpellInfo);
int32 mana = caster->GetMaxPower(POWER_MANA);
if (mana)
@@ -1247,7 +1735,7 @@ void Aura::TriggerSpell()
caster->ModifyPower( POWER_MANA, mana );
caster->SendEnergizeSpellLog(caster, 23493, mana, POWER_MANA);
}
- break;
+ return;
}
// // Stoneclaw Totem Passive TEST
// case 23792: break;
@@ -1304,10 +1792,21 @@ void Aura::TriggerSpell()
} break;
// // Steam Tank Passive
// case 27747: break;
-// // Frost Blast
-// case 27808: break;
-// // Detonate Mana
-// case 27819: break;
+ // Frost Blast
+ case 27808:
+ caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, target->GetMaxHealth()*0.26f, m_target, true, NULL, this);
+ return;
+ // Detonate Mana
+ case 27819:
+ {
+ 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());
+ }
+ return;
+ }
// // Controller Timer
// case 28095: break;
// // Stalagg Chain
@@ -1326,8 +1825,11 @@ void Aura::TriggerSpell()
// case 28522: break;
// // Silithyst
// case 29519: break;
-// // Inoculate Nestlewood Owlkin
- case 29528: trigger_spell_id = 28713; break;
+ // Inoculate Nestlewood Owlkin
+ case 29528:
+ if(target->GetTypeId()!=TYPEID_UNIT)// prevent error reports in case ignored player target
+ return;
+ break;
// // Overload
// case 29768: break;
// // Return Fire
@@ -1360,32 +1862,15 @@ void Aura::TriggerSpell()
Creature* creature = (Creature*)target;
// missing lootid has been reported on startup - just return
if (!creature->GetCreatureInfo()->SkinLootId)
- {
return;
- }
- Loot *loot = &creature->loot;
- loot->clear();
- loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, NULL);
- for(uint8 i=0;i<loot->items.size();i++)
- {
- LootItem *item = loot->LootItemInSlot(i,player);
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item->itemid, item->count );
- if ( msg == EQUIP_ERR_OK )
- {
- Item * newitem = player->StoreNewItem( dest, item->itemid, true, item->randomPropertyId);
-
- player->SendNewItem(newitem, uint32(item->count), false, false, true);
- }
- else
- player->SendEquipError( msg, NULL, NULL );
- }
+
+ player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId,LootTemplates_Skinning,true);
+
creature->setDeathState(JUST_DIED);
creature->RemoveCorpse();
creature->SetHealth(0); // just for nice GM-mode view
}
return;
- break;
}
// Quake
case 30576: trigger_spell_id = 30571; break;
@@ -1405,7 +1890,7 @@ void Aura::TriggerSpell()
// Doom
case 31347:
{
- m_target->CastSpell(m_target,31350,true);
+ m_target->CastSpell(m_target,31350,true, NULL, this);
m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
return;
}
@@ -1435,9 +1920,9 @@ void Aura::TriggerSpell()
{
// cast 24 spells 34269-34289, 34314-34316
for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
- caster->CastSpell(m_target,spell_id,true);
+ caster->CastSpell(m_target,spell_id,true, NULL, this);
for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
- caster->CastSpell(m_target,spell_id,true);
+ caster->CastSpell(m_target,spell_id,true, NULL, this);
return;
}
// // Gravity Lapse
@@ -1519,7 +2004,7 @@ void Aura::TriggerSpell()
// Eye of Grillok
case 38495:
{
- m_target->CastSpell(m_target, 38530, true);
+ m_target->CastSpell(m_target, 38530, true, NULL, this);
return;
}
// Absorb Eye of Grillok (Zezzak's Shard)
@@ -1528,7 +2013,7 @@ void Aura::TriggerSpell()
if(m_target->GetTypeId() != TYPEID_UNIT)
return;
- caster->CastSpell(caster, 38495, true);
+ caster->CastSpell(caster, 38495, true, NULL, this);
Creature* creatureTarget = (Creature*)m_target;
@@ -1588,13 +2073,13 @@ void Aura::TriggerSpell()
// Aura of Desire
case 41350:
{
- Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT);
- for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+ 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)
{
if ((*i)->GetId() == 41350)
{
(*i)->ApplyModifier(false);
- (*i)->GetModifier()->m_amount -= 5;
+ (*i)->SetAmount((*i)->GetAmount()-5);
(*i)->ApplyModifier(true);
break;
}
@@ -1635,11 +2120,8 @@ void Aura::TriggerSpell()
{
// Invisibility
case 66:
- {
- if(!m_duration)
- m_target->CastSpell(m_target, 32612, true, NULL, this);
+ // Here need periodic triger reducing threat spell (or do it manually)
return;
- }
default:
break;
}
@@ -1685,7 +2167,7 @@ void Aura::TriggerSpell()
case 22896:
case 26999:
{
- int32 LifePerRage = GetModifier()->m_amount;
+ int32 LifePerRage = GetAmount();
int32 lRage = m_target->GetPower(POWER_RAGE);
if(lRage > 100) // rage stored as rage*10
@@ -1749,7 +2231,7 @@ void Aura::TriggerSpell()
{
SpellEntry const* spell = itr->second->GetSpellProto();
if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN &&
- spell->SpellFamilyFlags & 0x0000000000000400L)
+ spell->SpellFamilyFlags[0] & 0x400)
return;
}
target->RemoveAurasDueToSpell(28820);
@@ -1759,9 +2241,9 @@ void Aura::TriggerSpell()
case 38443:
{
bool all = true;
- for(int i = 0; i < MAX_TOTEM; ++i)
+ for(int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
{
- if(!caster->m_TotemSlot[i])
+ if(!caster->m_SummonSlot[i])
{
all = false;
break;
@@ -1769,7 +2251,7 @@ void Aura::TriggerSpell()
}
if(all)
- caster->CastSpell(caster,38437,true);
+ caster->CastSpell(caster,38437,true, NULL, this);
else
caster->RemoveAurasDueToSpell(38437);
return;
@@ -1782,13 +2264,9 @@ void Aura::TriggerSpell()
default:
break;
}
+
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
- if(triggeredSpellInfo == NULL)
- {
- sLog.outError("Aura::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
- return;
- }
}
else
{
@@ -1805,22 +2283,22 @@ void Aura::TriggerSpell()
// 2) maybe aura must be replace by new with accumulative stat mods instead stacking
// prevent cast by triggered auras
- if(m_caster_guid == m_target->GetGUID())
+ if(GetCasterGUID() == m_target->GetGUID())
return;
// stop triggering after each affected stats lost > 90
int32 intellectLoss = 0;
int32 spiritLoss = 0;
- Unit::AuraList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
- for(Unit::AuraList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
+ Unit::AuraEffectList const& mModStat = m_target->GetAurasByType(SPELL_AURA_MOD_STAT);
+ for(Unit::AuraEffectList::const_iterator i = mModStat.begin(); i != mModStat.end(); ++i)
{
if ((*i)->GetId() == 1010)
{
- switch((*i)->GetModifier()->m_miscvalue)
+ switch((*i)->GetMiscValue())
{
- case STAT_INTELLECT: intellectLoss += (*i)->GetModifierValue(); break;
- case STAT_SPIRIT: spiritLoss += (*i)->GetModifierValue(); break;
+ case STAT_INTELLECT: intellectLoss += (*i)->GetAmount(); break;
+ case STAT_SPIRIT: spiritLoss += (*i)->GetAmount(); break;
default: break;
}
}
@@ -1830,54 +2308,87 @@ void Aura::TriggerSpell()
return;
caster = target;
- originalCasterGUID = 0;
break;
}
// Mana Tide
case 16191:
{
- caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
+ caster->CastCustomSpell(target, trigger_spell_id, &m_amount, NULL, NULL, true, NULL, this);
return;
}
// Negative Energy Periodic
case 46284:
- {
- caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this, originalCasterGUID);
+ caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this);
+ return;
+ // 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);
+ return;
+ // Mind Sear (target 76/16) if let m_target cast, will damage caster
+ case 48045:
+ case 53023:
+ // Curse of the Plaguebringer (22/15)
+ case 29213:
+ case 54835:
+ caster->CastSpell(m_target, trigger_spell_id, true, NULL, this);
return;
- }
}
}
- if(!GetSpellMaxRange(sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
- target = m_target; //for druid dispel poison
- m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, originalCasterGUID);
+
+ if(triggeredSpellInfo)
+ {
+ if(!caster->GetSpellMaxRangeForTarget(m_target,sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
+ target = m_target; //for druid dispel poison
+ m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, GetCasterGUID());
+ }
+ else if(target->GetTypeId()!=TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target))
+ sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
}
-Unit* Aura::GetTriggerTarget() const
+Unit* AuraEffect::GetTriggerTarget() const
{
- Unit* target = ObjectAccessor::GetUnit(*m_target,
- /*m_target->GetTypeId()==TYPEID_PLAYER ?
- ((Player*)m_target)->GetSelection() :*/
- m_target->GetUInt64Value(UNIT_FIELD_TARGET));
+ Unit* target = ObjectAccessor::GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET));
return target ? target : m_target;
}
+void AuraEffect::TriggerSpellWithValue()
+{
+ 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];
+ int32 basepoints0 = this->GetAmount();
+
+ caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
+}
+
/*********************************************************/
/*** AURA EFFECTS ***/
/*********************************************************/
-void Aura::HandleAuraDummy(bool apply, bool Real)
+void AuraEffect::HandleAuraDummy(bool apply, bool Real, bool changeAmount)
{
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
Unit* caster = GetCaster();
+ // spells required only Real aura add/remove
+ if (Real)
+ {
// AT APPLY
if(apply)
{
switch(GetId())
{
+ // Haunting Spirits - perdiodic trigger demon
+ case 7057:
+ m_isPeriodic = true;
+ m_amplitude = irand (0, 60) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ return;
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())
@@ -1888,13 +2399,50 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
if(caster)
caster->CastSpell(caster,13138,true,NULL,this);
return;
+ case 34026: // kill command
+ {
+ Unit * pet = m_target->GetGuardianPet();
+ 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)
+ Aura* owner_aura = m_target->GetAura(34027,GetCasterGUID());
+ Aura* pet_aura = pet->GetAura(58914, GetCasterGUID());
+ 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)
+ Aura* owner_aura = m_target->GetAura(55166,GetCasterGUID());
+ if( owner_aura )
+ {
+ // This aura lasts 2 sec, need this hack to properly proc spells
+ // TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
+ GetParentAura()->SetAuraDuration(owner_aura->GetAuraDuration());
+ // 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;
+ }
case 39850: // Rocket Blast
if(roll_chance_i(20)) // backfire stun
m_target->CastSpell(m_target, 51581, true, NULL, this);
return;
case 43873: // Headless Horseman Laugh
- if(caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)caster)->SendPlaySound(11965, false);
+ m_target->PlayDistanceSound(11965);
return;
case 46354: // Blood Elf Illusion
if(caster)
@@ -1919,24 +2467,26 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
// Earth Shield
- if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL))
+ if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags[1] & 0x400))
{
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
return;
}
+ //Druid, Survival Instincts
+ if(GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags[2]& 0x40 )
+ {
+ if(!m_target)
+ return;
+
+ int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
+ m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ }
}
// AT REMOVE
else
{
- if( m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->Effect[0]==72 )
- {
- // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
- ((Player*)m_target)->ClearFarsight();
- return;
- }
-
if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive())
{
uint32 finalSpelId = 0;
@@ -1990,6 +2540,37 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_target->SetReducedThreatPercent(0, 0);
return;
}
+
+ // Wrath of the Astromancer
+ if (GetId()==42783)
+ {
+ m_target->CastSpell(m_target,m_amount,true,NULL,this);
+ return;
+ }
+
+ switch(m_spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_WARLOCK:
+ // Haunt
+ if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
+ {
+ int32 bp0 = GetParentAura()->GetProcDamage() * m_amount / 100;
+ if(caster)
+ caster->CastCustomSpell(caster, 48210, &bp0, 0, 0, true, NULL, this);
+ return;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ // Living Bomb
+ if(m_spellProto->SpellFamilyFlags[1] & 0x20000)
+ {
+ if(caster && (GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL || GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE))
+ caster->CastSpell(m_target, GetAmount(), true);
+ return;
+ }
+ break;
+ }
+ }
}
// AT APPLY & REMOVE
@@ -1998,105 +2579,210 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
case SPELLFAMILY_GENERIC:
{
- // Unstable Power
- if( GetId()==24658 )
+ if (!Real)
+ break;
+ switch(GetId())
{
- uint32 spellId = 24659;
- if (apply)
+ // Unstable Power
+ case 24658:
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
+ uint32 spellId = 24659;
+ 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());
return;
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ }
+ m_target->RemoveAurasDueToSpell(spellId);
return;
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
- }
- // Restless Strength
- if( GetId()==24661 )
- {
- uint32 spellId = 24662;
- if (apply)
+ // Restless Strength
+ case 24661:
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
+ 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());
return;
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ }
+ m_target->RemoveAurasDueToSpell(spellId);
return;
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
- }
- // Victorious
- if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
- {
- m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
- return;
- }
- //Summon Fire Elemental
- if (GetId() == 40133 && caster)
- {
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ //Summon Fire Elemental
+ case 40133:
{
- if(apply)
- owner->CastSpell(owner,8985,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- }
- return;
- }
+ if (!caster)
+ return;
- //Summon Earth Elemental
- if (GetId() == 40132 && caster)
- {
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ 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 :
{
- if(apply)
- owner->CastSpell(owner,19704,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ 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;
}
- return;
+ // 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;
}
break;
}
case SPELLFAMILY_MAGE:
{
- // Hypothermia
- if( GetId()==41425 )
+ //if (!Real)
+ //break;
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ if (!Real && !changeAmount)
+ break;
+ // Pain and Suffering
+ if( m_spellProto->SpellIconID == 2874 && m_target->GetTypeId()==TYPEID_PLAYER )
{
- m_target->ModifyAuraState(AURA_STATE_HYPOTHERMIA,apply);
+ if(apply)
+ {
+ // Reduce backfire damage (dot damage) from Shadow Word: Death
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_amount;
+ mod->type = SPELLMOD_PCT;
+ mod->spellId = GetId();
+ mod->mask[1] = 0x00002000;
+ m_spellmod = mod;
+ }
+ ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
break;
}
case SPELLFAMILY_DRUID:
{
+ if (!Real && !changeAmount)
+ break;
+ switch(GetId())
+ {
+ case 34246: // Idol of the Emerald Queen
+ case 60779: // Idol of Lush Moss
+ {
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ {
+ SpellModifier *mod = new SpellModifier;
+ mod->op = SPELLMOD_DOT;
+ mod->value = m_amount/7;
+ 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
+ {
+ if (!Real)
+ break;
+ if(apply)
+ {
+ if (!m_target->IsInFeralForm())
+ return;
+
+ int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
+ m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ }
+ else
+ m_target-> RemoveAurasDueToSpell(50322);
+ return;
+ }
+ }
+
// Lifebloom
- if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL )
+ if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
{
if ( apply )
{
if ( caster )
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
}
- // Do final heal for real !apply
- else if (Real)
+ else
{
- if (GetAuraDuration() <= 0 || m_removeMode==AURA_REMOVE_BY_DISPEL)
+ // Final heal only on dispelled or duration end
+ if (GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ // final heal
+ if(m_target->IsInWorld())
+ m_target->CastCustomSpell(m_target,33778,&m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+
+ /*// 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)
{
- // final heal
- if(m_target->IsInWorld())
- m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
- }
+ int32 amount = m_amount / m_stackAmount;
+ m_target->CastCustomSpell(m_target,33778,&amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+ }*/
}
return;
}
@@ -2107,50 +2793,27 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
((Player*)m_target)->UpdateAttackPowerAndDamage();
return;
}
- // Idol of the Emerald Queen
- if ( GetId() == 34246 && m_target->GetTypeId()==TYPEID_PLAYER )
- {
- if(apply)
- {
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DOT;
- mod->value = m_modifier.m_amount/7;
- mod->type = SPELLMOD_FLAT;
- mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x001000000000LL;
- mod->charges = 0;
-
- m_spellmod = mod;
- }
-
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
- return;
- }
break;
}
case SPELLFAMILY_HUNTER:
{
- // Improved Aspect of the Viper
- if( GetId()==38390 && m_target->GetTypeId()==TYPEID_PLAYER )
+ if (!Real)
+ break;
+ // Glyph of Aspect of the Monkey
+ if(m_spellProto->Id==56833)
{
if(apply)
{
- // + effect value for Aspect of the Viper
SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_EFFECT1;
- mod->value = m_modifier.m_amount;
+ mod->op = SPELLMOD_CHANCE_OF_SUCCESS;
+ mod->value = 100;
mod->type = SPELLMOD_FLAT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
- mod->mask = 0x4000000000000LL;
- mod->charges = 0;
-
+ mod->mask[2] = 8192;
+ mod->mask[1] = 0x00000000;
+ mod->mask[0] = 524288;
m_spellmod = mod;
}
-
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
@@ -2158,6 +2821,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
case SPELLFAMILY_SHAMAN:
{
+ if (!Real && !changeAmount)
+ break;
// Improved Weapon Totems
if( GetSpellProto()->SpellIconID == 57 && m_target->GetTypeId()==TYPEID_PLAYER )
{
@@ -2165,21 +2830,18 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
SpellModifier *mod = new SpellModifier;
mod->op = SPELLMOD_EFFECT1;
- mod->value = m_modifier.m_amount;
+ mod->value = m_amount;
mod->type = SPELLMOD_PCT;
mod->spellId = GetId();
- mod->effectId = m_effIndex;
- mod->lastAffected = NULL;
switch (m_effIndex)
{
case 0:
- mod->mask = 0x00200000000LL; // Windfury Totem
+ mod->mask[1] = 0x002; // Windfury Totem
break;
case 1:
- mod->mask = 0x00400000000LL; // Flametongue Totem
+ mod->mask[1] = 0x004; // Flametongue Totem
break;
}
- mod->charges = 0;
m_spellmod = mod;
}
@@ -2187,16 +2849,17 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
-
+ if (!Real)
+ break;
// Sentry Totem
if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
{
if (apply)
{
- uint64 guid = caster->m_TotemSlot[3];
+ uint64 guid = caster->m_SummonSlot[3];
if (guid)
{
- Creature *totem = ObjectAccessor::GetCreature(*caster, guid);
+ Creature *totem = caster->GetMap()->GetCreature(guid);
if (totem && totem->isTotem())
((Player*)caster)->CastSpell(totem, 6277, true);
}
@@ -2209,54 +2872,44 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
}
- // pet auras
- if(PetAura const* petSpell = spellmgr.GetPetAura(GetId()))
+ if (Real)
{
- if(apply)
- m_target->AddPetAura(petSpell);
- else
- m_target->RemovePetAura(petSpell);
- return;
- }
-}
-
-void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
- SpellEntry const*spell = GetSpellProto();
- switch( spell->SpellFamilyName)
- {
- case SPELLFAMILY_ROGUE:
+ // pet auras
+ if(PetAura const* petSpell = spellmgr.GetPetAura(GetId()))
{
- // Master of Subtlety
- if (spell->Id==31666 && !apply && Real)
- {
- m_target->RemoveAurasDueToSpell(31665);
- break;
- }
- break;
+ if(apply)
+ m_target->AddPetAura(petSpell);
+ else
+ m_target->RemovePetAura(petSpell);
+ return;
}
- case SPELLFAMILY_HUNTER:
+
+ if(GetEffIndex()==0 && m_target->GetTypeId()==TYPEID_PLAYER)
{
- // Aspect of the Viper
- if (spell->SpellFamilyFlags&0x0004000000000000LL)
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
+ if(saBounds.first != saBounds.second)
{
- // Update regen on remove
- if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateManaRegen();
- break;
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ {
+ // some auras remove at aura remove
+ if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
+ m_target->RemoveAurasDueToSpell(itr->second->spellId);
+ // some auras applied at aura apply
+ else if(itr->second->autocast)
+ {
+ if( !m_target->HasAuraEffect(itr->second->spellId,0) )
+ m_target->CastSpell(m_target,itr->second->spellId,true);
+ }
+ }
}
- break;
}
}
-
- m_isPeriodic = apply;
}
-void Aura::HandleAuraMounted(bool apply, bool Real)
+void AuraEffect::HandleAuraMounted(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -2264,10 +2917,10 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
if(apply)
{
- CreatureInfo const* ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
+ CreatureInfo const* ci = objmgr.GetCreatureTemplate(GetMiscValue());
if(!ci)
{
- sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)", m_modifier.m_miscvalue);
+ sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)",GetMiscValue());
return;
}
@@ -2280,6 +2933,11 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
if (minfo)
display_id = minfo->modelid;
+ //some spell has one aura of mount and one of vehicle
+ for(uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
+ && GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
+ display_id = 0;
m_target->Mount(display_id);
}
else
@@ -2288,7 +2946,7 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
}
}
-void Aura::HandleAuraWaterWalk(bool apply, bool Real)
+void AuraEffect::HandleAuraWaterWalk(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -2304,7 +2962,7 @@ void Aura::HandleAuraWaterWalk(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleAuraFeatherFall(bool apply, bool Real)
+void AuraEffect::HandleAuraFeatherFall(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -2320,7 +2978,7 @@ void Aura::HandleAuraFeatherFall(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleAuraHover(bool apply, bool Real)
+void AuraEffect::HandleAuraHover(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -2336,31 +2994,21 @@ void Aura::HandleAuraHover(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
}
-void Aura::HandleWaterBreathing(bool apply, bool Real)
+void AuraEffect::HandleWaterBreathing(bool apply, bool Real, bool /*changeAmount*/)
{
- if(apply)
- m_target->waterbreath = true;
- else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty())
- {
- m_target->waterbreath = false;
-
- // update for enable timer in case not moving target
- if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld())
- {
- ((Player*)m_target)->UpdateUnderwaterState(m_target->GetMap(),m_target->GetPositionX(),m_target->GetPositionY(),m_target->GetPositionZ());
- ((Player*)m_target)->HandleDrowning();
- }
- }
+ // update timers in client
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_target)->UpdateMirrorTimers();
}
-void Aura::HandleAuraModShapeshift(bool apply, bool Real)
+void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real, bool changeAmount)
{
- if(!Real)
+ if(!Real && !changeAmount)
return;
uint32 modelid = 0;
Powers PowerType = POWER_MANA;
- ShapeshiftForm form = ShapeshiftForm(m_modifier.m_miscvalue);
+ ShapeshiftForm form = ShapeshiftForm(GetMiscValue());
switch(form)
{
case FORM_CAT:
@@ -2421,6 +3069,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
else
modelid = 21244;
break;
+ case FORM_METAMORPHOSIS:
+ modelid = 25277;
+ break;
case FORM_AMBIENT:
case FORM_SHADOW:
case FORM_STEALTH:
@@ -2437,7 +3088,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
modelid = 16031;
break;
default:
- sLog.outError("Auras: Unknown Shapeshift Type: %u", m_modifier.m_miscvalue);
+ sLog.outError("Auras: Unknown Shapeshift Type: %u", GetMiscValue());
}
// remove polymorph before changing display id to keep new display id
@@ -2467,7 +3118,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
{
// remove other shapeshift before applying a new one
if(m_target->m_ShapeShiftFormSpellId)
- m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId,this);
+ m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId);
m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
@@ -2487,22 +3138,22 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_DIREBEAR:
{
// get furor proc chance
- uint32 FurorChance = 0;
- Unit::AuraList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
+ int32 FurorChance = 0;
+ Unit::AuraEffectList const& mDummy = m_target->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
{
if ((*i)->GetSpellProto()->SpellIconID == 238)
{
- FurorChance = (*i)->GetModifier()->m_amount;
+ FurorChance = (*i)->GetAmount();
break;
}
}
- if (m_modifier.m_miscvalue == FORM_CAT)
+ if (GetMiscValue() == FORM_CAT)
{
m_target->SetPower(POWER_ENERGY,0);
if(urand(1,100) <= FurorChance)
- m_target->CastSpell(m_target,17099,true,NULL,this);
+ m_target->CastCustomSpell(m_target,17099,&FurorChance, NULL, NULL,true,NULL,this);
}
else
{
@@ -2558,18 +3209,16 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_BEAR:
case FORM_DIREBEAR:
case FORM_CAT:
- {
- if(Aura* dummy = m_target->GetDummyAura(37315) )
+ if(AuraEffect* dummy = m_target->GetDummyAura(37315) )
m_target->CastSpell(m_target,37316,true,NULL,dummy);
break;
- }
// Nordrassil Regalia - bonus
case FORM_MOONKIN:
- {
- if(Aura* dummy = m_target->GetDummyAura(37324) )
+ if(AuraEffect* dummy = m_target->GetDummyAura(37324) )
m_target->CastSpell(m_target,37325,true,NULL,dummy);
break;
- }
+ default:
+ break;
}
}
@@ -2579,20 +3228,41 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
if(m_target->GetTypeId()==TYPEID_PLAYER)
((Player*)m_target)->InitDataForForm();
+
+ if(m_target->getClass() == CLASS_DRUID)
+ {
+ if(form == FORM_CAT && apply) // add dash if in cat-from
+ {
+ 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);
+ }
+ }
+ }
+ 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);
+ }
+ }
}
-void Aura::HandleAuraTransform(bool apply, bool Real)
+void AuraEffect::HandleAuraTransform(bool apply, bool Real, bool /*changeAmount*/)
{
if (apply)
{
// special case (spell specific functionality)
- if(m_modifier.m_miscvalue==0)
+ if(GetMiscValue()==0)
{
// player applied only
- if(m_target->GetTypeId()!=TYPEID_PLAYER)
+ if (m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- switch(GetId())
+ switch (GetId())
{
// Orb of Deception
case 16739:
@@ -2651,12 +3321,12 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
else
{
- CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_modifier.m_miscvalue);
+ CreatureInfo const * ci = objmgr.GetCreatureTemplate(GetMiscValue());
if(!ci)
{
//pig pink ^_^
m_target->SetDisplayId(16358);
- sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", m_modifier.m_miscvalue, GetId());
+ sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", GetMiscValue(), GetId());
}
else
{
@@ -2665,41 +3335,44 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
m_target->SetDisplayId(modelid);
// Dragonmaw Illusion (set mount model also)
- if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
+ if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED).empty())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
- m_target->setTransForm(GetId());
}
+ // 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());
+
// polymorph case
- if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
+ if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
{
// for players, start regeneration after 1s (in polymorph fast regeneration case)
// only if caster is Player (after patch 2.4.2)
- if(IS_PLAYER_GUID(GetCasterGUID()) )
- ((Player*)m_target)->setRegenTimer(1000);
+ if (IS_PLAYER_GUID(GetCasterGUID()) )
+ ((Player*)m_target)->setRegenTimer(1*IN_MILISECONDS);
//dismount polymorphed target (after patch 2.4.2)
if (m_target->IsMounted())
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ m_target->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
}
else
{
- Unit::AuraList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
- if(otherTransforms.empty())
- {
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->setTransForm(0);
- }
- else
+ // 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
+ Unit::AuraEffectList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
+ if (!otherTransforms.empty())
{
// look for other transform auras
- Aura* handledAura = *otherTransforms.begin();
- for(Unit::AuraList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
+ AuraEffect* handledAura = *otherTransforms.begin();
+ for(Unit::AuraEffectList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
{
// negative auras are preferred
- if(!IsPositiveSpell((*i)->GetSpellProto()->Id))
+ if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
{
handledAura = *i;
break;
@@ -2709,11 +3382,11 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
// Dragonmaw Illusion (restore mount model)
- if(GetId()==42016 && m_target->GetMountID()==16314)
+ if (GetId()==42016 && m_target->GetMountID()==16314)
{
- if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
+ if (!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
{
- uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetModifier()->m_miscvalue;
+ uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetMiscValue();
if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
{
uint32 team = 0;
@@ -2732,54 +3405,42 @@ void Aura::HandleAuraTransform(bool apply, bool Real)
}
}
-void Aura::HandleForceReaction(bool apply, bool Real)
+void AuraEffect::HandleForceReaction(bool apply, bool Real, bool changeAmount)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- if(!Real)
+ if(!Real && !changeAmount)
return;
Player* player = (Player*)m_target;
- uint32 faction_id = m_modifier.m_miscvalue;
- uint32 faction_rank = m_modifier.m_amount;
+ uint32 faction_id = GetMiscValue();
+ uint32 faction_rank = m_amount;
- if(apply)
- player->m_forcedReactions[faction_id] = ReputationRank(faction_rank);
- else
- player->m_forcedReactions.erase(faction_id);
-
- WorldPacket data;
- data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+player->m_forcedReactions.size()*(4+4));
- data << uint32(player->m_forcedReactions.size());
- for(ForcedReactions::const_iterator itr = player->m_forcedReactions.begin(); itr != player->m_forcedReactions.end(); ++itr)
- {
- data << uint32(itr->first); // faction_id (Faction.dbc)
- data << uint32(itr->second); // reputation rank
- }
- player->SendDirectMessage(&data);
+ player->GetReputationMgr().ApplyForceReaction(faction_id,ReputationRank(faction_rank),apply);
+ player->GetReputationMgr().SendForceReactions();
}
-void Aura::HandleAuraModSkill(bool apply, bool Real)
+void AuraEffect::HandleAuraModSkill(bool apply, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
- int32 points = GetModifierValue();
+ int32 points = m_amount;
- ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_modifier.m_auraname==SPELL_AURA_MOD_SKILL_TALENT);
+ ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_auraName==SPELL_AURA_MOD_SKILL_TALENT);
if(prot == SKILL_DEFENSE)
((Player*)m_target)->UpdateDefenseBonusesMod();
}
-void Aura::HandleChannelDeathItem(bool apply, bool Real)
+void AuraEffect::HandleChannelDeathItem(bool apply, bool Real, bool /*changeAmount*/)
{
if(Real && !apply)
{
Unit* caster = GetCaster();
- Unit* victim = GetTarget();
+ Unit* victim = m_target;
if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim)// || m_removeMode!=AURA_REMOVE_BY_DEATH)
return;
@@ -2787,6 +3448,9 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
//talent will remove the caster's aura->interrupt channel->remove victim aura
if(victim->GetHealth() > 0)
return;
+ // Item amount
+ if (m_amount <= 0)
+ return;
SpellEntry const *spellInfo = GetSpellProto();
if(spellInfo->EffectItemType[m_effIndex] == 0)
@@ -2797,100 +3461,158 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
(victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
return;
+ //Adding items
+ uint32 noSpaceForCount = 0;
+ uint32 count = m_amount;
+
ItemPosCountVec dest;
- uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
+ uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
if( msg != EQUIP_ERR_OK )
{
+ count-=noSpaceForCount;
((Player*)caster)->SendEquipError( msg, NULL, NULL );
- return;
+ if (count==0)
+ return;
}
Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
- ((Player*)caster)->SendNewItem(newitem, 1, true, false);
+ ((Player*)caster)->SendNewItem(newitem, count, true, false);
}
}
-void Aura::HandleBindSight(bool apply, bool Real)
+void AuraEffect::HandleBindSight(bool apply, bool Real, bool /*changeAmount*/)
{
+ if (!Real)
+ return;
Unit* caster = GetCaster();
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
- if (apply)
- m_target->AddPlayerToVision((Player*)caster);
- else
- m_target->RemovePlayerFromVision((Player*)caster);
+ ((Player*)caster)->SetViewpoint(m_target, apply);
}
-void Aura::HandleFarSight(bool apply, bool Real)
+void AuraEffect::HandleFarSight(bool apply, bool Real, bool /*changeAmount*/)
{
- Unit* caster = GetCaster();
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
+ //Handled by client
}
-void Aura::HandleAuraTrackCreatures(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackCreatures(bool apply, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
- m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 );
+ m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(GetMiscValue()-1) : 0 );
}
-void Aura::HandleAuraTrackResources(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackResources(bool apply, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
- m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 );
+ m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(GetMiscValue()-1): 0 );
}
-void Aura::HandleAuraTrackStealthed(bool apply, bool Real)
+void AuraEffect::HandleAuraTrackStealthed(bool apply, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- if(apply)
- m_target->RemoveNoStackAurasDueToAura(this);
-
m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
}
-void Aura::HandleAuraModScale(bool apply, bool Real)
+void AuraEffect::HandleAuraModScale(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,GetModifierValue(),apply);
+ m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_amount,apply);
}
-void Aura::HandleModPossess(bool apply, bool Real)
+/*void AuraEffect::HandleModPossess(bool apply, bool Real)
{
if(!Real)
return;
+ if(m_target->getLevel() > m_amount)
+ return;
+
+ // not possess yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
- if(caster && caster->GetTypeId() == TYPEID_UNIT)
- {
- HandleModCharm(apply, Real);
+ if(!caster)
return;
- }
- if(apply)
+ if( apply )
{
- if(m_target->getLevel() > m_modifier.m_amount)
- return;
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->setFaction(caster->getFaction());
+
+ caster->SetCharm(m_target);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->SetFarSightGUID(m_target->GetGUID());
+ ((Player*)caster)->SetClientControl(m_target, 1);
+ }
+
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->StopMoving();
+ m_target->GetMotionMaster()->Clear();
+ m_target->GetMotionMaster()->MoveIdle();
+ }
+ else if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->SetClientControl(m_target, 0);
+ }
+
+ if(CharmInfo *charmInfo = m_target->InitCharmInfo(m_target))
+ charmInfo->InitPossessCreateSpells();
- m_target->SetCharmedOrPossessedBy(caster, true);
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)caster)->PossessSpellInitialize();
}
else
- m_target->RemoveCharmedOrPossessedBy(caster);
+ {
+ m_target->SetCharmerGUID(0);
+ caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ ((Player*)m_target)->SetClientControl(m_target, 1);
+ }
+ else if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ m_target->setFaction(cinfo->faction_A);
+ }
+
+ caster->SetCharm(NULL);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->SetFarSightGUID(0);
+ ((Player*)caster)->SetClientControl(m_target,0);
+
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
+ }
+ }
}
-void Aura::HandleModPossessPet(bool apply, bool Real)
+void AuraEffect::HandleModPossessPet(bool apply, bool Real)
{
if(!Real)
return;
@@ -2899,46 +3621,158 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
+ Pet *pet = caster->GetGuardianPet();
+ if(!pet || pet != m_target)
+ return;
+
if(apply)
- {
- if(caster->GetPet() != m_target)
- return;
+ pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
+ else
+ pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
- m_target->SetCharmedOrPossessedBy(caster, true);
+ ((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : 0);
+ ((Player*)caster)->SetCharm(apply ? pet : NULL);
+ ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0);
+
+ if(apply)
+ {
+ pet->StopMoving();
+ pet->GetMotionMaster()->Clear();
+ pet->GetMotionMaster()->MoveIdle();
}
else
{
- m_target->RemoveCharmedOrPossessedBy(caster);
-
- // 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);
- }
+ pet->AttackStop();
+ pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
}
+}*/
+
+void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real, bool changeAmount)
+{
+ if(!Real && !changeAmount)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Recalculate pet tlaent points
+ if (Pet *pet = ((Player*)m_target)->GetPet())
+ pet->InitTalentForLevel();
}
-void Aura::HandleModCharm(bool apply, bool Real)
+/*void AuraEffect::HandleModCharm(bool apply, bool Real)
{
if(!Real)
return;
+ // not charm yourself
+ if(GetCasterGUID() == m_target->GetGUID())
+ return;
+
Unit* caster = GetCaster();
+ if(!caster)
+ return;
- if(apply)
+ if(int32(m_target->getLevel()) <= m_amount)
{
- if(int32(m_target->getLevel()) > m_modifier.m_amount)
- return;
+ if( apply )
+ {
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->setFaction(caster->getFaction());
+ m_target->CastStop(m_target == caster ? GetId() : 0);
+ caster->SetCharm(m_target);
- m_target->SetCharmedOrPossessedBy(caster, false);
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ CharmInfo *charmInfo = m_target->InitCharmInfo(m_target);
+ charmInfo->InitCharmCreateSpells();
+ charmInfo->SetReactState( REACT_DEFENSIVE );
+
+ if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //does not appear to have relevance. Why code added initially? See note below at !apply
+ //to prevent client crash
+ //m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
+ //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));
+ }
+ }
+ }
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->CharmSpellInitialize();
+ }
+ }
+ else
+ {
+ m_target->SetCharmerGUID(0);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ else
+ {
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+
+ // restore faction
+ if(((Creature*)m_target)->isPet())
+ {
+ if(Unit* owner = m_target->GetOwner())
+ m_target->setFaction(owner->getFaction());
+ else if(cinfo)
+ m_target->setFaction(cinfo->faction_A);
+ }
+ else if(cinfo) // normal creature
+ m_target->setFaction(cinfo->faction_A);
+
+ // restore UNIT_FIELD_BYTES_0
+ if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //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();
+ if(cainfo && cainfo->bytes0 != 0)
+ m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
+ else
+ m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
+
+ if(m_target->GetCharmInfo())
+ m_target->GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("AuraEffect::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
+ }
+ }
+
+ caster->SetCharm(NULL);
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
+ data << uint64(0);
+ data << uint32(0);
+ ((Player*)caster)->GetSession()->SendPacket(&data);
+ }
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
+ }
+ }
}
- else
- m_target->RemoveCharmedOrPossessedBy(caster);
-}
+}*/
-void Aura::HandleModConfuse(bool apply, bool Real)
+void AuraEffect::HandleModConfuse(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
@@ -2947,7 +3781,7 @@ void Aura::HandleModConfuse(bool apply, bool Real)
m_target->SetControlled(apply, UNIT_STAT_CONFUSED);
}
-void Aura::HandleModFear(bool apply, bool Real)
+void AuraEffect::HandleModFear(bool apply, bool Real, bool /*changeAmount*/)
{
if (!Real)
return;
@@ -2956,7 +3790,7 @@ void Aura::HandleModFear(bool apply, bool Real)
m_target->SetControlled(apply, UNIT_STAT_FLEEING);
}
-void Aura::HandleFeignDeath(bool apply, bool Real)
+void AuraEffect::HandleFeignDeath(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
@@ -2975,7 +3809,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
std::list<Unit*> targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_target, targets, u_check);
m_target->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);
for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
@@ -2992,7 +3826,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
}
}
// blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -3000,10 +3834,10 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->addUnitState(UNIT_STAT_DIED);
m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
// prevent interrupt message
- if(m_caster_guid==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
+ if(GetCasterGUID()==m_target->GetGUID() && m_target->m_currentSpells[CURRENT_GENERIC_SPELL])
m_target->m_currentSpells[CURRENT_GENERIC_SPELL]->finish();
m_target->InterruptNonMeleeSpells(true);
m_target->getHostilRefManager().deleteReferences();
@@ -3017,7 +3851,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
m_target->SendMessageToSet(&data,true);
*/
// blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6);
+ m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
// blizz like 2.0.x
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
// blizz like 2.0.x
@@ -3027,221 +3861,142 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
}
}
-void Aura::HandleAuraModDisarm(bool apply, bool Real)
+void AuraEffect::HandleAuraModDisarm(bool apply, bool Real, bool /*changeAmount*/)
{
- if(!Real)
+ if (!Real)
return;
+ AuraType type = AuraType(GetAuraName());
- if(!apply && m_target->HasAuraType(SPELL_AURA_MOD_DISARM))
+ //Prevent handling aura twice
+ if(apply && m_target->GetAurasByType(type).size()>1)
return;
-
- // not sure for it's correctness
+ if(!apply && m_target->HasAuraType(type))
+ return;
+ uint32 field, flag, slot;
+ WeaponAttackType attType;
+ switch (type)
+ {
+ case SPELL_AURA_MOD_DISARM:
+ field=UNIT_FIELD_FLAGS;
+ flag=UNIT_FLAG_DISARMED;
+ slot=EQUIPMENT_SLOT_MAINHAND;
+ attType=BASE_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_OFFHAND:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_OFFHAND;
+ slot=EQUIPMENT_SLOT_OFFHAND;
+ attType=OFF_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_RANGED:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_RANGED;
+ slot=EQUIPMENT_SLOT_RANGED;
+ attType=RANGED_ATTACK;
+ break;
+ }
if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->SetFlag(field, flag);
else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ m_target->RemoveFlag(field, flag);
if (m_target->GetTypeId() == TYPEID_PLAYER)
{
- // main-hand attack speed already set to special value for feral form already and don't must change and reset at remove.
- if (((Player *)m_target)->IsInFeralForm())
+ Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot );
+ if(!pItem )
return;
-
- if (apply)
- m_target->SetAttackTime(BASE_ATTACK,BASE_ATTACK_TIME);
- else
- ((Player *)m_target)->SetRegularAttackTime();
+ ((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
}
- else
- {
- // creature does not have equipment
- if(apply && !((Creature*)m_target)->GetCurrentEquipmentId())
- return;
- }
-
- m_target->UpdateDamagePhysical(BASE_ATTACK);
+ else if (((Creature*)m_target)->GetCurrentEquipmentId())
+ m_target->UpdateDamagePhysical(attType);
}
-void Aura::HandleAuraModStun(bool apply, bool Real)
+void AuraEffect::HandleModStealth(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
- m_target->SetControlled(apply, UNIT_STAT_STUNNED);
-}
-
-void Aura::HandleModStealth(bool apply, bool Real)
-{
if(apply)
{
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
- {
- // drop flag at stealth in bg
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
-
- // remove player from the objective's active player count at stealth
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
-
- // only at real aura add
- if(Real)
- {
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02);
- if(m_target->GetTypeId()==TYPEID_PLAYER)
- m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
+ // drop flag at stealth in bg
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
- // apply only if not in GM invisibility (and overwrite invisibility state)
- if(m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_OFF);
- m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
- }
+ m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->CastSpell(m_target, 21009, true, NULL, this);
- }
+ // apply only if not in GM invisibility (and overwrite invisibility state)
+ if(m_target->GetVisibility() != VISIBILITY_OFF)
+ m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
}
- else
+ else if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
{
- // only at real aura remove
- if(Real)
- {
- // for RACE_NIGHTELF stealth
- if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580)
- m_target->RemoveAurasDueToSpell(21009);
-
- // if last SPELL_AURA_MOD_STEALTH and no GM invisibility
- if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00);
- if(m_target->GetTypeId()==TYPEID_PLAYER)
- m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
-
- // restore invisibility if any
- if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
- {
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
- m_target->SetVisibility(VISIBILITY_ON);
- }
- else
- {
- m_target->SetVisibility(VISIBILITY_ON);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
- }
- }
- }
+ m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
- // Master of Subtlety
- Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 2114 && Real)
- {
- if (apply)
- {
- int32 bp = (*i)->GetModifier()->m_amount;
- m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true);
- }
- else
- m_target->CastSpell(m_target,31666,true);
- break;
- }
+ if(m_target->GetVisibility() != VISIBILITY_OFF)
+ m_target->SetVisibility(VISIBILITY_ON);
}
}
-void Aura::HandleInvisibility(bool apply, bool Real)
+void AuraEffect::HandleInvisibility(bool apply, bool Real, bool /*changeAmount*/)
{
if(apply)
{
- m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
+ m_target->m_invisibilityMask |= (1 << GetMiscValue());
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
-
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
+ if(Real)
{
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
// apply glow vision
- m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // remove player from the objective's active player count at invisibility
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // apply only if not in GM invisibility and not stealth
- if(m_target->GetVisibility()==VISIBILITY_ON)
- {
- // Aura not added yet but visibility code expect temporary add aura
- //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
- //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
- m_target->SetVisibility(VISIBILITY_ON);
+ m_target->SetToNotify();
}
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target->m_invisibilityMask = 0;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
+ 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());
// only at real aura remove and if not have different invisibility auras.
- if(Real && m_target->m_invisibilityMask==0)
+ if(Real)
{
// remove glow vision
- if(m_target->GetTypeId() == TYPEID_PLAYER)
+ if(!m_target->m_invisibilityMask && m_target->GetTypeId() == TYPEID_PLAYER)
m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
- // apply only if not in GM invisibility & not stealthed while invisible
- if(m_target->GetVisibility()!=VISIBILITY_OFF)
- {
- // if have stealth aura then already have stealth visibility
- if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- {
- m_target->SetVisibility(VISIBILITY_ON);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if(OutdoorPvP * pvp = ((Player*)m_target)->GetOutdoorPvP())
- pvp->HandlePlayerActivityChanged((Player*)m_target);
- }
- }
+ m_target->SetToNotify();
}
}
}
-void Aura::HandleInvisibilityDetect(bool apply, bool Real)
+void AuraEffect::HandleInvisibilityDetect(bool apply, bool Real, bool /*changeAmount*/)
{
if(apply)
{
- m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
+ m_target->m_detectInvisibilityMask |= (1 << GetMiscValue());
}
else
{
// recalculate value at modifier remove (current aura already removed)
m_target->m_detectInvisibilityMask = 0;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
+ 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());
}
if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
//ObjectAccessor::UpdateVisibilityForPlayer((Player*)m_target);
m_target->SetToNotify();
}
-void Aura::HandleAuraModRoot(bool apply, bool Real)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- m_target->SetControlled(apply, UNIT_STAT_ROOT);
-}
-
-void Aura::HandleAuraModSilence(bool apply, bool Real)
+void AuraEffect::HandleAuraModSilence(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -3252,38 +4007,8 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
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++)
- {
- Spell* currentSpell = m_target->m_currentSpells[i];
- if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
- {
- uint32 state = currentSpell->getState();
- // Stop spells on prepare or casting state
- if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
- {
- currentSpell->cancel();
- }
- }
- }
-
- switch (GetId())
- {
- // Arcane Torrent (Energy)
- case 25046:
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
-
- // Search Mana Tap auras on caster
- Aura * dummy = m_target->GetDummyAura(28734);
- if (dummy)
- {
- int32 bp = dummy->GetStackAmount() * 10;
- caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true);
- m_target->RemoveAurasDueToSpell(28734);
- }
- }
- }
+ 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
}
else
{
@@ -3295,10 +4020,10 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
}
}
-void Aura::HandleModThreat(bool apply, bool Real)
+void AuraEffect::HandleModThreat(bool apply, bool Real, bool changeAmount)
{
// only at real add/remove aura
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(!m_target->isAlive())
@@ -3325,22 +4050,22 @@ void Aura::HandleModThreat(bool apply, bool Real)
break;
}
if (level_diff > 0)
- m_modifier.m_amount += multiplier * level_diff;
+ m_amount += multiplier * level_diff;
for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? GetModifierValue() : -GetModifierValue(), apply);
+ ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_amount, apply);
}
}
}
-void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalThreat(bool apply, bool Real, bool changeAmount)
{
// only at real add/remove aura
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(!m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER)
@@ -3353,14 +4078,14 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
float threatMod = 0.0f;
if(apply)
- threatMod = float(GetModifierValue());
+ threatMod = float(m_amount);
else
- threatMod = float(-GetModifierValue());
+ threatMod = float(-m_amount);
m_target->getHostilRefManager().threatAssist(caster, threatMod);
}
-void Aura::HandleModTaunt(bool apply, bool Real)
+void AuraEffect::HandleModTaunt(bool apply, bool Real, bool /*changeAmount*/)
{
// only at real add/remove aura
if(!Real)
@@ -3386,32 +4111,39 @@ void Aura::HandleModTaunt(bool apply, bool Real)
/*********************************************************/
/*** MODIFY SPEED ***/
/*********************************************************/
-void Aura::HandleAuraModIncreaseSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseSpeed(bool apply, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
+ 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 )
+ {
+ m_target->HandleAuraEffect(this, false);
+ return;
+ }
+
m_target->UpdateSpeed(MOVE_RUN, true);
}
-void Aura::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseMountedSpeed(bool /*apply*/, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
m_target->UpdateSpeed(MOVE_RUN, true);
}
-void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
// Enable Fly mode for flying mounts
- if (m_modifier.m_auraname == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)
+ if (m_auraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
{
WorldPacket data;
if(apply)
@@ -3427,38 +4159,37 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)
m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
- if( apply && m_target->HasAura(42016,0) && m_target->GetMountID())
+ if( apply && m_target->HasAuraEffect(42016,0) && m_target->GetMountID())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
m_target->UpdateSpeed(MOVE_FLIGHT, true);
}
-void Aura::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
m_target->UpdateSpeed(MOVE_SWIM, true);
}
-void Aura::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModDecreaseSpeed(bool /*apply*/, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
- //m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_target->UpdateSpeed(MOVE_RUN, true);
m_target->UpdateSpeed(MOVE_SWIM, true);
m_target->UpdateSpeed(MOVE_FLIGHT, true);
}
-void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real, bool changeAmount)
{
// all applied/removed only at real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
m_target->UpdateSpeed(MOVE_RUN, true);
@@ -3470,51 +4201,84 @@ void Aura::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real)
/*** IMMUNITY ***/
/*********************************************************/
-void Aura::HandleModMechanicImmunity(bool apply, bool Real)
+void AuraEffect::HandleModStateImmunityMask(bool apply, bool Real, bool /*changeAmount*/)
{
- uint32 mechanic = 1 << m_modifier.m_miscvalue;
+ if (!Real)
+ return;
+ 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);
+ if (GetMiscValue() & (1<<2))
+ immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ if (GetMiscValue() & (1<<9))
+ immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+
+ // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
+ // however not all mechanic specified in immunity
+ 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)
+ {
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end();++iter)
+ {
+ m_target->RemoveAurasByType(*iter);
+ }
+ }
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end();++iter)
+ {
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,*iter,apply);
+ }
+}
+
+void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if (!Real)
+ return;
+ uint32 mechanic;
+ mechanic = 1 << GetMiscValue();
//immune movement impairment and loss of control
- if(GetId()==42292)
+ if(GetId()==42292 || GetId()==59752)
mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
+ if (!mechanic)
+ return;
if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
{
Unit::AuraMap& Auras = m_target->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
- next = iter;
- ++next;
SpellEntry const *spell = iter->second->GetSpellProto();
- if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
- && !iter->second->IsPositive() // only remove negative spells
- && spell->Id != GetId())
+ if (spell->Id != GetId())
{
//check for mechanic mask
- if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
+ if(GetAllSpellMechanicMask(spell) & mechanic)
{
- m_target->RemoveAurasDueToSpell(spell->Id);
- if(Auras.empty())
- break;
- else
- next = Auras.begin();
+ m_target->RemoveAura(iter);
}
+ else
+ ++iter;
}
+ else
+ ++iter;
}
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);
-
- // special cases
- switch(m_modifier.m_miscvalue)
- {
- case MECHANIC_INVULNERABILITY:
- m_target->ModifyAuraState(AURA_STATE_FORBEARANCE,apply);
- break;
- case MECHANIC_SHIELD:
- m_target->ModifyAuraState(AURA_STATE_WEAKENED_SOUL,apply);
- break;
- }
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,GetMiscValue(),apply);
// Bestial Wrath
if ( GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->Id == 19574)
@@ -3523,8 +4287,8 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
if ( Unit* owner = m_target->GetOwner() )
{
// Search talent
- Unit::AuraList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
+ Unit::AuraEffectList const& m_dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
{
if ( (*i)->GetSpellProto()->SpellIconID == 2229 )
{
@@ -3543,10 +4307,10 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
{
if(apply)
{
- m_target->CastSpell(m_target,24395,true);
- m_target->CastSpell(m_target,24396,true);
- m_target->CastSpell(m_target,24397,true);
- m_target->CastSpell(m_target,26592,true);
+ 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);
}
else
{
@@ -3556,103 +4320,98 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
m_target->RemoveAurasDueToSpell(26592);
}
}
+
+ // Heroic Fury (remove Intercept cooldown)
+ 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)
+ {
+ if (apply)
+ m_target->RemoveMovementImpairingAuras();
+
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_ROOT,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_DECREASE_SPEED,apply);
+ }
+ // 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());
+ }
+ }
}
-void Aura::HandleAuraModEffectImmunity(bool apply, bool Real)
+//this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect
+void AuraEffect::HandleAuraModEffectImmunity(bool apply, bool Real, bool /*changeAmount*/)
{
- if(!apply)
+ // when removing flag aura, handle flag drop
+ if( !apply && m_target->GetTypeId() == TYPEID_PLAYER
+ && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) )
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
if(((Player*)m_target)->InBattleGround())
{
- BattleGround *bg = ((Player*)m_target)->GetBattleGround();
- if(bg)
- {
- switch(bg->GetTypeID())
- {
- case BATTLEGROUND_AV:
- {
- break;
- }
- case BATTLEGROUND_WS:
- {
- // Warsong Flag, horde // Silverwing Flag, alliance
- if(GetId() == 23333 || GetId() == 23335)
- bg->EventPlayerDroppedFlag(((Player*)m_target));
- break;
- }
- case BATTLEGROUND_AB:
- {
- break;
- }
- case BATTLEGROUND_EY:
- {
- if(GetId() == 34976)
- bg->EventPlayerDroppedFlag(((Player*)m_target));
- break;
- }
- }
- }
+ if( BattleGround *bg = ((Player*)m_target)->GetBattleGround() )
+ bg->EventPlayerDroppedFlag(((Player*)m_target));
}
else
sOutdoorPvPMgr.HandleDropFlag((Player*)m_target,GetSpellProto()->Id);
}
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,GetMiscValue(),apply);
}
-void Aura::HandleAuraModStateImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModStateImmunity(bool apply, bool Real, bool /*changeAmount*/)
{
if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
{
- Unit::AuraList const& auraList = m_target->GetAurasByType(AuraType(m_modifier.m_miscvalue));
- for(Unit::AuraList::const_iterator itr = auraList.begin(); itr != auraList.end();)
- {
- if (auraList.front() != this) // skip itself aura (it already added)
- {
- m_target->RemoveAurasDueToSpell(auraList.front()->GetId());
- itr = auraList.begin();
- }
- else
- ++itr;
- }
+ m_target->RemoveAurasByType(AuraType(GetMiscValue()), NULL , GetParentAura());
}
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,GetMiscValue(),apply);
}
-void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real, bool /*changeAmount*/)
{
- if(apply && m_modifier.m_miscvalue == SPELL_SCHOOL_MASK_NORMAL)
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ if(apply && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,GetMiscValue(),apply);
- m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,m_modifier.m_miscvalue,apply);
+ // 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);
- if(Real && apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ // 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
{
- if(IsPositiveSpell(GetId())) //Only positive immunity removes auras
+ uint32 school_mask = GetMiscValue();
+ Unit::AuraMap& Auras = m_target->GetAuras();
+ for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
- uint32 school_mask = m_modifier.m_miscvalue;
- Unit::AuraMap& Auras = m_target->GetAuras();
- for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
+ SpellEntry const *spell = iter->second->GetSpellProto();
+ if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
+ && IsDispelableBySpell(GetSpellProto(),spell->Id, true)
+ && !iter->second->IsPositive() //Don't remove positive spells
+ && spell->Id != GetId() ) //Don't remove self
{
- next = iter;
- ++next;
- SpellEntry const *spell = iter->second->GetSpellProto();
- if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
- && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
- && !iter->second->IsPositive() //Don't remove positive spells
- && spell->Id != GetId() ) //Don't remove self
- {
- m_target->RemoveAurasDueToSpell(spell->Id);
- if(Auras.empty())
- break;
- else
- next = Auras.begin();
- }
+ m_target->RemoveAura(iter);
}
+ else
+ ++iter;
}
}
if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH )
@@ -3664,40 +4423,27 @@ void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real)
}
}
-void Aura::HandleAuraModDmgImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModDmgImmunity(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,m_modifier.m_miscvalue,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,GetMiscValue(),apply);
}
-void Aura::HandleAuraModDispelImmunity(bool apply, bool Real)
+void AuraEffect::HandleAuraModDispelImmunity(bool apply, bool Real, bool /*changeAmount*/)
{
// all applied/removed only at real aura add/remove
if(!Real)
return;
- m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(m_modifier.m_miscvalue), apply);
+ m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(GetMiscValue()), apply);
}
-void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
+void AuraEffect::HandleAuraProcTriggerSpell(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
-
- if(apply)
- {
- // some spell have charges by functionality not have its in spell data
- switch (GetId())
- {
- case 28200: // Ascendance (Talisman of Ascendance trinket)
- m_procCharges = 6;
- UpdateAuraCharges();
- break;
- default: break;
- }
- }
}
-void Aura::HandleAuraModStalked(bool apply, bool Real)
+void AuraEffect::HandleAuraModStalked(bool apply, bool Real, bool /*changeAmount*/)
{
// used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
if(apply)
@@ -3710,111 +4456,119 @@ void Aura::HandleAuraModStalked(bool apply, bool Real)
/*** PERIODIC ***/
/*********************************************************/
-void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
+void AuraEffect::HandlePeriodicTriggerSpell(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
- m_isTrigger = apply;
-
- // Curse of the Plaguebringer
- if (!apply && m_spellProto->Id == 29213 && m_removeMode!=AURA_REMOVE_BY_DISPEL)
+ if (Real && m_spellProto->Id == 66 && !apply)
{
- // Cast Wrath of the Plaguebringer if not dispelled
- m_target->CastSpell(m_target, 29214, true, 0, this);
+ if (GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ m_target->CastSpell(m_target, 32612, true, NULL, this);
}
+}
- // Wrath of the Astromancer
- if(!apply && m_spellProto->Id == 42783)
- {
- m_target->CastSpell(m_target, 42787, true, 0, this);
- }
+void AuraEffect::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real, bool /*changeAmount*/)
+{
+ m_isPeriodic = apply;
}
-void Aura::HandlePeriodicEnergize(bool apply, bool Real)
+void AuraEffect::HandlePeriodicEnergize(bool apply, bool Real, bool changeAmount)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ if(!Real && !changeAmount)
+ return;
m_isPeriodic = apply;
+
+ // Replenishment (0.25% from max)
+ // Infinite Replenishment
+ if (m_spellProto->SpellIconID == 3184 && m_spellProto->SpellVisual[0] == 12495)
+ m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000;
}
-void Aura::HandlePeriodicHeal(bool apply, bool Real)
+void AuraEffect::HandleAuraPowerBurn(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
+}
- // only at real apply
- if (Real && apply && GetSpellProto()->Mechanic == MECHANIC_BANDAGE)
- {
- // provided m_target as original caster to prevent apply aura caster selection for this negative buff
- m_target->CastSpell(m_target,11196,true,NULL,this,m_target->GetGUID());
- }
+void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmount)
+{
+ // spells required only Real aura add/remove
+ if(!Real && !changeAmount)
+ return;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
- if(!loading && apply)
+ Unit* caster = GetCaster();
+
+ SpellEntry const*spell = GetSpellProto();
+ switch( spell->SpellFamilyName)
{
- switch (m_spellProto->SpellFamilyName)
+ case SPELLFAMILY_WARLOCK:
{
- case SPELLFAMILY_DRUID:
+ switch (spell->Id)
{
- // Rejuvenation
- if(m_spellProto->SpellFamilyFlags & 0x0000000000000010LL)
- {
- if(Unit* caster = GetCaster())
+ // 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
{
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 4953: // Increased Rejuvenation Healing - Harold's Rejuvenating Broach Aura
- case 4415: // Increased Rejuvenation Healing - Idol of Rejuvenation Aura
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
+ // 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;
}
}
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (apply && !loading && caster)
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 16 / 100);
+ break;
+ }
}
+
+ m_isPeriodic = apply;
}
-void Aura::HandlePeriodicDamage(bool apply, bool Real)
+void AuraEffect::HandlePeriodicHeal(bool apply, bool Real, bool /*changeAmount*/)
+{
+ m_isPeriodic = apply;
+}
+
+void AuraEffect::HandlePeriodicDamage(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
// For prevent double apply bonuses
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
+ // Custom damage calculation after
+ if (!apply || loading)
+ return;
+
Unit *caster = GetCaster();
+ if (!caster)
+ return;
switch (m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
// Pounce Bleed
- if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual == 0 )
+ if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual[0] == 0 )
{
// $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
return;
}
break;
@@ -3822,18 +4576,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_WARRIOR:
{
// Rend
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x20)
{
- // 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
- if (apply && !loading && caster)
- {
- 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);
- // WARNING! in 3.0 multiplier 0.00743f change to 0.6
- m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
- }
+ // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 mws = caster->GetAttackTime(BASE_ATTACK);
+ float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
+ float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
+ m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
return;
}
break;
@@ -3841,92 +4591,80 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_DRUID:
{
// Rake
- if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x1000)
{
- // $AP*0.06/3 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
+ // $AP*0.06 bonus per tick
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100);
return;
}
// Lacerate
- if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x0000000100)
{
// $AP*0.05/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
return;
}
// Rip
- if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
+ if (m_spellProto->SpellFamilyFlags[1] & 0x800000)
{
- // $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
+ // 0.01*$AP*cp
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
- // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
- Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+
+ // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
+ Unit::AuraEffectList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
+ {
+ if((*itr)->GetId()==34241)
{
- if((*itr)->GetId()==34241)
- {
- m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
- break;
- }
+ m_amount += cp * (*itr)->GetAmount();
+ break;
}
-
- if (cp > 4) cp = 4;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
}
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
+ return;
+ }
+ // Lock Jaw
+ if (m_spellProto->SpellFamilyFlags[1] & 0x10000000)
+ {
+ // 0.15*$AP
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 15 / 100);
return;
}
break;
}
case SPELLFAMILY_ROGUE:
{
- // Deadly poison aura state
- if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100)
+ // Rupture
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100000)
{
- if(apply)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
- else
- {
- // current aura already removed, search present of another
- bool found = false;
- Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- {
- SpellEntry const* itr_spell = (*itr)->GetSpellProto();
- if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100)
- {
- found = true;
- break;
- }
- }
- // this has been last deadly poison aura
- if(!found)
- m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
- }
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
+ //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
+ //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
+ //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
+ //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
+ float AP_per_combo[6] = {0.0f, 0.015f, 0.024f, 0.03f, 0.03428571f, 0.0375f};
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+ if (cp > 5) cp = 5;
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
return;
}
- // Rupture
- if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
+ // Garrote
+ if (m_spellProto->SpellFamilyFlags[0] & 0x100)
{
- // Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
- if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- uint8 cp = ((Player*)caster)->GetComboPoints();
- if (cp > 3) cp = 3;
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
- }
+ // $AP*0.07 bonus per tick
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 7 / 100);
return;
}
- // Garrote
- if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
+ // Deadly Poison
+ if (m_spellProto->SpellFamilyFlags[0] & 0x10000)
{
- // $AP*0.18/6 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
+ // 0.08*$AP / 4 * amount of stack
+ m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 * GetParentAura()->GetStackAmount() / 100);
return;
}
break;
@@ -3934,47 +4672,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_HUNTER:
{
// Serpent Sting
- if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4000)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
// Immolation Trap
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
+ if (m_spellProto->SpellFamilyFlags[0] & 0x4 && m_spellProto->SpellIconID == 678)
{
// $RAP*0.1/5 bonus per tick
- if (apply && !loading && caster)
- m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
- return;
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Consecration
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
- {
- if (apply && !loading)
- {
- if(Unit* caster = GetCaster())
- {
- Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
- {
- int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
- switch((*k)->GetModifier()->m_miscvalue)
- {
- case 5147: // Improved Consecration - Libram of the Eternal Rest
- {
- m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
- break;
- }
- }
- }
- }
- }
+ m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
return;
}
break;
@@ -3984,27 +4692,23 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
}
}
-void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
+void AuraEffect::HandlePeriodicDamagePCT(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
-void Aura::HandlePeriodicLeech(bool apply, bool Real)
+void AuraEffect::HandlePeriodicLeech(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
m_isPeriodic = apply;
}
-void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
+void AuraEffect::HandlePeriodicManaLeech(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
+ m_isPeriodic = apply;
+}
+void AuraEffect::HandlePeriodicHealthFunnel(bool apply, bool Real, bool /*changeAmount*/)
+{
m_isPeriodic = apply;
}
@@ -4016,90 +4720,82 @@ void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
/*** RESISTANCE ***/
/********************************/
-void Aura::HandleAuraModResistanceExclusive(bool apply, bool Real)
+void AuraEffect::HandleAuraModResistanceExclusive(bool apply, bool Rea, bool /*changeAmount*/)
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),GetParentAura()->IsPositive(),m_amount, apply);
}
}
}
-void Aura::HandleAuraModResistance(bool apply, bool Real)
+void AuraEffect::HandleAuraModResistance(bool apply, bool Real, bool /*changeAmount*/)
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
+ if(GetMiscValue() & int32(1<<x))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsMod(SpellSchools(x),GetParentAura()->IsPositive(),m_amount, apply);
}
}
- // Faerie Fire (druid versions)
- if( (m_spellProto->SpellIconID == 109 &&
- m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
- m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
- || m_spellProto->Id == 35325)
- {
- m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
- }
}
-void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
+void AuraEffect::HandleAuraModBaseResistancePCT(bool apply, bool Real, bool /*changeAmount*/)
{
// only players have base stats
if(m_target->GetTypeId() != TYPEID_PLAYER)
{
//pets only have base armor
- if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetModifierValue()), apply);
+ if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_amount), apply);
}
else
{
for(int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL;x++)
{
- if(m_modifier.m_miscvalue & int32(1<<x))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetModifierValue()), apply);
+ if(GetMiscValue() & int32(1<<x))
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_amount), apply);
}
}
}
-void Aura::HandleModResistancePercent(bool apply, bool Real)
+void AuraEffect::HandleModResistancePercent(bool apply, bool Real, bool /*changeAmount*/)
{
for(int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
{
- if(m_modifier.m_miscvalue & int32(1<<i))
+ if(GetMiscValue() & int32(1<<i))
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
{
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,GetModifierValue(), apply);
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,GetModifierValue(), apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_amount, apply);
+ m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_amount, apply);
}
}
}
}
-void Aura::HandleModBaseResistance(bool apply, bool Real)
+void AuraEffect::HandleModBaseResistance(bool apply, bool Real, bool /*changeAmount*/)
{
// only players have base stats
if(m_target->GetTypeId() != TYPEID_PLAYER)
{
//only pets have base stats
- if(((Creature*)m_target)->isPet() && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetModifierValue()), apply);
+ if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_amount), apply);
}
else
{
for(int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
- if(m_modifier.m_miscvalue & (1<<i))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ if(GetMiscValue() & (1<<i))
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_amount), apply);
}
}
@@ -4107,30 +4803,30 @@ void Aura::HandleModBaseResistance(bool apply, bool Real)
/*** STAT ***/
/********************************/
-void Aura::HandleAuraModStat(bool apply, bool Real)
+void AuraEffect::HandleAuraModStat(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_modifier.m_miscvalue < -2 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -2 || GetMiscValue() > 4)
{
- sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),m_modifier.m_miscvalue);
+ sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),GetMiscValue());
return;
}
for(int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
{
// -1 or -2 is all stats ( misc < -2 checked in function beginning )
- if (m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue == i)
+ if (GetMiscValue() < 0 || GetMiscValue() == i)
{
- //m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetModifierValue()), apply);
+ //m_target->ApplyStatMod(Stats(i), m_amount,apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatBuffMod(Stats(i),GetModifierValue(),apply);
+ m_target->ApplyStatBuffMod(Stats(i),m_amount,apply);
}
}
}
-void Aura::HandleModPercentStat(bool apply, bool Real)
+void AuraEffect::HandleModPercentStat(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
{
sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
return;
@@ -4142,12 +4838,12 @@ void Aura::HandleModPercentStat(bool apply, bool Real)
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
{
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(GetModifierValue()), apply);
+ if(GetMiscValue() == i || GetMiscValue() == -1)
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
}
}
-void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4158,7 +4854,7 @@ void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4167,16 +4863,7 @@ void Aura::HandleModSpellHealingPercentFromStat(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleAuraModDispelResist(bool apply, bool Real)
-{
- if(!Real || !apply)
- return;
-
- if(GetId()==33206)
- m_target->CastSpell(m_target,44416,true,NULL,this,GetCasterGUID());
-}
-
-void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4187,7 +4874,7 @@ void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4196,7 +4883,7 @@ void Aura::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModHealingDone(bool /*apply*/, bool Real)
+void AuraEffect::HandleModHealingDone(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4205,9 +4892,9 @@ void Aura::HandleModHealingDone(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
}
-void Aura::HandleModTotalPercentStat(bool apply, bool Real)
+void AuraEffect::HandleModTotalPercentStat(bool apply, bool Real, bool /*changeAmount*/)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
{
sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
return;
@@ -4219,16 +4906,16 @@ void Aura::HandleModTotalPercentStat(bool apply, bool Real)
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
{
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+ if(GetMiscValue() == i || GetMiscValue() == -1)
{
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_amount), apply);
if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatPercentBuffMod(Stats(i), GetModifierValue(), apply );
+ m_target->ApplyStatPercentBuffMod(Stats(i), m_amount, apply );
}
}
//recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
- if ((m_modifier.m_miscvalue == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
+ if ((GetMiscValue() == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
{
// newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue;
@@ -4236,12 +4923,12 @@ void Aura::HandleModTotalPercentStat(bool apply, bool Real)
}
}
-void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- if(m_modifier.m_miscvalue != SPELL_SCHOOL_MASK_NORMAL)
+ if(GetMiscValue() != SPELL_SCHOOL_MASK_NORMAL)
{
// support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
// and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
@@ -4256,145 +4943,70 @@ void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
/********************************/
/*** HEAL & ENERGIZE ***/
/********************************/
-void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real, bool /*changeAmount*/)
{
- /*
- Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
- so this aura not fully working.
- */
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetHealth() < m_target->GetMaxHealth())
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
-
m_isPeriodic = apply;
}
-void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
+void AuraEffect::HandleAuraModTotalEnergyPercentRegen(bool apply, bool Real, bool /*changeAmount*/)
{
- if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
- if(apply)
- {
- if(m_modifier.periodictime == 0)
- m_modifier.periodictime = 1000;
- if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
- {
- m_periodicTimer += m_modifier.periodictime;
-
- if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
- {
- // PeriodicTick can cast triggered spells with stats changes
- PeriodicTick();
- }
- }
- }
+ if(m_amplitude == 0)
+ m_amplitude = 1000;
+ m_periodicTimer = m_amplitude;
m_isPeriodic = apply;
}
-void Aura::HandleModRegen(bool apply, bool Real) // eating
+void AuraEffect::HandleModRegen(bool apply, bool Real, bool /*changeAmount*/) // eating
{
- if(apply)
- {
- if(!m_target->isAlive())
- return;
-
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
-
- if(m_periodicTimer <= 0)
- {
- m_periodicTimer += 5000;
- int32 gain = m_target->ModifyHealth(GetModifierValue());
- Unit *caster = GetCaster();
- if (caster)
- {
- SpellEntry const *spellProto = GetSpellProto();
- if (spellProto)
- m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
- }
- }
- }
+ if(m_amplitude == 0)
+ m_amplitude = 5000;
+ m_periodicTimer = 5000;
m_isPeriodic = apply;
}
-void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
+void AuraEffect::HandleModPowerRegen(bool apply, bool Real, bool changeAmount) // drinking
{
- if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
- m_target->SetStandState(PLAYER_STATE_SIT);
+ if(!Real && !changeAmount)
+ return;
- if(apply && m_periodicTimer <= 0)
+ Powers pt = m_target->getPowerType();
+ if(m_amplitude == 0)
{
-
- Powers pt = m_target->getPowerType();
+ // Anger Management (only spell use this aura for rage)
if (pt == POWER_RAGE)
- m_periodicTimer = 3000;
- else
- m_periodicTimer = 2000;
+ m_amplitude = 3000;
+ else
+ m_amplitude = 2000;
+ }
- if(int32(pt) != m_modifier.m_miscvalue)
- return;
+ m_periodicTimer = 5000;
- 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(398);
- }
+ if (m_target->GetTypeId() == TYPEID_PLAYER && GetMiscValue() == POWER_MANA)
+ ((Player*)m_target)->UpdateManaRegen();
- // Warrior talent, gain 1 rage every 3 seconds while in combat
- // Anger Menagement
- // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
- // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
- if(pt == POWER_RAGE)
- {
- m_target->ModifyPower(pt, m_modifier.m_amount*3/5);
- }
- }
m_isPeriodic = apply;
- if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
- ((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
+void AuraEffect::HandleModPowerRegenPCT(bool /*apply*/, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if (m_target->GetTypeId() != TYPEID_PLAYER)
return;
// Update manaregen value
- if (m_modifier.m_miscvalue == POWER_MANA)
+ if (GetMiscValue() == POWER_MANA)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleModManaRegen(bool /*apply*/, bool Real)
+void AuraEffect::HandleModManaRegen(bool /*apply*/, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if (m_target->GetTypeId() != TYPEID_PLAYER)
@@ -4404,7 +5016,7 @@ void Aura::HandleModManaRegen(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleComprehendLanguage(bool apply, bool Real)
+void AuraEffect::HandleComprehendLanguage(bool apply, bool Real, bool /*changeAmount*/)
{
if(apply)
m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
@@ -4412,32 +5024,36 @@ void Aura::HandleComprehendLanguage(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
}
-void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseHealth(bool apply, bool Real, bool changeAmount)
{
- if(Real)
+ if(Real || changeAmount)
{
if(apply)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->ModifyHealth(m_modifier.m_amount);
+ // Vampiric Blood
+ if(GetSpellProto()->Id == 55233)
+ m_amount = m_target->GetMaxHealth() * m_amount / 100;
+
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
+ m_target->ModifyHealth(m_amount);
}
else
{
- if (int32(m_target->GetHealth()) > m_modifier.m_amount)
- m_target->ModifyHealth(-m_modifier.m_amount);
+ if (int32(m_target->GetHealth()) > m_amount)
+ m_target->ModifyHealth(-m_amount);
else
m_target->SetHealth(1);
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
}
}
}
-void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseMaxHealth(bool apply, bool Real, bool /*changeAmount*/)
{
uint32 oldhealth = m_target->GetHealth();
double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth();
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
// refresh percentage
if(oldhealth > 0)
@@ -4450,38 +5066,43 @@ void Aura::HandleAuraModIncreaseMaxHealth(bool apply, bool Real)
}
}
-void Aura::HandleAuraModIncreaseEnergy(bool apply, bool Real)
+void AuraEffect::HandleAuraModIncreaseEnergy(bool apply, bool Real, bool /*changeAmount*/)
{
Powers powerType = m_target->getPowerType();
- if(int32(powerType) != m_modifier.m_miscvalue)
+ if(int32(powerType) != GetMiscValue())
return;
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_amount), apply);
}
-void Aura::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/)
+void AuraEffect::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
{
Powers powerType = m_target->getPowerType();
- if(int32(powerType) != m_modifier.m_miscvalue)
+ if(int32(powerType) != GetMiscValue())
return;
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)
+void AuraEffect::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_amount), apply);
+}
+
+void AuraEffect::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
+{
+ m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_amount), apply);
}
/********************************/
/*** FIGHT ***/
/********************************/
-void Aura::HandleAuraModParryPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModParryPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
@@ -4489,28 +5110,28 @@ void Aura::HandleAuraModParryPercent(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateParryPercentage();
}
-void Aura::HandleAuraModDodgePercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModDodgePercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
((Player*)m_target)->UpdateDodgePercentage();
- //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount));
+ //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_amount));
}
-void Aura::HandleAuraModBlockPercent(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModBlockPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
((Player*)m_target)->UpdateBlockPercentage();
- //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_modifier.m_amount));
+ //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_amount));
}
-void Aura::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(m_target->GetTypeId()!=TYPEID_PLAYER)
@@ -4519,13 +5140,13 @@ void Aura::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateManaRegen();
}
-void Aura::HandleAuraModCritPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModCritPercent(bool apply, bool Real, bool changeAmount)
{
if(m_target->GetTypeId()!=TYPEID_PLAYER)
return;
// apply item specific bonuses for already equipped weapon
- if(Real)
+ if(Real || changeAmount)
{
for(int i = 0; i < MAX_ATTACK; ++i)
if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
@@ -4534,13 +5155,13 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
if (GetSpellProto()->EquippedItemClass == -1)
{
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetModifierValue()), apply);
+ ((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);
}
else
{
@@ -4548,21 +5169,36 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)
}
}
-void Aura::HandleModHitChance(bool apply, bool Real)
+void AuraEffect::HandleModHitChance(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->m_modMeleeHitChance += apply ? GetModifierValue() : -GetModifierValue();
- m_target->m_modRangedHitChance += apply ? GetModifierValue() : -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateMeleeHitChances();
+ ((Player*)m_target)->UpdateRangedHitChances();
+ }
+ else
+ {
+ m_target->m_modMeleeHitChance += apply ? m_amount : (-m_amount);
+ m_target->m_modRangedHitChance += apply ? m_amount : (-m_amount);
+ }
}
-void Aura::HandleModSpellHitChance(bool apply, bool Real)
+void AuraEffect::HandleModSpellHitChance(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->m_modSpellHitChance += apply ? GetModifierValue(): -GetModifierValue();
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_target)->UpdateSpellHitChances();
+ }
+ else
+ {
+ m_target->m_modSpellHitChance += apply ? m_amount: (-m_amount);
+ }
}
-void Aura::HandleModSpellCritChance(bool apply, bool Real)
+void AuraEffect::HandleModSpellCritChance(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(m_target->GetTypeId() == TYPEID_PLAYER)
@@ -4571,21 +5207,21 @@ void Aura::HandleModSpellCritChance(bool apply, bool Real)
}
else
{
- m_target->m_baseSpellCritChance += apply ? GetModifierValue():-GetModifierValue();
+ m_target->m_baseSpellCritChance += apply ? m_amount:-m_amount;
}
}
-void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
+void AuraEffect::HandleModSpellCritChanceShool(bool /*apply*/, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
for(int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
- if (m_modifier.m_miscvalue & (1<<school))
+ if (GetMiscValue() & (1<<school))
((Player*)m_target)->UpdateSpellCritChance(school);
}
@@ -4593,157 +5229,137 @@ void Aura::HandleModSpellCritChanceShool(bool /*apply*/, bool Real)
/*** ATTACK SPEED ***/
/********************************/
-void Aura::HandleModCastingSpeed(bool apply, bool Real)
+void AuraEffect::HandleModCastingSpeed(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
+ m_target->ApplyCastTimePercentMod(m_amount,apply);
}
-void Aura::HandleModMeleeRangedSpeedPct(bool apply, bool Real)
+void AuraEffect::HandleModMeleeRangedSpeedPct(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), 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);
}
-void Aura::HandleModCombatSpeedPct(bool apply, bool Real)
+void AuraEffect::HandleModCombatSpeedPct(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyCastTimePercentMod(GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ 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);
}
-void Aura::HandleModAttackSpeed(bool apply, bool Real)
+void AuraEffect::HandleModAttackSpeed(bool apply, bool Real, bool /*changeAmount*/)
{
if(!m_target->isAlive() )
return;
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,GetModifierValue(),apply);
+ m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
}
-void Aura::HandleHaste(bool apply, bool Real)
+void AuraEffect::HandleHaste(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK, GetModifierValue(),apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(),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);
}
-void Aura::HandleAuraModRangedHaste(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedHaste(bool apply, bool Real, bool /*changeAmount*/)
{
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
}
-void Aura::HandleRangedAmmoHaste(bool apply, bool Real)
+void AuraEffect::HandleRangedAmmoHaste(bool apply, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetModifierValue(), apply);
+ m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_amount, apply);
}
/********************************/
/*** ATTACK POWER ***/
/********************************/
-void Aura::HandleAuraModAttackPower(bool apply, bool Real)
-{
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetModifierValue()), apply);
- if(apply)
- switch(m_spellProto->Id){
- // Warrior & Druid Demoshout should remove stealth
- case 1160:
- case 6190:
- case 11554:
- case 11555:
- case 11556:
- case 25202:
- case 25203:
- case 47437: //WotLK spell
- case 99:
- case 1735:
- case 9490:
- case 9747:
- case 9898:
- case 26998:
- case 48559: //WotLK spell
- case 48560: //WotLK spell
- m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- break;
- }
-}
-
-void Aura::HandleAuraModRangedAttackPower(bool apply, bool Real)
+void AuraEffect::HandleAuraModAttackPower(bool apply, bool Real, bool /*changeAmount*/)
+{
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_amount), apply);
+}
+
+void AuraEffect::HandleAuraModRangedAttackPower(bool apply, bool Real, bool /*changeAmount*/)
{
if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
return;
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_amount), apply);
}
-void Aura::HandleAuraModAttackPowerPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModAttackPowerPercent(bool apply, bool Real, bool /*changeAmount*/)
{
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real, bool /*changeAmount*/)
{
if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
return;
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_amount), apply);
}
-void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)
+void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
- if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
- return;
+ // Recalculate bonus
+ if(m_target->GetTypeId() == TYPEID_PLAYER && !(m_target->getClassMask() & CLASSMASK_WAND_USERS))
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+}
- if(m_modifier.m_miscvalue != STAT_INTELLECT)
- {
- // support required adding UpdateAttackPowerAndDamage calls at stat update
- sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!");
+void AuraEffect::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount)
+{
+ // spells required only Real aura add/remove
+ if(!Real && !changeAmount)
return;
- }
// Recalculate bonus
- ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
}
/********************************/
/*** DAMAGE BONUS ***/
/********************************/
-void Aura::HandleModDamageDone(bool apply, bool Real)
+void AuraEffect::HandleModDamageDone(bool apply, bool Real, bool changeAmount)
{
// apply item specific bonuses for already equipped weapon
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
+ if((Real || changeAmount) && m_target->GetTypeId()==TYPEID_PLAYER)
{
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);
}
- // m_modifier.m_miscvalue is bitmask of spell schools
+ // GetMiscValue() is bitmask of spell schools
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
// 127 - full bitmask any damages
//
// mods must be applied base at equipped weapon class and subclass comparison
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
{
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetModifierValue()), apply);
+ 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);
}
else
{
@@ -4752,15 +5368,15 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
- if(m_positive)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetModifierValue(),apply);
+ if(GetParentAura()->IsPositive())
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_amount,apply);
else
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetModifierValue(),apply);
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_amount,apply);
}
}
// Skip non magic case for speedup
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
return;
if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
@@ -4776,57 +5392,57 @@ void Aura::HandleModDamageDone(bool apply, bool Real)
// This information for client side use only
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
- if(m_positive)
+ if(GetParentAura()->IsPositive())
{
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
- if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,GetModifierValue(),apply);
+ if((GetMiscValue() & (1<<i)) != 0)
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_amount,apply);
}
}
else
{
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
{
- if((m_modifier.m_miscvalue & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,GetModifierValue(),apply);
+ if((GetMiscValue() & (1<<i)) != 0)
+ m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_amount,apply);
}
}
- Pet* pet = m_target->GetPet();
+ Pet* pet = ((Player*)m_target)->GetPet();
if(pet)
pet->UpdateAttackPowerAndDamage();
}
}
-void Aura::HandleModDamagePercentDone(bool apply, bool Real)
+void AuraEffect::HandleModDamagePercentDone(bool apply, bool Real, bool changeAmount)
{
- sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", m_modifier.m_miscvalue, m_positive ? 0 : 1);
+ sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", GetMiscValue(), GetParentAura()->IsPositive() ? 0 : 1);
// apply item specific bonuses for already equipped weapon
- if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
+ if((Real || changeAmount) && m_target->GetTypeId()==TYPEID_PLAYER)
{
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);
}
- // m_modifier.m_miscvalue is bitmask of spell schools
+ // GetMiscValue() is bitmask of spell schools
// 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including 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
- // m_modifier.m_miscvalue comparison with item generated damage types
+ // GetMiscValue() comparison with item generated damage types
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
{
// apply generic physical damage bonuses including wand case
if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetModifierValue()), apply);
+ 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);
}
else
{
@@ -4834,11 +5450,11 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
}
// For show in client
if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_modifier.m_amount/100.0f,apply);
+ m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_amount/100.0f,apply);
}
// Skip non magic case for speedup
- if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
return;
if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
@@ -4854,190 +5470,88 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real)
// Send info to client
if(m_target->GetTypeId() == TYPEID_PLAYER)
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_modifier.m_amount/100.0f,apply);
+ m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_amount/100.0f,apply);
}
-void Aura::HandleModOffhandDamagePercent(bool apply, bool Real)
+void AuraEffect::HandleModOffhandDamagePercent(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
sLog.outDebug("AURA MOD OFFHAND DAMAGE");
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetModifierValue()), apply);
+ m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_amount), apply);
}
/********************************/
/*** POWER COST ***/
/********************************/
-void Aura::HandleModPowerCostPCT(bool apply, bool Real)
+void AuraEffect::HandleModPowerCostPCT(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
- float amount = GetModifierValue() /100.0f;
+ float amount = m_amount /100.0f;
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(m_modifier.m_miscvalue & (1<<i))
+ if(GetMiscValue() & (1<<i))
m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
}
-void Aura::HandleModPowerCost(bool apply, bool Real)
+void AuraEffect::HandleModPowerCost(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(m_modifier.m_miscvalue & (1<<i))
- m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetModifierValue(),apply);
+ if(GetMiscValue() & (1<<i))
+ m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_amount,apply);
+}
+
+void AuraEffect::HandleNoReagentUseAura(bool Apply, bool Real, bool /*changeAmount*/)
+{
+ // spells required only Real aura add/remove
+ if(!Real)
+ return;
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ flag96 mask;
+ Unit::AuraEffectList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE);
+ for(Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ mask |= (*i)->m_spellProto->EffectSpellClassMask[(*i)->m_effIndex];
+
+ 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]);
}
/*********************************************************/
/*** OTHERS ***/
/*********************************************************/
-void Aura::HandleShapeshiftBoosts(bool apply)
+void AuraEffect::HandleAuraAllowOnlyAbility(bool apply, bool Real, bool /*changeAmount*/)
{
- uint32 spellId = 0;
- uint32 spellId2 = 0;
- uint32 HotWSpellId = 0;
-
- switch(GetModifier()->m_miscvalue)
- {
- case FORM_CAT:
- spellId = 3025;
- HotWSpellId = 24900;
- break;
- case FORM_TREE:
- spellId = 5420;
- 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;
- break;
- case FORM_FLIGHT_EPIC:
- spellId = 40122;
- spellId2 = 40121;
- 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 = GetModifier()->m_miscvalue-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(!Real)
+ return;
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- if(itr->first==spellId || itr->first==spellId2) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
- if (spellInfo->Stances & (1<<form))
- m_target->CastSpell(m_target, itr->first, true, NULL, this);
- }
- //LotP
- if (((Player*)m_target)->HasSpell(17007))
- {
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
- if (spellInfo && spellInfo->Stances & (1<<form))
- m_target->CastSpell(m_target, 24932, true, NULL, this);
- }
- // HotW
- if (HotWSpellId)
- {
- Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for(Unit::AuraList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetModifier()->m_miscvalue == 3)
- {
- int32 HotWMod = (*i)->GetModifier()->m_amount;
- if(GetModifier()->m_miscvalue == FORM_CAT)
- HotWMod /= 2;
+ if(!apply && m_target->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY))
+ return;
- m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
- break;
- }
- }
- }
- }
- }
- else
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
{
- m_target->RemoveAurasDueToSpell(spellId);
- m_target->RemoveAurasDueToSpell(spellId2);
-
- Unit::AuraMap& tAuras = m_target->GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- if (itr->second->IsRemovedOnShapeLost())
- {
- m_target->RemoveAurasDueToSpell(itr->second->GetId());
- itr = tAuras.begin();
- }
- else
- {
- ++itr;
- }
- }
+ if (apply)
+ m_target->SetFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ else
+ m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
}
-
- /*double healthPercentage = (double)m_target->GetHealth() / (double)m_target->GetMaxHealth();
- m_target->SetHealth(uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage)));*/
}
-void Aura::HandleAuraEmpathy(bool apply, bool Real)
+void AuraEffect::HandleAuraEmpathy(bool apply, bool Real, bool /*changeAmount*/)
{
- if(m_target->GetTypeId() != TYPEID_UNIT)
+ if(!Real || m_target->GetTypeId() != TYPEID_UNIT)
return;
CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
@@ -5045,43 +5559,43 @@ void Aura::HandleAuraEmpathy(bool apply, bool Real)
m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
}
-void Aura::HandleAuraUntrackable(bool apply, bool Real)
+void AuraEffect::HandleAuraUntrackable(bool apply, bool Real, bool /*changeAmount*/)
{
+ if (!Real)
+ return;
if(apply)
- m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
else
- m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_UNTRACKABLE);
+ m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
}
-void Aura::HandleAuraModPacify(bool apply, bool Real)
+void AuraEffect::HandleAuraModPacify(bool apply, bool Real, bool /*changeAmount*/)
{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
+ if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
return;
if(apply)
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
else
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
-
-
- 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);
- }
- }
}
-void Aura::HandleAuraModPacifyAndSilence(bool apply, bool Real)
+void AuraEffect::HandleAuraModPacifyAndSilence(bool apply, bool Real, bool changeAmount)
{
- HandleAuraModPacify(apply,Real);
- HandleAuraModSilence(apply,Real);
+ 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);
}
-void Aura::HandleAuraGhost(bool apply, bool Real)
+void AuraEffect::HandleAuraGhost(bool apply, bool Real, bool /*changeAmount*/)
{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
+ if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
return;
if(apply)
@@ -5094,7 +5608,7 @@ void Aura::HandleAuraGhost(bool apply, bool Real)
}
}
-void Aura::HandleAuraAllowFlight(bool apply, bool Real)
+void AuraEffect::HandleAuraAllowFlight(bool apply, bool Real, bool /*changeAmount*/)
{
// all applied/removed only at real aura add/remove
if(!Real)
@@ -5103,29 +5617,57 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real)
// allow fly
WorldPacket data;
if(apply)
+ {
data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
+ m_target->AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ }
+ }
else
+ {
data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
+ m_target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+ }
+ }
data.append(m_target->GetPackGUID());
data << uint32(0); // unk
m_target->SendMessageToSet(&data, true);
}
-void Aura::HandleModRating(bool apply, bool Real)
+void AuraEffect::HandleModRating(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
- if (m_modifier.m_miscvalue & (1 << rating))
- ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), GetModifierValue(), apply);
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_amount, apply);
+}
+
+void AuraEffect::HandleModRatingFromStat(bool apply, bool Real, bool changeAmount)
+{
+ // spells required only Real aura add/remove
+ if(!Real && !changeAmount)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Just recalculate ratings
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
}
-void Aura::HandleForceMoveForward(bool apply, bool Real)
+void AuraEffect::HandleForceMoveForward(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5135,7 +5677,7 @@ void Aura::HandleForceMoveForward(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
}
-void Aura::HandleAuraModExpertise(bool /*apply*/, bool Real)
+void AuraEffect::HandleAuraModExpertise(bool /*apply*/, bool Real, bool /*changeAmount*/)
{
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5144,36 +5686,36 @@ void Aura::HandleAuraModExpertise(bool /*apply*/, bool Real)
((Player*)m_target)->UpdateExpertise(OFF_ATTACK);
}
-void Aura::HandleModTargetResistance(bool apply, bool Real)
+void AuraEffect::HandleModTargetResistance(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
// applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
// show armor penetration
- if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL))
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,GetModifierValue(), apply);
+ if (m_target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_amount, apply);
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
- if (m_target->GetTypeId() == TYPEID_PLAYER && (m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,GetModifierValue(), apply);
+ 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);
}
-void Aura::HandleShieldBlockValue(bool apply, bool Real)
+void AuraEffect::HandleShieldBlockValue(bool apply, bool Real, bool /*changeAmount*/)
{
BaseModType modType = FLAT_MOD;
- if(m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
+ if(m_auraName == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
modType = PCT_MOD;
if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(GetModifierValue()), apply);
+ ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_amount), apply);
}
-void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
+void AuraEffect::HandleAuraRetainComboPoints(bool apply, bool Real, bool changeAmount)
{
// spells required only Real aura add/remove
- if(!Real)
+ if(!Real && !changeAmount)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
@@ -5183,23 +5725,26 @@ void Aura::HandleAuraRetainComboPoints(bool apply, bool Real)
// combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
// remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
- if( !apply && m_duration==0 && target->GetComboTarget())
+ if( !apply && GetParentAura()->GetAuraDuration()==0 && target->GetComboTarget())
if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
- target->AddComboPoints(unit, -GetModifierValue());
+ target->AddComboPoints(unit, -m_amount);
}
-void Aura::HandleModUnattackable( bool Apply, bool Real )
+void AuraEffect::HandleModUnattackable( bool Apply, bool Real , bool /*changeAmount*/)
{
- if(Real && Apply)
+ if(!Real)
+ return;
+
+ if(Apply)
{
m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_UNATTACKABLE);
+ m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
}
- m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE,Apply);
+ m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, Apply);
}
-void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
+void AuraEffect::HandleSpiritOfRedemption( bool apply, bool Real , bool /*changeAmount*/)
{
// spells required only Real aura add/remove
if(!Real)
@@ -5215,7 +5760,7 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
// set stand state (expected in this form)
if(!m_target->IsStandState())
- m_target->SetStandState(PLAYER_STATE_NONE);
+ m_target->SetStandState(UNIT_STAND_STATE_STAND);
}
m_target->SetHealth(1);
@@ -5225,38 +5770,9 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real )
m_target->setDeathState(JUST_DIED);
}
-void Aura::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);
-}
-
-void Aura::HandleAuraPowerBurn(bool apply, bool Real)
+void AuraEffect::HandleSchoolAbsorb(bool apply, bool Real, bool changeAmount)
{
- if (m_periodicTimer <= 0)
- m_periodicTimer += m_modifier.periodictime;
-
- m_isPeriodic = apply;
-}
-
-void Aura::HandleSchoolAbsorb(bool apply, bool Real)
-{
- if(!Real)
+ if(!Real && !changeAmount)
return;
// prevent double apply bonuses
@@ -5268,29 +5784,36 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_PRIEST:
- if(m_spellProto->SpellFamilyFlags == 0x1) //PW:S
+ // PW: S
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0x1, 0, 0x400))
{
- //+30% from +healing bonus
- DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
- break;
+ // +80.68% from sp bonus
+ DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f;
}
break;
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL)
+ // 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))
{
- //frost ward, fire ward, ice barrier
//+10% from +spd bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
- break;
}
+ */
break;
case SPELLFAMILY_WARLOCK:
- if(m_spellProto->SpellFamilyFlags == 0x00)
+ // shadow ward
+ if(m_spellProto->SpellFamilyFlags.IsEqual(0, 0, 0x40))
{
- //shadow ward
- //+10% from +spd bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
- break;
+ // +30% from sp bonus
+ DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
}
break;
default:
@@ -5299,17 +5822,17 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
- m_modifier.m_amount += (int32)DoneActualBenefit;
+ m_amount += (int32)DoneActualBenefit;
}
}
}
-void Aura::PeriodicTick()
+void AuraEffect::PeriodicTick()
{
if(!m_target->isAlive())
return;
- switch(m_modifier.m_auraname)
+ switch(GetAuraName())
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
@@ -5318,16 +5841,17 @@ void Aura::PeriodicTick()
if(!pCaster)
return;
+ // Consecrate ticks can miss and will not show up in the combat log
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)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// some auras remove at specific health level or more
- if(m_modifier.m_auraname==SPELL_AURA_PERIODIC_DAMAGE)
+ if(m_auraName==SPELL_AURA_PERIODIC_DAMAGE)
{
switch(GetId())
{
@@ -5354,19 +5878,20 @@ void Aura::PeriodicTick()
}
case 41337:// aura of anger
{
- Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i)
+ 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)
{
if ((*i)->GetId() == 41337)
{
(*i)->ApplyModifier(false);
- (*i)->GetModifier()->m_amount += 5;
+ (*i)->SetAmount((*i)->GetAmount()+5);
(*i)->ApplyModifier(true);
break;
}
}
- m_modifier.m_amount = 100 * m_tickNumber;
- }break;
+ m_amount = 100 * m_tickNumber;
+ break;
+ }
default:
break;
}
@@ -5377,30 +5902,27 @@ void Aura::PeriodicTick()
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
- uint32 pdamage;
-
- if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
+ if(GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
{
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),amount,DOT);
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
// 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)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
// Curse of Agony damage-per-tick calculation
- if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
+ if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x400) && GetSpellProto()->SpellIconID==544)
{
- uint32 totalTick = m_maxduration / m_modifier.periodictime;
+ uint32 totalTick = GetParentAura()->GetAuraMaxDuration() / m_amplitude;
// 1..4 ticks, 1/2 from normal tick damage
if(m_tickNumber <= totalTick / 3)
pdamage = pdamage/2;
@@ -5411,31 +5933,22 @@ void Aura::PeriodicTick()
}
}
else
- pdamage = uint32(m_target->GetMaxHealth()*amount/100);
+ pdamage = uint32(m_target->GetMaxHealth()*pdamage/100);
//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);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
- WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
- data.append(m_target->GetPackGUID());
- data.appendPackGUID(GetCasterGUID());
- data << uint32(GetId());
- data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)pdamage;
- data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
- data << (uint32)absorb;
- data << (uint32)resist;
- m_target->SendMessageToSet(&data,true);
+ pCaster->DealDamageMods(m_target,pdamage,&absorb);
+
+ SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, absorb, resist, 0.0f);
+ m_target->SendPeriodicAuraLog(&pInfo);
Unit* target = m_target; // aura can be deleted in DealDamage
SpellEntry const* spellProto = GetSpellProto();
@@ -5453,6 +5966,7 @@ void Aura::PeriodicTick()
break;
}
case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
{
Unit *pCaster = GetCaster();
if(!pCaster)
@@ -5465,88 +5979,32 @@ void Aura::PeriodicTick()
pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
return;
- // Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ // Check for immune
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
uint32 absorb=0;
uint32 resist=0;
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
+ //uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
//Calculate armor mitigation if it is a physical spell
if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
{
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
+ uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
- // talent Soul Siphon add bonus to Drain Life spells
- if( GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x8) )
- {
- // find talent max bonus percentage
- Unit::AuraList const& mClassScriptAuras = pCaster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for(Unit::AuraList::const_iterator i = mClassScriptAuras.begin(); i != mClassScriptAuras.end(); ++i)
- {
- if ((*i)->GetModifier()->m_miscvalue == 4992 || (*i)->GetModifier()->m_miscvalue == 4993)
- {
- if((*i)->GetEffIndex()!=1)
- {
- sLog.outError("Expected spell %u structure change, need code update",(*i)->GetId());
- break;
- }
-
- // effect 1 m_amount
- int32 maxPercent = (*i)->GetModifier()->m_amount;
- // effect 0 m_amount
- int32 stepPercent = pCaster->CalculateSpellDamage((*i)->GetSpellProto(),0,(*i)->GetSpellProto()->EffectBasePoints[0],pCaster);
-
- // count affliction effects and calc additional damage in percentage
- int32 modPercent = 0;
- Unit::AuraMap const& victimAuras = m_target->GetAuras();
- for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
- {
- Aura* aura = itr->second;
- if (aura->IsPositive())continue;
- SpellEntry const* m_spell = aura->GetSpellProto();
- if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK)
- continue;
-
- SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(m_spell->Id);
- SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(m_spell->Id);
-
- for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
- {
- if(_spell_idx->second->skillId == SKILL_AFFLICTION)
- {
- modPercent += stepPercent;
- if (modPercent >= maxPercent)
- {
- modPercent = maxPercent;
- break;
- }
- }
- }
- }
- pdamage += (pdamage*modPercent/100);
- break;
- }
- }
- }
-
//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);
- pdamage *= GetStackAmount();
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
+ pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
if(m_target->GetHealth() < pdamage)
pdamage = uint32(m_target->GetHealth());
@@ -5556,10 +6014,10 @@ void Aura::PeriodicTick()
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;
+ int32 stackAmount = GetParentAura()->GetStackAmount();
// Set trigger flag
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
@@ -5580,16 +6038,13 @@ void Aura::PeriodicTick()
}
}
-
if(Player *modOwner = pCaster->GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
- uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
+ uint32 heal = uint32(pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, stackAmount));
- int32 gain = pCaster->ModifyHealth(heal);
+ int32 gain = pCaster->DealHeal(pCaster, heal, spellProto);
pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
-
- pCaster->SendHealSpellLog(pCaster, spellProto->Id, heal);
break;
}
case SPELL_AURA_PERIODIC_HEAL:
@@ -5600,53 +6055,43 @@ void Aura::PeriodicTick()
return;
// heal for caster damage (must be alive)
- if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive())
+ if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive())
return;
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetHealth()==m_target->GetMaxHealth())
+ return;
- uint32 pdamage;
+ // ignore non positive values (can be result apply spellmods to aura damage
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ int32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
- if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
- pdamage = uint32(m_target->GetMaxHealth() * amount/100);
+ if(m_auraName==SPELL_AURA_OBS_MOD_HEALTH)
+ pdamage = uint32(m_target->GetMaxHealth() * pdamage * GetParentAura()->GetStackAmount() / 100);
else
- pdamage = pCaster->SpellHealingBonus(GetSpellProto(), amount, DOT, m_target);
-
- pdamage *= GetStackAmount();
-
- //pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
+ pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
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());
- WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
- data.append(m_target->GetPackGUID());
- data.appendPackGUID(GetCasterGUID());
- data << uint32(GetId());
- data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)pdamage;
- m_target->SendMessageToSet(&data,true);
-
int32 gain = m_target->ModifyHealth(pdamage);
+ SpellPeriodicAuraLogInfo pInfo(this, pdamage, pdamage - gain, 0, 0, 0.0f);
+ m_target->SendPeriodicAuraLog(&pInfo);
+
// 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);
- //Do check before because m_modifier.auraName can be invalidate by DealDamage.
- bool procSpell = (m_modifier.m_auraname == SPELL_AURA_PERIODIC_HEAL && m_target != pCaster);
-
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
Unit* target = m_target; // aura can be deleted in DealDamage
SpellEntry const* spellProto = GetSpellProto();
- bool haveCastItem = GetCastItemGUID()!=0;
+ bool haveCastItem = GetParentAura()->GetCastItemGUID()!=0;
+ // Health Funnel
// heal for caster damage
- if(m_target!=pCaster && spellProto->SpellVisual==163)
+ if(m_target!=pCaster && spellProto->SpellVisual[0]==163)
{
uint32 dmg = spellProto->manaPerSecond;
if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER)
@@ -5666,10 +6111,13 @@ void Aura::PeriodicTick()
}
else
{
- pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), gain, GetSpellSchoolMask(GetSpellProto()), 0, 0, false, 0, false);
+ uint32 damage = gain;
+ uint32 absorb = 0;
+ pCaster->DealDamageMods(pCaster,damage,&absorb);
+ pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- pCaster->DealDamage(pCaster, gain, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
+ pCaster->DealDamage(pCaster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
}
}
@@ -5677,12 +6125,21 @@ void Aura::PeriodicTick()
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
uint32 procEx = PROC_EX_INTERNAL_HOT | PROC_EX_NORMAL_HIT;
// ignore item heals
- if(procSpell && !haveCastItem)
+ if(!haveCastItem)
pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, pdamage, BASE_ATTACK, spellProto);
break;
}
case SPELL_AURA_PERIODIC_MANA_LEECH:
{
+ if(GetMiscValue() < 0 || GetMiscValue() >= MAX_POWERS)
+ return;
+
+ Powers power = Powers(GetMiscValue());
+
+ // power type might have changed between aura applying and tick (druid's shapeshift)
+ if(m_target->getPowerType() != power)
+ return;
+
Unit *pCaster = GetCaster();
if(!pCaster)
return;
@@ -5695,24 +6152,26 @@ void Aura::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ uint32 pdamage = m_amount > 0 ? m_amount : 0;
+
+ // Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
+ // It's mana percent cost spells, m_amount is percent drain from target
+ if (m_spellProto->ManaCostPercentage)
+ {
+ // max value
+ uint32 maxmana = pCaster->GetMaxPower(power) * pdamage * 2 / 100;
+ pdamage = m_target->GetMaxPower(power) * pdamage / 100;
+ if(pdamage > maxmana)
+ pdamage = maxmana;
+ }
sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
- break;
-
- Powers power = Powers(m_modifier.m_miscvalue);
-
- // power type might have changed between aura applying and tick (druid's shapeshift)
- if(m_target->getPowerType() != power)
- break;
-
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)
@@ -5731,16 +6190,8 @@ void Aura::PeriodicTick()
modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier);
}
- WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
- data.append(m_target->GetPackGUID());
- data.appendPackGUID(GetCasterGUID());
- data << uint32(GetId());
- data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)power; // power type
- data << (uint32)drain_amount;
- data << (float)gain_multiplier;
- m_target->SendMessageToSet(&data,true);
+ SpellPeriodicAuraLogInfo pInfo(this, drain_amount, 0, 0, 0, gain_multiplier);
+ m_target->SendPeriodicAuraLog(&pInfo);
int32 gain_amount = int32(drain_amount*gain_multiplier);
@@ -5755,7 +6206,7 @@ void Aura::PeriodicTick()
{
m_target->CastSpell(m_target, 31463, true, 0, this);
// Remove aura
- SetAuraDuration(0);
+ GetParentAura()->SetAuraDuration(0);
}
// Mark of Kazzak
@@ -5768,67 +6219,64 @@ void Aura::PeriodicTick()
{
m_target->CastSpell(m_target, 32961, true, 0, this);
// Remove aura
- SetAuraDuration(0);
+ GetParentAura()->SetAuraDuration(0);
}
}
break;
}
- case SPELL_AURA_PERIODIC_ENERGIZE:
+ case SPELL_AURA_OBS_MOD_ENERGY:
{
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ if(GetMiscValue() < 0)
+ return;
- 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(), pdamage, GetId());
+ Powers power;
+ if (GetMiscValue() == POWER_ALL)
+ power = m_target->getPowerType();
+ else
+ power = Powers(GetMiscValue());
- if(m_modifier.m_miscvalue < 0 || m_modifier.m_miscvalue > 4)
- break;
+ if(m_target->GetMaxPower(power) == 0)
+ return;
- Powers power = Powers(m_modifier.m_miscvalue);
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
+ return;
- if(m_target->GetMaxPower(power) == 0)
- break;
+ uint32 amount = m_amount * m_target->GetMaxPower(power) /100;
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), amount, GetId());
- WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
- data.append(m_target->GetPackGUID());
- data.appendPackGUID(GetCasterGUID());
- data << uint32(GetId());
- data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)power; // power type
- data << (uint32)pdamage;
- m_target->SendMessageToSet(&data,true);
+ SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f);
+ m_target->SendPeriodicAuraLog(&pInfo);
- int32 gain = m_target->ModifyPower(power,pdamage);
+ int32 gain = m_target->ModifyPower(power,amount);
if(Unit* pCaster = GetCaster())
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
break;
}
- case SPELL_AURA_OBS_MOD_MANA:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
{
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ if(m_amount < 0 || GetMiscValue() >= MAX_POWERS)
+ return;
- uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100);
+ Powers power = Powers(GetMiscValue());
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
+ if(m_target->GetMaxPower(power) == 0)
+ return;
- if(m_target->GetMaxPower(POWER_MANA) == 0)
- break;
+ if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
+ return;
+
+ uint32 amount = m_amount;
- WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
- data.append(m_target->GetPackGUID());
- data.appendPackGUID(GetCasterGUID());
- data << uint32(GetId());
- data << uint32(1);
- data << uint32(m_modifier.m_auraname);
- data << (uint32)0; // ?
- data << (uint32)pdamage;
- m_target->SendMessageToSet(&data,true);
+ SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f);
+ m_target->SendPeriodicAuraLog(&pInfo);
- int32 gain = m_target->ModifyPower(POWER_MANA, pdamage);
+ 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());
+
+ int32 gain = m_target->ModifyPower(power,amount);
if(Unit* pCaster = GetCaster())
m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
@@ -5841,12 +6289,12 @@ void Aura::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
- int32 pdamage = GetModifierValue() > 0 ? GetModifierValue() : 0;
+ int32 pdamage = m_amount > 0 ? m_amount : 0;
- Powers powerType = Powers(m_modifier.m_miscvalue);
+ Powers powerType = Powers(GetMiscValue());
if(!m_target->isAlive() || m_target->getPowerType() != powerType)
return;
@@ -5864,6 +6312,9 @@ void Aura::PeriodicTick()
SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
//no SpellDamageBonus for burn mana
pCaster->CalculateSpellDamageTaken(&damageInfo, gain, spellProto);
+
+ pCaster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
+
pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
// Set trigger flag
@@ -5878,124 +6329,150 @@ void Aura::PeriodicTick()
pCaster->DealSpellDamage(&damageInfo, true);
break;
}
+ case SPELL_AURA_MOD_REGEN:
+ {
+ int32 gain = m_target->ModifyHealth(m_amount);
+ 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();
+ if(int32(pt) != GetMiscValue())
+ return;
+
+ 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);
+ }
+ // Butchery
+ else if (m_spellProto->SpellFamilyName==SPELLFAMILY_DEATHKNIGHT
+ && m_spellProto->SpellIconID==2664)
+ {
+ if (m_target->isInCombat())
+ m_target->ModifyPower(pt,m_amount);
+ }
+
+ // Anger Management
+ // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
+ // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
+ if(pt == POWER_RAGE)
+ m_target->ModifyPower(pt, m_amount*3/5);
+ break;
+ }
+ case SPELL_AURA_DUMMY:
+ {
+ // Haunting Spirits
+ if (GetId() == 7057)
+ {
+ m_target->CastSpell((Unit*)NULL , m_amount , true);
+ m_amplitude = irand (0 , 60 ) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ break;
+ }
+ break;
+ }
// Here tick dummy auras
case SPELL_AURA_PERIODIC_DUMMY:
{
PeriodicDummyTick();
break;
}
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ {
+ TriggerSpell();
+ break;
+ }
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ {
+ TriggerSpellWithValue();
+ break;
+ }
default:
break;
}
}
-void Aura::PeriodicDummyTick()
+void AuraEffect::PeriodicDummyTick()
{
+ Unit *caster = GetCaster();
SpellEntry const* spell = GetSpellProto();
- 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:
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
- Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
- for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i)
+ 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:
{
- if ((*i)->GetId() == GetId())
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus
+ Unit::AuraEffectList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN);
+ for(Unit::AuraEffectList::const_iterator i = aura.begin(); i != aura.end(); ++i)
{
- BattleGround *bg = ((Player*)m_target)->GetBattleGround();
- if(!bg || !bg->isArena())
+ if ((*i)->GetId() == GetId())
{
- // default case - not in arena
- m_isPeriodic = false;
- if(m_tickNumber == 1)
- (*i)->GetModifier()->m_amount = m_modifier.m_amount;
+ (*i)->SetAmount(m_amount);
((Player*)m_target)->UpdateManaRegen();
+ // Disable continue
+ m_isPeriodic = false;
return;
}
- //**********************************************
- // This feature uses only in arenas
- //**********************************************
- // Here need increase mana regen per tick (6 second rule)
- // on 0 tick - 0 (handled in 2 second)
- // on 1 tick - 166% (handled in 4 second)
- // on 2 tick - 133% (handled in 6 second)
- // Not need update after 4 tick
- if (m_tickNumber > 4)
- return;
- // Apply bonus for 1 - 4 tick
- switch (m_tickNumber)
- {
- case 1: // 0%
- (*i)->GetModifier()->m_amount = 0;
- break;
- case 2: // 166%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
- break;
- case 3: // 133%
- (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
- break;
- default: // 100% - normal regen
- (*i)->GetModifier()->m_amount = m_modifier.m_amount;
- break;
- }
- ((Player*)m_target)->UpdateManaRegen();
- return;
}
+ 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;
}
- return;
- }
// // Panda
// case 19230: break;
-// // Master of Subtlety
-// case 31666: break;
// // Gossip NPC Periodic - Talk
// case 33208: break;
// // Gossip NPC Periodic - Despawn
// case 33209: break;
-// // Force of Nature
-// case 33831: break;
- // Aspect of the Viper
- case 34074:
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Should be manauser
- if (m_target->getPowerType()!=POWER_MANA)
- return;
- Unit *caster = GetCaster();
- if (!caster)
- return;
- // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
- int mana = m_target->GetPower(POWER_MANA);
- int max_mana = m_target->GetMaxPower(POWER_MANA);
- int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
- float regen_pct = 1.20f - 1.1f * mana / max_mana;
- if (regen_pct > 1.0f) regen_pct = 1.0f;
- else if (regen_pct < 0.2f) regen_pct = 0.2f;
- m_modifier.m_amount = int32 (base_regen * regen_pct);
- ((Player*)m_target)->UpdateManaRegen();
- return;
- }
// // Steal Weapon
// case 36207: break;
// // Simon Game START timer, (DND)
// case 39993: break;
-// // Harpooner's Mark
-// case 40084: break;
// // Knockdown Fel Cannon: break; The Aggro Burst
// case 40119: break;
// // Old Mount Spell
@@ -6008,6 +6485,8 @@ void Aura::PeriodicDummyTick()
// case 40846: break;
// // Copy Weapon
// case 41054: break;
+// // Dementia
+// case 41404: break;
// // Ethereal Ring Visual, Lightning Aura
// case 41477: break;
// // Ethereal Ring Visual, Lightning Aura (Fork)
@@ -6056,6 +6535,8 @@ void Aura::PeriodicDummyTick()
// case 43310: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17
// case 43884: break;
+// // Wretched!
+// case 43963: break;
// // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17
// case 44000: break;
// // Energy Feedback
@@ -6122,25 +6603,251 @@ void Aura::PeriodicDummyTick()
// case 47407: break;
// // Mole Machine Port Schedule
// case 47489: break;
+// case 47941: break; // Crystal Spike
+// case 48200: break; // Healer Aura
+// case 48630: break; // Summon Gauntlet Mobs Periodic
+// case 49313: break; // Proximity Mine Area Aura
// // Mole Machine Portal Schedule
// case 49466: break;
-// // Drink Coffee
-// case 49472: break;
+// case 49555: break; // Corpse Explode
+// case 49592: break; // Temporal Rift
+// case 49957: break; // Cutting Laser
+// case 50085: break; // Slow Fall
// // Listening to Music
// case 50493: break;
// // Love Rocket Barrage
// case 50530: break;
+ // Tenacity
+ case 58549:
+ case 59911:
+ GetParentAura()->RefreshAura();
+ break;
+// 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)
+ int32 apBonus = m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this);
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_WARLOCK:
+ switch (spell->Id)
+ {
+ // Demonic Circle
+ 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;
+ 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:
+ {
+ switch (spell->Id)
+ {
+ // Master of Subtlety
+ case 31666:
+ if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ m_target->RemoveAurasDueToSpell(31665);
+ break;
+ // Killing Spree
+ case 51690:
+ {
+ // TODO: this should use effect[1] of 51690
+ std::list<Unit*> targets;
+ {
+ // eff_radius ==0
+ float radius = GetSpellMaxRange(spell, false);
+
+ 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);
+ break;
+// default:
+// break;
+ }
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (spell->SpellFamilyFlags[1] & 0x80000000)
+ {
+ if(caster)
+ caster->CastCustomSpell(53352, SPELLVALUE_BASE_POINT0, m_amount, m_target, true, NULL, this);
+ 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
+ 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;
+ }
+ break;
+ }
+ case SPELLFAMILY_DEATHKNIGHT:
+ {
+ // Death and Decay
+ if (spell->SpellFamilyFlags[0] & 0x20)
+ {
+ if (caster)
+ caster->CastCustomSpell(m_target, 52212, &m_amount, NULL, NULL, true, 0, this);
+ return;
+ }
+ // Raise Dead
+// if (spell->SpellFamilyFlags & 0x0000000000001000LL)
+// return;
+ // Chains of Ice
+ if (spell->SpellFamilyFlags[1] & 0x00004000)
+ {
+ // Get 0 effect aura
+ AuraEffect *slow = GetParentAura()->GetPartAura(0);
+ if (slow)
+ {
+ slow->ApplyModifier(false, true);
+ slow->SetAmount(slow->GetAmount() + GetAmount());
+ if (slow->GetAmount() > 0) slow->SetAmount(0);
+ slow->ApplyModifier(true, true);
+ }
+ 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)
+ int32 apBonus = m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
+ 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;
+ }
default:
break;
}
}
-void Aura::HandlePreventFleeing(bool apply, bool Real)
+void AuraEffect::HandlePreventFleeing(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
- Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
+ Unit::AuraEffectList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
if( !fearAuras.empty() )
{
m_target->SetControlled(!apply, UNIT_STAT_FLEEING);
@@ -6151,9 +6858,9 @@ void Aura::HandlePreventFleeing(bool apply, bool Real)
}
}
-void Aura::HandleManaShield(bool apply, bool Real)
+void AuraEffect::HandleManaShield(bool apply, bool Real, bool changeAmount)
{
- if(!Real)
+ if(!Real && !changeAmount)
return;
// prevent double apply bonuses
@@ -6165,7 +6872,7 @@ void Aura::HandleManaShield(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_MAGE:
- if(m_spellProto->SpellFamilyFlags & 0x8000)
+ if(m_spellProto->SpellFamilyFlags[0] & 0x8000)
{
// Mana Shield
// +50% from +spd bonus
@@ -6179,12 +6886,12 @@ void Aura::HandleManaShield(bool apply, bool Real)
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
- m_modifier.m_amount += (int32)DoneActualBenefit;
+ m_amount += (int32)DoneActualBenefit;
}
}
}
-void Aura::HandleArenaPreparation(bool apply, bool Real)
+void AuraEffect::HandleArenaPreparation(bool apply, bool Real, bool /*changeAmount*/)
{
if(!Real)
return;
@@ -6195,21 +6902,229 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
}
-void Aura::UnregisterSingleCastAura()
+/**
+ * Such auras are applied from a caster(=player) to a vehicle.
+ * This has been verified using spell #49256
+ */
+void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAmount*/)
{
- if (IsSingleTarget())
+ if(!Real)
+ return;
+
+ if(m_target->GetTypeId() != TYPEID_UNIT || !((Creature*)m_target)->isVehicle())
+ return;
+
+ Unit *caster = GetSource();
+ if(!caster || caster == m_target)
+ return;
+
+ Vehicle * const vehicle = dynamic_cast<Vehicle * const>(m_target);
+
+ if (apply)
{
- Unit* caster = NULL;
- caster = GetCaster();
- if(caster)
+ //if(caster->GetTypeId() == TYPEID_PLAYER)
+ // if(Pet *pet = ((Player*)caster)->GetPet())
+ // pet->Remove(PET_SAVE_AS_CURRENT);
+ caster->EnterVehicle(vehicle, 0);
+ }
+ else
+ {
+ // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
+ caster->RemoveAurasDueToSpell(GetId());
+
+ caster->ExitVehicle();
+ }
+}
+
+void AuraEffect::HandleAuraConvertRune(bool apply, bool Real, bool /*changeAmount*/)
+{
+ 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)
{
- caster->GetSingleCastAuras().remove(this);
+ if(!plr->GetRuneCooldown(i))
+ {
+ plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]);
+ break;
+ }
}
else
{
- sLog.outError("Couldn't find the caster of the single target aura, may crash later!");
- assert(false);
+ if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex])
+ {
+ plr->ConvertRune(i, plr->GetBaseRune(i));
+ break;
+ }
}
- m_isSingleTargetAura = false;
}
}
+
+// Control Auras
+
+void AuraEffect::HandleAuraModStun(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ m_target->SetControlled(apply, UNIT_STAT_STUNNED);
+}
+
+void AuraEffect::HandleAuraModRoot(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ m_target->SetControlled(apply, UNIT_STAT_ROOT);
+}
+
+// Charm Auras
+
+void AuraEffect::HandleModPossess(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(caster && caster->GetTypeId() == TYPEID_UNIT)
+ {
+ HandleModCharm(apply, Real, false);
+ return;
+ }
+
+ if(apply)
+ {
+ if(m_target->getLevel() > m_amount)
+ return;
+
+ m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+ }
+ else
+ m_target->RemoveCharmedBy(caster);
+}
+
+void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ {
+ if(caster->GetGuardianPet() != m_target)
+ return;
+
+ m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+ }
+ else
+ {
+ m_target->RemoveCharmedBy(caster);
+
+ // 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);
+ }
+ }
+}
+
+void AuraEffect::HandleModCharm(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+
+ if(apply)
+ {
+ if(int32(m_target->getLevel()) > m_amount)
+ return;
+
+ m_target->SetCharmedBy(caster, CHARM_TYPE_CHARM);
+ }
+ else
+ m_target->RemoveCharmedBy(caster);
+}
+
+void AuraEffect::HandlePhase(bool apply, bool Real, bool /*changeAmount*/)
+{
+ if(!Real)
+ return;
+
+ // always non stackable
+ if(apply)
+ {
+ m_target->RemoveAurasByType(SPELL_AURA_PHASE, NULL, GetParentAura());
+ }
+
+ // no-phase is also phase state so same code for apply and remove
+
+ // phase auras normally not expected at BG but anyway better check
+ if(m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ // drop flag at invisible in bg
+ if(((Player*)m_target)->InBattleGround())
+ if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
+ bg->EventPlayerDroppedFlag((Player*)m_target);
+
+ // GM-mode have mask 0xFFFFFFFF
+ if(!((Player*)m_target)->isGameMaster())
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ ((Player*)m_target)->GetSession()->SendSetPhaseShift(apply ? GetMiscValue() : PHASEMASK_NORMAL);
+
+ if(GetEffIndex()==0)
+ {
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
+ if(saBounds.first != saBounds.second)
+ {
+ uint32 zone, area;
+ m_target->GetZoneAndAreaId(zone,area);
+
+ for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
+ {
+ // some auras remove at aura remove
+ if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
+ m_target->RemoveAurasDueToSpell(itr->second->spellId);
+ // some auras applied at aura apply
+ else if(itr->second->autocast)
+ {
+ if( !m_target->HasAura(itr->second->spellId) )
+ m_target->CastSpell(m_target,itr->second->spellId,true);
+ }
+ }
+ }
+ }
+ }
+ else
+ m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
+ if(m_target->GetVisibility()!=VISIBILITY_OFF)
+ m_target->SetVisibility(m_target->GetVisibility());
+}
+
+void AuraEffect::HandleAuraSafeFall( bool Apply, bool Real , bool /*changeAmount*/)
+{
+ // implemented in WorldSession::HandleMovementOpcodes
+
+ // only special case
+ if(Apply && Real && GetId()==32474 && m_target->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_target)->ActivateTaxiPathTo(506,GetId());
+}