2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "Common.h"
2010-06-08 17:01:03 -06:00
#include "DatabaseEnv.h"
2008-10-11 14:16:25 -05:00
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Log.h"
#include "UpdateMask.h"
#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "SkillExtraItems.h"
#include "Unit.h"
#include "Spell.h"
#include "DynamicObject.h"
#include "SpellAuras.h"
2010-01-10 01:23:15 +01:00
#include "SpellAuraEffects.h"
2008-10-11 14:16:25 -05:00
#include "Group.h"
#include "UpdateData.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "SharedDefines.h"
#include "Pet.h"
#include "GameObject.h"
#include "GossipDef.h"
#include "Creature.h"
#include "Totem.h"
#include "CreatureAI.h"
2010-08-08 04:37:24 +02:00
#include "BattlegroundMgr.h"
#include "Battleground.h"
#include "BattlegroundEY.h"
#include "BattlegroundWS.h"
2008-10-14 11:57:03 -05:00
#include "OutdoorPvPMgr.h"
2008-10-11 14:16:25 -05:00
#include "Language.h"
#include "SocialMgr.h"
#include "Util.h"
2010-06-05 00:59:25 +02:00
#include "VMapFactory.h"
2008-10-11 14:16:25 -05:00
#include "TemporarySummon.h"
2008-11-15 15:11:31 -06:00
#include "CellImpl.h"
2008-12-21 12:33:03 -06:00
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
2009-01-20 19:59:43 -06:00
#include "SkillDiscovery.h"
2009-03-10 15:28:51 -06:00
#include "Formulas.h"
2009-03-18 21:39:09 -06:00
#include "Vehicle.h"
2010-01-19 11:36:05 +01:00
#include "ScriptMgr.h"
2010-10-27 21:01:47 +02:00
#include "GameObjectAI.h"
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pEffect SpellEffects [ TOTAL_SPELL_EFFECTS ] =
{
& Spell :: EffectNULL , // 0
& Spell :: EffectInstaKill , // 1 SPELL_EFFECT_INSTAKILL
& Spell :: EffectSchoolDMG , // 2 SPELL_EFFECT_SCHOOL_DAMAGE
& Spell :: EffectDummy , // 3 SPELL_EFFECT_DUMMY
& Spell :: EffectUnused , // 4 SPELL_EFFECT_PORTAL_TELEPORT unused
& Spell :: EffectTeleportUnits , // 5 SPELL_EFFECT_TELEPORT_UNITS
& Spell :: EffectApplyAura , // 6 SPELL_EFFECT_APPLY_AURA
& Spell :: EffectEnvirinmentalDMG , // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE
& Spell :: EffectPowerDrain , // 8 SPELL_EFFECT_POWER_DRAIN
& Spell :: EffectHealthLeech , // 9 SPELL_EFFECT_HEALTH_LEECH
& Spell :: EffectHeal , // 10 SPELL_EFFECT_HEAL
2010-04-18 23:20:07 +02:00
& Spell :: EffectBind , // 11 SPELL_EFFECT_BIND
2008-10-11 14:16:25 -05:00
& Spell :: EffectNULL , // 12 SPELL_EFFECT_PORTAL
& Spell :: EffectUnused , // 13 SPELL_EFFECT_RITUAL_BASE unused
& Spell :: EffectUnused , // 14 SPELL_EFFECT_RITUAL_SPECIALIZE unused
& Spell :: EffectUnused , // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL unused
& Spell :: EffectQuestComplete , // 16 SPELL_EFFECT_QUEST_COMPLETE
& Spell :: EffectWeaponDmg , // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
& Spell :: EffectResurrect , // 18 SPELL_EFFECT_RESURRECT
& Spell :: EffectAddExtraAttacks , // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS
& Spell :: EffectUnused , // 20 SPELL_EFFECT_DODGE one spell: Dodge
& Spell :: EffectUnused , // 21 SPELL_EFFECT_EVADE one spell: Evade (DND)
& Spell :: EffectParry , // 22 SPELL_EFFECT_PARRY
& Spell :: EffectBlock , // 23 SPELL_EFFECT_BLOCK one spell: Block
& Spell :: EffectCreateItem , // 24 SPELL_EFFECT_CREATE_ITEM
& Spell :: EffectUnused , // 25 SPELL_EFFECT_WEAPON
& Spell :: EffectUnused , // 26 SPELL_EFFECT_DEFENSE one spell: Defense
& Spell :: EffectPersistentAA , // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA
& Spell :: EffectSummonType , // 28 SPELL_EFFECT_SUMMON
2010-07-21 02:06:51 +02:00
& Spell :: EffectLeap , // 29 SPELL_EFFECT_LEAP
2008-10-11 14:16:25 -05:00
& Spell :: EffectEnergize , // 30 SPELL_EFFECT_ENERGIZE
& Spell :: EffectWeaponDmg , // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
& Spell :: EffectTriggerMissileSpell , // 32 SPELL_EFFECT_TRIGGER_MISSILE
& Spell :: EffectOpenLock , // 33 SPELL_EFFECT_OPEN_LOCK
& Spell :: EffectSummonChangeItem , // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM
& Spell :: EffectApplyAreaAura , // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY
& Spell :: EffectLearnSpell , // 36 SPELL_EFFECT_LEARN_SPELL
& Spell :: EffectUnused , // 37 SPELL_EFFECT_SPELL_DEFENSE one spell: SPELLDEFENSE (DND)
& Spell :: EffectDispel , // 38 SPELL_EFFECT_DISPEL
& Spell :: EffectUnused , // 39 SPELL_EFFECT_LANGUAGE
& Spell :: EffectDualWield , // 40 SPELL_EFFECT_DUAL_WIELD
2009-04-11 22:41:15 -05:00
& Spell :: EffectJump , // 41 SPELL_EFFECT_JUMP
2010-07-19 21:24:09 +02:00
& Spell :: EffectJumpDest , // 42 SPELL_EFFECT_JUMP_DEST
2008-10-11 14:16:25 -05:00
& Spell :: EffectTeleUnitsFaceCaster , // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
& Spell :: EffectLearnSkill , // 44 SPELL_EFFECT_SKILL_STEP
& Spell :: EffectAddHonor , // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related
2010-07-19 22:52:21 +02:00
& Spell :: EffectUnused , // 46 SPELL_EFFECT_SPAWN clientside, unit appears as if it was just spawned
2008-10-11 14:16:25 -05:00
& Spell :: EffectTradeSkill , // 47 SPELL_EFFECT_TRADE_SKILL
& Spell :: EffectUnused , // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth
& Spell :: EffectUnused , // 49 SPELL_EFFECT_DETECT one spell: Detect
& Spell :: EffectTransmitted , // 50 SPELL_EFFECT_TRANS_DOOR
& Spell :: EffectUnused , // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused
& Spell :: EffectUnused , // 52 SPELL_EFFECT_GUARANTEE_HIT one spell: zzOLDCritical Shot
& Spell :: EffectEnchantItemPerm , // 53 SPELL_EFFECT_ENCHANT_ITEM
& Spell :: EffectEnchantItemTmp , // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
& Spell :: EffectTameCreature , // 55 SPELL_EFFECT_TAMECREATURE
& Spell :: EffectSummonPet , // 56 SPELL_EFFECT_SUMMON_PET
& Spell :: EffectLearnPetSpell , // 57 SPELL_EFFECT_LEARN_PET_SPELL
& Spell :: EffectWeaponDmg , // 58 SPELL_EFFECT_WEAPON_DAMAGE
2009-06-23 14:44:16 +02:00
& Spell :: EffectCreateRandomItem , // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM create item base at spell specific loot
2008-10-11 14:16:25 -05:00
& Spell :: EffectProficiency , // 60 SPELL_EFFECT_PROFICIENCY
& Spell :: EffectSendEvent , // 61 SPELL_EFFECT_SEND_EVENT
& Spell :: EffectPowerBurn , // 62 SPELL_EFFECT_POWER_BURN
& Spell :: EffectThreat , // 63 SPELL_EFFECT_THREAT
& Spell :: EffectTriggerSpell , // 64 SPELL_EFFECT_TRIGGER_SPELL
2008-12-24 09:58:26 -06:00
& Spell :: EffectApplyAreaAura , // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
2009-12-26 18:25:49 +01:00
& Spell :: EffectRechargeManaGem , // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
2008-10-11 14:16:25 -05:00
& Spell :: EffectHealMaxHealth , // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
& Spell :: EffectInterruptCast , // 68 SPELL_EFFECT_INTERRUPT_CAST
& Spell :: EffectDistract , // 69 SPELL_EFFECT_DISTRACT
& Spell :: EffectPull , // 70 SPELL_EFFECT_PULL one spell: Distract Move
& Spell :: EffectPickPocket , // 71 SPELL_EFFECT_PICKPOCKET
& Spell :: EffectAddFarsight , // 72 SPELL_EFFECT_ADD_FARSIGHT
2010-12-22 20:14:30 +02:00
& Spell :: EffectUntrainTalents , // 73 SPELL_EFFECT_UNTRAIN_TALENTS
2008-12-24 09:58:26 -06:00
& Spell :: EffectApplyGlyph , // 74 SPELL_EFFECT_APPLY_GLYPH
2008-10-11 14:16:25 -05:00
& Spell :: EffectHealMechanical , // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
& Spell :: EffectSummonObjectWild , // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
& Spell :: EffectScriptEffect , // 77 SPELL_EFFECT_SCRIPT_EFFECT
& Spell :: EffectUnused , // 78 SPELL_EFFECT_ATTACK
& Spell :: EffectSanctuary , // 79 SPELL_EFFECT_SANCTUARY
& Spell :: EffectAddComboPoints , // 80 SPELL_EFFECT_ADD_COMBO_POINTS
& Spell :: EffectUnused , // 81 SPELL_EFFECT_CREATE_HOUSE one spell: Create House (TEST)
& Spell :: EffectNULL , // 82 SPELL_EFFECT_BIND_SIGHT
& Spell :: EffectDuel , // 83 SPELL_EFFECT_DUEL
& Spell :: EffectStuck , // 84 SPELL_EFFECT_STUCK
& Spell :: EffectSummonPlayer , // 85 SPELL_EFFECT_SUMMON_PLAYER
& Spell :: EffectActivateObject , // 86 SPELL_EFFECT_ACTIVATE_OBJECT
2009-05-21 10:01:03 -05:00
& Spell :: EffectWMODamage , // 87 SPELL_EFFECT_WMO_DAMAGE
& Spell :: EffectWMORepair , // 88 SPELL_EFFECT_WMO_REPAIR
2010-12-01 20:59:05 +02:00
& Spell :: EffectWMOChange , // 89 SPELL_EFFECT_WMO_CHANGE // 0 intact // 1 damaged // 2 destroyed // 3 rebuilding
2009-09-11 15:38:31 -07:00
& Spell :: EffectKillCreditPersonal , // 90 SPELL_EFFECT_KILL_CREDIT Kill credit but only for single person
2008-10-11 14:16:25 -05:00
& Spell :: EffectUnused , // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
& Spell :: EffectEnchantHeldItem , // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
2010-01-13 10:27:44 +01:00
& Spell :: EffectForceDeselect , // 93 SPELL_EFFECT_FORCE_DESELECT
2008-10-11 14:16:25 -05:00
& Spell :: EffectSelfResurrect , // 94 SPELL_EFFECT_SELF_RESURRECT
& Spell :: EffectSkinning , // 95 SPELL_EFFECT_SKINNING
2009-05-04 12:11:54 -05:00
& Spell :: EffectCharge , // 96 SPELL_EFFECT_CHARGE
2009-12-17 12:23:01 +01:00
& Spell :: EffectCastButtons , // 97 SPELL_EFFECT_CAST_BUTTON (totem bar since 3.2.2a)
2008-10-11 14:16:25 -05:00
& Spell :: EffectKnockBack , // 98 SPELL_EFFECT_KNOCK_BACK
& Spell :: EffectDisEnchant , // 99 SPELL_EFFECT_DISENCHANT
& Spell :: EffectInebriate , //100 SPELL_EFFECT_INEBRIATE
& Spell :: EffectFeedPet , //101 SPELL_EFFECT_FEED_PET
& Spell :: EffectDismissPet , //102 SPELL_EFFECT_DISMISS_PET
& Spell :: EffectReputation , //103 SPELL_EFFECT_REPUTATION
& Spell :: EffectSummonObject , //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1
& Spell :: EffectSummonObject , //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2
& Spell :: EffectSummonObject , //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3
& Spell :: EffectSummonObject , //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4
& Spell :: EffectDispelMechanic , //108 SPELL_EFFECT_DISPEL_MECHANIC
& Spell :: EffectSummonDeadPet , //109 SPELL_EFFECT_SUMMON_DEAD_PET
& Spell :: EffectDestroyAllTotems , //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS
& Spell :: EffectDurabilityDamage , //111 SPELL_EFFECT_DURABILITY_DAMAGE
2009-01-06 13:45:49 -06:00
& Spell :: EffectUnused , //112 SPELL_EFFECT_112
2008-10-11 14:16:25 -05:00
& Spell :: EffectResurrectNew , //113 SPELL_EFFECT_RESURRECT_NEW
& Spell :: EffectTaunt , //114 SPELL_EFFECT_ATTACK_ME
& Spell :: EffectDurabilityDamagePCT , //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT
& Spell :: EffectSkinPlayerCorpse , //116 SPELL_EFFECT_SKIN_PLAYER_CORPSE one spell: Remove Insignia, bg usage, required special corpse flags...
& Spell :: EffectSpiritHeal , //117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal
& Spell :: EffectSkill , //118 SPELL_EFFECT_SKILL professions and more
& Spell :: EffectApplyAreaAura , //119 SPELL_EFFECT_APPLY_AREA_AURA_PET
& Spell :: EffectUnused , //120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test
& Spell :: EffectWeaponDmg , //121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG
& Spell :: EffectUnused , //122 SPELL_EFFECT_122 unused
& Spell :: EffectSendTaxi , //123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id)
2010-08-09 02:31:42 +02:00
& Spell :: EffectPullTowards , //124 SPELL_EFFECT_PULL_TOWARDS
2008-10-11 14:16:25 -05:00
& Spell :: EffectModifyThreatPercent , //125 SPELL_EFFECT_MODIFY_THREAT_PERCENT
& Spell :: EffectStealBeneficialBuff , //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect?
& Spell :: EffectProspecting , //127 SPELL_EFFECT_PROSPECTING Prospecting spell
& Spell :: EffectApplyAreaAura , //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
& Spell :: EffectApplyAreaAura , //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
2008-12-17 20:07:25 -06:00
& Spell :: EffectRedirectThreat , //130 SPELL_EFFECT_REDIRECT_THREAT
2011-03-07 21:13:18 +01:00
& Spell :: EffectPlayerNotification , //131 SPELL_EFFECT_PLAYER_NOTIFICATION sound id in misc value (SoundEntries.dbc)
2009-07-30 10:18:05 +08:00
& Spell :: EffectPlayMusic , //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
2008-10-11 14:16:25 -05:00
& Spell :: EffectUnlearnSpecialization , //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
& Spell :: EffectKillCredit , //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
& Spell :: EffectNULL , //135 SPELL_EFFECT_CALL_PET
& Spell :: EffectHealPct , //136 SPELL_EFFECT_HEAL_PCT
2009-06-08 21:19:34 +02:00
& Spell :: EffectEnergizePct , //137 SPELL_EFFECT_ENERGIZE_PCT
2010-07-19 21:24:09 +02:00
& Spell :: EffectLeapBack , //138 SPELL_EFFECT_LEAP_BACK Leap back
2010-07-04 19:16:40 +02:00
& Spell :: EffectQuestClear , //139 SPELL_EFFECT_CLEAR_QUEST Reset quest status (miscValue - quest ID)
2008-10-11 14:16:25 -05:00
& Spell :: EffectForceCast , //140 SPELL_EFFECT_FORCE_CAST
2010-07-19 22:52:21 +02:00
& Spell :: EffectForceCastWithValue , //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE
2008-10-11 14:16:25 -05:00
& Spell :: EffectTriggerSpellWithValue , //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
& Spell :: EffectApplyAreaAura , //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
2010-07-20 04:29:17 +02:00
& Spell :: EffectKnockBack , //144 SPELL_EFFECT_KNOCK_BACK_DEST
2010-08-09 02:31:42 +02:00
& Spell :: EffectPullTowards , //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect
2008-12-24 09:58:26 -06:00
& Spell :: EffectActivateRune , //146 SPELL_EFFECT_ACTIVATE_RUNE
2008-10-11 14:16:25 -05:00
& Spell :: EffectQuestFail , //147 SPELL_EFFECT_QUEST_FAIL quest fail
2010-07-20 22:55:28 +02:00
& Spell :: EffectUnused , //148 SPELL_EFFECT_148 1 spell - 43509
2010-07-19 19:22:05 +02:00
& Spell :: EffectChargeDest , //149 SPELL_EFFECT_CHARGE_DEST
2010-07-20 16:11:49 +02:00
& Spell :: EffectQuestStart , //150 SPELL_EFFECT_QUEST_START
2008-10-11 14:16:25 -05:00
& Spell :: EffectTriggerRitualOfSummoning , //151 SPELL_EFFECT_TRIGGER_SPELL_2
& Spell :: EffectNULL , //152 SPELL_EFFECT_152 summon Refer-a-Friend
2010-07-20 22:55:28 +02:00
& Spell :: EffectCreateTamedPet , //153 SPELL_EFFECT_CREATE_TAMED_PET misc value is creature entry
2010-08-08 19:45:53 +02:00
& Spell :: EffectDiscoverTaxi , //154 SPELL_EFFECT_DISCOVER_TAXI
2008-12-24 09:58:26 -06:00
& Spell :: EffectTitanGrip , //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
2009-02-03 19:12:17 -06:00
& Spell :: EffectEnchantItemPrismatic , //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
2009-06-23 14:44:16 +02:00
& Spell :: EffectCreateItem2 , //157 SPELL_EFFECT_CREATE_ITEM_2 create item or create item template and replace by some randon spell loot item
2009-01-22 22:44:27 -06:00
& Spell :: EffectMilling , //158 SPELL_EFFECT_MILLING milling
2009-06-11 00:45:59 -05:00
& Spell :: EffectRenamePet , //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
2010-07-20 16:11:49 +02:00
& Spell :: EffectNULL , //160 SPELL_EFFECT_160 1 spell - 45534
2009-08-14 17:24:52 -07:00
& Spell :: EffectSpecCount , //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
& Spell :: EffectActivateSpec , //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
2010-07-20 16:11:49 +02:00
& Spell :: EffectNULL , //163 unused
2010-07-20 04:29:17 +02:00
& Spell :: EffectRemoveAura , //164 SPELL_EFFECT_REMOVE_AURA
2008-10-11 14:16:25 -05:00
};
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectNULL ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "WORLD: Spell Effect DUMMY" );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectUnused ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-02-05 00:31:28 +01:00
// NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectResurrectNew ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> IsInWorld ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
Player * pTarget = unitTarget -> ToPlayer ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pTarget -> isRessurectRequested ()) // already have one active request
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 health = damage ;
2010-08-27 19:36:27 +02:00
uint32 mana = m_spellInfo -> EffectMiscValue [ effIndex ];
ExecuteLogEffectResurrect ( effIndex , pTarget );
2008-10-11 14:16:25 -05:00
pTarget -> setResurrectRequestData ( m_caster -> GetGUID (), m_caster -> GetMapId (), m_caster -> GetPositionX (), m_caster -> GetPositionY (), m_caster -> GetPositionZ (), health , mana );
SendResurrectRequest ( pTarget );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectInstaKill ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
if ( ! unitTarget || ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Demonic Sacrifice
2010-02-15 18:23:39 +01:00
if ( m_spellInfo -> Id == 18788 && unitTarget -> GetTypeId () == TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
{
uint32 entry = unitTarget -> GetEntry ();
uint32 spellID ;
2009-10-15 11:50:11 -07:00
switch ( entry )
2008-10-11 14:16:25 -05:00
{
2010-02-15 18:23:39 +01:00
case 416 : spellID = 18789 ; break ; //imp
case 417 : spellID = 18792 ; break ; //fellhunter
case 1860 : spellID = 18790 ; break ; //void
case 1863 : spellID = 18791 ; break ; //succubus
case 17252 : spellID = 35701 ; break ; //fellguard
2008-10-11 14:16:25 -05:00
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "EffectInstaKill: Unhandled creature entry (%u) case." , entry );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , spellID , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( m_caster == unitTarget ) // prevent interrupt message
2008-10-11 14:16:25 -05:00
finish ();
2009-10-17 15:51:44 -07:00
2010-08-28 00:30:07 +02:00
WorldPacket data ( SMSG_SPELLINSTAKILLLOG , 8 + 8 + 4 );
data << uint64 ( m_caster -> GetGUID ());
data << uint64 ( unitTarget -> GetGUID ());
data << uint32 ( m_spellInfo -> Id );
m_caster -> SendMessageToSet ( & data , true );
m_caster -> DealDamage ( unitTarget , unitTarget -> GetHealth (), NULL , NODAMAGE , SPELL_SCHOOL_MASK_NORMAL , NULL , false );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnvirinmentalDMG ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
uint32 absorb = 0 ;
uint32 resist = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Note: this hack with damage replace required until GO casting not implemented
// environment damage spells already have around enemies targeting but this not help in case not existed GO casting support
// currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc
2010-08-27 19:36:27 +02:00
damage = SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , effIndex , m_caster );
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
m_caster -> CalcAbsorbResist ( m_caster , GetSpellSchoolMask ( m_spellInfo ), SPELL_DIRECT_DAMAGE , damage , & absorb , & resist , m_spellInfo );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_caster -> SendSpellNonMeleeDamageLog ( m_caster , m_spellInfo -> Id , damage , GetSpellSchoolMask ( m_spellInfo ), absorb , resist , false , 0 , false );
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> EnvironmentalDamage ( DAMAGE_FIRE , damage );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSchoolDMG ( SpellEffIndex /*effIndex*/ )
2008-12-25 17:39:46 -06:00
{
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: SpellDamageSchoolDmg ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
bool apply_direct_bonus = true ;
2009-10-17 15:51:44 -07:00
2009-10-15 11:50:11 -07:00
if ( unitTarget && unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
switch ( m_spellInfo -> SpellFamilyName )
2008-10-11 14:16:25 -05:00
{
case SPELLFAMILY_GENERIC :
{
2008-10-25 15:46:52 -05:00
// Meteor like spells (divided damage to targets)
2010-12-19 05:15:47 +01:00
if ( m_customAttr & SPELL_ATTR0_CU_SHARE_DAMAGE )
2008-10-11 14:16:25 -05:00
{
2008-10-25 15:46:52 -05:00
uint32 count = 0 ;
2009-10-17 16:20:24 -07:00
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2010-08-27 19:36:27 +02:00
if ( ihit -> effectMask & ( 1 << effIndex ))
2008-10-25 15:46:52 -05:00
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-25 15:46:52 -05:00
damage /= count ; // divide to all targets
}
2009-10-17 15:51:44 -07:00
2008-10-25 15:46:52 -05:00
switch ( m_spellInfo -> Id ) // better way to check unknown
{
2009-05-18 15:04:05 -05:00
// Positive/Negative Charge
2010-02-15 18:23:39 +01:00
case 28062 :
case 28085 :
case 39090 :
case 39093 :
2009-10-15 11:50:11 -07:00
if ( ! m_triggeredByAuraSpell )
2009-05-20 11:44:38 -05:00
break ;
2009-10-15 11:50:11 -07:00
if ( unitTarget == m_caster )
2009-05-18 15:04:05 -05:00
{
2009-05-20 11:44:38 -05:00
uint8 count = 0 ;
2009-10-17 16:20:24 -07:00
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2010-04-07 19:14:10 +02:00
if ( ihit -> targetGUID != m_caster -> GetGUID ())
2010-07-30 15:51:07 +02:00
if ( Player * target = ObjectAccessor :: GetPlayer ( * m_caster , ihit -> targetGUID ))
2010-04-07 19:14:10 +02:00
if ( target -> HasAura ( m_triggeredByAuraSpell -> Id ))
2009-05-20 11:44:38 -05:00
++ count ;
2009-10-15 11:50:11 -07:00
if ( count )
2009-05-20 11:44:38 -05:00
{
2010-04-19 09:26:37 +02:00
uint32 spellId = 0 ;
2009-10-15 11:50:11 -07:00
switch ( m_spellInfo -> Id )
2009-05-20 11:44:38 -05:00
{
2010-02-15 18:23:39 +01:00
case 28062 : spellId = 29659 ; break ;
case 28085 : spellId = 29660 ; break ;
case 39090 : spellId = 39089 ; break ;
case 39093 : spellId = 39092 ; break ;
2009-05-20 11:44:38 -05:00
}
2010-01-10 01:23:15 +01:00
m_caster -> SetAuraStack ( spellId , m_caster , count );
2009-05-20 11:44:38 -05:00
}
2009-05-18 15:04:05 -05:00
}
2009-10-17 15:51:44 -07:00
2009-10-15 11:50:11 -07:00
if ( unitTarget -> HasAura ( m_triggeredByAuraSpell -> Id ))
2009-05-20 11:44:38 -05:00
damage = 0 ;
break ;
// Consumption
2010-02-15 18:23:39 +01:00
case 28865 :
2009-12-17 12:23:01 +01:00
damage = ((( InstanceMap * ) m_caster -> GetMap ()) -> GetDifficulty () == REGULAR_DIFFICULTY ? 2750 : 4250 );
2009-05-18 15:04:05 -05:00
break ;
2008-10-11 14:16:25 -05:00
// percent from health with min
2010-02-15 18:23:39 +01:00
case 25599 : // Thundercrash
2008-10-11 14:16:25 -05:00
{
damage = unitTarget -> GetHealth () / 2 ;
2010-04-07 19:14:10 +02:00
if ( damage < 200 )
2008-10-11 14:16:25 -05:00
damage = 200 ;
break ;
}
2008-11-24 15:15:09 -06:00
// arcane charge. must only affect demons (also undead?)
2010-02-15 18:23:39 +01:00
case 45072 :
2008-10-19 14:47:43 -05:00
{
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetCreatureType () != CREATURE_TYPE_DEMON
2008-11-24 15:15:09 -06:00
&& unitTarget -> GetCreatureType () != CREATURE_TYPE_UNDEAD )
2008-10-19 14:47:43 -05:00
return ;
break ;
}
2010-06-19 23:51:33 +02:00
case 33671 : // gruul's shatter
2010-06-20 01:34:11 +02:00
case 50811 : // krystallus shatter ( Normal )
case 61547 : // krystallus shatter ( Heroic )
2008-11-21 19:45:49 -06:00
{
// don't damage self and only players
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetGUID () == m_caster -> GetGUID () || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-11-21 19:45:49 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-14 15:56:04 +01:00
float radius = GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ 0 ]));
2009-10-15 11:50:11 -07:00
if ( ! radius ) return ;
2008-11-21 19:45:49 -06:00
float distance = m_caster -> GetDistance2d ( unitTarget );
2010-08-25 03:21:22 +03:00
damage = ( distance > radius ) ? 0 : int32 ( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 0 ) * (( radius - distance ) / radius ));
2009-04-30 19:35:37 -05:00
break ;
}
2010-02-24 21:38:51 +01:00
// TODO: add spell specific target requirement hook for spells
// Shadowbolts only affects targets with Shadow Mark (Gothik)
case 27831 :
case 55638 :
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> HasAura ( 27825 ))
2010-02-24 21:38:51 +01:00
return ;
break ;
2009-04-30 19:35:37 -05:00
// Cataclysmic Bolt
2010-02-15 18:23:39 +01:00
case 38441 :
2009-10-09 20:48:55 -07:00
{
2010-08-26 01:20:57 +06:00
damage = unitTarget -> CountPctFromMaxHealth ( 50 );
2009-04-30 19:35:37 -05:00
break ;
2009-10-09 20:48:55 -07:00
}
// Tympanic Tantrum
2010-02-15 18:23:39 +01:00
case 62775 :
2009-10-09 20:48:55 -07:00
{
2010-08-26 01:20:57 +06:00
damage = unitTarget -> CountPctFromMaxHealth ( 10 );
2009-10-09 20:48:55 -07:00
break ;
}
2009-12-25 13:10:54 -06:00
// Gargoyle Strike
2010-02-15 18:23:39 +01:00
case 51963 :
2009-12-26 14:46:19 -03:00
{
2009-12-17 09:10:04 +01:00
// about +4 base spell dmg per level
damage = ( m_caster -> getLevel () - 60 ) * 4 + 60 ;
break ;
}
2010-08-08 19:45:53 +02:00
2010-06-20 01:37:58 +02:00
// Loken Pulsing Shockwave
case 59837 :
case 52942 :
{
// don't damage self and only players
if ( unitTarget -> GetGUID () == m_caster -> GetGUID () || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-08-08 19:45:53 +02:00
2010-06-20 01:37:58 +02:00
float radius = GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ 0 ]));
if ( ! radius )
return ;
float distance = m_caster -> GetDistance2d ( unitTarget );
2010-08-25 03:21:22 +03:00
damage = ( distance > radius ) ? 0 : int32 ( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 0 ) * distance );
2010-06-20 01:37:58 +02:00
break ;
}
2008-10-11 14:16:25 -05:00
}
break ;
}
case SPELLFAMILY_WARRIOR :
{
// Bloodthirst
2010-02-15 19:09:17 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x400 )
2010-12-11 20:37:38 +06:00
ApplyPctF ( damage , m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ));
2008-10-11 14:16:25 -05:00
// Shield Slam
2010-02-15 19:09:17 +01:00
else if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x200 && m_spellInfo -> Category == 1209 )
2010-12-11 20:37:38 +06:00
damage += int32 ( m_caster -> ApplyEffectModifiers ( m_spellInfo , effIndex , float ( m_caster -> GetShieldBlockValue ())));
2008-10-11 14:16:25 -05:00
// Victory Rush
2010-02-15 19:09:17 +01:00
else if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x100 )
2008-10-11 14:16:25 -05:00
{
2010-12-11 20:37:38 +06:00
ApplyPctF ( damage , m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ));
2008-10-11 14:16:25 -05:00
m_caster -> ModifyAuraState ( AURA_STATE_WARRIOR_VICTORY_RUSH , false );
}
2010-02-15 19:09:17 +01:00
// Shockwave
else if ( m_spellInfo -> Id == 46968 )
2009-05-06 18:33:19 +02:00
{
2010-04-11 11:43:23 +04:00
int32 pct = m_caster -> CalculateSpellDamage ( unitTarget , m_spellInfo , 2 );
2009-05-06 18:33:19 +02:00
if ( pct > 0 )
2010-12-11 20:37:38 +06:00
damage += int32 ( CalculatePctN ( m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ), pct ));
2009-05-06 18:33:19 +02:00
break ;
}
2008-10-11 14:16:25 -05:00
break ;
}
case SPELLFAMILY_WARLOCK :
{
// Incinerate Rank 1 & 2
2010-04-07 23:25:02 +02:00
if (( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x000040 ) && m_spellInfo -> SpellIconID == 2128 )
2008-10-11 14:16:25 -05:00
{
2009-07-24 09:59:33 +08:00
// Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
// Check aura state for speed but aura state set not only for Immolate spell
2010-04-07 19:14:10 +02:00
if ( unitTarget -> HasAuraState ( AURA_STATE_CONFLAGRATE ))
2009-07-24 09:59:33 +08:00
{
2010-01-10 01:23:15 +01:00
if ( unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_WARLOCK , 0x4 , 0 , 0 ))
2009-08-08 16:18:05 +02:00
damage += damage / 4 ;
2009-07-24 09:59:33 +08:00
}
2008-10-11 14:16:25 -05:00
}
2009-07-24 09:59:33 +08:00
// Conflagrate - consumes Immolate or Shadowflame
else if ( m_spellInfo -> TargetAuraState == AURA_STATE_CONFLAGRATE )
2008-12-25 17:39:46 -06:00
{
2009-07-24 10:06:11 +08:00
AuraEffect const * aura = NULL ; // found req. aura for damage calculation
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & mPeriodic = unitTarget -> GetAuraEffectsByType ( SPELL_AURA_PERIODIC_DAMAGE );
2009-10-17 16:20:24 -07:00
for ( Unit :: AuraEffectList :: const_iterator i = mPeriodic . begin (); i != mPeriodic . end (); ++ i )
2008-12-25 17:39:46 -06:00
{
2009-07-24 10:06:11 +08:00
// for caster applied auras only
if (( * i ) -> GetSpellProto () -> SpellFamilyName != SPELLFAMILY_WARLOCK ||
2009-10-15 11:50:11 -07:00
( * i ) -> GetCasterGUID () != m_caster -> GetGUID ())
2009-07-24 10:06:11 +08:00
continue ;
2009-10-17 15:51:44 -07:00
2009-07-24 10:06:11 +08:00
// Immolate
if (( * i ) -> GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x4 )
2008-12-25 17:39:46 -06:00
{
2009-07-24 10:06:11 +08:00
aura = * i ; // it selected always if exist
2008-12-25 17:39:46 -06:00
break ;
}
2009-10-17 15:51:44 -07:00
2009-07-24 10:06:11 +08:00
// Shadowflame
if (( * i ) -> GetSpellProto () -> SpellFamilyFlags [ 2 ] & 0x00000002 )
aura = * i ; // remember but wait possible Immolate as primary priority
}
2009-10-17 15:51:44 -07:00
2009-07-24 10:06:11 +08:00
// found Immolate or Shadowflame
if ( aura )
{
2010-12-11 20:37:38 +06:00
uint32 pdamage = uint32 ( std :: max ( aura -> GetAmount (), 0 ));
2010-01-10 01:23:15 +01:00
pdamage = m_caster -> SpellDamageBonus ( unitTarget , aura -> GetSpellProto (), pdamage , DOT , aura -> GetBase () -> GetStackAmount ());
2010-08-27 19:36:27 +02:00
uint32 pct_dir = m_caster -> CalculateSpellDamage ( unitTarget , m_spellInfo , ( effIndex + 1 ));
2010-09-02 06:02:51 +03:00
uint8 baseTotalTicks = uint8 ( m_caster -> CalcSpellDuration ( aura -> GetSpellProto ()) / aura -> GetSpellProto () -> EffectAmplitude [ 0 ]);
2010-12-11 20:37:38 +06:00
damage += int32 ( CalculatePctU ( pdamage * baseTotalTicks , pct_dir ));
2010-04-23 21:24:32 +02:00
2010-08-27 19:36:27 +02:00
uint32 pct_dot = m_caster -> CalculateSpellDamage ( unitTarget , m_spellInfo , ( effIndex + 2 )) / 3 ;
2010-12-11 20:37:38 +06:00
m_spellValue -> EffectBasePoints [ 1 ] = SpellMgr :: CalculateSpellEffectBaseAmount ( int32 ( CalculatePctU ( pdamage * baseTotalTicks , pct_dot )), m_spellInfo , 1 );
2010-04-23 21:24:32 +02:00
2009-07-24 10:06:11 +08:00
apply_direct_bonus = false ;
// Glyph of Conflagrate
if ( ! m_caster -> HasAura ( 56235 ))
unitTarget -> RemoveAurasDueToSpell ( aura -> GetId (), m_caster -> GetGUID ());
2009-10-17 15:51:44 -07:00
2009-07-24 10:06:11 +08:00
break ;
2008-12-25 17:39:46 -06:00
}
}
2009-06-12 13:01:42 +02:00
// Shadow Bite
else if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x400000 )
{
2010-03-11 20:51:31 +01:00
if ( m_caster -> GetTypeId () == TYPEID_UNIT && m_caster -> ToCreature () -> isPet ())
2010-12-20 00:35:11 +01:00
{
if ( Player * owner = m_caster -> GetOwner () -> ToPlayer ())
{
if ( AuraEffect * aurEff = owner -> GetAuraEffect ( SPELL_AURA_ADD_FLAT_MODIFIER , SPELLFAMILY_WARLOCK , 214 , 0 ))
{
int32 bp0 = aurEff -> GetId () == 54037 ? 4 : 8 ;
m_caster -> CastCustomSpell ( m_caster , 54425 , & bp0 , NULL , NULL , true );
}
}
}
2009-06-12 13:01:42 +02:00
}
2008-10-11 14:16:25 -05:00
break ;
}
2008-12-29 17:27:50 -06:00
case SPELLFAMILY_PRIEST :
{
// Shadow Word: Death - deals damage equal to damage done to caster
2010-04-07 22:59:46 +02:00
if (( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x2 ))
2009-10-17 18:16:28 +02:00
{
2010-01-04 15:53:19 +02:00
int32 back_damage = m_caster -> SpellDamageBonus ( unitTarget , m_spellInfo , ( uint32 ) damage , SPELL_DIRECT_DAMAGE );
// Pain and Suffering reduces damage
2010-01-10 01:23:15 +01:00
if ( AuraEffect * aurEff = m_caster -> GetDummyAuraEffect ( SPELLFAMILY_PRIEST , 2874 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( back_damage , - aurEff -> GetAmount ());
2010-01-04 15:53:19 +02:00
2010-08-26 15:54:56 +06:00
if ( back_damage < int32 ( unitTarget -> GetHealth ()))
2010-02-15 18:23:39 +01:00
m_caster -> CastCustomSpell ( m_caster , 32409 , & back_damage , 0 , 0 , true );
2009-10-17 18:16:28 +02:00
}
2009-12-17 12:23:01 +01:00
// Improved Mind Blast (Mind Blast in shadow form bonus)
2010-12-09 17:03:42 +06:00
else if ( m_caster -> GetShapeshiftForm () == FORM_SHADOW && ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00002000 ))
2009-12-17 12:23:01 +01:00
{
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & ImprMindBlast = m_caster -> GetAuraEffectsByType ( SPELL_AURA_ADD_FLAT_MODIFIER );
2010-04-07 19:12:44 +02:00
for ( Unit :: AuraEffectList :: const_iterator i = ImprMindBlast . begin (); i != ImprMindBlast . end (); ++ i )
2009-12-17 12:23:01 +01:00
{
if (( * i ) -> GetSpellProto () -> SpellFamilyName == SPELLFAMILY_PRIEST &&
(( * i ) -> GetSpellProto () -> SpellIconID == 95 ))
{
2010-07-14 16:57:13 +02:00
int chance = SpellMgr :: CalculateSpellEffectAmount (( * i ) -> GetSpellProto (), 1 , m_caster );
2009-12-17 12:23:01 +01:00
if ( roll_chance_i ( chance ))
// Mind Trauma
2010-02-15 18:23:39 +01:00
m_caster -> CastSpell ( unitTarget , 48301 , true , 0 );
2009-12-17 12:23:01 +01:00
break ;
}
}
}
2008-12-29 17:27:50 -06:00
break ;
}
2008-10-11 14:16:25 -05:00
case SPELLFAMILY_DRUID :
{
// Ferocious Bite
2010-04-07 23:25:02 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER && ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x000800000 ) && m_spellInfo -> SpellVisual [ 0 ] == 6587 )
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
// converts each extra point of energy into ($f1+$AP/410) additional damage
float ap = m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK );
2010-08-27 19:36:27 +02:00
float multiple = ap / 410 + m_spellInfo -> EffectDamageMultiplier [ effIndex ];
2009-06-24 15:58:44 +02:00
int32 energy = - ( m_caster -> ModifyPower ( POWER_ENERGY , - 30 ));
damage += int32 ( energy * multiple );
2010-12-11 20:37:38 +06:00
damage += int32 ( CalculatePctN ( m_caster -> ToPlayer () -> GetComboPoints () * ap , 7 ));
2008-10-11 14:16:25 -05:00
}
2009-08-28 14:03:18 +02:00
// Wrath
else if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00000001 )
{
// Improved Insect Swarm
2010-01-10 01:23:15 +01:00
if ( AuraEffect const * aurEff = m_caster -> GetDummyAuraEffect ( SPELLFAMILY_DRUID , 1771 , 0 ))
if ( unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_DRUID , 0x00200000 , 0 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( damage , aurEff -> GetAmount ());
2009-08-28 14:03:18 +02:00
}
2008-10-11 14:16:25 -05:00
break ;
}
case SPELLFAMILY_ROGUE :
{
// Envenom
2009-10-18 18:38:46 -07:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER && ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x8 ))
2008-10-11 14:16:25 -05:00
{
// consume from stack dozes not more that have combo-points
2010-03-07 15:20:19 +01:00
if ( uint32 combo = m_caster -> ToPlayer () -> GetComboPoints ())
2008-10-11 14:16:25 -05:00
{
2009-01-09 16:06:17 -06:00
// Lookup for Deadly poison (only attacker applied)
2010-01-10 01:23:15 +01:00
if ( AuraEffect const * aurEff = unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_ROGUE , 0x10000 , 0 , 0 , m_caster -> GetGUID ()))
2009-01-09 16:06:17 -06:00
{
2009-08-08 16:18:05 +02:00
// count consumed deadly poison doses at target
2009-10-31 17:09:38 -07:00
bool needConsume = true ;
2009-08-08 16:18:05 +02:00
uint32 spellId = aurEff -> GetId ();
2010-01-10 01:23:15 +01:00
uint32 doses = aurEff -> GetBase () -> GetStackAmount ();
2009-01-09 16:06:17 -06:00
if ( doses > combo )
doses = combo ;
2009-10-31 17:09:38 -07:00
// Master Poisoner
2010-03-07 15:20:19 +01:00
Unit :: AuraEffectList const & auraList = m_caster -> ToPlayer () -> GetAuraEffectsByType ( SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK );
2009-10-31 17:09:38 -07:00
for ( Unit :: AuraEffectList :: const_iterator iter = auraList . begin (); iter != auraList . end (); ++ iter )
{
if (( * iter ) -> GetSpellProto () -> SpellFamilyName == SPELLFAMILY_ROGUE && ( * iter ) -> GetSpellProto () -> SpellIconID == 1960 )
{
2010-07-14 16:57:13 +02:00
uint32 chance = SpellMgr :: CalculateSpellEffectAmount (( * iter ) -> GetSpellProto (), 2 , m_caster );
2009-10-31 17:09:38 -07:00
if ( chance && roll_chance_i ( chance ))
needConsume = false ;
break ;
}
}
if ( needConsume )
for ( uint32 i = 0 ; i < doses ; ++ i )
unitTarget -> RemoveAuraFromStack ( spellId );
2009-01-09 16:06:17 -06:00
damage *= doses ;
2009-12-19 20:00:01 -06:00
damage += int32 ((( Player * ) m_caster ) -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 0.09f * doses );
2008-10-11 14:16:25 -05:00
}
// Eviscerate and Envenom Bonus Damage (item set effect)
2010-02-15 18:23:39 +01:00
if ( m_caster -> HasAura ( 37169 ))
2008-10-11 14:16:25 -05:00
damage += (( Player * ) m_caster ) -> GetComboPoints () * 40 ;
}
}
// Eviscerate
2009-10-18 18:38:46 -07:00
else if (( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00020000 ) && m_caster -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
if ( uint32 combo = (( Player * ) m_caster ) -> GetComboPoints ())
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
float ap = m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK );
damage += irand ( int32 ( ap * combo * 0.03f ), int32 ( ap * combo * 0.07f ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Eviscerate and Envenom Bonus Damage (item set effect)
2010-02-15 18:23:39 +01:00
if ( m_caster -> HasAura ( 37169 ))
2008-10-11 14:16:25 -05:00
damage += combo * 40 ;
}
}
break ;
}
case SPELLFAMILY_HUNTER :
{
2009-08-02 10:10:13 +08:00
//Gore
if ( m_spellInfo -> SpellIconID == 1578 )
{
2010-02-15 18:23:39 +01:00
if ( m_caster -> HasAura ( 57627 )) // Charge 6 sec post-affect
2009-08-02 10:10:13 +08:00
damage *= 2 ;
}
2008-10-11 14:16:25 -05:00
// Steady Shot
2009-10-15 11:50:11 -07:00
else if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x1 )
2008-10-11 14:16:25 -05:00
{
2008-12-25 17:39:46 -06:00
bool found = false ;
// check dazed affect
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & decSpeedList = unitTarget -> GetAuraEffectsByType ( SPELL_AURA_MOD_DECREASE_SPEED );
2009-10-15 11:50:11 -07:00
for ( Unit :: AuraEffectList :: const_iterator iter = decSpeedList . begin (); iter != decSpeedList . end (); ++ iter )
2008-12-25 17:39:46 -06:00
{
2009-10-15 11:50:11 -07:00
if (( * iter ) -> GetSpellProto () -> SpellIconID == 15 && ( * iter ) -> GetSpellProto () -> Dispel == 0 )
2008-12-25 17:39:46 -06:00
{
found = true ;
break ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-26 17:56:35 +02:00
// TODO: should this be put on taken but not done?
2010-04-07 19:14:10 +02:00
if ( found )
2010-08-25 03:21:22 +03:00
damage += SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 1 );
2009-10-17 16:20:24 -07:00
2009-08-21 17:15:35 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
{
2009-08-21 17:23:09 +02:00
// Add Ammo and Weapon damage plus RAP * 0.1
2010-03-07 15:20:19 +01:00
Item * item = m_caster -> ToPlayer () -> GetWeaponForAttack ( RANGED_ATTACK );
2009-10-15 11:50:11 -07:00
if ( item )
2009-08-21 17:15:35 +02:00
{
2011-04-28 22:42:33 +02:00
float dmg_min = item -> GetTemplate () -> Damage -> DamageMin ;
float dmg_max = item -> GetTemplate () -> Damage -> DamageMax ;
2009-10-15 11:50:11 -07:00
if ( dmg_max == 0.0f && dmg_min > dmg_max )
2009-11-17 16:59:58 -08:00
damage += int32 ( dmg_min );
2009-08-26 17:56:35 +02:00
else
2009-11-17 16:59:58 -08:00
damage += irand ( int32 ( dmg_min ), int32 ( dmg_max ));
2011-04-28 22:42:33 +02:00
damage += int32 ( m_caster -> ToPlayer () -> GetAmmoDPS () * item -> GetTemplate () -> Delay * 0.001f );
2009-08-21 17:15:35 +02:00
}
}
2008-10-11 14:16:25 -05:00
}
break ;
}
case SPELLFAMILY_PALADIN :
{
2009-02-01 16:21:40 -06:00
// Hammer of the Righteous
2009-12-25 16:01:19 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x00040000 )
2009-02-01 16:21:40 -06:00
{
// Add main hand dps * effect[2] amount
2009-05-14 15:38:20 -05:00
float average = ( m_caster -> GetFloatValue ( UNIT_FIELD_MINDAMAGE ) + m_caster -> GetFloatValue ( UNIT_FIELD_MAXDAMAGE )) / 2 ;
2010-11-09 11:15:00 +01:00
int32 count = m_caster -> CalculateSpellDamage ( unitTarget , m_spellInfo , EFFECT_2 );
2010-07-12 00:30:17 +02:00
damage += count * int32 ( average * IN_MILLISECONDS ) / m_caster -> GetAttackTime ( BASE_ATTACK );
2010-11-09 11:15:00 +01:00
break ;
2009-02-01 16:21:40 -06:00
}
2009-03-09 18:15:27 -06:00
// Shield of Righteousness
2010-11-09 11:15:00 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_1 ] & 0x100000 )
2009-03-09 18:15:27 -06:00
{
2010-12-11 20:37:38 +06:00
damage += CalculatePctN ( m_caster -> GetShieldBlockValue (), SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , EFFECT_1 ));
2010-11-09 11:15:00 +01:00
break ;
2009-03-09 18:15:27 -06:00
}
2008-10-11 14:16:25 -05:00
break ;
}
2009-07-06 00:51:50 +02:00
case SPELLFAMILY_DEATHKNIGHT :
{
// Blood Boil - bonus for diseased targets
2011-05-28 03:12:41 +07:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00040000 )
2009-07-06 00:51:50 +02:00
{
2011-05-28 03:12:41 +07:00
if ( unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_DEATHKNIGHT , 0 , 0 , 0x00000002 , m_caster -> GetGUID ()))
{
damage += m_damage / 2 ;
damage += int32 ( m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 0.035f );
}
2009-07-06 00:51:50 +02:00
}
break ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( m_originalCaster && damage > 0 && apply_direct_bonus )
2009-01-10 09:29:22 -06:00
damage = m_originalCaster -> SpellDamageBonus ( unitTarget , m_spellInfo , ( uint32 ) damage , SPELL_DIRECT_DAMAGE );
2009-10-17 15:51:44 -07:00
2009-01-10 09:29:22 -06:00
m_damage += damage ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDummy ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
if ( ! unitTarget && ! gameObjTarget && ! itemTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-31 11:09:37 -06:00
uint32 spell_id = 0 ;
int32 bp = 0 ;
2009-06-18 14:17:11 +02:00
bool triggered = true ;
SpellCastTargets targets ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// selection by spell family
2009-10-15 11:50:11 -07:00
switch ( m_spellInfo -> SpellFamilyName )
2008-10-11 14:16:25 -05:00
{
case SPELLFAMILY_GENERIC :
2008-11-28 11:38:28 -06:00
{
2009-10-15 11:50:11 -07:00
switch ( m_spellInfo -> Id )
2008-10-11 14:16:25 -05:00
{
2010-02-15 18:23:39 +01:00
case 31225 : // Shimmering Vessel (restore creature to life)
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
return ;
2010-03-07 18:30:53 +01:00
unitTarget -> ToCreature () -> setDeathState ( JUST_ALIVED );
2008-10-11 14:16:25 -05:00
return ;
}
2010-02-15 18:23:39 +01:00
case 12162 : // Deep wounds
case 12850 : // (now good common check for this spells)
case 12868 :
2008-10-11 14:16:25 -05:00
{
2009-10-15 11:50:11 -07:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
float damage ;
// DW should benefit of attack power, damage percent mods etc.
// TODO: check if using offhand damage is correct and if it should be divided by 2
if ( m_caster -> haveOffhandWeapon () && m_caster -> getAttackTimer ( BASE_ATTACK ) > m_caster -> getAttackTimer ( OFF_ATTACK ))
damage = ( m_caster -> GetFloatValue ( UNIT_FIELD_MINOFFHANDDAMAGE ) + m_caster -> GetFloatValue ( UNIT_FIELD_MAXOFFHANDDAMAGE )) / 2 ;
else
damage = ( m_caster -> GetFloatValue ( UNIT_FIELD_MINDAMAGE ) + m_caster -> GetFloatValue ( UNIT_FIELD_MAXDAMAGE )) / 2 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
switch ( m_spellInfo -> Id )
{
2010-02-15 18:23:39 +01:00
case 12162 : damage *= 0.16f ; break ; // Rank 1
case 12850 : damage *= 0.32f ; break ; // Rank 2
case 12868 : damage *= 0.48f ; break ; // Rank 3
2008-10-11 14:16:25 -05:00
default :
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Spell::EffectDummy: Spell %u not handled in DW" , m_spellInfo -> Id );
2008-10-11 14:16:25 -05:00
return ;
};
2009-10-17 15:51:44 -07:00
2009-06-23 14:18:20 +02:00
// get remaining damage of old Deep Wound aura
2011-05-19 00:25:53 +07:00
AuraEffect * deepWound = unitTarget -> GetAuraEffect ( 12721 , 0 , m_caster -> GetGUID ());
2009-10-15 11:50:11 -07:00
if ( deepWound )
2009-06-23 14:18:20 +02:00
{
2010-01-10 01:23:15 +01:00
int32 remainingTicks = deepWound -> GetBase () -> GetDuration () / deepWound -> GetAmplitude ();
2009-06-23 14:18:20 +02:00
damage += remainingTicks * deepWound -> GetAmount ();
}
2009-10-17 15:51:44 -07:00
2009-06-23 14:18:20 +02:00
// 1 tick/sec * 6 sec = 6 ticks
int32 deepWoundsDotBasePoints0 = int32 ( damage / 6 );
2008-10-11 14:16:25 -05:00
m_caster -> CastCustomSpell ( unitTarget , 12721 , & deepWoundsDotBasePoints0 , NULL , NULL , true , NULL );
return ;
}
2009-12-27 17:49:52 -06:00
case 13567 : // Dummy Trigger
{
// can be used for different aura triggering, so select by aura
if ( ! m_triggeredByAuraSpell || ! unitTarget )
return ;
switch ( m_triggeredByAuraSpell -> Id )
{
case 26467 : // Persistent Shield
m_caster -> CastCustomSpell ( unitTarget , 26470 , & damage , NULL , NULL , true );
break ;
default :
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectDummy: Non-handled case for spell 13567 for triggered aura %u" , m_triggeredByAuraSpell -> Id );
2009-12-27 17:49:52 -06:00
break ;
}
return ;
}
2008-10-11 14:16:25 -05:00
case 17251 : // Spirit Healer Res
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! m_originalCaster )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( m_originalCaster -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
WorldPacket data ( SMSG_SPIRIT_HEALER_CONFIRM , 8 );
2009-05-31 15:56:51 -05:00
data << uint64 ( unitTarget -> GetGUID ());
2010-04-07 22:59:46 +02:00
m_originalCaster -> ToPlayer () -> GetSession () -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
return ;
}
case 20577 : // Cannibalize
if ( unitTarget )
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 20578 , false , NULL );
2008-10-11 14:16:25 -05:00
return ;
case 23019 : // Crystal Prison Dummy DND
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || unitTarget -> GetTypeId () != TYPEID_UNIT || unitTarget -> ToCreature () -> isPet ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 18:30:53 +01:00
Creature * creatureTarget = unitTarget -> ToCreature ();
2009-10-17 15:51:44 -07:00
2010-09-03 21:55:57 -07:00
m_caster -> SummonGameObject ( 179644 , creatureTarget -> GetPositionX (), creatureTarget -> GetPositionY (), creatureTarget -> GetPositionZ (), creatureTarget -> GetOrientation (), 0 , 0 , 0 , 0 , uint32 ( creatureTarget -> GetRespawnTime () - time ( NULL )));
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019" );
2009-10-17 15:51:44 -07:00
2011-01-02 21:33:37 +01:00
creatureTarget -> DespawnOrUnsummon ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return ;
}
2009-07-16 10:54:43 +08:00
case 23448 : // Transporter Arrival - Ultrasafe Transporter: Gadgetzan - backfires
2008-10-11 14:16:25 -05:00
{
int32 r = irand ( 0 , 119 );
2010-04-07 22:59:46 +02:00
if ( r < 20 ) // Transporter Malfunction - 1/6 polymorph
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23444 , true );
2010-04-07 22:59:46 +02:00
else if ( r < 100 ) // Evil Twin - 4/6 evil twin
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23445 , true );
2009-07-16 10:54:43 +08:00
else // Transporter Malfunction - 1/6 miss the target
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36902 , true );
2008-10-11 14:16:25 -05:00
return ;
}
2009-07-16 10:54:43 +08:00
case 23453 : // Gnomish Transporter - Ultrasafe Transporter: Gadgetzan
2010-04-07 22:59:46 +02:00
if ( roll_chance_i ( 50 )) // Gadgetzan Transporter - success
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23441 , true );
2009-07-16 10:54:43 +08:00
else // Gadgetzan Transporter Failure - failure
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23446 , true );
2008-10-11 14:16:25 -05:00
return ;
case 25860 : // Reindeer Transformation
{
if ( ! m_caster -> HasAuraType ( SPELL_AURA_MOUNTED ))
return ;
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
float flyspeed = m_caster -> GetSpeedRate ( MOVE_FLIGHT );
2008-10-11 14:16:25 -05:00
float speed = m_caster -> GetSpeedRate ( MOVE_RUN );
2009-10-17 15:51:44 -07:00
2009-04-06 13:31:14 +02:00
m_caster -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//5 different spells used depending on mounted speed and if mount can fly or not
if ( flyspeed >= 4.1f )
2009-07-16 10:54:43 +08:00
// Flying Reindeer
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 44827 , true ); //310% flying Reindeer
else if ( flyspeed >= 3.8f )
2009-07-16 10:54:43 +08:00
// Flying Reindeer
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 44825 , true ); //280% flying Reindeer
else if ( flyspeed >= 1.6f )
2009-07-16 10:54:43 +08:00
// Flying Reindeer
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 44824 , true ); //60% flying Reindeer
else if ( speed >= 2.0f )
2009-07-16 10:54:43 +08:00
// Reindeer
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 25859 , true ); //100% ground Reindeer
else
2009-07-16 10:54:43 +08:00
// Reindeer
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 25858 , true ); //60% ground Reindeer
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return ;
}
2009-07-16 10:54:43 +08:00
case 26074 : // Holiday Cheer
// implemented at client side
return ;
2009-05-18 15:04:05 -05:00
// Polarity Shift
2009-05-20 11:44:38 -05:00
case 28089 :
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2009-05-20 11:44:38 -05:00
unitTarget -> CastSpell ( unitTarget , roll_chance_i ( 50 ) ? 28059 : 28084 , true , NULL , NULL , m_caster -> GetGUID ());
break ;
// Polarity Shift
case 39096 :
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2009-05-20 11:44:38 -05:00
unitTarget -> CastSpell ( unitTarget , roll_chance_i ( 50 ) ? 39088 : 39091 , true , NULL , NULL , m_caster -> GetGUID ());
break ;
2008-10-11 14:16:25 -05:00
case 29200 : // Purify Helboar Meat
{
2010-04-07 22:59:46 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-07-16 10:54:43 +08:00
uint32 spell_id = roll_chance_i ( 50 )
? 29277 // Summon Purified Helboar Meat
: 29278 ; // Summon Toxic Helboar Meat
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( m_caster , spell_id , true , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
case 29858 : // Soulshatter
2008-12-02 20:53:06 -06:00
if ( unitTarget && unitTarget -> CanHaveThreatList ()
&& unitTarget -> getThreatManager (). getThreat ( m_caster ) > 0.0f )
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( unitTarget , 32835 , true );
2008-10-11 14:16:25 -05:00
return ;
case 30458 : // Nigh Invulnerability
if ( ! m_CastItem ) return ;
2010-04-07 19:14:10 +02:00
if ( roll_chance_i ( 86 )) // Nigh-Invulnerability - success
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 30456 , true , m_CastItem );
2009-07-16 10:54:43 +08:00
else // Complete Vulnerability - backfire in 14% casts
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 30457 , true , m_CastItem );
return ;
case 30507 : // Poultryizer
if ( ! m_CastItem ) return ;
2010-04-07 19:14:10 +02:00
if ( roll_chance_i ( 80 )) // Poultryized! - success
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( unitTarget , 30501 , true , m_CastItem );
2009-07-16 10:54:43 +08:00
else // Poultryized! - backfire 20%
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( unitTarget , 30504 , true , m_CastItem );
return ;
2009-07-16 10:54:43 +08:00
case 35745 : // Socrethar's Stone
2008-10-11 14:16:25 -05:00
{
uint32 spell_id ;
switch ( m_caster -> GetAreaId ())
{
2009-07-16 10:54:43 +08:00
case 3900 : spell_id = 35743 ; break ; // Socrethar Portal
case 3742 : spell_id = 35744 ; break ; // Socrethar Portal
2008-10-11 14:16:25 -05:00
default : return ;
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , spell_id , true );
2008-10-11 14:16:25 -05:00
return ;
}
case 37674 : // Chaos Blast
2008-12-06 14:01:44 -06:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-12-06 14:01:44 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-12-06 14:01:44 -06:00
int32 basepoints0 = 100 ;
2009-05-31 15:56:51 -05:00
m_caster -> CastCustomSpell ( unitTarget , 37675 , & basepoints0 , NULL , NULL , true );
2008-10-11 14:16:25 -05:00
return ;
2008-12-06 14:01:44 -06:00
}
2010-07-16 14:42:24 +02:00
// Wrath of the Astromancer
case 42784 :
{
uint32 count = 0 ;
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2010-08-27 19:36:27 +02:00
if ( ihit -> effectMask & ( 1 << effIndex ))
2010-07-16 14:42:24 +02:00
++ count ;
damage = 12000 ; // maybe wrong value
damage /= count ;
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( 42784 );
// now deal the damage
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2010-08-27 19:36:27 +02:00
if ( ihit -> effectMask & ( 1 << effIndex ))
2010-07-16 14:42:24 +02:00
{
if ( Unit * casttarget = Unit :: GetUnit (( * unitTarget ), ihit -> targetGUID ))
m_caster -> DealDamage ( casttarget , damage , NULL , SPELL_DIRECT_DAMAGE , SPELL_SCHOOL_MASK_ARCANE , spellInfo , false );
}
return ;
}
2008-11-28 11:38:28 -06:00
// Demon Broiled Surprise
case 43723 :
{
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-10-17 15:51:44 -07:00
2009-08-17 12:52:11 +02:00
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2009-08-17 12:52:11 +02:00
if ( player && player -> GetQuestStatus ( 11379 ) == QUEST_STATUS_INCOMPLETE )
{
Creature * creature = player -> FindNearestCreature ( 19973 , 10 , false );
if ( ! creature )
{
SendCastResult ( SPELL_FAILED_NOT_HERE );
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-17 12:52:11 +02:00
player -> CastSpell ( player , 43753 , false );
}
2008-11-28 11:38:28 -06:00
return ;
}
2008-10-11 14:16:25 -05:00
case 44875 : // Complete Raptor Capture
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-01-02 21:33:37 +01:00
unitTarget -> ToCreature () -> DespawnOrUnsummon ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//cast spell Raptor Capture Credit
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 42337 , true , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2010-05-01 08:30:46 +02:00
case 47170 : // Impale Leviroth
{
2010-08-26 01:20:57 +06:00
if ( ! unitTarget && unitTarget -> GetEntry () != 26452 && unitTarget -> HealthAbovePct ( 95 ))
return ;
2010-05-01 08:30:46 +02:00
2010-08-28 00:30:07 +02:00
m_caster -> DealDamage ( unitTarget , unitTarget -> CountPctFromMaxHealth ( 93 ));
2010-08-26 01:20:57 +06:00
return ;
2010-05-01 08:30:46 +02:00
}
2009-10-31 16:55:12 -07:00
case 49357 : // Brewfest Mount Transformation
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( ! m_caster -> HasAuraType ( SPELL_AURA_MOUNTED ))
return ;
m_caster -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Ram for Alliance, Kodo for Horde
2010-03-07 15:20:19 +01:00
if ( m_caster -> ToPlayer () -> GetTeam () == ALLIANCE )
2009-10-31 16:55:12 -07:00
{
if ( m_caster -> GetSpeedRate ( MOVE_RUN ) >= 2.0f )
// 100% Ram
m_caster -> CastSpell ( m_caster , 43900 , true );
else
// 60% Ram
m_caster -> CastSpell ( m_caster , 43899 , true );
}
else
{
2010-03-07 15:20:19 +01:00
if ( m_caster -> ToPlayer () -> GetSpeedRate ( MOVE_RUN ) >= 2.0f )
2009-10-31 16:55:12 -07:00
// 100% Kodo
m_caster -> CastSpell ( m_caster , 49379 , true );
else
// 60% Kodo
m_caster -> CastSpell ( m_caster , 49378 , true );
}
return ;
case 52845 : // Brewfest Mount Transformation (Faction Swap)
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( ! m_caster -> HasAuraType ( SPELL_AURA_MOUNTED ))
return ;
m_caster -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Ram for Horde, Kodo for Alliance
2010-03-07 15:20:19 +01:00
if ( m_caster -> ToPlayer () -> GetTeam () == HORDE )
2009-10-31 16:55:12 -07:00
{
if ( m_caster -> GetSpeedRate ( MOVE_RUN ) >= 2.0f )
// 100% Ram
m_caster -> CastSpell ( m_caster , 43900 , true );
else
// 60% Ram
m_caster -> CastSpell ( m_caster , 43899 , true );
}
else
{
2010-03-07 15:20:19 +01:00
if ( m_caster -> ToPlayer () -> GetSpeedRate ( MOVE_RUN ) >= 2.0f )
2009-10-31 16:55:12 -07:00
// 100% Kodo
m_caster -> CastSpell ( m_caster , 49379 , true );
else
// 60% Kodo
m_caster -> CastSpell ( m_caster , 49378 , true );
}
return ;
2009-07-30 10:19:03 +08:00
case 55004 : // Nitro Boosts
2009-10-31 16:55:12 -07:00
if ( ! m_CastItem )
return ;
if ( roll_chance_i ( 95 )) // Nitro Boosts - success
2009-07-30 10:19:03 +08:00
m_caster -> CastSpell ( m_caster , 54861 , true , m_CastItem );
else // Knocked Up - backfire 5%
m_caster -> CastSpell ( m_caster , 46014 , true , m_CastItem );
return ;
2008-10-11 14:16:25 -05:00
case 50243 : // Teach Language
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// spell has a 1/3 chance to trigger one of the below
2009-10-31 16:55:12 -07:00
if ( roll_chance_i ( 66 ))
2008-10-11 14:16:25 -05:00
return ;
2010-03-07 15:20:19 +01:00
if ( m_caster -> ToPlayer () -> GetTeam () == ALLIANCE )
2008-10-11 14:16:25 -05:00
{
// 1000001 - gnomish binary
m_caster -> CastSpell ( m_caster , 50242 , true );
}
else
{
// 01001000 - goblin binary
m_caster -> CastSpell ( m_caster , 50246 , true );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return ;
}
case 51582 : //Rocket Boots Engaged (Rocket Boots Xtreme and Rocket Boots Xtreme Lite)
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-08 04:37:24 +02:00
if ( Battleground * bg = m_caster -> ToPlayer () -> GetBattleground ())
2010-07-27 21:12:40 -07:00
bg -> EventPlayerDroppedFlag ( m_caster -> ToPlayer ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_caster -> CastSpell ( m_caster , 30452 , true , NULL );
return ;
2009-03-29 17:22:58 -06:00
}
2009-05-22 16:49:37 -05:00
case 52759 : // Ancestral Awakening
if ( ! unitTarget )
return ;
m_caster -> CastCustomSpell ( unitTarget , 52752 , & damage , NULL , NULL , true );
return ;
2010-07-16 14:42:24 +02:00
case 54171 : //Divine Storm
{
m_caster -> CastCustomSpell ( unitTarget , 54172 , & damage , 0 , 0 , true );
return ;
}
2009-03-03 18:41:44 -06:00
case 58418 : // Portal to Orgrimmar
case 58420 : // Portal to Stormwind
2009-03-29 17:18:51 -06:00
return ; // implemented in EffectScript[0]
2009-08-23 01:08:09 -05:00
case 62324 : // Throw Passenger
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
{
2010-04-07 19:14:10 +02:00
if ( m_targets . HasTraj ())
2009-08-23 01:08:09 -05:00
{
2010-04-07 19:14:10 +02:00
if ( Vehicle * vehicle = m_caster -> GetVehicleKit ())
if ( Unit * passenger = vehicle -> GetPassenger ( damage - 1 ))
2009-08-23 01:08:09 -05:00
{
std :: list < Unit *> unitList ;
// use 99 because it is 3d search
SearchAreaTarget ( unitList , 99 , PUSH_DST_CENTER , SPELL_TARGETS_ENTRY , 33114 );
float minDist = 99 * 99 ;
2011-03-04 21:16:27 +01:00
Unit * target = NULL ;
2009-10-17 16:20:24 -07:00
for ( std :: list < Unit *>:: iterator itr = unitList . begin (); itr != unitList . end (); ++ itr )
2009-08-23 01:08:09 -05:00
{
2010-04-07 19:14:10 +02:00
if ( Vehicle * seat = ( * itr ) -> GetVehicleKit ())
if ( ! seat -> GetPassenger ( 0 ))
if ( Unit * device = seat -> GetPassenger ( 2 ))
if ( ! device -> GetCurrentSpell ( CURRENT_CHANNELED_SPELL ))
2009-08-23 01:08:09 -05:00
{
2009-08-29 23:20:16 -05:00
float dist = ( * itr ) -> GetExactDistSq ( & m_targets . m_dstPos );
2010-04-07 19:14:10 +02:00
if ( dist < minDist )
2009-08-23 01:08:09 -05:00
{
minDist = dist ;
2011-03-04 21:16:27 +01:00
target = ( * itr );
2009-08-23 01:08:09 -05:00
}
}
}
2011-03-04 21:16:27 +01:00
if ( target && target -> IsWithinDist2d ( & m_targets . m_dstPos , GetSpellRadius ( m_spellInfo , effIndex , false ) * 2 )) // now we use *2 because the location of the seat is not correct
2009-08-23 01:08:09 -05:00
passenger -> EnterVehicle ( target , 0 );
else
{
passenger -> ExitVehicle ();
2009-08-29 23:20:16 -05:00
float x , y , z ;
m_targets . m_dstPos . GetPosition ( x , y , z );
passenger -> GetMotionMaster () -> MoveJump ( x , y , z , m_targets . GetSpeedXY (), m_targets . GetSpeedZ ());
2009-08-23 01:08:09 -05:00
}
}
}
return ;
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
}
case 64385 : // Unusual Compass
{
2011-04-29 20:47:02 +02:00
m_caster -> SetOrientation ( float ( urand ( 0 , 62832 )) / 10000.0f );
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
WorldPacket data ;
m_caster -> BuildHeartBeatMsg ( & data );
2011-04-29 20:47:02 +02:00
m_caster -> SendMessageToSet ( & data , true );
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
return ;
}
2011-01-06 21:40:32 +01:00
case 53808 : // Pygmy Oil
{
2011-01-06 22:45:07 +01:00
Aura * pAura = m_caster -> GetAura ( 53806 );
if ( pAura )
2011-01-06 21:40:32 +01:00
pAura -> RefreshDuration ();
else
{
2011-01-06 22:45:07 +01:00
pAura = m_caster -> GetAura ( 53805 );
2011-01-06 21:40:32 +01:00
if ( ! pAura || pAura -> GetStackAmount () < 5 || ! roll_chance_i ( 50 ))
m_caster -> CastSpell ( m_caster , 53805 , true );
else
{
pAura -> Remove ();
m_caster -> CastSpell ( m_caster , 53806 , true );
}
}
return ;
}
2011-01-06 19:33:22 +01:00
case 54577 : // U.D.E.D.
{
2011-01-06 19:57:36 +01:00
if ( unitTarget -> GetEntry () != 29402 )
2011-01-06 19:33:22 +01:00
return ;
m_caster -> SummonGameObject ( 192693 , unitTarget -> GetPositionX (), unitTarget -> GetPositionY (), unitTarget -> GetPositionZ (), unitTarget -> GetOrientation (), 0 , 0 , 0 , 0 , 100 );
2011-01-06 19:57:36 +01:00
for ( uint8 i = 0 ; i < 4 ; ++ i )
2011-01-06 19:33:22 +01:00
m_caster -> SummonGameObject ( 191567 , float ( unitTarget -> GetPositionX () + irand ( - 7 , 7 )), float ( unitTarget -> GetPositionY () + irand ( - 7 , 7 )), unitTarget -> GetPositionZ (), unitTarget -> GetOrientation (), 0 , 0 , 0 , 0 , 100 );
unitTarget -> Kill ( unitTarget );
return ;
}
2011-01-06 20:22:39 +01:00
case 51961 : // Captured Chicken Cover - Quest 12702 & 12532
{
if ( m_caster -> GetTypeId () != TYPEID_PLAYER
|| ! unitTarget -> HasAura ( 51959 )
|| ! ( m_caster -> ToPlayer () -> GetQuestStatus ( 12702 ) == QUEST_STATUS_INCOMPLETE || m_caster -> ToPlayer () -> GetQuestStatus ( 12532 ) == QUEST_STATUS_INCOMPLETE ))
return ;
m_caster -> CastSpell ( m_caster , 51037 , true );
unitTarget -> Kill ( unitTarget );
return ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
break ;
2008-11-28 11:38:28 -06:00
}
2008-10-11 14:16:25 -05:00
case SPELLFAMILY_WARRIOR :
// Charge
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags & SPELLFAMILYFLAG_WARRIOR_CHARGE && m_spellInfo -> SpellVisual [ 0 ] == 867 )
2008-10-11 14:16:25 -05:00
{
int32 chargeBasePoints0 = damage ;
2009-05-31 15:56:51 -05:00
m_caster -> CastCustomSpell ( m_caster , 34846 , & chargeBasePoints0 , NULL , NULL , true );
2009-12-17 12:23:01 +01:00
//Juggernaut crit bonus
2010-04-07 19:14:10 +02:00
if ( m_caster -> HasAura ( 64976 ))
2009-12-17 12:23:01 +01:00
m_caster -> CastSpell ( m_caster , 65156 , true );
2008-10-11 14:16:25 -05:00
return ;
}
2009-04-07 10:51:45 +02:00
//Slam
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_WARRIOR_SLAM && m_spellInfo -> SpellIconID == 559 )
2009-04-07 10:51:45 +02:00
{
int32 bp0 = damage ;
m_caster -> CastCustomSpell ( unitTarget , 50783 , & bp0 , NULL , NULL , true , 0 );
2009-03-03 20:42:49 +01:00
return ;
2009-04-07 10:51:45 +02:00
}
2008-10-11 14:16:25 -05:00
// Execute
2010-09-05 14:28:13 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_0 ] & SPELLFAMILYFLAG_WARRIOR_EXECUTE )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-31 11:09:37 -06:00
spell_id = 20647 ;
2010-03-01 17:57:14 -06:00
2010-09-05 14:28:13 +02:00
int32 rageUsed = std :: min < int32 > ( 300 - m_powerCost , m_caster -> GetPower ( POWER_RAGE ));
int32 newRage = std :: max < int32 > ( 0 , m_caster -> GetPower ( POWER_RAGE ) - rageUsed );
// Sudden Death rage save
if ( AuraEffect * aurEff = m_caster -> GetAuraEffect ( SPELL_AURA_PROC_TRIGGER_SPELL , SPELLFAMILY_GENERIC , 1989 , EFFECT_0 ))
2009-05-13 18:00:07 +02:00
{
2010-09-05 14:28:13 +02:00
int32 ragesave = SpellMgr :: CalculateSpellEffectAmount ( aurEff -> GetSpellProto (), EFFECT_1 ) * 10 ;
newRage = std :: max ( newRage , ragesave );
2009-05-13 18:00:07 +02:00
}
2009-10-17 15:51:44 -07:00
2010-09-05 14:28:13 +02:00
m_caster -> SetPower ( POWER_RAGE , uint32 ( newRage ));
// Glyph of Execution bonus
if ( AuraEffect * aurEff = m_caster -> GetAuraEffect ( 58367 , EFFECT_0 ))
rageUsed += aurEff -> GetAmount () * 10 ;
2010-03-01 17:57:14 -06:00
2010-09-05 14:28:13 +02:00
bp = damage + int32 ( rageUsed * m_spellInfo -> EffectDamageMultiplier [ effIndex ] + m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ) * 0.2f );
2009-02-02 10:01:56 -06:00
break ;
2008-10-11 14:16:25 -05:00
}
2009-04-24 11:15:04 -05:00
// Concussion Blow
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_WARRIOR_CONCUSSION_BLOW )
2009-04-24 11:15:04 -05:00
{
2010-12-11 20:37:38 +06:00
m_damage += CalculatePctF ( damage , m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ));
2009-04-24 11:15:04 -05:00
return ;
2009-05-04 15:48:10 +02:00
}
2009-01-14 18:42:53 -06:00
switch ( m_spellInfo -> Id )
2008-10-11 14:16:25 -05:00
{
2009-01-25 16:35:14 -06:00
// Bloodthirst
case 23881 :
{
m_caster -> CastCustomSpell ( unitTarget , 23885 , & damage , NULL , NULL , true , NULL );
return ;
}
2008-10-11 14:16:25 -05:00
}
break ;
case SPELLFAMILY_WARLOCK :
2009-01-02 11:03:43 -06:00
// Life Tap
2011-05-26 16:12:33 +02:00
if (( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_WARLOCK_LIFETAP ) && m_caster -> ToPlayer ())
2008-10-11 14:16:25 -05:00
{
2010-08-22 23:46:40 +06:00
float spFactor = 0.0f ;
2010-05-26 14:54:56 -03:00
switch ( m_spellInfo -> Id )
{
2010-08-22 23:46:40 +06:00
case 11689 : spFactor = 0.2f ; break ;
2010-08-08 19:45:53 +02:00
case 27222 :
2010-08-22 23:46:40 +06:00
case 57946 : spFactor = 0.5f ; break ;
2010-05-26 14:54:56 -03:00
}
2010-08-25 03:21:22 +03:00
int32 damage = int32 ( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 0 ) + ( 6.3875 * m_spellInfo -> baseLevel ));
2010-08-22 12:39:39 -07:00
int32 mana = int32 ( damage + ( m_caster -> ToPlayer () -> GetUInt32Value ( PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW ) * spFactor ));
2010-05-22 04:04:51 -03:00
2010-04-07 19:14:10 +02:00
if ( unitTarget && ( int32 ( unitTarget -> GetHealth ()) > damage ))
2008-10-11 14:16:25 -05:00
{
// Shouldn't Appear in Combat Log
2009-01-02 11:03:43 -06:00
unitTarget -> ModifyHealth ( - damage );
2009-10-17 15:51:44 -07:00
2009-01-02 11:03:43 -06:00
// Improved Life Tap mod
2010-01-10 01:23:15 +01:00
if ( AuraEffect const * aurEff = m_caster -> GetDummyAuraEffect ( SPELLFAMILY_WARLOCK , 208 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( mana , aurEff -> GetAmount ());
2009-10-17 15:51:44 -07:00
2009-01-02 11:03:43 -06:00
m_caster -> CastCustomSpell ( unitTarget , 31818 , & mana , NULL , NULL , true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Mana Feed
2009-01-02 11:03:43 -06:00
int32 manaFeedVal = 0 ;
2009-08-11 19:57:27 +02:00
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( SPELL_AURA_ADD_FLAT_MODIFIER , SPELLFAMILY_WARLOCK , 1982 , 0 ))
manaFeedVal = aurEff -> GetAmount ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( manaFeedVal > 0 )
2009-01-02 11:03:43 -06:00
{
2010-12-11 20:37:38 +06:00
ApplyPctN ( manaFeedVal , mana );
2009-01-02 11:03:43 -06:00
m_caster -> CastCustomSpell ( m_caster , 32553 , & manaFeedVal , NULL , NULL , true , NULL );
}
2008-10-11 14:16:25 -05:00
}
else
SendCastResult ( SPELL_FAILED_FIZZLE );
return ;
}
break ;
case SPELLFAMILY_DRUID :
2009-03-03 20:42:49 +01:00
// Starfall
2009-12-24 12:37:26 -06:00
if ( m_spellInfo -> SpellFamilyFlags [ 2 ] & SPELLFAMILYFLAG2_DRUID_STARFALL )
2009-03-03 20:42:49 +01:00
{
2009-03-21 22:48:52 -06:00
//Shapeshifting into an animal form or mounting cancels the effect.
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetCreatureType () == CREATURE_TYPE_BEAST || m_caster -> IsMounted ())
2009-03-21 22:48:52 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_triggeredByAuraSpell )
2009-03-21 22:48:52 -06:00
m_caster -> RemoveAurasDueToSpell ( m_triggeredByAuraSpell -> Id );
return ;
}
2009-10-17 15:51:44 -07:00
2009-03-21 22:48:52 -06:00
//Any effect which causes you to lose control of your character will supress the starfall effect.
2011-04-10 08:46:47 +03:00
if ( m_caster -> HasUnitState ( UNIT_STAT_CONTROLLED ))
2009-03-21 22:48:52 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-21 22:48:52 -06:00
m_caster -> CastSpell ( unitTarget , damage , true );
2009-03-03 20:42:49 +01:00
return ;
}
2008-10-11 14:16:25 -05:00
break ;
case SPELLFAMILY_PALADIN :
2009-08-08 16:18:05 +02:00
// Divine Storm
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & SPELLFAMILYFLAG1_PALADIN_DIVINESTORM && effIndex == 1 )
2009-08-08 16:18:05 +02:00
{
2010-12-11 20:37:38 +06:00
int32 dmg = CalculatePctN ( m_damage , damage );
2009-10-31 16:00:47 -07:00
if ( ! unitTarget )
unitTarget = m_caster ;
2009-10-16 12:44:00 -07:00
m_caster -> CastCustomSpell ( unitTarget , 54171 , & dmg , 0 , 0 , true );
2009-08-08 16:18:05 +02:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-04-09 14:58:25 +02:00
switch ( m_spellInfo -> Id )
{
2008-10-11 14:16:25 -05:00
case 31789 : // Righteous Defense (step 1)
{
// Clear targets for eff 1
2009-10-31 16:00:47 -07:00
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2008-10-11 14:16:25 -05:00
ihit -> effectMask &= ~ ( 1 << 1 );
2009-10-17 15:51:44 -07:00
2009-12-17 12:23:01 +01:00
// not empty (checked), copy
2009-12-20 15:11:57 +01:00
Unit :: AttackerSet attackers = unitTarget -> getAttackers ();
2009-10-17 15:51:44 -07:00
2009-12-17 12:23:01 +01:00
// selected from list 3
2011-05-14 14:12:40 +02:00
uint32 maxTargets = std :: min < uint32 > ( 3 , attackers . size ());
for ( uint32 i = 0 ; i < maxTargets ; ++ i )
2008-10-11 14:16:25 -05:00
{
2009-12-17 12:23:01 +01:00
Unit :: AttackerSet :: iterator aItr = attackers . begin ();
2011-05-14 14:12:40 +02:00
std :: advance ( aItr , urand ( 0 , attackers . size () - 1 ));
AddUnitTarget ( * aItr , 1 );
2009-12-17 12:23:01 +01:00
attackers . erase ( aItr );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// now let next effect cast spell at each target.
return ;
}
}
break ;
case SPELLFAMILY_SHAMAN :
2009-08-08 16:18:05 +02:00
// Cleansing Totem Pulse
2010-04-07 23:25:02 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS && m_spellInfo -> SpellIconID == 1673 )
2009-05-22 16:42:29 -05:00
{
2009-08-08 16:18:05 +02:00
int32 bp1 = 1 ;
// Cleansing Totem Effect
2009-10-31 16:45:56 -07:00
if ( unitTarget )
m_caster -> CastCustomSpell ( unitTarget , 52025 , NULL , & bp1 , NULL , true , NULL , NULL , m_originalCasterGUID );
2009-05-22 16:42:29 -05:00
return ;
}
2009-01-26 17:13:27 -06:00
// Healing Stream Totem
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_SHAMAN_HEALING_STREAM )
2009-01-26 17:13:27 -06:00
{
2010-01-04 11:05:19 +02:00
if ( ! unitTarget )
return ;
// Restorative Totems
2010-04-07 19:14:10 +02:00
if ( Unit * owner = m_caster -> GetOwner ())
2010-01-04 11:05:19 +02:00
if ( AuraEffect * dummy = owner -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_SHAMAN , 338 , 1 ))
2010-12-11 20:37:38 +06:00
AddPctN ( damage , dummy -> GetAmount ());
2010-01-04 11:05:19 +02:00
2009-10-31 16:45:56 -07:00
m_caster -> CastCustomSpell ( unitTarget , 52042 , & damage , 0 , 0 , true , 0 , 0 , m_originalCasterGUID );
2009-01-26 17:13:27 -06:00
return ;
}
// Mana Spring Totem
2009-12-24 12:37:26 -06:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_SHAMAN_MANA_SPRING )
2009-01-26 17:13:27 -06:00
{
2009-10-31 16:45:56 -07:00
if ( ! unitTarget || unitTarget -> getPowerType () != POWER_MANA )
2009-01-26 17:13:27 -06:00
return ;
m_caster -> CastCustomSpell ( unitTarget , 52032 , & damage , 0 , 0 , true , 0 , 0 , m_originalCasterGUID );
return ;
}
2009-01-12 21:58:01 -06:00
// Lava Lash
2009-12-24 12:37:26 -06:00
if ( m_spellInfo -> SpellFamilyFlags [ 2 ] & SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH )
2009-01-12 21:58:01 -06:00
{
2009-10-18 18:38:46 -07:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-01-12 21:58:01 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-30 15:25:15 +02:00
if ( m_caster -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_OFFHAND ))
2009-01-12 21:58:01 -06:00
{
2009-08-08 16:18:05 +02:00
// Damage is increased by 25% if your off-hand weapon is enchanted with Flametongue.
2010-01-10 01:23:15 +01:00
if ( m_caster -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_SHAMAN , 0x200000 , 0 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( m_damage , damage );
2009-01-12 21:58:01 -06:00
}
return ;
}
2008-10-11 14:16:25 -05:00
break ;
2009-03-04 00:19:55 +01:00
case SPELLFAMILY_DEATHKNIGHT :
2009-08-08 16:18:05 +02:00
// Death strike
2009-12-24 12:37:26 -06:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_DK_DEATH_STRIKE )
2009-03-04 00:19:55 +01:00
{
2009-11-17 20:13:41 -08:00
uint32 count = unitTarget -> GetDiseasesByCaster ( m_caster -> GetGUID ());
2010-09-03 21:55:57 -07:00
int32 bp = int32 ( count * m_caster -> CountPctFromMaxHealth ( int32 ( m_spellInfo -> EffectDamageMultiplier [ 0 ])));
2009-08-08 16:18:05 +02:00
// Improved Death Strike
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( SPELL_AURA_ADD_PCT_MODIFIER , SPELLFAMILY_DEATHKNIGHT , 2751 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( bp , m_caster -> CalculateSpellDamage ( m_caster , aurEff -> GetSpellProto (), 2 ));
2009-11-17 19:49:24 -08:00
m_caster -> CastCustomSpell ( m_caster , 45470 , & bp , NULL , NULL , false );
2009-03-04 00:19:55 +01:00
return ;
}
2009-03-08 03:10:03 +01:00
// Death Coil
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_DK_DEATH_COIL )
2009-03-08 03:10:03 +01:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> IsFriendlyTo ( unitTarget ))
2009-03-08 03:10:03 +01:00
{
2010-08-22 12:39:39 -07:00
int32 bp = int32 ( damage * 1.5f );
2009-05-31 15:56:51 -05:00
m_caster -> CastCustomSpell ( unitTarget , 47633 , & bp , NULL , NULL , true );
2009-03-08 03:10:03 +01:00
}
else
2009-03-31 14:25:38 -06:00
{
int32 bp = damage ;
2009-05-31 15:56:51 -05:00
m_caster -> CastCustomSpell ( unitTarget , 47632 , & bp , NULL , NULL , true );
2009-03-31 14:25:38 -06:00
}
2009-03-08 03:10:03 +01:00
return ;
}
2010-08-18 00:20:23 +06:00
switch ( m_spellInfo -> Id )
2009-04-11 22:41:15 -05:00
{
2010-08-18 00:20:23 +06:00
case 49560 : // Death Grip
2010-04-11 15:30:39 +02:00
Position pos ;
2010-08-27 19:36:27 +02:00
GetSummonPosition ( effIndex , pos );
2009-08-23 22:09:43 -05:00
if ( Unit * unit = unitTarget -> GetVehicleBase ()) // what is this for?
2010-08-18 00:20:23 +06:00
unit -> CastSpell ( pos . GetPositionX (), pos . GetPositionY (), pos . GetPositionZ (), damage , true );
2010-11-09 23:02:47 -03:00
else if ( ! unitTarget -> HasAuraType ( SPELL_AURA_DEFLECT_SPELLS )) // Deterrence
2010-08-18 00:20:23 +06:00
unitTarget -> CastSpell ( pos . GetPositionX (), pos . GetPositionY (), pos . GetPositionZ (), damage , true );
2009-04-11 22:41:15 -05:00
return ;
2010-08-18 00:20:23 +06:00
case 46584 : // Raise Dead
2010-04-07 22:59:46 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-06-18 14:17:11 +02:00
return ;
2009-10-17 15:51:44 -07:00
2009-06-18 14:17:11 +02:00
// Do we have talent Master of Ghouls?
2010-04-07 19:14:10 +02:00
if ( m_caster -> HasAura ( 52143 ))
2009-06-18 14:17:11 +02:00
// summon as pet
2010-08-18 00:20:23 +06:00
bp = 52150 ;
2009-06-18 14:17:11 +02:00
else
// or guardian
bp = 46585 ;
2009-10-17 15:51:44 -07:00
2009-06-18 14:17:11 +02:00
if ( m_targets . HasDst ())
2010-08-08 20:32:14 +02:00
targets . setDst ( m_targets . m_dstPos );
2009-06-18 14:17:11 +02:00
else
{
2010-08-08 20:32:14 +02:00
targets . setDst ( * m_caster );
2010-04-07 22:59:46 +02:00
// Corpse not found - take reagents (only not triggered cast can take them)
2009-06-18 14:17:11 +02:00
triggered = false ;
}
// Remove cooldown - summon spellls have category
2010-08-18 00:20:23 +06:00
m_caster -> ToPlayer () -> RemoveSpellCooldown ( m_spellInfo -> Id , true );
spell_id = 48289 ;
break ;
2009-06-18 14:17:11 +02:00
// Raise dead - take reagents and trigger summon spells
2010-08-18 00:20:23 +06:00
case 48289 :
2009-06-18 14:17:11 +02:00
if ( m_targets . HasDst ())
2010-08-08 20:32:14 +02:00
targets . setDst ( m_targets . m_dstPos );
2009-10-17 15:51:44 -07:00
2010-07-15 23:20:41 +02:00
spell_id = CalculateDamage ( 0 , NULL );
2010-08-18 00:20:23 +06:00
break ;
2009-08-04 19:28:31 +02:00
}
2009-03-08 03:10:03 +01:00
break ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-04-03 16:59:01 -06:00
//spells triggered by dummy effect should not miss
2010-04-07 19:14:10 +02:00
if ( spell_id )
2009-04-03 16:59:01 -06:00
{
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( spell_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2009-04-03 16:59:01 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "EffectDummy of spell %u: triggering unknown spell id %i \n " , m_spellInfo -> Id , spell_id );
2009-04-03 16:59:01 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-04-03 16:59:01 -06:00
targets . setUnitTarget ( unitTarget );
2010-08-21 21:00:06 +02:00
Spell * spell = new Spell ( m_caster , spellInfo , triggered , m_originalCasterGUID , true );
2010-08-27 06:40:23 +02:00
if ( bp ) spell -> SetSpellValue ( SPELLVALUE_BASE_POINT0 , bp );
2009-04-03 16:59:01 -06:00
spell -> prepare ( & targets );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// pet auras
2011-04-29 20:47:02 +02:00
if ( PetAura const * petSpell = sSpellMgr -> GetPetAura ( m_spellInfo -> Id , effIndex ))
2008-10-11 14:16:25 -05:00
{
m_caster -> AddPetAura ( petSpell );
return ;
}
2009-10-17 15:51:44 -07:00
2010-07-24 21:51:25 +02:00
// normal DB scripted effect
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell ScriptStart spellid %u in EffectDummy(%u)" , m_spellInfo -> Id , effIndex );
2010-08-28 21:01:16 +06:00
m_caster -> GetMap () -> ScriptsStart ( sSpellScripts , uint32 ( m_spellInfo -> Id | ( effIndex << 24 )), m_caster , unitTarget );
2010-07-24 21:51:25 +02:00
2009-03-13 18:34:46 -06:00
// Script based implementation. Must be used only for not good for implementation in core spell effects
// So called only for not proccessed cases
2010-04-07 19:14:10 +02:00
if ( gameObjTarget )
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnDummyEffect ( m_caster , m_spellInfo -> Id , effIndex , gameObjTarget );
2010-04-07 19:14:10 +02:00
else if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_UNIT )
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnDummyEffect ( m_caster , m_spellInfo -> Id , effIndex , unitTarget -> ToCreature ());
2010-04-07 19:14:10 +02:00
else if ( itemTarget )
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnDummyEffect ( m_caster , m_spellInfo -> Id , effIndex , itemTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTriggerSpellWithValue ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// normal case
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i" , m_spellInfo -> Id , triggered_spell_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 bp = damage ;
2010-02-20 23:57:54 +01:00
Unit * caster = GetTriggeredSpellCaster ( spellInfo , m_caster , unitTarget );
2010-04-07 18:09:10 +02:00
2011-04-29 20:47:02 +02:00
caster -> CastCustomSpell ( unitTarget , triggered_spell_id , & bp , & bp , & bp , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTriggerRitualOfSummoning ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i" , m_spellInfo -> Id , triggered_spell_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
finish ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( unitTarget , spellInfo , false );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectForceCast ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// normal case
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectForceCast of spell %u: triggering unknown spell id %i" , m_spellInfo -> Id , triggered_spell_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-07-30 00:05:36 +02:00
if ( damage )
2009-08-15 20:36:21 -05:00
{
2011-01-12 22:50:51 +01:00
switch ( m_spellInfo -> Id )
2009-08-15 20:36:21 -05:00
{
2010-02-20 23:57:54 +01:00
case 48598 : // Ride Flamebringer Cue
2010-04-07 18:09:10 +02:00
unitTarget -> RemoveAura ( damage );
2010-02-20 23:57:54 +01:00
break ;
2011-05-24 05:20:57 +02:00
case 52588 : // Skeletal Gryphon Escape
unitTarget -> RemoveAura ( damage );
unitTarget -> CastSpell ( unitTarget , spellInfo , true );
return ;
2010-02-20 23:57:54 +01:00
case 52463 : // Hide In Mine Car
case 52349 : // Overtake
unitTarget -> CastCustomSpell ( unitTarget , spellInfo -> Id , & damage , NULL , NULL , true , NULL , NULL , m_originalCasterGUID );
return ;
2010-08-21 20:50:38 +02:00
case 72378 : // Blood Nova
case 73058 : // Blood Nova
2011-01-12 22:50:51 +01:00
m_caster -> CastSpell ( unitTarget , 72380 , true ); // additional spell cast
2010-08-21 20:50:38 +02:00
break ;
2009-08-15 20:36:21 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-12-27 11:06:53 +01:00
Unit * caster = GetTriggeredSpellCaster ( spellInfo , m_caster , unitTarget );
2011-01-26 01:03:35 +01:00
2010-12-27 11:06:53 +01:00
caster -> CastSpell ( unitTarget , spellInfo , true , NULL , NULL , m_originalCasterGUID );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectForceCastWithValue ( SpellEffIndex effIndex )
2010-07-19 22:52:21 +02:00
{
if ( ! unitTarget )
return ;
2010-08-27 19:36:27 +02:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2010-07-19 22:52:21 +02:00
// normal case
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
if ( ! spellInfo )
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectForceCastWithValue of spell %u: triggering unknown spell id %i" , m_spellInfo -> Id , triggered_spell_id );
2010-07-19 22:52:21 +02:00
return ;
}
int32 bp = damage ;
2010-12-27 11:06:53 +01:00
Unit * caster = GetTriggeredSpellCaster ( spellInfo , m_caster , unitTarget );
caster -> CastCustomSpell ( unitTarget , spellInfo -> Id , & bp , & bp , & bp , true , NULL , NULL , m_originalCasterGUID );
2010-07-19 22:52:21 +02:00
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectTriggerSpell ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-08-12 21:07:03 -05:00
// only unit case known
if ( ! unitTarget )
{
2010-04-07 19:14:10 +02:00
if ( gameObjTarget || itemTarget )
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Spell::EffectTriggerSpell (Spell: %u): Unsupported non-unit case!" , m_spellInfo -> Id );
2009-08-12 21:07:03 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-17 15:54:39 -05:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2010-03-16 21:32:01 +01:00
Unit * originalCaster = NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// special cases
switch ( triggered_spell_id )
{
2009-08-07 16:45:56 +02:00
// Mirror Image
case 58832 :
{
// Glyph of Mirror Image
2009-08-08 16:18:05 +02:00
if ( m_caster -> HasAura ( 63093 ))
2009-08-07 16:45:56 +02:00
m_caster -> CastSpell ( m_caster , 65047 , true ); // Mirror Image
2009-10-17 15:51:44 -07:00
2009-08-07 16:45:56 +02:00
break ;
}
2009-08-02 10:19:40 +08:00
// Vanish (not exist)
2008-10-11 14:16:25 -05:00
case 18461 :
{
2009-08-12 21:07:03 -05:00
unitTarget -> RemoveMovementImpairingAuras ();
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOD_STALKED );
2009-10-17 15:51:44 -07:00
2010-11-13 06:43:45 +01:00
// If this spell is given to an NPC, it must handle the rest using its own AI
2009-08-12 21:07:03 -05:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-11-13 06:43:45 +01:00
// See if we already are stealthed. If so, we're done.
if ( unitTarget -> HasAura ( 1784 ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-11-13 06:43:45 +01:00
// Reset cooldown on stealth if needed
if ( unitTarget -> ToPlayer () -> HasSpellCooldown ( 1784 ))
unitTarget -> ToPlayer () -> RemoveSpellCooldown ( 1784 );
2009-10-17 15:51:44 -07:00
2010-11-13 06:43:45 +01:00
triggered_spell_id = 1784 ;
break ;
2008-10-11 14:16:25 -05:00
}
2009-05-19 18:33:49 +02:00
// Demonic Empowerment -- succubus
case 54437 :
{
unitTarget -> RemoveMovementImpairingAuras ();
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOD_STALKED );
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOD_STUN );
2009-10-17 15:51:44 -07:00
2009-05-19 18:33:49 +02:00
// Cast Lesser Invisibility
triggered_spell_id = 7870 ;
break ;
}
2008-10-11 14:16:25 -05:00
// just skip
case 23770 : // Sayge's Dark Fortune of *
// not exist, common cooldown can be implemented in scripts if need.
return ;
// Brittle Armor - (need add max stack of 24575 Brittle Armor)
case 29284 :
{
2009-08-02 10:19:40 +08:00
// Brittle Armor
SpellEntry const * spell = sSpellStore . LookupEntry ( 24575 );
2008-10-11 14:16:25 -05:00
if ( ! spell )
return ;
2009-10-17 15:51:44 -07:00
2010-08-26 15:54:56 +06:00
for ( uint32 j = 0 ; j < spell -> StackAmount ; ++ j )
2010-02-20 23:57:54 +01:00
m_caster -> CastSpell ( unitTarget , spell -> Id , true );
2008-10-11 14:16:25 -05:00
return ;
}
// Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
case 29286 :
{
2009-08-02 10:19:40 +08:00
// Mercurial Shield
SpellEntry const * spell = sSpellStore . LookupEntry ( 26464 );
2008-10-11 14:16:25 -05:00
if ( ! spell )
return ;
2009-10-17 15:51:44 -07:00
2010-08-26 15:54:56 +06:00
for ( uint32 j = 0 ; j < spell -> StackAmount ; ++ j )
2010-02-20 23:57:54 +01:00
m_caster -> CastSpell ( unitTarget , spell -> Id , true );
2008-10-11 14:16:25 -05:00
return ;
}
// Righteous Defense
case 31980 :
{
2010-02-20 23:57:54 +01:00
m_caster -> CastSpell ( unitTarget , 31790 , true );
2008-10-11 14:16:25 -05:00
return ;
}
// Cloak of Shadows
2009-08-02 10:19:40 +08:00
case 35729 :
2008-10-11 14:16:25 -05:00
{
2008-11-27 11:54:27 -06:00
uint32 dispelMask = GetDispellMask ( DISPEL_ALL );
2010-01-10 01:23:15 +01:00
Unit :: AuraApplicationMap & Auras = unitTarget -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator iter = Auras . begin (); iter != Auras . end ();)
2008-10-11 14:16:25 -05:00
{
// remove all harmful spells on you...
2010-01-10 01:23:15 +01:00
SpellEntry const * spell = iter -> second -> GetBase () -> GetSpellProto ();
2010-04-07 19:14:10 +02:00
if (( spell -> DmgClass == SPELL_DAMAGE_CLASS_MAGIC // only affect magic spells
2008-11-27 11:54:27 -06:00
|| (( 1 << spell -> Dispel ) & dispelMask ))
2008-10-23 22:04:14 -05:00
// ignore positive and passive auras
2010-01-10 01:23:15 +01:00
&& ! iter -> second -> IsPositive () && ! iter -> second -> GetBase () -> IsPassive ())
2008-10-11 14:16:25 -05:00
{
2009-04-08 00:21:11 +02:00
m_caster -> RemoveAura ( iter );
2008-10-11 14:16:25 -05:00
}
2009-04-08 00:07:32 +02:00
else
2011-05-12 10:41:25 +02:00
++ iter ;
2008-10-11 14:16:25 -05:00
}
return ;
}
// Priest Shadowfiend (34433) need apply mana gain trigger aura on pet
case 41967 :
{
2009-08-12 21:07:03 -05:00
if ( Unit * pet = unitTarget -> GetGuardianPet ())
2008-10-11 14:16:25 -05:00
pet -> CastSpell ( pet , 28305 , true );
return ;
}
2010-01-23 16:06:06 +01:00
// Empower Rune Weapon
case 53258 :
return ; // skip, hack-added in spell effect
2010-03-16 21:32:01 +01:00
// Snake Trap
case 57879 :
originalCaster = m_originalCaster ;
break ;
2010-08-18 17:19:47 +02:00
// Coldflame
case 33801 :
return ; // just make the core stfu
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// normal case
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
2009-08-12 21:07:03 -05:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectTriggerSpell of spell %u: triggering unknown spell id %i" , m_spellInfo -> Id , triggered_spell_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-06-07 12:49:06 +02:00
// Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
2009-06-07 13:14:08 +02:00
// Needed by freezing arrow and few other spells
2009-06-07 12:49:06 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER && m_spellInfo -> CategoryRecoveryTime && spellInfo -> CategoryRecoveryTime
&& m_spellInfo -> Category == spellInfo -> Category )
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> RemoveSpellCooldown ( spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2009-08-17 15:54:39 -05:00
// Note: not exist spells with weapon req. and IsSpellHaveCasterSourceTargets == true
// so this just for speedup places in else
2010-02-20 23:57:54 +01:00
Unit * caster = GetTriggeredSpellCaster ( spellInfo , m_caster , unitTarget );
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
caster -> CastSpell ( unitTarget , spellInfo , true , 0 , 0 , ( originalCaster ? originalCaster -> GetGUID () : 0 ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTriggerMissileSpell ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 triggered_spell_id = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// normal case
2010-04-07 22:59:46 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( triggered_spell_id );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "EffectTriggerMissileSpell of spell %u (eff: %u): triggering unknown spell id %u" ,
2011-04-29 20:47:02 +02:00
m_spellInfo -> Id , effIndex , triggered_spell_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( m_CastItem )
2010-12-23 23:25:44 +01:00
sLog -> outStaticDebug ( "WORLD: cast Item spellId - %i" , spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2009-06-07 12:49:06 +02:00
// Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
2009-06-07 13:14:08 +02:00
// Needed by freezing arrow and few other spells
2009-06-07 12:49:06 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER && m_spellInfo -> CategoryRecoveryTime && spellInfo -> CategoryRecoveryTime
&& m_spellInfo -> Category == spellInfo -> Category )
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> RemoveSpellCooldown ( spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2009-08-29 23:20:16 -05:00
float x , y , z ;
m_targets . m_dstPos . GetPosition ( x , y , z );
m_caster -> CastSpell ( x , y , z , spellInfo -> Id , true , m_CastItem , 0 , m_originalCasterGUID );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectJump ( SpellEffIndex effIndex )
2010-07-19 21:24:09 +02:00
{
if ( m_caster -> isInFlight ())
return ;
2011-05-12 10:41:25 +02:00
float x , y , z ;
2010-07-19 21:24:09 +02:00
if ( m_targets . getUnitTarget ())
2011-04-29 20:47:02 +02:00
m_targets . getUnitTarget () -> GetContactPoint ( m_caster , x , y , z , CONTACT_DISTANCE );
2010-07-19 21:24:09 +02:00
else if ( m_targets . getGOTarget ())
2011-04-29 20:47:02 +02:00
m_targets . getGOTarget () -> GetContactPoint ( m_caster , x , y , z , CONTACT_DISTANCE );
2010-07-19 21:24:09 +02:00
else
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectJump - unsupported target mode for spell ID %u" , m_spellInfo -> Id );
2010-07-19 21:24:09 +02:00
return ;
}
float speedXY , speedZ ;
2010-08-27 19:36:27 +02:00
CalculateJumpSpeeds ( effIndex , m_caster -> GetExactDist2d ( x , y ), speedXY , speedZ );
2010-07-19 21:24:09 +02:00
m_caster -> GetMotionMaster () -> MoveJump ( x , y , z , speedXY , speedZ );
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectJumpDest ( SpellEffIndex effIndex )
2009-03-12 14:50:14 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> isInFlight ())
2009-03-12 14:50:14 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-12 14:50:14 -06:00
// Init dest coordinates
2011-05-12 10:41:25 +02:00
float x , y , z ;
2010-04-07 19:14:10 +02:00
if ( m_targets . HasDst ())
2009-03-12 14:50:14 -06:00
{
2009-08-29 23:20:16 -05:00
m_targets . m_dstPos . GetPosition ( x , y , z );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> EffectImplicitTargetA [ effIndex ] == TARGET_DEST_TARGET_BACK )
2009-03-13 18:28:10 -06:00
{
// explicit cast data from client or server-side cast
// some spell at client send caster
Unit * pTarget = NULL ;
2010-04-08 08:20:08 +02:00
if ( m_targets . getUnitTarget () && m_targets . getUnitTarget () != m_caster )
2009-03-13 18:28:10 -06:00
pTarget = m_targets . getUnitTarget ();
2010-04-07 19:14:10 +02:00
else if ( m_caster -> getVictim ())
2009-03-13 18:28:10 -06:00
pTarget = m_caster -> getVictim ();
2010-04-07 19:14:10 +02:00
else if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
pTarget = ObjectAccessor :: GetUnit ( * m_caster , m_caster -> ToPlayer () -> GetSelection ());
2009-10-17 15:51:44 -07:00
2009-03-13 18:28:10 -06:00
}
2009-03-12 14:50:14 -06:00
}
else
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectJumpDest - unsupported target mode for spell ID %u" , m_spellInfo -> Id );
2009-03-13 18:28:10 -06:00
return ;
2009-03-12 14:50:14 -06:00
}
2009-10-17 15:51:44 -07:00
2010-07-19 21:24:09 +02:00
float speedXY , speedZ ;
2010-08-27 19:36:27 +02:00
CalculateJumpSpeeds ( effIndex , m_caster -> GetExactDist2d ( x , y ), speedXY , speedZ );
2010-07-19 21:24:09 +02:00
m_caster -> GetMotionMaster () -> MoveJump ( x , y , z , speedXY , speedZ );
}
void Spell :: CalculateJumpSpeeds ( uint8 i , float dist , float & speedXY , float & speedZ )
{
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> EffectMiscValue [ i ])
2009-04-11 22:41:15 -05:00
speedZ = float ( m_spellInfo -> EffectMiscValue [ i ]) / 10 ;
2010-04-07 19:14:10 +02:00
else if ( m_spellInfo -> EffectMiscValueB [ i ])
2009-04-11 22:41:15 -05:00
speedZ = float ( m_spellInfo -> EffectMiscValueB [ i ]) / 10 ;
else
speedZ = 10.0f ;
2010-07-19 21:24:09 +02:00
speedXY = dist * 10.0f / speedZ ;
2009-03-12 14:50:14 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTeleportUnits ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-10-30 18:54:38 -07:00
if ( ! unitTarget || unitTarget -> isInFlight ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-06-20 04:34:58 +02:00
// Pre effects
uint8 uiMaxSafeLevel = 0 ;
switch ( m_spellInfo -> Id )
{
case 48129 : // Scroll of Recall
uiMaxSafeLevel = 40 ;
case 60320 : // Scroll of Recall II
if ( ! uiMaxSafeLevel )
uiMaxSafeLevel = 70 ;
case 60321 : // Scroll of Recal III
if ( ! uiMaxSafeLevel )
uiMaxSafeLevel = 80 ;
2010-08-08 19:45:53 +02:00
2010-06-20 04:34:58 +02:00
if ( unitTarget -> getLevel () > uiMaxSafeLevel )
{
2011-04-29 20:47:02 +02:00
unitTarget -> AddAura ( 60444 , unitTarget ); //Apply Lost! Aura
2010-06-20 04:34:58 +02:00
return ;
}
break ;
2011-01-09 00:00:08 -03:00
case 66550 : // teleports outside (Isle of Conquest)
if ( Player * pTarget = unitTarget -> ToPlayer ())
{
if ( pTarget -> GetTeamId () == TEAM_ALLIANCE )
2011-04-29 20:47:02 +02:00
m_targets . setDst ( 442.24f , - 835.25f , 44.30f , 0.06f , 628 );
2011-01-09 00:00:08 -03:00
else
2011-04-29 20:47:02 +02:00
m_targets . setDst ( 1120.43f , - 762.11f , 47.92f , 2.94f , 628 );
2011-01-09 00:00:08 -03:00
}
break ;
case 66551 : // teleports inside (Isle of Conquest)
if ( Player * pTarget = unitTarget -> ToPlayer ())
{
if ( pTarget -> GetTeamId () == TEAM_ALLIANCE )
2011-04-29 20:47:02 +02:00
m_targets . setDst ( 389.57f , - 832.38f , 48.65f , 3.00f , 628 );
2011-01-09 00:00:08 -03:00
else
2011-04-29 20:47:02 +02:00
m_targets . setDst ( 1174.85f , - 763.24f , 48.72f , 6.26f , 628 );
2011-01-09 00:00:08 -03:00
}
break ;
2010-06-20 04:34:58 +02:00
}
2008-11-01 15:08:12 -05:00
// If not exist data for dest location - return
2009-10-30 18:54:38 -07:00
if ( ! m_targets . HasDst ())
2008-11-01 15:08:12 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectTeleportUnits - does not have destination for spell ID %u \n " , m_spellInfo -> Id );
2009-03-09 19:17:12 -06:00
return ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-09 19:17:12 -06:00
// Init dest coordinates
2009-08-29 23:20:16 -05:00
uint32 mapid = m_targets . m_dstPos . GetMapId ();
2009-11-07 18:47:11 +01:00
if ( mapid == MAPID_INVALID )
2009-10-30 18:54:38 -07:00
mapid = unitTarget -> GetMapId ();
2009-11-07 18:47:11 +01:00
float x , y , z , orientation ;
m_targets . m_dstPos . GetPosition ( x , y , z , orientation );
if ( ! orientation && m_targets . getUnitTarget ())
orientation = m_targets . getUnitTarget () -> GetOrientation ();
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell::EffectTeleportUnits - teleport unit to %u %f %f %f %f \n " , mapid , x , y , z , orientation );
2009-10-17 15:51:44 -07:00
2009-11-07 18:47:11 +01:00
if ( mapid == unitTarget -> GetMapId ())
2009-03-13 18:28:10 -06:00
unitTarget -> NearTeleportTo ( x , y , z , orientation , unitTarget == m_caster );
2010-04-07 19:14:10 +02:00
else if ( unitTarget -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> TeleportTo ( mapid , x , y , z , orientation , unitTarget == m_caster ? TELE_TO_SPELL : 0 );
2009-10-17 15:51:44 -07:00
2009-05-02 11:28:11 -05:00
// post effects for TARGET_DST_DB
2009-10-30 18:54:38 -07:00
switch ( m_spellInfo -> Id )
2008-10-11 14:16:25 -05:00
{
// Dimensional Ripper - Everlook
case 23442 :
{
int32 r = irand ( 0 , 119 );
2010-04-07 22:59:46 +02:00
if ( r >= 70 ) // 7/12 success
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( r < 100 ) // 4/12 evil twin
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23445 , true );
2008-10-11 14:16:25 -05:00
else // 1/12 fire
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23449 , true );
2008-10-11 14:16:25 -05:00
}
return ;
}
// Ultrasafe Transporter: Toshley's Station
case 36941 :
{
2010-04-07 22:59:46 +02:00
if ( roll_chance_i ( 50 )) // 50% success
2008-10-11 14:16:25 -05:00
{
2009-05-31 15:56:51 -05:00
int32 rand_eff = urand ( 1 , 7 );
2010-04-07 22:59:46 +02:00
switch ( rand_eff )
2008-10-11 14:16:25 -05:00
{
case 1 :
// soul split - evil
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36900 , true );
2008-10-11 14:16:25 -05:00
break ;
case 2 :
// soul split - good
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36901 , true );
2008-10-11 14:16:25 -05:00
break ;
case 3 :
// Increase the size
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36895 , true );
2008-10-11 14:16:25 -05:00
break ;
case 4 :
// Decrease the size
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36893 , true );
2008-10-11 14:16:25 -05:00
break ;
case 5 :
// Transform
{
2010-04-07 22:59:46 +02:00
if ( m_caster -> ToPlayer () -> GetTeam () == ALLIANCE )
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36897 , true );
2008-10-11 14:16:25 -05:00
else
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36899 , true );
2008-10-11 14:16:25 -05:00
break ;
}
case 6 :
// chicken
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36940 , true );
2008-10-11 14:16:25 -05:00
break ;
case 7 :
// evil twin
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 23445 , true );
2008-10-11 14:16:25 -05:00
break ;
}
}
return ;
}
// Dimensional Ripper - Area 52
case 36890 :
{
2010-04-07 22:59:46 +02:00
if ( roll_chance_i ( 50 )) // 50% success
2008-10-11 14:16:25 -05:00
{
2009-05-31 15:56:51 -05:00
int32 rand_eff = urand ( 1 , 4 );
2010-04-07 22:59:46 +02:00
switch ( rand_eff )
2008-10-11 14:16:25 -05:00
{
case 1 :
// soul split - evil
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36900 , true );
2008-10-11 14:16:25 -05:00
break ;
case 2 :
// soul split - good
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36901 , true );
2008-10-11 14:16:25 -05:00
break ;
case 3 :
// Increase the size
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36895 , true );
2008-10-11 14:16:25 -05:00
break ;
case 4 :
2010-10-04 20:32:10 +02:00
// Transform
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( m_caster -> ToPlayer () -> GetTeam () == ALLIANCE )
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36897 , true );
2008-10-11 14:16:25 -05:00
else
2009-05-31 15:56:51 -05:00
m_caster -> CastSpell ( m_caster , 36899 , true );
2008-10-11 14:16:25 -05:00
break ;
}
}
}
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectApplyAura ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-02-07 18:16:53 +01:00
if ( ! m_spellAura || ! unitTarget )
2010-01-10 01:23:15 +01:00
return ;
2010-07-30 20:04:28 +02:00
ASSERT ( unitTarget == m_spellAura -> GetOwner ());
2010-08-27 19:36:27 +02:00
m_spellAura -> _ApplyEffectForTargets ( effIndex );
2009-05-02 17:43:41 +02:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectApplyAreaAura ( SpellEffIndex effIndex )
2009-05-02 17:43:41 +02:00
{
2010-02-07 18:16:53 +01:00
if ( ! m_spellAura || ! unitTarget )
2010-01-10 01:23:15 +01:00
return ;
2010-07-30 20:04:28 +02:00
ASSERT ( unitTarget == m_spellAura -> GetOwner ());
2010-08-27 19:36:27 +02:00
m_spellAura -> _ApplyEffectForTargets ( effIndex );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectUnlearnSpecialization ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * _player = ( Player * ) unitTarget ;
2010-08-27 19:36:27 +02:00
uint32 spellToUnlearn = m_spellInfo -> EffectTriggerSpell [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
_player -> removeSpell ( spellToUnlearn );
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell: Player %u has unlearned spell %u from NpcGUID: %u" , _player -> GetGUIDLow (), spellToUnlearn , m_caster -> GetGUIDLow ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPowerDrain ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-30 15:25:15 +02:00
if ( m_spellInfo -> EffectMiscValue [ effIndex ] < 0 || m_spellInfo -> EffectMiscValue [ effIndex ] >= int8 ( MAX_POWERS ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
Powers powerType = Powers ( m_spellInfo -> EffectMiscValue [ effIndex ]);
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || unitTarget -> getPowerType () != powerType || damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
// add spell damage bonus
damage = m_caster -> SpellDamageBonus ( unitTarget , m_spellInfo , uint32 ( damage ), SPELL_DIRECT_DAMAGE );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
2010-08-27 20:51:29 +02:00
int32 power = damage ;
2010-08-26 19:07:55 +02:00
if ( powerType == POWER_MANA )
2009-12-19 18:46:51 +01:00
power -= unitTarget -> GetSpellCritDamageReduction ( power );
2009-10-17 15:51:44 -07:00
2010-08-27 20:51:29 +02:00
int32 newDamage = - ( unitTarget -> ModifyPower ( powerType , - int32 ( power )));
2009-10-17 15:51:44 -07:00
2010-08-27 17:49:32 +02:00
float gainMultiplier = 0.0f ;
2009-01-09 16:06:17 -06:00
// Don`t restore from self drain
2010-08-26 19:07:55 +02:00
if ( m_caster != unitTarget )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
gainMultiplier = SpellMgr :: CalculateSpellEffectValueMultiplier ( m_spellInfo , effIndex , m_originalCaster , this );
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
int32 gain = int32 ( newDamage * gainMultiplier );
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
m_caster -> EnergizeBySpell ( m_caster , m_spellInfo -> Id , gain , powerType );
2008-10-11 14:16:25 -05:00
}
2010-08-27 19:36:27 +02:00
ExecuteLogEffectTakeTargetPower ( effIndex , unitTarget , powerType , newDamage , gainMultiplier );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSendEvent ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-03-24 09:37:45 -06:00
/*
we do not handle a flag dropping or clicking on flag in battleground by sendevent system
*/
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell ScriptStart %u for spellid %u in EffectSendEvent " , m_spellInfo -> EffectMiscValue [ effIndex ], m_spellInfo -> Id );
2010-01-21 23:57:14 +01:00
Object * pTarget ;
if ( focusObject )
pTarget = focusObject ;
else if ( unitTarget )
pTarget = unitTarget ;
else if ( gameObjTarget )
pTarget = gameObjTarget ;
else
pTarget = NULL ;
2011-01-20 12:27:08 -03:00
if ( unitTarget )
{
if ( ZoneScript * zoneScript = unitTarget -> GetZoneScript ())
zoneScript -> ProcessEvent ( unitTarget , m_spellInfo -> EffectMiscValue [ effIndex ]);
}
2010-08-27 19:36:27 +02:00
m_caster -> GetMap () -> ScriptsStart ( sEventScripts , m_spellInfo -> EffectMiscValue [ effIndex ], m_caster , pTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPowerBurn ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-30 15:25:15 +02:00
if ( m_spellInfo -> EffectMiscValue [ effIndex ] < 0 || m_spellInfo -> EffectMiscValue [ effIndex ] >= int8 ( MAX_POWERS ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
Powers powerType = Powers ( m_spellInfo -> EffectMiscValue [ effIndex ]);
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || unitTarget -> getPowerType () != powerType || damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-04-03 16:33:25 -06:00
// burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> ManaCostPercentage )
2009-04-03 16:33:25 -06:00
{
2010-12-11 20:37:38 +06:00
int32 maxDamage = int32 ( CalculatePctN ( m_caster -> GetMaxPower ( powerType ), damage * 2 ));
damage = int32 ( CalculatePctN ( unitTarget -> GetMaxPower ( powerType ), damage ));
2010-08-27 20:51:29 +02:00
damage = std :: min ( damage , maxDamage );
2009-04-03 16:33:25 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-26 15:54:56 +06:00
int32 power = damage ;
2009-03-01 14:38:26 +01:00
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
2010-08-26 19:07:55 +02:00
if ( powerType == POWER_MANA )
2009-12-19 18:46:51 +01:00
power -= unitTarget -> GetSpellCritDamageReduction ( power );
2009-10-17 15:51:44 -07:00
2010-08-27 20:51:29 +02:00
int32 newDamage = - ( unitTarget -> ModifyPower ( powerType , - power ));
2009-10-17 15:51:44 -07:00
2010-08-26 19:07:55 +02:00
// NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
2010-08-27 19:36:27 +02:00
float dmgMultiplier = SpellMgr :: CalculateSpellEffectValueMultiplier ( m_spellInfo , effIndex , m_originalCaster , this );
2009-10-17 15:51:44 -07:00
2010-09-25 15:03:48 +02:00
// add log data before multiplication (need power amount, not damage)
ExecuteLogEffectTakeTargetPower ( effIndex , unitTarget , powerType , newDamage , 0.0f );
2009-10-17 15:51:44 -07:00
2010-09-25 15:03:48 +02:00
newDamage = int32 ( newDamage * dmgMultiplier );
2010-08-27 17:49:32 +02:00
2010-08-29 05:26:32 +02:00
m_damage += newDamage ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectHeal ( SpellEffIndex /*effIndex*/ )
2008-12-25 17:39:46 -06:00
{
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: SpellDamageHeal ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( unitTarget && unitTarget -> isAlive () && damage >= 0 )
2008-10-11 14:16:25 -05:00
{
// Try to get original caster
Unit * caster = m_originalCasterGUID ? m_originalCaster : m_caster ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Skip if m_originalCaster not available
if ( ! caster )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 addhealth = damage ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Vessel of the Naaru (Vial of the Sunwell trinket)
if ( m_spellInfo -> Id == 45064 )
{
// Amount of heal - depends from stacked Holy Energy
int damageAmount = 0 ;
2009-08-08 16:18:05 +02:00
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( 45062 , 0 ))
{
damageAmount += aurEff -> GetAmount ();
2008-10-11 14:16:25 -05:00
m_caster -> RemoveAurasDueToSpell ( 45062 );
2009-08-08 16:18:05 +02:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
addhealth += damageAmount ;
}
// Swiftmend - consumes Regrowth or Rejuvenation
2009-03-18 19:53:36 +01:00
else if ( m_spellInfo -> TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget -> HasAuraState ( AURA_STATE_SWIFTMEND , m_spellInfo , m_caster ))
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & RejorRegr = unitTarget -> GetAuraEffectsByType ( SPELL_AURA_PERIODIC_HEAL );
2008-10-11 14:16:25 -05:00
// find most short by duration
2009-04-06 13:31:14 +02:00
AuraEffect * targetAura = NULL ;
2009-10-17 16:20:24 -07:00
for ( Unit :: AuraEffectList :: const_iterator i = RejorRegr . begin (); i != RejorRegr . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if (( * i ) -> GetSpellProto () -> SpellFamilyName == SPELLFAMILY_DRUID
2009-08-08 16:18:05 +02:00
&& ( * i ) -> GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x50 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! targetAura || ( * i ) -> GetBase () -> GetDuration () < targetAura -> GetBase () -> GetDuration ())
2008-10-11 14:16:25 -05:00
targetAura = * i ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! targetAura )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Target(GUID:" UI64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura." , unitTarget -> GetGUID ());
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-04-06 13:31:14 +02:00
int32 tickheal = targetAura -> GetAmount ();
2010-04-07 19:14:10 +02:00
if ( Unit * auraCaster = targetAura -> GetCaster ())
2009-01-29 19:33:39 -06:00
tickheal = auraCaster -> SpellHealingBonus ( unitTarget , targetAura -> GetSpellProto (), tickheal , DOT );
2008-12-13 10:12:22 -06:00
//int32 tickheal = targetAura->GetSpellProto()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
2009-10-17 15:51:44 -07:00
2009-03-01 21:51:38 +01:00
int32 tickcount = 0 ;
2009-08-08 16:18:05 +02:00
// Rejuvenation
if ( targetAura -> GetSpellProto () -> SpellFamilyFlags [ 0 ] & 0x10 )
tickcount = 4 ;
// Regrowth
else // if (targetAura->GetSpellProto()->SpellFamilyFlags[0] & 0x40)
tickcount = 6 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
addhealth += tickheal * tickcount ;
2009-10-17 15:51:44 -07:00
2009-04-06 18:00:16 +02:00
// Glyph of Swiftmend
2010-04-07 19:14:10 +02:00
if ( ! caster -> HasAura ( 54824 ))
2009-04-06 18:00:16 +02:00
unitTarget -> RemoveAura ( targetAura -> GetId (), targetAura -> GetCasterGUID ());
2009-10-17 15:51:44 -07:00
2008-12-13 10:12:22 -06:00
//addhealth += tickheal * tickcount;
2011-04-29 20:47:02 +02:00
//addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
2008-10-11 14:16:25 -05:00
}
2009-12-17 13:07:38 +01:00
// Glyph of Nourish
else if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x2000000 )
{
addhealth = caster -> SpellHealingBonus ( unitTarget , m_spellInfo , addhealth , HEAL );
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( 62971 , 0 ))
{
2010-01-10 01:23:15 +01:00
Unit :: AuraEffectList const & Periodic = unitTarget -> GetAuraEffectsByType ( SPELL_AURA_PERIODIC_HEAL );
2009-12-17 13:07:38 +01:00
for ( Unit :: AuraEffectList :: const_iterator i = Periodic . begin (); i != Periodic . end (); ++ i )
{
if ( m_caster -> GetGUID () == ( * i ) -> GetCasterGUID ())
2010-12-11 20:37:38 +06:00
AddPctN ( addhealth , aurEff -> GetAmount ());
2009-12-17 13:07:38 +01:00
}
}
}
2010-07-28 12:57:00 +02:00
// Lifebloom - final heal coef multiplied by original DoT stack
else if ( m_spellInfo -> Id == 33778 )
addhealth = caster -> SpellHealingBonus ( unitTarget , m_spellInfo , addhealth , HEAL , m_spellValue -> EffectBasePoints [ 1 ]);
2009-04-10 16:59:34 +02:00
// Riptide - increase healing done by Chain Heal
2010-04-07 23:25:02 +02:00
else if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x100 )
2009-04-10 16:59:34 +02:00
{
2009-04-20 12:38:35 +02:00
addhealth = caster -> SpellHealingBonus ( unitTarget , m_spellInfo , addhealth , HEAL );
2010-01-10 01:23:15 +01:00
if ( AuraEffect * aurEff = unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_HEAL , SPELLFAMILY_SHAMAN , 0 , 0 , 0x10 , m_originalCasterGUID ))
2009-04-10 16:59:34 +02:00
{
2010-08-22 12:39:39 -07:00
addhealth = int32 ( addhealth * 1.25f );
2009-04-10 16:59:34 +02:00
// consume aura
2010-01-10 01:23:15 +01:00
unitTarget -> RemoveAura ( aurEff -> GetBase ());
2009-04-10 16:59:34 +02:00
}
}
2009-06-22 23:30:17 +02:00
// Death Pact - return pct of max health to caster
else if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00080000 )
2010-08-26 01:20:57 +06:00
addhealth = caster -> SpellHealingBonus ( unitTarget , m_spellInfo , int32 ( caster -> CountPctFromMaxHealth ( damage )), HEAL );
2008-10-11 14:16:25 -05:00
else
2009-01-29 19:33:39 -06:00
addhealth = caster -> SpellHealingBonus ( unitTarget , m_spellInfo , addhealth , HEAL );
2009-10-17 15:51:44 -07:00
2010-06-20 00:37:02 +02:00
// Remove Grievious bite if fully healed
if ( unitTarget -> HasAura ( 48920 ) && ( unitTarget -> GetHealth () + addhealth >= unitTarget -> GetMaxHealth ()))
unitTarget -> RemoveAura ( 48920 );
2008-12-25 17:39:46 -06:00
m_damage -= addhealth ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectHealPct ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-08-28 23:01:04 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || damage < 0 )
return ;
2009-10-17 15:51:44 -07:00
2010-08-28 23:01:04 +02:00
// Skip if m_originalCaster not available
if ( ! m_originalCaster )
return ;
2009-10-17 15:51:44 -07:00
2010-08-28 23:01:04 +02:00
// Rune Tap - Party
if ( m_spellInfo -> Id == 59754 && unitTarget == m_caster )
return ;
2009-10-17 15:51:44 -07:00
2010-08-28 23:01:04 +02:00
m_healing += m_originalCaster -> SpellHealingBonus ( unitTarget , m_spellInfo , unitTarget -> CountPctFromMaxHealth ( damage ), HEAL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectHealMechanical ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-08-28 23:01:04 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || damage < 0 )
return ;
2009-10-17 15:51:44 -07:00
2010-08-28 23:01:04 +02:00
// Skip if m_originalCaster not available
if ( ! m_originalCaster )
return ;
2009-10-17 15:51:44 -07:00
2010-08-28 23:01:04 +02:00
m_healing += m_originalCaster -> SpellHealingBonus ( unitTarget , m_spellInfo , uint32 ( damage ), HEAL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectHealthLeech ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-26 19:07:55 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-05-10 22:28:28 +07:00
damage = m_caster -> SpellDamageBonus ( unitTarget , m_spellInfo , uint32 ( damage ), SPELL_DIRECT_DAMAGE );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "HealthLeech :%i" , damage );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
float healMultiplier = SpellMgr :: CalculateSpellEffectValueMultiplier ( m_spellInfo , effIndex , m_originalCaster , this );
2009-10-17 15:51:44 -07:00
2010-09-02 15:34:36 +02:00
m_damage += damage ;
// get max possible damage, don't count overkill for heal
uint32 healthGain = uint32 ( - unitTarget -> GetHealthGain ( - damage ) * healMultiplier );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( m_caster -> isAlive ())
2008-10-11 14:16:25 -05:00
{
2010-09-02 15:34:36 +02:00
healthGain = m_caster -> SpellHealingBonus ( m_caster , m_spellInfo , healthGain , HEAL );
m_caster -> HealBySpell ( m_caster , m_spellInfo , uint32 ( healthGain ));
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-19 09:26:37 +02:00
void Spell :: DoCreateItem ( uint32 /*i*/ , uint32 itemtype )
2008-10-11 14:16:25 -05:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 newitemid = itemtype ;
2011-04-28 22:42:33 +02:00
ItemTemplate const * pProto = sObjectMgr -> GetItemTemplate ( newitemid );
2010-04-07 19:14:10 +02:00
if ( ! pProto )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-12 20:36:55 -05:00
// bg reward have some special in code work
uint32 bgType = 0 ;
switch ( m_spellInfo -> Id )
{
case SPELL_AV_MARK_WINNER :
case SPELL_AV_MARK_LOSER :
bgType = BATTLEGROUND_AV ;
break ;
case SPELL_WS_MARK_WINNER :
case SPELL_WS_MARK_LOSER :
bgType = BATTLEGROUND_WS ;
break ;
case SPELL_AB_MARK_WINNER :
case SPELL_AB_MARK_LOSER :
bgType = BATTLEGROUND_AB ;
break ;
default :
break ;
}
2009-10-17 15:51:44 -07:00
2010-04-14 12:22:35 +04:00
uint32 num_to_add = damage ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( num_to_add < 1 )
num_to_add = 1 ;
2009-01-03 11:06:51 -06:00
if ( num_to_add > pProto -> GetMaxStackSize ())
num_to_add = pProto -> GetMaxStackSize ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// init items_count to 1, since 1 item will be created regardless of specialization
int items_count = 1 ;
// the chance to create additional items
float additionalCreateChance = 0.0f ;
// the maximum number of created additional items
uint8 additionalMaxNum = 0 ;
// get the chance and maximum number for creating extra items
2010-04-07 22:59:46 +02:00
if ( canCreateExtraItems ( player , m_spellInfo -> Id , additionalCreateChance , additionalMaxNum ))
2008-10-11 14:16:25 -05:00
{
// roll with this chance till we roll not to create or we create the max num
2010-04-07 23:56:35 +02:00
while ( roll_chance_f ( additionalCreateChance ) && items_count <= additionalMaxNum )
2008-10-11 14:16:25 -05:00
++ items_count ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// really will be created more items
num_to_add *= items_count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// can the player store the new item?
ItemPosCountVec dest ;
uint32 no_space = 0 ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = player -> CanStoreNewItem ( NULL_BAG , NULL_SLOT , dest , newitemid , num_to_add , & no_space );
2010-04-07 22:59:46 +02:00
if ( msg != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
// convert to possible store amount
2010-04-07 22:59:46 +02:00
if ( msg == EQUIP_ERR_INVENTORY_FULL || msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS )
2008-10-11 14:16:25 -05:00
num_to_add -= no_space ;
else
{
// if not created by another reason from full inventory or unique items amount limitation
2010-08-05 22:08:07 +06:00
player -> SendEquipError ( msg , NULL , NULL , newitemid );
2008-10-11 14:16:25 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( num_to_add )
2008-10-11 14:16:25 -05:00
{
// create the new item and store it
2010-04-07 22:59:46 +02:00
Item * pItem = player -> StoreNewItem ( dest , newitemid , true , Item :: GenerateItemRandomPropertyId ( newitemid ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// was it successful? return error if not
2010-04-07 19:14:10 +02:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// set the "Crafted by ..." property of the item
2011-04-28 22:42:33 +02:00
if ( pItem -> GetTemplate () -> Class != ITEM_CLASS_CONSUMABLE && pItem -> GetTemplate () -> Class != ITEM_CLASS_QUEST && newitemid != 6265 && newitemid != 6948 )
2009-05-31 15:56:51 -05:00
pItem -> SetUInt32Value ( ITEM_FIELD_CREATOR , player -> GetGUIDLow ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// send info to the client
2010-04-07 19:14:10 +02:00
if ( pItem )
2009-08-12 20:36:55 -05:00
player -> SendNewItem ( pItem , num_to_add , true , bgType == 0 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// we succeeded in creating at least one item, so a levelup is possible
2010-04-07 19:14:10 +02:00
if ( bgType == 0 )
2009-08-12 20:36:55 -05:00
player -> UpdateCraftSkill ( m_spellInfo -> Id );
}
2009-10-17 15:51:44 -07:00
2009-08-12 20:36:55 -05:00
/*
// for battleground marks send by mail if not add all expected
2010-04-07 19:14:10 +02:00
if (no_space > 0 && bgType)
2009-08-12 20:36:55 -05:00
{
2010-12-22 21:25:23 +01:00
if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BattlegroundTypeId(bgType)))
2009-08-12 20:36:55 -05:00
bg->SendRewardMarkByMail(player, newitemid, no_space);
2009-04-06 21:14:51 +02:00
}
2009-10-17 16:20:24 -07:00
*/
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectCreateItem ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
DoCreateItem ( effIndex , m_spellInfo -> EffectItemType [ effIndex ]);
2010-08-27 19:36:27 +02:00
ExecuteLogEffectCreateItem ( effIndex , m_spellInfo -> EffectItemType [ effIndex ]);
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectCreateItem2 ( SpellEffIndex effIndex )
2009-02-05 23:02:07 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-05-24 11:17:41 -05:00
return ;
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 item_id = m_spellInfo -> EffectItemType [ effIndex ];
2009-10-17 15:51:44 -07:00
2010-04-11 11:24:05 +04:00
if ( item_id )
2010-08-27 19:36:27 +02:00
DoCreateItem ( effIndex , item_id );
2009-10-17 15:51:44 -07:00
2009-05-24 11:17:41 -05:00
// special case: fake item replaced by generate using spell_loot_template
2010-04-07 19:14:10 +02:00
if ( IsLootCraftingSpell ( m_spellInfo ))
2009-02-05 23:02:07 -06:00
{
2010-04-11 11:24:05 +04:00
if ( item_id )
{
if ( ! player -> HasItemCount ( item_id , 1 ))
return ;
2009-10-17 15:51:44 -07:00
2010-04-11 11:24:05 +04:00
// remove reagent
uint32 count = 1 ;
player -> DestroyItemCount ( item_id , count , true );
2009-10-17 15:51:44 -07:00
2010-04-11 11:24:05 +04:00
// create some random items
player -> AutoStoreLoot ( m_spellInfo -> Id , LootTemplates_Spell );
2010-06-16 20:10:42 +02:00
}
else
player -> AutoStoreLoot ( m_spellInfo -> Id , LootTemplates_Spell ); // create some random items
2009-02-05 23:02:07 -06:00
}
2010-08-27 17:49:32 +02:00
// TODO: ExecuteLogEffectCreateItem(i, m_spellInfo->EffectItemType[i]);
2009-02-05 23:02:07 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectCreateRandomItem ( SpellEffIndex /*effIndex*/ )
2009-06-23 14:44:16 +02:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-06-23 14:44:16 +02:00
return ;
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2009-06-23 14:44:16 +02:00
// create some random items
player -> AutoStoreLoot ( m_spellInfo -> Id , LootTemplates_Spell );
2010-08-27 17:49:32 +02:00
// TODO: ExecuteLogEffectCreateItem(i, m_spellInfo->EffectItemType[i]);
2009-06-23 14:44:16 +02:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPersistentAA ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
if ( ! m_spellAura )
2009-08-27 16:41:10 -05:00
{
2010-08-27 19:36:27 +02:00
float radius = GetSpellRadiusForFriend ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2010-04-07 19:14:10 +02:00
if ( Player * modOwner = m_originalCaster -> GetSpellModOwner ())
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( m_spellInfo -> Id , SPELLMOD_RADIUS , radius );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
Unit * caster = m_caster -> GetEntry () == WORLD_TRIGGER ? m_originalCaster : m_caster ;
2010-01-24 23:47:17 +01:00
// Caster not in world, might be spell triggered from aura removal
if ( ! caster -> IsInWorld ())
return ;
2011-04-19 15:14:50 +02:00
DynamicObject * dynObj = new DynamicObject ();
if ( ! dynObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_DYNAMICOBJECT ), caster , m_spellInfo -> Id , m_targets . m_dstPos , radius , false , DYNAMIC_OBJECT_AREA_SPELL ))
2010-01-10 01:23:15 +01:00
{
delete dynObj ;
return ;
}
2011-04-19 15:14:50 +02:00
2010-01-10 01:23:15 +01:00
dynObj -> GetMap () -> Add ( dynObj );
2009-10-17 15:51:44 -07:00
2011-04-19 15:14:50 +02:00
if ( Aura * aura = Aura :: TryCreate ( m_spellInfo , dynObj , caster , & m_spellValue -> EffectBasePoints [ 0 ]))
2011-02-04 00:27:43 +01:00
{
2010-01-10 01:23:15 +01:00
m_spellAura = aura ;
2011-02-04 00:27:43 +01:00
m_spellAura -> _RegisterForTargets ();
}
2010-01-10 01:23:15 +01:00
else
return ;
2008-10-11 14:16:25 -05:00
}
2011-04-19 15:14:50 +02:00
2010-07-30 20:04:28 +02:00
ASSERT ( m_spellAura -> GetDynobjOwner ());
2010-08-27 19:36:27 +02:00
m_spellAura -> _ApplyEffectForTargets ( effIndex );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnergize ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-30 15:25:15 +02:00
if ( m_spellInfo -> EffectMiscValue [ effIndex ] < 0 || m_spellInfo -> EffectMiscValue [ effIndex ] >= int8 ( MAX_POWERS ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
Powers power = Powers ( m_spellInfo -> EffectMiscValue [ effIndex ]);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Some level depends spells
2009-07-31 11:16:38 +08:00
int level_multiplier = 0 ;
2008-10-11 14:16:25 -05:00
int level_diff = 0 ;
switch ( m_spellInfo -> Id )
{
2009-07-31 11:16:38 +08:00
case 9512 : // Restore Energy
2008-10-11 14:16:25 -05:00
level_diff = m_caster -> getLevel () - 40 ;
2009-07-31 11:16:38 +08:00
level_multiplier = 2 ;
2008-10-11 14:16:25 -05:00
break ;
2009-07-31 11:16:38 +08:00
case 24571 : // Blood Fury
2008-10-11 14:16:25 -05:00
level_diff = m_caster -> getLevel () - 60 ;
2009-07-31 11:16:38 +08:00
level_multiplier = 10 ;
2008-10-11 14:16:25 -05:00
break ;
2009-07-31 11:16:38 +08:00
case 24532 : // Burst of Energy
2008-10-11 14:16:25 -05:00
level_diff = m_caster -> getLevel () - 60 ;
2009-07-31 11:16:38 +08:00
level_multiplier = 4 ;
2008-10-11 14:16:25 -05:00
break ;
2009-07-31 11:16:38 +08:00
case 31930 : // Judgements of the Wise
case 63375 : // Improved Stormstrike
2009-12-18 11:28:12 +02:00
case 68082 : // Glyph of Seal of Command
2010-12-11 20:37:38 +06:00
damage = int32 ( CalculatePctN ( unitTarget -> GetCreateMana (), damage ));
2009-08-13 14:36:50 +02:00
break ;
2009-08-11 19:57:27 +02:00
case 48542 : // Revitalize
2010-12-11 20:37:38 +06:00
damage = int32 ( CalculatePctN ( unitTarget -> GetMaxPower ( power ), damage ));
2009-08-11 19:57:27 +02:00
break ;
2011-03-07 19:15:00 +01:00
case 71132 : // Glyph of Shadow Word: Pain
damage = int32 ( CalculatePctN ( unitTarget -> GetCreateMana (), 1 )); // set 1 as value, missing in dbc
break ;
2008-10-11 14:16:25 -05:00
default :
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( level_diff > 0 )
2009-07-31 11:16:38 +08:00
damage -= level_multiplier * level_diff ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetMaxPower ( power ) == 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-06-14 10:16:55 -05:00
m_caster -> EnergizeBySpell ( unitTarget , m_spellInfo -> Id , damage , power );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Mad Alchemist's Potion
2010-02-15 18:23:39 +01:00
if ( m_spellInfo -> Id == 45051 )
2008-10-11 14:16:25 -05:00
{
// find elixirs on target
2010-02-01 19:22:32 +01:00
bool guardianFound = false ;
bool battleFound = false ;
2010-01-10 01:23:15 +01:00
Unit :: AuraApplicationMap & Auras = unitTarget -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator itr = Auras . begin (); itr != Auras . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
uint32 spell_id = itr -> second -> GetBase () -> GetId ();
2010-02-01 19:22:32 +01:00
if ( ! guardianFound )
2010-12-22 21:25:23 +01:00
if ( sSpellMgr -> IsSpellMemberOfSpellGroup ( spell_id , SPELL_GROUP_ELIXIR_GUARDIAN ))
2010-02-01 19:22:32 +01:00
guardianFound = true ;
if ( ! battleFound )
2010-12-22 21:25:23 +01:00
if ( sSpellMgr -> IsSpellMemberOfSpellGroup ( spell_id , SPELL_GROUP_ELIXIR_BATTLE ))
2010-02-01 19:22:32 +01:00
battleFound = true ;
if ( battleFound && guardianFound )
break ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// get all available elixirs by mask and spell level
2010-02-02 22:35:01 +01:00
std :: set < uint32 > avalibleElixirs ;
2010-02-01 19:22:32 +01:00
if ( ! guardianFound )
2010-12-22 21:25:23 +01:00
sSpellMgr -> GetSetOfSpellsInSpellGroup ( SPELL_GROUP_ELIXIR_GUARDIAN , avalibleElixirs );
2010-02-01 19:22:32 +01:00
if ( ! battleFound )
2010-12-22 21:25:23 +01:00
sSpellMgr -> GetSetOfSpellsInSpellGroup ( SPELL_GROUP_ELIXIR_BATTLE , avalibleElixirs );
2010-02-02 22:35:01 +01:00
for ( std :: set < uint32 >:: iterator itr = avalibleElixirs . begin (); itr != avalibleElixirs . end () ;)
2010-02-01 19:22:32 +01:00
{
2010-02-02 22:35:01 +01:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( * itr );
if ( spellInfo -> spellLevel < m_spellInfo -> spellLevel || spellInfo -> spellLevel > unitTarget -> getLevel ())
avalibleElixirs . erase ( itr ++ );
2010-12-22 21:25:23 +01:00
else if ( sSpellMgr -> IsSpellMemberOfSpellGroup ( * itr , SPELL_GROUP_ELIXIR_SHATTRATH ))
2010-02-02 22:35:01 +01:00
avalibleElixirs . erase ( itr ++ );
2010-12-22 21:25:23 +01:00
else if ( sSpellMgr -> IsSpellMemberOfSpellGroup ( * itr , SPELL_GROUP_ELIXIR_UNSTABLE ))
2010-02-02 22:35:01 +01:00
avalibleElixirs . erase ( itr ++ );
else
++ itr ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-01 19:22:32 +01:00
if ( ! avalibleElixirs . empty ())
2008-10-11 14:16:25 -05:00
{
// cast random elixir on target
2011-04-29 20:47:02 +02:00
uint32 rand_spell = urand ( 0 , avalibleElixirs . size () - 1 );
2010-02-02 22:35:01 +01:00
std :: set < uint32 >:: iterator itr = avalibleElixirs . begin ();
2010-02-01 19:22:32 +01:00
std :: advance ( itr , rand_spell );
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( unitTarget , * itr , true , m_CastItem );
2008-10-11 14:16:25 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnergizePct ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-30 15:25:15 +02:00
if ( m_spellInfo -> EffectMiscValue [ effIndex ] < 0 || m_spellInfo -> EffectMiscValue [ effIndex ] >= int8 ( MAX_POWERS ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
Powers power = Powers ( m_spellInfo -> EffectMiscValue [ effIndex ]);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 maxPower = unitTarget -> GetMaxPower ( power );
2010-04-07 19:14:10 +02:00
if ( maxPower == 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-11 20:37:38 +06:00
uint32 gain = CalculatePctN ( maxPower , damage );
2009-06-14 10:16:55 -05:00
m_caster -> EnergizeBySpell ( unitTarget , m_spellInfo -> Id , gain , power );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Spell :: SendLoot ( uint64 guid , LootType loottype )
{
2010-12-26 16:35:29 +01:00
Player * player = m_caster -> ToPlayer ();
2008-10-11 14:16:25 -05:00
if ( ! player )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( gameObjTarget )
{
2011-01-18 20:02:28 +01:00
// Players shouldn't be able to loot gameobjects that are currently despawned
2011-01-20 03:06:51 +01:00
if ( ! gameObjTarget -> isSpawned () && ! player -> isGameMaster ())
2011-01-18 20:02:28 +01:00
{
sLog -> outError ( "Possible hacking attempt: Player %s [guid: %u] tried to loot a gameobject [entry: %u id: %u] which is on respawn time without being in GM mode!" ,
player -> GetName (), player -> GetGUIDLow (), gameObjTarget -> GetEntry (), gameObjTarget -> GetGUIDLow ());
return ;
}
2010-12-26 16:35:29 +01:00
// special case, already has GossipHello inside so return and avoid calling twice
if ( gameObjTarget -> GetGoType () == GAMEOBJECT_TYPE_GOOBER )
{
gameObjTarget -> Use ( m_caster );
return ;
}
2010-12-22 21:25:23 +01:00
if ( sScriptMgr -> OnGossipHello ( player , gameObjTarget ))
2008-12-06 14:01:44 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-27 21:01:47 +02:00
gameObjTarget -> AI () -> GossipHello ( player );
2008-10-11 14:16:25 -05:00
switch ( gameObjTarget -> GetGoType ())
{
case GAMEOBJECT_TYPE_DOOR :
case GAMEOBJECT_TYPE_BUTTON :
gameObjTarget -> UseDoorOrButton ();
2009-07-31 10:48:34 +08:00
player -> GetMap () -> ScriptsStart ( sGameObjectScripts , gameObjTarget -> GetDBTableGUIDLow (), player , gameObjTarget );
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case GAMEOBJECT_TYPE_QUESTGIVER :
// start or end quest
player -> PrepareQuestMenu ( guid );
player -> SendPreparedQuest ( guid );
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case GAMEOBJECT_TYPE_SPELL_FOCUS :
// triggering linked GO
2010-04-07 19:14:10 +02:00
if ( uint32 trapEntry = gameObjTarget -> GetGOInfo () -> spellFocus . linkedTrapId )
2011-04-29 20:47:02 +02:00
gameObjTarget -> TriggeringLinkedGameObject ( trapEntry , m_caster );
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case GAMEOBJECT_TYPE_CHEST :
// TODO: possible must be moved to loot release (in different from linked triggering)
if ( gameObjTarget -> GetGOInfo () -> chest . eventId )
{
2011-04-29 20:47:02 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Chest ScriptStart id %u for GO %u" , gameObjTarget -> GetGOInfo () -> chest . eventId , gameObjTarget -> GetDBTableGUIDLow ());
2009-07-31 10:48:34 +08:00
player -> GetMap () -> ScriptsStart ( sEventScripts , gameObjTarget -> GetGOInfo () -> chest . eventId , player , gameObjTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// triggering linked GO
2010-04-07 19:14:10 +02:00
if ( uint32 trapEntry = gameObjTarget -> GetGOInfo () -> chest . linkedTrapId )
2011-04-29 20:47:02 +02:00
gameObjTarget -> TriggeringLinkedGameObject ( trapEntry , m_caster );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Don't return, let loots been taken
2009-05-03 22:21:46 -05:00
default :
break ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Send loot
player -> SendLoot ( guid , loottype );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectOpenLock ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-12-22 20:18:34 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "WORLD: Open Lock - No Player Caster!" );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 lockId = 0 ;
uint64 guid = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Get lockId
2010-04-07 19:14:10 +02:00
if ( gameObjTarget )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * goInfo = gameObjTarget -> GetGOInfo ();
2008-10-11 14:16:25 -05:00
// Arathi Basin banner opening !
2010-08-30 15:25:15 +02:00
if (( goInfo -> type == GAMEOBJECT_TYPE_BUTTON && goInfo -> button . noDamageImmune ) ||
( goInfo -> type == GAMEOBJECT_TYPE_GOOBER && goInfo -> goober . losOK ))
2008-10-11 14:16:25 -05:00
{
2010-08-08 04:37:24 +02:00
//CanUseBattlegroundObject() already called in CheckCast()
2008-10-11 14:16:25 -05:00
// in battleground check
2010-08-08 04:37:24 +02:00
if ( Battleground * bg = player -> GetBattleground ())
2010-02-20 23:57:54 +01:00
{
bg -> EventPlayerClickedOnFlag ( player , gameObjTarget );
return ;
}
2008-10-11 14:16:25 -05:00
}
else if ( goInfo -> type == GAMEOBJECT_TYPE_FLAGSTAND )
{
2010-08-08 04:37:24 +02:00
//CanUseBattlegroundObject() already called in CheckCast()
2008-10-11 14:16:25 -05:00
// in battleground check
2010-08-08 04:37:24 +02:00
if ( Battleground * bg = player -> GetBattleground ())
2008-10-11 14:16:25 -05:00
{
2010-05-26 11:34:37 +02:00
if ( bg -> GetTypeID ( true ) == BATTLEGROUND_EY )
2008-10-11 14:16:25 -05:00
bg -> EventPlayerClickedOnFlag ( player , gameObjTarget );
return ;
}
2010-05-23 22:17:01 -03:00
} else if ( m_spellInfo -> Id == 1842 && gameObjTarget -> GetGOInfo () -> type == GAMEOBJECT_TYPE_TRAP && gameObjTarget -> GetOwner ())
2010-03-26 22:04:38 -03:00
{
2010-05-23 18:20:10 -03:00
gameObjTarget -> SetLootState ( GO_JUST_DEACTIVATED );
return ;
2008-10-11 14:16:25 -05:00
}
2009-12-18 13:41:30 -08:00
// TODO: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2008-10-14 11:57:03 -05:00
// handle outdoor pvp object opening, return true if go was registered for handling
// these objects must have been spawned by outdoorpvp!
2010-12-22 21:25:23 +01:00
else if ( gameObjTarget -> GetGOInfo () -> type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr -> HandleOpenGo ( player , gameObjTarget -> GetGUID ()))
2008-10-14 11:57:03 -05:00
return ;
2009-07-16 12:06:07 +08:00
lockId = goInfo -> GetLockId ();
2008-10-11 14:16:25 -05:00
guid = gameObjTarget -> GetGUID ();
}
2010-04-07 19:14:10 +02:00
else if ( itemTarget )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
lockId = itemTarget -> GetTemplate () -> LockID ;
2008-10-11 14:16:25 -05:00
guid = itemTarget -> GetGUID ();
}
else
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "WORLD: Open Lock - No GameObject/Item Target!" );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-03-15 17:54:24 -06:00
SkillType skillId = SKILL_NONE ;
int32 reqSkillValue = 0 ;
int32 skillValue ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
SpellCastResult res = CanOpenLock ( effIndex , lockId , skillId , reqSkillValue , skillValue );
2010-04-07 19:14:10 +02:00
if ( res != SPELL_CAST_OK )
2008-10-11 14:16:25 -05:00
{
2009-03-15 17:54:24 -06:00
SendCastResult ( res );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-08-04 10:34:30 +02:00
if ( gameObjTarget )
SendLoot ( guid , LOOT_SKINNING );
else
itemTarget -> SetFlag ( ITEM_FIELD_FLAGS , ITEM_FLAG_UNLOCKED );
2009-10-17 15:51:44 -07:00
2009-03-16 12:00:14 -06:00
// not allow use skill grow at item base open
2010-04-07 19:14:10 +02:00
if ( ! m_CastItem && skillId != SKILL_NONE )
2008-10-11 14:16:25 -05:00
{
2009-03-15 17:54:24 -06:00
// update skill if really known
2010-04-07 19:14:10 +02:00
if ( uint32 pureSkillValue = player -> GetPureSkillValue ( skillId ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( gameObjTarget )
2009-03-15 17:18:59 -06:00
{
2009-03-15 17:54:24 -06:00
// Allow one skill-up until respawned
2010-04-07 22:59:46 +02:00
if ( ! gameObjTarget -> IsInSkillupList ( player -> GetGUIDLow ()) &&
player -> UpdateGatherSkill ( skillId , pureSkillValue , reqSkillValue ))
gameObjTarget -> AddToSkillupList ( player -> GetGUIDLow ());
2009-03-15 17:54:24 -06:00
}
2010-04-07 19:14:10 +02:00
else if ( itemTarget )
2009-03-15 17:54:24 -06:00
{
// Do one skill-up
player -> UpdateGatherSkill ( skillId , pureSkillValue , reqSkillValue );
2009-03-15 17:18:59 -06:00
}
}
2008-10-11 14:16:25 -05:00
}
2010-08-27 17:49:32 +02:00
ExecuteLogEffectOpenLock ( effIndex , gameObjTarget ? ( Object * ) gameObjTarget : ( Object * ) itemTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonChangeItem ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// applied only to using item
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( ! m_CastItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// ... only to item in own inventory/bank/equip_slot
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_CastItem -> GetOwnerGUID () != player -> GetGUID ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 newitemid = m_spellInfo -> EffectItemType [ effIndex ];
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( ! newitemid )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint16 pos = m_CastItem -> GetPos ();
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
Item * pNewItem = Item :: CreateItem ( newitemid , 1 , player );
if ( ! pNewItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
for ( uint8 j = PERM_ENCHANTMENT_SLOT ; j <= TEMP_ENCHANTMENT_SLOT ; ++ j )
if ( m_CastItem -> GetEnchantmentId ( EnchantmentSlot ( j )))
2009-04-27 18:42:35 -05:00
pNewItem -> SetEnchantment ( EnchantmentSlot ( j ), m_CastItem -> GetEnchantmentId ( EnchantmentSlot ( j )), m_CastItem -> GetEnchantmentDuration ( EnchantmentSlot ( j )), m_CastItem -> GetEnchantmentCharges ( EnchantmentSlot ( j )));
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_CastItem -> GetUInt32Value ( ITEM_FIELD_DURABILITY ) < m_CastItem -> GetUInt32Value ( ITEM_FIELD_MAXDURABILITY ))
2008-10-11 14:16:25 -05:00
{
2010-11-14 23:46:34 +02:00
double lossPercent = 1 - m_CastItem -> GetUInt32Value ( ITEM_FIELD_DURABILITY ) / double ( m_CastItem -> GetUInt32Value ( ITEM_FIELD_MAXDURABILITY ));
player -> DurabilityLoss ( pNewItem , lossPercent );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( player -> IsInventoryPos ( pos ))
2008-10-11 14:16:25 -05:00
{
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = player -> CanStoreItem ( m_CastItem -> GetBagSlot (), m_CastItem -> GetSlot (), dest , pNewItem , true );
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( msg == EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2009-05-31 15:56:51 -05:00
player -> DestroyItem ( m_CastItem -> GetBagSlot (), m_CastItem -> GetSlot (), true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent crash at access and unexpected charges counting with item update queue corrupt
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_CastItem == m_targets . getItemTarget ())
2008-10-11 14:16:25 -05:00
m_targets . setItemTarget ( NULL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_CastItem = NULL ;
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
player -> StoreItem ( dest , pNewItem , true );
2008-10-11 14:16:25 -05:00
return ;
}
}
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
else if ( player -> IsBankPos ( pos ))
2008-10-11 14:16:25 -05:00
{
ItemPosCountVec dest ;
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
uint8 msg = player -> CanBankItem ( m_CastItem -> GetBagSlot (), m_CastItem -> GetSlot (), dest , pNewItem , true );
if ( msg == EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
{
2009-05-31 15:56:51 -05:00
player -> DestroyItem ( m_CastItem -> GetBagSlot (), m_CastItem -> GetSlot (), true );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent crash at access and unexpected charges counting with item update queue corrupt
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_CastItem == m_targets . getItemTarget ())
2008-10-11 14:16:25 -05:00
m_targets . setItemTarget ( NULL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_CastItem = NULL ;
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
player -> BankItem ( dest , pNewItem , true );
2008-10-11 14:16:25 -05:00
return ;
}
}
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
else if ( player -> IsEquipmentPos ( pos ))
2008-10-11 14:16:25 -05:00
{
uint16 dest ;
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
player -> DestroyItem ( m_CastItem -> GetBagSlot (), m_CastItem -> GetSlot (), true );
uint8 msg = player -> CanEquipItem ( m_CastItem -> GetSlot (), dest , pNewItem , true );
if ( msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW )
2008-10-11 14:16:25 -05:00
{
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( msg == EQUIP_ERR_CANT_DO_RIGHT_NOW ) dest = EQUIPMENT_SLOT_MAINHAND ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent crash at access and unexpected charges counting with item update queue corrupt
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
if ( m_CastItem == m_targets . getItemTarget ())
2008-10-11 14:16:25 -05:00
m_targets . setItemTarget ( NULL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_CastItem = NULL ;
2009-10-17 15:51:44 -07:00
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
player -> EquipItem ( dest , pNewItem , true );
2008-10-11 14:16:25 -05:00
player -> AutoUnequipOffhandIfNeed ();
return ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// fail
delete pNewItem ;
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectProficiency ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * p_target = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 subClassMask = m_spellInfo -> EquippedItemSubClassMask ;
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> EquippedItemClass == ITEM_CLASS_WEAPON && ! ( p_target -> GetWeaponProficiency () & subClassMask ))
2008-10-11 14:16:25 -05:00
{
p_target -> AddWeaponProficiency ( subClassMask );
2009-05-31 15:56:51 -05:00
p_target -> SendProficiency ( ITEM_CLASS_WEAPON , p_target -> GetWeaponProficiency ());
2008-10-11 14:16:25 -05:00
}
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> EquippedItemClass == ITEM_CLASS_ARMOR && ! ( p_target -> GetArmorProficiency () & subClassMask ))
2008-10-11 14:16:25 -05:00
{
p_target -> AddArmorProficiency ( subClassMask );
2009-05-31 15:56:51 -05:00
p_target -> SendProficiency ( ITEM_CLASS_ARMOR , p_target -> GetArmorProficiency ());
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonType ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 entry = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-11-01 17:53:07 -08:00
if ( ! entry )
2009-03-20 14:01:46 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
SummonPropertiesEntry const * properties = sSummonPropertiesStore . LookupEntry ( m_spellInfo -> EffectMiscValueB [ effIndex ]);
2009-11-01 17:53:07 -08:00
if ( ! properties )
2009-03-25 16:20:30 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "EffectSummonType: Unhandled summon type %u" , m_spellInfo -> EffectMiscValueB [ effIndex ]);
2009-03-25 16:20:30 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! m_originalCaster )
2009-04-27 18:12:45 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-04-27 18:12:45 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2009-11-01 17:53:07 -08:00
if ( Player * modOwner = m_originalCaster -> GetSpellModOwner ())
2009-04-27 18:12:45 -05:00
modOwner -> ApplySpellMod ( m_spellInfo -> Id , SPELLMOD_DURATION , duration );
2009-10-17 15:51:44 -07:00
2009-08-29 14:58:45 -05:00
Position pos ;
2010-08-27 19:36:27 +02:00
GetSummonPosition ( effIndex , pos );
2009-10-17 15:51:44 -07:00
2009-04-27 18:12:45 -05:00
TempSummon * summon = NULL ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
switch ( properties -> Category )
2008-10-11 14:16:25 -05:00
{
2011-04-22 12:05:15 +02:00
case SUMMON_CATEGORY_WILD :
case SUMMON_CATEGORY_ALLY :
2011-04-24 10:22:58 +02:00
case SUMMON_CATEGORY_UNK :
2009-07-22 17:10:30 +02:00
if ( properties -> Flags & 512 )
2009-07-22 20:22:36 +02:00
{
2010-08-27 19:36:27 +02:00
SummonGuardian ( effIndex , entry , properties );
2009-07-22 17:10:30 +02:00
break ;
2009-07-22 20:22:36 +02:00
}
2009-11-01 17:53:07 -08:00
switch ( properties -> Type )
2009-03-18 21:16:24 -06:00
{
2009-03-25 16:20:30 -06:00
case SUMMON_TYPE_PET :
case SUMMON_TYPE_GUARDIAN :
2009-12-14 01:51:12 +01:00
case SUMMON_TYPE_GUARDIAN2 :
2009-03-25 16:20:30 -06:00
case SUMMON_TYPE_MINION :
2010-08-27 19:36:27 +02:00
SummonGuardian ( effIndex , entry , properties );
2009-03-18 21:16:24 -06:00
break ;
2011-04-22 12:05:15 +02:00
// Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2009-03-25 16:20:30 -06:00
case SUMMON_TYPE_VEHICLE :
2009-04-22 17:50:26 -05:00
case SUMMON_TYPE_VEHICLE2 :
2011-05-19 22:27:18 +02:00
summon = m_caster -> GetMap () -> SummonCreature ( entry , pos , properties , duration , m_originalCaster , m_spellInfo -> Id );
2009-03-18 21:16:24 -06:00
break ;
2009-03-25 16:20:30 -06:00
case SUMMON_TYPE_TOTEM :
2009-04-27 18:12:45 -05:00
{
2011-05-19 22:27:18 +02:00
summon = m_caster -> GetMap () -> SummonCreature ( entry , pos , properties , duration , m_originalCaster , m_spellInfo -> Id );
if ( ! summon || ! summon -> isTotem ())
return ;
2011-05-19 01:24:53 +07:00
2011-05-19 22:27:18 +02:00
// Mana Tide Totem
if ( m_spellInfo -> Id == 16190 )
damage = m_caster -> CountPctFromMaxHealth ( 10 );
2009-10-17 15:51:44 -07:00
2011-05-19 22:27:18 +02:00
if ( damage ) // if not spell info, DB values used
{
summon -> SetMaxHealth ( damage );
summon -> SetHealth ( damage );
2009-04-27 18:12:45 -05:00
}
2009-03-25 16:20:30 -06:00
break ;
2009-04-27 18:12:45 -05:00
}
2009-03-25 16:20:30 -06:00
case SUMMON_TYPE_MINIPET :
2009-04-27 18:12:45 -05:00
{
2011-05-19 22:27:18 +02:00
summon = m_caster -> GetMap () -> SummonCreature ( entry , pos , properties , duration , m_originalCaster , m_spellInfo -> Id );
2009-11-01 17:53:07 -08:00
if ( ! summon || ! summon -> HasUnitTypeMask ( UNIT_MASK_MINION ))
2009-04-27 18:12:45 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-04-27 18:12:45 -05:00
//summon->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as summon...
2009-05-03 22:26:53 -05:00
summon -> SelectLevel ( summon -> GetCreatureInfo ()); // some summoned creaters have different from 1 DB data for level/hp
2009-05-04 17:25:13 -05:00
summon -> SetUInt32Value ( UNIT_NPC_FLAGS , summon -> GetCreatureInfo () -> npcflag );
2009-10-17 15:51:44 -07:00
2009-04-27 18:12:45 -05:00
summon -> SetFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_NON_ATTACKABLE );
2009-10-17 15:51:44 -07:00
2009-05-12 10:11:54 -05:00
summon -> AI () -> EnterEvadeMode ();
2009-10-17 15:51:44 -07:00
2009-04-27 18:12:45 -05:00
std :: string name = m_originalCaster -> GetName ();
name . append ( petTypeSuffix [ 3 ]);
2009-11-01 17:53:07 -08:00
summon -> SetName ( name );
2009-03-25 16:20:30 -06:00
break ;
2009-04-27 18:12:45 -05:00
}
2009-03-25 16:20:30 -06:00
default :
2009-04-27 18:12:45 -05:00
{
2010-08-27 19:36:27 +02:00
float radius = GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2009-10-17 15:51:44 -07:00
2010-08-26 15:54:56 +06:00
uint32 amount = damage > 0 ? damage : 1 ;
2011-04-22 12:05:15 +02:00
if ( m_spellInfo -> Id == 18662 || // Curse of Doom
properties -> Id == 2081 ) // Mechanical Dragonling, Arcanite Dragonling, Mithril Dragonling TODO: Research on meaning of basepoints
2009-06-15 17:15:19 +02:00
amount = 1 ;
2009-10-17 15:51:44 -07:00
2011-04-22 12:05:15 +02:00
TempSummonType summonType = ( duration == 0 ) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN ;
2009-10-17 16:20:24 -07:00
for ( uint32 count = 0 ; count < amount ; ++ count )
2009-04-27 18:12:45 -05:00
{
2010-08-27 19:36:27 +02:00
GetSummonPosition ( effIndex , pos , radius , count );
2009-10-17 15:51:44 -07:00
2010-06-07 01:59:04 +02:00
summon = m_originalCaster -> SummonCreature ( entry , pos , summonType , duration );
2009-07-22 22:52:05 +02:00
if ( ! summon )
continue ;
2011-04-22 12:05:15 +02:00
2009-07-09 17:02:29 +02:00
if ( properties -> Category == SUMMON_CATEGORY_ALLY )
2009-08-14 22:25:12 -05:00
{
summon -> SetUInt64Value ( UNIT_FIELD_SUMMONEDBY , m_originalCaster -> GetGUID ());
2009-07-11 13:03:06 +02:00
summon -> setFaction ( m_originalCaster -> getFaction ());
2009-08-26 19:28:21 -05:00
summon -> SetUInt32Value ( UNIT_CREATED_BY_SPELL , m_spellInfo -> Id );
2009-08-14 22:25:12 -05:00
}
2011-04-22 12:05:15 +02:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , summon );
2009-04-27 18:12:45 -05:00
}
2010-08-27 17:49:32 +02:00
return ;
2009-04-27 18:12:45 -05:00
}
} //switch
2008-10-11 14:16:25 -05:00
break ;
2009-03-25 16:20:30 -06:00
case SUMMON_CATEGORY_PET :
2010-08-27 19:36:27 +02:00
SummonGuardian ( effIndex , entry , properties );
2009-03-25 16:20:30 -06:00
break ;
2009-05-25 22:52:08 -05:00
case SUMMON_CATEGORY_PUPPET :
2011-05-19 22:27:18 +02:00
summon = m_caster -> GetMap () -> SummonCreature ( entry , pos , properties , duration , m_originalCaster , m_spellInfo -> Id );
2009-03-25 16:20:30 -06:00
break ;
2011-04-24 10:22:58 +02:00
case SUMMON_CATEGORY_VEHICLE :
2011-04-22 12:05:15 +02:00
// Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
// to cast a ride vehicle spell on the summoned unit.
2009-04-27 18:12:45 -05:00
float x , y , z ;
m_caster -> GetClosePoint ( x , y , z , DEFAULT_WORLD_OBJECT_SIZE );
2011-05-19 22:27:18 +02:00
summon = m_originalCaster -> GetMap () -> SummonCreature ( entry , pos , properties , duration , m_caster , m_spellInfo -> Id );
2009-11-01 17:53:07 -08:00
if ( ! summon || ! summon -> IsVehicle ())
2009-04-27 18:12:45 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-22 12:05:15 +02:00
// The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2011-04-25 14:39:37 +02:00
uint32 spell = VEHICLE_SPELL_RIDE_HARDCODED ;
if ( SpellEntry const * spellProto = sSpellStore . LookupEntry ( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , effIndex )))
spell = spellProto -> Id ;
2010-05-13 17:57:59 +02:00
2011-02-26 23:00:09 +01:00
// Hard coded enter vehicle spell
2011-04-22 12:05:15 +02:00
m_originalCaster -> CastSpell ( summon , spell , true );
2011-02-26 23:00:09 +01:00
uint32 faction = properties -> Faction ;
if ( ! faction )
faction = m_originalCaster -> getFaction ();
summon -> setFaction ( faction );
2009-03-25 16:20:30 -06:00
break ;
2009-04-27 18:12:45 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( summon )
2010-06-07 01:59:04 +02:00
{
summon -> SetCreatorGUID ( m_originalCaster -> GetGUID ());
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , summon );
2010-06-07 01:59:04 +02:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectLearnSpell ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2010-08-27 19:36:27 +02:00
EffectLearnPetSpell ( effIndex );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 spellToLearn = ( m_spellInfo -> Id == 483 || m_spellInfo -> Id == 55884 ) ? damage : m_spellInfo -> EffectTriggerSpell [ effIndex ];
2010-04-11 11:16:42 +04:00
player -> learnSpell ( spellToLearn , false );
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell: Player %u has learned spell %u from NpcGUID=%u" , player -> GetGUIDLow (), spellToLearn , m_caster -> GetGUIDLow ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 12:08:58 +01:00
typedef std :: list < std :: pair < uint32 , uint64 > > DispelList ;
2010-05-25 10:36:33 +02:00
typedef std :: list < std :: pair < Aura * , uint8 > > DispelChargesList ;
2010-08-27 19:36:27 +02:00
void Spell :: EffectDispel ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-25 10:36:33 +02:00
DispelChargesList dispel_list ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Create dispel mask by dispel type
2010-08-27 19:36:27 +02:00
uint32 dispel_type = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-04-07 22:59:46 +02:00
uint32 dispelMask = GetDispellMask ( DispelType ( dispel_type ));
2010-08-06 21:32:42 -07:00
// we should not be able to dispel diseases if the target is affected by unholy blight
if ( dispelMask & ( 1 << DISPEL_DISEASE ) && unitTarget -> HasAura ( 50536 ))
dispelMask &= ~ ( 1 << DISPEL_DISEASE );
2010-01-10 01:23:15 +01:00
Unit :: AuraMap const & auras = unitTarget -> GetOwnedAuras ();
2009-10-17 16:20:24 -07:00
for ( Unit :: AuraMap :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
Aura * aura = itr -> second ;
2010-01-10 20:09:44 +01:00
AuraApplication * aurApp = aura -> GetApplicationOfTarget ( unitTarget -> GetGUID ());
if ( ! aurApp )
continue ;
2011-01-02 22:43:36 +01:00
// don't try to remove passive auras
if ( aura -> IsPassive ())
continue ;
2010-01-10 01:23:15 +01:00
if (( 1 << aura -> GetSpellProto () -> Dispel ) & dispelMask )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( aura -> GetSpellProto () -> Dispel == DISPEL_MAGIC )
2008-10-11 14:16:25 -05:00
{
2010-12-19 05:15:47 +01:00
bool positive = aurApp -> IsPositive () ? ( ! ( aura -> GetSpellProto () -> AttributesEx & SPELL_ATTR1_NEGATIVE )) : false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// do not remove positive auras if friendly target
// negative auras if non-friendly target
2010-04-07 19:14:10 +02:00
if ( positive == unitTarget -> IsFriendlyTo ( m_caster ))
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-05-25 10:36:33 +02:00
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
// Polymorph instead of 1 / (5 + 1) -> 16%.
2010-12-19 05:15:47 +01:00
bool dispel_charges = aura -> GetSpellProto () -> AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES ;
2010-05-25 10:36:33 +02:00
uint8 charges = dispel_charges ? aura -> GetCharges () : aura -> GetStackAmount ();
if ( charges > 0 )
dispel_list . push_back ( std :: make_pair ( aura , charges ));
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-09-04 10:01:52 -05:00
if ( dispel_list . empty ())
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Ok if exist some buffs for dispel try dispel it
2009-09-04 10:01:52 -05:00
uint32 failCount = 0 ;
2011-05-05 19:06:11 -03:00
DispelChargesList success_list ;
2009-09-04 10:01:52 -05:00
WorldPacket dataFail ( SMSG_DISPEL_FAILED , 8 + 8 + 4 + 4 + damage * 4 );
// dispel N = damage buffs (or while exist buffs for dispel)
2010-05-25 10:36:33 +02:00
for ( int32 count = 0 ; count < damage && ! dispel_list . empty ();)
2008-10-11 14:16:25 -05:00
{
2009-09-04 10:01:52 -05:00
// Random select buff for dispel
2010-05-25 10:36:33 +02:00
DispelChargesList :: iterator itr = dispel_list . begin ();
2009-09-04 10:01:52 -05:00
std :: advance ( itr , urand ( 0 , dispel_list . size () - 1 ));
2009-10-17 15:51:44 -07:00
2010-05-25 10:36:33 +02:00
bool success = false ;
// 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2010-06-27 04:03:30 +02:00
if ( ! GetDispelChance ( itr -> first -> GetCaster (), unitTarget , itr -> first -> GetId (), ! unitTarget -> IsFriendlyTo ( m_caster ), & success ))
2009-04-06 13:31:14 +02:00
{
2009-09-04 10:01:52 -05:00
dispel_list . erase ( itr );
2010-05-25 10:36:33 +02:00
continue ;
2008-10-11 14:16:25 -05:00
}
2009-09-04 10:01:52 -05:00
else
2008-10-11 14:16:25 -05:00
{
2010-05-25 10:36:33 +02:00
if ( success )
2008-10-11 14:16:25 -05:00
{
2011-05-05 19:06:11 -03:00
bool alreadyListed = false ;
for ( DispelChargesList :: iterator successItr = success_list . begin (); successItr != success_list . end (); ++ successItr )
{
if ( successItr -> first -> GetId () == itr -> first -> GetId ())
{
++ successItr -> second ;
alreadyListed = true ;
}
}
if ( ! alreadyListed )
success_list . push_back ( std :: make_pair ( itr -> first , 1 ));
2010-05-25 10:36:33 +02:00
-- itr -> second ;
if ( itr -> second <= 0 )
dispel_list . erase ( itr );
2008-10-11 14:16:25 -05:00
}
2010-05-25 10:36:33 +02:00
else
{
if ( ! failCount )
{
// Failed to dispell
dataFail << uint64 ( m_caster -> GetGUID ()); // Caster GUID
dataFail << uint64 ( unitTarget -> GetGUID ()); // Victim GUID
dataFail << uint32 ( m_spellInfo -> Id ); // dispel spell id
}
++ failCount ;
dataFail << uint32 ( itr -> first -> GetId ()); // Spell Id
}
++ count ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-09-04 10:01:52 -05:00
if ( failCount )
m_caster -> SendMessageToSet ( & dataFail , true );
2009-10-17 15:51:44 -07:00
2009-09-04 10:01:52 -05:00
if ( success_list . empty ())
return ;
2009-10-17 15:51:44 -07:00
2011-05-05 19:06:11 -03:00
WorldPacket dataSuccess ( SMSG_SPELLDISPELLOG , 8 + 8 + 4 + 1 + 4 + success_list . size () * 5 );
2009-09-04 10:01:52 -05:00
// Send packet header
dataSuccess . append ( unitTarget -> GetPackGUID ()); // Victim GUID
dataSuccess . append ( m_caster -> GetPackGUID ()); // Caster GUID
dataSuccess << uint32 ( m_spellInfo -> Id ); // dispel spell id
dataSuccess << uint8 ( 0 ); // not used
dataSuccess << uint32 ( success_list . size ()); // count
2011-05-05 19:06:11 -03:00
for ( DispelChargesList :: iterator itr = success_list . begin (); itr != success_list . end (); ++ itr )
2009-09-04 10:01:52 -05:00
{
// Send dispelled spell info
2011-05-05 19:06:11 -03:00
dataSuccess << uint32 ( itr -> first -> GetId ()); // Spell Id
2009-09-04 10:01:52 -05:00
dataSuccess << uint8 ( 0 ); // 0 - dispelled !=0 cleansed
2011-05-05 19:06:11 -03:00
unitTarget -> RemoveAurasDueToSpellByDispel ( itr -> first -> GetId (), itr -> first -> GetCasterGUID (), m_caster , itr -> second );
2009-09-04 10:01:52 -05:00
}
m_caster -> SendMessageToSet ( & dataSuccess , true );
2009-10-17 15:51:44 -07:00
2009-09-04 10:01:52 -05:00
// On success dispel
// Devour Magic
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo -> Category == SPELLCATEGORY_DEVOUR_MAGIC )
{
2010-07-14 16:57:13 +02:00
int32 heal_amount = SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 1 );
2009-09-04 10:01:52 -05:00
m_caster -> CastCustomSpell ( m_caster , 19658 , & heal_amount , NULL , NULL , true );
2010-12-23 19:03:28 +01:00
// Glyph of Felhunter
if ( Unit * pOwner = m_caster -> GetOwner ())
if ( pOwner -> GetAura ( 56249 ))
pOwner -> CastCustomSpell ( pOwner , 19658 , & heal_amount , NULL , NULL , true );
2009-09-04 10:01:52 -05:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDualWield ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2008-10-29 20:00:21 -05:00
unitTarget -> SetCanDualWield ( true );
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () == TYPEID_UNIT )
2010-03-07 18:30:53 +01:00
unitTarget -> ToCreature () -> UpdateDamagePhysical ( OFF_ATTACK );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-12-16 18:08:23 +01:00
void Spell :: EffectPull ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
// TODO: create a proper pull towards distract spell center for distract
2010-12-16 18:08:23 +01:00
EffectNULL ( effIndex );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDistract ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
// Check for possible target
if ( ! unitTarget || unitTarget -> isInCombat ())
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// target must be OK to do this
2010-12-17 13:43:24 +01:00
if ( unitTarget -> HasUnitState ( UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-29 23:20:16 -05:00
float angle = unitTarget -> GetAngle ( & m_targets . m_dstPos );
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
// For players just turn them
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> SetPosition ( unitTarget -> GetPositionX (), unitTarget -> GetPositionY (), unitTarget -> GetPositionZ (), angle , false );
2010-03-18 17:58:27 +01:00
unitTarget -> ToPlayer () -> SendTeleportAckPacket ();
2008-10-11 14:16:25 -05:00
}
else
{
// Set creature Distracted, Stop it, And turn it
unitTarget -> SetOrientation ( angle );
unitTarget -> StopMoving ();
2010-07-12 00:30:17 +02:00
unitTarget -> GetMotionMaster () -> MoveDistract ( damage * IN_MILLISECONDS );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPickPocket ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// victim must be creature and attackable
2009-11-01 17:53:07 -08:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT || m_caster -> IsFriendlyTo ( unitTarget ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// victim have to be alive and humanoid or undead
2009-11-01 17:53:07 -08:00
if ( unitTarget -> isAlive () && ( unitTarget -> GetCreatureTypeMask () & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD ) != 0 )
2011-04-29 20:47:02 +02:00
m_caster -> ToPlayer () -> SendLoot ( unitTarget -> GetGUID (), LOOT_PICKPOCKETING );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectAddFarsight ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2008-11-14 20:40:35 -06:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
float radius = GetSpellRadiusForFriend ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2010-01-24 23:47:17 +01:00
// Caster not in world, might be spell triggered from aura removal
if ( ! m_caster -> IsInWorld ())
return ;
2011-04-19 15:14:50 +02:00
DynamicObject * dynObj = new DynamicObject ();
if ( ! dynObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_DYNAMICOBJECT ), m_caster , m_spellInfo -> Id , m_targets . m_dstPos , radius , true , DYNAMIC_OBJECT_FARSIGHT_FOCUS ))
2008-10-11 14:16:25 -05:00
{
delete dynObj ;
return ;
}
2011-04-19 15:14:50 +02:00
2010-01-10 01:23:15 +01:00
dynObj -> SetDuration ( duration );
2009-10-17 15:51:44 -07:00
2009-02-26 16:29:55 -06:00
dynObj -> setActive ( true ); //must before add to map to be put in world container
dynObj -> GetMap () -> Add ( dynObj ); //grid will also be loaded
2011-02-04 00:27:43 +01:00
dynObj -> SetCasterViewpoint ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-12-25 06:28:38 +01:00
void Spell :: EffectUntrainTalents ( SpellEffIndex /*effIndex*/ )
2010-12-22 20:14:30 +02:00
{
if ( ! unitTarget || m_caster -> GetTypeId () == TYPEID_PLAYER )
return ;
if ( uint64 guid = m_caster -> GetGUID ()) // the trainer is the caster
unitTarget -> ToPlayer () -> SendTalentWipeConfirm ( guid );
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectTeleUnitsFaceCaster ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( unitTarget -> isInFlight ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
float dis = ( float ) m_caster -> GetSpellRadiusForTarget ( unitTarget , sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
float fx , fy , fz ;
m_caster -> GetClosePoint ( fx , fy , fz , unitTarget -> GetObjectSize (), dis );
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
unitTarget -> NearTeleportTo ( fx , fy , fz , - m_caster -> GetOrientation (), unitTarget == m_caster );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectLearnSkill ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 skillid = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-03-07 15:20:19 +01:00
uint16 skillval = unitTarget -> ToPlayer () -> GetPureSkillValue ( skillid );
2010-08-27 19:36:27 +02:00
unitTarget -> ToPlayer () -> SetSkill ( skillid , SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , effIndex ), skillval ? skillval : 1 , damage * 75 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectAddHonor ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-15 17:20:15 -06:00
// not scale value for item based reward (/10 value expected)
2009-11-01 17:53:07 -08:00
if ( m_CastItem )
2009-03-15 17:20:15 -06:00
{
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> RewardHonor ( NULL , 1 , damage / 10 );
2011-04-29 20:47:02 +02:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u" , m_spellInfo -> Id , damage / 10 , m_CastItem -> GetEntry (), unitTarget -> ToPlayer () -> GetGUIDLow ());
2009-03-15 17:20:15 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-03-10 15:28:51 -06:00
// do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2009-11-01 17:53:07 -08:00
if ( damage <= 50 )
2009-03-15 17:20:15 -06:00
{
2010-12-11 20:37:38 +06:00
uint32 honor_reward = Trinity :: Honor :: hk_honor_at_level ( unitTarget -> getLevel (), float ( damage ));
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> RewardHonor ( NULL , 1 , honor_reward );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u" , m_spellInfo -> Id , honor_reward , unitTarget -> ToPlayer () -> GetGUIDLow ());
2009-03-15 17:20:15 -06:00
}
2009-03-10 15:28:51 -06:00
else
{
//maybe we have correct honor_gain in damage already
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> RewardHonor ( NULL , 1 , damage );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u" , m_spellInfo -> Id , damage , unitTarget -> ToPlayer () -> GetGUIDLow ());
2009-03-10 15:28:51 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTradeSkill ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
// uint32 skillid = m_spellInfo->EffectMiscValue[i];
2010-03-07 15:20:19 +01:00
// uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2011-04-29 20:47:02 +02:00
// unitTarget->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnchantItemPerm ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
if ( ! itemTarget )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * p_caster = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2009-05-01 15:40:49 +02:00
// Handle vellums
if ( itemTarget -> IsWeaponVellum () || itemTarget -> IsArmorVellum ())
{
// destroy one vellum from stack
2009-11-01 17:53:07 -08:00
uint32 count = 1 ;
2011-04-29 20:47:02 +02:00
p_caster -> DestroyItemCount ( itemTarget , count , true );
2009-05-01 17:21:16 +02:00
unitTarget = p_caster ;
2009-05-01 15:40:49 +02:00
// and add a scroll
2011-04-29 20:47:02 +02:00
DoCreateItem ( effIndex , m_spellInfo -> EffectItemType [ effIndex ]);
2009-05-01 15:40:49 +02:00
itemTarget = NULL ;
m_targets . setItemTarget ( NULL );
}
else
{
2009-05-01 17:21:16 +02:00
// do not increase skill if vellum used
2011-04-28 22:42:33 +02:00
if ( ! ( m_CastItem && m_CastItem -> GetTemplate () -> Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST ))
2009-05-01 17:21:16 +02:00
p_caster -> UpdateCraftSkill ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 enchant_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-05-01 15:40:49 +02:00
if ( ! enchant_id )
return ;
2009-10-17 15:51:44 -07:00
2009-05-01 15:40:49 +02:00
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( enchant_id );
2010-04-07 19:14:10 +02:00
if ( ! pEnchant )
2009-05-01 15:40:49 +02:00
return ;
2010-10-07 14:00:52 +02:00
2009-05-01 15:40:49 +02:00
// item can be in trade slot and have owner diff. from caster
Player * item_owner = itemTarget -> GetOwner ();
2009-11-01 17:53:07 -08:00
if ( ! item_owner )
2009-05-01 15:40:49 +02:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( item_owner != p_caster && p_caster -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld -> getBoolConfig ( CONFIG_GM_LOG_TRADE ))
2009-05-01 15:40:49 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outCommand ( p_caster -> GetSession () -> GetAccountId (), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)" ,
p_caster -> GetName (), p_caster -> GetSession () -> GetAccountId (),
2011-04-29 19:59:40 +02:00
itemTarget -> GetTemplate () -> Name1 . c_str (), itemTarget -> GetEntry (),
2011-04-29 20:47:02 +02:00
item_owner -> GetName (), item_owner -> GetSession () -> GetAccountId ());
2009-05-01 15:40:49 +02:00
}
2009-10-17 15:51:44 -07:00
2009-05-01 15:40:49 +02:00
// remove old enchanting before applying new if equipped
2011-04-29 20:47:02 +02:00
item_owner -> ApplyEnchantment ( itemTarget , PERM_ENCHANTMENT_SLOT , false );
2009-10-17 15:51:44 -07:00
2009-05-01 15:40:49 +02:00
itemTarget -> SetEnchantment ( PERM_ENCHANTMENT_SLOT , enchant_id , 0 , 0 );
2009-10-17 15:51:44 -07:00
2009-05-01 15:40:49 +02:00
// add new enchanting if equipped
2011-04-29 20:47:02 +02:00
item_owner -> ApplyEnchantment ( itemTarget , PERM_ENCHANTMENT_SLOT , true );
2010-09-21 21:55:16 +02:00
itemTarget -> SetSoulboundTradeable ( NULL , item_owner , false );
2009-05-01 15:40:49 +02:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnchantItemPrismatic ( SpellEffIndex effIndex )
2009-02-03 19:12:17 -06:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-02-03 19:12:17 -06:00
return ;
if ( ! itemTarget )
return ;
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
Player * p_caster = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 enchant_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-02-03 19:12:17 -06:00
if ( ! enchant_id )
return ;
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( enchant_id );
2010-04-07 19:14:10 +02:00
if ( ! pEnchant )
2009-02-03 19:12:17 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// support only enchantings with add socket in this slot
{
bool add_socket = false ;
2010-09-28 08:21:51 +03:00
for ( uint8 i = 0 ; i < MAX_ITEM_ENCHANTMENT_EFFECTS ; ++ i )
2009-02-03 19:12:17 -06:00
{
2010-04-07 23:25:02 +02:00
if ( pEnchant -> type [ i ] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET )
2009-02-03 19:12:17 -06:00
{
add_socket = true ;
break ;
}
}
2010-04-07 19:14:10 +02:00
if ( ! add_socket )
2009-02-03 19:12:17 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (%u), not suppoted yet." ,
2011-04-29 20:47:02 +02:00
m_spellInfo -> Id , SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC , ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET );
2009-02-03 19:12:17 -06:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// item can be in trade slot and have owner diff. from caster
Player * item_owner = itemTarget -> GetOwner ();
2009-11-01 17:53:07 -08:00
if ( ! item_owner )
2009-02-03 19:12:17 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( item_owner != p_caster && p_caster -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld -> getBoolConfig ( CONFIG_GM_LOG_TRADE ))
2009-02-03 19:12:17 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outCommand ( p_caster -> GetSession () -> GetAccountId (), "GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)" ,
p_caster -> GetName (), p_caster -> GetSession () -> GetAccountId (),
2011-04-29 19:59:40 +02:00
itemTarget -> GetTemplate () -> Name1 . c_str (), itemTarget -> GetEntry (),
2011-04-29 20:47:02 +02:00
item_owner -> GetName (), item_owner -> GetSession () -> GetAccountId ());
2009-02-03 19:12:17 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// remove old enchanting before applying new if equipped
2011-04-29 20:47:02 +02:00
item_owner -> ApplyEnchantment ( itemTarget , PRISMATIC_ENCHANTMENT_SLOT , false );
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
itemTarget -> SetEnchantment ( PRISMATIC_ENCHANTMENT_SLOT , enchant_id , 0 , 0 );
2009-10-17 15:51:44 -07:00
2009-02-03 19:12:17 -06:00
// add new enchanting if equipped
2011-04-29 20:47:02 +02:00
item_owner -> ApplyEnchantment ( itemTarget , PRISMATIC_ENCHANTMENT_SLOT , true );
2010-09-21 21:55:16 +02:00
itemTarget -> SetSoulboundTradeable ( NULL , item_owner , false );
2009-02-03 19:12:17 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnchantItemTmp ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * p_caster = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2009-12-17 12:23:01 +01:00
// Rockbiter Weapon apply to both weapon
2009-11-01 17:53:07 -08:00
if ( ! itemTarget )
2009-12-17 12:23:01 +01:00
return ;
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x400000 )
2008-10-11 14:16:25 -05:00
{
2009-12-17 12:23:01 +01:00
uint32 spell_id = 0 ;
2009-10-17 15:51:44 -07:00
2009-12-17 12:23:01 +01:00
// enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2008-10-11 14:16:25 -05:00
// Note: damage calculated (correctly) with rounding int32(float(v)) but
// RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2009-12-17 12:23:01 +01:00
switch ( damage )
2008-10-11 14:16:25 -05:00
{
// Rank 1
2010-04-07 23:56:35 +02:00
case 2 : spell_id = 36744 ; break ; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2008-10-11 14:16:25 -05:00
// Rank 2
2010-04-07 23:56:35 +02:00
case 4 : spell_id = 36753 ; break ; // 0% [ 7% == 4, 14% == 4]
2009-12-17 12:23:01 +01:00
case 5 : spell_id = 36751 ; break ; // 20%
2008-10-11 14:16:25 -05:00
// Rank 3
2010-04-07 23:56:35 +02:00
case 6 : spell_id = 36754 ; break ; // 0% [ 7% == 6, 14% == 6]
2009-12-17 12:23:01 +01:00
case 7 : spell_id = 36755 ; break ; // 20%
2008-10-11 14:16:25 -05:00
// Rank 4
2010-04-07 23:56:35 +02:00
case 9 : spell_id = 36761 ; break ; // 0% [ 7% == 6]
2009-12-17 12:23:01 +01:00
case 10 : spell_id = 36758 ; break ; // 14%
case 11 : spell_id = 36760 ; break ; // 20%
2008-10-11 14:16:25 -05:00
default :
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW" , damage );
2008-10-11 14:16:25 -05:00
return ;
}
2009-12-17 12:23:01 +01:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( spell_id );
if ( ! spellInfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectEnchantItemTmp: unknown spell id %i" , spell_id );
2009-12-17 12:23:01 +01:00
return ;
2010-01-10 01:23:15 +01:00
2009-12-17 12:23:01 +01:00
}
2010-04-07 19:12:44 +02:00
for ( int j = BASE_ATTACK ; j <= OFF_ATTACK ; ++ j )
2009-12-17 12:23:01 +01:00
{
if ( Item * item = p_caster -> GetWeaponForAttack ( WeaponAttackType ( j )))
{
if ( item -> IsFitToSpellRequirements ( m_spellInfo ))
{
Spell * spell = new Spell ( m_caster , spellInfo , true );
SpellCastTargets targets ;
2010-04-07 22:59:46 +02:00
targets . setItemTarget ( item );
2009-12-17 12:23:01 +01:00
spell -> prepare ( & targets );
}
}
}
return ;
2008-10-11 14:16:25 -05:00
}
2009-12-17 12:23:01 +01:00
if ( ! itemTarget )
return ;
2010-08-27 19:36:27 +02:00
uint32 enchant_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! enchant_id )
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id" , m_spellInfo -> Id , effIndex );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( enchant_id );
2009-11-01 17:53:07 -08:00
if ( ! pEnchant )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id %u " , m_spellInfo -> Id , effIndex , enchant_id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// select enchantment duration
uint32 duration ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// rogue family enchantments exception by duration
2009-11-01 17:53:07 -08:00
if ( m_spellInfo -> Id == 38615 )
2008-10-11 14:16:25 -05:00
duration = 1800 ; // 30 mins
// other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_ROGUE )
2008-10-11 14:16:25 -05:00
duration = 3600 ; // 1 hour
// shaman family enchantments
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_SHAMAN )
2008-10-11 14:16:25 -05:00
duration = 1800 ; // 30 mins
// other cases with this SpellVisual already selected
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> SpellVisual [ 0 ] == 215 )
2008-10-11 14:16:25 -05:00
duration = 1800 ; // 30 mins
2010-05-24 13:56:21 +02:00
// some fishing pole bonuses except Glow Worm which lasts full hour
else if ( m_spellInfo -> SpellVisual [ 0 ] == 563 && m_spellInfo -> Id != 64401 )
2008-10-11 14:16:25 -05:00
duration = 600 ; // 10 mins
// shaman rockbiter enchantments
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> SpellVisual [ 0 ] == 0 )
2008-10-11 14:16:25 -05:00
duration = 1800 ; // 30 mins
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> Id == 29702 )
2008-10-11 14:16:25 -05:00
duration = 300 ; // 5 mins
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> Id == 37360 )
2008-10-11 14:16:25 -05:00
duration = 300 ; // 5 mins
// default case
else
duration = 3600 ; // 1 hour
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// item can be in trade slot and have owner diff. from caster
Player * item_owner = itemTarget -> GetOwner ();
2009-11-01 17:53:07 -08:00
if ( ! item_owner )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( item_owner != p_caster && p_caster -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld -> getBoolConfig ( CONFIG_GM_LOG_TRADE ))
2008-11-25 16:36:50 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outCommand ( p_caster -> GetSession () -> GetAccountId (), "GM %s (Account: %u) enchanting(temp): %s (Entry: %d) for player: %s (Account: %u)" ,
2009-05-31 15:56:51 -05:00
p_caster -> GetName (), p_caster -> GetSession () -> GetAccountId (),
2011-04-29 19:59:40 +02:00
itemTarget -> GetTemplate () -> Name1 . c_str (), itemTarget -> GetEntry (),
2009-05-31 15:56:51 -05:00
item_owner -> GetName (), item_owner -> GetSession () -> GetAccountId ());
2008-11-25 16:36:50 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove old enchanting before applying new if equipped
2011-04-29 20:47:02 +02:00
item_owner -> ApplyEnchantment ( itemTarget , TEMP_ENCHANTMENT_SLOT , false );
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
itemTarget -> SetEnchantment ( TEMP_ENCHANTMENT_SLOT , enchant_id , duration * 1000 , 0 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// add new enchanting if equipped
2009-05-31 15:56:51 -05:00
item_owner -> ApplyEnchantment ( itemTarget , TEMP_ENCHANTMENT_SLOT , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTameCreature ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetPetGUID ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( unitTarget -> GetTypeId () != TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 18:30:53 +01:00
Creature * creatureTarget = unitTarget -> ToCreature ();
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( creatureTarget -> isPet ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( m_caster -> getClass () != CLASS_HUNTER )
2008-11-04 09:23:06 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-11-04 09:23:06 -06:00
// cast finish successfully
//SendChannelUpdate(0);
finish ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
Pet * pet = m_caster -> CreateTamedPetFrom ( creatureTarget , m_spellInfo -> Id );
2009-11-01 17:53:07 -08:00
if ( ! pet ) // in very specific state like near world end/etc.
2009-06-02 17:40:22 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-06-18 17:05:01 -05:00
// "kill" original creature
2011-01-02 21:33:37 +01:00
creatureTarget -> DespawnOrUnsummon ();
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
uint8 level = ( creatureTarget -> getLevel () < ( m_caster -> getLevel () - 5 )) ? ( m_caster -> getLevel () - 5 ) : creatureTarget -> getLevel ();
2009-10-17 15:51:44 -07:00
2008-11-04 09:23:06 -06:00
// prepare visual effect for levelup
2008-12-24 09:58:26 -06:00
pet -> SetUInt32Value ( UNIT_FIELD_LEVEL , level - 1 );
2009-10-17 15:51:44 -07:00
2008-11-04 09:23:06 -06:00
// add to world
2010-03-07 18:30:53 +01:00
pet -> GetMap () -> Add ( pet -> ToCreature ());
2009-10-17 15:51:44 -07:00
2008-11-04 09:23:06 -06:00
// visual effect for levelup
2008-12-24 09:58:26 -06:00
pet -> SetUInt32Value ( UNIT_FIELD_LEVEL , level );
2009-10-17 15:51:44 -07:00
2008-11-04 09:23:06 -06:00
// caster have pet now
2009-05-02 19:24:22 -05:00
m_caster -> SetMinion ( pet , true );
2009-10-17 16:20:24 -07:00
2009-08-17 04:45:34 +02:00
pet -> InitTalentForLevel ();
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2008-11-04 09:23:06 -06:00
{
pet -> SavePetToDB ( PET_SAVE_AS_CURRENT );
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> PetSpellInitialize ();
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonPet ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-02-24 20:52:55 -06:00
Player * owner = NULL ;
2009-11-01 17:53:07 -08:00
if ( m_originalCaster )
2009-02-24 20:52:55 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_originalCaster -> GetTypeId () == TYPEID_PLAYER )
2009-02-24 20:52:55 -06:00
owner = ( Player * ) m_originalCaster ;
2010-04-07 19:14:10 +02:00
else if ( m_originalCaster -> ToCreature () -> isTotem ())
2009-02-24 20:52:55 -06:00
owner = m_originalCaster -> GetCharmerOrOwnerPlayerOrPlayerItself ();
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 petentry = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! owner )
2008-12-30 22:01:45 -06:00
{
2009-04-15 20:19:47 -05:00
SummonPropertiesEntry const * properties = sSummonPropertiesStore . LookupEntry ( 67 );
2010-04-07 19:14:10 +02:00
if ( properties )
2010-08-27 19:36:27 +02:00
SummonGuardian ( effIndex , petentry , properties );
2008-12-30 22:01:45 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-24 20:52:55 -06:00
Pet * OldSummon = owner -> GetPet ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// if pet requested type already exist
2009-11-01 17:53:07 -08:00
if ( OldSummon )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( petentry == 0 || OldSummon -> GetEntry () == petentry )
2008-10-11 14:16:25 -05:00
{
// pet in corpse state can't be summoned
2009-11-01 17:53:07 -08:00
if ( OldSummon -> isDead ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-07-30 20:04:28 +02:00
ASSERT ( OldSummon -> GetMap () == owner -> GetMap ());
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
//OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
float px , py , pz ;
2009-02-24 20:52:55 -06:00
owner -> GetClosePoint ( px , py , pz , OldSummon -> GetObjectSize ());
2009-10-17 15:51:44 -07:00
2009-08-26 21:17:47 -05:00
OldSummon -> NearTeleportTo ( px , py , pz , OldSummon -> GetOrientation ());
//OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
//OldSummon->SetMap(owner->GetMap());
2010-03-07 18:30:53 +01:00
//owner->GetMap()->Add(OldSummon->ToCreature());
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( owner -> GetTypeId () == TYPEID_PLAYER && OldSummon -> isControlled ())
2010-03-07 15:20:19 +01:00
owner -> ToPlayer () -> PetSpellInitialize ();
2009-11-01 17:53:07 -08:00
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( owner -> GetTypeId () == TYPEID_PLAYER )
2011-04-29 20:47:02 +02:00
owner -> ToPlayer () -> RemovePet ( OldSummon , ( OldSummon -> getPetType () == HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT ), false );
2008-10-11 14:16:25 -05:00
else
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-24 20:52:55 -06:00
float x , y , z ;
owner -> GetClosePoint ( x , y , z , owner -> GetObjectSize ());
Pet * pet = owner -> SummonPet ( petentry , x , y , z , owner -> GetOrientation (), SUMMON_PET , 0 );
2009-11-01 17:53:07 -08:00
if ( ! pet )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () == TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
{
2010-03-07 18:30:53 +01:00
if ( m_caster -> ToCreature () -> isTotem ())
2009-03-05 18:48:56 -06:00
pet -> SetReactState ( REACT_AGGRESSIVE );
2008-11-18 19:40:06 -06:00
else
2009-03-05 18:48:56 -06:00
pet -> SetReactState ( REACT_DEFENSIVE );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-24 20:52:55 -06:00
pet -> SetUInt32Value ( UNIT_CREATED_BY_SPELL , m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2009-02-24 20:52:55 -06:00
// generate new name for summon pet
2010-12-22 21:25:23 +01:00
std :: string new_name = sObjectMgr -> GeneratePetName ( petentry );
2009-11-01 17:53:07 -08:00
if ( ! new_name . empty ())
2009-02-24 20:52:55 -06:00
pet -> SetName ( new_name );
2010-08-27 17:49:32 +02:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , pet );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectLearnPetSpell ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * _player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
2009-11-01 17:53:07 -08:00
if ( ! pet )
2008-10-11 14:16:25 -05:00
return ;
2009-11-01 17:53:07 -08:00
if ( ! pet -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
SpellEntry const * learn_spellproto = sSpellStore . LookupEntry ( m_spellInfo -> EffectTriggerSpell [ effIndex ]);
2009-11-01 17:53:07 -08:00
if ( ! learn_spellproto )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pet -> learnSpell ( learn_spellproto -> Id );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pet -> SavePetToDB ( PET_SAVE_AS_CURRENT );
_player -> PetSpellInitialize ();
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTaunt ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-04-27 18:42:35 -05:00
if ( ! unitTarget )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// this effect use before aura Taunt apply for prevent taunt already attacking target
// for spell as marked "non effective at already attacking target"
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! unitTarget -> CanHaveThreatList ()
2009-04-17 18:08:52 -05:00
|| unitTarget -> getVictim () == m_caster )
2008-10-11 14:16:25 -05:00
{
2009-04-17 18:08:52 -05:00
SendCastResult ( SPELL_FAILED_DONT_REPORT );
return ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-17 12:23:01 +01:00
if ( m_spellInfo -> Id == 62124 )
2011-05-10 20:27:08 +07:00
m_caster -> CastSpell ( unitTarget , 67485 , true );
2009-12-17 12:23:01 +01:00
2008-10-11 14:16:25 -05:00
// Also use this effect to set the taunter's threat to the taunted creature's highest value
2009-11-01 17:53:07 -08:00
if ( unitTarget -> getThreatManager (). getCurrentVictim ())
2009-04-17 18:08:52 -05:00
{
float myThreat = unitTarget -> getThreatManager (). getThreat ( m_caster );
float itsThreat = unitTarget -> getThreatManager (). getCurrentVictim () -> getThreat ();
2009-11-01 17:53:07 -08:00
if ( itsThreat > myThreat )
2009-04-17 18:08:52 -05:00
unitTarget -> getThreatManager (). addThreat ( m_caster , itsThreat - myThreat );
}
2009-10-17 15:51:44 -07:00
2009-06-17 00:44:35 +02:00
//Set aggro victim to caster
2009-11-01 17:53:07 -08:00
if ( ! unitTarget -> getThreatManager (). getOnlineContainer (). empty ())
2010-03-09 11:11:10 +01:00
if ( HostileReference * forcedVictim = unitTarget -> getThreatManager (). getOnlineContainer (). getReferenceByTarget ( m_caster ))
2009-06-17 00:44:35 +02:00
unitTarget -> getThreatManager (). setCurrentVictim ( forcedVictim );
2009-10-17 15:51:44 -07:00
2010-03-07 18:30:53 +01:00
if ( unitTarget -> ToCreature () -> IsAIEnabled && ! unitTarget -> ToCreature () -> HasReactState ( REACT_PASSIVE ))
unitTarget -> ToCreature () -> AI () -> AttackStart ( m_caster );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectWeaponDmg ( SpellEffIndex /*effIndex*/ )
2008-12-25 17:39:46 -06:00
{
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: SpellDamageWeaponDmg ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-11-01 17:53:07 -08:00
if ( ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// multiple weapon dmg effect workaround
// execute only the last weapon damage
// and handle all effects at once
2010-09-28 08:21:51 +03:00
for ( uint32 j = effIndex + 1 ; j < MAX_SPELL_EFFECTS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
switch ( m_spellInfo -> Effect [ j ])
2008-10-11 14:16:25 -05:00
{
case SPELL_EFFECT_WEAPON_DAMAGE :
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL :
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG :
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE :
2009-11-01 17:53:07 -08:00
return ; // we must calculate only at last weapon effect
2008-10-11 14:16:25 -05:00
break ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// some spell specific modifiers
float totalDamagePercentMod = 1.0f ; // applied to final bonus+weapon damage
2008-12-17 23:27:01 -06:00
int32 fixed_bonus = 0 ;
2008-10-11 14:16:25 -05:00
int32 spell_bonus = 0 ; // bonus specific for spell
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
switch ( m_spellInfo -> SpellFamilyName )
2008-10-11 14:16:25 -05:00
{
2010-08-18 17:19:47 +02:00
case SPELLFAMILY_GENERIC :
{
switch ( m_spellInfo -> Id )
{
case 69055 : // Saber Lash
case 70814 : // Saber Lash
{
uint32 count = 0 ;
for ( std :: list < TargetInfo >:: iterator ihit = m_UniqueTargetInfo . begin (); ihit != m_UniqueTargetInfo . end (); ++ ihit )
2010-08-27 19:36:27 +02:00
if ( ihit -> effectMask & ( 1 << effIndex ))
2010-08-18 17:19:47 +02:00
++ count ;
totalDamagePercentMod /= count ;
break ;
}
}
break ;
}
2008-10-11 14:16:25 -05:00
case SPELLFAMILY_WARRIOR :
{
2010-01-05 14:36:06 +03:00
// Devastate (player ones)
2009-11-01 17:53:07 -08:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x40 )
2008-10-11 14:16:25 -05:00
{
2010-01-05 14:36:06 +03:00
// Player can apply only 58567 Sunder Armor effect.
bool needCast = ! unitTarget -> HasAura ( 58567 , m_caster -> GetGUID ());
if ( needCast )
m_caster -> CastSpell ( unitTarget , 58567 , true );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
if ( Aura * aur = unitTarget -> GetAura ( 58567 , m_caster -> GetGUID ()))
2008-11-25 19:14:55 -06:00
{
2010-01-05 14:36:06 +03:00
// 58388 - Glyph of Devastate dummy aura.
if ( int32 num = ( needCast ? 0 : 1 ) + ( m_caster -> HasAura ( 58388 ) ? 1 : 0 ))
2010-01-10 01:23:15 +01:00
aur -> ModStackAmount ( num );
2010-01-05 14:36:06 +03:00
fixed_bonus += ( aur -> GetStackAmount () - 1 ) * CalculateDamage ( 2 , unitTarget );
2008-10-11 14:16:25 -05:00
}
}
break ;
}
case SPELLFAMILY_ROGUE :
{
2010-04-21 18:52:30 +02:00
// Fan of Knives, Hemorrhage, Ghostly Strike
2010-04-29 23:12:16 +02:00
if (( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x40000 )
2010-04-21 18:52:30 +02:00
|| ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x6000000 ))
2009-04-14 20:21:16 +02:00
{
2010-04-21 18:52:30 +02:00
// Hemorrhage
if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x2000000 )
{
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
m_caster -> ToPlayer () -> AddComboPoints ( unitTarget , 1 , this );
}
2009-04-14 20:21:16 +02:00
// 50% more damage with daggers
2009-11-01 17:53:07 -08:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
if ( Item * item = m_caster -> ToPlayer () -> GetWeaponForAttack ( m_attackType , true ))
2011-04-28 22:42:33 +02:00
if ( item -> GetTemplate () -> SubClass == ITEM_SUBCLASS_WEAPON_DAGGER )
2009-08-11 19:57:27 +02:00
totalDamagePercentMod *= 1.5f ;
2009-04-14 20:21:16 +02:00
}
2008-10-11 14:16:25 -05:00
// Mutilate (for each hand)
2009-11-01 17:53:07 -08:00
else if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x6 )
2008-10-11 14:16:25 -05:00
{
bool found = false ;
// fast check
2009-11-01 17:53:07 -08:00
if ( unitTarget -> HasAuraState ( AURA_STATE_DEADLY_POISON , m_spellInfo , m_caster ))
2008-10-11 14:16:25 -05:00
found = true ;
// full aura scan
else
{
2010-01-10 01:23:15 +01:00
Unit :: AuraApplicationMap const & auras = unitTarget -> GetAppliedAuras ();
2010-04-08 08:20:08 +02:00
for ( Unit :: AuraApplicationMap :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
if ( itr -> second -> GetBase () -> GetSpellProto () -> Dispel == DISPEL_POISON )
2008-10-11 14:16:25 -05:00
{
found = true ;
break ;
}
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( found )
2009-02-21 17:07:48 -06:00
totalDamagePercentMod *= 1.2f ; // 120% if poisoned
2008-10-11 14:16:25 -05:00
}
break ;
}
case SPELLFAMILY_PALADIN :
{
2009-04-09 14:58:25 +02:00
// Seal of Command Unleashed
2011-05-12 04:25:55 +07:00
if ( m_spellInfo -> Id == 20467 )
2009-04-09 14:58:25 +02:00
{
2010-12-11 20:37:38 +06:00
spell_bonus += int32 ( 0.08f * m_caster -> GetTotalAttackPowerValue ( BASE_ATTACK ));
spell_bonus += int32 ( 0.13f * m_caster -> SpellBaseDamageBonus ( GetSpellSchoolMask ( m_spellInfo )));
2009-04-09 14:58:25 +02:00
}
2008-10-11 14:16:25 -05:00
break ;
}
case SPELLFAMILY_SHAMAN :
{
// Skyshatter Harness item set bonus
// Stormstrike
2009-07-13 21:27:05 +02:00
if ( AuraEffect * aurEff = m_caster -> IsScriptOverriden ( m_spellInfo , 5634 ))
m_caster -> CastSpell ( m_caster , 38430 , true , NULL , aurEff );
2008-12-17 23:27:01 -06:00
break ;
}
case SPELLFAMILY_DRUID :
{
// Mangle (Cat): CP
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x400 )
2008-12-17 23:27:01 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2010-12-11 20:37:38 +06:00
m_caster -> ToPlayer () -> AddComboPoints ( unitTarget , 1 , this );
2008-12-17 23:27:01 -06:00
}
2009-06-28 19:39:15 +02:00
// Shred, Maul - Rend and Tear
2010-02-14 19:13:14 -07:00
else if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x00008800 && unitTarget -> HasAuraState ( AURA_STATE_BLEEDING ))
2009-06-28 19:39:15 +02:00
{
2010-01-10 01:23:15 +01:00
if ( AuraEffect const * rendAndTear = m_caster -> GetDummyAuraEffect ( SPELLFAMILY_DRUID , 2859 , 0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( totalDamagePercentMod , rendAndTear -> GetAmount ());
2009-06-28 19:39:15 +02:00
}
2008-12-17 23:27:01 -06:00
break ;
2008-10-11 14:16:25 -05:00
}
2009-12-20 17:25:10 -06:00
case SPELLFAMILY_HUNTER :
{
2010-01-13 09:54:03 +01:00
// Kill Shot - bonus damage from Ranged Attack Power
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x800000 )
2010-12-11 20:37:38 +06:00
spell_bonus += int32 ( 0.4f * m_caster -> GetTotalAttackPowerValue ( RANGED_ATTACK ));
2009-12-20 17:25:10 -06:00
break ;
}
2009-06-13 17:28:38 +02:00
case SPELLFAMILY_DEATHKNIGHT :
{
2009-08-08 21:51:00 +02:00
// Plague Strike
2010-12-04 10:31:14 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_0 ] & 0x1 )
2009-08-08 21:51:00 +02:00
{
// Glyph of Plague Strike
2010-12-04 10:31:14 +01:00
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( 58657 , EFFECT_0 ))
2010-12-11 20:37:38 +06:00
AddPctN ( totalDamagePercentMod , aurEff -> GetAmount ());
2010-12-04 10:31:14 +01:00
break ;
2009-08-08 21:51:00 +02:00
}
// Blood Strike
2010-12-04 10:31:14 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_0 ] & 0x400000 )
2009-08-08 21:51:00 +02:00
{
2010-12-11 20:37:38 +06:00
AddPctF ( totalDamagePercentMod , SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , EFFECT_2 ) * unitTarget -> GetDiseasesByCaster ( m_caster -> GetGUID ()) / 2.0f );
2009-10-17 15:51:44 -07:00
2009-08-08 21:51:00 +02:00
// Glyph of Blood Strike
2010-12-04 10:31:14 +01:00
if ( m_caster -> GetAuraEffect ( 59332 , EFFECT_0 ))
2010-04-07 19:14:10 +02:00
if ( unitTarget -> HasAuraType ( SPELL_AURA_MOD_DECREASE_SPEED ))
2010-12-11 20:37:38 +06:00
AddPctN ( totalDamagePercentMod , 20 );
2010-12-04 10:31:14 +01:00
break ;
2009-08-08 21:51:00 +02:00
}
// Death Strike
2010-12-04 10:31:14 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_0 ] & 0x10 )
2009-08-08 21:51:00 +02:00
{
// Glyph of Death Strike
2010-12-04 10:31:14 +01:00
if ( AuraEffect const * aurEff = m_caster -> GetAuraEffect ( 59336 , EFFECT_0 ))
if ( uint32 runic = std :: min < uint32 > ( m_caster -> GetPower ( POWER_RUNIC_POWER ), SpellMgr :: CalculateSpellEffectAmount ( aurEff -> GetSpellProto (), EFFECT_1 )))
2010-12-11 20:37:38 +06:00
AddPctN ( totalDamagePercentMod , runic );
2010-12-04 10:31:14 +01:00
break ;
2009-08-08 21:51:00 +02:00
}
2009-06-13 17:28:38 +02:00
// Obliterate (12.5% more damage per disease)
2010-12-04 10:31:14 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_1 ] & 0x20000 )
2009-06-14 20:07:12 +02:00
{
bool consumeDiseases = true ;
// Annihilation
2010-12-04 10:31:14 +01:00
if ( AuraEffect const * aurEff = m_caster -> GetDummyAuraEffect ( SPELLFAMILY_DEATHKNIGHT , 2710 , EFFECT_0 ))
2009-06-14 20:07:12 +02:00
// Do not consume diseases if roll sucesses
if ( roll_chance_i ( aurEff -> GetAmount ()))
consumeDiseases = false ;
2010-12-04 10:31:14 +01:00
2010-12-11 20:37:38 +06:00
AddPctF ( totalDamagePercentMod , SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , EFFECT_2 ) * unitTarget -> GetDiseasesByCaster ( m_caster -> GetGUID (), consumeDiseases ) / 2.0f );
2010-12-04 10:31:14 +01:00
break ;
2009-06-14 20:07:12 +02:00
}
2009-08-08 21:51:00 +02:00
// Blood-Caked Strike - Blood-Caked Blade
2010-12-04 10:31:14 +01:00
if ( m_spellInfo -> SpellIconID == 1736 )
{
2010-12-11 20:37:38 +06:00
AddPctF ( totalDamagePercentMod , unitTarget -> GetDiseasesByCaster ( m_caster -> GetGUID ()) * 12.5f );
2010-12-04 10:31:14 +01:00
break ;
}
// Heart Strike
if ( m_spellInfo -> SpellFamilyFlags [ EFFECT_0 ] & 0x1000000 )
{
2010-12-11 20:37:38 +06:00
AddPctN ( totalDamagePercentMod , SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , EFFECT_2 ) * unitTarget -> GetDiseasesByCaster ( m_caster -> GetGUID ()));
2010-12-04 10:31:14 +01:00
break ;
}
2009-06-13 17:28:38 +02:00
break ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-12-17 23:27:01 -06:00
bool normalized = false ;
2010-12-11 20:37:38 +06:00
float weaponDamagePercentMod = 1.0f ;
2010-09-28 08:21:51 +03:00
for ( int j = 0 ; j < MAX_SPELL_EFFECTS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2010-12-11 20:37:38 +06:00
switch ( m_spellInfo -> Effect [ j ])
2008-10-11 14:16:25 -05:00
{
case SPELL_EFFECT_WEAPON_DAMAGE :
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL :
2009-05-31 15:56:51 -05:00
fixed_bonus += CalculateDamage ( j , unitTarget );
2008-10-11 14:16:25 -05:00
break ;
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG :
2009-05-31 15:56:51 -05:00
fixed_bonus += CalculateDamage ( j , unitTarget );
2008-10-11 14:16:25 -05:00
normalized = true ;
break ;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE :
2010-12-11 20:37:38 +06:00
ApplyPctN ( weaponDamagePercentMod , CalculateDamage ( j , unitTarget ));
2009-03-28 16:34:34 -06:00
break ;
2008-10-11 14:16:25 -05:00
default :
break ; // not weapon damage effect, just skip
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
2010-04-07 19:14:10 +02:00
if ( fixed_bonus || spell_bonus )
2008-10-11 14:16:25 -05:00
{
UnitMods unitMod ;
2010-12-11 20:37:38 +06:00
switch ( m_attackType )
2008-10-11 14:16:25 -05:00
{
default :
case BASE_ATTACK : unitMod = UNIT_MOD_DAMAGE_MAINHAND ; break ;
case OFF_ATTACK : unitMod = UNIT_MOD_DAMAGE_OFFHAND ; break ;
case RANGED_ATTACK : unitMod = UNIT_MOD_DAMAGE_RANGED ; break ;
}
2009-10-17 15:51:44 -07:00
2009-10-07 19:34:20 +02:00
float weapon_total_pct = 1.0f ;
2010-04-07 22:59:46 +02:00
if ( m_spellInfo -> SchoolMask & SPELL_SCHOOL_MASK_NORMAL )
2009-10-07 19:34:20 +02:00
weapon_total_pct = m_caster -> GetModifierValue ( unitMod , TOTAL_PCT );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( fixed_bonus )
2008-12-17 23:27:01 -06:00
fixed_bonus = int32 ( fixed_bonus * weapon_total_pct );
2010-04-07 19:14:10 +02:00
if ( spell_bonus )
2008-12-17 23:27:01 -06:00
spell_bonus = int32 ( spell_bonus * weapon_total_pct );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-10-07 19:34:20 +02:00
int32 weaponDamage = m_caster -> CalculateDamage ( m_attackType , normalized , true );
2009-10-17 15:51:44 -07:00
2008-12-17 23:27:01 -06:00
// Sequence is important
2010-09-28 08:21:51 +03:00
for ( int j = 0 ; j < MAX_SPELL_EFFECTS ; ++ j )
2008-12-17 23:27:01 -06:00
{
// We assume that a spell have at most one fixed_bonus
// and at most one weaponDamagePercentMod
2009-12-17 12:23:01 +01:00
switch ( m_spellInfo -> Effect [ j ])
2008-12-17 23:27:01 -06:00
{
case SPELL_EFFECT_WEAPON_DAMAGE :
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL :
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG :
weaponDamage += fixed_bonus ;
break ;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE :
weaponDamage = int32 ( weaponDamage * weaponDamagePercentMod );
default :
break ; // not weapon damage effect, just skip
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( spell_bonus )
2008-12-17 23:27:01 -06:00
weaponDamage += spell_bonus ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( totalDamagePercentMod != 1.0f )
2008-12-17 23:27:01 -06:00
weaponDamage = int32 ( weaponDamage * totalDamagePercentMod );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// prevent negative damage
2010-12-11 20:37:38 +06:00
uint32 eff_damage ( std :: max ( weaponDamage , 0 ));
2009-10-17 15:51:44 -07:00
2008-11-26 15:14:03 -06:00
// Add melee damage bonuses (also check for negative)
m_caster -> MeleeDamageBonus ( unitTarget , & eff_damage , m_attackType , m_spellInfo );
2010-12-11 20:37:38 +06:00
m_damage += eff_damage ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectThreat ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || ! m_caster -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> CanHaveThreatList ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
unitTarget -> AddThreat ( m_caster , float ( damage ));
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectHealMaxHealth ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-08-28 23:01:04 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-05-31 20:45:34 -05:00
int32 addhealth ;
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_PALADIN ) // Lay on Hands
2010-02-14 19:13:14 -07:00
{
2010-08-28 23:01:04 +02:00
if ( m_caster -> GetGUID () == unitTarget -> GetGUID ())
2010-03-25 17:09:05 +01:00
{
m_caster -> CastSpell ( m_caster , 25771 , true ); // Forbearance
m_caster -> CastSpell ( m_caster , 61988 , true ); // Immune shield marker (serverside)
m_caster -> CastSpell ( m_caster , 61987 , true ); // Avenging Wrath marker
}
2010-08-28 23:01:04 +02:00
}
2010-02-14 19:13:14 -07:00
2010-08-28 23:01:04 +02:00
// damage == 0 - heal for caster max health
if ( damage == 0 )
2009-05-31 20:45:34 -05:00
addhealth = m_caster -> GetMaxHealth ();
else
addhealth = unitTarget -> GetMaxHealth () - unitTarget -> GetHealth ();
2010-08-28 23:01:04 +02:00
2010-04-07 19:14:10 +02:00
if ( m_originalCaster )
2010-12-11 20:37:38 +06:00
m_healing += m_originalCaster -> SpellHealingBonus ( unitTarget , m_spellInfo , addhealth , HEAL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectInterruptCast ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-28 23:01:04 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// TODO: not all spells that used this effect apply cooldown at school spells
// also exist case: apply cooldown to interrupted cast only and to all spells
2009-08-19 16:52:51 -05:00
for ( uint32 i = CURRENT_FIRST_NON_MELEE_SPELL ; i < CURRENT_MAX_SPELL ; ++ i )
2008-10-11 14:16:25 -05:00
{
2009-08-19 16:52:51 -05:00
if ( Spell * spell = unitTarget -> GetCurrentSpell ( CurrentSpellTypes ( i )))
2008-10-11 14:16:25 -05:00
{
2009-08-19 16:52:51 -05:00
SpellEntry const * curSpellInfo = spell -> m_spellInfo ;
2008-10-11 14:16:25 -05:00
// check if we can interrupt spell
2009-08-19 16:52:51 -05:00
if (( spell -> getState () == SPELL_STATE_CASTING
2010-08-30 15:25:15 +02:00
|| ( spell -> getState () == SPELL_STATE_PREPARING && spell -> GetCastTime () > 0.0f ))
2010-04-07 22:59:46 +02:00
&& curSpellInfo -> InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT && curSpellInfo -> PreventionType == SPELL_PREVENTION_TYPE_SILENCE )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_originalCaster )
2008-12-15 09:55:57 -06:00
{
2009-04-06 13:31:14 +02:00
int32 duration = m_originalCaster -> ModSpellDuration ( m_spellInfo , unitTarget , m_originalCaster -> CalcSpellDuration ( m_spellInfo ), false );
2011-05-25 19:54:17 +07:00
unitTarget -> ProhibitSpellSchool ( GetSpellSchoolMask ( curSpellInfo ), duration /*GetSpellDuration(m_spellInfo)*/ );
2008-12-15 09:55:57 -06:00
}
2010-08-27 17:49:32 +02:00
ExecuteLogEffectInterruptCast ( effIndex , unitTarget , curSpellInfo -> Id );
2009-08-19 16:52:51 -05:00
unitTarget -> InterruptSpell ( CurrentSpellTypes ( i ), false );
2008-10-11 14:16:25 -05:00
}
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonObjectWild ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 gameobject_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameObject * pGameObj = new GameObject ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldObject * target = focusObject ;
2010-04-07 22:59:46 +02:00
if ( ! target )
2008-10-11 14:16:25 -05:00
target = m_caster ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
float x , y , z ;
2010-04-07 19:14:10 +02:00
if ( m_targets . HasDst ())
2009-08-29 23:20:16 -05:00
m_targets . m_dstPos . GetPosition ( x , y , z );
2008-10-11 14:16:25 -05:00
else
2009-05-31 15:56:51 -05:00
m_caster -> GetClosePoint ( x , y , z , DEFAULT_WORLD_OBJECT_SIZE );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Map * map = target -> GetMap ();
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
if ( ! pGameObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), gameobject_id , map ,
2009-04-27 18:36:10 -05:00
m_caster -> GetPhaseMask (), x , y , z , target -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 100 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
delete pGameObj ;
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2009-10-17 15:51:44 -07:00
2010-07-12 00:30:17 +02:00
pGameObj -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2008-10-11 14:16:25 -05:00
pGameObj -> SetSpellId ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , pGameObj );
2010-08-27 17:49:32 +02:00
2009-08-08 12:25:20 -05:00
// Wild object not have owner and check clickable by players
2008-10-11 14:16:25 -05:00
map -> Add ( pGameObj );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pGameObj -> GetGoType () == GAMEOBJECT_TYPE_FLAGDROP && m_caster -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
2010-03-11 20:51:31 +01:00
Player * pl = m_caster -> ToPlayer ();
2010-08-08 04:37:24 +02:00
Battleground * bg = pl -> GetBattleground ();
2009-10-17 15:51:44 -07:00
2009-08-08 12:25:20 -05:00
switch ( pGameObj -> GetMapId ())
2008-10-11 14:16:25 -05:00
{
2009-08-08 12:25:20 -05:00
case 489 : //WS
2008-10-11 14:16:25 -05:00
{
2010-05-26 11:34:37 +02:00
if ( bg && bg -> GetTypeID ( true ) == BATTLEGROUND_WS && bg -> GetStatus () == STATUS_IN_PROGRESS )
2009-08-08 12:25:20 -05:00
{
uint32 team = ALLIANCE ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pl -> GetTeam () == team )
2009-08-08 12:25:20 -05:00
team = HORDE ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
(( BattlegroundWS * ) bg ) -> SetDroppedFlagGUID ( pGameObj -> GetGUID (), team );
2009-08-08 12:25:20 -05:00
}
break ;
2008-10-11 14:16:25 -05:00
}
2009-08-08 12:25:20 -05:00
case 566 : //EY
2008-10-11 14:16:25 -05:00
{
2010-05-26 11:34:37 +02:00
if ( bg && bg -> GetTypeID ( true ) == BATTLEGROUND_EY && bg -> GetStatus () == STATUS_IN_PROGRESS )
2009-08-08 12:25:20 -05:00
{
2010-08-08 04:37:24 +02:00
(( BattlegroundEY * ) bg ) -> SetDroppedFlagGUID ( pGameObj -> GetGUID ());
2009-08-08 12:25:20 -05:00
}
break ;
2008-10-11 14:16:25 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( uint32 linkedEntry = pGameObj -> GetGOInfo () -> GetLinkedGameObjectEntry ())
2008-10-11 14:16:25 -05:00
{
GameObject * linkedGO = new GameObject ;
2010-12-22 21:25:23 +01:00
if ( linkedGO -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), linkedEntry , map ,
2009-04-27 18:36:10 -05:00
m_caster -> GetPhaseMask (), x , y , z , target -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 100 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
2010-07-12 00:30:17 +02:00
linkedGO -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2008-10-11 14:16:25 -05:00
linkedGO -> SetSpellId ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , linkedGO );
2010-08-27 17:49:32 +02:00
2009-08-08 12:25:20 -05:00
// Wild object not have owner and check clickable by players
2008-10-11 14:16:25 -05:00
map -> Add ( linkedGO );
}
else
{
delete linkedGO ;
linkedGO = NULL ;
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectScriptEffect ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
// TODO: we must implement hunter pet summon at login there (spell 6962)
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
switch ( m_spellInfo -> SpellFamilyName )
2008-10-11 14:16:25 -05:00
{
2009-01-20 19:59:43 -06:00
case SPELLFAMILY_GENERIC :
2008-12-06 14:01:44 -06:00
{
2009-01-20 19:59:43 -06:00
switch ( m_spellInfo -> Id )
{
2009-08-23 17:59:32 +02:00
// Glyph of Backstab
case 63975 :
{
2011-04-29 20:47:02 +02:00
if ( AuraEffect const * aurEff = unitTarget -> GetAuraEffect ( SPELL_AURA_PERIODIC_DAMAGE , SPELLFAMILY_ROGUE , 0x00100000 , 0 , 0 , m_caster -> GetGUID ()))
2009-08-23 17:59:32 +02:00
{
2010-01-10 01:23:15 +01:00
uint32 countMin = aurEff -> GetBase () -> GetMaxDuration ();
2009-08-23 17:59:32 +02:00
uint32 countMax = 12000 ;
countMax += m_caster -> HasAura ( 56801 ) ? 4000 : 0 ;
2009-10-17 15:51:44 -07:00
2009-08-23 17:59:32 +02:00
if ( countMin < countMax )
{
2010-01-10 01:23:15 +01:00
aurEff -> GetBase () -> SetDuration ( uint32 ( aurEff -> GetBase () -> GetDuration () + 3000 ));
aurEff -> GetBase () -> SetMaxDuration ( countMin + 2000 );
2009-08-23 17:59:32 +02:00
}
2009-10-17 15:51:44 -07:00
2009-08-23 17:59:32 +02:00
}
return ;
}
2009-07-22 17:10:30 +02:00
case 45204 : // Clone Me!
2011-04-08 23:16:57 +03:00
m_caster -> CastSpell ( unitTarget , damage , true );
break ;
2009-08-12 20:47:54 -05:00
case 55693 : // Remove Collapsing Cave Aura
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2009-08-12 20:47:54 -05:00
return ;
2010-07-14 16:57:13 +02:00
unitTarget -> RemoveAurasDueToSpell ( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , effIndex ));
2009-08-12 20:47:54 -05:00
break ;
2009-01-20 19:59:43 -06:00
// PX-238 Winter Wondervolt TRAP
case 26275 :
{
2009-01-21 16:18:57 -06:00
uint32 spells [ 4 ] = { 26272 , 26157 , 26273 , 26274 };
2009-10-17 15:51:44 -07:00
2009-01-21 16:18:57 -06:00
// check presence
2009-10-17 16:20:24 -07:00
for ( uint8 j = 0 ; j < 4 ; ++ j )
2011-04-29 20:47:02 +02:00
if ( unitTarget -> HasAuraEffect ( spells [ j ], 0 ))
2009-01-21 16:18:57 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-21 16:18:57 -06:00
// select spell
2011-04-29 20:47:02 +02:00
uint32 iTmpSpellId = spells [ urand ( 0 , 3 )];
2009-10-17 15:51:44 -07:00
2009-01-21 16:18:57 -06:00
// cast
2009-01-20 19:59:43 -06:00
unitTarget -> CastSpell ( unitTarget , iTmpSpellId , true );
return ;
}
// Bending Shinbone
case 8856 :
{
2010-04-07 19:14:10 +02:00
if ( ! itemTarget && m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
uint32 spell_id = 0 ;
2009-05-31 15:56:51 -05:00
switch ( urand ( 1 , 5 ))
2009-01-20 19:59:43 -06:00
{
case 1 : spell_id = 8854 ; break ;
default : spell_id = 8855 ; break ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( m_caster , spell_id , true , NULL );
2009-01-20 19:59:43 -06:00
return ;
}
// Brittle Armor - need remove one 24575 Brittle Armor aura
case 24590 :
2009-04-06 13:31:14 +02:00
unitTarget -> RemoveAuraFromStack ( 24575 );
2009-01-20 19:59:43 -06:00
return ;
// Mercurial Shield - need remove one 26464 Mercurial Shield aura
case 26465 :
2009-04-06 13:31:14 +02:00
unitTarget -> RemoveAuraFromStack ( 26464 );
2009-01-20 19:59:43 -06:00
return ;
// Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
case 22539 :
case 22972 :
case 22975 :
case 22976 :
case 22977 :
case 22978 :
case 22979 :
case 22980 :
case 22981 :
case 22982 :
case 22983 :
case 22984 :
case 22985 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive ())
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// Onyxia Scale Cloak
2010-04-07 19:14:10 +02:00
if ( unitTarget -> HasAura ( 22683 ))
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// Shadow Flame
m_caster -> CastSpell ( unitTarget , 22682 , true );
return ;
}
// Piccolo of the Flaming Fire
case 17512 :
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-01-20 19:59:43 -06:00
return ;
unitTarget -> HandleEmoteCommand ( EMOTE_STATE_DANCE );
2009-03-09 18:09:00 -06:00
return ;
}
// Escape artist
case 20589 :
2010-09-05 13:59:49 +02:00
m_caster -> RemoveMovementImpairingAuras ();
2009-04-06 13:31:14 +02:00
return ;
2009-05-16 14:49:58 -05:00
// Decimate
case 28374 :
case 54426 :
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2009-05-16 14:49:58 -05:00
{
2010-08-26 01:20:57 +06:00
int32 damage = int32 ( unitTarget -> GetHealth ()) - int32 ( unitTarget -> CountPctFromMaxHealth ( 5 ));
2010-04-07 19:14:10 +02:00
if ( damage > 0 )
2009-05-16 14:49:58 -05:00
m_caster -> CastCustomSpell ( 28375 , SPELLVALUE_BASE_POINT0 , damage , unitTarget );
}
return ;
2009-01-20 19:59:43 -06:00
// Mirren's Drinking Hat
case 29830 :
{
uint32 item = 0 ;
2010-04-07 22:59:46 +02:00
switch ( urand ( 1 , 6 ))
2009-01-20 19:59:43 -06:00
{
2009-05-31 15:56:51 -05:00
case 1 :
case 2 :
case 3 :
item = 23584 ; break ; // Loch Modan Lager
case 4 :
case 5 :
item = 23585 ; break ; // Stouthammer Lite
2009-01-20 19:59:43 -06:00
case 6 :
2009-05-31 15:56:51 -05:00
item = 23586 ; break ; // Aerie Peak Pale Ale
2009-01-20 19:59:43 -06:00
}
if ( item )
2011-04-29 20:47:02 +02:00
DoCreateItem ( effIndex , item );
2009-01-20 19:59:43 -06:00
break ;
}
// Improved Sprint
case 30918 :
{
// Removes snares and roots.
2009-08-11 19:57:27 +02:00
unitTarget -> RemoveMovementImpairingAuras ();
2009-01-20 19:59:43 -06:00
break ;
}
2009-12-24 13:01:39 +01:00
// Spirit Walk
case 58876 :
{
// Removes snares and roots.
unitTarget -> RemoveMovementImpairingAuras ();
break ;
}
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
// Plant Warmaul Ogre Banner
case 32307 :
{
Player * p_caster = dynamic_cast < Player *> ( m_caster );
if ( ! p_caster )
break ;
p_caster -> RewardPlayerAndGroupAtEvent ( 18388 , unitTarget );
Creature * cTarget = dynamic_cast < Creature *> ( unitTarget );
if ( ! cTarget )
break ;
cTarget -> setDeathState ( CORPSE );
cTarget -> RemoveCorpse ();
break ;
}
2009-02-12 17:21:33 -06:00
case 48025 : // Headless Horseman's Mount
{
2010-05-22 22:57:16 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-02-12 17:21:33 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill and zone
bool canFly = true ;
uint32 v_map = GetVirtualMapForMapAndZone ( unitTarget -> GetMapId (), unitTarget -> GetZoneId ());
if ( v_map != 530 && v_map != 571 )
canFly = false ;
if ( canFly && v_map == 571 && ! unitTarget -> ToPlayer () -> HasSpell ( 54197 ))
canFly = false ;
float x , y , z ;
unitTarget -> GetPosition ( x , y , z );
uint32 areaFlag = unitTarget -> GetBaseMap () -> GetAreaFlag ( x , y , z );
AreaTableEntry const * pArea = sAreaStore . LookupEntry ( areaFlag );
2010-11-16 14:08:12 +01:00
if ( ! pArea || ( canFly && ( pArea -> flags & AREA_FLAG_NO_FLY_ZONE )))
2010-05-22 22:57:16 +02:00
canFly = false ;
switch ( unitTarget -> ToPlayer () -> GetBaseSkillValue ( SKILL_RIDING ))
2009-02-12 17:21:33 -06:00
{
2010-05-22 22:57:16 +02:00
case 75 : unitTarget -> CastSpell ( unitTarget , 51621 , true ); break ;
case 150 : unitTarget -> CastSpell ( unitTarget , 48024 , true ); break ;
case 225 :
{
if ( canFly )
2009-12-18 13:41:30 -08:00
unitTarget -> CastSpell ( unitTarget , 51617 , true );
2010-05-22 22:57:16 +02:00
else
unitTarget -> CastSpell ( unitTarget , 48024 , true );
} break ;
case 300 :
{
if ( canFly )
2009-12-18 13:41:30 -08:00
unitTarget -> CastSpell ( unitTarget , 48023 , true );
2010-05-22 22:57:16 +02:00
else
unitTarget -> CastSpell ( unitTarget , 48024 , true );
} break ;
2009-02-12 17:21:33 -06:00
}
2010-05-22 22:57:16 +02:00
return ;
2009-02-12 17:21:33 -06:00
}
2009-02-15 11:57:00 -06:00
case 47977 : // Magic Broom
{
2010-05-22 22:57:16 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-02-15 11:57:00 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill and zone
bool canFly = true ;
uint32 v_map = GetVirtualMapForMapAndZone ( unitTarget -> GetMapId (), unitTarget -> GetZoneId ());
if ( v_map != 530 && v_map != 571 )
canFly = false ;
if ( canFly && v_map == 571 && ! unitTarget -> ToPlayer () -> HasSpell ( 54197 ))
canFly = false ;
float x , y , z ;
unitTarget -> GetPosition ( x , y , z );
uint32 areaFlag = unitTarget -> GetBaseMap () -> GetAreaFlag ( x , y , z );
AreaTableEntry const * pArea = sAreaStore . LookupEntry ( areaFlag );
2010-11-16 14:08:12 +01:00
if ( ! pArea || ( canFly && ( pArea -> flags & AREA_FLAG_NO_FLY_ZONE )))
2010-05-22 22:57:16 +02:00
canFly = false ;
switch ( unitTarget -> ToPlayer () -> GetBaseSkillValue ( SKILL_RIDING ))
2009-02-15 11:57:00 -06:00
{
2010-05-22 22:57:16 +02:00
case 75 : unitTarget -> CastSpell ( unitTarget , 42680 , true ); break ;
case 150 : unitTarget -> CastSpell ( unitTarget , 42683 , true ); break ;
case 225 :
2009-02-15 11:57:00 -06:00
{
2010-05-22 22:57:16 +02:00
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 42667 , true );
else
unitTarget -> CastSpell ( unitTarget , 42683 , true );
} break ;
case 300 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 42668 , true );
else
unitTarget -> CastSpell ( unitTarget , 42683 , true );
} break ;
2009-02-15 11:57:00 -06:00
}
2010-05-22 22:57:16 +02:00
return ;
2009-02-15 11:57:00 -06:00
}
2009-08-11 19:57:27 +02:00
// Mug Transformation
2009-01-20 19:59:43 -06:00
case 41931 :
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-19 19:55:24 -08:00
uint8 bag = 19 ;
uint8 slot = 0 ;
Item * item = NULL ;
2009-10-17 15:51:44 -07:00
2010-08-30 15:25:15 +02:00
while ( bag ) // 256 = 0 due to var type
2009-01-20 19:59:43 -06:00
{
2010-03-07 15:20:19 +01:00
item = m_caster -> ToPlayer () -> GetItemByPos ( bag , slot );
2009-01-20 19:59:43 -06:00
if ( item && item -> GetEntry () == 38587 ) break ;
2009-11-19 19:55:24 -08:00
++ slot ;
2009-01-20 19:59:43 -06:00
if ( slot == 39 )
{
slot = 0 ;
2009-11-19 19:55:24 -08:00
++ bag ;
2009-01-20 19:59:43 -06:00
}
}
2010-08-30 15:25:15 +02:00
if ( bag )
2009-01-20 19:59:43 -06:00
{
2011-04-29 20:47:02 +02:00
if ( m_caster -> ToPlayer () -> GetItemByPos ( bag , slot ) -> GetCount () == 1 ) m_caster -> ToPlayer () -> RemoveItem ( bag , slot , true );
else m_caster -> ToPlayer () -> GetItemByPos ( bag , slot ) -> SetCount ( m_caster -> ToPlayer () -> GetItemByPos ( bag , slot ) -> GetCount () - 1 );
2009-01-20 19:59:43 -06:00
// Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
2009-11-19 19:55:24 -08:00
m_caster -> CastSpell ( m_caster , 42518 , true );
2009-01-20 19:59:43 -06:00
return ;
}
break ;
}
2009-11-19 19:55:24 -08:00
// Brutallus - Burn
case 45141 :
case 45151 :
{
//Workaround for Range ... should be global for every ScriptEffect
2009-11-19 20:03:35 -08:00
float radius = GetSpellRadiusForHostile ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2009-11-19 19:55:24 -08:00
if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER && unitTarget -> GetDistance ( m_caster ) >= radius && ! unitTarget -> HasAura ( 46394 ) && unitTarget != m_caster )
unitTarget -> CastSpell ( unitTarget , 46394 , true );
break ;
}
2009-01-20 19:59:43 -06:00
// Goblin Weather Machine
case 46203 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-04-27 18:42:35 -05:00
uint32 spellId = 0 ;
2009-05-31 15:56:51 -05:00
switch ( rand () % 4 )
2009-01-20 19:59:43 -06:00
{
2009-01-21 16:18:57 -06:00
case 0 : spellId = 46740 ; break ;
case 1 : spellId = 46739 ; break ;
case 2 : spellId = 46738 ; break ;
case 3 : spellId = 46736 ; break ;
2009-01-20 19:59:43 -06:00
}
unitTarget -> CastSpell ( unitTarget , spellId , true );
break ;
}
2011-04-29 20:47:02 +02:00
// 5, 000 Gold
2009-01-20 19:59:43 -06:00
case 46642 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> ModifyMoney ( 5000 * GOLD );
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
break ;
}
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
// Roll Dice - Decahedral Dwarven Dice
case 47770 :
{
char buf [ 128 ];
2010-08-30 15:25:15 +02:00
const char * gender = "his" ;
2010-04-07 19:14:10 +02:00
if ( m_caster -> getGender () > 0 )
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
gender = "her" ;
2011-04-29 20:47:02 +02:00
sprintf ( buf , "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u." , m_caster -> GetName (), gender , gender , urand ( 1 , 10 ), urand ( 1 , 10 ));
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
m_caster -> MonsterTextEmote ( buf , 0 );
break ;
}
// Roll 'dem Bones - Worn Troll Dice
case 47776 :
{
char buf [ 128 ];
2010-08-30 15:25:15 +02:00
const char * gender = "his" ;
2010-04-07 19:14:10 +02:00
if ( m_caster -> getGender () > 0 )
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
gender = "her" ;
2011-04-29 20:47:02 +02:00
sprintf ( buf , "%s causually tosses %s [Worn Troll Dice]. One %u and one %u." , m_caster -> GetName (), gender , urand ( 1 , 6 ), urand ( 1 , 6 ));
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
m_caster -> MonsterTextEmote ( buf , 0 );
break ;
}
2009-05-21 20:02:22 +02:00
// Vigilance
case 50725 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-05-21 20:02:22 +02:00
return ;
2009-10-17 15:51:44 -07:00
2009-05-21 20:02:22 +02:00
// Remove Taunt cooldown
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> RemoveSpellCooldown ( 355 , true );
2009-10-17 15:51:44 -07:00
2009-05-21 20:02:22 +02:00
return ;
}
2009-08-11 19:57:27 +02:00
// Death Knight Initiate Visual
case 51519 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT )
2009-08-11 19:57:27 +02:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-11 19:57:27 +02:00
uint32 iTmpSpellId = 0 ;
switch ( unitTarget -> GetDisplayId ())
{
case 25369 : iTmpSpellId = 51552 ; break ; // bloodelf female
case 25373 : iTmpSpellId = 51551 ; break ; // bloodelf male
case 25363 : iTmpSpellId = 51542 ; break ; // draenei female
case 25357 : iTmpSpellId = 51541 ; break ; // draenei male
case 25361 : iTmpSpellId = 51537 ; break ; // dwarf female
case 25356 : iTmpSpellId = 51538 ; break ; // dwarf male
case 25372 : iTmpSpellId = 51550 ; break ; // forsaken female
case 25367 : iTmpSpellId = 51549 ; break ; // forsaken male
case 25362 : iTmpSpellId = 51540 ; break ; // gnome female
case 25359 : iTmpSpellId = 51539 ; break ; // gnome male
case 25355 : iTmpSpellId = 51534 ; break ; // human female
case 25354 : iTmpSpellId = 51520 ; break ; // human male
case 25360 : iTmpSpellId = 51536 ; break ; // nightelf female
case 25358 : iTmpSpellId = 51535 ; break ; // nightelf male
case 25368 : iTmpSpellId = 51544 ; break ; // orc female
case 25364 : iTmpSpellId = 51543 ; break ; // orc male
case 25371 : iTmpSpellId = 51548 ; break ; // tauren female
case 25366 : iTmpSpellId = 51547 ; break ; // tauren male
case 25370 : iTmpSpellId = 51545 ; break ; // troll female
case 25365 : iTmpSpellId = 51546 ; break ; // troll male
default : return ;
}
2009-10-17 15:51:44 -07:00
2009-08-11 19:57:27 +02:00
unitTarget -> CastSpell ( unitTarget , iTmpSpellId , true );
2010-03-07 18:30:53 +01:00
Creature * npc = unitTarget -> ToCreature ();
2009-08-11 19:57:27 +02:00
npc -> LoadEquipment ( npc -> GetEquipmentId ());
return ;
}
2009-01-20 19:59:43 -06:00
// Emblazon Runeblade
case 51770 :
{
2010-04-07 19:14:10 +02:00
if ( ! m_originalCaster )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-03-15 00:48:35 -06:00
m_originalCaster -> CastSpell ( m_originalCaster , damage , false );
2009-01-20 19:59:43 -06:00
break ;
}
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
// Deathbolt from Thalgran Blightbringer
// reflected by Freya's Ward
// Retribution by Sevenfold Retribution
case 51854 :
{
2010-12-22 20:18:34 +02:00
if ( ! unitTarget )
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
return ;
if ( unitTarget -> HasAura ( 51845 ))
unitTarget -> CastSpell ( m_caster , 51856 , true );
else
m_caster -> CastSpell ( unitTarget , 51855 , true );
break ;
}
2009-05-25 22:52:08 -05:00
// Summon Ghouls On Scarlet Crusade
case 51904 :
{
2010-04-07 19:14:10 +02:00
if ( ! m_targets . HasDst ())
2009-05-25 22:52:08 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-05-25 22:52:08 -05:00
float x , y , z ;
float radius = GetSpellRadius ( m_spellInfo , effIndex , true );
*Implement spells: 781, 13280, 32307, 40109, 47770, 47776, 49625, 49634, 51854, 64385, by Warhead
2009-10-31 04:28:02 -07:00
for ( uint8 i = 0 ; i < 15 ; ++ i )
2009-05-25 22:52:08 -05:00
{
2009-08-29 23:20:16 -05:00
m_caster -> GetRandomPoint ( m_targets . m_dstPos , radius , x , y , z );
2009-05-25 22:52:08 -05:00
m_caster -> CastSpell ( x , y , z , 54522 , true );
}
break ;
2009-05-27 23:33:21 -05:00
}
2009-08-05 17:00:01 +02:00
case 52173 : // Coyote Spirit Despawn
case 60243 : // Blood Parrot Despawn
2010-03-07 18:30:53 +01:00
if ( unitTarget -> GetTypeId () == TYPEID_UNIT && unitTarget -> ToCreature () -> isSummon ())
2010-03-27 16:08:14 +01:00
unitTarget -> ToTempSummon () -> UnSummon ();
2009-08-05 17:00:01 +02:00
return ;
2009-06-03 23:24:57 -05:00
case 52479 : // Gift of the Harvester
2010-04-07 19:14:10 +02:00
if ( unitTarget && m_originalCaster )
2009-06-03 23:24:57 -05:00
m_originalCaster -> CastSpell ( unitTarget , urand ( 0 , 1 ) ? damage : 52505 , true );
return ;
2009-06-14 21:05:37 -05:00
case 53110 : // Devour Humanoid
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2009-06-14 21:05:37 -05:00
unitTarget -> CastSpell ( m_caster , damage , true );
return ;
2009-04-29 00:17:33 -05:00
// Winged Steed of the Ebon Blade
case 54729 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-04-29 00:17:33 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Prevent stacking of mounts and client crashes upon dismounting
2009-04-29 01:00:15 -05:00
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Triggered spell id dependent on riding skill
2010-04-07 19:14:10 +02:00
if ( uint16 skillval = unitTarget -> ToPlayer () -> GetSkillValue ( SKILL_RIDING ))
2009-04-29 00:17:33 -05:00
{
if ( skillval >= 300 )
unitTarget -> CastSpell ( unitTarget , 54727 , true );
else
unitTarget -> CastSpell ( unitTarget , 54726 , true );
}
return ;
}
2009-03-29 17:18:51 -06:00
case 58418 : // Portal to Orgrimmar
case 58420 : // Portal to Stormwind
{
2010-04-08 08:20:08 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER || effIndex != 0 )
2009-03-29 17:18:51 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-07-14 16:57:13 +02:00
uint32 spellID = SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 0 );
uint32 questID = SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , 1 );
2009-10-17 15:51:44 -07:00
2011-01-13 23:06:59 +01:00
if ( unitTarget -> ToPlayer () -> GetQuestStatus ( questID ) == QUEST_STATUS_COMPLETE )
2009-03-29 17:18:51 -06:00
unitTarget -> CastSpell ( unitTarget , spellID , true );
2009-10-17 15:51:44 -07:00
2009-03-29 17:18:51 -06:00
return ;
}
2009-05-23 01:43:46 -05:00
case 58941 : // Rock Shards
2010-04-07 19:14:10 +02:00
if ( unitTarget && m_originalCaster )
2009-05-23 01:43:46 -05:00
{
2009-10-17 16:20:24 -07:00
for ( uint32 i = 0 ; i < 3 ; ++ i )
2009-05-23 01:43:46 -05:00
{
m_originalCaster -> CastSpell ( unitTarget , 58689 , true );
m_originalCaster -> CastSpell ( unitTarget , 58692 , true );
}
2010-04-07 19:14:10 +02:00
if ((( InstanceMap * ) m_originalCaster -> GetMap ()) -> GetDifficulty () == REGULAR_DIFFICULTY )
2009-05-23 01:43:46 -05:00
{
2009-12-17 12:23:01 +01:00
m_originalCaster -> CastSpell ( unitTarget , 58695 , true );
m_originalCaster -> CastSpell ( unitTarget , 58696 , true );
2009-05-23 01:43:46 -05:00
}
else
{
2009-12-17 12:23:01 +01:00
m_originalCaster -> CastSpell ( unitTarget , 60883 , true );
m_originalCaster -> CastSpell ( unitTarget , 60884 , true );
2009-05-23 01:43:46 -05:00
}
}
return ;
2009-08-05 17:00:01 +02:00
case 58983 : // Big Blizzard Bear
2009-08-05 16:00:36 +02:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-08-05 16:00:36 +02:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Prevent stacking of mounts and client crashes upon dismounting
2009-08-05 16:00:36 +02:00
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
2009-10-17 15:51:44 -07:00
2010-05-22 22:57:16 +02:00
// Triggered spell id dependent on riding skill
2010-04-07 19:14:10 +02:00
if ( uint16 skillval = unitTarget -> ToPlayer () -> GetSkillValue ( SKILL_RIDING ))
2009-08-05 16:00:36 +02:00
{
if ( skillval >= 150 )
unitTarget -> CastSpell ( unitTarget , 58999 , true );
else
unitTarget -> CastSpell ( unitTarget , 58997 , true );
}
return ;
}
2010-09-06 12:22:19 +02:00
case 63845 : // Create Lance
{
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
if ( m_caster -> ToPlayer () -> GetTeam () == ALLIANCE )
m_caster -> CastSpell ( m_caster , 63914 , true );
else
m_caster -> CastSpell ( m_caster , 63919 , true );
return ;
}
2010-05-22 22:57:16 +02:00
case 71342 : // Big Love Rocket
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill and zone
bool canFly = true ;
uint32 v_map = GetVirtualMapForMapAndZone ( unitTarget -> GetMapId (), unitTarget -> GetZoneId ());
if ( v_map != 530 && v_map != 571 )
canFly = false ;
if ( canFly && v_map == 571 && ! unitTarget -> ToPlayer () -> HasSpell ( 54197 ))
canFly = false ;
float x , y , z ;
unitTarget -> GetPosition ( x , y , z );
uint32 areaFlag = unitTarget -> GetBaseMap () -> GetAreaFlag ( x , y , z );
AreaTableEntry const * pArea = sAreaStore . LookupEntry ( areaFlag );
2010-11-16 14:08:12 +01:00
if ( ! pArea || ( canFly && ( pArea -> flags & AREA_FLAG_NO_FLY_ZONE )))
2010-05-22 22:57:16 +02:00
canFly = false ;
switch ( unitTarget -> ToPlayer () -> GetBaseSkillValue ( SKILL_RIDING ))
{
case 0 : unitTarget -> CastSpell ( unitTarget , 71343 , true ); break ;
case 75 : unitTarget -> CastSpell ( unitTarget , 71344 , true ); break ;
case 150 : unitTarget -> CastSpell ( unitTarget , 71345 , true ); break ;
case 225 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 71346 , true );
else
unitTarget -> CastSpell ( unitTarget , 71345 , true );
} break ;
case 300 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 71347 , true );
else
unitTarget -> CastSpell ( unitTarget , 71345 , true );
} break ;
}
return ;
}
case 72286 : // Invincible
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill and zone
bool canFly = true ;
uint32 v_map = GetVirtualMapForMapAndZone ( unitTarget -> GetMapId (), unitTarget -> GetZoneId ());
if ( v_map != 530 && v_map != 571 )
canFly = false ;
if ( canFly && v_map == 571 && ! unitTarget -> ToPlayer () -> HasSpell ( 54197 ))
canFly = false ;
float x , y , z ;
unitTarget -> GetPosition ( x , y , z );
uint32 areaFlag = unitTarget -> GetBaseMap () -> GetAreaFlag ( x , y , z );
AreaTableEntry const * pArea = sAreaStore . LookupEntry ( areaFlag );
2010-11-16 14:08:12 +01:00
if ( ! pArea || ( canFly && ( pArea -> flags & AREA_FLAG_NO_FLY_ZONE )))
2010-05-22 22:57:16 +02:00
canFly = false ;
switch ( unitTarget -> ToPlayer () -> GetBaseSkillValue ( SKILL_RIDING ))
{
case 75 : unitTarget -> CastSpell ( unitTarget , 72281 , true ); break ;
case 150 : unitTarget -> CastSpell ( unitTarget , 72282 , true ); break ;
case 225 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 72283 , true );
else
unitTarget -> CastSpell ( unitTarget , 72282 , true );
} break ;
case 300 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 72284 , true );
else
unitTarget -> CastSpell ( unitTarget , 72282 , true );
} break ;
}
return ;
}
case 74856 : // Blazing Hippogryph
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill
if ( uint16 skillval = unitTarget -> ToPlayer () -> GetSkillValue ( SKILL_RIDING ))
{
if ( skillval >= 300 )
unitTarget -> CastSpell ( unitTarget , 74855 , true );
else
unitTarget -> CastSpell ( unitTarget , 74854 , true );
}
return ;
}
2010-05-24 16:11:35 +02:00
case 75614 : // Celestial Steed
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
// Prevent stacking of mounts and client crashes upon dismounting
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill and zone
bool canFly = true ;
uint32 v_map = GetVirtualMapForMapAndZone ( unitTarget -> GetMapId (), unitTarget -> GetZoneId ());
if ( v_map != 530 && v_map != 571 )
canFly = false ;
if ( canFly && v_map == 571 && ! unitTarget -> ToPlayer () -> HasSpell ( 54197 ))
canFly = false ;
float x , y , z ;
unitTarget -> GetPosition ( x , y , z );
uint32 areaFlag = unitTarget -> GetBaseMap () -> GetAreaFlag ( x , y , z );
AreaTableEntry const * pArea = sAreaStore . LookupEntry ( areaFlag );
2010-11-16 14:08:12 +01:00
if ( ! pArea || ( canFly && ( pArea -> flags & AREA_FLAG_NO_FLY_ZONE )))
2010-05-24 16:11:35 +02:00
canFly = false ;
switch ( unitTarget -> ToPlayer () -> GetBaseSkillValue ( SKILL_RIDING ))
{
case 75 : unitTarget -> CastSpell ( unitTarget , 75619 , true ); break ;
case 150 : unitTarget -> CastSpell ( unitTarget , 75620 , true ); break ;
case 225 :
{
if ( canFly )
unitTarget -> CastSpell ( unitTarget , 75617 , true );
else
unitTarget -> CastSpell ( unitTarget , 75620 , true );
} break ;
case 300 :
{
if ( canFly )
{
if ( unitTarget -> ToPlayer () -> Has310Flyer ( false ))
unitTarget -> CastSpell ( unitTarget , 76153 , true );
else
unitTarget -> CastSpell ( unitTarget , 75618 , true );
}
else
unitTarget -> CastSpell ( unitTarget , 75620 , true );
} break ;
}
return ;
}
case 75973 : // X-53 Touring Rocket
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
// Prevent stacking of mounts
unitTarget -> RemoveAurasByType ( SPELL_AURA_MOUNTED );
// Triggered spell id dependent on riding skill
if ( uint16 skillval = unitTarget -> ToPlayer () -> GetSkillValue ( SKILL_RIDING ))
{
if ( skillval >= 300 )
{
if ( unitTarget -> ToPlayer () -> Has310Flyer ( false ))
unitTarget -> CastSpell ( unitTarget , 76154 , true );
else
unitTarget -> CastSpell ( unitTarget , 75972 , true );
}
else
unitTarget -> CastSpell ( unitTarget , 75957 , true );
}
return ;
}
2009-05-05 14:46:32 -05:00
case 59317 : // Teleporting
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
2009-10-17 15:51:44 -07:00
2009-05-05 14:46:32 -05:00
// return from top
2010-03-07 15:20:19 +01:00
if ( unitTarget -> ToPlayer () -> GetAreaId () == 4637 )
2009-05-05 14:46:32 -05:00
unitTarget -> CastSpell ( unitTarget , 59316 , true );
// teleport atop
else
unitTarget -> CastSpell ( unitTarget , 59314 , true );
2009-10-17 15:51:44 -07:00
2009-05-05 14:46:32 -05:00
return ;
2009-01-20 19:59:43 -06:00
// random spell learn instead placeholder
case 60893 : // Northrend Alchemy Research
case 61177 : // Northrend Inscription Research
case 61288 : // Minor Inscription Research
2009-01-22 22:44:27 -06:00
case 61756 : // Northrend Inscription Research (FAST QA VERSION)
2009-07-30 10:55:13 +08:00
case 64323 : // Book of Glyph Mastery
2009-01-20 19:59:43 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-21 16:18:57 -06:00
// learn random explicit discovery recipe (if any)
2011-03-04 21:18:38 +01:00
if ( uint32 discoveredSpell = GetExplicitDiscoverySpell ( m_spellInfo -> Id , m_caster -> ToPlayer ()))
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> learnSpell ( discoveredSpell , false );
2008-10-11 14:16:25 -05:00
return ;
2009-01-20 19:59:43 -06:00
}
2009-06-14 09:57:57 -05:00
case 62428 : // Load into Catapult
2009-12-17 13:07:38 +01:00
{
2010-04-07 19:14:10 +02:00
if ( Vehicle * seat = m_caster -> GetVehicleKit ())
if ( Unit * passenger = seat -> GetPassenger ( 0 ))
if ( Unit * demolisher = m_caster -> GetVehicleBase ())
2009-08-23 01:08:09 -05:00
passenger -> CastSpell ( demolisher , damage , true );
2009-06-14 09:57:57 -05:00
return ;
2009-12-17 13:07:38 +01:00
}
2009-08-28 11:26:20 -05:00
case 62482 : // Grab Crate
2009-12-17 13:07:38 +01:00
{
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2009-08-28 11:26:20 -05:00
{
2010-04-07 19:14:10 +02:00
if ( Vehicle * seat = m_caster -> GetVehicleKit ())
2009-08-28 11:26:20 -05:00
{
2010-04-07 19:14:10 +02:00
if ( Creature * oldContainer = dynamic_cast < Creature *> ( seat -> GetPassenger ( 1 )))
2009-08-28 11:26:20 -05:00
oldContainer -> DisappearAndDie ();
2009-08-29 23:20:16 -05:00
// TODO: a hack, range = 11, should after some time cast, otherwise too far
2010-12-25 03:18:21 +01:00
m_caster -> CastSpell ( seat -> GetBase (), 62496 , true );
2011-03-04 21:16:27 +01:00
unitTarget -> EnterVehicle ( m_caster , 1 );
2009-08-28 11:26:20 -05:00
}
}
return ;
2009-12-17 12:23:01 +01:00
}
2009-08-17 02:53:39 +02:00
case 60123 : // Lightwell
2009-08-10 15:52:11 -05:00
{
2010-03-07 18:30:53 +01:00
if ( m_caster -> GetTypeId () != TYPEID_UNIT || ! m_caster -> ToCreature () -> isSummon ())
2009-08-17 02:53:39 +02:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
uint32 spell_heal ;
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
switch ( m_caster -> GetEntry ())
{
case 31897 : spell_heal = 7001 ; break ;
case 31896 : spell_heal = 27873 ; break ;
case 31895 : spell_heal = 27874 ; break ;
case 31894 : spell_heal = 28276 ; break ;
case 31893 : spell_heal = 48084 ; break ;
case 31883 : spell_heal = 48085 ; break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Unknown Lightwell spell caster %u" , m_caster -> GetEntry ());
2009-08-17 02:53:39 +02:00
return ;
2009-08-10 15:52:11 -05:00
}
2009-08-17 02:53:39 +02:00
Aura * chargesaura = m_caster -> GetAura ( 59907 );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( chargesaura && chargesaura -> GetCharges () > 1 )
2009-08-17 02:53:39 +02:00
{
2010-01-10 01:23:15 +01:00
chargesaura -> SetCharges ( chargesaura -> GetCharges () - 1 );
2010-03-27 16:08:14 +01:00
m_caster -> CastSpell ( unitTarget , spell_heal , true , NULL , NULL , m_caster -> ToTempSummon () -> GetSummonerGUID ());
2009-08-17 02:53:39 +02:00
}
else
2010-03-27 16:08:14 +01:00
m_caster -> ToTempSummon () -> UnSummon ();
2009-08-23 01:08:09 -05:00
return ;
2009-08-10 15:52:11 -05:00
}
2009-09-14 13:34:23 -07:00
// Stoneclaw Totem
case 55328 : // Rank 1
case 55329 : // Rank 2
case 55330 : // Rank 3
case 55332 : // Rank 4
case 55333 : // Rank 5
case 55335 : // Rank 6
case 55278 : // Rank 7
case 58589 : // Rank 8
case 58590 : // Rank 9
case 58591 : // Rank 10
{
int32 basepoints0 = damage ;
// Cast Absorb on totems
2009-10-17 16:20:24 -07:00
for ( uint8 slot = SUMMON_SLOT_TOTEM ; slot < MAX_TOTEM_SLOT ; ++ slot )
2009-09-14 13:34:23 -07:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> m_SummonSlot [ slot ])
2009-09-14 13:34:23 -07:00
continue ;
2009-10-17 15:51:44 -07:00
2009-09-14 13:34:23 -07:00
Creature * totem = unitTarget -> GetMap () -> GetCreature ( unitTarget -> m_SummonSlot [ slot ]);
2010-04-07 19:14:10 +02:00
if ( totem && totem -> isTotem ())
2009-09-14 13:34:23 -07:00
{
m_caster -> CastCustomSpell ( totem , 55277 , & basepoints0 , NULL , NULL , true );
}
}
// Glyph of Stoneclaw Totem
if ( AuraEffect * aur = unitTarget -> GetAuraEffect ( 63298 , 0 ))
{
basepoints0 *= aur -> GetAmount ();
m_caster -> CastCustomSpell ( unitTarget , 55277 , & basepoints0 , NULL , NULL , true );
}
break ;
}
2009-12-27 18:01:34 -03:00
case 66545 : //Summon Memory
{
2011-04-29 20:47:02 +02:00
uint8 uiRandom = urand ( 0 , 25 );
uint32 uiSpells [ 26 ] = { 66704 , 66705 , 66706 , 66707 , 66709 , 66710 , 66711 , 66712 , 66713 , 66714 , 66715 , 66708 , 66708 , 66691 , 66692 , 66694 , 66695 , 66696 , 66697 , 66698 , 66699 , 66700 , 66701 , 66702 , 66703 , 66543 };
2009-12-27 18:01:34 -03:00
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( m_caster , uiSpells [ uiRandom ], true );
2009-12-27 18:01:34 -03:00
break ;
}
2010-02-23 23:48:07 +01:00
case 45668 : // Ultra-Advanced Proto-Typical Shortening Blaster
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT )
return ;
2010-04-07 18:09:10 +02:00
2010-02-23 23:48:07 +01:00
if ( roll_chance_i ( 50 )) // chance unknown, using 50
return ;
2010-04-07 18:09:10 +02:00
2010-02-23 23:48:07 +01:00
static uint32 const spellPlayer [ 5 ] =
{
45674 , // Bigger!
45675 , // Shrunk
45678 , // Yellow
45682 , // Ghost
45684 // Polymorph
};
2010-04-07 18:09:10 +02:00
2010-02-23 23:48:07 +01:00
static uint32 const spellTarget [ 5 ] = {
45673 , // Bigger!
45672 , // Shrunk
45677 , // Yellow
45681 , // Ghost
45683 // Polymorph
};
2010-04-07 18:09:10 +02:00
2011-04-29 20:47:02 +02:00
m_caster -> CastSpell ( m_caster , spellPlayer [ urand ( 0 , 4 )], true );
unitTarget -> CastSpell ( unitTarget , spellTarget [ urand ( 0 , 4 )], true );
2010-02-23 23:48:07 +01:00
break ;
}
2010-06-16 20:59:15 +02:00
case 64142 : // Upper Deck - Create Foam Sword
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * plr = unitTarget -> ToPlayer ();
static uint32 const itemId [] = { 45061 , 45176 , 45177 , 45178 , 45179 , 0 };
// player can only have one of these items
2010-06-16 21:32:34 +02:00
for ( uint32 const * itr = & itemId [ 0 ]; * itr ; ++ itr )
2010-06-16 20:59:15 +02:00
if ( plr -> HasItemCount ( * itr , 1 , true ))
return ;
2011-04-29 20:47:02 +02:00
DoCreateItem ( effIndex , itemId [ urand ( 0 , 4 )]);
2010-06-16 20:59:15 +02:00
return ;
2008-10-11 14:16:25 -05:00
}
break ;
}
2009-01-20 19:59:43 -06:00
case SPELLFAMILY_PALADIN :
2008-12-24 09:58:26 -06:00
{
2009-08-05 16:39:09 -05:00
// Judgement (seal trigger)
if ( m_spellInfo -> Category == SPELLCATEGORY_JUDGEMENT )
2008-12-24 09:58:26 -06:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive ())
2009-01-20 19:59:43 -06:00
return ;
uint32 spellId1 = 0 ;
uint32 spellId2 = 0 ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// Judgement self add switch
switch ( m_spellInfo -> Id )
{
case 53407 : spellId1 = 20184 ; break ; // Judgement of Justice
case 20271 : // Judgement of Light
case 57774 : spellId1 = 20185 ; break ; // Judgement of Light
case 53408 : spellId1 = 20186 ; break ; // Judgement of Wisdom
default :
2011-04-29 20:47:02 +02:00
sLog -> outError ( "Unsupported Judgement (seal trigger) spell (Id: %u) in Spell::EffectScriptEffect" , m_spellInfo -> Id );
2009-01-20 19:59:43 -06:00
return ;
}
// all seals have aura dummy in 2 effect
2010-01-10 01:23:15 +01:00
Unit :: AuraApplicationMap & sealAuras = m_caster -> GetAppliedAuras ();
for ( Unit :: AuraApplicationMap :: iterator iter = sealAuras . begin (); iter != sealAuras . end ();)
2009-04-09 14:58:25 +02:00
{
2010-01-10 01:23:15 +01:00
Aura * aura = iter -> second -> GetBase ();
if ( IsSealSpell ( aura -> GetSpellProto ()))
2009-04-09 14:58:25 +02:00
{
2010-01-10 01:23:15 +01:00
if ( AuraEffect * aureff = aura -> GetEffect ( 2 ))
if ( aureff -> GetAuraType () == SPELL_AURA_DUMMY )
2009-04-09 14:58:25 +02:00
{
if ( sSpellStore . LookupEntry ( aureff -> GetAmount ()))
spellId2 = aureff -> GetAmount ();
break ;
}
if ( ! spellId2 )
{
switch ( iter -> first )
{
2009-11-17 19:24:31 -08:00
// Seal of light, Seal of wisdom, Seal of justice
2009-04-09 14:58:25 +02:00
case 20165 :
case 20166 :
case 20164 :
2009-11-17 19:24:31 -08:00
spellId2 = 54158 ;
2009-04-09 14:58:25 +02:00
}
}
break ;
}
else
++ iter ;
2008-12-24 09:58:26 -06:00
}
2009-01-20 19:59:43 -06:00
if ( spellId1 )
m_caster -> CastSpell ( unitTarget , spellId1 , true );
if ( spellId2 )
m_caster -> CastSpell ( unitTarget , spellId2 , true );
2008-12-24 09:58:26 -06:00
return ;
}
}
2009-01-20 19:59:43 -06:00
case SPELLFAMILY_POTION :
2008-10-11 14:16:25 -05:00
{
2009-01-20 19:59:43 -06:00
switch ( m_spellInfo -> Id )
2009-01-14 00:35:13 -06:00
{
2009-01-20 19:59:43 -06:00
// Netherbloom
case 28702 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2009-01-20 19:59:43 -06:00
return ;
// 25% chance of casting a random buff
2010-04-07 19:14:10 +02:00
if ( roll_chance_i ( 75 ))
2009-01-20 19:59:43 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// triggered spells are 28703 to 28707
// Note: some sources say, that there was the possibility of
// receiving a debuff. However, this seems to be removed by a patch.
const uint32 spellid = 28703 ;
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// don't overwrite an existing aura
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; i < 5 ; ++ i )
2010-04-07 19:14:10 +02:00
if ( unitTarget -> HasAura ( spellid + i ))
2009-01-20 19:59:43 -06:00
return ;
unitTarget -> CastSpell ( unitTarget , spellid + urand ( 0 , 4 ), true );
break ;
}
2009-10-17 15:51:44 -07:00
2009-01-20 19:59:43 -06:00
// Nightmare Vine
case 28720 :
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2009-01-20 19:59:43 -06:00
return ;
// 25% chance of casting Nightmare Pollen
2010-04-07 19:14:10 +02:00
if ( roll_chance_i ( 75 ))
2009-01-20 19:59:43 -06:00
return ;
unitTarget -> CastSpell ( unitTarget , 28721 , true );
break ;
}
2009-01-14 00:35:13 -06:00
}
2009-01-20 19:59:43 -06:00
break ;
2008-10-11 14:16:25 -05:00
}
2009-06-14 21:04:44 +02:00
case SPELLFAMILY_DEATHKNIGHT :
{
// Pestilence
2010-04-07 22:59:46 +02:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x10000 )
2009-06-14 21:04:44 +02:00
{
// Get diseases on target of spell
if ( m_targets . getUnitTarget () && // Glyph of Disease - cast on unit target too to refresh aura
( m_targets . getUnitTarget () != unitTarget || m_caster -> GetAura ( 63334 )))
{
// And spread them on target
// Blood Plague
if ( m_targets . getUnitTarget () -> GetAura ( 55078 ))
m_caster -> CastSpell ( unitTarget , 55078 , true );
// Frost Fever
if ( m_targets . getUnitTarget () -> GetAura ( 55095 ))
m_caster -> CastSpell ( unitTarget , 55095 , true );
}
}
2009-06-18 14:17:11 +02:00
break ;
2009-06-14 21:04:44 +02:00
}
2009-07-27 17:32:56 +02:00
case SPELLFAMILY_WARRIOR :
{
// Shattering Throw
2009-12-17 12:23:01 +01:00
if ( m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x00400000 )
2009-07-27 17:32:56 +02:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2009-07-27 17:32:56 +02:00
return ;
// remove shields, will still display immune to damage part
2009-08-11 19:57:27 +02:00
unitTarget -> RemoveAurasWithMechanic ( 1 << MECHANIC_IMMUNE_SHIELD , AURA_REMOVE_BY_ENEMY_SPELL );
2009-07-27 17:32:56 +02:00
return ;
}
break ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// normal DB scripted effect
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell ScriptStart spellid %u in EffectScriptEffect(%u)" , m_spellInfo -> Id , effIndex );
2010-08-28 21:01:16 +06:00
m_caster -> GetMap () -> ScriptsStart ( sSpellScripts , uint32 ( m_spellInfo -> Id | ( effIndex << 24 )), m_caster , unitTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSanctuary ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-11-13 18:04:56 +01:00
unitTarget -> getHostileRefManager (). UpdateVisibility ();
2010-11-13 20:23:05 +01:00
Unit :: AttackerSet const & attackers = unitTarget -> getAttackers ();
for ( Unit :: AttackerSet :: const_iterator itr = attackers . begin (); itr != attackers . end ();)
{
if ( ! ( * itr ) -> canSeeOrDetect ( unitTarget ))
( * ( itr ++ )) -> AttackStop ();
else
++ itr ;
}
2010-11-13 18:04:56 +01:00
unitTarget -> m_lastSanctuaryTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER
2010-03-08 17:20:25 +01:00
&& m_spellInfo -> SpellFamilyName == SPELLFAMILY_ROGUE
&& ( m_spellInfo -> SpellFamilyFlags [ 0 ] & SPELLFAMILYFLAG_ROGUE_VANISH ))
2008-10-11 14:16:25 -05:00
{
2010-03-11 20:51:31 +01:00
m_caster -> ToPlayer () -> RemoveAurasByType ( SPELL_AURA_MOD_ROOT );
2009-12-26 14:46:19 -03:00
// Overkill
2010-04-07 19:14:10 +02:00
if ( m_caster -> ToPlayer () -> HasSpell ( 58426 ))
2009-12-24 12:55:29 +01:00
m_caster -> CastSpell ( m_caster , 58427 , true );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectAddComboPoints ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! m_caster -> m_movedPlayer )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( damage <= 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-01 00:17:39 -05:00
m_caster -> m_movedPlayer -> AddComboPoints ( unitTarget , damage , this );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDuel ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-12-22 20:18:34 +02:00
if ( ! unitTarget || m_caster -> GetTypeId () != TYPEID_PLAYER || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * caster = ( Player * ) m_caster ;
Player * target = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// caster or target already have requested duel
2010-04-07 22:59:46 +02:00
if ( caster -> duel || target -> duel || ! target -> GetSocial () || target -> GetSocial () -> HasIgnore ( caster -> GetGUIDLow ()))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)
// Don't have to check the target's map since you cannot challenge someone across maps
2010-04-07 19:14:10 +02:00
if ( caster -> GetMap () -> Instanceable ())
2010-04-07 22:59:46 +02:00
//if (mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
2008-10-11 14:16:25 -05:00
{
SendCastResult ( SPELL_FAILED_NO_DUELING ); // Dueling isn't allowed here
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTableEntry const * casterAreaEntry = GetAreaEntryByAreaID ( caster -> GetZoneId ());
2010-04-07 22:59:46 +02:00
if ( casterAreaEntry && ( casterAreaEntry -> flags & AREA_FLAG_CAPITAL ))
2008-10-11 14:16:25 -05:00
{
SendCastResult ( SPELL_FAILED_NO_DUELING ); // Dueling isn't allowed here
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTableEntry const * targetAreaEntry = GetAreaEntryByAreaID ( target -> GetZoneId ());
2010-04-07 22:59:46 +02:00
if ( targetAreaEntry && ( targetAreaEntry -> flags & AREA_FLAG_CAPITAL ))
2008-10-11 14:16:25 -05:00
{
SendCastResult ( SPELL_FAILED_NO_DUELING ); // Dueling isn't allowed here
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//CREATE DUEL FLAG OBJECT
GameObject * pGameObj = new GameObject ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 gameobject_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Map * map = m_caster -> GetMap ();
2010-12-22 21:25:23 +01:00
if ( ! pGameObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), gameobject_id ,
2009-01-31 16:38:50 -06:00
map , m_caster -> GetPhaseMask (),
2008-10-11 14:16:25 -05:00
m_caster -> GetPositionX () + ( unitTarget -> GetPositionX () - m_caster -> GetPositionX ()) / 2 ,
m_caster -> GetPositionY () + ( unitTarget -> GetPositionY () - m_caster -> GetPositionY ()) / 2 ,
m_caster -> GetPositionZ (),
2009-04-27 18:36:10 -05:00
m_caster -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 0 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
delete pGameObj ;
return ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
pGameObj -> SetUInt32Value ( GAMEOBJECT_FACTION , m_caster -> getFaction ());
pGameObj -> SetUInt32Value ( GAMEOBJECT_LEVEL , m_caster -> getLevel () + 1 );
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2010-07-12 00:30:17 +02:00
pGameObj -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2008-10-11 14:16:25 -05:00
pGameObj -> SetSpellId ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , pGameObj );
2010-08-27 17:49:32 +02:00
2008-10-11 14:16:25 -05:00
m_caster -> AddGameObject ( pGameObj );
map -> Add ( pGameObj );
//END
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Send request
2009-05-31 15:56:51 -05:00
WorldPacket data ( SMSG_DUEL_REQUESTED , 8 + 8 );
data << uint64 ( pGameObj -> GetGUID ());
data << uint64 ( caster -> GetGUID ());
2008-10-11 14:16:25 -05:00
caster -> GetSession () -> SendPacket ( & data );
target -> GetSession () -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// create duel-info
DuelInfo * duel = new DuelInfo ;
duel -> initiator = caster ;
duel -> opponent = target ;
duel -> startTime = 0 ;
duel -> startTimer = 0 ;
caster -> duel = duel ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
DuelInfo * duel2 = new DuelInfo ;
duel2 -> initiator = caster ;
duel2 -> opponent = caster ;
duel2 -> startTime = 0 ;
duel2 -> startTimer = 0 ;
target -> duel = duel2 ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
caster -> SetUInt64Value ( PLAYER_DUEL_ARBITER , pGameObj -> GetGUID ());
target -> SetUInt64Value ( PLAYER_DUEL_ARBITER , pGameObj -> GetGUID ());
2010-09-13 01:42:14 +03:00
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnPlayerDuelRequest ( target , caster );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectStuck ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( ! sWorld -> getBoolConfig ( CONFIG_CAST_UNSTUCK ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * pTarget = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Spell Effect: Stuck" );
2010-12-23 23:25:44 +01:00
sLog -> outDetail ( "Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)" , pTarget -> GetName (), pTarget -> GetGUIDLow (), m_caster -> GetMapId (), m_caster -> GetPositionX (), pTarget -> GetPositionY (), pTarget -> GetPositionZ ());
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pTarget -> isInFlight ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-17 23:51:08 -05:00
pTarget -> TeleportTo ( pTarget -> GetStartPosition (), unitTarget == m_caster ? TELE_TO_SPELL : 0 );
2008-10-11 14:16:25 -05:00
// homebind location is loaded always
2011-04-29 20:47:02 +02:00
// pTarget->TeleportTo(pTarget->m_homebindMapId, pTarget->m_homebindX, pTarget->m_homebindY, pTarget->m_homebindZ, pTarget->GetOrientation(), (unitTarget == m_caster ? TELE_TO_SPELL : 0));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Stuck spell trigger Hearthstone cooldown
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( 8690 );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
return ;
2009-05-31 15:56:51 -05:00
Spell spell ( pTarget , spellInfo , true , 0 );
2008-10-11 14:16:25 -05:00
spell . SendSpellCooldown ();
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonPlayer ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Evil Twin (ignore player summon, but hide this for summoner)
2010-04-07 19:14:10 +02:00
if ( unitTarget -> HasAura ( 23445 ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
float x , y , z ;
m_caster -> GetClosePoint ( x , y , z , unitTarget -> GetObjectSize ());
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
unitTarget -> ToPlayer () -> SetSummonPoint ( m_caster -> GetMapId (), x , y , z );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( SMSG_SUMMON_REQUEST , 8 + 4 + 4 );
data << uint64 ( m_caster -> GetGUID ()); // summoner guid
data << uint32 ( m_caster -> GetZoneId ()); // summoner zone
2010-07-12 00:30:17 +02:00
data << uint32 ( MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS ); // auto decline after msecs
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> GetSession () -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
static ScriptInfo generateActivateCommand ()
{
ScriptInfo si ;
si . command = SCRIPT_COMMAND_ACTIVATE_OBJECT ;
return si ;
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectActivateObject ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! gameObjTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
static ScriptInfo activateCommand = generateActivateCommand ();
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
int32 delay_secs = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2009-07-31 10:48:34 +08:00
gameObjTarget -> GetMap () -> ScriptCommandStart ( activateCommand , delay_secs , m_caster , gameObjTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectApplyGlyph ( SpellEffIndex effIndex )
2008-12-24 09:58:26 -06:00
{
2010-03-23 14:38:31 -05:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER || m_glyphIndex >= MAX_GLYPH_SLOT_INDEX )
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-12-24 09:58:26 -06:00
Player * player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2010-09-08 06:11:32 +03:00
// glyph sockets level requirement
uint8 minLevel = 0 ;
switch ( m_glyphIndex )
{
case 0 :
case 1 : minLevel = 15 ; break ;
case 2 : minLevel = 50 ; break ;
case 3 : minLevel = 30 ; break ;
case 4 : minLevel = 70 ; break ;
case 5 : minLevel = 80 ; break ;
}
if ( minLevel && m_caster -> getLevel () < minLevel )
{
SendCastResult ( SPELL_FAILED_GLYPH_SOCKET_LOCKED );
return ;
}
2008-12-24 09:58:26 -06:00
// apply new one
2010-08-27 19:36:27 +02:00
if ( uint32 glyph = m_spellInfo -> EffectMiscValue [ effIndex ])
2008-12-24 09:58:26 -06:00
{
2010-03-23 14:38:31 -05:00
if ( GlyphPropertiesEntry const * gp = sGlyphPropertiesStore . LookupEntry ( glyph ))
2008-12-24 09:58:26 -06:00
{
2010-03-23 14:38:31 -05:00
if ( GlyphSlotEntry const * gs = sGlyphSlotStore . LookupEntry ( player -> GetGlyphSlot ( m_glyphIndex )))
2008-12-24 09:58:26 -06:00
{
2010-03-23 14:38:31 -05:00
if ( gp -> TypeFlags != gs -> TypeFlags )
2008-12-24 09:58:26 -06:00
{
SendCastResult ( SPELL_FAILED_INVALID_GLYPH );
2009-03-21 14:53:38 -06:00
return ; // glyph slot mismatch
}
}
2009-10-17 15:51:44 -07:00
2009-03-21 14:53:38 -06:00
// remove old glyph
2010-03-23 14:38:31 -05:00
if ( uint32 oldglyph = player -> GetGlyph ( m_glyphIndex ))
2009-03-21 14:53:38 -06:00
{
2010-03-23 14:38:31 -05:00
if ( GlyphPropertiesEntry const * old_gp = sGlyphPropertiesStore . LookupEntry ( oldglyph ))
2009-03-21 14:53:38 -06:00
{
player -> RemoveAurasDueToSpell ( old_gp -> SpellId );
player -> SetGlyph ( m_glyphIndex , 0 );
2008-12-24 09:58:26 -06:00
}
}
2009-10-17 15:51:44 -07:00
2008-12-24 09:58:26 -06:00
player -> CastSpell ( m_caster , gp -> SpellId , true );
player -> SetGlyph ( m_glyphIndex , glyph );
2009-06-11 00:45:59 -05:00
player -> SendTalentsInfoData ( false );
2008-12-24 09:58:26 -06:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectEnchantHeldItem ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
// this is only item spell effect applied to main-hand weapon of target player (players in area)
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * item_owner = ( Player * ) unitTarget ;
Item * item = item_owner -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_MAINHAND );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! item )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// must be equipped
2010-04-07 19:14:10 +02:00
if ( ! item -> IsEquipped ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> EffectMiscValue [ effIndex ])
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 enchant_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo ); //Try duration index first ..
2010-04-07 19:14:10 +02:00
if ( ! duration )
2008-12-25 17:39:46 -06:00
duration = damage ; //+1; //Base points after ..
2010-04-07 19:14:10 +02:00
if ( ! duration )
2008-10-11 14:16:25 -05:00
duration = 10 ; //10 seconds for enchants which don't have listed duration
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SpellItemEnchantmentEntry const * pEnchant = sSpellItemEnchantmentStore . LookupEntry ( enchant_id );
2010-04-07 19:14:10 +02:00
if ( ! pEnchant )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Always go to temp enchantment slot
EnchantmentSlot slot = TEMP_ENCHANTMENT_SLOT ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Enchantment will not be applied if a different one already exists
2010-04-07 19:14:10 +02:00
if ( item -> GetEnchantmentId ( slot ) && item -> GetEnchantmentId ( slot ) != enchant_id )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Apply the temporary enchantment
2010-07-12 00:30:17 +02:00
item -> SetEnchantment ( slot , enchant_id , duration * IN_MILLISECONDS , 0 );
2009-05-31 15:56:51 -05:00
item_owner -> ApplyEnchantment ( item , slot , true );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDisEnchant ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * p_caster = ( Player * ) m_caster ;
2011-04-28 22:42:33 +02:00
if ( ! itemTarget || ! itemTarget -> GetTemplate () -> DisenchantID )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
p_caster -> UpdateCraftSkill ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
m_caster -> ToPlayer () -> SendLoot ( itemTarget -> GetGUID (), LOOT_DISENCHANTING );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// item will be removed at disenchanting end
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectInebriate ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = ( Player * ) unitTarget ;
uint16 currentDrunk = player -> GetDrunkValue ();
uint16 drunkMod = damage * 256 ;
if ( currentDrunk + drunkMod > 0xFFFF )
currentDrunk = 0xFFFF ;
else
currentDrunk += drunkMod ;
2009-05-31 15:56:51 -05:00
player -> SetDrunkValue ( currentDrunk , m_CastItem ? m_CastItem -> GetEntry () : 0 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectFeedPet ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * _player = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2009-01-02 15:49:28 -06:00
Item * foodItem = m_targets . getItemTarget ();
2010-04-07 19:14:10 +02:00
if ( ! foodItem )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Pet * pet = _player -> GetPet ();
2010-04-07 19:14:10 +02:00
if ( ! pet )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! pet -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
int32 benefit = pet -> GetCurrentFoodBenefitLevel ( foodItem -> GetTemplate () -> ItemLevel );
2010-04-07 19:14:10 +02:00
if ( benefit <= 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-09-02 22:04:08 +02:00
ExecuteLogEffectDestroyItem ( effIndex , foodItem -> GetEntry ());
2008-10-11 14:16:25 -05:00
uint32 count = 1 ;
2010-09-02 22:04:08 +02:00
_player -> DestroyItemCount ( foodItem , count , true );
2008-10-11 14:16:25 -05:00
// TODO: fix crash when a spell has two effects, both pointed at the same item target
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
m_caster -> CastCustomSpell ( pet , m_spellInfo -> EffectTriggerSpell [ effIndex ], & benefit , NULL , NULL , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDismissPet ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
Pet * pet = m_caster -> ToPlayer () -> GetPet ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// not let dismiss dead pet
2010-04-07 19:14:10 +02:00
if ( ! pet ||! pet -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectUnsummonObject ( effIndex , pet );
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> RemovePet ( pet , PET_SAVE_NOT_IN_SLOT );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonObject ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 19:36:27 +02:00
uint32 go_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 slot = 0 ;
2010-08-27 19:36:27 +02:00
switch ( m_spellInfo -> Effect [ effIndex ])
2008-10-11 14:16:25 -05:00
{
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1 : slot = 0 ; break ;
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2 : slot = 1 ; break ;
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3 : slot = 2 ; break ;
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4 : slot = 3 ; break ;
default : return ;
}
2009-10-17 15:51:44 -07:00
2009-07-30 11:45:51 +02:00
uint64 guid = m_caster -> m_ObjectSlot [ slot ];
2010-04-07 19:14:10 +02:00
if ( guid != 0 )
2008-10-11 14:16:25 -05:00
{
2009-07-30 11:45:51 +02:00
GameObject * obj = NULL ;
2010-04-07 22:59:46 +02:00
if ( m_caster )
2009-07-30 11:45:51 +02:00
obj = m_caster -> GetMap () -> GetGameObject ( guid );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( obj )
2009-07-30 11:45:51 +02:00
{
// Recast case - null spell id to make auras not be removed on object remove from world
if ( m_spellInfo -> Id == obj -> GetSpellId ())
obj -> SetSpellId ( 0 );
m_caster -> RemoveGameObject ( obj , true );
}
2008-10-11 14:16:25 -05:00
m_caster -> m_ObjectSlot [ slot ] = 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameObject * pGameObj = new GameObject ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
float x , y , z ;
2008-10-11 14:16:25 -05:00
// If dest location if present
2009-08-29 23:20:16 -05:00
if ( m_targets . HasDst ())
m_targets . m_dstPos . GetPosition ( x , y , z );
2008-10-11 14:16:25 -05:00
// Summon in random point all other units if location present
else
2009-05-31 15:56:51 -05:00
m_caster -> GetClosePoint ( x , y , z , DEFAULT_WORLD_OBJECT_SIZE );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Map * map = m_caster -> GetMap ();
2010-12-22 21:25:23 +01:00
if ( ! pGameObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), go_id , map ,
2009-04-27 18:36:10 -05:00
m_caster -> GetPhaseMask (), x , y , z , m_caster -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 0 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
delete pGameObj ;
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2010-07-12 00:30:17 +02:00
pGameObj -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2008-10-11 14:16:25 -05:00
pGameObj -> SetSpellId ( m_spellInfo -> Id );
m_caster -> AddGameObject ( pGameObj );
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectSummonObject ( effIndex , pGameObj );
2010-08-27 17:49:32 +02:00
2008-10-11 14:16:25 -05:00
map -> Add ( pGameObj );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_caster -> m_ObjectSlot [ slot ] = pGameObj -> GetGUID ();
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectResurrect ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> IsInWorld ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
switch ( m_spellInfo -> Id )
{
// Defibrillate (Goblin Jumper Cables) have 33% chance on success
case 8342 :
if ( roll_chance_i ( 67 ))
{
m_caster -> CastSpell ( m_caster , 8338 , true , m_CastItem );
return ;
}
break ;
// Defibrillate (Goblin Jumper Cables XL) have 50% chance on success
case 22999 :
if ( roll_chance_i ( 50 ))
{
m_caster -> CastSpell ( m_caster , 23055 , true , m_CastItem );
return ;
}
break ;
2010-06-20 00:55:54 +02:00
// Defibrillate ( Gnomish Army Knife) have 67% chance on success_list
case 54732 :
if ( roll_chance_i ( 33 ))
{
return ;
}
break ;
2008-10-11 14:16:25 -05:00
default :
break ;
}
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
Player * pTarget = unitTarget -> ToPlayer ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( pTarget -> isRessurectRequested ()) // already have one active request
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-26 01:20:57 +06:00
uint32 health = pTarget -> CountPctFromMaxHealth ( damage );
2010-12-11 20:37:38 +06:00
uint32 mana = CalculatePctN ( pTarget -> GetMaxPower ( POWER_MANA ), damage );
2009-10-17 15:51:44 -07:00
2010-08-27 17:49:32 +02:00
ExecuteLogEffectResurrect ( effIndex , pTarget );
2008-10-11 14:16:25 -05:00
pTarget -> setResurrectRequestData ( m_caster -> GetGUID (), m_caster -> GetMapId (), m_caster -> GetPositionX (), m_caster -> GetPositionY (), m_caster -> GetPositionZ (), health , mana );
SendResurrectRequest ( pTarget );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectAddExtraAttacks ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-27 17:49:32 +02:00
if ( ! unitTarget || ! unitTarget -> isAlive () || ! unitTarget -> getVictim ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( unitTarget -> m_extraAttacks )
2009-06-27 16:37:29 +02:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
unitTarget -> m_extraAttacks = damage ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectExtraAttacks ( effIndex , unitTarget -> getVictim (), damage );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectParry ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> SetCanParry ( true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectBlock ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2008-12-24 09:58:26 -06:00
if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> SetCanBlock ( true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectLeap ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( unitTarget -> isInFlight ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! m_targets . HasDst ())
2008-11-01 18:52:59 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-07-21 02:06:51 +02:00
unitTarget -> NearTeleportTo ( m_targets . m_dstPos . GetPositionX (), m_targets . m_dstPos . GetPositionY (), m_targets . m_dstPos . GetPositionZ (), m_targets . m_dstPos . GetOrientation (), unitTarget == m_caster );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectReputation ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-08-09 11:33:31 -06:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-09 11:33:31 -06:00
Player * _player = ( Player * ) unitTarget ;
2009-10-17 15:51:44 -07:00
2010-08-09 11:33:31 -06:00
int32 rep_change = damage ; //+1; // field store reputation change -1
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 faction_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2010-08-09 11:33:31 -06:00
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( faction_id );
2009-10-17 15:51:44 -07:00
2010-08-09 11:33:31 -06:00
if ( ! factionEntry )
return ;
2010-12-22 21:25:23 +01:00
if ( RepRewardRate const * repData = sObjectMgr -> GetRepRewardRate ( faction_id ))
2010-08-09 11:33:31 -06:00
{
2010-08-22 12:39:39 -07:00
rep_change = int32 (( float ) rep_change * repData -> spell_rate );
2010-07-27 02:25:22 +02:00
}
2010-08-09 11:33:31 -06:00
_player -> GetReputationMgr (). ModifyReputation ( factionEntry , rep_change );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectQuestComplete ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-01-25 20:45:02 +01:00
Player * pPlayer ;
2009-10-17 15:51:44 -07:00
2010-01-25 20:45:02 +01:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
pPlayer = ( Player * ) m_caster ;
2010-01-27 14:50:42 -03:00
else if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER )
2010-01-25 20:45:02 +01:00
pPlayer = ( Player * ) unitTarget ;
else
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 quest_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-07-04 19:16:40 +02:00
if ( quest_id )
{
uint16 log_slot = pPlayer -> FindQuestSlot ( quest_id );
if ( log_slot < MAX_QUEST_LOG_SIZE )
pPlayer -> AreaExploredOrEventHappens ( quest_id );
2010-07-22 13:02:47 +02:00
else if ( ! pPlayer -> GetQuestRewardStatus ( quest_id )) // never rewarded before
2010-07-04 19:16:40 +02:00
pPlayer -> CompleteQuest ( quest_id ); // quest not in log - for internal use
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectForceDeselect ( SpellEffIndex /*effIndex*/ )
2010-01-13 10:27:44 +01:00
{
2010-01-13 18:22:31 +01:00
WorldPacket data ( SMSG_CLEAR_TARGET , 8 );
data << uint64 ( m_caster -> GetGUID ());
2010-01-13 10:27:44 +01:00
m_caster -> SendMessageToSet ( & data , true );
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectSelfResurrect ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( ! unitTarget -> IsInWorld ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 health = 0 ;
uint32 mana = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// flat case
2010-04-07 19:14:10 +02:00
if ( damage < 0 )
2008-10-11 14:16:25 -05:00
{
health = uint32 ( - damage );
2010-08-27 19:36:27 +02:00
mana = m_spellInfo -> EffectMiscValue [ effIndex ];
2008-10-11 14:16:25 -05:00
}
// percent case
else
{
2010-08-26 01:20:57 +06:00
health = unitTarget -> CountPctFromMaxHealth ( damage );
2010-04-07 19:14:10 +02:00
if ( unitTarget -> GetMaxPower ( POWER_MANA ) > 0 )
2010-12-11 20:37:38 +06:00
mana = CalculatePctN ( unitTarget -> GetMaxPower ( POWER_MANA ), damage );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
Player * plr = unitTarget -> ToPlayer ();
2008-10-11 14:16:25 -05:00
plr -> ResurrectPlayer ( 0.0f );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
plr -> SetHealth ( health );
plr -> SetPower ( POWER_MANA , mana );
plr -> SetPower ( POWER_RAGE , 0 );
plr -> SetPower ( POWER_ENERGY , plr -> GetMaxPower ( POWER_ENERGY ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
plr -> SpawnCorpseBones ();
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSkinning ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 22:59:46 +02:00
if ( unitTarget -> GetTypeId () != TYPEID_UNIT )
2008-10-11 14:16:25 -05:00
return ;
2010-12-22 20:18:34 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 18:30:53 +01:00
Creature * creature = unitTarget -> ToCreature ();
2008-10-11 14:16:25 -05:00
int32 targetLevel = creature -> getLevel ();
2009-10-17 15:51:44 -07:00
2008-11-18 19:40:06 -06:00
uint32 skill = creature -> GetCreatureInfo () -> GetRequiredLootSkill ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
m_caster -> ToPlayer () -> SendLoot ( creature -> GetGUID (), LOOT_SKINNING );
2008-10-11 14:16:25 -05:00
creature -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SKINNABLE );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? ( targetLevel - 10 ) * 10 : targetLevel * 5 ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
int32 skillValue = m_caster -> ToPlayer () -> GetPureSkillValue ( skill );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Double chances for elites
2010-04-07 22:59:46 +02:00
m_caster -> ToPlayer () -> UpdateGatherSkill ( skill , skillValue , reqValue , creature -> isElite () ? 2 : 1 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectCharge ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-07-01 17:47:31 -05:00
Unit * target = m_targets . getUnitTarget ();
2010-04-07 19:14:10 +02:00
if ( ! target )
2009-07-01 17:47:31 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-07-01 17:47:31 -05:00
float x , y , z ;
target -> GetContactPoint ( m_caster , x , y , z );
m_caster -> GetMotionMaster () -> MoveCharge ( x , y , z );
2009-10-17 15:51:44 -07:00
2009-07-01 17:36:34 -05:00
// not all charge effects used in negative spells
2010-04-07 22:59:46 +02:00
if ( ! IsPositiveSpell ( m_spellInfo -> Id ) && m_caster -> GetTypeId () == TYPEID_PLAYER )
2009-07-01 17:47:31 -05:00
m_caster -> Attack ( target , true );
2009-07-01 17:36:34 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectChargeDest ( SpellEffIndex /*effIndex*/ )
2009-07-01 17:36:34 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_targets . HasDst ())
2009-07-01 17:47:31 -05:00
{
2010-07-19 19:28:54 +02:00
float x , y , z ;
2010-07-19 19:22:05 +02:00
m_targets . m_dstPos . GetPosition ( x , y , z );
m_caster -> GetMotionMaster () -> MoveCharge ( x , y , z );
2009-07-01 17:47:31 -05:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectKnockBack ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-05-07 22:16:30 +02:00
if ( Creature * creatureTarget = unitTarget -> ToCreature ())
if ( creatureTarget -> isWorldBoss () || creatureTarget -> IsDungeonBoss ())
return ;
2009-08-18 00:35:32 +02:00
// Typhoon
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x01000000 )
{
// Glyph of Typhoon
if ( m_caster -> HasAura ( 62135 ))
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-18 00:35:32 +02:00
// Thunderstorm
if ( m_spellInfo -> SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo -> SpellFamilyFlags [ 1 ] & 0x00002000 )
{
// Glyph of Thunderstorm
if ( m_caster -> HasAura ( 62132 ))
return ;
}
2009-10-17 15:51:44 -07:00
2011-05-05 18:08:01 -03:00
// Instantly interrupt non melee spells being casted
if ( unitTarget -> IsNonMeleeSpellCasted ( true ))
unitTarget -> InterruptNonMeleeSpells ( true );
2009-08-25 23:50:58 -05:00
float ratio = m_caster -> GetCombatReach () / std :: max ( unitTarget -> GetCombatReach (), 1.0f );
2010-04-07 19:14:10 +02:00
if ( ratio < 1.0f )
2009-08-25 23:50:58 -05:00
ratio = ratio * ratio * ratio * 0.1f ; // volume = length^3
else
ratio = 0.1f ; // dbc value ratio
2010-08-27 19:36:27 +02:00
float speedxy = float ( m_spellInfo -> EffectMiscValue [ effIndex ]) * ratio ;
2009-08-25 16:34:17 -05:00
float speedz = float ( damage ) * ratio ;
2010-04-07 19:14:10 +02:00
if ( speedxy < 0.1f && speedz < 0.1f )
2009-08-25 16:34:17 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-06 21:48:47 -06:00
float x , y ;
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> Effect [ effIndex ] == SPELL_EFFECT_KNOCK_BACK_DEST )
2010-07-20 04:29:17 +02:00
{
if ( m_targets . HasDst ())
m_targets . m_dstPos . GetPosition ( x , y );
else
return ;
}
else //if (m_spellInfo->Effect[i] == SPELL_EFFECT_KNOCK_BACK)
{
2009-08-29 23:20:16 -05:00
m_caster -> GetPosition ( x , y );
2010-08-08 19:45:53 +02:00
}
2009-10-17 15:51:44 -07:00
2009-04-11 22:41:15 -05:00
unitTarget -> KnockbackFrom ( x , y , speedxy , speedz );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectLeapBack ( SpellEffIndex effIndex )
2009-04-11 22:41:15 -05:00
{
2010-08-27 19:36:27 +02:00
float speedxy = float ( m_spellInfo -> EffectMiscValue [ effIndex ]) / 10 ;
2009-04-11 22:41:15 -05:00
float speedz = float ( damage / 10 );
2010-04-07 19:14:10 +02:00
if ( ! speedxy )
2009-04-11 22:41:15 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_targets . getUnitTarget ())
2009-05-03 16:29:33 -05:00
m_caster -> JumpTo ( m_targets . getUnitTarget (), speedz );
2009-04-11 22:41:15 -05:00
}
else
{
//1891: Disengage
2009-08-11 19:57:27 +02:00
m_caster -> JumpTo ( speedxy , speedz , m_spellInfo -> SpellIconID != 1891 );
2009-04-11 22:41:15 -05:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectQuestClear ( SpellEffIndex effIndex )
2010-07-04 19:16:40 +02:00
{
Player * pPlayer = NULL ;
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
pPlayer = m_caster -> ToPlayer ();
else if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER )
pPlayer = unitTarget -> ToPlayer ();
2010-08-08 19:45:53 +02:00
2010-07-04 19:16:40 +02:00
if ( ! pPlayer )
return ;
2010-08-27 19:36:27 +02:00
uint32 quest_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-07-04 19:16:40 +02:00
2010-12-22 21:25:23 +01:00
Quest const * pQuest = sObjectMgr -> GetQuestTemplate ( quest_id );
2010-07-04 19:16:40 +02:00
if ( ! pQuest )
return ;
// Player has never done this quest
2010-12-26 21:18:22 +01:00
if ( pPlayer -> GetQuestStatus ( quest_id ) == QUEST_STATUS_NONE )
2010-07-04 19:16:40 +02:00
return ;
// remove all quest entries for 'entry' from quest log
for ( uint8 slot = 0 ; slot < MAX_QUEST_LOG_SIZE ; ++ slot )
{
uint32 quest = pPlayer -> GetQuestSlotQuestId ( slot );
if ( quest == quest_id )
{
pPlayer -> SetQuestSlot ( slot , 0 );
// we ignore unequippable quest items in this case, its' still be equipped
pPlayer -> TakeQuestSourceItem ( quest , false );
}
}
2010-12-26 21:34:08 +01:00
pPlayer -> RemoveActiveQuest ( quest_id );
pPlayer -> RemoveRewardedQuest ( quest_id );
2010-07-04 19:16:40 +02:00
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectSendTaxi ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
unitTarget -> ToPlayer () -> ActivateTaxiPathTo ( m_spellInfo -> EffectMiscValue [ effIndex ], m_spellInfo -> Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPullTowards ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
float speedZ = ( float )( SpellMgr :: CalculateSpellEffectAmount ( m_spellInfo , effIndex ) / 10 );
float speedXY = ( float )( m_spellInfo -> EffectMiscValue [ effIndex ] / 10 );
2010-08-09 02:31:42 +02:00
Position pos ;
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> Effect [ effIndex ] == SPELL_EFFECT_PULL_TOWARDS_DEST )
2010-08-09 02:31:42 +02:00
{
if ( m_targets . HasDst ())
pos . Relocate ( m_targets . m_dstPos );
else
return ;
}
else //if (m_spellInfo->Effect[i] == SPELL_EFFECT_PULL_TOWARDS)
{
pos . Relocate ( m_caster );
}
unitTarget -> GetMotionMaster () -> MoveJump ( pos . GetPositionX (), pos . GetPositionY (), pos . GetPositionZ (), speedXY , speedZ );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDispelMechanic ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 mechanic = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2009-04-19 22:21:40 +02:00
std :: queue < std :: pair < uint32 , uint64 > > dispel_list ;
2009-10-17 15:51:44 -07:00
2010-01-10 20:09:44 +01:00
Unit :: AuraMap const & auras = unitTarget -> GetOwnedAuras ();
for ( Unit :: AuraMap :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
2009-04-13 18:56:29 +02:00
{
2010-01-10 20:09:44 +01:00
Aura * aura = itr -> second ;
if ( ! aura -> GetApplicationOfTarget ( unitTarget -> GetGUID ()))
continue ;
2010-05-25 10:36:33 +02:00
bool success = false ;
GetDispelChance ( aura -> GetCaster (), unitTarget , aura -> GetId (), ! unitTarget -> IsFriendlyTo ( m_caster ), & success );
2010-06-27 04:03:30 +02:00
if (( GetAllSpellMechanicMask ( aura -> GetSpellProto ()) & ( 1 << mechanic )) && success )
2010-04-07 22:59:46 +02:00
dispel_list . push ( std :: make_pair ( aura -> GetId (), aura -> GetCasterGUID ()));
2009-04-13 18:56:29 +02:00
}
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for (; dispel_list . size (); dispel_list . pop ())
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
unitTarget -> RemoveAura ( dispel_list . front (). first , dispel_list . front (). second , 0 , AURA_REMOVE_BY_ENEMY_SPELL );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSummonDeadPet ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
Player * _player = ( Player * ) m_caster ;
Pet * pet = _player -> GetPet ();
2010-04-07 19:14:10 +02:00
if ( ! pet )
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( pet -> isAlive ())
2008-10-11 14:16:25 -05:00
return ;
2010-04-07 19:14:10 +02:00
if ( damage < 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
float x , y , z ;
2010-01-16 19:11:32 +03:00
_player -> GetPosition ( x , y , z );
_player -> GetMap () -> CreatureRelocation ( pet , x , y , z , _player -> GetOrientation ());
2008-10-11 14:16:25 -05:00
pet -> SetUInt32Value ( UNIT_DYNAMIC_FLAGS , 0 );
pet -> RemoveFlag ( UNIT_FIELD_FLAGS , UNIT_FLAG_SKINNABLE );
2010-04-07 22:59:46 +02:00
pet -> setDeathState ( ALIVE );
2011-03-08 16:42:00 +01:00
pet -> ClearUnitState ( uint32 ( UNIT_STAT_ALL_STATE ));
2010-08-26 01:20:57 +06:00
pet -> SetHealth ( pet -> CountPctFromMaxHealth ( damage ));
2009-10-17 15:51:44 -07:00
2009-04-06 22:08:12 -05:00
//pet->AIM_Initialize();
//_player->PetSpellInitialize();
2008-10-11 14:16:25 -05:00
pet -> SavePetToDB ( PET_SAVE_AS_CURRENT );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDestroyAllTotems ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2009-05-06 17:00:11 -05:00
int32 mana = 0 ;
2009-10-17 16:20:24 -07:00
for ( uint8 slot = SUMMON_SLOT_TOTEM ; slot < MAX_TOTEM_SLOT ; ++ slot )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! m_caster -> m_SummonSlot [ slot ])
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-04-20 20:28:19 -05:00
Creature * totem = m_caster -> GetMap () -> GetCreature ( m_caster -> m_SummonSlot [ slot ]);
2010-04-07 19:14:10 +02:00
if ( totem && totem -> isTotem ())
2008-10-11 14:16:25 -05:00
{
uint32 spell_id = totem -> GetUInt32Value ( UNIT_CREATED_BY_SPELL );
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( spell_id );
2010-04-07 19:14:10 +02:00
if ( spellInfo )
2009-04-12 01:29:56 +02:00
{
mana += spellInfo -> manaCost ;
2010-12-11 20:37:38 +06:00
mana += int32 ( CalculatePctU ( m_caster -> GetCreateMana (), spellInfo -> ManaCostPercentage ));
2009-04-12 01:29:56 +02:00
}
2010-03-10 07:58:11 +01:00
totem -> ToTotem () -> UnSummon ();
2008-10-11 14:16:25 -05:00
}
}
2010-12-11 20:37:38 +06:00
ApplyPctN ( mana , damage );
2009-05-06 17:00:11 -05:00
if ( mana )
m_caster -> CastCustomSpell ( m_caster , 39104 , & mana , NULL , NULL , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDurabilityDamage ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
int32 slot = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// FIXME: some spells effects have value -1/-2
// Possibly its mean -1 all player equipped items and -2 all items
2010-04-07 19:14:10 +02:00
if ( slot < 0 )
2008-10-11 14:16:25 -05:00
{
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> DurabilityPointsLossAll ( damage , ( slot < - 1 ));
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// invalid slot value
2010-04-07 19:14:10 +02:00
if ( slot >= INVENTORY_SLOT_BAG_END )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( Item * item = unitTarget -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot ))
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> DurabilityPointsLoss ( item , damage );
2010-08-27 17:49:32 +02:00
2010-08-27 19:36:27 +02:00
ExecuteLogEffectDurabilityDamage ( effIndex , unitTarget , slot , damage );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectDurabilityDamagePCT ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
int32 slot = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// FIXME: some spells effects have value -1/-2
// Possibly its mean -1 all player equipped items and -2 all items
2010-04-07 19:14:10 +02:00
if ( slot < 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-11 20:37:38 +06:00
unitTarget -> ToPlayer () -> DurabilityLossAll ( float ( damage ) / 100.0f , ( slot < - 1 ));
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// invalid slot value
2010-04-07 19:14:10 +02:00
if ( slot >= INVENTORY_SLOT_BAG_END )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( damage <= 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( Item * item = unitTarget -> ToPlayer () -> GetItemByPos ( INVENTORY_SLOT_BAG_0 , slot ))
2010-12-11 20:37:38 +06:00
unitTarget -> ToPlayer () -> DurabilityLoss ( item , float ( damage ) / 100.0f );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectModifyThreatPercent ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
unitTarget -> getThreatManager (). modifyThreatPercent ( m_caster , damage );
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectTransmitted ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
uint32 name_id = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * goinfo = sObjectMgr -> GetGameObjectTemplate ( name_id );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! goinfo )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Gameobject (Entry: %u) not exist and not created at spell (ID: %u) cast" , name_id , m_spellInfo -> Id );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
float fx , fy , fz ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( m_targets . HasDst ())
2009-08-29 23:20:16 -05:00
m_targets . m_dstPos . GetPosition ( fx , fy , fz );
2008-10-11 14:16:25 -05:00
//FIXME: this can be better check for most objects but still hack
2010-04-07 23:25:02 +02:00
else if ( m_spellInfo -> EffectRadiusIndex [ effIndex ] && m_spellInfo -> speed == 0 )
2008-10-11 14:16:25 -05:00
{
2009-02-14 15:56:04 +01:00
float dis = GetSpellRadiusForFriend ( sSpellRadiusStore . LookupEntry ( m_spellInfo -> EffectRadiusIndex [ effIndex ]));
2009-05-31 15:56:51 -05:00
m_caster -> GetClosePoint ( fx , fy , fz , DEFAULT_WORLD_OBJECT_SIZE , dis );
2008-10-11 14:16:25 -05:00
}
else
{
2009-02-14 15:56:04 +01:00
//GO is always friendly to it's creator, get range for friends
float min_dis = GetSpellMinRangeForFriend ( sSpellRangeStore . LookupEntry ( m_spellInfo -> rangeIndex ));
float max_dis = GetSpellMaxRangeForFriend ( sSpellRangeStore . LookupEntry ( m_spellInfo -> rangeIndex ));
2010-08-22 12:39:39 -07:00
float dis = ( float ) rand_norm () * ( max_dis - min_dis ) + min_dis ;
2009-10-17 15:51:44 -07:00
2009-05-31 15:56:51 -05:00
m_caster -> GetClosePoint ( fx , fy , fz , DEFAULT_WORLD_OBJECT_SIZE , dis );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Map * cMap = m_caster -> GetMap ();
2010-11-10 11:37:41 +01:00
if ( goinfo -> type == GAMEOBJECT_TYPE_FISHINGNODE || goinfo -> type == GAMEOBJECT_TYPE_FISHINGHOLE )
2008-10-11 14:16:25 -05:00
{
2010-06-05 00:59:25 +02:00
LiquidData liqData ;
if ( ! cMap -> IsInWater ( fx , fy , fz + 1.f /* -0.5f */ , & liqData )) // Hack to prevent fishing bobber from failing to land on fishing hole
2008-10-11 14:16:25 -05:00
{ // but this is not proper, we really need to ignore not materialized objects
SendCastResult ( SPELL_FAILED_NOT_HERE );
SendChannelUpdate ( 0 );
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// replace by water level in this case
2010-06-05 00:59:25 +02:00
//fz = cMap->GetWaterLevel(fx, fy);
fz = liqData . level ;
2008-10-11 14:16:25 -05:00
}
// if gameobject is summoning object, it should be spawned right on caster's position
2010-04-07 23:25:02 +02:00
else if ( goinfo -> type == GAMEOBJECT_TYPE_SUMMONING_RITUAL )
2008-10-11 14:16:25 -05:00
{
2009-05-31 15:56:51 -05:00
m_caster -> GetPosition ( fx , fy , fz );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameObject * pGameObj = new GameObject ;
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
if ( ! pGameObj -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), name_id , cMap ,
2009-04-27 18:36:10 -05:00
m_caster -> GetPhaseMask (), fx , fy , fz , m_caster -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 100 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
delete pGameObj ;
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 duration = GetSpellDuration ( m_spellInfo );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
switch ( goinfo -> type )
{
case GAMEOBJECT_TYPE_FISHINGNODE :
{
2011-04-29 20:47:02 +02:00
m_caster -> SetUInt64Value ( UNIT_FIELD_CHANNEL_OBJECT , pGameObj -> GetGUID ());
2008-10-11 14:16:25 -05:00
m_caster -> AddGameObject ( pGameObj ); // will removed at spell cancel
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
// start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
2009-04-27 18:42:35 -05:00
int32 lastSec = 0 ;
2008-10-11 14:16:25 -05:00
switch ( urand ( 0 , 3 ))
{
case 0 : lastSec = 3 ; break ;
case 1 : lastSec = 7 ; break ;
case 2 : lastSec = 13 ; break ;
case 3 : lastSec = 17 ; break ;
}
2009-10-17 15:51:44 -07:00
2010-07-12 00:30:17 +02:00
duration = duration - lastSec * IN_MILLISECONDS + FISHING_BOBBER_READY_TIME * IN_MILLISECONDS ;
2008-10-11 14:16:25 -05:00
break ;
}
case GAMEOBJECT_TYPE_SUMMONING_RITUAL :
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () == TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
{
2010-11-10 11:37:41 +01:00
pGameObj -> AddUniqueUse ( m_caster -> ToPlayer ());
m_caster -> AddGameObject ( pGameObj ); // will removed at spell cancel
2008-10-11 14:16:25 -05:00
}
break ;
}
2009-08-13 00:21:10 -05:00
case GAMEOBJECT_TYPE_DUEL_ARBITER : // 52991
m_caster -> AddGameObject ( pGameObj );
break ;
2008-10-11 14:16:25 -05:00
case GAMEOBJECT_TYPE_FISHINGHOLE :
case GAMEOBJECT_TYPE_CHEST :
default :
break ;
}
2009-10-17 15:51:44 -07:00
2010-07-12 00:30:17 +02:00
pGameObj -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2009-10-17 15:51:44 -07:00
2009-07-30 10:26:15 +08:00
pGameObj -> SetOwnerGUID ( m_caster -> GetGUID ());
2009-10-17 15:51:44 -07:00
2009-07-30 10:26:15 +08:00
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
2008-10-11 14:16:25 -05:00
pGameObj -> SetSpellId ( m_spellInfo -> Id );
2009-10-17 15:51:44 -07:00
2010-08-27 17:49:32 +02:00
ExecuteLogEffectSummonObject ( effIndex , pGameObj );
2010-12-23 23:25:44 +01:00
sLog -> outStaticDebug ( "AddObject at SpellEfects.cpp EffectTransmitted" );
2008-10-11 14:16:25 -05:00
//m_caster->AddGameObject(pGameObj);
//m_ObjToDel.push_back(pGameObj);
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
cMap -> Add ( pGameObj );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( uint32 linkedEntry = pGameObj -> GetGOInfo () -> GetLinkedGameObjectEntry ())
2008-10-11 14:16:25 -05:00
{
GameObject * linkedGO = new GameObject ;
2010-12-22 21:25:23 +01:00
if ( linkedGO -> Create ( sObjectMgr -> GenerateLowGuid ( HIGHGUID_GAMEOBJECT ), linkedEntry , cMap ,
2009-04-27 18:36:10 -05:00
m_caster -> GetPhaseMask (), fx , fy , fz , m_caster -> GetOrientation (), 0.0f , 0.0f , 0.0f , 0.0f , 100 , GO_STATE_READY ))
2008-10-11 14:16:25 -05:00
{
2010-07-12 00:30:17 +02:00
linkedGO -> SetRespawnTime ( duration > 0 ? duration / IN_MILLISECONDS : 0 );
2009-07-30 10:26:15 +08:00
//linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
2008-10-11 14:16:25 -05:00
linkedGO -> SetSpellId ( m_spellInfo -> Id );
2009-07-30 10:26:15 +08:00
linkedGO -> SetOwnerGUID ( m_caster -> GetGUID ());
2009-10-17 15:51:44 -07:00
2010-08-27 17:49:32 +02:00
ExecuteLogEffectSummonObject ( effIndex , linkedGO );
2008-11-18 19:40:06 -06:00
linkedGO -> GetMap () -> Add ( linkedGO );
2008-10-11 14:16:25 -05:00
}
else
{
delete linkedGO ;
linkedGO = NULL ;
return ;
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectProspecting ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * p_caster = ( Player * ) m_caster ;
2011-04-28 22:42:33 +02:00
if ( ! itemTarget || ! ( itemTarget -> GetTemplate () -> Flags & ITEM_PROTO_FLAG_PROSPECTABLE ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( itemTarget -> GetCount () < 5 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( sWorld -> getBoolConfig ( CONFIG_SKILL_PROSPECTING ))
2008-10-11 14:16:25 -05:00
{
uint32 SkillValue = p_caster -> GetPureSkillValue ( SKILL_JEWELCRAFTING );
2011-04-28 22:42:33 +02:00
uint32 reqSkillValue = itemTarget -> GetTemplate () -> RequiredSkillRank ;
2008-10-11 14:16:25 -05:00
p_caster -> UpdateGatherSkill ( SKILL_JEWELCRAFTING , SkillValue , reqSkillValue );
}
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> SendLoot ( itemTarget -> GetGUID (), LOOT_PROSPECTING );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectMilling ( SpellEffIndex /*effIndex*/ )
2008-12-24 09:58:26 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-12-24 09:58:26 -06:00
Player * p_caster = ( Player * ) m_caster ;
2011-04-28 22:42:33 +02:00
if ( ! itemTarget || ! ( itemTarget -> GetTemplate () -> Flags & ITEM_PROTO_FLAG_MILLABLE ))
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( itemTarget -> GetCount () < 5 )
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( sWorld -> getBoolConfig ( CONFIG_SKILL_MILLING ))
2008-12-24 09:58:26 -06:00
{
uint32 SkillValue = p_caster -> GetPureSkillValue ( SKILL_INSCRIPTION );
2011-04-28 22:42:33 +02:00
uint32 reqSkillValue = itemTarget -> GetTemplate () -> RequiredSkillRank ;
2008-12-24 09:58:26 -06:00
p_caster -> UpdateGatherSkill ( SKILL_INSCRIPTION , SkillValue , reqSkillValue );
}
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
m_caster -> ToPlayer () -> SendLoot ( itemTarget -> GetGUID (), LOOT_MILLING );
2008-12-24 09:58:26 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSkill ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "WORLD: SkillEFFECT" );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-08 04:37:24 +02:00
/* There is currently no need for this effect. We handle it in Battleground.cpp
2008-10-11 14:16:25 -05:00
If we would handle the resurrection here, the spiritguide would instantly disappear as the
player revives, and so we wouldn't see the spirit heal visual effect on the npc.
This is why we use a half sec delay between the visual effect and the resurrection itself */
2010-08-27 19:36:27 +02:00
void Spell :: EffectSpiritHeal ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
/*
2010-04-07 19:14:10 +02:00
if (!unitTarget || unitTarget->isAlive())
2008-10-11 14:16:25 -05:00
return;
2010-04-07 19:14:10 +02:00
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
2008-10-11 14:16:25 -05:00
return;
2010-04-07 19:14:10 +02:00
if (!unitTarget->IsInWorld())
2008-10-11 14:16:25 -05:00
return;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//m_spellInfo->EffectBasePoints[i]; == 99 (percent?)
2010-03-07 15:20:19 +01:00
//unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
unitTarget->ToPlayer()->SpawnCorpseBones();
2008-10-11 14:16:25 -05:00
*/
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove insignia spell effect
2010-08-27 19:36:27 +02:00
void Spell :: EffectSkinPlayerCorpse ( SpellEffIndex /*effIndex*/ )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Effect: SkinPlayerCorpse" );
2010-04-07 22:59:46 +02:00
if (( m_caster -> GetTypeId () != TYPEID_PLAYER ) || ( unitTarget -> GetTypeId () != TYPEID_PLAYER ) || ( unitTarget -> isAlive ()))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
unitTarget -> ToPlayer () -> RemovedInsignia (( Player * ) m_caster );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectStealBeneficialBuff ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Effect: StealBeneficialBuff" );
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( ! unitTarget || unitTarget == m_caster ) // can't steal from self
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-05-25 10:36:33 +02:00
DispelChargesList steal_list ;
2008-10-11 14:16:25 -05:00
// Create dispel mask by dispel type
2010-08-27 19:36:27 +02:00
uint32 dispelMask = GetDispellMask ( DispelType ( m_spellInfo -> EffectMiscValue [ effIndex ]));
2010-01-10 01:23:15 +01:00
Unit :: AuraMap const & auras = unitTarget -> GetOwnedAuras ();
2009-10-17 16:20:24 -07:00
for ( Unit :: AuraMap :: const_iterator itr = auras . begin (); itr != auras . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
Aura * aura = itr -> second ;
2010-01-10 20:09:44 +01:00
AuraApplication * aurApp = aura -> GetApplicationOfTarget ( unitTarget -> GetGUID ());
if ( ! aurApp )
continue ;
2010-01-10 01:23:15 +01:00
if (( 1 << aura -> GetSpellProto () -> Dispel ) & dispelMask )
2008-10-11 14:16:25 -05:00
{
// Need check for passive? this
2010-12-19 05:15:47 +01:00
if ( ! aurApp -> IsPositive () || aura -> IsPassive () || aura -> GetSpellProto () -> AttributesEx4 & SPELL_ATTR4_NOT_STEALABLE )
2010-01-10 12:08:58 +01:00
continue ;
2010-05-25 10:36:33 +02:00
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
// Polymorph instead of 1 / (5 + 1) -> 16%.
2010-12-19 05:15:47 +01:00
bool dispel_charges = aura -> GetSpellProto () -> AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES ;
2010-05-25 10:36:33 +02:00
uint8 charges = dispel_charges ? aura -> GetCharges () : aura -> GetStackAmount ();
if ( charges > 0 )
steal_list . push_back ( std :: make_pair ( aura , charges ));
2008-10-11 14:16:25 -05:00
}
}
2010-05-25 10:36:33 +02:00
if ( steal_list . empty ())
return ;
2008-10-11 14:16:25 -05:00
// Ok if exist some buffs for dispel try dispel it
2010-05-25 10:36:33 +02:00
uint32 failCount = 0 ;
DispelList success_list ;
WorldPacket dataFail ( SMSG_DISPEL_FAILED , 8 + 8 + 4 + 4 + damage * 4 );
// dispel N = damage buffs (or while exist buffs for dispel)
for ( int32 count = 0 ; count < damage && ! steal_list . empty ();)
2008-10-11 14:16:25 -05:00
{
2010-05-25 10:36:33 +02:00
// Random select buff for dispel
DispelChargesList :: iterator itr = steal_list . begin ();
std :: advance ( itr , urand ( 0 , steal_list . size () - 1 ));
2009-10-17 15:51:44 -07:00
2010-05-25 10:36:33 +02:00
bool success = false ;
// 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2010-06-27 04:03:30 +02:00
if ( ! GetDispelChance ( itr -> first -> GetCaster (), unitTarget , itr -> first -> GetId (), ! unitTarget -> IsFriendlyTo ( m_caster ), & success ))
2008-10-11 14:16:25 -05:00
{
2009-04-06 13:31:14 +02:00
steal_list . erase ( itr );
2010-05-25 10:36:33 +02:00
continue ;
2008-10-11 14:16:25 -05:00
}
2010-05-25 10:36:33 +02:00
else
2008-10-11 14:16:25 -05:00
{
2010-05-25 10:36:33 +02:00
if ( success )
2008-10-11 14:16:25 -05:00
{
2010-05-25 10:36:33 +02:00
success_list . push_back ( std :: make_pair ( itr -> first -> GetId (), itr -> first -> GetCasterGUID ()));
-- itr -> second ;
if ( itr -> second <= 0 )
steal_list . erase ( itr );
2008-10-11 14:16:25 -05:00
}
2010-05-25 10:36:33 +02:00
else
{
if ( ! failCount )
{
// Failed to dispell
dataFail << uint64 ( m_caster -> GetGUID ()); // Caster GUID
dataFail << uint64 ( unitTarget -> GetGUID ()); // Victim GUID
dataFail << uint32 ( m_spellInfo -> Id ); // dispel spell id
}
++ failCount ;
dataFail << uint32 ( itr -> first -> GetId ()); // Spell Id
}
++ count ;
2008-10-11 14:16:25 -05:00
}
}
2010-05-25 10:36:33 +02:00
if ( failCount )
m_caster -> SendMessageToSet ( & dataFail , true );
if ( success_list . empty ())
return ;
WorldPacket dataSuccess ( SMSG_SPELLSTEALLOG , 8 + 8 + 4 + 1 + 4 + damage * 5 );
dataSuccess . append ( unitTarget -> GetPackGUID ()); // Victim GUID
dataSuccess . append ( m_caster -> GetPackGUID ()); // Caster GUID
dataSuccess << uint32 ( m_spellInfo -> Id ); // dispel spell id
dataSuccess << uint8 ( 0 ); // not used
dataSuccess << uint32 ( success_list . size ()); // count
for ( DispelList :: iterator itr = success_list . begin (); itr != success_list . end (); ++ itr )
{
dataSuccess << uint32 ( itr -> first ); // Spell Id
dataSuccess << uint8 ( 0 ); // 0 - steals !=0 transfers
unitTarget -> RemoveAurasDueToSpellBySteal ( itr -> first , itr -> second , m_caster );
}
m_caster -> SendMessageToSet ( & dataSuccess , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectKillCreditPersonal ( SpellEffIndex effIndex )
2009-09-11 15:38:31 -07:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-09-11 15:38:31 -07:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
unitTarget -> ToPlayer () -> KilledMonsterCredit ( m_spellInfo -> EffectMiscValue [ effIndex ], 0 );
2009-09-11 15:38:31 -07:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectKillCredit ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
int32 creatureEntry = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-04-07 19:14:10 +02:00
if ( ! creatureEntry )
2009-05-05 12:27:11 -05:00
{
2010-04-07 19:14:10 +02:00
if ( m_spellInfo -> Id == 42793 ) // Burn Body
2009-05-05 12:27:11 -05:00
creatureEntry = 24008 ; // Fallen Combatant
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( creatureEntry )
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> RewardPlayerAndGroupAtEvent ( creatureEntry , unitTarget );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectQuestFail ( SpellEffIndex effIndex )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
unitTarget -> ToPlayer () -> FailQuest ( m_spellInfo -> EffectMiscValue [ effIndex ]);
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectQuestStart ( SpellEffIndex effIndex )
2010-07-20 16:11:49 +02:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * player = unitTarget -> ToPlayer ();
2010-12-22 21:25:23 +01:00
if ( Quest const * qInfo = sObjectMgr -> GetQuestTemplate ( m_spellInfo -> EffectMiscValue [ effIndex ]))
2010-07-20 16:11:49 +02:00
{
if ( player -> CanTakeQuest ( qInfo , false ) && player -> CanAddQuest ( qInfo , false ))
{
player -> AddQuest ( qInfo , NULL );
}
}
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectActivateRune ( SpellEffIndex effIndex )
2008-12-24 09:58:26 -06:00
{
2010-04-07 19:14:10 +02:00
if ( m_caster -> GetTypeId () != TYPEID_PLAYER )
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-12-24 09:58:26 -06:00
Player * plr = ( Player * ) m_caster ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( plr -> getClass () != CLASS_DEATH_KNIGHT )
2008-12-24 09:58:26 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-01-23 16:06:06 +01:00
// needed later
2010-03-07 15:20:19 +01:00
m_runesState = m_caster -> ToPlayer () -> GetRunesState ();
2010-01-23 16:06:06 +01:00
uint32 count = damage ;
if ( count == 0 ) count = 1 ;
2010-04-07 19:12:44 +02:00
for ( uint32 j = 0 ; j < MAX_RUNES && count > 0 ; ++ j )
2008-12-24 09:58:26 -06:00
{
2010-08-27 19:36:27 +02:00
if ( plr -> GetRuneCooldown ( j ) && plr -> GetCurrentRune ( j ) == RuneType ( m_spellInfo -> EffectMiscValue [ effIndex ]))
2008-12-24 09:58:26 -06:00
{
plr -> SetRuneCooldown ( j , 0 );
2010-01-23 16:06:06 +01:00
-- count ;
}
}
// Empower rune weapon
if ( m_spellInfo -> Id == 47568 )
{
// Need to do this just once
2010-08-27 19:36:27 +02:00
if ( effIndex != 0 )
2010-01-23 16:06:06 +01:00
return ;
2010-04-07 19:12:44 +02:00
for ( uint32 i = 0 ; i < MAX_RUNES ; ++ i )
2010-01-23 16:06:06 +01:00
{
2010-04-07 19:14:10 +02:00
if ( plr -> GetRuneCooldown ( i ) && ( plr -> GetCurrentRune ( i ) == RUNE_FROST || plr -> GetCurrentRune ( i ) == RUNE_DEATH ))
2010-01-23 16:06:06 +01:00
plr -> SetRuneCooldown ( i , 0 );
2008-12-24 09:58:26 -06:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectCreateTamedPet ( SpellEffIndex effIndex )
2010-07-20 22:55:28 +02:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER || unitTarget -> GetPetGUID () || unitTarget -> getClass () != CLASS_HUNTER )
return ;
2010-08-27 19:36:27 +02:00
uint32 creatureEntry = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-07-20 22:55:28 +02:00
Pet * pet = unitTarget -> CreateTamedPetFrom ( creatureEntry , m_spellInfo -> Id );
if ( ! pet )
return ;
// add to world
pet -> GetMap () -> Add ( pet -> ToCreature ());
// unitTarget has pet now
unitTarget -> SetMinion ( pet , true );
pet -> InitTalentForLevel ();
if ( unitTarget -> GetTypeId () == TYPEID_PLAYER )
{
pet -> SavePetToDB ( PET_SAVE_AS_CURRENT );
unitTarget -> ToPlayer () -> PetSpellInitialize ();
}
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectDiscoverTaxi ( SpellEffIndex effIndex )
2010-07-20 18:27:18 +02:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-08-27 19:36:27 +02:00
uint32 nodeid = m_spellInfo -> EffectMiscValue [ effIndex ];
2010-07-20 18:27:18 +02:00
if ( sTaxiNodesStore . LookupEntry ( nodeid ))
unitTarget -> ToPlayer () -> GetSession () -> SendDiscoverNewTaxiNode ( nodeid );
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectTitanGrip ( SpellEffIndex /*effIndex*/ )
2008-12-24 09:58:26 -06:00
{
if ( unitTarget && unitTarget -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> SetCanTitanGrip ( true );
2008-12-24 09:58:26 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectRedirectThreat ( SpellEffIndex /*effIndex*/ )
2008-12-17 20:07:25 -06:00
{
2010-04-07 19:14:10 +02:00
if ( unitTarget )
2008-12-17 20:07:25 -06:00
m_caster -> SetReducedThreatPercent (( uint32 ) damage , unitTarget -> GetGUID ());
2009-01-06 15:48:42 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectWMODamage ( SpellEffIndex /*effIndex*/ )
2009-05-21 10:01:03 -05:00
{
2009-11-01 17:53:07 -08:00
if ( gameObjTarget && gameObjTarget -> GetGoType () == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING )
2009-10-13 16:16:45 -07:00
{
Unit * caster = m_originalCaster ;
2009-11-01 17:53:07 -08:00
if ( ! caster )
2009-10-13 16:16:45 -07:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-19 13:15:47 +02:00
// Do not allow damage if hp is 0
if ( gameObjTarget -> GetGOValue () -> building . health == 0 )
return ;
2009-10-13 16:16:45 -07:00
FactionTemplateEntry const * casterft , * goft ;
casterft = caster -> getFactionTemplateEntry ();
2009-10-13 23:04:11 -07:00
goft = sFactionTemplateStore . LookupEntry ( gameObjTarget -> GetUInt32Value ( GAMEOBJECT_FACTION ));
2010-10-19 13:15:47 +02:00
// Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
if (( casterft && goft && ! casterft -> IsFriendlyTo ( * goft )) || ! goft )
2010-03-14 21:10:21 +01:00
{
gameObjTarget -> TakenDamage ( uint32 ( damage ), caster );
WorldPacket data ( SMSG_DESTRUCTIBLE_BUILDING_DAMAGE , 8 + 8 + 8 + 4 + 4 );
data . append ( gameObjTarget -> GetPackGUID ());
data . append ( caster -> GetPackGUID ());
if ( Unit * who = caster -> GetCharmerOrOwner ())
data . append ( who -> GetPackGUID ());
else
data << uint8 ( 0 );
data << uint32 ( damage );
data << uint32 ( m_spellInfo -> Id );
gameObjTarget -> SendMessageToSet ( & data , false );
}
2009-10-13 16:16:45 -07:00
}
2009-05-21 10:01:03 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectWMORepair ( SpellEffIndex /*effIndex*/ )
2009-05-21 10:01:03 -05:00
{
2009-11-01 17:53:07 -08:00
if ( gameObjTarget && gameObjTarget -> GetGoType () == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING )
2009-05-21 10:01:03 -05:00
gameObjTarget -> Rebuild ();
}
2009-10-17 15:51:44 -07:00
2010-12-01 20:59:05 +02:00
void Spell :: EffectWMOChange ( SpellEffIndex effIndex )
{
if ( gameObjTarget && gameObjTarget -> GetGoType () == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING )
{
Unit * caster = m_originalCaster ;
if ( ! caster )
return ;
int ChangeType = m_spellInfo -> EffectMiscValue [ effIndex ];
switch ( ChangeType )
{
case 0 : // intact
if ( gameObjTarget -> HasFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DAMAGED ))
gameObjTarget -> RemoveFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DAMAGED );
if ( gameObjTarget -> HasFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DESTROYED ))
gameObjTarget -> RemoveFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DESTROYED );
break ;
case 1 : // damaged
gameObjTarget -> SetFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DAMAGED );
break ;
case 2 : // destroyed
gameObjTarget -> SetFlag ( GAMEOBJECT_FLAGS , GO_FLAG_DESTROYED );
break ;
case 3 : // rebuild
gameObjTarget -> Rebuild ();
break ;
}
}
}
2009-08-29 14:58:45 -05:00
void Spell :: SummonGuardian ( uint32 i , uint32 entry , SummonPropertiesEntry const * properties )
2009-03-20 14:01:46 -06:00
{
Unit * caster = m_originalCaster ;
2009-11-01 17:53:07 -08:00
if ( ! caster )
2009-03-18 21:16:24 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( caster -> isTotem ())
2010-03-10 07:58:11 +01:00
caster = caster -> ToTotem () -> GetOwner ();
2009-10-17 15:51:44 -07:00
2009-03-20 14:01:46 -06:00
// in another case summon new
2009-11-01 17:53:07 -08:00
uint8 level = caster -> getLevel ();
2009-10-17 15:51:44 -07:00
2009-03-20 14:01:46 -06:00
// level of pet summoned using engineering item based at engineering skill level
2009-11-01 17:53:07 -08:00
if ( m_CastItem && caster -> GetTypeId () == TYPEID_PLAYER )
2011-04-28 22:42:33 +02:00
if ( ItemTemplate const * proto = m_CastItem -> GetTemplate ())
2009-11-01 17:53:07 -08:00
if ( proto -> RequiredSkill == SKILL_ENGINERING )
2010-03-07 15:20:19 +01:00
if ( uint16 skill202 = caster -> ToPlayer () -> GetSkillValue ( SKILL_ENGINERING ))
2009-11-01 17:53:07 -08:00
level = skill202 / 5 ;
2009-10-17 15:51:44 -07:00
2009-03-20 14:01:46 -06:00
//float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
float radius = 5.0f ;
2010-08-26 15:54:56 +06:00
uint32 amount = damage > 0 ? damage : 1 ;
2009-12-14 01:51:12 +01:00
int32 duration = GetSpellDuration ( m_spellInfo );
2009-11-01 17:53:07 -08:00
switch ( m_spellInfo -> Id )
2009-05-17 17:33:39 -05:00
{
case 1122 : // Inferno
2009-06-30 15:55:02 +02:00
amount = 1 ;
2009-05-17 17:33:39 -05:00
break ;
2009-12-14 01:51:12 +01:00
case 49028 : // Dancing Rune Weapon
2009-12-14 02:01:22 +01:00
if ( AuraEffect * aurEff = m_originalCaster -> GetAuraEffect ( 63330 , 0 )) // glyph of Dancing Rune Weapon
duration += aurEff -> GetAmount ();
2009-12-14 01:51:12 +01:00
break ;
2009-05-17 17:33:39 -05:00
}
2010-04-07 19:14:10 +02:00
if ( Player * modOwner = m_originalCaster -> GetSpellModOwner ())
2009-10-15 08:34:19 -07:00
modOwner -> ApplySpellMod ( m_spellInfo -> Id , SPELLMOD_DURATION , duration );
2009-10-17 15:51:44 -07:00
2010-04-19 09:26:37 +02:00
//TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2009-03-20 14:01:46 -06:00
Map * map = caster -> GetMap ();
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( uint32 count = 0 ; count < amount ; ++ count )
2009-03-20 14:01:46 -06:00
{
2009-08-29 14:58:45 -05:00
Position pos ;
GetSummonPosition ( i , pos , radius , count );
2009-10-17 15:51:44 -07:00
2011-05-19 22:27:18 +02:00
TempSummon * summon = map -> SummonCreature ( entry , pos , properties , duration , caster , m_spellInfo -> Id );
2009-11-01 17:53:07 -08:00
if ( ! summon )
2009-03-20 14:01:46 -06:00
return ;
2009-11-01 17:53:07 -08:00
if ( summon -> HasUnitTypeMask ( UNIT_MASK_GUARDIAN ))
2009-03-20 14:01:46 -06:00
(( Guardian * ) summon ) -> InitStatsForLevel ( level );
2009-10-17 15:51:44 -07:00
2011-04-27 16:22:42 +06:00
if ( properties && properties -> Category == SUMMON_CATEGORY_ALLY )
summon -> setFaction ( caster -> getFaction ());
2010-03-19 00:21:57 +01:00
if ( summon -> HasUnitTypeMask ( UNIT_MASK_MINION ) && m_targets . HasDst ())
2009-07-22 17:10:30 +02:00
(( Minion * ) summon ) -> SetFollowAngle ( m_caster -> GetAngle ( summon ));
2009-10-17 15:51:44 -07:00
2009-12-14 01:51:12 +01:00
if ( summon -> GetEntry () == 27893 )
2010-08-30 15:25:15 +02:00
{
2009-12-14 01:51:12 +01:00
if ( uint32 weapon = m_caster -> GetUInt32Value ( PLAYER_VISIBLE_ITEM_16_ENTRYID ))
{
summon -> SetDisplayId ( 11686 );
summon -> SetUInt32Value ( UNIT_VIRTUAL_ITEM_SLOT_ID , weapon );
}
else
summon -> SetDisplayId ( 1126 );
2010-08-30 15:25:15 +02:00
}
2009-12-17 12:23:01 +01:00
2009-05-12 10:11:54 -05:00
summon -> AI () -> EnterEvadeMode ();
2010-08-27 17:49:32 +02:00
ExecuteLogEffectSummonObject ( i , summon );
2009-03-20 14:01:46 -06:00
}
}
2009-10-17 15:51:44 -07:00
2009-08-29 14:58:45 -05:00
void Spell :: GetSummonPosition ( uint32 i , Position & pos , float radius , uint32 count )
2009-03-19 15:45:22 -06:00
{
2009-08-29 23:20:16 -05:00
pos . SetOrientation ( m_caster -> GetOrientation ());
2009-10-17 15:51:44 -07:00
2010-03-19 00:21:57 +01:00
if ( m_targets . HasDst ())
2009-03-19 15:45:22 -06:00
{
// Summon 1 unit in dest location
if ( count == 0 )
2009-08-29 23:20:16 -05:00
pos . Relocate ( m_targets . m_dstPos );
2009-03-19 15:45:22 -06:00
// Summon in random point all other units if location present
else
2009-05-10 22:47:03 -05:00
{
//This is a workaround. Do not have time to write much about it
2009-11-01 17:53:07 -08:00
switch ( m_spellInfo -> EffectImplicitTargetA [ i ])
2009-05-10 22:47:03 -05:00
{
case TARGET_MINION :
case TARGET_DEST_CASTER_RANDOM :
2010-08-22 12:39:39 -07:00
m_caster -> GetNearPosition ( pos , radius * ( float ) rand_norm (), ( float ) rand_norm () * static_cast < float > ( 2 * M_PI ));
2009-05-10 22:47:03 -05:00
break ;
case TARGET_DEST_DEST_RANDOM :
case TARGET_DEST_TARGET_RANDOM :
2009-08-29 23:20:16 -05:00
m_caster -> GetRandomPoint ( m_targets . m_dstPos , radius , pos );
2009-05-10 22:47:03 -05:00
break ;
default :
2009-08-29 23:20:16 -05:00
pos . Relocate ( m_targets . m_dstPos );
2009-05-10 22:47:03 -05:00
break ;
}
}
2009-03-19 15:45:22 -06:00
}
// Summon if dest location not present near caster
else
2009-08-29 14:58:45 -05:00
{
float x , y , z ;
2011-04-29 20:47:02 +02:00
m_caster -> GetClosePoint ( x , y , z , 3.0f );
2009-08-29 23:20:16 -05:00
pos . Relocate ( x , y , z );
2009-08-29 14:58:45 -05:00
}
2009-03-19 15:45:22 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectRenamePet ( SpellEffIndex /*effIndex*/ )
2009-01-22 22:44:27 -06:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_UNIT ||
2010-03-07 18:30:53 +01:00
! unitTarget -> ToCreature () -> isPet () || (( Pet * ) unitTarget ) -> getPetType () != HUNTER_PET )
2009-01-22 22:44:27 -06:00
return ;
2009-10-17 15:51:44 -07:00
2010-11-07 22:23:12 +01:00
unitTarget -> SetByteFlag ( UNIT_FIELD_BYTES_2 , 2 , UNIT_CAN_BE_RENAMED );
2009-07-30 10:18:05 +08:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectPlayMusic ( SpellEffIndex effIndex )
2009-07-30 10:18:05 +08:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-07-30 10:18:05 +08:00
return ;
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
uint32 soundid = m_spellInfo -> EffectMiscValue [ effIndex ];
2009-10-17 15:51:44 -07:00
2009-07-30 10:18:05 +08:00
if ( ! sSoundEntriesStore . LookupEntry ( soundid ))
{
2011-04-29 20:47:02 +02:00
sLog -> outError ( "EffectPlayMusic: Sound (Id: %u) not exist in spell %u." , soundid , m_spellInfo -> Id );
2009-07-30 10:18:05 +08:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-07-30 10:18:05 +08:00
WorldPacket data ( SMSG_PLAY_MUSIC , 4 );
data << uint32 ( soundid );
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> GetSession () -> SendPacket ( & data );
2009-07-30 10:18:05 +08:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectSpecCount ( SpellEffIndex /*effIndex*/ )
2009-08-14 17:24:52 -07:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-08-14 17:24:52 -07:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> UpdateSpecCount ( damage );
2009-08-14 17:24:52 -07:00
}
2009-10-17 15:51:44 -07:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectActivateSpec ( SpellEffIndex /*effIndex*/ )
2009-08-14 17:24:52 -07:00
{
2009-11-01 17:53:07 -08:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-08-14 17:24:52 -07:00
return ;
2009-10-17 15:51:44 -07:00
2010-03-07 15:20:19 +01:00
unitTarget -> ToPlayer () -> ActivateSpec ( damage - 1 ); // damage is 1 or 2, spec is 0 or 1
2009-08-14 17:24:52 -07:00
}
2011-03-07 21:13:18 +01:00
void Spell :: EffectPlayerNotification ( SpellEffIndex effIndex )
2010-01-10 01:23:15 +01:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
switch ( m_spellInfo -> Id )
{
case 58730 : // Restricted Flight Area
case 58600 : // Restricted Flight Area
2010-03-11 20:51:31 +01:00
unitTarget -> ToPlayer () -> GetSession () -> SendNotification ( LANG_ZONE_NOFLYZONE );
2010-01-10 01:23:15 +01:00
break ;
}
2011-03-07 21:13:18 +01:00
uint32 soundid = m_spellInfo -> EffectMiscValue [ effIndex ];
if ( ! sSoundEntriesStore . LookupEntry ( soundid ))
{
sLog -> outError ( "EffectPlayerNotification: Sound (Id: %u) not exist in spell %u." , soundid , m_spellInfo -> Id );
return ;
}
WorldPacket data ( SMSG_PLAY_SOUND , 4 );
data << uint32 ( soundid );
unitTarget -> ToPlayer () -> GetSession () -> SendPacket ( & data );
2010-01-10 01:23:15 +01:00
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectRemoveAura ( SpellEffIndex effIndex )
2010-07-20 04:29:17 +02:00
{
if ( ! unitTarget )
return ;
// there may be need of specifying casterguid of removed auras
2010-08-27 19:36:27 +02:00
unitTarget -> RemoveAurasDueToSpell ( m_spellInfo -> EffectTriggerSpell [ effIndex ]);
2010-07-20 04:29:17 +02:00
}
2010-08-27 19:36:27 +02:00
void Spell :: EffectCastButtons ( SpellEffIndex effIndex )
2009-12-17 12:23:01 +01:00
{
if ( ! unitTarget || m_caster -> GetTypeId () != TYPEID_PLAYER )
return ;
Player * p_caster = ( Player * ) m_caster ;
2010-08-27 19:36:27 +02:00
uint32 button_id = m_spellInfo -> EffectMiscValue [ effIndex ] + 132 ;
uint32 n_buttons = m_spellInfo -> EffectMiscValueB [ effIndex ];
2009-12-17 12:23:01 +01:00
for (; n_buttons ; n_buttons -- , button_id ++ )
{
2010-04-28 16:08:31 +02:00
ActionButton const * ab = p_caster -> GetActionButton ( button_id );
2010-04-29 11:35:31 +02:00
if ( ! ab || ab -> GetType () != ACTION_BUTTON_SPELL )
continue ;
2009-12-17 12:23:01 +01:00
2010-04-28 16:08:31 +02:00
uint32 spell_id = ab -> GetAction ();
if ( ! spell_id )
continue ;
if ( p_caster -> HasSpellCooldown ( spell_id ))
continue ;
2009-12-17 12:23:01 +01:00
2010-04-28 16:08:31 +02:00
SpellEntry const * spellInfo = sSpellStore . LookupEntry ( spell_id );
uint32 cost = CalculatePowerCost ( spellInfo , m_caster , GetSpellSchoolMask ( spellInfo ));
2009-12-17 12:23:01 +01:00
2010-04-28 16:08:31 +02:00
if ( m_caster -> GetPower ( POWER_MANA ) < cost )
break ;
2009-12-17 12:23:01 +01:00
m_caster -> CastSpell ( unitTarget , spell_id , true );
m_caster -> ModifyPower ( POWER_MANA , - ( int32 ) cost );
p_caster -> AddSpellAndCategoryCooldowns ( spellInfo , 0 );
}
}
2009-12-26 18:25:49 +01:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectRechargeManaGem ( SpellEffIndex /*effIndex*/ )
2009-12-26 18:25:49 +01:00
{
2010-04-07 19:14:10 +02:00
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
2009-12-26 18:25:49 +01:00
return ;
2010-08-18 15:04:00 +02:00
Player * player = m_caster -> ToPlayer ();
2009-12-26 18:25:49 +01:00
if ( ! player )
return ;
uint32 item_id = m_spellInfo -> EffectItemType [ 0 ];
2011-04-28 22:42:33 +02:00
ItemTemplate const * pProto = sObjectMgr -> GetItemTemplate ( item_id );
2010-04-07 19:14:10 +02:00
if ( ! pProto )
2009-12-26 18:25:49 +01:00
{
2010-04-07 22:59:46 +02:00
player -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , NULL , NULL );
2009-12-26 18:25:49 +01:00
return ;
}
if ( Item * pItem = player -> GetItemByEntry ( item_id ))
{
2010-04-07 19:12:44 +02:00
for ( int x = 0 ; x < MAX_ITEM_PROTO_SPELLS ; ++ x )
2011-04-29 20:47:02 +02:00
pItem -> SetSpellCharges ( x , pProto -> Spells [ x ]. SpellCharges );
pItem -> SetState ( ITEM_CHANGED , player );
2009-12-26 18:25:49 +01:00
}
}
2010-04-18 23:20:07 +02:00
2010-08-27 19:36:27 +02:00
void Spell :: EffectBind ( SpellEffIndex effIndex )
2010-04-18 23:20:07 +02:00
{
if ( ! unitTarget || unitTarget -> GetTypeId () != TYPEID_PLAYER )
return ;
2010-12-03 13:54:00 +01:00
Player * player = unitTarget -> ToPlayer ();
2010-04-18 23:20:07 +02:00
uint32 area_id ;
WorldLocation loc ;
2010-08-27 19:36:27 +02:00
if ( m_spellInfo -> EffectImplicitTargetA [ effIndex ] == TARGET_DST_DB || m_spellInfo -> EffectImplicitTargetB [ effIndex ] == TARGET_DST_DB )
2010-04-18 23:20:07 +02:00
{
2010-12-22 21:25:23 +01:00
SpellTargetPosition const * st = sSpellMgr -> GetSpellTargetPosition ( m_spellInfo -> Id );
2010-04-18 23:20:07 +02:00
if ( ! st )
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Spell::EffectBind - unknown teleport coordinates for spell ID %u" , m_spellInfo -> Id );
2010-04-18 23:20:07 +02:00
return ;
}
2010-12-03 13:54:00 +01:00
loc . m_mapId = st -> target_mapId ;
2010-04-18 23:20:07 +02:00
loc . m_positionX = st -> target_X ;
loc . m_positionY = st -> target_Y ;
2010-12-03 13:54:00 +01:00
loc . m_positionZ = st -> target_Z ;
2010-04-18 23:20:07 +02:00
loc . m_orientation = st -> target_Orientation ;
area_id = player -> GetAreaId ();
}
else
{
player -> GetPosition ( & loc );
area_id = player -> GetAreaId ();
}
player -> SetHomebind ( loc , area_id );
// binding
2010-12-03 13:54:00 +01:00
WorldPacket data ( SMSG_BINDPOINTUPDATE , ( 4 + 4 + 4 + 4 + 4 ));
2010-04-18 23:20:07 +02:00
data << float ( loc . m_positionX );
data << float ( loc . m_positionY );
data << float ( loc . m_positionZ );
data << uint32 ( loc . m_mapId );
data << uint32 ( area_id );
2010-12-03 13:54:00 +01:00
player -> SendDirectMessage ( & data );
2010-04-18 23:20:07 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outStaticDebug ( "New homebind X : %f" , loc . m_positionX );
sLog -> outStaticDebug ( "New homebind Y : %f" , loc . m_positionY );
sLog -> outStaticDebug ( "New homebind Z : %f" , loc . m_positionZ );
sLog -> outStaticDebug ( "New homebind MapId : %u" , loc . m_mapId );
sLog -> outStaticDebug ( "New homebind AreaId : %u" , area_id );
2010-04-18 23:20:07 +02:00
// zone update
data . Initialize ( SMSG_PLAYERBOUND , 8 + 4 );
data << uint64 ( player -> GetGUID ());
data << uint32 ( area_id );
player -> SendDirectMessage ( & data );
}