PageRenderTime 77ms CodeModel.GetById 51ms RepoModel.GetById 0ms app.codeStats 2ms

/src/server/game/Spells/Spell.cpp

https://gitlab.com/IlluminatiCore/IlluminatiCore
C++ | 7453 lines | 5814 code | 1007 blank | 632 comment | 2218 complexity | d9e7a50b5eb0c9922b1987c566c7600b MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause
  1. /*
  2. * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
  3. * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Common.h"
  19. #include "DatabaseEnv.h"
  20. #include "WorldPacket.h"
  21. #include "WorldSession.h"
  22. #include "GridNotifiers.h"
  23. #include "GridNotifiersImpl.h"
  24. #include "Opcodes.h"
  25. #include "Log.h"
  26. #include "UpdateMask.h"
  27. #include "World.h"
  28. #include "ObjectMgr.h"
  29. #include "SpellMgr.h"
  30. #include "Player.h"
  31. #include "Pet.h"
  32. #include "Unit.h"
  33. #include "Totem.h"
  34. #include "Spell.h"
  35. #include "DynamicObject.h"
  36. #include "Guild.h"
  37. #include "Group.h"
  38. #include "UpdateData.h"
  39. #include "MapManager.h"
  40. #include "ObjectAccessor.h"
  41. #include "CellImpl.h"
  42. #include "SharedDefines.h"
  43. #include "LootMgr.h"
  44. #include "VMapFactory.h"
  45. #include "Battleground.h"
  46. #include "Util.h"
  47. #include "TemporarySummon.h"
  48. #include "Vehicle.h"
  49. #include "SpellAuraEffects.h"
  50. #include "ScriptMgr.h"
  51. #include "ConditionMgr.h"
  52. #include "DisableMgr.h"
  53. #include "SpellScript.h"
  54. #include "InstanceScript.h"
  55. #include "SpellInfo.h"
  56. #include "DB2Stores.h"
  57. #include "Battlefield.h"
  58. #include "BattlefieldMgr.h"
  59. extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
  60. SpellDestination::SpellDestination()
  61. {
  62. _position.Relocate(0, 0, 0, 0);
  63. _transportGUID.Clear();
  64. _transportOffset.Relocate(0, 0, 0, 0);
  65. }
  66. SpellDestination::SpellDestination(float x, float y, float z, float orientation, uint32 mapId)
  67. {
  68. _position.Relocate(x, y, z, orientation);
  69. _transportGUID.Clear();
  70. _position.m_mapId = mapId;
  71. _transportOffset.Relocate(0, 0, 0, 0);
  72. }
  73. SpellDestination::SpellDestination(Position const& pos)
  74. {
  75. _position.Relocate(pos);
  76. _transportGUID.Clear();
  77. _transportOffset.Relocate(0, 0, 0, 0);
  78. }
  79. SpellDestination::SpellDestination(WorldObject const& wObj)
  80. {
  81. _transportGUID = wObj.GetTransGUID();
  82. _transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
  83. _position.Relocate(wObj);
  84. }
  85. void SpellDestination::Relocate(Position const& pos)
  86. {
  87. if (_transportGUID)
  88. {
  89. Position offset;
  90. _position.GetPositionOffsetTo(pos, offset);
  91. _transportOffset.RelocateOffset(offset);
  92. }
  93. _position.Relocate(pos);
  94. }
  95. void SpellDestination::RelocateOffset(Position const& offset)
  96. {
  97. if (_transportGUID)
  98. _transportOffset.RelocateOffset(offset);
  99. _position.RelocateOffset(offset);
  100. }
  101. SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()
  102. {
  103. m_objectTarget = NULL;
  104. m_itemTarget = NULL;
  105. m_itemTargetEntry = 0;
  106. m_targetMask = 0;
  107. }
  108. SpellCastTargets::~SpellCastTargets() { }
  109. void SpellCastTargets::Read(ByteBuffer& data, Unit* caster)
  110. {
  111. data >> m_targetMask;
  112. if (m_targetMask == TARGET_FLAG_NONE)
  113. return;
  114. if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_CORPSE_ALLY))
  115. data >> m_objectTargetGUID.ReadAsPacked();
  116. if (m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
  117. data >> m_itemTargetGUID.ReadAsPacked();
  118. if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
  119. {
  120. data >> m_src._transportGUID.ReadAsPacked();
  121. if (m_src._transportGUID)
  122. data >> m_src._transportOffset.PositionXYZStream();
  123. else
  124. data >> m_src._position.PositionXYZStream();
  125. }
  126. else
  127. {
  128. m_src._transportGUID = caster->GetTransGUID();
  129. if (m_src._transportGUID)
  130. m_src._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
  131. else
  132. m_src._position.Relocate(caster);
  133. }
  134. if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
  135. {
  136. data >> m_dst._transportGUID.ReadAsPacked();
  137. if (m_dst._transportGUID)
  138. data >> m_dst._transportOffset.PositionXYZStream();
  139. else
  140. data >> m_dst._position.PositionXYZStream();
  141. }
  142. else
  143. {
  144. m_dst._transportGUID = caster->GetTransGUID();
  145. if (m_dst._transportGUID)
  146. m_dst._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
  147. else
  148. m_dst._position.Relocate(caster);
  149. }
  150. if (m_targetMask & TARGET_FLAG_STRING)
  151. data >> m_strTarget;
  152. Update(caster);
  153. }
  154. void SpellCastTargets::Write(ByteBuffer& data)
  155. {
  156. data << uint32(m_targetMask);
  157. if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_MINIPET))
  158. data << m_objectTargetGUID.WriteAsPacked();
  159. if (m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
  160. {
  161. if (m_itemTarget)
  162. data << m_itemTarget->GetPackGUID();
  163. else
  164. data << uint8(0);
  165. }
  166. if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
  167. {
  168. data << m_src._transportGUID.WriteAsPacked(); // relative position guid here - transport for example
  169. if (m_src._transportGUID)
  170. data << m_src._transportOffset.PositionXYZStream();
  171. else
  172. data << m_src._position.PositionXYZStream();
  173. }
  174. if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
  175. {
  176. data << m_dst._transportGUID.WriteAsPacked(); // relative position guid here - transport for example
  177. if (m_dst._transportGUID)
  178. data << m_dst._transportOffset.PositionXYZStream();
  179. else
  180. data << m_dst._position.PositionXYZStream();
  181. }
  182. if (m_targetMask & TARGET_FLAG_STRING)
  183. data << m_strTarget;
  184. }
  185. ObjectGuid SpellCastTargets::GetOrigUnitTargetGUID() const
  186. {
  187. switch (m_origObjectTargetGUID.GetHigh())
  188. {
  189. case HIGHGUID_PLAYER:
  190. case HIGHGUID_VEHICLE:
  191. case HIGHGUID_UNIT:
  192. case HIGHGUID_PET:
  193. return m_origObjectTargetGUID;
  194. default:
  195. return ObjectGuid();
  196. }
  197. }
  198. void SpellCastTargets::SetOrigUnitTarget(Unit* target)
  199. {
  200. if (!target)
  201. return;
  202. m_origObjectTargetGUID = target->GetGUID();
  203. }
  204. ObjectGuid SpellCastTargets::GetUnitTargetGUID() const
  205. {
  206. if (m_objectTargetGUID.IsUnit())
  207. return m_objectTargetGUID;
  208. return ObjectGuid::Empty;
  209. }
  210. Unit* SpellCastTargets::GetUnitTarget() const
  211. {
  212. if (m_objectTarget)
  213. return m_objectTarget->ToUnit();
  214. return NULL;
  215. }
  216. void SpellCastTargets::SetUnitTarget(Unit* target)
  217. {
  218. if (!target)
  219. return;
  220. m_objectTarget = target;
  221. m_objectTargetGUID = target->GetGUID();
  222. m_targetMask |= TARGET_FLAG_UNIT;
  223. }
  224. ObjectGuid SpellCastTargets::GetGOTargetGUID() const
  225. {
  226. if (m_objectTargetGUID.IsAnyTypeGameObject())
  227. return m_objectTargetGUID;
  228. return ObjectGuid::Empty;
  229. }
  230. GameObject* SpellCastTargets::GetGOTarget() const
  231. {
  232. if (m_objectTarget)
  233. return m_objectTarget->ToGameObject();
  234. return NULL;
  235. }
  236. void SpellCastTargets::SetGOTarget(GameObject* target)
  237. {
  238. if (!target)
  239. return;
  240. m_objectTarget = target;
  241. m_objectTargetGUID = target->GetGUID();
  242. m_targetMask |= TARGET_FLAG_GAMEOBJECT;
  243. }
  244. ObjectGuid SpellCastTargets::GetCorpseTargetGUID() const
  245. {
  246. if (m_objectTargetGUID.IsCorpse())
  247. return m_objectTargetGUID;
  248. return ObjectGuid::Empty;
  249. }
  250. Corpse* SpellCastTargets::GetCorpseTarget() const
  251. {
  252. if (m_objectTarget)
  253. return m_objectTarget->ToCorpse();
  254. return NULL;
  255. }
  256. WorldObject* SpellCastTargets::GetObjectTarget() const
  257. {
  258. return m_objectTarget;
  259. }
  260. ObjectGuid SpellCastTargets::GetObjectTargetGUID() const
  261. {
  262. return m_objectTargetGUID;
  263. }
  264. void SpellCastTargets::RemoveObjectTarget()
  265. {
  266. m_objectTarget = NULL;
  267. m_objectTargetGUID.Clear();
  268. m_targetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_GAMEOBJECT_MASK);
  269. }
  270. void SpellCastTargets::SetItemTarget(Item* item)
  271. {
  272. if (!item)
  273. return;
  274. m_itemTarget = item;
  275. m_itemTargetGUID = item->GetGUID();
  276. m_itemTargetEntry = item->GetEntry();
  277. m_targetMask |= TARGET_FLAG_ITEM;
  278. }
  279. void SpellCastTargets::SetTradeItemTarget(Player* caster)
  280. {
  281. m_itemTargetGUID.Set(uint64(TRADE_SLOT_NONTRADED));
  282. m_itemTargetEntry = 0;
  283. m_targetMask |= TARGET_FLAG_TRADE_ITEM;
  284. Update(caster);
  285. }
  286. void SpellCastTargets::UpdateTradeSlotItem()
  287. {
  288. if (m_itemTarget && (m_targetMask & TARGET_FLAG_TRADE_ITEM))
  289. {
  290. m_itemTargetGUID = m_itemTarget->GetGUID();
  291. m_itemTargetEntry = m_itemTarget->GetEntry();
  292. }
  293. }
  294. SpellDestination const* SpellCastTargets::GetSrc() const
  295. {
  296. return &m_src;
  297. }
  298. Position const* SpellCastTargets::GetSrcPos() const
  299. {
  300. return &m_src._position;
  301. }
  302. void SpellCastTargets::SetSrc(float x, float y, float z)
  303. {
  304. m_src = SpellDestination(x, y, z);
  305. m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
  306. }
  307. void SpellCastTargets::SetSrc(Position const& pos)
  308. {
  309. m_src = SpellDestination(pos);
  310. m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
  311. }
  312. void SpellCastTargets::SetSrc(WorldObject const& wObj)
  313. {
  314. m_src = SpellDestination(wObj);
  315. m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
  316. }
  317. void SpellCastTargets::ModSrc(Position const& pos)
  318. {
  319. ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION);
  320. m_src.Relocate(pos);
  321. }
  322. void SpellCastTargets::RemoveSrc()
  323. {
  324. m_targetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
  325. }
  326. SpellDestination const* SpellCastTargets::GetDst() const
  327. {
  328. return &m_dst;
  329. }
  330. WorldLocation const* SpellCastTargets::GetDstPos() const
  331. {
  332. return &m_dst._position;
  333. }
  334. void SpellCastTargets::SetDst(float x, float y, float z, float orientation, uint32 mapId)
  335. {
  336. m_dst = SpellDestination(x, y, z, orientation, mapId);
  337. m_targetMask |= TARGET_FLAG_DEST_LOCATION;
  338. }
  339. void SpellCastTargets::SetDst(Position const& pos)
  340. {
  341. m_dst = SpellDestination(pos);
  342. m_targetMask |= TARGET_FLAG_DEST_LOCATION;
  343. }
  344. void SpellCastTargets::SetDst(WorldObject const& wObj)
  345. {
  346. m_dst = SpellDestination(wObj);
  347. m_targetMask |= TARGET_FLAG_DEST_LOCATION;
  348. }
  349. void SpellCastTargets::SetDst(SpellDestination const& spellDest)
  350. {
  351. m_dst = spellDest;
  352. m_targetMask |= TARGET_FLAG_DEST_LOCATION;
  353. }
  354. void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
  355. {
  356. m_dst = spellTargets.m_dst;
  357. m_targetMask |= TARGET_FLAG_DEST_LOCATION;
  358. }
  359. void SpellCastTargets::ModDst(Position const& pos)
  360. {
  361. ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
  362. m_dst.Relocate(pos);
  363. }
  364. void SpellCastTargets::ModDst(SpellDestination const& spellDest)
  365. {
  366. ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
  367. m_dst = spellDest;
  368. }
  369. void SpellCastTargets::RemoveDst()
  370. {
  371. m_targetMask &= ~(TARGET_FLAG_DEST_LOCATION);
  372. }
  373. void SpellCastTargets::Update(Unit* caster)
  374. {
  375. m_objectTarget = m_objectTargetGUID ? ((m_objectTargetGUID == caster->GetGUID()) ? caster : ObjectAccessor::GetWorldObject(*caster, m_objectTargetGUID)) : NULL;
  376. m_itemTarget = NULL;
  377. if (caster->GetTypeId() == TYPEID_PLAYER)
  378. {
  379. Player* player = caster->ToPlayer();
  380. if (m_targetMask & TARGET_FLAG_ITEM)
  381. m_itemTarget = player->GetItemByGuid(m_itemTargetGUID);
  382. else if (m_targetMask & TARGET_FLAG_TRADE_ITEM)
  383. if (m_itemTargetGUID.GetRawValue() == TRADE_SLOT_NONTRADED) // here it is not guid but slot. Also prevents hacking slots
  384. if (TradeData* pTrade = player->GetTradeData())
  385. m_itemTarget = pTrade->GetTraderData()->GetItem(TRADE_SLOT_NONTRADED);
  386. if (m_itemTarget)
  387. m_itemTargetEntry = m_itemTarget->GetEntry();
  388. }
  389. // update positions by transport move
  390. if (HasSrc() && m_src._transportGUID)
  391. {
  392. if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_src._transportGUID))
  393. {
  394. m_src._position.Relocate(transport);
  395. m_src._position.RelocateOffset(m_src._transportOffset);
  396. }
  397. }
  398. if (HasDst() && m_dst._transportGUID)
  399. {
  400. if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_dst._transportGUID))
  401. {
  402. m_dst._position.Relocate(transport);
  403. m_dst._position.RelocateOffset(m_dst._transportOffset);
  404. }
  405. }
  406. }
  407. void SpellCastTargets::OutDebug() const
  408. {
  409. if (!m_targetMask)
  410. TC_LOG_INFO("spells", "No targets");
  411. TC_LOG_INFO("spells", "target mask: %u", m_targetMask);
  412. if (m_targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
  413. TC_LOG_INFO("spells", "Object target: %s", m_objectTargetGUID.ToString().c_str());
  414. if (m_targetMask & TARGET_FLAG_ITEM)
  415. TC_LOG_INFO("spells", "Item target: %s", m_itemTargetGUID.ToString().c_str());
  416. if (m_targetMask & TARGET_FLAG_TRADE_ITEM)
  417. TC_LOG_INFO("spells", "Trade item target: %s", m_itemTargetGUID.ToString().c_str());
  418. if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
  419. TC_LOG_INFO("spells", "Source location: transport guid:%s trans offset: %s position: %s", m_src._transportGUID.ToString().c_str(), m_src._transportOffset.ToString().c_str(), m_src._position.ToString().c_str());
  420. if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
  421. TC_LOG_INFO("spells", "Destination location: transport guid:%s trans offset: %s position: %s", m_dst._transportGUID.ToString().c_str(), m_dst._transportOffset.ToString().c_str(), m_dst._position.ToString().c_str());
  422. if (m_targetMask & TARGET_FLAG_STRING)
  423. TC_LOG_INFO("spells", "String: %s", m_strTarget.c_str());
  424. TC_LOG_INFO("spells", "speed: %f", m_speed);
  425. TC_LOG_INFO("spells", "elevation: %f", m_elevation);
  426. }
  427. SpellValue::SpellValue(SpellInfo const* proto)
  428. {
  429. for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  430. EffectBasePoints[i] = proto->Effects[i].BasePoints;
  431. MaxAffectedTargets = proto->MaxAffectedTargets;
  432. RadiusMod = 1.0f;
  433. AuraStackAmount = 1;
  434. }
  435. Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) :
  436. m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
  437. m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
  438. , m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
  439. {
  440. m_customError = SPELL_CUSTOM_ERROR_NONE;
  441. m_skipCheck = skipCheck;
  442. m_selfContainer = NULL;
  443. m_referencedFromCurrentSpell = false;
  444. m_executedCurrently = false;
  445. m_needComboPoints = m_spellInfo->NeedsComboPoints();
  446. m_comboPointGain = 0;
  447. m_delayStart = 0;
  448. m_delayAtDamageCount = 0;
  449. m_applyMultiplierMask = 0;
  450. m_auraScaleMask = 0;
  451. memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
  452. // Get data for type of attack
  453. switch (m_spellInfo->DmgClass)
  454. {
  455. case SPELL_DAMAGE_CLASS_MELEE:
  456. if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND)
  457. m_attackType = OFF_ATTACK;
  458. else
  459. m_attackType = BASE_ATTACK;
  460. break;
  461. case SPELL_DAMAGE_CLASS_RANGED:
  462. m_attackType = m_spellInfo->IsRangedWeaponSpell() ? RANGED_ATTACK : BASE_ATTACK;
  463. break;
  464. default:
  465. // Wands
  466. if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG)
  467. m_attackType = RANGED_ATTACK;
  468. else
  469. m_attackType = BASE_ATTACK;
  470. break;
  471. }
  472. m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
  473. if (m_attackType == RANGED_ATTACK)
  474. // wand case
  475. if ((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId() == TYPEID_PLAYER)
  476. if (Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK))
  477. m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->DamageType);
  478. if (originalCasterGUID)
  479. m_originalCasterGUID = originalCasterGUID;
  480. else
  481. m_originalCasterGUID = m_caster->GetGUID();
  482. if (m_originalCasterGUID == m_caster->GetGUID())
  483. m_originalCaster = m_caster;
  484. else
  485. {
  486. m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
  487. if (m_originalCaster && !m_originalCaster->IsInWorld())
  488. m_originalCaster = NULL;
  489. }
  490. m_spellState = SPELL_STATE_NULL;
  491. _triggeredCastFlags = triggerFlags;
  492. if (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED)
  493. _triggeredCastFlags = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT);
  494. m_CastItem = NULL;
  495. m_castItemGUID.Clear();
  496. m_castItemEntry = 0;
  497. unitTarget = NULL;
  498. itemTarget = NULL;
  499. gameObjTarget = NULL;
  500. destTarget = NULL;
  501. damage = 0;
  502. effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH;
  503. m_diminishLevel = DIMINISHING_LEVEL_1;
  504. m_diminishGroup = DIMINISHING_NONE;
  505. m_damage = 0;
  506. m_healing = 0;
  507. m_procAttacker = 0;
  508. m_procVictim = 0;
  509. m_procEx = 0;
  510. focusObject = NULL;
  511. m_cast_count = 0;
  512. m_glyphIndex = 0;
  513. m_preCastSpell = 0;
  514. m_triggeredByAuraSpell = NULL;
  515. m_spellAura = NULL;
  516. //Auto Shot & Shoot (wand)
  517. m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell();
  518. m_runesState = 0;
  519. m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
  520. m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
  521. m_timer = 0; // will set to castime in prepare
  522. m_channeledDuration = 0; // will be setup in Spell::handle_immediate
  523. m_immediateHandled = false;
  524. m_channelTargetEffectMask = 0;
  525. // Determine if spell can be reflected back to the caster
  526. // Patch 1.2 notes: Spell Reflection no longer reflects abilities
  527. m_canReflect = m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->Attributes & SPELL_ATTR0_ABILITY)
  528. && !(m_spellInfo->AttributesEx & SPELL_ATTR1_CANT_BE_REFLECTED) && !(m_spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)
  529. && !m_spellInfo->IsPassive() && !m_spellInfo->IsPositive();
  530. CleanupTargetList();
  531. memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
  532. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  533. m_destTargets[i] = SpellDestination(*m_caster);
  534. }
  535. Spell::~Spell()
  536. {
  537. // unload scripts
  538. while (!m_loadedScripts.empty())
  539. {
  540. std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
  541. (*itr)->_Unload();
  542. delete (*itr);
  543. m_loadedScripts.erase(itr);
  544. }
  545. if (m_referencedFromCurrentSpell && m_selfContainer && *m_selfContainer == this)
  546. {
  547. // Clean the reference to avoid later crash.
  548. // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
  549. TC_LOG_ERROR("spells", "SPELL: deleting spell for spell ID %u. However, spell still referenced.", m_spellInfo->Id);
  550. *m_selfContainer = NULL;
  551. }
  552. if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER)
  553. ASSERT(m_caster->ToPlayer()->m_spellModTakingSpell != this);
  554. delete m_spellValue;
  555. CheckEffectExecuteData();
  556. }
  557. void Spell::InitExplicitTargets(SpellCastTargets const& targets)
  558. {
  559. m_targets = targets;
  560. m_targets.SetOrigUnitTarget(m_targets.GetUnitTarget());
  561. // this function tries to correct spell explicit targets for spell
  562. // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
  563. // this also makes sure that we correctly send explicit targets to client (removes redundant data)
  564. uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
  565. if (WorldObject* target = m_targets.GetObjectTarget())
  566. {
  567. // check if object target is valid with needed target flags
  568. // for unit case allow corpse target mask because player with not released corpse is a unit target
  569. if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
  570. || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
  571. || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
  572. m_targets.RemoveObjectTarget();
  573. }
  574. else
  575. {
  576. // try to select correct unit target if not provided by client or by serverside cast
  577. if (neededTargets & (TARGET_FLAG_UNIT_MASK))
  578. {
  579. Unit* unit = NULL;
  580. // try to use player selection as a target
  581. if (Player* playerCaster = m_caster->ToPlayer())
  582. {
  583. // selection has to be found and to be valid target for the spell
  584. if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
  585. if (m_spellInfo->CheckExplicitTarget(m_caster, selectedUnit) == SPELL_CAST_OK)
  586. unit = selectedUnit;
  587. }
  588. // try to use attacked unit as a target
  589. else if ((m_caster->GetTypeId() == TYPEID_UNIT) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
  590. unit = m_caster->GetVictim();
  591. // didn't find anything - let's use self as target
  592. if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
  593. unit = m_caster;
  594. m_targets.SetUnitTarget(unit);
  595. }
  596. }
  597. // check if spell needs dst target
  598. if (neededTargets & TARGET_FLAG_DEST_LOCATION)
  599. {
  600. // and target isn't set
  601. if (!m_targets.HasDst())
  602. {
  603. // try to use unit target if provided
  604. if (WorldObject* target = targets.GetObjectTarget())
  605. m_targets.SetDst(*target);
  606. // or use self if not available
  607. else
  608. m_targets.SetDst(*m_caster);
  609. }
  610. }
  611. else
  612. m_targets.RemoveDst();
  613. if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
  614. {
  615. if (!targets.HasSrc())
  616. m_targets.SetSrc(*m_caster);
  617. }
  618. else
  619. m_targets.RemoveSrc();
  620. }
  621. void Spell::SelectExplicitTargets()
  622. {
  623. // here go all explicit target changes made to explicit targets after spell prepare phase is finished
  624. if (Unit* target = m_targets.GetUnitTarget())
  625. {
  626. // check for explicit target redirection, for Grounding Totem for example
  627. if (m_spellInfo->GetExplicitTargetMask() & TARGET_FLAG_UNIT_ENEMY
  628. || (m_spellInfo->GetExplicitTargetMask() & TARGET_FLAG_UNIT && !m_spellInfo->IsPositive()))
  629. {
  630. Unit* redirect;
  631. switch (m_spellInfo->DmgClass)
  632. {
  633. case SPELL_DAMAGE_CLASS_MAGIC:
  634. redirect = m_caster->GetMagicHitRedirectTarget(target, m_spellInfo);
  635. break;
  636. case SPELL_DAMAGE_CLASS_MELEE:
  637. case SPELL_DAMAGE_CLASS_RANGED:
  638. redirect = m_caster->GetMeleeHitRedirectTarget(target, m_spellInfo);
  639. break;
  640. default:
  641. redirect = NULL;
  642. break;
  643. }
  644. if (redirect && (redirect != target))
  645. m_targets.SetUnitTarget(redirect);
  646. }
  647. }
  648. }
  649. void Spell::SelectSpellTargets()
  650. {
  651. // select targets for cast phase
  652. SelectExplicitTargets();
  653. uint32 processedAreaEffectsMask = 0;
  654. for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  655. {
  656. // not call for empty effect.
  657. // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
  658. if (!m_spellInfo->Effects[i].IsEffect())
  659. continue;
  660. // set expected type of implicit targets to be sent to client
  661. uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
  662. if (implicitTargetMask & TARGET_FLAG_UNIT)
  663. m_targets.SetTargetFlag(TARGET_FLAG_UNIT);
  664. if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
  665. m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
  666. SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
  667. SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
  668. // Select targets of effect based on effect type
  669. // those are used when no valid target could be added for spell effect based on spell target type
  670. // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
  671. // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
  672. // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
  673. SelectEffectTypeImplicitTargets(i);
  674. if (m_targets.HasDst())
  675. AddDestTarget(*m_targets.GetDst(), i);
  676. if (m_spellInfo->IsChanneled())
  677. {
  678. uint8 mask = (1 << i);
  679. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  680. {
  681. if (ihit->effectMask & mask)
  682. {
  683. m_channelTargetEffectMask |= mask;
  684. break;
  685. }
  686. }
  687. }
  688. else if (m_auraScaleMask)
  689. {
  690. bool checkLvl = !m_UniqueTargetInfo.empty();
  691. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();)
  692. {
  693. // remove targets which did not pass min level check
  694. if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask)
  695. {
  696. // Do not check for selfcast
  697. if (!ihit->scaleAura && ihit->targetGUID != m_caster->GetGUID())
  698. {
  699. m_UniqueTargetInfo.erase(ihit++);
  700. continue;
  701. }
  702. }
  703. ++ihit;
  704. }
  705. if (checkLvl && m_UniqueTargetInfo.empty())
  706. {
  707. SendCastResult(SPELL_FAILED_LOWLEVEL);
  708. finish(false);
  709. }
  710. }
  711. }
  712. if (m_targets.HasDst())
  713. {
  714. if (m_targets.HasTraj())
  715. {
  716. float speed = m_targets.GetSpeedXY();
  717. if (speed > 0.0f)
  718. m_delayMoment = uint64(std::floor(m_targets.GetDist2d() / speed * 1000.0f));
  719. }
  720. else if (m_spellInfo->Speed > 0.0f)
  721. {
  722. float dist = m_caster->GetDistance(*m_targets.GetDstPos());
  723. if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
  724. m_delayMoment = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
  725. else
  726. m_delayMoment = uint64(m_spellInfo->Speed * 1000.0f);
  727. }
  728. }
  729. }
  730. void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
  731. {
  732. if (!targetType.GetTarget())
  733. return;
  734. uint32 effectMask = 1 << effIndex;
  735. // set the same target list for all effects
  736. // some spells appear to need this, however this requires more research
  737. switch (targetType.GetSelectionCategory())
  738. {
  739. case TARGET_SELECT_CATEGORY_NEARBY:
  740. case TARGET_SELECT_CATEGORY_CONE:
  741. case TARGET_SELECT_CATEGORY_AREA:
  742. // targets for effect already selected
  743. if (effectMask & processedEffectMask)
  744. return;
  745. // choose which targets we can select at once
  746. for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
  747. {
  748. SpellEffectInfo const* effects = GetSpellInfo()->Effects;
  749. if (effects[j].IsEffect() &&
  750. effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
  751. effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
  752. effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
  753. effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
  754. CheckScriptEffectImplicitTargets(effIndex, j))
  755. {
  756. effectMask |= 1 << j;
  757. }
  758. }
  759. processedEffectMask |= effectMask;
  760. break;
  761. default:
  762. break;
  763. }
  764. switch (targetType.GetSelectionCategory())
  765. {
  766. case TARGET_SELECT_CATEGORY_CHANNEL:
  767. SelectImplicitChannelTargets(effIndex, targetType);
  768. break;
  769. case TARGET_SELECT_CATEGORY_NEARBY:
  770. SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
  771. break;
  772. case TARGET_SELECT_CATEGORY_CONE:
  773. SelectImplicitConeTargets(effIndex, targetType, effectMask);
  774. break;
  775. case TARGET_SELECT_CATEGORY_AREA:
  776. SelectImplicitAreaTargets(effIndex, targetType, effectMask);
  777. break;
  778. case TARGET_SELECT_CATEGORY_DEFAULT:
  779. switch (targetType.GetObjectType())
  780. {
  781. case TARGET_OBJECT_TYPE_SRC:
  782. switch (targetType.GetReferenceType())
  783. {
  784. case TARGET_REFERENCE_TYPE_CASTER:
  785. m_targets.SetSrc(*m_caster);
  786. break;
  787. default:
  788. ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
  789. break;
  790. }
  791. break;
  792. case TARGET_OBJECT_TYPE_DEST:
  793. switch (targetType.GetReferenceType())
  794. {
  795. case TARGET_REFERENCE_TYPE_CASTER:
  796. SelectImplicitCasterDestTargets(effIndex, targetType);
  797. break;
  798. case TARGET_REFERENCE_TYPE_TARGET:
  799. SelectImplicitTargetDestTargets(effIndex, targetType);
  800. break;
  801. case TARGET_REFERENCE_TYPE_DEST:
  802. SelectImplicitDestDestTargets(effIndex, targetType);
  803. break;
  804. default:
  805. ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
  806. break;
  807. }
  808. break;
  809. default:
  810. switch (targetType.GetReferenceType())
  811. {
  812. case TARGET_REFERENCE_TYPE_CASTER:
  813. SelectImplicitCasterObjectTargets(effIndex, targetType);
  814. break;
  815. case TARGET_REFERENCE_TYPE_TARGET:
  816. SelectImplicitTargetObjectTargets(effIndex, targetType);
  817. break;
  818. default:
  819. ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
  820. break;
  821. }
  822. break;
  823. }
  824. break;
  825. case TARGET_SELECT_CATEGORY_NYI:
  826. TC_LOG_DEBUG("spells", "SPELL: target type %u, found in spellID %u, effect %u is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
  827. break;
  828. default:
  829. ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
  830. break;
  831. }
  832. }
  833. void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  834. {
  835. if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
  836. {
  837. ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
  838. return;
  839. }
  840. Spell* channeledSpell = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
  841. if (!channeledSpell)
  842. {
  843. TC_LOG_DEBUG("spells", "Spell::SelectImplicitChannelTargets: cannot find channel spell for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
  844. return;
  845. }
  846. switch (targetType.GetTarget())
  847. {
  848. case TARGET_UNIT_CHANNEL_TARGET:
  849. {
  850. WorldObject* target = ObjectAccessor::GetUnit(*m_caster, m_originalCaster->GetChannelObjectGuid());
  851. CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
  852. // unit target may be no longer avalible - teleported out of map for example
  853. if (target && target->ToUnit())
  854. AddUnitTarget(target->ToUnit(), 1 << effIndex);
  855. else
  856. TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
  857. break;
  858. }
  859. case TARGET_DEST_CHANNEL_TARGET:
  860. if (channeledSpell->m_targets.HasDst())
  861. m_targets.SetDst(channeledSpell->m_targets);
  862. else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, m_originalCaster->GetChannelObjectGuid()))
  863. {
  864. CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
  865. if (target)
  866. m_targets.SetDst(*target);
  867. }
  868. else
  869. TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
  870. break;
  871. case TARGET_DEST_CHANNEL_CASTER:
  872. m_targets.SetDst(*channeledSpell->GetCaster());
  873. break;
  874. default:
  875. ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
  876. break;
  877. }
  878. }
  879. void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
  880. {
  881. if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
  882. {
  883. ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
  884. return;
  885. }
  886. float range = 0.0f;
  887. switch (targetType.GetCheckType())
  888. {
  889. case TARGET_CHECK_ENEMY:
  890. range = m_spellInfo->GetMaxRange(false, m_caster, this);
  891. break;
  892. case TARGET_CHECK_ALLY:
  893. case TARGET_CHECK_PARTY:
  894. case TARGET_CHECK_RAID:
  895. case TARGET_CHECK_RAID_CLASS:
  896. range = m_spellInfo->GetMaxRange(true, m_caster, this);
  897. break;
  898. case TARGET_CHECK_ENTRY:
  899. case TARGET_CHECK_DEFAULT:
  900. range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive(), m_caster, this);
  901. break;
  902. default:
  903. ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
  904. break;
  905. }
  906. ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
  907. // handle emergency case - try to use other provided targets if no conditions provided
  908. if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
  909. {
  910. TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID %u, effect %u - selecting default targets", m_spellInfo->Id, effIndex);
  911. switch (targetType.GetObjectType())
  912. {
  913. case TARGET_OBJECT_TYPE_GOBJ:
  914. if (m_spellInfo->RequiresSpellFocus)
  915. {
  916. if (focusObject)
  917. AddGOTarget(focusObject, effMask);
  918. return;
  919. }
  920. break;
  921. case TARGET_OBJECT_TYPE_DEST:
  922. if (m_spellInfo->RequiresSpellFocus)
  923. {
  924. if (focusObject)
  925. m_targets.SetDst(*focusObject);
  926. return;
  927. }
  928. break;
  929. default:
  930. break;
  931. }
  932. }
  933. WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
  934. if (!target)
  935. {
  936. TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
  937. return;
  938. }
  939. CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
  940. if (!target)
  941. {
  942. TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set NULL target, effect %u", m_spellInfo->Id, effIndex);
  943. return;
  944. }
  945. switch (targetType.GetObjectType())
  946. {
  947. case TARGET_OBJECT_TYPE_UNIT:
  948. {
  949. if (Unit* unitTarget = target->ToUnit())
  950. AddUnitTarget(unitTarget, effMask, true, false);
  951. else
  952. {
  953. TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set object of wrong type, expected unit, got %s, effect %u", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
  954. return;
  955. }
  956. break;
  957. }
  958. case TARGET_OBJECT_TYPE_GOBJ:
  959. if (GameObject* gobjTarget = target->ToGameObject())
  960. AddGOTarget(gobjTarget, effMask);
  961. else
  962. {
  963. TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set object of wrong type, expected gameobject, got %s, effect %u", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
  964. return;
  965. }
  966. break;
  967. case TARGET_OBJECT_TYPE_DEST:
  968. m_targets.SetDst(*target);
  969. break;
  970. default:
  971. ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
  972. break;
  973. }
  974. SelectImplicitChainTargets(effIndex, targetType, target, effMask);
  975. }
  976. void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
  977. {
  978. if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
  979. {
  980. ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
  981. return;
  982. }
  983. std::list<WorldObject*> targets;
  984. SpellTargetObjectTypes objectType = targetType.GetObjectType();
  985. SpellTargetCheckTypes selectionType = targetType.GetCheckType();
  986. ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
  987. float coneAngle = float(M_PI) / 2;
  988. float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
  989. if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
  990. {
  991. Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
  992. Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
  993. SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
  994. CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
  995. if (!targets.empty())
  996. {
  997. // Other special target selection goes here
  998. if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
  999. Trinity::Containers::RandomResizeList(targets, maxTargets);
  1000. for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
  1001. {
  1002. if (Unit* unitTarget = (*itr)->ToUnit())
  1003. AddUnitTarget(unitTarget, effMask, false);
  1004. else if (GameObject* gObjTarget = (*itr)->ToGameObject())
  1005. AddGOTarget(gObjTarget, effMask);
  1006. }
  1007. }
  1008. }
  1009. }
  1010. void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
  1011. {
  1012. Unit* referer = NULL;
  1013. switch (targetType.GetReferenceType())
  1014. {
  1015. case TARGET_REFERENCE_TYPE_SRC:
  1016. case TARGET_REFERENCE_TYPE_DEST:
  1017. case TARGET_REFERENCE_TYPE_CASTER:
  1018. referer = m_caster;
  1019. break;
  1020. case TARGET_REFERENCE_TYPE_TARGET:
  1021. referer = m_targets.GetUnitTarget();
  1022. break;
  1023. case TARGET_REFERENCE_TYPE_LAST:
  1024. {
  1025. // find last added target for this effect
  1026. for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
  1027. {
  1028. if (ihit->effectMask & (1<<effIndex))
  1029. {
  1030. referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
  1031. break;
  1032. }
  1033. }
  1034. break;
  1035. }
  1036. default:
  1037. ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
  1038. return;
  1039. }
  1040. if (!referer)
  1041. return;
  1042. Position const* center = NULL;
  1043. switch (targetType.GetReferenceType())
  1044. {
  1045. case TARGET_REFERENCE_TYPE_SRC:
  1046. center = m_targets.GetSrcPos();
  1047. break;
  1048. case TARGET_REFERENCE_TYPE_DEST:
  1049. center = m_targets.GetDstPos();
  1050. break;
  1051. case TARGET_REFERENCE_TYPE_CASTER:
  1052. case TARGET_REFERENCE_TYPE_TARGET:
  1053. case TARGET_REFERENCE_TYPE_LAST:
  1054. center = referer;
  1055. break;
  1056. default:
  1057. ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
  1058. return;
  1059. }
  1060. std::list<WorldObject*> targets;
  1061. float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
  1062. SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
  1063. CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
  1064. if (!targets.empty())
  1065. {
  1066. // Other special target selection goes here
  1067. if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
  1068. Trinity::Containers::RandomResizeList(targets, maxTargets);
  1069. for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
  1070. {
  1071. if (Unit* unitTarget = (*itr)->ToUnit())
  1072. AddUnitTarget(unitTarget, effMask, false, true, center);
  1073. else if (GameObject* gObjTarget = (*itr)->ToGameObject())
  1074. AddGOTarget(gObjTarget, effMask);
  1075. }
  1076. }
  1077. }
  1078. void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  1079. {
  1080. SpellDestination dest(*m_caster);
  1081. switch (targetType.GetTarget())
  1082. {
  1083. case TARGET_DEST_CASTER:
  1084. break;
  1085. case TARGET_DEST_HOME:
  1086. if (Player* playerCaster = m_caster->ToPlayer())
  1087. dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
  1088. break;
  1089. case TARGET_DEST_DB:
  1090. if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
  1091. {
  1092. /// @todo fix this check
  1093. if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
  1094. dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
  1095. else if (st->target_mapId == m_caster->GetMapId())
  1096. dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
  1097. }
  1098. else
  1099. {
  1100. TC_LOG_DEBUG("spells", "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id);
  1101. if (WorldObject* target = m_targets.GetObjectTarget())
  1102. dest = SpellDestination(*target);
  1103. }
  1104. break;
  1105. case TARGET_DEST_CASTER_FISHING:
  1106. {
  1107. float minDist = m_spellInfo->GetMinRange(true);
  1108. float maxDist = m_spellInfo->GetMaxRange(true);
  1109. float dist = frand(minDist, maxDist);
  1110. float x, y, z;
  1111. float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
  1112. m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
  1113. float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z, true, 50.0f);
  1114. float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
  1115. LiquidData liquidData;
  1116. if (m_caster->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData))
  1117. liquidLevel = liquidData.level;
  1118. if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
  1119. {
  1120. SendCastResult(SPELL_FAILED_NOT_HERE);
  1121. SendChannelUpdate(0);
  1122. finish(false);
  1123. return;
  1124. }
  1125. if (ground + 0.75 > liquidLevel)
  1126. {
  1127. SendCastResult(SPELL_FAILED_TOO_SHALLOW);
  1128. SendChannelUpdate(0);
  1129. finish(false);
  1130. return;
  1131. }
  1132. dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
  1133. break;
  1134. }
  1135. default:
  1136. {
  1137. float dist;
  1138. float angle = targetType.CalcDirectionAngle();
  1139. float objSize = m_caster->GetObjectSize();
  1140. if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
  1141. dist = PET_FOLLOW_DIST;
  1142. else
  1143. dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
  1144. if (dist < objSize)
  1145. dist = objSize;
  1146. else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
  1147. dist = objSize + (dist - objSize) * float(rand_norm());
  1148. Position pos = dest._position;
  1149. m_caster->MovePositionToFirstCollision(pos, dist, angle);
  1150. dest.Relocate(pos);
  1151. break;
  1152. }
  1153. }
  1154. CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
  1155. m_targets.SetDst(dest);
  1156. }
  1157. void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  1158. {
  1159. ASSERT(m_targets.GetObjectTarget() && "Spell::SelectImplicitTargetDestTargets - no explicit object target available!");
  1160. WorldObject* target = m_targets.GetObjectTarget();
  1161. SpellDestination dest(*target);
  1162. switch (targetType.GetTarget())
  1163. {
  1164. case TARGET_DEST_TARGET_ENEMY:
  1165. case TARGET_DEST_TARGET_ANY:
  1166. break;
  1167. default:
  1168. {
  1169. float angle = targetType.CalcDirectionAngle();
  1170. float objSize = target->GetObjectSize();
  1171. float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
  1172. if (dist < objSize)
  1173. dist = objSize;
  1174. else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
  1175. dist = objSize + (dist - objSize) * float(rand_norm());
  1176. Position pos = dest._position;
  1177. target->MovePositionToFirstCollision(pos, dist, angle);
  1178. dest.Relocate(pos);
  1179. break;
  1180. }
  1181. }
  1182. CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
  1183. m_targets.SetDst(dest);
  1184. }
  1185. void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  1186. {
  1187. // set destination to caster if no dest provided
  1188. // can only happen if previous destination target could not be set for some reason
  1189. // (not found nearby target, or channel target for example
  1190. // maybe we should abort the spell in such case?
  1191. CheckDst();
  1192. SpellDestination dest(*m_targets.GetDst());
  1193. switch (targetType.GetTarget())
  1194. {
  1195. case TARGET_DEST_DYNOBJ_ENEMY:
  1196. case TARGET_DEST_DYNOBJ_ALLY:
  1197. case TARGET_DEST_DYNOBJ_NONE:
  1198. case TARGET_DEST_DEST:
  1199. return;
  1200. case TARGET_DEST_TRAJ:
  1201. SelectImplicitTrajTargets(effIndex);
  1202. return;
  1203. default:
  1204. {
  1205. float angle = targetType.CalcDirectionAngle();
  1206. float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
  1207. if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
  1208. dist *= float(rand_norm());
  1209. Position pos = dest._position;
  1210. m_caster->MovePositionToFirstCollision(pos, dist, angle);
  1211. dest.Relocate(pos);
  1212. break;
  1213. }
  1214. }
  1215. CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
  1216. m_targets.ModDst(dest);
  1217. }
  1218. void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  1219. {
  1220. WorldObject* target = NULL;
  1221. bool checkIfValid = true;
  1222. switch (targetType.GetTarget())
  1223. {
  1224. case TARGET_UNIT_CASTER:
  1225. target = m_caster;
  1226. checkIfValid = false;
  1227. break;
  1228. case TARGET_UNIT_MASTER:
  1229. target = m_caster->GetCharmerOrOwner();
  1230. break;
  1231. case TARGET_UNIT_PET:
  1232. target = m_caster->GetGuardianPet();
  1233. break;
  1234. case TARGET_UNIT_SUMMONER:
  1235. if (m_caster->IsSummon())
  1236. target = m_caster->ToTempSummon()->GetSummoner();
  1237. break;
  1238. case TARGET_UNIT_VEHICLE:
  1239. target = m_caster->GetVehicleBase();
  1240. break;
  1241. case TARGET_UNIT_PASSENGER_0:
  1242. case TARGET_UNIT_PASSENGER_1:
  1243. case TARGET_UNIT_PASSENGER_2:
  1244. case TARGET_UNIT_PASSENGER_3:
  1245. case TARGET_UNIT_PASSENGER_4:
  1246. case TARGET_UNIT_PASSENGER_5:
  1247. case TARGET_UNIT_PASSENGER_6:
  1248. case TARGET_UNIT_PASSENGER_7:
  1249. if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle())
  1250. target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
  1251. break;
  1252. default:
  1253. break;
  1254. }
  1255. CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
  1256. if (target && target->ToUnit())
  1257. AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
  1258. }
  1259. void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  1260. {
  1261. ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
  1262. WorldObject* target = m_targets.GetObjectTarget();
  1263. CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
  1264. if (target)
  1265. {
  1266. if (Unit* unit = target->ToUnit())
  1267. AddUnitTarget(unit, 1 << effIndex, true, false);
  1268. else if (GameObject* gobj = target->ToGameObject())
  1269. AddGOTarget(gobj, 1 << effIndex);
  1270. SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
  1271. }
  1272. // Script hook can remove object target and we would wrongly land here
  1273. else if (Item* item = m_targets.GetItemTarget())
  1274. AddItemTarget(item, 1 << effIndex);
  1275. }
  1276. void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
  1277. {
  1278. uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
  1279. if (Player* modOwner = m_caster->GetSpellModOwner())
  1280. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
  1281. if (maxTargets > 1)
  1282. {
  1283. // mark damage multipliers as used
  1284. for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
  1285. if (effMask & (1 << k))
  1286. m_damageMultipliers[k] = 1.0f;
  1287. m_applyMultiplierMask |= effMask;
  1288. std::list<WorldObject*> targets;
  1289. SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()
  1290. , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
  1291. // Chain primary target is added earlier
  1292. CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
  1293. for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
  1294. if (Unit* unitTarget = (*itr)->ToUnit())
  1295. AddUnitTarget(unitTarget, effMask, false);
  1296. }
  1297. }
  1298. float tangent(float x)
  1299. {
  1300. x = std::tan(x);
  1301. //if (x < std::numeric_limits<float>::max() && x > -std::numeric_limits<float>::max()) return x;
  1302. //if (x >= std::numeric_limits<float>::max()) return std::numeric_limits<float>::max();
  1303. //if (x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max();
  1304. if (x < 100000.0f && x > -100000.0f) return x;
  1305. if (x >= 100000.0f) return 100000.0f;
  1306. if (x <= 100000.0f) return -100000.0f;
  1307. return 0.0f;
  1308. }
  1309. #define DEBUG_TRAJ(a) //a
  1310. void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
  1311. {
  1312. if (!m_targets.HasTraj())
  1313. return;
  1314. float dist2d = m_targets.GetDist2d();
  1315. if (!dist2d)
  1316. return;
  1317. float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
  1318. std::list<WorldObject*> targets;
  1319. Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo);
  1320. Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
  1321. SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
  1322. if (targets.empty())
  1323. return;
  1324. targets.sort(Trinity::ObjectDistanceOrderPred(m_caster));
  1325. float b = tangent(m_targets.GetElevation());
  1326. float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
  1327. if (a > -0.0001f)
  1328. a = 0;
  1329. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Spell::SelectTrajTargets: a %f b %f", a, b);)
  1330. float bestDist = m_spellInfo->GetMaxRange(false);
  1331. std::list<WorldObject*>::const_iterator itr = targets.begin();
  1332. for (; itr != targets.end(); ++itr)
  1333. {
  1334. if (!m_caster->HasInLine(*itr, 5.0f))
  1335. continue;
  1336. if (m_spellInfo->CheckTarget(m_caster, *itr, true) != SPELL_CAST_OK)
  1337. continue;
  1338. if (Unit* unitTarget = (*itr)->ToUnit())
  1339. {
  1340. if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || unitTarget->GetVehicle())
  1341. continue;
  1342. if (Creature* creatureTarget = unitTarget->ToCreature())
  1343. {
  1344. if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PROJECTILE_COLLISION))
  1345. continue;
  1346. }
  1347. }
  1348. const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
  1349. /// @todo all calculation should be based on src instead of m_caster
  1350. const float objDist2d = m_targets.GetSrcPos()->GetExactDist2d(*itr) * std::cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr));
  1351. const float dz = (*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ;
  1352. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);)
  1353. float dist = objDist2d - size;
  1354. float height = dist * (a * dist + b);
  1355. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)
  1356. if (dist < bestDist && height < dz + size && height > dz - size)
  1357. {
  1358. bestDist = dist > 0 ? dist : 0;
  1359. break;
  1360. }
  1361. #define CHECK_DIST {\
  1362. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)\
  1363. if (dist > bestDist)\
  1364. continue;\
  1365. if (dist < objDist2d + size && dist > objDist2d - size)\
  1366. {\
  1367. bestDist = dist;\
  1368. break;\
  1369. }\
  1370. }
  1371. if (!a)
  1372. {
  1373. height = dz - size;
  1374. dist = height / b;
  1375. CHECK_DIST;
  1376. height = dz + size;
  1377. dist = height / b;
  1378. CHECK_DIST;
  1379. continue;
  1380. }
  1381. height = dz - size;
  1382. float sqrt1 = b * b + 4 * a * height;
  1383. if (sqrt1 > 0)
  1384. {
  1385. sqrt1 = std::sqrt(sqrt1);
  1386. dist = (sqrt1 - b) / (2 * a);
  1387. CHECK_DIST;
  1388. }
  1389. height = dz + size;
  1390. float sqrt2 = b * b + 4 * a * height;
  1391. if (sqrt2 > 0)
  1392. {
  1393. sqrt2 = std::sqrt(sqrt2);
  1394. dist = (sqrt2 - b) / (2 * a);
  1395. CHECK_DIST;
  1396. dist = (-sqrt2 - b) / (2 * a);
  1397. CHECK_DIST;
  1398. }
  1399. if (sqrt1 > 0)
  1400. {
  1401. dist = (-sqrt1 - b) / (2 * a);
  1402. CHECK_DIST;
  1403. }
  1404. }
  1405. if (m_targets.GetSrcPos()->GetExactDist2d(m_targets.GetDstPos()) > bestDist)
  1406. {
  1407. float x = m_targets.GetSrcPos()->m_positionX + std::cos(m_caster->GetOrientation()) * bestDist;
  1408. float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
  1409. float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
  1410. if (itr != targets.end())
  1411. {
  1412. float distSq = (*itr)->GetExactDistSq(x, y, z);
  1413. float sizeSq = (*itr)->GetObjectSize();
  1414. sizeSq *= sizeSq;
  1415. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
  1416. if (distSq > sizeSq)
  1417. {
  1418. float factor = 1 - std::sqrt(sizeSq / distSq);
  1419. x += factor * ((*itr)->GetPositionX() - x);
  1420. y += factor * ((*itr)->GetPositionY() - y);
  1421. z += factor * ((*itr)->GetPositionZ() - z);
  1422. distSq = (*itr)->GetExactDistSq(x, y, z);
  1423. DEBUG_TRAJ(TC_LOG_ERROR("spells", "Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
  1424. }
  1425. }
  1426. Position trajDst;
  1427. trajDst.Relocate(x, y, z, m_caster->GetOrientation());
  1428. SpellDestination dest(*m_targets.GetDst());
  1429. dest.Relocate(trajDst);
  1430. CallScriptDestinationTargetSelectHandlers(dest, effIndex, SpellImplicitTargetInfo(TARGET_DEST_TRAJ));
  1431. m_targets.ModDst(dest);
  1432. }
  1433. if (Vehicle* veh = m_caster->GetVehicleKit())
  1434. veh->SetLastShootPos(*m_targets.GetDstPos());
  1435. }
  1436. void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
  1437. {
  1438. // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
  1439. /// @todo this is a workaround - target shouldn't be stored in target map for those spells
  1440. switch (m_spellInfo->Effects[effIndex].Effect)
  1441. {
  1442. case SPELL_EFFECT_SUMMON_RAF_FRIEND:
  1443. case SPELL_EFFECT_SUMMON_PLAYER:
  1444. if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget())
  1445. {
  1446. WorldObject* target = ObjectAccessor::FindPlayer(m_caster->GetTarget());
  1447. CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex), SpellImplicitTargetInfo());
  1448. if (target && target->ToPlayer())
  1449. AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
  1450. }
  1451. return;
  1452. default:
  1453. break;
  1454. }
  1455. // select spell implicit targets based on effect type
  1456. if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
  1457. return;
  1458. uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
  1459. if (!targetMask)
  1460. return;
  1461. WorldObject* target = NULL;
  1462. switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
  1463. {
  1464. // add explicit object target or self to the target map
  1465. case EFFECT_IMPLICIT_TARGET_EXPLICIT:
  1466. // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
  1467. if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK))
  1468. {
  1469. if (Unit* unitTarget = m_targets.GetUnitTarget())
  1470. target = unitTarget;
  1471. else if (targetMask & TARGET_FLAG_CORPSE_MASK)
  1472. {
  1473. if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
  1474. {
  1475. /// @todo this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
  1476. if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
  1477. target = owner;
  1478. }
  1479. }
  1480. else //if (targetMask & TARGET_FLAG_UNIT_MASK)
  1481. target = m_caster;
  1482. }
  1483. if (targetMask & TARGET_FLAG_ITEM_MASK)
  1484. {
  1485. if (Item* itemTarget = m_targets.GetItemTarget())
  1486. AddItemTarget(itemTarget, 1 << effIndex);
  1487. return;
  1488. }
  1489. if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
  1490. target = m_targets.GetGOTarget();
  1491. break;
  1492. // add self to the target map
  1493. case EFFECT_IMPLICIT_TARGET_CASTER:
  1494. if (targetMask & TARGET_FLAG_UNIT_MASK)
  1495. target = m_caster;
  1496. break;
  1497. default:
  1498. break;
  1499. }
  1500. CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex), SpellImplicitTargetInfo());
  1501. if (target)
  1502. {
  1503. if (target->ToUnit())
  1504. AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
  1505. else if (target->ToGameObject())
  1506. AddGOTarget(target->ToGameObject(), 1 << effIndex);
  1507. }
  1508. }
  1509. uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList)
  1510. {
  1511. // this function selects which containers need to be searched for spell target
  1512. uint32 retMask = GRID_MAP_TYPE_MASK_ALL;
  1513. // filter searchers based on searched object type
  1514. switch (objType)
  1515. {
  1516. case TARGET_OBJECT_TYPE_UNIT:
  1517. case TARGET_OBJECT_TYPE_UNIT_AND_DEST:
  1518. case TARGET_OBJECT_TYPE_CORPSE:
  1519. case TARGET_OBJECT_TYPE_CORPSE_ENEMY:
  1520. case TARGET_OBJECT_TYPE_CORPSE_ALLY:
  1521. retMask &= GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_CREATURE;
  1522. break;
  1523. case TARGET_OBJECT_TYPE_GOBJ:
  1524. case TARGET_OBJECT_TYPE_GOBJ_ITEM:
  1525. retMask &= GRID_MAP_TYPE_MASK_GAMEOBJECT;
  1526. break;
  1527. default:
  1528. break;
  1529. }
  1530. if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD))
  1531. retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
  1532. if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS)
  1533. retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER;
  1534. if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS)
  1535. retMask &= GRID_MAP_TYPE_MASK_PLAYER;
  1536. if (condList)
  1537. retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
  1538. return retMask;
  1539. }
  1540. template<class SEARCHER>
  1541. void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius)
  1542. {
  1543. if (!containerMask)
  1544. return;
  1545. // search world and grid for possible targets
  1546. bool searchInGrid = (containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT)) != 0;
  1547. bool searchInWorld = (containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE)) != 0;
  1548. if (searchInGrid || searchInWorld)
  1549. {
  1550. float x, y;
  1551. x = pos->GetPositionX();
  1552. y = pos->GetPositionY();
  1553. CellCoord p(Trinity::ComputeCellCoord(x, y));
  1554. Cell cell(p);
  1555. cell.SetNoCreate();
  1556. Map& map = *(referer->GetMap());
  1557. if (searchInWorld)
  1558. {
  1559. TypeContainerVisitor<SEARCHER, WorldTypeMapContainer> world_object_notifier(searcher);
  1560. cell.Visit(p, world_object_notifier, map, radius, x, y);
  1561. }
  1562. if (searchInGrid)
  1563. {
  1564. TypeContainerVisitor<SEARCHER, GridTypeMapContainer > grid_object_notifier(searcher);
  1565. cell.Visit(p, grid_object_notifier, map, radius, x, y);
  1566. }
  1567. }
  1568. }
  1569. WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
  1570. {
  1571. WorldObject* target = NULL;
  1572. uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
  1573. if (!containerTypeMask)
  1574. return NULL;
  1575. Trinity::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
  1576. Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> searcher(m_caster, target, check, containerTypeMask);
  1577. SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
  1578. return target;
  1579. }
  1580. void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
  1581. {
  1582. uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
  1583. if (!containerTypeMask)
  1584. return;
  1585. Trinity::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
  1586. Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
  1587. SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
  1588. }
  1589. void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionList* condList, bool isChainHeal)
  1590. {
  1591. // max dist for jump target selection
  1592. float jumpRadius = 0.0f;
  1593. switch (m_spellInfo->DmgClass)
  1594. {
  1595. case SPELL_DAMAGE_CLASS_RANGED:
  1596. // 7.5y for multi shot
  1597. jumpRadius = 7.5f;
  1598. break;
  1599. case SPELL_DAMAGE_CLASS_MELEE:
  1600. // 5y for swipe, cleave and similar
  1601. jumpRadius = 5.0f;
  1602. break;
  1603. case SPELL_DAMAGE_CLASS_NONE:
  1604. case SPELL_DAMAGE_CLASS_MAGIC:
  1605. // 12.5y for chain heal spell since 3.2 patch
  1606. if (isChainHeal)
  1607. jumpRadius = 12.5f;
  1608. // 10y as default for magic chain spells
  1609. else
  1610. jumpRadius = 10.0f;
  1611. break;
  1612. }
  1613. // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
  1614. bool isBouncingFar = (m_spellInfo->AttributesEx4 & SPELL_ATTR4_AREA_TARGET_CHAIN
  1615. || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE
  1616. || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC);
  1617. // max dist which spell can reach
  1618. float searchRadius = jumpRadius;
  1619. if (isBouncingFar)
  1620. searchRadius *= chainTargets;
  1621. std::list<WorldObject*> tempTargets;
  1622. SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
  1623. tempTargets.remove(target);
  1624. // remove targets which are always invalid for chain spells
  1625. // for some spells allow only chain targets in front of caster (swipe for example)
  1626. if (!isBouncingFar)
  1627. {
  1628. for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
  1629. {
  1630. std::list<WorldObject*>::iterator checkItr = itr++;
  1631. if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
  1632. tempTargets.erase(checkItr);
  1633. }
  1634. }
  1635. while (chainTargets)
  1636. {
  1637. // try to get unit for next chain jump
  1638. std::list<WorldObject*>::iterator foundItr = tempTargets.end();
  1639. // get unit with highest hp deficit in dist
  1640. if (isChainHeal)
  1641. {
  1642. uint32 maxHPDeficit = 0;
  1643. for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
  1644. {
  1645. if (Unit* unitTarget = (*itr)->ToUnit())
  1646. {
  1647. uint32 deficit = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
  1648. if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unitTarget, jumpRadius) && target->IsWithinLOSInMap(unitTarget))
  1649. {
  1650. foundItr = itr;
  1651. maxHPDeficit = deficit;
  1652. }
  1653. }
  1654. }
  1655. }
  1656. // get closest object
  1657. else
  1658. {
  1659. for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
  1660. {
  1661. if (foundItr == tempTargets.end())
  1662. {
  1663. if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr))
  1664. foundItr = itr;
  1665. }
  1666. else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr))
  1667. foundItr = itr;
  1668. }
  1669. }
  1670. // not found any valid target - chain ends
  1671. if (foundItr == tempTargets.end())
  1672. break;
  1673. target = *foundItr;
  1674. tempTargets.erase(foundItr);
  1675. targets.push_back(target);
  1676. --chainTargets;
  1677. }
  1678. }
  1679. GameObject* Spell::SearchSpellFocus()
  1680. {
  1681. GameObject* focus = NULL;
  1682. Trinity::GameObjectFocusCheck check(m_caster, m_spellInfo->RequiresSpellFocus);
  1683. Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> searcher(m_caster, focus, check);
  1684. SearchTargets<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> > (searcher, GRID_MAP_TYPE_MASK_GAMEOBJECT, m_caster, m_caster, m_caster->GetVisibilityRange());
  1685. return focus;
  1686. }
  1687. void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
  1688. {
  1689. //==========================================================================================
  1690. // Now fill data for trigger system, need know:
  1691. // can spell trigger another or not (m_canTrigger)
  1692. // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
  1693. //==========================================================================================
  1694. m_procVictim = m_procAttacker = 0;
  1695. // Get data for type of attack and fill base info for trigger
  1696. switch (m_spellInfo->DmgClass)
  1697. {
  1698. case SPELL_DAMAGE_CLASS_MELEE:
  1699. m_procAttacker = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS;
  1700. if (m_attackType == OFF_ATTACK)
  1701. m_procAttacker |= PROC_FLAG_DONE_OFFHAND_ATTACK;
  1702. else
  1703. m_procAttacker |= PROC_FLAG_DONE_MAINHAND_ATTACK;
  1704. m_procVictim = PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS;
  1705. break;
  1706. case SPELL_DAMAGE_CLASS_RANGED:
  1707. // Auto attack
  1708. if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG)
  1709. {
  1710. m_procAttacker = PROC_FLAG_DONE_RANGED_AUTO_ATTACK;
  1711. m_procVictim = PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK;
  1712. }
  1713. else // Ranged spell attack
  1714. {
  1715. m_procAttacker = PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS;
  1716. m_procVictim = PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS;
  1717. }
  1718. break;
  1719. default:
  1720. if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON &&
  1721. m_spellInfo->EquippedItemSubClassMask & (1<<ITEM_SUBCLASS_WEAPON_WAND)
  1722. && m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) // Wands auto attack
  1723. {
  1724. m_procAttacker = PROC_FLAG_DONE_RANGED_AUTO_ATTACK;
  1725. m_procVictim = PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK;
  1726. }
  1727. // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
  1728. // Because spell positivity is dependant on target
  1729. }
  1730. m_procEx = PROC_EX_NONE;
  1731. // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
  1732. if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
  1733. (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
  1734. m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
  1735. m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
  1736. {
  1737. m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION;
  1738. }
  1739. /* Effects which are result of aura proc from triggered spell cannot proc
  1740. to prevent chain proc of these spells */
  1741. // Hellfire Effect - trigger as DOT
  1742. if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[0] & 0x00000040)
  1743. {
  1744. m_procAttacker = PROC_FLAG_DONE_PERIODIC;
  1745. m_procVictim = PROC_FLAG_TAKEN_PERIODIC;
  1746. }
  1747. // Ranged autorepeat attack is set as triggered spell - ignore it
  1748. if (!(m_procAttacker & PROC_FLAG_DONE_RANGED_AUTO_ATTACK))
  1749. {
  1750. if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS &&
  1751. (m_spellInfo->AttributesEx2 & SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC ||
  1752. m_spellInfo->AttributesEx3 & SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2))
  1753. m_procEx |= PROC_EX_INTERNAL_CANT_PROC;
  1754. else if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS)
  1755. m_procEx |= PROC_EX_INTERNAL_TRIGGERED;
  1756. }
  1757. // Totem casts require spellfamilymask defined in spell_proc_event to proc
  1758. if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsTotem() && m_caster->IsControlledByPlayer())
  1759. m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY;
  1760. }
  1761. void Spell::CleanupTargetList()
  1762. {
  1763. m_UniqueTargetInfo.clear();
  1764. m_UniqueGOTargetInfo.clear();
  1765. m_UniqueItemInfo.clear();
  1766. m_delayMoment = 0;
  1767. }
  1768. void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/)
  1769. {
  1770. for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
  1771. if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex, losPosition))
  1772. effectMask &= ~(1 << effIndex);
  1773. // no effects left
  1774. if (!effectMask)
  1775. return;
  1776. if (checkIfValid)
  1777. if (m_spellInfo->CheckTarget(m_caster, target, implicit) != SPELL_CAST_OK)
  1778. return;
  1779. // Check for effect immune skip if immuned
  1780. for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
  1781. if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
  1782. effectMask &= ~(1 << effIndex);
  1783. ObjectGuid targetGUID = target->GetGUID();
  1784. // Lookup target in already in list
  1785. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  1786. {
  1787. if (targetGUID == ihit->targetGUID) // Found in list
  1788. {
  1789. ihit->effectMask |= effectMask; // Immune effects removed from mask
  1790. ihit->scaleAura = false;
  1791. if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
  1792. {
  1793. SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
  1794. if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
  1795. ihit->scaleAura = true;
  1796. }
  1797. return;
  1798. }
  1799. }
  1800. // This is new target calculate data for him
  1801. // Get spell hit result on target
  1802. TargetInfo targetInfo;
  1803. targetInfo.targetGUID = targetGUID; // Store target GUID
  1804. targetInfo.effectMask = effectMask; // Store all effects not immune
  1805. targetInfo.processed = false; // Effects not apply on target
  1806. targetInfo.alive = target->IsAlive();
  1807. targetInfo.damage = 0;
  1808. targetInfo.crit = false;
  1809. targetInfo.scaleAura = false;
  1810. if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
  1811. {
  1812. SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
  1813. if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
  1814. targetInfo.scaleAura = true;
  1815. }
  1816. // Calculate hit result
  1817. if (m_originalCaster)
  1818. {
  1819. targetInfo.missCondition = m_originalCaster->SpellHitResult(target, m_spellInfo, m_canReflect);
  1820. if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
  1821. targetInfo.missCondition = SPELL_MISS_NONE;
  1822. }
  1823. else
  1824. targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
  1825. // Spell have speed - need calculate incoming time
  1826. // Incoming time is zero for self casts. At least I think so.
  1827. if (m_spellInfo->Speed > 0.0f && m_caster != target)
  1828. {
  1829. // calculate spell incoming interval
  1830. /// @todo this is a hack
  1831. float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
  1832. if (dist < 5.0f)
  1833. dist = 5.0f;
  1834. if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
  1835. targetInfo.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
  1836. else
  1837. targetInfo.timeDelay = uint64(m_spellInfo->Speed * 1000.0f);
  1838. // Calculate minimum incoming time
  1839. if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
  1840. m_delayMoment = targetInfo.timeDelay;
  1841. }
  1842. else
  1843. targetInfo.timeDelay = 0LL;
  1844. // If target reflect spell back to caster
  1845. if (targetInfo.missCondition == SPELL_MISS_REFLECT)
  1846. {
  1847. // Calculate reflected spell result on caster
  1848. targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect);
  1849. if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
  1850. targetInfo.reflectResult = SPELL_MISS_PARRY;
  1851. // Increase time interval for reflected spells by 1.5
  1852. targetInfo.timeDelay += targetInfo.timeDelay >> 1;
  1853. }
  1854. else
  1855. targetInfo.reflectResult = SPELL_MISS_NONE;
  1856. // Add target to list
  1857. m_UniqueTargetInfo.push_back(targetInfo);
  1858. }
  1859. void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
  1860. {
  1861. for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
  1862. {
  1863. if (!m_spellInfo->Effects[effIndex].IsEffect())
  1864. effectMask &= ~(1 << effIndex);
  1865. else
  1866. {
  1867. switch (m_spellInfo->Effects[effIndex].Effect)
  1868. {
  1869. case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
  1870. case SPELL_EFFECT_GAMEOBJECT_REPAIR:
  1871. case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE:
  1872. if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  1873. effectMask &= ~(1 << effIndex);
  1874. break;
  1875. default:
  1876. break;
  1877. }
  1878. }
  1879. }
  1880. if (!effectMask)
  1881. return;
  1882. ObjectGuid targetGUID = go->GetGUID();
  1883. // Lookup target in already in list
  1884. for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
  1885. {
  1886. if (targetGUID == ihit->targetGUID) // Found in list
  1887. {
  1888. ihit->effectMask |= effectMask; // Add only effect mask
  1889. return;
  1890. }
  1891. }
  1892. // This is new target calculate data for him
  1893. GOTargetInfo target;
  1894. target.targetGUID = targetGUID;
  1895. target.effectMask = effectMask;
  1896. target.processed = false; // Effects not apply on target
  1897. // Spell have speed - need calculate incoming time
  1898. if (m_spellInfo->Speed > 0.0f)
  1899. {
  1900. // calculate spell incoming interval
  1901. float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
  1902. if (dist < 5.0f)
  1903. dist = 5.0f;
  1904. if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
  1905. target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
  1906. else
  1907. target.timeDelay = uint64(m_spellInfo->Speed * 1000.0f);
  1908. if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
  1909. m_delayMoment = target.timeDelay;
  1910. }
  1911. else
  1912. target.timeDelay = 0LL;
  1913. // Add target to list
  1914. m_UniqueGOTargetInfo.push_back(target);
  1915. }
  1916. void Spell::AddItemTarget(Item* item, uint32 effectMask)
  1917. {
  1918. for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
  1919. if (!m_spellInfo->Effects[effIndex].IsEffect())
  1920. effectMask &= ~(1 << effIndex);
  1921. // no effects left
  1922. if (!effectMask)
  1923. return;
  1924. // Lookup target in already in list
  1925. for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
  1926. {
  1927. if (item == ihit->item) // Found in list
  1928. {
  1929. ihit->effectMask |= effectMask; // Add only effect mask
  1930. return;
  1931. }
  1932. }
  1933. // This is new target add data
  1934. ItemTargetInfo target;
  1935. target.item = item;
  1936. target.effectMask = effectMask;
  1937. m_UniqueItemInfo.push_back(target);
  1938. }
  1939. void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex)
  1940. {
  1941. m_destTargets[effIndex] = dest;
  1942. }
  1943. void Spell::DoAllEffectOnTarget(TargetInfo* target)
  1944. {
  1945. if (!target || target->processed)
  1946. return;
  1947. target->processed = true; // Target checked in apply effects procedure
  1948. // Get mask of effects for target
  1949. uint8 mask = target->effectMask;
  1950. Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
  1951. if (!unit)
  1952. {
  1953. uint8 farMask = 0;
  1954. // create far target mask
  1955. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  1956. if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
  1957. if ((1 << i) & mask)
  1958. farMask |= (1 << i);
  1959. if (!farMask)
  1960. return;
  1961. // find unit in world
  1962. unit = ObjectAccessor::FindUnit(target->targetGUID);
  1963. if (!unit)
  1964. return;
  1965. // do far effects on the unit
  1966. // can't use default call because of threading, do stuff as fast as possible
  1967. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  1968. if (farMask & (1 << i))
  1969. HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
  1970. return;
  1971. }
  1972. if (unit->IsAlive() != target->alive)
  1973. return;
  1974. if (getState() == SPELL_STATE_DELAYED && !m_spellInfo->IsPositive() && (getMSTime() - target->timeDelay) <= unit->m_lastSanctuaryTime)
  1975. return; // No missinfo in that case
  1976. // Get original caster (if exist) and calculate damage/healing from him data
  1977. Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
  1978. // Skip if m_originalCaster not avaiable
  1979. if (!caster)
  1980. return;
  1981. SpellMissInfo missInfo = target->missCondition;
  1982. // Need init unitTarget by default unit (can changed in code on reflect)
  1983. // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
  1984. unitTarget = unit;
  1985. // Reset damage/healing counter
  1986. m_damage = target->damage;
  1987. m_healing = -target->damage;
  1988. // Fill base trigger info
  1989. uint32 procAttacker = m_procAttacker;
  1990. uint32 procVictim = m_procVictim;
  1991. uint32 procEx = m_procEx;
  1992. m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
  1993. //Spells with this flag cannot trigger if effect is cast on self
  1994. bool canEffectTrigger = !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2);
  1995. Unit* spellHitTarget = NULL;
  1996. if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
  1997. spellHitTarget = unit;
  1998. else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
  1999. {
  2000. if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
  2001. {
  2002. spellHitTarget = m_caster;
  2003. if (m_caster->GetTypeId() == TYPEID_UNIT)
  2004. m_caster->ToCreature()->LowerPlayerDamageReq(target->damage);
  2005. }
  2006. }
  2007. if (spellHitTarget)
  2008. {
  2009. SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
  2010. if (missInfo2 != SPELL_MISS_NONE)
  2011. {
  2012. if (missInfo2 != SPELL_MISS_MISS)
  2013. m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo2);
  2014. m_damage = 0;
  2015. spellHitTarget = NULL;
  2016. }
  2017. }
  2018. // Do not take combo points on dodge and miss
  2019. if (missInfo != SPELL_MISS_NONE && m_needComboPoints &&
  2020. m_targets.GetUnitTargetGUID() == target->targetGUID)
  2021. {
  2022. m_needComboPoints = false;
  2023. // Restore spell mods for a miss/dodge/parry Cold Blood
  2024. /// @todo check how broad this rule should be
  2025. if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS ||
  2026. missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
  2027. m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
  2028. }
  2029. // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
  2030. if (canEffectTrigger && !procAttacker && !procVictim)
  2031. {
  2032. bool positive = true;
  2033. if (m_damage > 0)
  2034. positive = false;
  2035. else if (!m_healing)
  2036. positive = m_spellInfo->IsPositive();
  2037. switch (m_spellInfo->DmgClass)
  2038. {
  2039. case SPELL_DAMAGE_CLASS_MAGIC:
  2040. if (positive)
  2041. {
  2042. procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
  2043. procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS;
  2044. }
  2045. else
  2046. {
  2047. procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
  2048. procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG;
  2049. }
  2050. break;
  2051. case SPELL_DAMAGE_CLASS_NONE:
  2052. if (positive)
  2053. {
  2054. procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS;
  2055. procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS;
  2056. }
  2057. else
  2058. {
  2059. procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
  2060. procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG;
  2061. }
  2062. break;
  2063. }
  2064. }
  2065. CallScriptOnHitHandlers();
  2066. // All calculated do it!
  2067. // Do healing and triggers
  2068. if (m_healing > 0)
  2069. {
  2070. bool crit = caster->IsSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
  2071. uint32 addhealth = m_healing;
  2072. if (crit)
  2073. {
  2074. procEx |= PROC_EX_CRITICAL_HIT;
  2075. addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, NULL);
  2076. }
  2077. else
  2078. procEx |= PROC_EX_NORMAL_HIT;
  2079. int32 gain = caster->HealBySpell(unitTarget, m_spellInfo, addhealth, crit);
  2080. unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
  2081. m_healing = gain;
  2082. // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
  2083. if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
  2084. caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
  2085. }
  2086. // Do damage and triggers
  2087. else if (m_damage > 0)
  2088. {
  2089. // Fill base damage struct (unitTarget - is real spell target)
  2090. SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
  2091. // Add bonuses and fill damageInfo struct
  2092. caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
  2093. caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
  2094. // Send log damage message to client
  2095. caster->SendSpellNonMeleeDamageLog(&damageInfo);
  2096. procEx |= createProcExtendMask(&damageInfo, missInfo);
  2097. procVictim |= PROC_FLAG_TAKEN_DAMAGE;
  2098. // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
  2099. if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
  2100. {
  2101. caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
  2102. if (caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->Attributes & SPELL_ATTR0_STOP_ATTACK_TARGET) == 0 &&
  2103. (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
  2104. caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
  2105. }
  2106. m_damage = damageInfo.damage;
  2107. caster->DealSpellDamage(&damageInfo, true);
  2108. }
  2109. // Passive spell hits/misses or active spells only misses (only triggers)
  2110. else
  2111. {
  2112. // Fill base damage struct (unitTarget - is real spell target)
  2113. SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
  2114. procEx |= createProcExtendMask(&damageInfo, missInfo);
  2115. // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
  2116. if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
  2117. caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
  2118. // Failed Pickpocket, reveal rogue
  2119. if (missInfo == SPELL_MISS_RESIST && m_spellInfo->AttributesCu & SPELL_ATTR0_CU_PICKPOCKET && unitTarget->GetTypeId() == TYPEID_UNIT)
  2120. {
  2121. m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
  2122. if (unitTarget->ToCreature()->IsAIEnabled)
  2123. unitTarget->ToCreature()->AI()->AttackStart(m_caster);
  2124. }
  2125. }
  2126. if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)))
  2127. {
  2128. m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO));
  2129. if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_AURA_CC)
  2130. if (!unit->IsStandState())
  2131. unit->SetStandState(UNIT_STAND_STATE_STAND);
  2132. }
  2133. if (spellHitTarget)
  2134. {
  2135. //AI functions
  2136. if (spellHitTarget->GetTypeId() == TYPEID_UNIT)
  2137. if (spellHitTarget->ToCreature()->IsAIEnabled)
  2138. spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
  2139. if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsAIEnabled)
  2140. m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
  2141. // Needs to be called after dealing damage/healing to not remove breaking on damage auras
  2142. DoTriggersOnSpellHit(spellHitTarget, mask);
  2143. // if target is fallged for pvp also flag caster if a player
  2144. if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER)
  2145. m_caster->ToPlayer()->UpdatePvP(true);
  2146. CallScriptAfterHitHandlers();
  2147. }
  2148. }
  2149. SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleAura)
  2150. {
  2151. if (!unit || !effectMask)
  2152. return SPELL_MISS_EVADE;
  2153. // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
  2154. if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
  2155. return SPELL_MISS_IMMUNE;
  2156. // disable effects to which unit is immune
  2157. SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
  2158. for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
  2159. if (effectMask & (1 << effectNumber))
  2160. if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
  2161. effectMask &= ~(1 << effectNumber);
  2162. if (!effectMask)
  2163. return returnVal;
  2164. PrepareScriptHitHandlers();
  2165. CallScriptBeforeHitHandlers();
  2166. if (Player* player = unit->ToPlayer())
  2167. {
  2168. player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
  2169. player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, 0, m_caster);
  2170. player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
  2171. }
  2172. if (Player* player = m_caster->ToPlayer())
  2173. {
  2174. player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id);
  2175. player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, 0, unit);
  2176. }
  2177. if (m_caster != unit)
  2178. {
  2179. // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
  2180. if (m_spellInfo->Speed > 0.0f && unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) && unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
  2181. return SPELL_MISS_EVADE;
  2182. if (m_caster->_IsValidAttackTarget(unit, m_spellInfo))
  2183. {
  2184. unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
  2185. /// @todo This is a hack. But we do not know what types of stealth should be interrupted by CC
  2186. if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_AURA_CC) && unit->IsControlledByPlayer())
  2187. unit->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
  2188. }
  2189. else if (m_caster->IsFriendlyTo(unit))
  2190. {
  2191. // for delayed spells ignore negative spells (after duel end) for friendly targets
  2192. /// @todo this cause soul transfer bugged
  2193. // 63881 - Malady of the Mind jump spell (Yogg-Saron)
  2194. if (m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive() && m_spellInfo->Id != 63881)
  2195. return SPELL_MISS_EVADE;
  2196. // assisting case, healing and resurrection
  2197. if (unit->HasUnitState(UNIT_STATE_ATTACK_PLAYER))
  2198. {
  2199. m_caster->SetContestedPvP();
  2200. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2201. m_caster->ToPlayer()->UpdatePvP(true);
  2202. }
  2203. if (unit->IsInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO))
  2204. {
  2205. m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
  2206. unit->getHostileRefManager().threatAssist(m_caster, 0.0f);
  2207. }
  2208. }
  2209. }
  2210. uint8 aura_effmask = 0;
  2211. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2212. if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
  2213. aura_effmask |= 1 << i;
  2214. // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
  2215. m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell != nullptr);
  2216. if (m_diminishGroup && aura_effmask)
  2217. {
  2218. m_diminishLevel = unit->GetDiminishing(m_diminishGroup);
  2219. DiminishingReturnsType type = GetDiminishingReturnsGroupType(m_diminishGroup);
  2220. // Increase Diminishing on unit, current informations for actually casts will use values above
  2221. if ((type == DRTYPE_PLAYER &&
  2222. (unit->GetCharmerOrOwnerPlayerOrPlayerItself() || (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH))) ||
  2223. type == DRTYPE_ALL)
  2224. unit->IncrDiminishing(m_diminishGroup);
  2225. }
  2226. if (aura_effmask)
  2227. {
  2228. // Select rank for aura with level requirements only in specific cases
  2229. // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
  2230. SpellInfo const* aurSpellInfo = m_spellInfo;
  2231. int32 basePoints[3];
  2232. if (scaleAura)
  2233. {
  2234. aurSpellInfo = m_spellInfo->GetAuraRankForLevel(unitTarget->getLevel());
  2235. ASSERT(aurSpellInfo);
  2236. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2237. {
  2238. basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
  2239. if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
  2240. {
  2241. aurSpellInfo = m_spellInfo;
  2242. break;
  2243. }
  2244. }
  2245. }
  2246. if (m_originalCaster)
  2247. {
  2248. bool refresh = false;
  2249. m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit,
  2250. m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh);
  2251. if (m_spellAura)
  2252. {
  2253. // Set aura stack amount to desired value
  2254. if (m_spellValue->AuraStackAmount > 1)
  2255. {
  2256. if (!refresh)
  2257. m_spellAura->SetStackAmount(m_spellValue->AuraStackAmount);
  2258. else
  2259. m_spellAura->ModStackAmount(m_spellValue->AuraStackAmount);
  2260. }
  2261. // Now Reduce spell duration using data received at spell hit
  2262. int32 duration = m_spellAura->GetMaxDuration();
  2263. int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
  2264. float diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
  2265. // unit is immune to aura if it was diminished to 0 duration
  2266. if (diminishMod == 0.0f)
  2267. {
  2268. m_spellAura->Remove();
  2269. bool found = false;
  2270. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2271. if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
  2272. found = true;
  2273. if (!found)
  2274. return SPELL_MISS_IMMUNE;
  2275. }
  2276. else
  2277. {
  2278. ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
  2279. bool positive = m_spellAura->GetSpellInfo()->IsPositive();
  2280. if (AuraApplication* aurApp = m_spellAura->GetApplicationOfTarget(m_originalCaster->GetGUID()))
  2281. positive = aurApp->IsPositive();
  2282. duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
  2283. if (duration > 0)
  2284. {
  2285. // Haste modifies duration of channeled spells
  2286. if (m_spellInfo->IsChanneled())
  2287. m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this);
  2288. else if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
  2289. {
  2290. int32 origDuration = duration;
  2291. duration = 0;
  2292. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2293. if (AuraEffect const* eff = m_spellAura->GetEffect(i))
  2294. if (int32 amplitude = eff->GetAmplitude()) // amplitude is hastened by UNIT_MOD_CAST_SPEED
  2295. duration = std::max(std::max(origDuration / amplitude, 1) * amplitude, duration);
  2296. // if there is no periodic effect
  2297. if (!duration)
  2298. duration = int32(origDuration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
  2299. }
  2300. }
  2301. if (duration != m_spellAura->GetMaxDuration())
  2302. {
  2303. m_spellAura->SetMaxDuration(duration);
  2304. m_spellAura->SetDuration(duration);
  2305. }
  2306. m_spellAura->_RegisterForTargets();
  2307. }
  2308. }
  2309. }
  2310. }
  2311. for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
  2312. if (effectMask & (1 << effectNumber))
  2313. HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
  2314. return SPELL_MISS_NONE;
  2315. }
  2316. void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
  2317. {
  2318. // Apply additional spell effects to target
  2319. /// @todo move this code to scripts
  2320. if (m_preCastSpell)
  2321. {
  2322. // Paladin immunity shields
  2323. if (m_preCastSpell == 61988)
  2324. {
  2325. // Cast Forbearance
  2326. m_caster->CastSpell(unit, 25771, true);
  2327. // Cast Avenging Wrath Marker
  2328. unit->CastSpell(unit, 61987, true);
  2329. }
  2330. // Avenging Wrath
  2331. if (m_preCastSpell == 61987)
  2332. // Cast the serverside immunity shield marker
  2333. m_caster->CastSpell(unit, 61988, true);
  2334. if (sSpellMgr->GetSpellInfo(m_preCastSpell))
  2335. // Blizz seems to just apply aura without bothering to cast
  2336. m_caster->AddAura(m_preCastSpell, unit);
  2337. }
  2338. // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
  2339. // this is executed after spell proc spells on target hit
  2340. // spells are triggered for each hit spell target
  2341. // info confirmed with retail sniffs of permafrost and shadow weaving
  2342. if (!m_hitTriggerSpells.empty())
  2343. {
  2344. int _duration = 0;
  2345. for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
  2346. {
  2347. if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
  2348. {
  2349. m_caster->CastSpell(unit, i->triggeredSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_TARGET_CHECK));
  2350. TC_LOG_DEBUG("spells", "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
  2351. // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
  2352. // set duration of current aura to the triggered spell
  2353. if (i->triggeredSpell->GetDuration() == -1)
  2354. {
  2355. if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
  2356. {
  2357. // get duration from aura-only once
  2358. if (!_duration)
  2359. {
  2360. Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
  2361. _duration = aur ? aur->GetDuration() : -1;
  2362. }
  2363. triggeredAur->SetDuration(_duration);
  2364. }
  2365. }
  2366. }
  2367. }
  2368. }
  2369. // trigger linked auras remove/apply
  2370. /// @todo remove/cleanup this, as this table is not documented and people are doing stupid things with it
  2371. if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
  2372. {
  2373. for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
  2374. {
  2375. if (*i < 0)
  2376. unit->RemoveAurasDueToSpell(-(*i));
  2377. else
  2378. unit->CastSpell(unit, *i, true, nullptr, nullptr, m_caster->GetGUID());
  2379. }
  2380. }
  2381. }
  2382. void Spell::DoAllEffectOnTarget(GOTargetInfo* target)
  2383. {
  2384. if (target->processed) // Check target
  2385. return;
  2386. target->processed = true; // Target checked in apply effects procedure
  2387. uint32 effectMask = target->effectMask;
  2388. if (!effectMask)
  2389. return;
  2390. GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
  2391. if (!go)
  2392. return;
  2393. PrepareScriptHitHandlers();
  2394. CallScriptBeforeHitHandlers();
  2395. for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
  2396. if (effectMask & (1 << effectNumber))
  2397. HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
  2398. CallScriptOnHitHandlers();
  2399. CallScriptAfterHitHandlers();
  2400. }
  2401. void Spell::DoAllEffectOnTarget(ItemTargetInfo* target)
  2402. {
  2403. uint32 effectMask = target->effectMask;
  2404. if (!target->item || !effectMask)
  2405. return;
  2406. PrepareScriptHitHandlers();
  2407. CallScriptBeforeHitHandlers();
  2408. for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
  2409. if (effectMask & (1 << effectNumber))
  2410. HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
  2411. CallScriptOnHitHandlers();
  2412. CallScriptAfterHitHandlers();
  2413. }
  2414. bool Spell::UpdateChanneledTargetList()
  2415. {
  2416. // Not need check return true
  2417. if (m_channelTargetEffectMask == 0)
  2418. return true;
  2419. uint8 channelTargetEffectMask = m_channelTargetEffectMask;
  2420. uint8 channelAuraMask = 0;
  2421. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2422. if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
  2423. channelAuraMask |= 1<<i;
  2424. channelAuraMask &= channelTargetEffectMask;
  2425. float range = 0;
  2426. if (channelAuraMask)
  2427. {
  2428. range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive());
  2429. if (Player* modOwner = m_caster->GetSpellModOwner())
  2430. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
  2431. }
  2432. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  2433. {
  2434. if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
  2435. {
  2436. Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
  2437. if (!unit)
  2438. continue;
  2439. if (IsValidDeadOrAliveTarget(unit))
  2440. {
  2441. if (channelAuraMask & ihit->effectMask)
  2442. {
  2443. if (AuraApplication * aurApp = unit->GetAuraApplication(m_spellInfo->Id, m_originalCasterGUID))
  2444. {
  2445. if (m_caster != unit && !m_caster->IsWithinDistInMap(unit, range))
  2446. {
  2447. ihit->effectMask &= ~aurApp->GetEffectMask();
  2448. unit->RemoveAura(aurApp);
  2449. continue;
  2450. }
  2451. }
  2452. else // aura is dispelled
  2453. continue;
  2454. }
  2455. channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
  2456. }
  2457. }
  2458. }
  2459. // is all effects from m_needAliveTargetMask have alive targets
  2460. return channelTargetEffectMask == 0;
  2461. }
  2462. void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura)
  2463. {
  2464. if (m_CastItem)
  2465. {
  2466. m_castItemGUID = m_CastItem->GetGUID();
  2467. m_castItemEntry = m_CastItem->GetEntry();
  2468. }
  2469. else
  2470. {
  2471. m_castItemGUID.Clear();
  2472. m_castItemEntry = 0;
  2473. }
  2474. InitExplicitTargets(*targets);
  2475. // Fill aura scaling information
  2476. if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))
  2477. {
  2478. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2479. {
  2480. if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
  2481. {
  2482. // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
  2483. if (m_spellInfo->IsPositiveEffect(i))
  2484. {
  2485. m_auraScaleMask |= (1 << i);
  2486. if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
  2487. {
  2488. m_auraScaleMask = 0;
  2489. break;
  2490. }
  2491. }
  2492. }
  2493. }
  2494. }
  2495. m_spellState = SPELL_STATE_PREPARING;
  2496. if (triggeredByAura)
  2497. m_triggeredByAuraSpell = triggeredByAura->GetSpellInfo();
  2498. // create and add update event for this spell
  2499. SpellEvent* Event = new SpellEvent(this);
  2500. m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));
  2501. //Prevent casting at cast another spell (ServerSide check)
  2502. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS) && m_caster->IsNonMeleeSpellCast(false, true, true) && m_cast_count)
  2503. {
  2504. SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);
  2505. finish(false);
  2506. return;
  2507. }
  2508. if (DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
  2509. {
  2510. SendCastResult(SPELL_FAILED_SPELL_UNAVAILABLE);
  2511. finish(false);
  2512. return;
  2513. }
  2514. LoadScripts();
  2515. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2516. m_caster->ToPlayer()->SetSpellModTakingSpell(this, true);
  2517. // Fill cost data (not use power for item casts
  2518. m_powerCost = m_CastItem ? 0 : m_spellInfo->CalcPowerCost(m_caster, m_spellSchoolMask);
  2519. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2520. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2521. // Set combo point requirement
  2522. if ((_triggeredCastFlags & TRIGGERED_IGNORE_COMBO_POINTS) || m_CastItem || !m_caster->m_movedPlayer)
  2523. m_needComboPoints = false;
  2524. SpellCastResult result = CheckCast(true);
  2525. // target is checked in too many locations and with different results to handle each of them
  2526. // handle just the general SPELL_FAILED_BAD_TARGETS result which is the default result for most DBC target checks
  2527. if (_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_CHECK && result == SPELL_FAILED_BAD_TARGETS)
  2528. result = SPELL_CAST_OK;
  2529. if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
  2530. {
  2531. // Periodic auras should be interrupted when aura triggers a spell which can't be cast
  2532. // for example bladestorm aura should be removed on disarm as of patch 3.3.5
  2533. // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
  2534. // a possible alternative sollution for those would be validating aura target on unit state change
  2535. if (triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
  2536. {
  2537. SendChannelUpdate(0);
  2538. triggeredByAura->GetBase()->SetDuration(0);
  2539. }
  2540. SendCastResult(result);
  2541. finish(false);
  2542. return;
  2543. }
  2544. // Prepare data for triggers
  2545. prepareDataForTriggerSystem(triggeredByAura);
  2546. if (Player* player = m_caster->ToPlayer())
  2547. {
  2548. if (!player->GetCommandStatus(CHEAT_CASTTIME))
  2549. {
  2550. player->SetSpellModTakingSpell(this, true);
  2551. // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
  2552. m_casttime = m_spellInfo->CalcCastTime(player->getLevel(), this);
  2553. player->SetSpellModTakingSpell(this, false);
  2554. }
  2555. else
  2556. m_casttime = 0; // Set cast time to 0 if .cheat casttime is enabled.
  2557. }
  2558. else
  2559. m_casttime = m_spellInfo->CalcCastTime(m_caster->getLevel(), this);
  2560. // don't allow channeled spells / spells with cast time to be cast while moving
  2561. // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
  2562. // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
  2563. if (((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() &&
  2564. m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
  2565. {
  2566. SendCastResult(SPELL_FAILED_MOVING);
  2567. finish(false);
  2568. return;
  2569. }
  2570. // set timer base at cast time
  2571. ReSetTimer();
  2572. TC_LOG_DEBUG("spells", "Spell::prepare: spell id %u source %u caster %d customCastFlags %u mask %u", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
  2573. //Containers for channeled spells have to be set
  2574. /// @todoApply this to all cast spells if needed
  2575. // Why check duration? 29350: channelled triggers channelled
  2576. if ((_triggeredCastFlags & TRIGGERED_CAST_DIRECTLY) && (!m_spellInfo->IsChanneled() || !m_spellInfo->GetMaxDuration()))
  2577. cast(true);
  2578. else
  2579. {
  2580. // stealth must be removed at cast starting (at show channel bar)
  2581. // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
  2582. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS) && m_spellInfo->IsBreakingStealth())
  2583. {
  2584. m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST);
  2585. for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  2586. if (m_spellInfo->Effects[i].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT)
  2587. {
  2588. m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_SPELL_ATTACK);
  2589. break;
  2590. }
  2591. }
  2592. m_caster->SetCurrentCastSpell(this);
  2593. SendSpellStart();
  2594. // set target for proper facing
  2595. if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
  2596. if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
  2597. m_caster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget());
  2598. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD))
  2599. TriggerGlobalCooldown();
  2600. //item: first cast may destroy item and second cast causes crash
  2601. if (!m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL)
  2602. cast(true);
  2603. }
  2604. }
  2605. void Spell::cancel()
  2606. {
  2607. if (m_spellState == SPELL_STATE_FINISHED)
  2608. return;
  2609. uint32 oldState = m_spellState;
  2610. m_spellState = SPELL_STATE_FINISHED;
  2611. m_autoRepeat = false;
  2612. switch (oldState)
  2613. {
  2614. case SPELL_STATE_PREPARING:
  2615. CancelGlobalCooldown();
  2616. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2617. m_caster->ToPlayer()->RestoreSpellMods(this);
  2618. // no break
  2619. case SPELL_STATE_DELAYED:
  2620. SendInterrupted(0);
  2621. SendCastResult(SPELL_FAILED_INTERRUPTED);
  2622. break;
  2623. case SPELL_STATE_CASTING:
  2624. for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  2625. if ((*ihit).missCondition == SPELL_MISS_NONE)
  2626. if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
  2627. unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
  2628. SendChannelUpdate(0);
  2629. SendInterrupted(0);
  2630. SendCastResult(SPELL_FAILED_INTERRUPTED);
  2631. // spell is canceled-take mods and clear list
  2632. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2633. m_caster->ToPlayer()->RemoveSpellMods(this);
  2634. m_appliedMods.clear();
  2635. break;
  2636. default:
  2637. break;
  2638. }
  2639. SetReferencedFromCurrent(false);
  2640. if (m_selfContainer && *m_selfContainer == this)
  2641. *m_selfContainer = NULL;
  2642. m_caster->RemoveDynObject(m_spellInfo->Id);
  2643. if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
  2644. m_caster->RemoveGameObject(m_spellInfo->Id, true);
  2645. //set state back so finish will be processed
  2646. m_spellState = oldState;
  2647. finish(false);
  2648. }
  2649. void Spell::cast(bool skipCheck)
  2650. {
  2651. // update pointers base at GUIDs to prevent access to non-existed already object
  2652. if (!UpdatePointers())
  2653. {
  2654. // cancel the spell if UpdatePointers() returned false, something wrong happened there
  2655. cancel();
  2656. return;
  2657. }
  2658. // cancel at lost explicit target during cast
  2659. if (m_targets.GetObjectTargetGUID() && !m_targets.GetObjectTarget())
  2660. {
  2661. cancel();
  2662. return;
  2663. }
  2664. if (Player* playerCaster = m_caster->ToPlayer())
  2665. {
  2666. // now that we've done the basic check, now run the scripts
  2667. // should be done before the spell is actually executed
  2668. sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
  2669. // As of 3.0.2 pets begin attacking their owner's target immediately
  2670. // Let any pets know we've attacked something. Check DmgClass for harmful spells only
  2671. // This prevents spells such as Hunter's Mark from triggering pet attack
  2672. if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
  2673. if (Pet* playerPet = playerCaster->GetPet())
  2674. if (playerPet->IsAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT))
  2675. playerPet->AI()->OwnerAttacked(m_targets.GetUnitTarget());
  2676. }
  2677. SetExecutedCurrently(true);
  2678. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING))
  2679. if (m_caster->GetTypeId() == TYPEID_UNIT && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
  2680. m_caster->SetInFront(m_targets.GetObjectTarget());
  2681. // Should this be done for original caster?
  2682. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2683. {
  2684. // Set spell which will drop charges for triggered cast spells
  2685. // if not successfully cast, will be remove in finish(false)
  2686. m_caster->ToPlayer()->SetSpellModTakingSpell(this, true);
  2687. }
  2688. CallScriptBeforeCastHandlers();
  2689. // skip check if done already (for instant cast spells for example)
  2690. if (!skipCheck)
  2691. {
  2692. SpellCastResult castResult = CheckCast(false);
  2693. if (castResult != SPELL_CAST_OK)
  2694. {
  2695. SendCastResult(castResult);
  2696. SendInterrupted(0);
  2697. //restore spell mods
  2698. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2699. {
  2700. m_caster->ToPlayer()->RestoreSpellMods(this);
  2701. // cleanup after mod system
  2702. // triggered spell pointer can be not removed in some cases
  2703. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2704. }
  2705. finish(false);
  2706. SetExecutedCurrently(false);
  2707. return;
  2708. }
  2709. // additional check after cast bar completes (must not be in CheckCast)
  2710. // if trade not complete then remember it in trade data
  2711. if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM)
  2712. {
  2713. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2714. {
  2715. if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
  2716. {
  2717. if (!my_trade->IsInAcceptProcess())
  2718. {
  2719. // Spell will be cast after completing the trade. Silently ignore at this place
  2720. my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
  2721. SendCastResult(SPELL_FAILED_DONT_REPORT);
  2722. SendInterrupted(0);
  2723. m_caster->ToPlayer()->RestoreSpellMods(this);
  2724. // cleanup after mod system
  2725. // triggered spell pointer can be not removed in some cases
  2726. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2727. finish(false);
  2728. SetExecutedCurrently(false);
  2729. return;
  2730. }
  2731. }
  2732. }
  2733. }
  2734. }
  2735. SelectSpellTargets();
  2736. // Spell may be finished after target map check
  2737. if (m_spellState == SPELL_STATE_FINISHED)
  2738. {
  2739. SendInterrupted(0);
  2740. //restore spell mods
  2741. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2742. {
  2743. m_caster->ToPlayer()->RestoreSpellMods(this);
  2744. // cleanup after mod system
  2745. // triggered spell pointer can be not removed in some cases
  2746. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2747. }
  2748. finish(false);
  2749. SetExecutedCurrently(false);
  2750. return;
  2751. }
  2752. PrepareTriggersExecutedOnHit();
  2753. CallScriptOnCastHandlers();
  2754. // traded items have trade slot instead of guid in m_itemTargetGUID
  2755. // set to real guid to be sent later to the client
  2756. m_targets.UpdateTradeSlotItem();
  2757. if (Player* player = m_caster->ToPlayer())
  2758. {
  2759. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM) && m_CastItem)
  2760. {
  2761. player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry());
  2762. player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
  2763. }
  2764. player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
  2765. }
  2766. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
  2767. {
  2768. // Powers have to be taken before SendSpellGo
  2769. TakePower();
  2770. TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
  2771. }
  2772. else if (Item* targetItem = m_targets.GetItemTarget())
  2773. {
  2774. /// Not own traded item (in trader trade slot) req. reagents including triggered spell case
  2775. if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
  2776. TakeReagents();
  2777. }
  2778. // CAST SPELL
  2779. SendSpellCooldown();
  2780. PrepareScriptHitHandlers();
  2781. HandleLaunchPhase();
  2782. // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
  2783. SendSpellGo();
  2784. // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
  2785. if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled()) || m_spellInfo->AttributesEx4 & SPELL_ATTR4_UNK4)
  2786. {
  2787. // Remove used for cast item if need (it can be already NULL after TakeReagents call
  2788. // in case delayed spell remove item at cast delay start
  2789. TakeCastItem();
  2790. // Okay, maps created, now prepare flags
  2791. m_immediateHandled = false;
  2792. m_spellState = SPELL_STATE_DELAYED;
  2793. SetDelayStart(0);
  2794. if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
  2795. m_caster->ClearUnitState(UNIT_STATE_CASTING);
  2796. }
  2797. else
  2798. {
  2799. // Immediate spell, no big deal
  2800. handle_immediate();
  2801. }
  2802. CallScriptAfterCastHandlers();
  2803. if (const std::vector<int32> *spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
  2804. {
  2805. for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
  2806. if (*i < 0)
  2807. m_caster->RemoveAurasDueToSpell(-(*i));
  2808. else
  2809. m_caster->CastSpell(m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : m_caster, *i, true);
  2810. }
  2811. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2812. {
  2813. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2814. //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
  2815. if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
  2816. m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
  2817. }
  2818. SetExecutedCurrently(false);
  2819. }
  2820. void Spell::handle_immediate()
  2821. {
  2822. // start channeling if applicable
  2823. if (m_spellInfo->IsChanneled())
  2824. {
  2825. int32 duration = m_spellInfo->GetDuration();
  2826. if (duration > 0)
  2827. {
  2828. // First mod_duration then haste - see Missile Barrage
  2829. // Apply duration mod
  2830. if (Player* modOwner = m_caster->GetSpellModOwner())
  2831. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
  2832. // Apply haste mods
  2833. m_caster->ModSpellCastTime(m_spellInfo, duration, this);
  2834. m_spellState = SPELL_STATE_CASTING;
  2835. m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
  2836. m_channeledDuration = duration;
  2837. SendChannelStart(duration);
  2838. }
  2839. else if (duration == -1)
  2840. {
  2841. m_spellState = SPELL_STATE_CASTING;
  2842. m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
  2843. SendChannelStart(duration);
  2844. }
  2845. }
  2846. PrepareTargetProcessing();
  2847. // process immediate effects (items, ground, etc.) also initialize some variables
  2848. _handle_immediate_phase();
  2849. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  2850. DoAllEffectOnTarget(&(*ihit));
  2851. for (std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
  2852. DoAllEffectOnTarget(&(*ihit));
  2853. FinishTargetProcessing();
  2854. // spell is finished, perform some last features of the spell here
  2855. _handle_finish_phase();
  2856. // Remove used for cast item if need (it can be already NULL after TakeReagents call
  2857. TakeCastItem();
  2858. // handle ammo consumption for thrown weapons
  2859. if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled())
  2860. TakeAmmo();
  2861. if (m_spellState != SPELL_STATE_CASTING)
  2862. finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
  2863. }
  2864. uint64 Spell::handle_delayed(uint64 t_offset)
  2865. {
  2866. if (!UpdatePointers())
  2867. {
  2868. // finish the spell if UpdatePointers() returned false, something wrong happened there
  2869. finish(false);
  2870. return 0;
  2871. }
  2872. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2873. m_caster->ToPlayer()->SetSpellModTakingSpell(this, true);
  2874. uint64 next_time = 0;
  2875. PrepareTargetProcessing();
  2876. if (!m_immediateHandled)
  2877. {
  2878. _handle_immediate_phase();
  2879. m_immediateHandled = true;
  2880. }
  2881. bool single_missile = (m_targets.HasDst());
  2882. // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
  2883. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  2884. {
  2885. if (ihit->processed == false)
  2886. {
  2887. if (single_missile || ihit->timeDelay <= t_offset)
  2888. {
  2889. ihit->timeDelay = t_offset;
  2890. DoAllEffectOnTarget(&(*ihit));
  2891. }
  2892. else if (next_time == 0 || ihit->timeDelay < next_time)
  2893. next_time = ihit->timeDelay;
  2894. }
  2895. }
  2896. // now recheck gameobject targeting correctness
  2897. for (std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
  2898. {
  2899. if (ighit->processed == false)
  2900. {
  2901. if (single_missile || ighit->timeDelay <= t_offset)
  2902. DoAllEffectOnTarget(&(*ighit));
  2903. else if (next_time == 0 || ighit->timeDelay < next_time)
  2904. next_time = ighit->timeDelay;
  2905. }
  2906. }
  2907. FinishTargetProcessing();
  2908. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  2909. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  2910. // All targets passed - need finish phase
  2911. if (next_time == 0)
  2912. {
  2913. // spell is finished, perform some last features of the spell here
  2914. _handle_finish_phase();
  2915. finish(true); // successfully finish spell cast
  2916. // return zero, spell is finished now
  2917. return 0;
  2918. }
  2919. else
  2920. {
  2921. // spell is unfinished, return next execution time
  2922. return next_time;
  2923. }
  2924. }
  2925. void Spell::_handle_immediate_phase()
  2926. {
  2927. m_spellAura = NULL;
  2928. // initialize Diminishing Returns Data
  2929. m_diminishLevel = DIMINISHING_LEVEL_1;
  2930. m_diminishGroup = DIMINISHING_NONE;
  2931. // handle some immediate features of the spell here
  2932. HandleThreatSpells();
  2933. PrepareScriptHitHandlers();
  2934. // handle effects with SPELL_EFFECT_HANDLE_HIT mode
  2935. for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
  2936. {
  2937. // don't do anything for empty effect
  2938. if (!m_spellInfo->Effects[j].IsEffect())
  2939. continue;
  2940. // call effect handlers to handle destination hit
  2941. HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT);
  2942. }
  2943. // process items
  2944. for (std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
  2945. DoAllEffectOnTarget(&(*ihit));
  2946. if (!m_originalCaster)
  2947. return;
  2948. // Handle procs on cast
  2949. /// @todo finish new proc system:P
  2950. if (m_UniqueTargetInfo.empty() && m_targets.HasDst())
  2951. {
  2952. uint32 procAttacker = m_procAttacker;
  2953. if (!procAttacker)
  2954. procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
  2955. // Proc the spells that have DEST target
  2956. m_originalCaster->ProcDamageAndSpell(NULL, procAttacker, 0, m_procEx | PROC_EX_NORMAL_HIT, 0, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell);
  2957. }
  2958. }
  2959. void Spell::_handle_finish_phase()
  2960. {
  2961. if (m_caster->m_movedPlayer)
  2962. {
  2963. // Take for real after all targets are processed
  2964. if (m_needComboPoints)
  2965. m_caster->m_movedPlayer->ClearComboPoints();
  2966. // Real add combo points from effects
  2967. if (m_comboPointGain)
  2968. m_caster->m_movedPlayer->GainSpellComboPoints(m_comboPointGain);
  2969. if (m_spellInfo->PowerType == POWER_HOLY_POWER && m_caster->m_movedPlayer->getClass() == CLASS_PALADIN)
  2970. HandleHolyPower(m_caster->m_movedPlayer);
  2971. }
  2972. if (m_caster->m_extraAttacks && m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
  2973. {
  2974. if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID()))
  2975. m_caster->HandleProcExtraAttackFor(victim);
  2976. else
  2977. m_caster->m_extraAttacks = 0;
  2978. }
  2979. /// @todo trigger proc phase finish here
  2980. }
  2981. void Spell::SendSpellCooldown()
  2982. {
  2983. Player* _player = m_caster->ToPlayer();
  2984. if (!_player)
  2985. {
  2986. // Handle pet cooldowns here if needed instead of in PetAI to avoid hidden cooldown restarts
  2987. Creature* _creature = m_caster->ToCreature();
  2988. if (_creature && _creature->IsPet())
  2989. _creature->AddCreatureSpellCooldown(m_spellInfo->Id);
  2990. return;
  2991. }
  2992. // mana/health/etc potions, disabled by client (until combat out as declarate)
  2993. if (m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
  2994. {
  2995. // need in some way provided data for Spell::finish SendCooldownEvent
  2996. _player->SetLastPotionId(m_CastItem->GetEntry());
  2997. return;
  2998. }
  2999. // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
  3000. if (m_spellInfo->IsCooldownStartedOnEvent() || m_spellInfo->IsPassive() || (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD))
  3001. return;
  3002. _player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this);
  3003. }
  3004. void Spell::update(uint32 difftime)
  3005. {
  3006. // update pointers based at it's GUIDs
  3007. if (!UpdatePointers())
  3008. {
  3009. // cancel the spell if UpdatePointers() returned false, something wrong happened there
  3010. cancel();
  3011. return;
  3012. }
  3013. if (m_targets.GetUnitTargetGUID() && !m_targets.GetUnitTarget())
  3014. {
  3015. TC_LOG_DEBUG("spells", "Spell %u is cancelled due to removal of target.", m_spellInfo->Id);
  3016. cancel();
  3017. return;
  3018. }
  3019. // check if the player caster has moved before the spell finished
  3020. // with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
  3021. if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
  3022. m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) &&
  3023. (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
  3024. !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
  3025. {
  3026. // don't cancel for melee, autorepeat, triggered and instant spells
  3027. if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered())
  3028. cancel();
  3029. }
  3030. switch (m_spellState)
  3031. {
  3032. case SPELL_STATE_PREPARING:
  3033. {
  3034. if (m_timer > 0)
  3035. {
  3036. if (difftime >= (uint32)m_timer)
  3037. m_timer = 0;
  3038. else
  3039. m_timer -= difftime;
  3040. }
  3041. if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
  3042. // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
  3043. cast(!m_casttime);
  3044. break;
  3045. }
  3046. case SPELL_STATE_CASTING:
  3047. {
  3048. if (m_timer)
  3049. {
  3050. // check if there are alive targets left
  3051. if (!UpdateChanneledTargetList())
  3052. {
  3053. TC_LOG_DEBUG("spells", "Channeled spell %d is removed due to lack of targets", m_spellInfo->Id);
  3054. SendChannelUpdate(0);
  3055. finish();
  3056. }
  3057. if (m_timer > 0)
  3058. {
  3059. if (difftime >= (uint32)m_timer)
  3060. m_timer = 0;
  3061. else
  3062. m_timer -= difftime;
  3063. }
  3064. }
  3065. if (m_timer == 0)
  3066. {
  3067. SendChannelUpdate(0);
  3068. finish();
  3069. }
  3070. break;
  3071. }
  3072. default:
  3073. break;
  3074. }
  3075. }
  3076. void Spell::finish(bool ok)
  3077. {
  3078. if (!m_caster)
  3079. return;
  3080. if (m_spellState == SPELL_STATE_FINISHED)
  3081. return;
  3082. m_spellState = SPELL_STATE_FINISHED;
  3083. if (m_spellInfo->IsChanneled())
  3084. m_caster->UpdateInterruptMask();
  3085. if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
  3086. m_caster->ClearUnitState(UNIT_STATE_CASTING);
  3087. // Unsummon summon as possessed creatures on spell cancel
  3088. if (m_spellInfo->IsChanneled() && m_caster->GetTypeId() == TYPEID_PLAYER)
  3089. {
  3090. if (Unit* charm = m_caster->GetCharm())
  3091. if (charm->GetTypeId() == TYPEID_UNIT
  3092. && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
  3093. && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
  3094. ((Puppet*)charm)->UnSummon();
  3095. }
  3096. if (Creature* creatureCaster = m_caster->ToCreature())
  3097. creatureCaster->ReleaseFocus(this);
  3098. if (!ok)
  3099. return;
  3100. if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsSummon())
  3101. {
  3102. // Unsummon statue
  3103. uint32 spell = m_caster->GetUInt32Value(UNIT_CREATED_BY_SPELL);
  3104. SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
  3105. if (spellInfo && spellInfo->SpellIconID == 2056)
  3106. {
  3107. TC_LOG_DEBUG("spells", "Statue %d is unsummoned in spell %d finish", m_caster->GetGUIDLow(), m_spellInfo->Id);
  3108. m_caster->setDeathState(JUST_DIED);
  3109. return;
  3110. }
  3111. }
  3112. if (IsAutoActionResetSpell())
  3113. {
  3114. bool found = false;
  3115. Unit::AuraEffectList const& vIgnoreReset = m_caster->GetAuraEffectsByType(SPELL_AURA_IGNORE_MELEE_RESET);
  3116. for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
  3117. {
  3118. if ((*i)->IsAffectingSpell(m_spellInfo))
  3119. {
  3120. found = true;
  3121. break;
  3122. }
  3123. }
  3124. if (!found && !(m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
  3125. {
  3126. m_caster->resetAttackTimer(BASE_ATTACK);
  3127. if (m_caster->haveOffhandWeapon())
  3128. m_caster->resetAttackTimer(OFF_ATTACK);
  3129. m_caster->resetAttackTimer(RANGED_ATTACK);
  3130. }
  3131. }
  3132. // potions disabled by client, send event "not in combat" if need
  3133. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  3134. {
  3135. if (!m_triggeredByAuraSpell)
  3136. m_caster->ToPlayer()->UpdatePotionCooldown(this);
  3137. // triggered spell pointer can be not set in some cases
  3138. // this is needed for proper apply of triggered spell mods
  3139. m_caster->ToPlayer()->SetSpellModTakingSpell(this, true);
  3140. // Take mods after trigger spell (needed for 14177 to affect 48664)
  3141. // mods are taken only on succesfull cast and independantly from targets of the spell
  3142. m_caster->ToPlayer()->RemoveSpellMods(this);
  3143. m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
  3144. }
  3145. // Stop Attack for some spells
  3146. if (m_spellInfo->Attributes & SPELL_ATTR0_STOP_ATTACK_TARGET)
  3147. m_caster->AttackStop();
  3148. }
  3149. void Spell::SendCastResult(SpellCastResult result)
  3150. {
  3151. if (result == SPELL_CAST_OK)
  3152. return;
  3153. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  3154. return;
  3155. if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
  3156. return;
  3157. SendCastResult(m_caster->ToPlayer(), m_spellInfo, m_cast_count, result, m_customError);
  3158. }
  3159. void Spell::SendPetCastResult(SpellCastResult result)
  3160. {
  3161. if (result == SPELL_CAST_OK)
  3162. return;
  3163. Unit* owner = m_caster->GetCharmerOrOwner();
  3164. if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
  3165. return;
  3166. SendCastResult(owner->ToPlayer(), m_spellInfo, m_cast_count, result, SPELL_CUSTOM_ERROR_NONE, SMSG_PET_CAST_FAILED);
  3167. }
  3168. void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError /*= SPELL_CUSTOM_ERROR_NONE*/, Opcodes opcode /*= SMSG_CAST_FAILED*/)
  3169. {
  3170. if (result == SPELL_CAST_OK)
  3171. return;
  3172. WorldPacket data(opcode, (4+1+1));
  3173. data << uint8(cast_count);
  3174. data << uint32(spellInfo->Id);
  3175. data << uint8(result); // problem
  3176. switch (result)
  3177. {
  3178. case SPELL_FAILED_NOT_READY:
  3179. data << uint32(0); // unknown (value 1 update cooldowns on client flag)
  3180. break;
  3181. case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
  3182. data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
  3183. break;
  3184. case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
  3185. // hardcode areas limitation case
  3186. switch (spellInfo->Id)
  3187. {
  3188. case 41617: // Cenarion Mana Salve
  3189. case 41619: // Cenarion Healing Salve
  3190. data << uint32(3905);
  3191. break;
  3192. case 41618: // Bottled Nethergon Energy
  3193. case 41620: // Bottled Nethergon Vapor
  3194. data << uint32(3842);
  3195. break;
  3196. case 45373: // Bloodberry Elixir
  3197. data << uint32(4075);
  3198. break;
  3199. default: // default case (don't must be)
  3200. data << uint32(0);
  3201. break;
  3202. }
  3203. break;
  3204. case SPELL_FAILED_TOTEMS:
  3205. if (spellInfo->Totem[0])
  3206. data << uint32(spellInfo->Totem[0]);
  3207. if (spellInfo->Totem[1])
  3208. data << uint32(spellInfo->Totem[1]);
  3209. break;
  3210. case SPELL_FAILED_TOTEM_CATEGORY:
  3211. if (spellInfo->TotemCategory[0])
  3212. data << uint32(spellInfo->TotemCategory[0]);
  3213. if (spellInfo->TotemCategory[1])
  3214. data << uint32(spellInfo->TotemCategory[1]);
  3215. break;
  3216. case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
  3217. case SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND:
  3218. case SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND:
  3219. data << uint32(spellInfo->EquippedItemClass);
  3220. data << uint32(spellInfo->EquippedItemSubClassMask);
  3221. break;
  3222. case SPELL_FAILED_TOO_MANY_OF_ITEM:
  3223. {
  3224. uint32 item = 0;
  3225. for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
  3226. if (spellInfo->Effects[eff].ItemType)
  3227. item = spellInfo->Effects[eff].ItemType;
  3228. ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
  3229. if (proto && proto->ItemLimitCategory)
  3230. data << uint32(proto->ItemLimitCategory);
  3231. break;
  3232. }
  3233. case SPELL_FAILED_PREVENTED_BY_MECHANIC:
  3234. data << uint32(spellInfo->GetAllEffectsMechanicMask()); // SpellMechanic.dbc id
  3235. break;
  3236. case SPELL_FAILED_NEED_EXOTIC_AMMO:
  3237. data << uint32(spellInfo->EquippedItemSubClassMask); // seems correct...
  3238. break;
  3239. case SPELL_FAILED_NEED_MORE_ITEMS:
  3240. data << uint32(0); // Item id
  3241. data << uint32(0); // Item count?
  3242. break;
  3243. case SPELL_FAILED_MIN_SKILL:
  3244. data << uint32(0); // SkillLine.dbc id
  3245. data << uint32(0); // required skill value
  3246. break;
  3247. case SPELL_FAILED_FISHING_TOO_LOW:
  3248. data << uint32(0); // required fishing skill
  3249. break;
  3250. case SPELL_FAILED_CUSTOM_ERROR:
  3251. data << uint32(customError);
  3252. break;
  3253. case SPELL_FAILED_SILENCED:
  3254. data << uint32(0); // Unknown
  3255. break;
  3256. case SPELL_FAILED_REAGENTS:
  3257. {
  3258. uint32 missingItem = 0;
  3259. for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
  3260. {
  3261. if (spellInfo->Reagent[i] <= 0)
  3262. continue;
  3263. uint32 itemid = spellInfo->Reagent[i];
  3264. uint32 itemcount = spellInfo->ReagentCount[i];
  3265. if (!caster->HasItemCount(itemid, itemcount))
  3266. {
  3267. missingItem = itemid;
  3268. break;
  3269. }
  3270. }
  3271. data << uint32(missingItem); // first missing item
  3272. break;
  3273. }
  3274. // TODO: SPELL_FAILED_NOT_STANDING
  3275. default:
  3276. break;
  3277. }
  3278. caster->GetSession()->SendPacket(&data);
  3279. }
  3280. void Spell::SendSpellStart()
  3281. {
  3282. if (!IsNeedSendToClient())
  3283. return;
  3284. //TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
  3285. uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
  3286. if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
  3287. castFlags |= CAST_FLAG_PENDING;
  3288. if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
  3289. (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsPet()))
  3290. && m_spellInfo->PowerType != POWER_HEALTH)
  3291. castFlags |= CAST_FLAG_POWER_LEFT_SELF;
  3292. if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNES)
  3293. castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
  3294. WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
  3295. if (m_CastItem)
  3296. data << m_CastItem->GetPackGUID();
  3297. else
  3298. data << m_caster->GetPackGUID();
  3299. data << m_caster->GetPackGUID();
  3300. data << uint8(m_cast_count); // pending spell cast?
  3301. data << uint32(m_spellInfo->Id); // spellId
  3302. data << uint32(castFlags); // cast flags
  3303. data << uint32(m_timer); // delay?
  3304. data << uint32(m_casttime);
  3305. m_targets.Write(data);
  3306. if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
  3307. data << uint32(m_caster->GetPower((Powers)m_spellInfo->PowerType));
  3308. if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
  3309. {
  3310. //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
  3311. //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
  3312. if (Player* player = m_caster->ToPlayer())
  3313. {
  3314. data << uint8(m_runesState); // runes state before
  3315. data << uint8(player->GetRunesState()); // runes state after
  3316. for (uint8 i = 0; i < MAX_RUNES; ++i)
  3317. {
  3318. // float casts ensure the division is performed on floats as we need float result
  3319. float baseCd = float(player->GetRuneBaseCooldown(i));
  3320. data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
  3321. }
  3322. }
  3323. else
  3324. {
  3325. data << uint8(0);
  3326. data << uint8(0);
  3327. for (uint8 i = 0; i < MAX_RUNES; ++i)
  3328. data << uint8(0);
  3329. }
  3330. }
  3331. if (castFlags & CAST_FLAG_PROJECTILE)
  3332. {
  3333. data << uint32(0); // Ammo display ID
  3334. data << uint32(0); // Inventory Type
  3335. }
  3336. if (castFlags & CAST_FLAG_IMMUNITY)
  3337. {
  3338. data << uint32(0);
  3339. data << uint32(0);
  3340. }
  3341. if (castFlags & CAST_FLAG_HEAL_PREDICTION)
  3342. {
  3343. data << uint32(0);
  3344. data << uint8(0); // unkByte
  3345. // if (unkByte == 2)
  3346. // data.append(0);
  3347. }
  3348. m_caster->SendMessageToSet(&data, true);
  3349. }
  3350. void Spell::SendSpellGo()
  3351. {
  3352. // not send invisible spell casting
  3353. if (!IsNeedSendToClient())
  3354. return;
  3355. //TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
  3356. uint32 castFlags = CAST_FLAG_UNKNOWN_9;
  3357. // triggered spells with spell visual != 0
  3358. if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
  3359. castFlags |= CAST_FLAG_PENDING;
  3360. if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
  3361. (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsPet()))
  3362. && m_spellInfo->PowerType != POWER_HEALTH)
  3363. castFlags |= CAST_FLAG_POWER_LEFT_SELF; // should only be sent to self, but the current messaging doesn't make that possible
  3364. if ((m_caster->GetTypeId() == TYPEID_PLAYER)
  3365. && (m_caster->getClass() == CLASS_DEATH_KNIGHT)
  3366. && m_spellInfo->RuneCostID
  3367. && m_spellInfo->PowerType == POWER_RUNES
  3368. && !(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
  3369. {
  3370. castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
  3371. castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
  3372. }
  3373. if (m_spellInfo->HasEffect(SPELL_EFFECT_ACTIVATE_RUNE))
  3374. castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
  3375. if (m_targets.HasTraj())
  3376. castFlags |= CAST_FLAG_ADJUST_MISSILE;
  3377. if (!m_spellInfo->StartRecoveryTime)
  3378. castFlags |= CAST_FLAG_NO_GCD;
  3379. WorldPacket data(SMSG_SPELL_GO, 50); // guess size
  3380. if (m_CastItem)
  3381. data << m_CastItem->GetPackGUID();
  3382. else
  3383. data << m_caster->GetPackGUID();
  3384. data << m_caster->GetPackGUID();
  3385. data << uint8(m_cast_count); // pending spell cast?
  3386. data << uint32(m_spellInfo->Id); // spellId
  3387. data << uint32(castFlags); // cast flags
  3388. data << uint32(m_timer);
  3389. data << uint32(getMSTime()); // timestamp
  3390. WriteSpellGoTargets(&data);
  3391. m_targets.Write(data);
  3392. if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
  3393. data << uint32(m_caster->GetPower((Powers)m_spellInfo->PowerType));
  3394. if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
  3395. {
  3396. /// @todo There is a crash caused by a spell with CAST_FLAG_RUNE_LIST cast by a creature
  3397. //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
  3398. if (Player* player = m_caster->ToPlayer())
  3399. {
  3400. data << uint8(m_runesState); // runes state before
  3401. data << uint8(player->GetRunesState()); // runes state after
  3402. for (uint8 i = 0; i < MAX_RUNES; ++i)
  3403. {
  3404. // float casts ensure the division is performed on floats as we need float result
  3405. float baseCd = float(player->GetRuneBaseCooldown(i));
  3406. data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
  3407. }
  3408. }
  3409. }
  3410. if (castFlags & CAST_FLAG_ADJUST_MISSILE)
  3411. {
  3412. data << m_targets.GetElevation();
  3413. data << uint32(m_delayMoment);
  3414. }
  3415. if (castFlags & CAST_FLAG_PROJECTILE)
  3416. {
  3417. data << uint32(0); // Ammo display ID
  3418. data << uint32(0); // Inventory Type
  3419. }
  3420. if (castFlags & CAST_FLAG_VISUAL_CHAIN)
  3421. {
  3422. data << uint32(0);
  3423. data << uint32(0);
  3424. }
  3425. if (m_targets.GetTargetMask() & TARGET_FLAG_DEST_LOCATION)
  3426. {
  3427. data << uint8(0);
  3428. }
  3429. if (m_targets.GetTargetMask() & TARGET_FLAG_EXTRA_TARGETS)
  3430. {
  3431. data << uint32(0); // Extra targets count
  3432. /*
  3433. for (uint8 i = 0; i < count; ++i)
  3434. {
  3435. data << float(0); // Target Position X
  3436. data << float(0); // Target Position Y
  3437. data << float(0); // Target Position Z
  3438. data << uint64(0); // Target Guid
  3439. }
  3440. */
  3441. }
  3442. m_caster->SendMessageToSet(&data, true);
  3443. }
  3444. /// Writes miss and hit targets for a SMSG_SPELL_GO packet
  3445. void Spell::WriteSpellGoTargets(WorldPacket* data)
  3446. {
  3447. // This function also fill data for channeled spells:
  3448. // m_needAliveTargetMask req for stop channelig if one target die
  3449. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  3450. {
  3451. if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
  3452. // possibly SPELL_MISS_IMMUNE2 for this??
  3453. ihit->missCondition = SPELL_MISS_IMMUNE2;
  3454. }
  3455. // Hit and miss target counts are both uint8, that limits us to 255 targets for each
  3456. // sending more than 255 targets crashes the client (since count sent would be wrong)
  3457. // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
  3458. // target conditions but we still need to limit the number of targets sent and keeping
  3459. // correct count for both hit and miss).
  3460. uint32 hit = 0;
  3461. size_t hitPos = data->wpos();
  3462. *data << (uint8)0; // placeholder
  3463. for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
  3464. {
  3465. if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
  3466. {
  3467. *data << uint64(ihit->targetGUID);
  3468. m_channelTargetEffectMask |=ihit->effectMask;
  3469. ++hit;
  3470. }
  3471. }
  3472. for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
  3473. {
  3474. *data << uint64(ighit->targetGUID); // Always hits
  3475. ++hit;
  3476. }
  3477. uint32 miss = 0;
  3478. size_t missPos = data->wpos();
  3479. *data << (uint8)0; // placeholder
  3480. for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
  3481. {
  3482. if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
  3483. {
  3484. *data << uint64(ihit->targetGUID);
  3485. *data << uint8(ihit->missCondition);
  3486. if (ihit->missCondition == SPELL_MISS_REFLECT)
  3487. *data << uint8(ihit->reflectResult);
  3488. ++miss;
  3489. }
  3490. }
  3491. // Reset m_needAliveTargetMask for non channeled spell
  3492. if (!m_spellInfo->IsChanneled())
  3493. m_channelTargetEffectMask = 0;
  3494. data->put<uint8>(hitPos, (uint8)hit);
  3495. data->put<uint8>(missPos, (uint8)miss);
  3496. }
  3497. void Spell::SendLogExecute()
  3498. {
  3499. WorldPacket data(SMSG_SPELLLOGEXECUTE, (8+4+4+4+4+8));
  3500. data << m_caster->GetPackGUID();
  3501. data << uint32(m_spellInfo->Id);
  3502. uint8 effCount = 0;
  3503. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  3504. {
  3505. if (m_effectExecuteData[i])
  3506. ++effCount;
  3507. }
  3508. if (!effCount)
  3509. return;
  3510. data << uint32(effCount);
  3511. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  3512. {
  3513. if (!m_effectExecuteData[i])
  3514. continue;
  3515. data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
  3516. data.append(*m_effectExecuteData[i]);
  3517. delete m_effectExecuteData[i];
  3518. m_effectExecuteData[i] = NULL;
  3519. }
  3520. m_caster->SendMessageToSet(&data, true);
  3521. }
  3522. void Spell::ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit* target, uint32 powerType, uint32 powerTaken, float gainMultiplier)
  3523. {
  3524. InitEffectExecuteData(effIndex);
  3525. *m_effectExecuteData[effIndex] << target->GetPackGUID();
  3526. *m_effectExecuteData[effIndex] << uint32(powerTaken);
  3527. *m_effectExecuteData[effIndex] << uint32(powerType);
  3528. *m_effectExecuteData[effIndex] << float(gainMultiplier);
  3529. }
  3530. void Spell::ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit* victim, uint32 attCount)
  3531. {
  3532. InitEffectExecuteData(effIndex);
  3533. *m_effectExecuteData[effIndex] << victim->GetPackGUID();
  3534. *m_effectExecuteData[effIndex] << uint32(attCount);
  3535. }
  3536. void Spell::ExecuteLogEffectInterruptCast(uint8 /*effIndex*/, Unit* victim, uint32 spellId)
  3537. {
  3538. ObjectGuid casterGuid = m_caster->GetGUID();
  3539. ObjectGuid targetGuid = victim->GetGUID();
  3540. WorldPacket data(SMSG_SPELLINTERRUPTLOG, 8 + 8 + 4 + 4);
  3541. data.WriteBit(targetGuid[4]);
  3542. data.WriteBit(casterGuid[5]);
  3543. data.WriteBit(casterGuid[6]);
  3544. data.WriteBit(casterGuid[1]);
  3545. data.WriteBit(casterGuid[3]);
  3546. data.WriteBit(casterGuid[0]);
  3547. data.WriteBit(targetGuid[3]);
  3548. data.WriteBit(targetGuid[5]);
  3549. data.WriteBit(targetGuid[1]);
  3550. data.WriteBit(casterGuid[4]);
  3551. data.WriteBit(casterGuid[7]);
  3552. data.WriteBit(targetGuid[7]);
  3553. data.WriteBit(targetGuid[6]);
  3554. data.WriteBit(targetGuid[2]);
  3555. data.WriteBit(casterGuid[2]);
  3556. data.WriteBit(targetGuid[0]);
  3557. data.WriteByteSeq(casterGuid[7]);
  3558. data.WriteByteSeq(casterGuid[6]);
  3559. data.WriteByteSeq(casterGuid[3]);
  3560. data.WriteByteSeq(casterGuid[2]);
  3561. data.WriteByteSeq(targetGuid[3]);
  3562. data.WriteByteSeq(targetGuid[6]);
  3563. data.WriteByteSeq(targetGuid[2]);
  3564. data.WriteByteSeq(targetGuid[4]);
  3565. data.WriteByteSeq(targetGuid[7]);
  3566. data.WriteByteSeq(targetGuid[0]);
  3567. data.WriteByteSeq(casterGuid[4]);
  3568. data << uint32(m_spellInfo->Id);
  3569. data.WriteByteSeq(targetGuid[1]);
  3570. data.WriteByteSeq(casterGuid[0]);
  3571. data.WriteByteSeq(casterGuid[5]);
  3572. data.WriteByteSeq(casterGuid[1]);
  3573. data << uint32(spellId);
  3574. data.WriteByteSeq(targetGuid[5]);
  3575. m_caster->SendMessageToSet(&data, true);
  3576. }
  3577. void Spell::ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit* victim, int32 itemId, int32 slot)
  3578. {
  3579. InitEffectExecuteData(effIndex);
  3580. *m_effectExecuteData[effIndex] << victim->GetPackGUID();
  3581. *m_effectExecuteData[effIndex] << int32(itemId);
  3582. *m_effectExecuteData[effIndex] << int32(slot);
  3583. }
  3584. void Spell::ExecuteLogEffectOpenLock(uint8 effIndex, Object* obj)
  3585. {
  3586. InitEffectExecuteData(effIndex);
  3587. *m_effectExecuteData[effIndex] << obj->GetPackGUID();
  3588. }
  3589. void Spell::ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
  3590. {
  3591. InitEffectExecuteData(effIndex);
  3592. *m_effectExecuteData[effIndex] << uint32(entry);
  3593. }
  3594. void Spell::ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
  3595. {
  3596. InitEffectExecuteData(effIndex);
  3597. *m_effectExecuteData[effIndex] << uint32(entry);
  3598. }
  3599. void Spell::ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject* obj)
  3600. {
  3601. InitEffectExecuteData(effIndex);
  3602. *m_effectExecuteData[effIndex] << obj->GetPackGUID();
  3603. }
  3604. void Spell::ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject* obj)
  3605. {
  3606. InitEffectExecuteData(effIndex);
  3607. *m_effectExecuteData[effIndex] << obj->GetPackGUID();
  3608. }
  3609. void Spell::ExecuteLogEffectResurrect(uint8 effIndex, Unit* target)
  3610. {
  3611. InitEffectExecuteData(effIndex);
  3612. *m_effectExecuteData[effIndex] << target->GetPackGUID();
  3613. }
  3614. void Spell::SendInterrupted(uint8 result)
  3615. {
  3616. WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
  3617. data << m_caster->GetPackGUID();
  3618. data << uint8(m_cast_count);
  3619. data << uint32(m_spellInfo->Id);
  3620. data << uint8(result);
  3621. m_caster->SendMessageToSet(&data, true);
  3622. data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
  3623. data << m_caster->GetPackGUID();
  3624. data << uint8(m_cast_count);
  3625. data << uint32(m_spellInfo->Id);
  3626. data << uint8(result);
  3627. m_caster->SendMessageToSet(&data, true);
  3628. }
  3629. void Spell::SendChannelUpdate(uint32 time)
  3630. {
  3631. if (time == 0)
  3632. {
  3633. m_caster->SetChannelObjectGuid(ObjectGuid::Empty);
  3634. m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
  3635. }
  3636. WorldPacket data(MSG_CHANNEL_UPDATE, 8+4);
  3637. data << m_caster->GetPackGUID();
  3638. data << uint32(time);
  3639. m_caster->SendMessageToSet(&data, true);
  3640. }
  3641. void Spell::SendChannelStart(uint32 duration)
  3642. {
  3643. ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
  3644. if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
  3645. if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
  3646. channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
  3647. WorldPacket data(MSG_CHANNEL_START, (8+4+4));
  3648. data << m_caster->GetPackGUID();
  3649. data << uint32(m_spellInfo->Id);
  3650. data << uint32(duration);
  3651. data << uint8(0); // immunity (castflag & 0x04000000)
  3652. /*
  3653. if (immunity)
  3654. {
  3655. data << uint32(); // CastSchoolImmunities
  3656. data << uint32(); // CastImmunities
  3657. }
  3658. */
  3659. data << uint8(0); // healPrediction (castflag & 0x40000000)
  3660. /*
  3661. if (healPrediction)
  3662. {
  3663. data.appendPackGUID(channelTarget); // target packguid
  3664. data << uint32(); // spellid
  3665. data << uint8(0); // unk3
  3666. if (unk3 == 2)
  3667. data.append(); // unk packed guid (unused ?)
  3668. }
  3669. */
  3670. m_caster->SendMessageToSet(&data, true);
  3671. m_timer = duration;
  3672. if (channelTarget)
  3673. m_caster->SetChannelObjectGuid(channelTarget);
  3674. m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id);
  3675. }
  3676. void Spell::SendResurrectRequest(Player* target)
  3677. {
  3678. // get resurrector name for creature resurrections, otherwise packet will be not accepted
  3679. // for player resurrections the name is looked up by guid
  3680. std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
  3681. ? ""
  3682. : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
  3683. WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+sentName.size()+1+1+1+4));
  3684. data << uint64(m_caster->GetGUID());
  3685. data << uint32(sentName.size() + 1);
  3686. data << sentName;
  3687. data << uint8(0); // null terminator
  3688. data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
  3689. // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
  3690. // 4.2.2 edit : id of the spell used to resurect. (used client-side for Mass Resurect)
  3691. data << uint32(m_spellInfo->Id);
  3692. target->GetSession()->SendPacket(&data);
  3693. }
  3694. void Spell::TakeCastItem()
  3695. {
  3696. if (!m_CastItem)
  3697. return;
  3698. Player* player = m_caster->ToPlayer();
  3699. if (!player)
  3700. return;
  3701. // not remove cast item at triggered spell (equipping, weapon damage, etc)
  3702. if (_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM)
  3703. return;
  3704. ItemTemplate const* proto = m_CastItem->GetTemplate();
  3705. if (!proto)
  3706. {
  3707. // This code is to avoid a crash
  3708. // I'm not sure, if this is really an error, but I guess every item needs a prototype
  3709. TC_LOG_ERROR("spells", "Cast item has no item prototype highId=%d, lowId=%d", m_CastItem->GetGUIDHigh(), m_CastItem->GetGUIDLow());
  3710. return;
  3711. }
  3712. bool expendable = false;
  3713. bool withoutCharges = false;
  3714. for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
  3715. {
  3716. if (proto->Spells[i].SpellId)
  3717. {
  3718. // item has limited charges
  3719. if (proto->Spells[i].SpellCharges)
  3720. {
  3721. if (proto->Spells[i].SpellCharges < 0)
  3722. expendable = true;
  3723. int32 charges = m_CastItem->GetSpellCharges(i);
  3724. // item has charges left
  3725. if (charges)
  3726. {
  3727. (charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use
  3728. if (proto->Stackable == 1)
  3729. m_CastItem->SetSpellCharges(i, charges);
  3730. m_CastItem->SetState(ITEM_CHANGED, player);
  3731. }
  3732. // all charges used
  3733. withoutCharges = (charges == 0);
  3734. }
  3735. }
  3736. }
  3737. if (expendable && withoutCharges)
  3738. {
  3739. uint32 count = 1;
  3740. m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
  3741. // prevent crash at access to deleted m_targets.GetItemTarget
  3742. if (m_CastItem == m_targets.GetItemTarget())
  3743. m_targets.SetItemTarget(NULL);
  3744. m_CastItem = NULL;
  3745. m_castItemGUID.Clear();
  3746. m_castItemEntry = 0;
  3747. }
  3748. }
  3749. void Spell::TakePower()
  3750. {
  3751. if (m_CastItem || m_triggeredByAuraSpell)
  3752. return;
  3753. //Don't take power if the spell is cast while .cheat power is enabled.
  3754. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  3755. {
  3756. if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_POWER))
  3757. return;
  3758. }
  3759. Powers powerType = Powers(m_spellInfo->PowerType);
  3760. bool hit = true;
  3761. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  3762. {
  3763. if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNES)
  3764. if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
  3765. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  3766. if (ihit->targetGUID == targetGUID)
  3767. {
  3768. if (ihit->missCondition != SPELL_MISS_NONE)
  3769. {
  3770. hit = false;
  3771. //lower spell cost on fail (by talent aura)
  3772. if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
  3773. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost);
  3774. }
  3775. break;
  3776. }
  3777. }
  3778. if (powerType == POWER_RUNES)
  3779. {
  3780. TakeRunePower(hit);
  3781. return;
  3782. }
  3783. if (!m_powerCost)
  3784. return;
  3785. // health as power used
  3786. if (powerType == POWER_HEALTH)
  3787. {
  3788. m_caster->ModifyHealth(-(int32)m_powerCost);
  3789. return;
  3790. }
  3791. if (powerType >= MAX_POWERS)
  3792. {
  3793. TC_LOG_ERROR("spells", "Spell::TakePower: Unknown power type '%d'", powerType);
  3794. return;
  3795. }
  3796. if (hit)
  3797. m_caster->ModifyPower(powerType, -m_powerCost);
  3798. else
  3799. m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4));
  3800. }
  3801. void Spell::TakeAmmo()
  3802. {
  3803. if (m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
  3804. {
  3805. Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
  3806. // wands don't have ammo
  3807. if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
  3808. return;
  3809. if ((pItem->GetTemplate()->InventoryType == INVTYPE_THROWN ||
  3810. pItem->GetTemplate()->InventoryType == INVTYPE_RANGED ||
  3811. pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT)
  3812. && roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE)))
  3813. {
  3814. if (pItem->GetMaxStackCount() == 1)
  3815. {
  3816. // decrease durability for non-stackable throw weapon
  3817. m_caster->ToPlayer()->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
  3818. }
  3819. else
  3820. {
  3821. // decrease items amount for stackable throw weapon
  3822. uint32 count = 1;
  3823. m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
  3824. }
  3825. }
  3826. }
  3827. }
  3828. SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
  3829. {
  3830. if (m_spellInfo->PowerType != POWER_RUNES || !runeCostID)
  3831. return SPELL_CAST_OK;
  3832. Player* player = m_caster->ToPlayer();
  3833. if (!player)
  3834. return SPELL_CAST_OK;
  3835. if (player->getClass() != CLASS_DEATH_KNIGHT)
  3836. return SPELL_CAST_OK;
  3837. SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(runeCostID);
  3838. if (!src)
  3839. return SPELL_CAST_OK;
  3840. if (src->NoRuneCost())
  3841. return SPELL_CAST_OK;
  3842. int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
  3843. for (uint32 i = 0; i < RUNE_DEATH; ++i)
  3844. {
  3845. runeCost[i] = src->RuneCost[i];
  3846. if (Player* modOwner = m_caster->GetSpellModOwner())
  3847. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
  3848. }
  3849. runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
  3850. for (uint32 i = 0; i < MAX_RUNES; ++i)
  3851. {
  3852. RuneType rune = player->GetCurrentRune(i);
  3853. if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
  3854. runeCost[rune]--;
  3855. }
  3856. for (uint32 i = 0; i < RUNE_DEATH; ++i)
  3857. if (runeCost[i] > 0)
  3858. runeCost[RUNE_DEATH] += runeCost[i];
  3859. if (runeCost[RUNE_DEATH] > MAX_RUNES)
  3860. return SPELL_FAILED_NO_POWER; // not sure if result code is correct
  3861. return SPELL_CAST_OK;
  3862. }
  3863. void Spell::TakeRunePower(bool didHit)
  3864. {
  3865. if (m_caster->GetTypeId() != TYPEID_PLAYER || m_caster->getClass() != CLASS_DEATH_KNIGHT)
  3866. return;
  3867. SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
  3868. if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
  3869. return;
  3870. Player* player = m_caster->ToPlayer();
  3871. m_runesState = player->GetRunesState(); // store previous state
  3872. int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
  3873. for (uint32 i = 0; i < RUNE_DEATH; ++i)
  3874. {
  3875. runeCost[i] = runeCostData->RuneCost[i];
  3876. if (Player* modOwner = m_caster->GetSpellModOwner())
  3877. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
  3878. }
  3879. runeCost[RUNE_DEATH] = 0; // calculated later
  3880. for (uint32 i = 0; i < MAX_RUNES; ++i)
  3881. {
  3882. RuneType rune = player->GetCurrentRune(i);
  3883. if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
  3884. {
  3885. player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true);
  3886. player->SetLastUsedRune(rune);
  3887. runeCost[rune]--;
  3888. }
  3889. }
  3890. runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
  3891. if (runeCost[RUNE_DEATH] > 0)
  3892. {
  3893. for (uint32 i = 0; i < MAX_RUNES; ++i)
  3894. {
  3895. RuneType rune = player->GetCurrentRune(i);
  3896. if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH)
  3897. {
  3898. player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true);
  3899. player->SetLastUsedRune(rune);
  3900. runeCost[rune]--;
  3901. // keep Death Rune type if missed
  3902. if (didHit)
  3903. player->RestoreBaseRune(i);
  3904. if (runeCost[RUNE_DEATH] == 0)
  3905. break;
  3906. }
  3907. }
  3908. }
  3909. // you can gain some runic power when use runes
  3910. if (didHit)
  3911. if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
  3912. player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
  3913. }
  3914. void Spell::TakeReagents()
  3915. {
  3916. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  3917. return;
  3918. ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : NULL;
  3919. // do not take reagents for these item casts
  3920. if (castItemTemplate && castItemTemplate->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)
  3921. return;
  3922. Player* p_caster = m_caster->ToPlayer();
  3923. if (p_caster->CanNoReagentCast(m_spellInfo))
  3924. return;
  3925. for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
  3926. {
  3927. if (m_spellInfo->Reagent[x] <= 0)
  3928. continue;
  3929. uint32 itemid = m_spellInfo->Reagent[x];
  3930. uint32 itemcount = m_spellInfo->ReagentCount[x];
  3931. // if CastItem is also spell reagent
  3932. if (castItemTemplate && castItemTemplate->ItemId == itemid)
  3933. {
  3934. for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
  3935. {
  3936. // CastItem will be used up and does not count as reagent
  3937. int32 charges = m_CastItem->GetSpellCharges(s);
  3938. if (castItemTemplate->Spells[s].SpellCharges < 0 && abs(charges) < 2)
  3939. {
  3940. ++itemcount;
  3941. break;
  3942. }
  3943. }
  3944. m_CastItem = NULL;
  3945. m_castItemGUID.Clear();
  3946. m_castItemEntry = 0;
  3947. }
  3948. // if GetItemTarget is also spell reagent
  3949. if (m_targets.GetItemTargetEntry() == itemid)
  3950. m_targets.SetItemTarget(NULL);
  3951. p_caster->DestroyItemCount(itemid, itemcount, true);
  3952. }
  3953. }
  3954. void Spell::HandleThreatSpells()
  3955. {
  3956. if (m_UniqueTargetInfo.empty())
  3957. return;
  3958. if ((m_spellInfo->AttributesEx & SPELL_ATTR1_NO_THREAT) ||
  3959. (m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO))
  3960. return;
  3961. float threat = 0.0f;
  3962. if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
  3963. {
  3964. if (threatEntry->apPctMod != 0.0f)
  3965. threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
  3966. threat += threatEntry->flatMod;
  3967. }
  3968. else if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_NO_INITIAL_THREAT) == 0)
  3969. threat += m_spellInfo->SpellLevel;
  3970. // past this point only multiplicative effects occur
  3971. if (threat == 0.0f)
  3972. return;
  3973. // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
  3974. threat /= m_UniqueTargetInfo.size();
  3975. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  3976. {
  3977. float threatToAdd = threat;
  3978. if (ihit->missCondition != SPELL_MISS_NONE)
  3979. threatToAdd = 0.0f;
  3980. Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
  3981. if (!target)
  3982. continue;
  3983. // positive spells distribute threat among all units that are in combat with target, like healing
  3984. if (m_spellInfo->_IsPositiveSpell())
  3985. target->getHostileRefManager().threatAssist(m_caster, threatToAdd, m_spellInfo);
  3986. // for negative spells threat gets distributed among affected targets
  3987. else
  3988. {
  3989. if (!target->CanHaveThreatList())
  3990. continue;
  3991. target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
  3992. }
  3993. }
  3994. TC_LOG_DEBUG("spells", "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
  3995. }
  3996. void Spell::HandleHolyPower(Player* caster)
  3997. {
  3998. if (!caster)
  3999. return;
  4000. bool hit = true;
  4001. Player* modOwner = caster->GetSpellModOwner();
  4002. m_powerCost = caster->GetPower(POWER_HOLY_POWER); // Always use all the holy power we have
  4003. if (!m_powerCost || !modOwner)
  4004. return;
  4005. if (uint64 targetGUID = m_targets.GetUnitTargetGUID())
  4006. {
  4007. for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  4008. {
  4009. if (ihit->targetGUID == targetGUID)
  4010. {
  4011. if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS)
  4012. hit = false;
  4013. break;
  4014. }
  4015. }
  4016. // The spell did hit the target, apply aura cost mods if there are any.
  4017. if (hit)
  4018. {
  4019. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, m_powerCost);
  4020. m_caster->ModifyPower(POWER_HOLY_POWER, -m_powerCost);
  4021. }
  4022. }
  4023. }
  4024. void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
  4025. {
  4026. effectHandleMode = mode;
  4027. unitTarget = pUnitTarget;
  4028. itemTarget = pItemTarget;
  4029. gameObjTarget = pGOTarget;
  4030. destTarget = &m_destTargets[i]._position;
  4031. uint8 eff = m_spellInfo->Effects[i].Effect;
  4032. TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff);
  4033. damage = CalculateDamage(i, unitTarget);
  4034. bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
  4035. if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
  4036. {
  4037. (this->*SpellEffects[eff])((SpellEffIndex)i);
  4038. }
  4039. }
  4040. SpellCastResult Spell::CheckCast(bool strict)
  4041. {
  4042. // check death state
  4043. if (!m_caster->IsAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !((m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD) || (IsTriggered() && !m_triggeredByAuraSpell)))
  4044. return SPELL_FAILED_CASTER_DEAD;
  4045. // check cooldowns to prevent cheating
  4046. if (m_caster->GetTypeId() == TYPEID_PLAYER && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE))
  4047. {
  4048. //can cast triggered (by aura only?) spells while have this flag
  4049. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && m_caster->ToPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY))
  4050. return SPELL_FAILED_SPELL_IN_PROGRESS;
  4051. if (m_caster->ToPlayer()->HasSpellCooldown(m_spellInfo->Id))
  4052. {
  4053. if (m_triggeredByAuraSpell)
  4054. return SPELL_FAILED_DONT_REPORT;
  4055. else
  4056. return SPELL_FAILED_NOT_READY;
  4057. }
  4058. // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
  4059. if (m_caster->ToPlayer()->GetLastPotionId() && m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent()))
  4060. return SPELL_FAILED_NOT_READY;
  4061. }
  4062. if (m_spellInfo->AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL && !m_caster->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS))
  4063. {
  4064. m_customError = SPELL_CUSTOM_ERROR_GM_ONLY;
  4065. return SPELL_FAILED_CUSTOM_ERROR;
  4066. }
  4067. // Check global cooldown
  4068. if (strict && !(_triggeredCastFlags & TRIGGERED_IGNORE_GCD) && HasGlobalCooldown())
  4069. return SPELL_FAILED_NOT_READY;
  4070. // only triggered spells can be processed an ended battleground
  4071. if (!IsTriggered() && m_caster->GetTypeId() == TYPEID_PLAYER)
  4072. if (Battleground* bg = m_caster->ToPlayer()->GetBattleground())
  4073. if (bg->GetStatus() == STATUS_WAIT_LEAVE)
  4074. return SPELL_FAILED_DONT_REPORT;
  4075. if (m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled())
  4076. {
  4077. if (m_spellInfo->Attributes & SPELL_ATTR0_OUTDOORS_ONLY &&
  4078. !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
  4079. return SPELL_FAILED_ONLY_OUTDOORS;
  4080. if (m_spellInfo->Attributes & SPELL_ATTR0_INDOORS_ONLY &&
  4081. m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
  4082. return SPELL_FAILED_ONLY_INDOORS;
  4083. }
  4084. // only check at first call, Stealth auras are already removed at second call
  4085. // for now, ignore triggered spells
  4086. if (strict && !(_triggeredCastFlags & TRIGGERED_IGNORE_SHAPESHIFT))
  4087. {
  4088. bool checkForm = true;
  4089. // Ignore form req aura
  4090. Unit::AuraEffectList const& ignore = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
  4091. for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
  4092. {
  4093. if (!(*i)->IsAffectingSpell(m_spellInfo))
  4094. continue;
  4095. checkForm = false;
  4096. break;
  4097. }
  4098. if (checkForm)
  4099. {
  4100. // Cannot be used in this stance/form
  4101. SpellCastResult shapeError = m_spellInfo->CheckShapeshift(m_caster->GetShapeshiftForm());
  4102. if (shapeError != SPELL_CAST_OK)
  4103. return shapeError;
  4104. if ((m_spellInfo->Attributes & SPELL_ATTR0_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
  4105. return SPELL_FAILED_ONLY_STEALTHED;
  4106. }
  4107. }
  4108. Unit::AuraEffectList const& blockSpells = m_caster->GetAuraEffectsByType(SPELL_AURA_BLOCK_SPELL_FAMILY);
  4109. for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
  4110. if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
  4111. return SPELL_FAILED_SPELL_UNAVAILABLE;
  4112. bool reqCombat = true;
  4113. Unit::AuraEffectList const& stateAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
  4114. for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
  4115. {
  4116. if ((*j)->IsAffectingSpell(m_spellInfo))
  4117. {
  4118. m_needComboPoints = false;
  4119. if ((*j)->GetMiscValue() == 1)
  4120. {
  4121. reqCombat=false;
  4122. break;
  4123. }
  4124. }
  4125. }
  4126. // caster state requirements
  4127. // not for triggered spells (needed by execute)
  4128. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE))
  4129. {
  4130. if (m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraStateType(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
  4131. return SPELL_FAILED_CASTER_AURASTATE;
  4132. if (m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraStateType(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
  4133. return SPELL_FAILED_CASTER_AURASTATE;
  4134. // Note: spell 62473 requres casterAuraSpell = triggering spell
  4135. if (m_spellInfo->CasterAuraSpell && !m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->CasterAuraSpell, m_caster)))
  4136. return SPELL_FAILED_CASTER_AURASTATE;
  4137. if (m_spellInfo->ExcludeCasterAuraSpell && m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeCasterAuraSpell, m_caster)))
  4138. return SPELL_FAILED_CASTER_AURASTATE;
  4139. if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
  4140. return SPELL_FAILED_AFFECTING_COMBAT;
  4141. }
  4142. // cancel autorepeat spells if cast start when moving
  4143. // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
  4144. // Do not cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
  4145. if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->isMoving() && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
  4146. {
  4147. // skip stuck spell to allow use it in falling case and apply spell limitations at movement
  4148. if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK) &&
  4149. (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0))
  4150. return SPELL_FAILED_MOVING;
  4151. }
  4152. // Check vehicle flags
  4153. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE))
  4154. {
  4155. SpellCastResult vehicleCheck = m_spellInfo->CheckVehicle(m_caster);
  4156. if (vehicleCheck != SPELL_CAST_OK)
  4157. return vehicleCheck;
  4158. }
  4159. // check spell cast conditions from database
  4160. {
  4161. ConditionSourceInfo condInfo = ConditionSourceInfo(m_caster);
  4162. condInfo.mConditionTargets[1] = m_targets.GetObjectTarget();
  4163. ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
  4164. if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
  4165. {
  4166. // mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
  4167. if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
  4168. {
  4169. if (condInfo.mLastFailedCondition->ErrorType == SPELL_FAILED_CUSTOM_ERROR)
  4170. m_customError = SpellCustomErrors(condInfo.mLastFailedCondition->ErrorTextId);
  4171. return SpellCastResult(condInfo.mLastFailedCondition->ErrorType);
  4172. }
  4173. if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
  4174. return SPELL_FAILED_CASTER_AURASTATE;
  4175. return SPELL_FAILED_BAD_TARGETS;
  4176. }
  4177. }
  4178. // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
  4179. // those spells may have incorrect target entries or not filled at all (for example 15332)
  4180. // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
  4181. // also, such casts shouldn't be sent to client
  4182. if (!((m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == m_caster)))
  4183. {
  4184. // Check explicit target for m_originalCaster - todo: get rid of such workarounds
  4185. SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(m_originalCaster ? m_originalCaster : m_caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget());
  4186. if (castResult != SPELL_CAST_OK)
  4187. return castResult;
  4188. }
  4189. if (Unit* target = m_targets.GetUnitTarget())
  4190. {
  4191. SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
  4192. if (castResult != SPELL_CAST_OK)
  4193. return castResult;
  4194. if (target != m_caster)
  4195. {
  4196. // Must be behind the target
  4197. if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
  4198. return SPELL_FAILED_NOT_BEHIND;
  4199. // Target must be facing you
  4200. if ((m_spellInfo->AttributesCu & SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
  4201. return SPELL_FAILED_NOT_INFRONT;
  4202. if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly cast by a trigger)
  4203. {
  4204. WorldObject* losTarget = m_caster;
  4205. if (IsTriggered() && m_triggeredByAuraSpell)
  4206. if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id))
  4207. losTarget = dynObj;
  4208. if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget))
  4209. return SPELL_FAILED_LINE_OF_SIGHT;
  4210. }
  4211. }
  4212. }
  4213. // Check for line of sight for spells with dest
  4214. if (m_targets.HasDst())
  4215. {
  4216. float x, y, z;
  4217. m_targets.GetDstPos()->GetPosition(x, y, z);
  4218. if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z))
  4219. return SPELL_FAILED_LINE_OF_SIGHT;
  4220. }
  4221. // check pet presence
  4222. for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
  4223. {
  4224. if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
  4225. {
  4226. if (!m_caster->GetGuardianPet())
  4227. {
  4228. if (m_triggeredByAuraSpell) // not report pet not existence for triggered spells
  4229. return SPELL_FAILED_DONT_REPORT;
  4230. else
  4231. return SPELL_FAILED_NO_PET;
  4232. }
  4233. break;
  4234. }
  4235. }
  4236. // Spell cast only in battleground
  4237. if ((m_spellInfo->AttributesEx3 & SPELL_ATTR3_BATTLEGROUND) && m_caster->GetTypeId() == TYPEID_PLAYER)
  4238. if (!m_caster->ToPlayer()->InBattleground())
  4239. return SPELL_FAILED_ONLY_BATTLEGROUNDS;
  4240. // do not allow spells to be cast in arenas or rated battlegrounds
  4241. if (Player* player = m_caster->ToPlayer())
  4242. if (player->InArena()/* || player->InRatedBattleGround() NYI*/)
  4243. {
  4244. SpellCastResult castResult = CheckArenaAndRatedBattlegroundCastRules();
  4245. if (castResult != SPELL_CAST_OK)
  4246. return castResult;
  4247. }
  4248. // zone check
  4249. if (m_caster->GetTypeId() == TYPEID_UNIT || !m_caster->ToPlayer()->IsGameMaster())
  4250. {
  4251. uint32 zone, area;
  4252. m_caster->GetZoneAndAreaId(zone, area);
  4253. SpellCastResult locRes = m_spellInfo->CheckLocation(m_caster->GetMapId(), zone, area, m_caster->ToPlayer());
  4254. if (locRes != SPELL_CAST_OK)
  4255. return locRes;
  4256. }
  4257. // not let players cast spells at mount (and let do it to creatures)
  4258. if (m_caster->IsMounted() && m_caster->GetTypeId() == TYPEID_PLAYER && !(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE) &&
  4259. !m_spellInfo->IsPassive() && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_MOUNTED))
  4260. {
  4261. if (m_caster->IsInFlight())
  4262. return SPELL_FAILED_NOT_ON_TAXI;
  4263. else
  4264. return SPELL_FAILED_NOT_MOUNTED;
  4265. }
  4266. // check spell focus object
  4267. if (m_spellInfo->RequiresSpellFocus)
  4268. {
  4269. focusObject = SearchSpellFocus();
  4270. if (!focusObject)
  4271. return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
  4272. }
  4273. SpellCastResult castResult = SPELL_CAST_OK;
  4274. // always (except passive spells) check items (only player related checks)
  4275. if (!m_spellInfo->IsPassive())
  4276. {
  4277. castResult = CheckItems();
  4278. if (castResult != SPELL_CAST_OK)
  4279. return castResult;
  4280. }
  4281. // Triggered spells also have range check
  4282. /// @todo determine if there is some flag to enable/disable the check
  4283. castResult = CheckRange(strict);
  4284. if (castResult != SPELL_CAST_OK)
  4285. return castResult;
  4286. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST))
  4287. {
  4288. castResult = CheckPower();
  4289. if (castResult != SPELL_CAST_OK)
  4290. return castResult;
  4291. }
  4292. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURAS))
  4293. {
  4294. castResult = CheckCasterAuras();
  4295. if (castResult != SPELL_CAST_OK)
  4296. return castResult;
  4297. }
  4298. // script hook
  4299. castResult = CallScriptCheckCastHandlers();
  4300. if (castResult != SPELL_CAST_OK)
  4301. return castResult;
  4302. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  4303. {
  4304. // for effects of spells that have only one target
  4305. switch (m_spellInfo->Effects[i].Effect)
  4306. {
  4307. case SPELL_EFFECT_DUMMY:
  4308. {
  4309. if (m_spellInfo->Id == 19938) // Awaken Peon
  4310. {
  4311. Unit* unit = m_targets.GetUnitTarget();
  4312. if (!unit || !unit->HasAura(17743))
  4313. return SPELL_FAILED_BAD_TARGETS;
  4314. }
  4315. else if (m_spellInfo->Id == 31789) // Righteous Defense
  4316. {
  4317. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4318. return SPELL_FAILED_DONT_REPORT;
  4319. Unit* target = m_targets.GetUnitTarget();
  4320. if (!target || !target->IsFriendlyTo(m_caster) || target->getAttackers().empty())
  4321. return SPELL_FAILED_BAD_TARGETS;
  4322. }
  4323. break;
  4324. }
  4325. case SPELL_EFFECT_LEARN_SPELL:
  4326. {
  4327. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4328. return SPELL_FAILED_BAD_TARGETS;
  4329. if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
  4330. break;
  4331. Pet* pet = m_caster->ToPlayer()->GetPet();
  4332. if (!pet)
  4333. return SPELL_FAILED_NO_PET;
  4334. SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
  4335. if (!learn_spellproto)
  4336. return SPELL_FAILED_NOT_KNOWN;
  4337. if (m_spellInfo->SpellLevel > pet->getLevel())
  4338. return SPELL_FAILED_LOWLEVEL;
  4339. break;
  4340. }
  4341. case SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB:
  4342. {
  4343. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4344. return SPELL_FAILED_BAD_TARGETS;
  4345. if (Guild* guild = m_caster->ToPlayer()->GetGuild())
  4346. if (guild->GetLeaderGUID() != m_caster->ToPlayer()->GetGUID())
  4347. return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
  4348. break;
  4349. }
  4350. case SPELL_EFFECT_LEARN_PET_SPELL:
  4351. {
  4352. // check target only for unit target case
  4353. if (Unit* unitTarget = m_targets.GetUnitTarget())
  4354. {
  4355. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4356. return SPELL_FAILED_BAD_TARGETS;
  4357. Pet* pet = unitTarget->ToPet();
  4358. if (!pet || pet->GetOwner() != m_caster)
  4359. return SPELL_FAILED_BAD_TARGETS;
  4360. SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
  4361. if (!learn_spellproto)
  4362. return SPELL_FAILED_NOT_KNOWN;
  4363. if (m_spellInfo->SpellLevel > pet->getLevel())
  4364. return SPELL_FAILED_LOWLEVEL;
  4365. }
  4366. break;
  4367. }
  4368. case SPELL_EFFECT_APPLY_GLYPH:
  4369. {
  4370. uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
  4371. if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
  4372. if (m_caster->HasAura(gp->SpellId))
  4373. return SPELL_FAILED_UNIQUE_GLYPH;
  4374. break;
  4375. }
  4376. case SPELL_EFFECT_FEED_PET:
  4377. {
  4378. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4379. return SPELL_FAILED_BAD_TARGETS;
  4380. Item* foodItem = m_targets.GetItemTarget();
  4381. if (!foodItem)
  4382. return SPELL_FAILED_BAD_TARGETS;
  4383. Pet* pet = m_caster->ToPlayer()->GetPet();
  4384. if (!pet)
  4385. return SPELL_FAILED_NO_PET;
  4386. if (!pet->HaveInDiet(foodItem->GetTemplate()))
  4387. return SPELL_FAILED_WRONG_PET_FOOD;
  4388. if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
  4389. return SPELL_FAILED_FOOD_LOWLEVEL;
  4390. if (m_caster->IsInCombat() || pet->IsInCombat())
  4391. return SPELL_FAILED_AFFECTING_COMBAT;
  4392. break;
  4393. }
  4394. case SPELL_EFFECT_POWER_BURN:
  4395. case SPELL_EFFECT_POWER_DRAIN:
  4396. {
  4397. // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
  4398. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  4399. if (Unit* target = m_targets.GetUnitTarget())
  4400. if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue))
  4401. return SPELL_FAILED_BAD_TARGETS;
  4402. break;
  4403. }
  4404. case SPELL_EFFECT_CHARGE:
  4405. {
  4406. if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)
  4407. {
  4408. // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
  4409. if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
  4410. m_caster->RemoveMovementImpairingAuras();
  4411. }
  4412. if (m_caster->HasUnitState(UNIT_STATE_ROOT))
  4413. return SPELL_FAILED_ROOTED;
  4414. if (GetSpellInfo()->NeedsExplicitUnitTarget())
  4415. {
  4416. Unit* target = m_targets.GetUnitTarget();
  4417. if (!target)
  4418. return SPELL_FAILED_DONT_REPORT;
  4419. float objSize = target->GetObjectSize();
  4420. float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
  4421. m_preGeneratedPath.SetPathLengthLimit(range);
  4422. // first try with raycast, if it fails fall back to normal path
  4423. bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize(), false, true);
  4424. if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
  4425. return SPELL_FAILED_OUT_OF_RANGE;
  4426. else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH)
  4427. {
  4428. result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize(), false, false);
  4429. if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
  4430. return SPELL_FAILED_OUT_OF_RANGE;
  4431. else if (!result || m_preGeneratedPath.GetPathType() & PATHFIND_NOPATH)
  4432. return SPELL_FAILED_NOPATH;
  4433. }
  4434. m_preGeneratedPath.ReducePathLenghtByDist(objSize); // move back
  4435. }
  4436. break;
  4437. }
  4438. case SPELL_EFFECT_SKINNING:
  4439. {
  4440. if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_targets.GetUnitTarget() || m_targets.GetUnitTarget()->GetTypeId() != TYPEID_UNIT)
  4441. return SPELL_FAILED_BAD_TARGETS;
  4442. if (!(m_targets.GetUnitTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_SKINNABLE))
  4443. return SPELL_FAILED_TARGET_UNSKINNABLE;
  4444. Creature* creature = m_targets.GetUnitTarget()->ToCreature();
  4445. if (!creature->IsCritter() && !creature->loot.isLooted())
  4446. return SPELL_FAILED_TARGET_NOT_LOOTED;
  4447. uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
  4448. int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
  4449. int32 TargetLevel = m_targets.GetUnitTarget()->getLevel();
  4450. int32 ReqValue = (skillValue < 100 ? (TargetLevel-10) * 10 : TargetLevel * 5);
  4451. if (ReqValue > skillValue)
  4452. return SPELL_FAILED_LOW_CASTLEVEL;
  4453. // chance for fail at orange skinning attempt
  4454. if ((m_selfContainer && (*m_selfContainer) == this) &&
  4455. skillValue < sWorld->GetConfigMaxSkillValue() &&
  4456. (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
  4457. return SPELL_FAILED_TRY_AGAIN;
  4458. break;
  4459. }
  4460. case SPELL_EFFECT_OPEN_LOCK:
  4461. {
  4462. if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
  4463. m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
  4464. break;
  4465. if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
  4466. // we need a go target in case of TARGET_GAMEOBJECT_TARGET
  4467. || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
  4468. return SPELL_FAILED_BAD_TARGETS;
  4469. Item* pTempItem = NULL;
  4470. if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM)
  4471. {
  4472. if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
  4473. pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue())); // at this point item target guid contains the trade slot
  4474. }
  4475. else if (m_targets.GetTargetMask() & TARGET_FLAG_ITEM)
  4476. pTempItem = m_caster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID());
  4477. // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
  4478. if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
  4479. !m_targets.GetGOTarget() &&
  4480. (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
  4481. return SPELL_FAILED_BAD_TARGETS;
  4482. if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
  4483. m_targets.GetGOTarget()->GetGOInfo()->type != GAMEOBJECT_TYPE_TRAP))
  4484. if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
  4485. !m_caster->ToPlayer()->CanUseBattlegroundObject(m_targets.GetGOTarget()))
  4486. return SPELL_FAILED_TRY_AGAIN;
  4487. // get the lock entry
  4488. uint32 lockId = 0;
  4489. if (GameObject* go = m_targets.GetGOTarget())
  4490. {
  4491. lockId = go->GetGOInfo()->GetLockId();
  4492. if (!lockId)
  4493. return SPELL_FAILED_BAD_TARGETS;
  4494. }
  4495. else if (Item* itm = m_targets.GetItemTarget())
  4496. lockId = itm->GetTemplate()->LockID;
  4497. SkillType skillId = SKILL_NONE;
  4498. int32 reqSkillValue = 0;
  4499. int32 skillValue = 0;
  4500. // check lock compatibility
  4501. SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
  4502. if (res != SPELL_CAST_OK)
  4503. return res;
  4504. // chance for fail at orange mining/herb/LockPicking gathering attempt
  4505. // second check prevent fail at rechecks
  4506. if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
  4507. {
  4508. bool canFailAtMax = skillId != SKILL_HERBALISM && skillId != SKILL_MINING;
  4509. // chance for failure in orange gather / lockpick (gathering skill can't fail at maxskill)
  4510. if ((canFailAtMax || skillValue < sWorld->GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
  4511. return SPELL_FAILED_TRY_AGAIN;
  4512. }
  4513. break;
  4514. }
  4515. case SPELL_EFFECT_RESURRECT_PET:
  4516. {
  4517. Creature* pet = m_caster->GetGuardianPet();
  4518. if (pet && pet->IsAlive())
  4519. return SPELL_FAILED_ALREADY_HAVE_SUMMON;
  4520. break;
  4521. }
  4522. // This is generic summon effect
  4523. case SPELL_EFFECT_SUMMON:
  4524. {
  4525. SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
  4526. if (!SummonProperties)
  4527. break;
  4528. switch (SummonProperties->Category)
  4529. {
  4530. case SUMMON_CATEGORY_PET:
  4531. if (m_caster->GetPetGUID())
  4532. return SPELL_FAILED_ALREADY_HAVE_SUMMON;
  4533. // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET
  4534. case SUMMON_CATEGORY_PUPPET:
  4535. if (m_caster->GetCharmGUID())
  4536. return SPELL_FAILED_ALREADY_HAVE_CHARM;
  4537. break;
  4538. }
  4539. break;
  4540. }
  4541. case SPELL_EFFECT_CREATE_TAMED_PET:
  4542. {
  4543. if (m_targets.GetUnitTarget())
  4544. {
  4545. if (m_targets.GetUnitTarget()->GetTypeId() != TYPEID_PLAYER)
  4546. return SPELL_FAILED_BAD_TARGETS;
  4547. if (m_targets.GetUnitTarget()->GetPetGUID())
  4548. return SPELL_FAILED_ALREADY_HAVE_SUMMON;
  4549. }
  4550. break;
  4551. }
  4552. case SPELL_EFFECT_SUMMON_PET:
  4553. {
  4554. if (m_caster->GetPetGUID()) //let warlock do a replacement summon
  4555. {
  4556. if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARLOCK)
  4557. {
  4558. if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
  4559. if (Pet* pet = m_caster->ToPlayer()->GetPet())
  4560. pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
  4561. }
  4562. else
  4563. return SPELL_FAILED_ALREADY_HAVE_SUMMON;
  4564. }
  4565. if (m_caster->GetCharmGUID())
  4566. return SPELL_FAILED_ALREADY_HAVE_CHARM;
  4567. break;
  4568. }
  4569. case SPELL_EFFECT_SUMMON_PLAYER:
  4570. {
  4571. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4572. return SPELL_FAILED_BAD_TARGETS;
  4573. if (!m_caster->GetTarget())
  4574. return SPELL_FAILED_BAD_TARGETS;
  4575. Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetTarget());
  4576. if (!target || m_caster->ToPlayer() == target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
  4577. return SPELL_FAILED_BAD_TARGETS;
  4578. // check if our map is dungeon
  4579. MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
  4580. if (map->IsDungeon())
  4581. {
  4582. uint32 mapId = m_caster->GetMap()->GetId();
  4583. Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
  4584. if (map->IsRaid())
  4585. if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
  4586. if (InstancePlayerBind* casterBind = m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
  4587. if (targetBind->perm && targetBind->save != casterBind->save)
  4588. return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;
  4589. InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
  4590. if (!instance)
  4591. return SPELL_FAILED_TARGET_NOT_IN_INSTANCE;
  4592. if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
  4593. return SPELL_FAILED_BAD_TARGETS;
  4594. }
  4595. break;
  4596. }
  4597. // RETURN HERE
  4598. case SPELL_EFFECT_SUMMON_RAF_FRIEND:
  4599. {
  4600. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4601. return SPELL_FAILED_BAD_TARGETS;
  4602. Player* playerCaster = m_caster->ToPlayer();
  4603. //
  4604. if (!(playerCaster->GetTarget()))
  4605. return SPELL_FAILED_BAD_TARGETS;
  4606. Player* target = playerCaster->GetSelectedPlayer();
  4607. if (!target ||
  4608. !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
  4609. return SPELL_FAILED_BAD_TARGETS;
  4610. break;
  4611. }
  4612. case SPELL_EFFECT_LEAP:
  4613. case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER:
  4614. {
  4615. //Do not allow to cast it before BG starts.
  4616. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  4617. if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
  4618. if (bg->GetStatus() != STATUS_IN_PROGRESS)
  4619. return SPELL_FAILED_TRY_AGAIN;
  4620. break;
  4621. }
  4622. case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF:
  4623. {
  4624. if (m_targets.GetUnitTarget() == m_caster)
  4625. return SPELL_FAILED_BAD_TARGETS;
  4626. break;
  4627. }
  4628. case SPELL_EFFECT_LEAP_BACK:
  4629. {
  4630. if (m_caster->HasUnitState(UNIT_STATE_ROOT))
  4631. {
  4632. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  4633. return SPELL_FAILED_ROOTED;
  4634. else
  4635. return SPELL_FAILED_DONT_REPORT;
  4636. }
  4637. break;
  4638. }
  4639. case SPELL_EFFECT_TALENT_SPEC_SELECT:
  4640. // can't change during already started arena/battleground
  4641. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  4642. if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
  4643. if (bg->GetStatus() == STATUS_IN_PROGRESS)
  4644. return SPELL_FAILED_NOT_IN_BATTLEGROUND;
  4645. break;
  4646. default:
  4647. break;
  4648. }
  4649. }
  4650. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  4651. {
  4652. switch (m_spellInfo->Effects[i].ApplyAuraName)
  4653. {
  4654. case SPELL_AURA_MOD_POSSESS_PET:
  4655. {
  4656. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4657. return SPELL_FAILED_NO_PET;
  4658. Pet* pet = m_caster->ToPlayer()->GetPet();
  4659. if (!pet)
  4660. return SPELL_FAILED_NO_PET;
  4661. if (pet->GetCharmerGUID())
  4662. return SPELL_FAILED_CHARMED;
  4663. break;
  4664. }
  4665. case SPELL_AURA_MOD_POSSESS:
  4666. case SPELL_AURA_MOD_CHARM:
  4667. case SPELL_AURA_AOE_CHARM:
  4668. {
  4669. if (m_caster->GetCharmerGUID())
  4670. return SPELL_FAILED_CHARMED;
  4671. if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_CHARM
  4672. || m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
  4673. {
  4674. if (m_caster->GetPetGUID())
  4675. return SPELL_FAILED_ALREADY_HAVE_SUMMON;
  4676. if (m_caster->GetCharmGUID())
  4677. return SPELL_FAILED_ALREADY_HAVE_CHARM;
  4678. }
  4679. if (Unit* target = m_targets.GetUnitTarget())
  4680. {
  4681. if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
  4682. return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
  4683. if (target->IsMounted())
  4684. return SPELL_FAILED_CANT_BE_CHARMED;
  4685. if (target->GetCharmerGUID())
  4686. return SPELL_FAILED_CHARMED;
  4687. if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER)
  4688. return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED;
  4689. int32 damage = CalculateDamage(i, target);
  4690. if (damage && int32(target->getLevel()) > damage)
  4691. return SPELL_FAILED_HIGHLEVEL;
  4692. }
  4693. break;
  4694. }
  4695. case SPELL_AURA_MOUNTED:
  4696. {
  4697. if (m_caster->IsInWater())
  4698. return SPELL_FAILED_ONLY_ABOVEWATER;
  4699. // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
  4700. bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
  4701. InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
  4702. if (it)
  4703. allowMount = it->AllowMount;
  4704. if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
  4705. return SPELL_FAILED_NO_MOUNTS_ALLOWED;
  4706. if (m_caster->IsInDisallowedMountForm())
  4707. return SPELL_FAILED_NOT_SHAPESHIFT;
  4708. break;
  4709. }
  4710. case SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS:
  4711. {
  4712. if (!m_targets.GetUnitTarget())
  4713. return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
  4714. // can be cast at non-friendly unit or own pet/charm
  4715. if (m_caster->IsFriendlyTo(m_targets.GetUnitTarget()))
  4716. return SPELL_FAILED_TARGET_FRIENDLY;
  4717. break;
  4718. }
  4719. case SPELL_AURA_FLY:
  4720. case SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED:
  4721. {
  4722. // not allow cast fly spells if not have req. skills (all spells is self target)
  4723. // allow always ghost flight spells
  4724. if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->IsAlive())
  4725. {
  4726. Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
  4727. if (AreaTableEntry const* area = GetAreaEntryByAreaID(m_originalCaster->GetAreaId()))
  4728. if (area->flags & AREA_FLAG_NO_FLY_ZONE || (Bf && !Bf->CanFlyIn()))
  4729. return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE;
  4730. }
  4731. break;
  4732. }
  4733. case SPELL_AURA_PERIODIC_MANA_LEECH:
  4734. {
  4735. if (m_spellInfo->Effects[i].IsTargetingArea())
  4736. break;
  4737. if (!m_targets.GetUnitTarget())
  4738. return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
  4739. if (m_caster->GetTypeId() != TYPEID_PLAYER || m_CastItem)
  4740. break;
  4741. if (m_targets.GetUnitTarget()->getPowerType() != POWER_MANA)
  4742. return SPELL_FAILED_BAD_TARGETS;
  4743. break;
  4744. }
  4745. default:
  4746. break;
  4747. }
  4748. }
  4749. // check trade slot case (last, for allow catch any another cast problems)
  4750. if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM)
  4751. {
  4752. if (m_CastItem)
  4753. return SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW;
  4754. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  4755. return SPELL_FAILED_NOT_TRADING;
  4756. TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
  4757. if (!my_trade)
  4758. return SPELL_FAILED_NOT_TRADING;
  4759. // Item target guid contains trade slot until m_targets.UpdateTradeSlotItem() is called
  4760. TradeSlots slot = TradeSlots(m_targets.GetItemTargetGUID().GetRawValue());
  4761. if (slot != TRADE_SLOT_NONTRADED)
  4762. return SPELL_FAILED_BAD_TARGETS;
  4763. if (!IsTriggered())
  4764. if (my_trade->GetSpell())
  4765. return SPELL_FAILED_ITEM_ALREADY_ENCHANTED;
  4766. }
  4767. // check if caster has at least 1 combo point for spells that require combo points
  4768. if (m_needComboPoints)
  4769. if (Player* plrCaster = m_caster->ToPlayer())
  4770. if (!plrCaster->GetComboPoints())
  4771. return SPELL_FAILED_NO_COMBO_POINTS;
  4772. // all ok
  4773. return SPELL_CAST_OK;
  4774. }
  4775. SpellCastResult Spell::CheckPetCast(Unit* target)
  4776. {
  4777. if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
  4778. return SPELL_FAILED_SPELL_IN_PROGRESS;
  4779. // dead owner (pets still alive when owners ressed?)
  4780. if (Unit* owner = m_caster->GetCharmerOrOwner())
  4781. if (!owner->IsAlive())
  4782. return SPELL_FAILED_CASTER_DEAD;
  4783. if (!target && m_targets.GetUnitTarget())
  4784. target = m_targets.GetUnitTarget();
  4785. if (m_spellInfo->NeedsExplicitUnitTarget())
  4786. {
  4787. if (!target)
  4788. return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
  4789. m_targets.SetUnitTarget(target);
  4790. }
  4791. // cooldown
  4792. if (Creature const* creatureCaster = m_caster->ToCreature())
  4793. if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
  4794. return SPELL_FAILED_NOT_READY;
  4795. // Check if spell is affected by GCD
  4796. if (m_spellInfo->StartRecoveryCategory > 0)
  4797. if (m_caster->GetCharmInfo() && m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo))
  4798. return SPELL_FAILED_NOT_READY;
  4799. return CheckCast(true);
  4800. }
  4801. SpellCastResult Spell::CheckCasterAuras() const
  4802. {
  4803. // spells totally immuned to caster auras (wsg flag drop, give marks etc)
  4804. if (m_spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CASTER_AURAS)
  4805. return SPELL_CAST_OK;
  4806. uint8 school_immune = 0;
  4807. uint32 mechanic_immune = 0;
  4808. uint32 dispel_immune = 0;
  4809. // Check if the spell grants school or mechanic immunity.
  4810. // We use bitmasks so the loop is done only once and not on every aura check below.
  4811. if (m_spellInfo->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
  4812. {
  4813. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  4814. {
  4815. if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
  4816. school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
  4817. else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
  4818. mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
  4819. else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
  4820. dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
  4821. }
  4822. // immune movement impairment and loss of control
  4823. if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 19574)
  4824. mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
  4825. }
  4826. bool usableInStun = (m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_STUNNED) != 0;
  4827. // Glyph of Pain Suppression
  4828. // Allow Pain Suppression and Guardian Spirit to be cast while stunned
  4829. // there is no other way to handle it
  4830. if ((m_spellInfo->Id == 33206 || m_spellInfo->Id == 47788) && !m_caster->HasAura(63248))
  4831. usableInStun = false;
  4832. // Check whether the cast should be prevented by any state you might have.
  4833. SpellCastResult prevented_reason = SPELL_CAST_OK;
  4834. // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
  4835. uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state
  4836. if (unitflag & UNIT_FLAG_STUNNED)
  4837. {
  4838. // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
  4839. if (usableInStun)
  4840. {
  4841. bool foundNotStun = false;
  4842. Unit::AuraEffectList const& stunAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_STUN);
  4843. for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
  4844. {
  4845. if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & (1<<MECHANIC_STUN)))
  4846. {
  4847. foundNotStun = true;
  4848. break;
  4849. }
  4850. }
  4851. if (foundNotStun && m_spellInfo->Id != 22812)
  4852. prevented_reason = SPELL_FAILED_STUNNED;
  4853. }
  4854. else
  4855. prevented_reason = SPELL_FAILED_STUNNED;
  4856. }
  4857. else if (unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_CONFUSED))
  4858. prevented_reason = SPELL_FAILED_CONFUSED;
  4859. else if (unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_FEARED))
  4860. prevented_reason = SPELL_FAILED_FLEEING;
  4861. else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
  4862. prevented_reason = SPELL_FAILED_SILENCED;
  4863. else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY)
  4864. prevented_reason = SPELL_FAILED_PACIFIED;
  4865. // Attr must make flag drop spell totally immune from all effects
  4866. if (prevented_reason != SPELL_CAST_OK)
  4867. {
  4868. if (school_immune || mechanic_immune || dispel_immune)
  4869. {
  4870. //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
  4871. Unit::AuraApplicationMap const& auras = m_caster->GetAppliedAuras();
  4872. for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
  4873. {
  4874. Aura const* aura = itr->second->GetBase();
  4875. SpellInfo const* auraInfo = aura->GetSpellInfo();
  4876. if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
  4877. continue;
  4878. if (auraInfo->GetSchoolMask() & school_immune && !(auraInfo->AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE))
  4879. continue;
  4880. if (auraInfo->GetDispelMask() & dispel_immune)
  4881. continue;
  4882. //Make a second check for spell failed so the right SPELL_FAILED message is returned.
  4883. //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
  4884. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  4885. {
  4886. if (AuraEffect* part = aura->GetEffect(i))
  4887. {
  4888. switch (part->GetAuraType())
  4889. {
  4890. case SPELL_AURA_MOD_STUN:
  4891. if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & (1<<MECHANIC_STUN)))
  4892. return SPELL_FAILED_STUNNED;
  4893. break;
  4894. case SPELL_AURA_MOD_CONFUSE:
  4895. if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_CONFUSED))
  4896. return SPELL_FAILED_CONFUSED;
  4897. break;
  4898. case SPELL_AURA_MOD_FEAR:
  4899. if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_FEARED))
  4900. return SPELL_FAILED_FLEEING;
  4901. break;
  4902. case SPELL_AURA_MOD_SILENCE:
  4903. case SPELL_AURA_MOD_PACIFY:
  4904. case SPELL_AURA_MOD_PACIFY_SILENCE:
  4905. if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY)
  4906. return SPELL_FAILED_PACIFIED;
  4907. else if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
  4908. return SPELL_FAILED_SILENCED;
  4909. break;
  4910. default: break;
  4911. }
  4912. }
  4913. }
  4914. }
  4915. }
  4916. // You are prevented from casting and the spell cast does not grant immunity. Return a failed error.
  4917. else
  4918. return prevented_reason;
  4919. }
  4920. return SPELL_CAST_OK;
  4921. }
  4922. SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
  4923. {
  4924. bool isRatedBattleground = false; // NYI
  4925. bool isArena = !isRatedBattleground;
  4926. // check USABLE attributes
  4927. // USABLE takes precedence over NOT_USABLE
  4928. if (isRatedBattleground && m_spellInfo->AttributesEx9 & SPELL_ATTR9_USABLE_IN_RATED_BATTLEGROUNDS)
  4929. return SPELL_CAST_OK;
  4930. if (isArena && m_spellInfo->AttributesEx4 & SPELL_ATTR4_USABLE_IN_ARENA)
  4931. return SPELL_CAST_OK;
  4932. // check NOT_USABLE attributes
  4933. if (m_spellInfo->AttributesEx4 & SPELL_ATTR4_NOT_USABLE_IN_ARENA_OR_RATED_BG)
  4934. return isArena ? SPELL_FAILED_NOT_IN_ARENA : SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND;
  4935. if (isArena && m_spellInfo->AttributesEx9 & SPELL_ATTR9_NOT_USABLE_IN_ARENA)
  4936. return SPELL_FAILED_NOT_IN_ARENA;
  4937. // check cooldowns
  4938. uint32 spellCooldown = m_spellInfo->GetRecoveryTime();
  4939. if (isArena && spellCooldown > 10 * MINUTE * IN_MILLISECONDS) // not sure if still needed
  4940. return SPELL_FAILED_NOT_IN_ARENA;
  4941. if (isRatedBattleground && spellCooldown > 15 * MINUTE * IN_MILLISECONDS)
  4942. return SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND;
  4943. return SPELL_CAST_OK;
  4944. }
  4945. bool Spell::CanAutoCast(Unit* target)
  4946. {
  4947. ObjectGuid targetguid = target->GetGUID();
  4948. for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
  4949. {
  4950. if (m_spellInfo->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
  4951. {
  4952. if (m_spellInfo->StackAmount <= 1)
  4953. {
  4954. if (target->HasAuraEffect(m_spellInfo->Id, j))
  4955. return false;
  4956. }
  4957. else
  4958. {
  4959. if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
  4960. if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
  4961. return false;
  4962. }
  4963. }
  4964. else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
  4965. {
  4966. if (target->HasAuraEffect(m_spellInfo->Id, j))
  4967. return false;
  4968. }
  4969. }
  4970. SpellCastResult result = CheckPetCast(target);
  4971. if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
  4972. {
  4973. SelectSpellTargets();
  4974. //check if among target units, our WANTED target is as well (->only self cast spells return false)
  4975. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  4976. if (ihit->targetGUID == targetguid)
  4977. return true;
  4978. }
  4979. return false; //target invalid
  4980. }
  4981. SpellCastResult Spell::CheckRange(bool strict)
  4982. {
  4983. // Don't check for instant cast spells
  4984. if (!strict && m_casttime == 0)
  4985. return SPELL_CAST_OK;
  4986. uint32 range_type = 0;
  4987. if (m_spellInfo->RangeEntry)
  4988. {
  4989. // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
  4990. // these are triggered by other spells - possibly we should omit range check in that case?
  4991. if (m_spellInfo->RangeEntry->ID == 1)
  4992. return SPELL_CAST_OK;
  4993. range_type = m_spellInfo->RangeEntry->type;
  4994. }
  4995. Unit* target = m_targets.GetUnitTarget();
  4996. float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
  4997. float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
  4998. if (Player* modOwner = m_caster->GetSpellModOwner())
  4999. modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
  5000. if (target && target != m_caster)
  5001. {
  5002. if (range_type == SPELL_RANGE_MELEE)
  5003. {
  5004. // Because of lag, we can not check too strictly here.
  5005. if (!m_caster->IsWithinMeleeRange(target, max_range))
  5006. return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
  5007. }
  5008. else if (!m_caster->IsWithinCombatRange(target, max_range))
  5009. return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; //0x5A;
  5010. if (range_type == SPELL_RANGE_RANGED)
  5011. {
  5012. if (m_caster->IsWithinMeleeRange(target))
  5013. return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
  5014. }
  5015. else if (min_range && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
  5016. return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
  5017. if (m_caster->GetTypeId() == TYPEID_PLAYER &&
  5018. (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
  5019. return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_UNIT_NOT_INFRONT : SPELL_FAILED_DONT_REPORT;
  5020. }
  5021. if (m_targets.HasDst() && !m_targets.HasTraj())
  5022. {
  5023. if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
  5024. return SPELL_FAILED_OUT_OF_RANGE;
  5025. if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
  5026. return SPELL_FAILED_TOO_CLOSE;
  5027. }
  5028. return SPELL_CAST_OK;
  5029. }
  5030. SpellCastResult Spell::CheckPower()
  5031. {
  5032. // item cast not used power
  5033. if (m_CastItem)
  5034. return SPELL_CAST_OK;
  5035. // health as power used - need check health amount
  5036. if (m_spellInfo->PowerType == POWER_HEALTH)
  5037. {
  5038. if (int32(m_caster->GetHealth()) <= m_powerCost)
  5039. return SPELL_FAILED_CASTER_AURASTATE;
  5040. return SPELL_CAST_OK;
  5041. }
  5042. // Check valid power type
  5043. if (m_spellInfo->PowerType >= MAX_POWERS)
  5044. {
  5045. TC_LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '%d'", m_spellInfo->PowerType);
  5046. return SPELL_FAILED_UNKNOWN;
  5047. }
  5048. //check rune cost only if a spell has PowerType == POWER_RUNES
  5049. if (m_spellInfo->PowerType == POWER_RUNES)
  5050. {
  5051. SpellCastResult failReason = CheckRuneCost(m_spellInfo->RuneCostID);
  5052. if (failReason != SPELL_CAST_OK)
  5053. return failReason;
  5054. }
  5055. // Check power amount
  5056. Powers powerType = Powers(m_spellInfo->PowerType);
  5057. if (int32(m_caster->GetPower(powerType)) < m_powerCost)
  5058. return SPELL_FAILED_NO_POWER;
  5059. else
  5060. return SPELL_CAST_OK;
  5061. }
  5062. SpellCastResult Spell::CheckItems()
  5063. {
  5064. Player* player = m_caster->ToPlayer();
  5065. if (!player)
  5066. return SPELL_CAST_OK;
  5067. if (!m_CastItem)
  5068. {
  5069. if (m_castItemGUID)
  5070. return SPELL_FAILED_ITEM_NOT_READY;
  5071. }
  5072. else
  5073. {
  5074. uint32 itemid = m_CastItem->GetEntry();
  5075. if (!player->HasItemCount(itemid))
  5076. return SPELL_FAILED_ITEM_NOT_READY;
  5077. ItemTemplate const* proto = m_CastItem->GetTemplate();
  5078. if (!proto)
  5079. return SPELL_FAILED_ITEM_NOT_READY;
  5080. for (uint8 i = 0; i < MAX_ITEM_SPELLS; ++i)
  5081. if (proto->Spells[i].SpellCharges)
  5082. if (m_CastItem->GetSpellCharges(i) == 0)
  5083. return SPELL_FAILED_NO_CHARGES_REMAIN;
  5084. // consumable cast item checks
  5085. if (proto->Class == ITEM_CLASS_CONSUMABLE && m_targets.GetUnitTarget())
  5086. {
  5087. // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
  5088. SpellCastResult failReason = SPELL_CAST_OK;
  5089. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5090. {
  5091. // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
  5092. if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
  5093. continue;
  5094. if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
  5095. {
  5096. if (m_targets.GetUnitTarget()->IsFullHealth())
  5097. {
  5098. failReason = SPELL_FAILED_ALREADY_AT_FULL_HEALTH;
  5099. continue;
  5100. }
  5101. else
  5102. {
  5103. failReason = SPELL_CAST_OK;
  5104. break;
  5105. }
  5106. }
  5107. // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
  5108. if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
  5109. {
  5110. if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
  5111. {
  5112. failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
  5113. continue;
  5114. }
  5115. Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
  5116. if (m_targets.GetUnitTarget()->GetPower(power) == m_targets.GetUnitTarget()->GetMaxPower(power))
  5117. {
  5118. failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
  5119. continue;
  5120. }
  5121. else
  5122. {
  5123. failReason = SPELL_CAST_OK;
  5124. break;
  5125. }
  5126. }
  5127. }
  5128. if (failReason != SPELL_CAST_OK)
  5129. return failReason;
  5130. }
  5131. }
  5132. // check target item
  5133. if (m_targets.GetItemTargetGUID())
  5134. {
  5135. if (!m_targets.GetItemTarget())
  5136. return SPELL_FAILED_ITEM_GONE;
  5137. if (!m_targets.GetItemTarget()->IsFitToSpellRequirements(m_spellInfo))
  5138. return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5139. }
  5140. // if not item target then required item must be equipped
  5141. else
  5142. {
  5143. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
  5144. if (!player->HasItemFitToSpellRequirements(m_spellInfo))
  5145. return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5146. }
  5147. // do not take reagents for these item casts
  5148. if (!(m_CastItem && m_CastItem->GetTemplate()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST))
  5149. {
  5150. bool checkReagents = !(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST) && !player->CanNoReagentCast(m_spellInfo);
  5151. // Not own traded item (in trader trade slot) requires reagents even if triggered spell
  5152. if (!checkReagents)
  5153. if (Item* targetItem = m_targets.GetItemTarget())
  5154. if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
  5155. checkReagents = true;
  5156. // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
  5157. if (checkReagents)
  5158. {
  5159. for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
  5160. {
  5161. if (m_spellInfo->Reagent[i] <= 0)
  5162. continue;
  5163. uint32 itemid = m_spellInfo->Reagent[i];
  5164. uint32 itemcount = m_spellInfo->ReagentCount[i];
  5165. // if CastItem is also spell reagent
  5166. if (m_CastItem && m_CastItem->GetEntry() == itemid)
  5167. {
  5168. ItemTemplate const* proto = m_CastItem->GetTemplate();
  5169. if (!proto)
  5170. return SPELL_FAILED_ITEM_NOT_READY;
  5171. for (uint8 s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
  5172. {
  5173. // CastItem will be used up and does not count as reagent
  5174. int32 charges = m_CastItem->GetSpellCharges(s);
  5175. if (proto->Spells[s].SpellCharges < 0 && abs(charges) < 2)
  5176. {
  5177. ++itemcount;
  5178. break;
  5179. }
  5180. }
  5181. }
  5182. if (!player->HasItemCount(itemid, itemcount))
  5183. return SPELL_FAILED_REAGENTS;
  5184. }
  5185. }
  5186. // check totem-item requirements (items presence in inventory)
  5187. uint32 totems = 2;
  5188. for (uint8 i = 0; i < 2; ++i)
  5189. {
  5190. if (m_spellInfo->Totem[i] != 0)
  5191. {
  5192. if (player->HasItemCount(m_spellInfo->Totem[i]))
  5193. {
  5194. totems -= 1;
  5195. continue;
  5196. }
  5197. }
  5198. else
  5199. totems -= 1;
  5200. }
  5201. if (totems != 0)
  5202. return SPELL_FAILED_TOTEMS;
  5203. }
  5204. // special checks for spell effects
  5205. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5206. {
  5207. switch (m_spellInfo->Effects[i].Effect)
  5208. {
  5209. case SPELL_EFFECT_CREATE_ITEM:
  5210. case SPELL_EFFECT_CREATE_ITEM_2:
  5211. {
  5212. if (!IsTriggered() && m_spellInfo->Effects[i].ItemType)
  5213. {
  5214. ItemPosCountVec dest;
  5215. InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
  5216. if (msg != EQUIP_ERR_OK)
  5217. {
  5218. ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
  5219. /// @todo Needs review
  5220. if (pProto && !(pProto->ItemLimitCategory))
  5221. {
  5222. player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType);
  5223. return SPELL_FAILED_DONT_REPORT;
  5224. }
  5225. else
  5226. {
  5227. if (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (m_spellInfo->SpellFamilyFlags[0] & 0x40000000)))
  5228. return SPELL_FAILED_TOO_MANY_OF_ITEM;
  5229. else if (!(player->HasItemCount(m_spellInfo->Effects[i].ItemType)))
  5230. return SPELL_FAILED_TOO_MANY_OF_ITEM;
  5231. else
  5232. player->CastSpell(m_caster, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
  5233. return SPELL_FAILED_DONT_REPORT;
  5234. }
  5235. }
  5236. }
  5237. break;
  5238. }
  5239. case SPELL_EFFECT_ENCHANT_ITEM:
  5240. if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
  5241. && (m_targets.GetItemTarget()->IsVellum()))
  5242. {
  5243. // cannot enchant vellum for other player
  5244. if (m_targets.GetItemTarget()->GetOwner() != m_caster)
  5245. return SPELL_FAILED_NOT_TRADEABLE;
  5246. // do not allow to enchant vellum from scroll made by vellum-prevent exploit
  5247. if (m_CastItem && m_CastItem->GetTemplate()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)
  5248. return SPELL_FAILED_TOTEM_CATEGORY;
  5249. ItemPosCountVec dest;
  5250. InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
  5251. if (msg != EQUIP_ERR_OK)
  5252. {
  5253. player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType);
  5254. return SPELL_FAILED_DONT_REPORT;
  5255. }
  5256. }
  5257. // no break
  5258. case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC:
  5259. {
  5260. Item* targetItem = m_targets.GetItemTarget();
  5261. if (!targetItem)
  5262. return SPELL_FAILED_ITEM_NOT_FOUND;
  5263. if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel)
  5264. return SPELL_FAILED_LOWLEVEL;
  5265. bool isItemUsable = false;
  5266. for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
  5267. {
  5268. ItemTemplate const* proto = targetItem->GetTemplate();
  5269. if (proto->Spells[e].SpellId && (
  5270. proto->Spells[e].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE ||
  5271. proto->Spells[e].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE))
  5272. {
  5273. isItemUsable = true;
  5274. break;
  5275. }
  5276. }
  5277. SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
  5278. // do not allow adding usable enchantments to items that have use effect already
  5279. if (enchantEntry)
  5280. {
  5281. for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s)
  5282. {
  5283. switch (enchantEntry->type[s])
  5284. {
  5285. case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
  5286. if (isItemUsable)
  5287. return SPELL_FAILED_ON_USE_ENCHANT;
  5288. break;
  5289. case ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET:
  5290. {
  5291. uint32 numSockets = 0;
  5292. for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
  5293. if (targetItem->GetTemplate()->Socket[socket].Color)
  5294. ++numSockets;
  5295. if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
  5296. return SPELL_FAILED_MAX_SOCKETS;
  5297. break;
  5298. }
  5299. }
  5300. }
  5301. }
  5302. // Not allow enchant in trade slot for some enchant type
  5303. if (targetItem->GetOwner() != m_caster)
  5304. {
  5305. if (!enchantEntry)
  5306. return SPELL_FAILED_ERROR;
  5307. if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
  5308. return SPELL_FAILED_NOT_TRADEABLE;
  5309. }
  5310. break;
  5311. }
  5312. case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
  5313. {
  5314. Item* item = m_targets.GetItemTarget();
  5315. if (!item)
  5316. return SPELL_FAILED_ITEM_NOT_FOUND;
  5317. // Not allow enchant in trade slot for some enchant type
  5318. if (item->GetOwner() != m_caster)
  5319. {
  5320. uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
  5321. SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
  5322. if (!pEnchant)
  5323. return SPELL_FAILED_ERROR;
  5324. if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
  5325. return SPELL_FAILED_NOT_TRADEABLE;
  5326. }
  5327. break;
  5328. }
  5329. case SPELL_EFFECT_ENCHANT_HELD_ITEM:
  5330. // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
  5331. break;
  5332. case SPELL_EFFECT_DISENCHANT:
  5333. {
  5334. if (!m_targets.GetItemTarget())
  5335. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5336. // prevent disenchanting in trade slot
  5337. if (m_targets.GetItemTarget()->GetOwnerGUID() != m_caster->GetGUID())
  5338. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5339. ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
  5340. if (!itemProto)
  5341. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5342. uint32 item_quality = itemProto->Quality;
  5343. // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
  5344. uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
  5345. if (item_disenchantskilllevel == uint32(-1))
  5346. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5347. if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
  5348. return SPELL_FAILED_LOW_CASTLEVEL;
  5349. if (item_quality > 4 || item_quality < 2)
  5350. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5351. if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
  5352. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5353. if (!itemProto->DisenchantID)
  5354. return SPELL_FAILED_CANT_BE_DISENCHANTED;
  5355. break;
  5356. }
  5357. case SPELL_EFFECT_PROSPECTING:
  5358. {
  5359. if (!m_targets.GetItemTarget())
  5360. return SPELL_FAILED_CANT_BE_PROSPECTED;
  5361. //ensure item is a prospectable ore
  5362. if (!(m_targets.GetItemTarget()->GetTemplate()->Flags & ITEM_PROTO_FLAG_PROSPECTABLE))
  5363. return SPELL_FAILED_CANT_BE_PROSPECTED;
  5364. //prevent prospecting in trade slot
  5365. if (m_targets.GetItemTarget()->GetOwnerGUID() != m_caster->GetGUID())
  5366. return SPELL_FAILED_CANT_BE_PROSPECTED;
  5367. //Check for enough skill in jewelcrafting
  5368. uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
  5369. if (item_prospectingskilllevel >player->GetSkillValue(SKILL_JEWELCRAFTING))
  5370. return SPELL_FAILED_LOW_CASTLEVEL;
  5371. //make sure the player has the required ores in inventory
  5372. if (m_targets.GetItemTarget()->GetCount() < 5)
  5373. return SPELL_FAILED_NEED_MORE_ITEMS;
  5374. if (!LootTemplates_Prospecting.HaveLootFor(m_targets.GetItemTargetEntry()))
  5375. return SPELL_FAILED_CANT_BE_PROSPECTED;
  5376. break;
  5377. }
  5378. case SPELL_EFFECT_MILLING:
  5379. {
  5380. if (!m_targets.GetItemTarget())
  5381. return SPELL_FAILED_CANT_BE_MILLED;
  5382. //ensure item is a millable herb
  5383. if (!(m_targets.GetItemTarget()->GetTemplate()->Flags & ITEM_PROTO_FLAG_MILLABLE))
  5384. return SPELL_FAILED_CANT_BE_MILLED;
  5385. //prevent milling in trade slot
  5386. if (m_targets.GetItemTarget()->GetOwnerGUID() != m_caster->GetGUID())
  5387. return SPELL_FAILED_CANT_BE_MILLED;
  5388. //Check for enough skill in inscription
  5389. uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
  5390. if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
  5391. return SPELL_FAILED_LOW_CASTLEVEL;
  5392. //make sure the player has the required herbs in inventory
  5393. if (m_targets.GetItemTarget()->GetCount() < 5)
  5394. return SPELL_FAILED_NEED_MORE_ITEMS;
  5395. if (!LootTemplates_Milling.HaveLootFor(m_targets.GetItemTargetEntry()))
  5396. return SPELL_FAILED_CANT_BE_MILLED;
  5397. break;
  5398. }
  5399. case SPELL_EFFECT_WEAPON_DAMAGE:
  5400. case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
  5401. {
  5402. if (m_attackType != RANGED_ATTACK)
  5403. break;
  5404. Item* pItem = player->GetWeaponForAttack(m_attackType);
  5405. if (!pItem || pItem->IsBroken())
  5406. return SPELL_FAILED_EQUIPPED_ITEM;
  5407. switch (pItem->GetTemplate()->SubClass)
  5408. {
  5409. case ITEM_SUBCLASS_WEAPON_THROWN:
  5410. {
  5411. uint32 ammo = pItem->GetEntry();
  5412. if (!player->HasItemCount(ammo))
  5413. return SPELL_FAILED_NO_AMMO;
  5414. break;
  5415. }
  5416. case ITEM_SUBCLASS_WEAPON_GUN:
  5417. case ITEM_SUBCLASS_WEAPON_BOW:
  5418. case ITEM_SUBCLASS_WEAPON_CROSSBOW:
  5419. case ITEM_SUBCLASS_WEAPON_WAND:
  5420. break;
  5421. default:
  5422. break;
  5423. }
  5424. break;
  5425. }
  5426. case SPELL_EFFECT_CREATE_MANA_GEM:
  5427. {
  5428. uint32 item_id = m_spellInfo->Effects[i].ItemType;
  5429. ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
  5430. if (!pProto)
  5431. return SPELL_FAILED_ITEM_AT_MAX_CHARGES;
  5432. if (Item* pitem = player->GetItemByEntry(item_id))
  5433. {
  5434. for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
  5435. if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
  5436. return SPELL_FAILED_ITEM_AT_MAX_CHARGES;
  5437. }
  5438. break;
  5439. }
  5440. default:
  5441. break;
  5442. }
  5443. }
  5444. // check weapon presence in slots for main/offhand weapons
  5445. if (!(_triggeredCastFlags & TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) && m_spellInfo->EquippedItemClass >=0)
  5446. {
  5447. // main hand weapon required
  5448. if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_MAIN_HAND)
  5449. {
  5450. Item* item = m_caster->ToPlayer()->GetWeaponForAttack(BASE_ATTACK);
  5451. // skip spell if no weapon in slot or broken
  5452. if (!item || item->IsBroken())
  5453. return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5454. // skip spell if weapon not fit to triggered spell
  5455. if (!item->IsFitToSpellRequirements(m_spellInfo))
  5456. return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5457. }
  5458. // offhand hand weapon required
  5459. if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND)
  5460. {
  5461. Item* item = m_caster->ToPlayer()->GetWeaponForAttack(OFF_ATTACK);
  5462. // skip spell if no weapon in slot or broken
  5463. if (!item || item->IsBroken())
  5464. return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5465. // skip spell if weapon not fit to triggered spell
  5466. if (!item->IsFitToSpellRequirements(m_spellInfo))
  5467. return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_EQUIPPED_ITEM_CLASS;
  5468. }
  5469. }
  5470. return SPELL_CAST_OK;
  5471. }
  5472. void Spell::Delayed() // only called in DealDamage()
  5473. {
  5474. if (!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER)
  5475. return;
  5476. //if (m_spellState == SPELL_STATE_DELAYED)
  5477. // return; // spell is active and can't be time-backed
  5478. if (isDelayableNoMore()) // Spells may only be delayed twice
  5479. return;
  5480. // spells not loosing casting time (slam, dynamites, bombs..)
  5481. //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
  5482. // return;
  5483. //check pushback reduce
  5484. int32 delaytime = 500; // spellcasting delay is normally 500ms
  5485. int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
  5486. m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
  5487. delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
  5488. if (delayReduce >= 100)
  5489. return;
  5490. AddPct(delaytime, -delayReduce);
  5491. if (m_timer + delaytime > m_casttime)
  5492. {
  5493. delaytime = m_casttime - m_timer;
  5494. m_timer = m_casttime;
  5495. }
  5496. else
  5497. m_timer += delaytime;
  5498. TC_LOG_INFO("spells", "Spell %u partially interrupted for (%d) ms at damage", m_spellInfo->Id, delaytime);
  5499. WorldPacket data(SMSG_SPELL_DELAYED, 8+4);
  5500. data << m_caster->GetPackGUID();
  5501. data << uint32(delaytime);
  5502. m_caster->SendMessageToSet(&data, true);
  5503. }
  5504. void Spell::DelayedChannel()
  5505. {
  5506. if (!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER || getState() != SPELL_STATE_CASTING)
  5507. return;
  5508. if (isDelayableNoMore()) // Spells may only be delayed twice
  5509. return;
  5510. //check pushback reduce
  5511. // should be affected by modifiers, not take the dbc duration.
  5512. int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
  5513. int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
  5514. int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
  5515. m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
  5516. delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
  5517. if (delayReduce >= 100)
  5518. return;
  5519. AddPct(delaytime, -delayReduce);
  5520. if (m_timer <= delaytime)
  5521. {
  5522. delaytime = m_timer;
  5523. m_timer = 0;
  5524. }
  5525. else
  5526. m_timer -= delaytime;
  5527. TC_LOG_DEBUG("spells", "Spell %u partially interrupted for %i ms, new duration: %u ms", m_spellInfo->Id, delaytime, m_timer);
  5528. for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  5529. if ((*ihit).missCondition == SPELL_MISS_NONE)
  5530. if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
  5531. unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
  5532. // partially interrupt persistent area auras
  5533. if (DynamicObject* dynObj = m_caster->GetDynObject(m_spellInfo->Id))
  5534. dynObj->Delay(delaytime);
  5535. SendChannelUpdate(m_timer);
  5536. }
  5537. bool Spell::UpdatePointers()
  5538. {
  5539. if (m_originalCasterGUID == m_caster->GetGUID())
  5540. m_originalCaster = m_caster;
  5541. else
  5542. {
  5543. m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
  5544. if (m_originalCaster && !m_originalCaster->IsInWorld())
  5545. m_originalCaster = NULL;
  5546. }
  5547. if (m_castItemGUID && m_caster->GetTypeId() == TYPEID_PLAYER)
  5548. {
  5549. m_CastItem = m_caster->ToPlayer()->GetItemByGuid(m_castItemGUID);
  5550. // cast item not found, somehow the item is no longer where we expected
  5551. if (!m_CastItem)
  5552. return false;
  5553. // check if the item is really the same, in case it has been wrapped for example
  5554. if (m_castItemEntry != m_CastItem->GetEntry())
  5555. return false;
  5556. }
  5557. m_targets.Update(m_caster);
  5558. // further actions done only for dest targets
  5559. if (!m_targets.HasDst())
  5560. return true;
  5561. // cache last transport
  5562. WorldObject* transport = NULL;
  5563. // update effect destinations (in case of moved transport dest target)
  5564. for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
  5565. {
  5566. SpellDestination& dest = m_destTargets[effIndex];
  5567. if (!dest._transportGUID)
  5568. continue;
  5569. if (!transport || transport->GetGUID() != dest._transportGUID)
  5570. transport = ObjectAccessor::GetWorldObject(*m_caster, dest._transportGUID);
  5571. if (transport)
  5572. {
  5573. dest._position.Relocate(transport);
  5574. dest._position.RelocateOffset(dest._transportOffset);
  5575. }
  5576. }
  5577. return true;
  5578. }
  5579. CurrentSpellTypes Spell::GetCurrentContainer() const
  5580. {
  5581. if (IsNextMeleeSwingSpell())
  5582. return(CURRENT_MELEE_SPELL);
  5583. else if (IsAutoRepeat())
  5584. return(CURRENT_AUTOREPEAT_SPELL);
  5585. else if (m_spellInfo->IsChanneled())
  5586. return(CURRENT_CHANNELED_SPELL);
  5587. else
  5588. return(CURRENT_GENERIC_SPELL);
  5589. }
  5590. bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const
  5591. {
  5592. switch (m_spellInfo->Effects[eff].ApplyAuraName)
  5593. {
  5594. case SPELL_AURA_MOD_POSSESS:
  5595. case SPELL_AURA_MOD_CHARM:
  5596. case SPELL_AURA_MOD_POSSESS_PET:
  5597. case SPELL_AURA_AOE_CHARM:
  5598. if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle())
  5599. return false;
  5600. if (target->IsMounted())
  5601. return false;
  5602. if (target->GetCharmerGUID())
  5603. return false;
  5604. if (int32 damage = CalculateDamage(eff, target))
  5605. if ((int32)target->getLevel() > damage)
  5606. return false;
  5607. break;
  5608. default:
  5609. break;
  5610. }
  5611. // check for ignore LOS on the effect itself
  5612. if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS))
  5613. return true;
  5614. // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
  5615. if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, NULL, SPELL_DISABLE_LOS)))
  5616. return true;
  5617. /// @todo shit below shouldn't be here, but it's temporary
  5618. //Check targets for LOS visibility (except spells without range limitations)
  5619. switch (m_spellInfo->Effects[eff].Effect)
  5620. {
  5621. case SPELL_EFFECT_RESURRECT_NEW:
  5622. // player far away, maybe his corpse near?
  5623. if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
  5624. {
  5625. if (!m_targets.GetCorpseTargetGUID())
  5626. return false;
  5627. Corpse* corpse = ObjectAccessor::GetCorpse(*m_caster, m_targets.GetCorpseTargetGUID());
  5628. if (!corpse)
  5629. return false;
  5630. if (target->GetGUID() != corpse->GetOwnerGUID())
  5631. return false;
  5632. if (!corpse->IsWithinLOSInMap(m_caster))
  5633. return false;
  5634. }
  5635. // all ok by some way or another, skip normal check
  5636. break;
  5637. default: // normal case
  5638. {
  5639. if (losPosition)
  5640. return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ());
  5641. else
  5642. {
  5643. // Get GO cast coordinates if original caster -> GO
  5644. WorldObject* caster = NULL;
  5645. if (m_originalCasterGUID.IsGameObject())
  5646. caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
  5647. if (!caster)
  5648. caster = m_caster;
  5649. if (target != m_caster && !target->IsWithinLOSInMap(caster))
  5650. return false;
  5651. }
  5652. break;
  5653. }
  5654. }
  5655. return true;
  5656. }
  5657. bool Spell::IsNextMeleeSwingSpell() const
  5658. {
  5659. return (m_spellInfo->Attributes & SPELL_ATTR0_ON_NEXT_SWING) != 0;
  5660. }
  5661. bool Spell::IsAutoActionResetSpell() const
  5662. {
  5663. /// @todo changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
  5664. return !IsTriggered() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT);
  5665. }
  5666. bool Spell::IsNeedSendToClient() const
  5667. {
  5668. return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() ||
  5669. (m_spellInfo->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT) || m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered());
  5670. }
  5671. bool Spell::HaveTargetsForEffect(uint8 effect) const
  5672. {
  5673. for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
  5674. if (itr->effectMask & (1 << effect))
  5675. return true;
  5676. for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
  5677. if (itr->effectMask & (1 << effect))
  5678. return true;
  5679. for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
  5680. if (itr->effectMask & (1 << effect))
  5681. return true;
  5682. return false;
  5683. }
  5684. SpellEvent::SpellEvent(Spell* spell) : BasicEvent()
  5685. {
  5686. m_Spell = spell;
  5687. }
  5688. SpellEvent::~SpellEvent()
  5689. {
  5690. if (m_Spell->getState() != SPELL_STATE_FINISHED)
  5691. m_Spell->cancel();
  5692. if (m_Spell->IsDeletable())
  5693. {
  5694. delete m_Spell;
  5695. }
  5696. else
  5697. {
  5698. TC_LOG_ERROR("spells", "~SpellEvent: %s %u tried to delete non-deletable spell %u. Was not deleted, causes memory leak.",
  5699. (m_Spell->GetCaster()->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), m_Spell->GetCaster()->GetGUIDLow(), m_Spell->m_spellInfo->Id);
  5700. ASSERT(false);
  5701. }
  5702. }
  5703. bool SpellEvent::Execute(uint64 e_time, uint32 p_time)
  5704. {
  5705. // update spell if it is not finished
  5706. if (m_Spell->getState() != SPELL_STATE_FINISHED)
  5707. m_Spell->update(p_time);
  5708. // check spell state to process
  5709. switch (m_Spell->getState())
  5710. {
  5711. case SPELL_STATE_FINISHED:
  5712. {
  5713. // spell was finished, check deletable state
  5714. if (m_Spell->IsDeletable())
  5715. {
  5716. // check, if we do have unfinished triggered spells
  5717. return true; // spell is deletable, finish event
  5718. }
  5719. // event will be re-added automatically at the end of routine)
  5720. } break;
  5721. case SPELL_STATE_DELAYED:
  5722. {
  5723. // first, check, if we have just started
  5724. if (m_Spell->GetDelayStart() != 0)
  5725. {
  5726. // no, we aren't, do the typical update
  5727. // check, if we have channeled spell on our hands
  5728. /*
  5729. if (m_Spell->m_spellInfo->IsChanneled())
  5730. {
  5731. // evented channeled spell is processed separately, cast once after delay, and not destroyed till finish
  5732. // check, if we have casting anything else except this channeled spell and autorepeat
  5733. if (m_Spell->GetCaster()->IsNonMeleeSpellCast(false, true, true))
  5734. {
  5735. // another non-melee non-delayed spell is cast now, abort
  5736. m_Spell->cancel();
  5737. }
  5738. else
  5739. {
  5740. // Set last not triggered spell for apply spellmods
  5741. ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, true);
  5742. // do the action (pass spell to channeling state)
  5743. m_Spell->handle_immediate();
  5744. // And remove after effect handling
  5745. ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, false);
  5746. }
  5747. // event will be re-added automatically at the end of routine)
  5748. }
  5749. else
  5750. */
  5751. {
  5752. // run the spell handler and think about what we can do next
  5753. uint64 t_offset = e_time - m_Spell->GetDelayStart();
  5754. uint64 n_offset = m_Spell->handle_delayed(t_offset);
  5755. if (n_offset)
  5756. {
  5757. // re-add us to the queue
  5758. m_Spell->GetCaster()->m_Events.AddEvent(this, m_Spell->GetDelayStart() + n_offset, false);
  5759. return false; // event not complete
  5760. }
  5761. // event complete
  5762. // finish update event will be re-added automatically at the end of routine)
  5763. }
  5764. }
  5765. else
  5766. {
  5767. // delaying had just started, record the moment
  5768. m_Spell->SetDelayStart(e_time);
  5769. // re-plan the event for the delay moment
  5770. m_Spell->GetCaster()->m_Events.AddEvent(this, e_time + m_Spell->GetDelayMoment(), false);
  5771. return false; // event not complete
  5772. }
  5773. } break;
  5774. default:
  5775. {
  5776. // all other states
  5777. // event will be re-added automatically at the end of routine)
  5778. } break;
  5779. }
  5780. // spell processing not complete, plan event on the next update interval
  5781. m_Spell->GetCaster()->m_Events.AddEvent(this, e_time + 1, false);
  5782. return false; // event not complete
  5783. }
  5784. void SpellEvent::Abort(uint64 /*e_time*/)
  5785. {
  5786. // oops, the spell we try to do is aborted
  5787. if (m_Spell->getState() != SPELL_STATE_FINISHED)
  5788. m_Spell->cancel();
  5789. }
  5790. bool SpellEvent::IsDeletable() const
  5791. {
  5792. return m_Spell->IsDeletable();
  5793. }
  5794. bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const
  5795. {
  5796. if (target->IsAlive())
  5797. return !m_spellInfo->IsRequiringDeadTarget();
  5798. if (m_spellInfo->IsAllowingDeadTarget())
  5799. return true;
  5800. return false;
  5801. }
  5802. void Spell::HandleLaunchPhase()
  5803. {
  5804. // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
  5805. for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5806. {
  5807. // don't do anything for empty effect
  5808. if (!m_spellInfo->Effects[i].IsEffect())
  5809. continue;
  5810. HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH);
  5811. }
  5812. float multiplier[MAX_SPELL_EFFECTS];
  5813. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5814. if (m_applyMultiplierMask & (1 << i))
  5815. multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
  5816. bool usesAmmo = (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) != 0;
  5817. for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
  5818. {
  5819. TargetInfo& target = *ihit;
  5820. uint32 mask = target.effectMask;
  5821. if (!mask)
  5822. continue;
  5823. // do not consume ammo anymore for Hunter's volley spell
  5824. if (IsTriggered() && m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->IsTargetingArea())
  5825. usesAmmo = false;
  5826. if (usesAmmo)
  5827. {
  5828. bool ammoTaken = false;
  5829. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
  5830. {
  5831. if (!(mask & 1<<i))
  5832. continue;
  5833. switch (m_spellInfo->Effects[i].Effect)
  5834. {
  5835. case SPELL_EFFECT_SCHOOL_DAMAGE:
  5836. case SPELL_EFFECT_WEAPON_DAMAGE:
  5837. case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
  5838. case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
  5839. case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
  5840. ammoTaken=true;
  5841. TakeAmmo();
  5842. }
  5843. if (ammoTaken)
  5844. break;
  5845. }
  5846. }
  5847. DoAllEffectOnLaunchTarget(target, multiplier);
  5848. }
  5849. }
  5850. void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
  5851. {
  5852. Unit* unit = NULL;
  5853. // In case spell hit target, do all effect on that target
  5854. if (targetInfo.missCondition == SPELL_MISS_NONE)
  5855. unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
  5856. // In case spell reflect from target, do all effect on caster (if hit)
  5857. else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
  5858. unit = m_caster;
  5859. if (!unit)
  5860. return;
  5861. for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5862. {
  5863. if (targetInfo.effectMask & (1<<i))
  5864. {
  5865. m_damage = 0;
  5866. m_healing = 0;
  5867. HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
  5868. if (m_damage > 0)
  5869. {
  5870. if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
  5871. {
  5872. m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
  5873. if (m_caster->GetTypeId() != TYPEID_PLAYER)
  5874. m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
  5875. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  5876. {
  5877. uint32 targetAmount = m_UniqueTargetInfo.size();
  5878. if (targetAmount > 10)
  5879. m_damage = m_damage * 10/targetAmount;
  5880. }
  5881. }
  5882. }
  5883. if (m_applyMultiplierMask & (1 << i))
  5884. {
  5885. m_damage = int32(m_damage * m_damageMultipliers[i]);
  5886. m_damageMultipliers[i] *= multiplier[i];
  5887. }
  5888. targetInfo.damage += m_damage;
  5889. }
  5890. }
  5891. targetInfo.crit = m_caster->IsSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
  5892. }
  5893. SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
  5894. {
  5895. if (!lockId) // possible case for GO and maybe for items.
  5896. return SPELL_CAST_OK;
  5897. // Get LockInfo
  5898. LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
  5899. if (!lockInfo)
  5900. return SPELL_FAILED_BAD_TARGETS;
  5901. bool reqKey = false; // some locks not have reqs
  5902. for (int j = 0; j < MAX_LOCK_CASE; ++j)
  5903. {
  5904. switch (lockInfo->Type[j])
  5905. {
  5906. // check key item (many fit cases can be)
  5907. case LOCK_KEY_ITEM:
  5908. if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
  5909. return SPELL_CAST_OK;
  5910. reqKey = true;
  5911. break;
  5912. // check key skill (only single first fit case can be)
  5913. case LOCK_KEY_SKILL:
  5914. {
  5915. reqKey = true;
  5916. // wrong locktype, skip
  5917. if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
  5918. continue;
  5919. skillId = SkillByLockType(LockType(lockInfo->Index[j]));
  5920. if (skillId != SKILL_NONE)
  5921. {
  5922. reqSkillValue = lockInfo->Skill[j];
  5923. // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
  5924. skillValue = m_CastItem || m_caster->GetTypeId()!= TYPEID_PLAYER ?
  5925. 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
  5926. // skill bonus provided by casting spell (mostly item spells)
  5927. // add the effect base points modifier from the spell cast (cheat lock / skeleton key etc.)
  5928. if (m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
  5929. skillValue += m_spellInfo->Effects[effIndex].CalcValue();
  5930. if (skillValue < reqSkillValue)
  5931. return SPELL_FAILED_LOW_CASTLEVEL;
  5932. }
  5933. return SPELL_CAST_OK;
  5934. }
  5935. }
  5936. }
  5937. if (reqKey)
  5938. return SPELL_FAILED_BAD_TARGETS;
  5939. return SPELL_CAST_OK;
  5940. }
  5941. void Spell::SetSpellValue(SpellValueMod mod, int32 value)
  5942. {
  5943. switch (mod)
  5944. {
  5945. case SPELLVALUE_BASE_POINT0:
  5946. m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
  5947. break;
  5948. case SPELLVALUE_BASE_POINT1:
  5949. m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
  5950. break;
  5951. case SPELLVALUE_BASE_POINT2:
  5952. m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
  5953. break;
  5954. case SPELLVALUE_RADIUS_MOD:
  5955. m_spellValue->RadiusMod = (float)value / 10000;
  5956. break;
  5957. case SPELLVALUE_MAX_TARGETS:
  5958. m_spellValue->MaxAffectedTargets = (uint32)value;
  5959. break;
  5960. case SPELLVALUE_AURA_STACK:
  5961. m_spellValue->AuraStackAmount = uint8(value);
  5962. break;
  5963. }
  5964. }
  5965. void Spell::PrepareTargetProcessing()
  5966. {
  5967. CheckEffectExecuteData();
  5968. }
  5969. void Spell::FinishTargetProcessing()
  5970. {
  5971. SendLogExecute();
  5972. }
  5973. void Spell::InitEffectExecuteData(uint8 effIndex)
  5974. {
  5975. ASSERT(effIndex < MAX_SPELL_EFFECTS);
  5976. if (!m_effectExecuteData[effIndex])
  5977. {
  5978. m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
  5979. // first dword - target counter
  5980. *m_effectExecuteData[effIndex] << uint32(1);
  5981. }
  5982. else
  5983. {
  5984. // increase target counter by one
  5985. uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
  5986. (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
  5987. }
  5988. }
  5989. void Spell::CheckEffectExecuteData()
  5990. {
  5991. for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
  5992. ASSERT(!m_effectExecuteData[i]);
  5993. }
  5994. void Spell::LoadScripts()
  5995. {
  5996. sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
  5997. for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
  5998. {
  5999. if (!(*itr)->_Load(this))
  6000. {
  6001. std::list<SpellScript*>::iterator bitr = itr;
  6002. ++itr;
  6003. delete (*bitr);
  6004. m_loadedScripts.erase(bitr);
  6005. continue;
  6006. }
  6007. TC_LOG_DEBUG("spells", "Spell::LoadScripts: Script `%s` for spell `%u` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
  6008. (*itr)->Register();
  6009. ++itr;
  6010. }
  6011. }
  6012. void Spell::CallScriptBeforeCastHandlers()
  6013. {
  6014. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6015. {
  6016. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
  6017. std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
  6018. for (; hookItr != hookItrEnd; ++hookItr)
  6019. (*hookItr).Call(*scritr);
  6020. (*scritr)->_FinishScriptCall();
  6021. }
  6022. }
  6023. void Spell::CallScriptOnCastHandlers()
  6024. {
  6025. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6026. {
  6027. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
  6028. std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
  6029. for (; hookItr != hookItrEnd; ++hookItr)
  6030. (*hookItr).Call(*scritr);
  6031. (*scritr)->_FinishScriptCall();
  6032. }
  6033. }
  6034. void Spell::CallScriptAfterCastHandlers()
  6035. {
  6036. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6037. {
  6038. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
  6039. std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
  6040. for (; hookItr != hookItrEnd; ++hookItr)
  6041. (*hookItr).Call(*scritr);
  6042. (*scritr)->_FinishScriptCall();
  6043. }
  6044. }
  6045. SpellCastResult Spell::CallScriptCheckCastHandlers()
  6046. {
  6047. SpellCastResult retVal = SPELL_CAST_OK;
  6048. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6049. {
  6050. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
  6051. std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
  6052. for (; hookItr != hookItrEnd; ++hookItr)
  6053. {
  6054. SpellCastResult tempResult = (*hookItr).Call(*scritr);
  6055. if (retVal == SPELL_CAST_OK)
  6056. retVal = tempResult;
  6057. }
  6058. (*scritr)->_FinishScriptCall();
  6059. }
  6060. return retVal;
  6061. }
  6062. void Spell::PrepareScriptHitHandlers()
  6063. {
  6064. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6065. (*scritr)->_InitHit();
  6066. }
  6067. bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
  6068. {
  6069. // execute script effect handler hooks and check if effects was prevented
  6070. bool preventDefault = false;
  6071. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6072. {
  6073. std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
  6074. SpellScriptHookType hookType;
  6075. switch (mode)
  6076. {
  6077. case SPELL_EFFECT_HANDLE_LAUNCH:
  6078. effItr = (*scritr)->OnEffectLaunch.begin();
  6079. effEndItr = (*scritr)->OnEffectLaunch.end();
  6080. hookType = SPELL_SCRIPT_HOOK_EFFECT_LAUNCH;
  6081. break;
  6082. case SPELL_EFFECT_HANDLE_LAUNCH_TARGET:
  6083. effItr = (*scritr)->OnEffectLaunchTarget.begin();
  6084. effEndItr = (*scritr)->OnEffectLaunchTarget.end();
  6085. hookType = SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET;
  6086. break;
  6087. case SPELL_EFFECT_HANDLE_HIT:
  6088. effItr = (*scritr)->OnEffectHit.begin();
  6089. effEndItr = (*scritr)->OnEffectHit.end();
  6090. hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT;
  6091. break;
  6092. case SPELL_EFFECT_HANDLE_HIT_TARGET:
  6093. effItr = (*scritr)->OnEffectHitTarget.begin();
  6094. effEndItr = (*scritr)->OnEffectHitTarget.end();
  6095. hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET;
  6096. break;
  6097. default:
  6098. ASSERT(false);
  6099. return false;
  6100. }
  6101. (*scritr)->_PrepareScriptCall(hookType);
  6102. for (; effItr != effEndItr; ++effItr)
  6103. // effect execution can be prevented
  6104. if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
  6105. (*effItr).Call(*scritr, effIndex);
  6106. if (!preventDefault)
  6107. preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
  6108. (*scritr)->_FinishScriptCall();
  6109. }
  6110. return preventDefault;
  6111. }
  6112. void Spell::CallScriptBeforeHitHandlers()
  6113. {
  6114. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6115. {
  6116. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
  6117. std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
  6118. for (; hookItr != hookItrEnd; ++hookItr)
  6119. (*hookItr).Call(*scritr);
  6120. (*scritr)->_FinishScriptCall();
  6121. }
  6122. }
  6123. void Spell::CallScriptOnHitHandlers()
  6124. {
  6125. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6126. {
  6127. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
  6128. std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
  6129. for (; hookItr != hookItrEnd; ++hookItr)
  6130. (*hookItr).Call(*scritr);
  6131. (*scritr)->_FinishScriptCall();
  6132. }
  6133. }
  6134. void Spell::CallScriptAfterHitHandlers()
  6135. {
  6136. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6137. {
  6138. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
  6139. std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
  6140. for (; hookItr != hookItrEnd; ++hookItr)
  6141. (*hookItr).Call(*scritr);
  6142. (*scritr)->_FinishScriptCall();
  6143. }
  6144. }
  6145. void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  6146. {
  6147. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6148. {
  6149. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
  6150. std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
  6151. for (; hookItr != hookItrEnd; ++hookItr)
  6152. if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
  6153. hookItr->Call(*scritr, targets);
  6154. (*scritr)->_FinishScriptCall();
  6155. }
  6156. }
  6157. void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  6158. {
  6159. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6160. {
  6161. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
  6162. std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
  6163. for (; hookItr != hookItrEnd; ++hookItr)
  6164. if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
  6165. hookItr->Call(*scritr, target);
  6166. (*scritr)->_FinishScriptCall();
  6167. }
  6168. }
  6169. void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
  6170. {
  6171. for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
  6172. {
  6173. (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
  6174. std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
  6175. for (; hookItr != hookItrEnd; ++hookItr)
  6176. if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
  6177. hookItr->Call(*scritr, target);
  6178. (*scritr)->_FinishScriptCall();
  6179. }
  6180. }
  6181. bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
  6182. {
  6183. // Skip if there are not any script
  6184. if (!m_loadedScripts.size())
  6185. return true;
  6186. for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
  6187. {
  6188. std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
  6189. for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
  6190. if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
  6191. (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
  6192. return false;
  6193. std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
  6194. for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
  6195. if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
  6196. (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
  6197. return false;
  6198. }
  6199. return true;
  6200. }
  6201. bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura) const
  6202. {
  6203. bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER));
  6204. // If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a cast spell with TARGET_UNIT_CASTER
  6205. for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i)
  6206. {
  6207. if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
  6208. return true;
  6209. }
  6210. return false;
  6211. }
  6212. void Spell::PrepareTriggersExecutedOnHit()
  6213. {
  6214. /// @todo move this to scripts
  6215. if (m_spellInfo->SpellFamilyName)
  6216. {
  6217. SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
  6218. if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
  6219. m_preCastSpell = m_spellInfo->ExcludeCasterAuraSpell;
  6220. SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
  6221. if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
  6222. m_preCastSpell = m_spellInfo->ExcludeTargetAuraSpell;
  6223. }
  6224. /// @todo move this to scripts
  6225. switch (m_spellInfo->SpellFamilyName)
  6226. {
  6227. case SPELLFAMILY_MAGE:
  6228. {
  6229. // Permafrost
  6230. if (m_spellInfo->SpellFamilyFlags[1] & 0x00001000 || m_spellInfo->SpellFamilyFlags[0] & 0x00100220)
  6231. m_preCastSpell = 68391;
  6232. break;
  6233. }
  6234. }
  6235. // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
  6236. // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
  6237. // and to correctly calculate proc chance when combopoints are present
  6238. Unit::AuraEffectList const& targetTriggers = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER);
  6239. for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
  6240. {
  6241. if (!(*i)->IsAffectingSpell(m_spellInfo))
  6242. continue;
  6243. SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
  6244. uint32 auraSpellIdx = (*i)->GetEffIndex();
  6245. if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
  6246. {
  6247. // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
  6248. // this possibly needs fixing
  6249. int32 auraBaseAmount = (*i)->GetBaseAmount();
  6250. // proc chance is stored in effect amount
  6251. int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
  6252. // build trigger and add to the list
  6253. HitTriggerSpell spellTriggerInfo;
  6254. spellTriggerInfo.triggeredSpell = spellInfo;
  6255. spellTriggerInfo.triggeredByAura = auraSpellInfo;
  6256. spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
  6257. m_hitTriggerSpells.push_back(spellTriggerInfo);
  6258. }
  6259. }
  6260. }
  6261. // Global cooldowns management
  6262. enum GCDLimits
  6263. {
  6264. MIN_GCD = 1000,
  6265. MAX_GCD = 1500
  6266. };
  6267. bool Spell::HasGlobalCooldown() const
  6268. {
  6269. // Only player or controlled units have global cooldown
  6270. if (m_caster->GetCharmInfo())
  6271. return m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
  6272. else if (m_caster->GetTypeId() == TYPEID_PLAYER)
  6273. return m_caster->ToPlayer()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
  6274. else
  6275. return false;
  6276. }
  6277. void Spell::TriggerGlobalCooldown()
  6278. {
  6279. int32 gcd = m_spellInfo->StartRecoveryTime;
  6280. if (!gcd)
  6281. return;
  6282. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  6283. if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
  6284. return;
  6285. // Global cooldown can't leave range 1..1.5 secs
  6286. // There are some spells (mostly not cast directly by player) that have < 1 sec and > 1.5 sec global cooldowns
  6287. // but as tests show are not affected by any spell mods.
  6288. if (m_spellInfo->StartRecoveryTime >= MIN_GCD && m_spellInfo->StartRecoveryTime <= MAX_GCD)
  6289. {
  6290. // gcd modifier auras are applied only to own spells and only players have such mods
  6291. if (m_caster->GetTypeId() == TYPEID_PLAYER)
  6292. m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
  6293. // Apply haste rating
  6294. gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
  6295. if (gcd < MIN_GCD)
  6296. gcd = MIN_GCD;
  6297. else if (gcd > MAX_GCD)
  6298. gcd = MAX_GCD;
  6299. }
  6300. // Only players or controlled units have global cooldown
  6301. if (m_caster->GetCharmInfo())
  6302. m_caster->GetCharmInfo()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
  6303. else if (m_caster->GetTypeId() == TYPEID_PLAYER)
  6304. m_caster->ToPlayer()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
  6305. }
  6306. void Spell::CancelGlobalCooldown()
  6307. {
  6308. if (!m_spellInfo->StartRecoveryTime)
  6309. return;
  6310. // Cancel global cooldown when interrupting current cast
  6311. if (m_caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) != this)
  6312. return;
  6313. // Only players or controlled units have global cooldown
  6314. if (m_caster->GetCharmInfo())
  6315. m_caster->GetCharmInfo()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
  6316. else if (m_caster->GetTypeId() == TYPEID_PLAYER)
  6317. m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
  6318. }
  6319. namespace Trinity
  6320. {
  6321. WorldObjectSpellTargetCheck::WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
  6322. SpellTargetCheckTypes selectionType, ConditionList* condList) : _caster(caster), _referer(referer), _spellInfo(spellInfo),
  6323. _targetSelectionType(selectionType), _condList(condList)
  6324. {
  6325. if (condList)
  6326. _condSrcInfo = new ConditionSourceInfo(NULL, caster);
  6327. else
  6328. _condSrcInfo = NULL;
  6329. }
  6330. WorldObjectSpellTargetCheck::~WorldObjectSpellTargetCheck()
  6331. {
  6332. delete _condSrcInfo;
  6333. }
  6334. bool WorldObjectSpellTargetCheck::operator()(WorldObject* target)
  6335. {
  6336. if (_spellInfo->CheckTarget(_caster, target, true) != SPELL_CAST_OK)
  6337. return false;
  6338. Unit* unitTarget = target->ToUnit();
  6339. if (Corpse* corpseTarget = target->ToCorpse())
  6340. {
  6341. // use ofter for party/assistance checks
  6342. if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
  6343. unitTarget = owner;
  6344. else
  6345. return false;
  6346. }
  6347. if (unitTarget)
  6348. {
  6349. switch (_targetSelectionType)
  6350. {
  6351. case TARGET_CHECK_ENEMY:
  6352. if (unitTarget->IsTotem())
  6353. return false;
  6354. if (!_caster->_IsValidAttackTarget(unitTarget, _spellInfo))
  6355. return false;
  6356. break;
  6357. case TARGET_CHECK_ALLY:
  6358. if (unitTarget->IsTotem())
  6359. return false;
  6360. if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
  6361. return false;
  6362. break;
  6363. case TARGET_CHECK_PARTY:
  6364. if (unitTarget->IsTotem())
  6365. return false;
  6366. if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
  6367. return false;
  6368. if (!_referer->IsInPartyWith(unitTarget))
  6369. return false;
  6370. break;
  6371. case TARGET_CHECK_RAID_CLASS:
  6372. if (_referer->getClass() != unitTarget->getClass())
  6373. return false;
  6374. // nobreak;
  6375. case TARGET_CHECK_RAID:
  6376. if (unitTarget->IsTotem())
  6377. return false;
  6378. if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
  6379. return false;
  6380. if (!_referer->IsInRaidWith(unitTarget))
  6381. return false;
  6382. break;
  6383. default:
  6384. break;
  6385. }
  6386. }
  6387. if (!_condSrcInfo)
  6388. return true;
  6389. _condSrcInfo->mConditionTargets[0] = target;
  6390. return sConditionMgr->IsObjectMeetToConditions(*_condSrcInfo, *_condList);
  6391. }
  6392. WorldObjectSpellNearbyTargetCheck::WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
  6393. SpellTargetCheckTypes selectionType, ConditionList* condList)
  6394. : WorldObjectSpellTargetCheck(caster, caster, spellInfo, selectionType, condList), _range(range), _position(caster) { }
  6395. bool WorldObjectSpellNearbyTargetCheck::operator()(WorldObject* target)
  6396. {
  6397. float dist = target->GetDistance(*_position);
  6398. if (dist < _range && WorldObjectSpellTargetCheck::operator ()(target))
  6399. {
  6400. _range = dist;
  6401. return true;
  6402. }
  6403. return false;
  6404. }
  6405. WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
  6406. Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
  6407. : WorldObjectSpellTargetCheck(caster, referer, spellInfo, selectionType, condList), _range(range), _position(position) { }
  6408. bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
  6409. {
  6410. if (!target->IsWithinDist3d(_position, _range) && !(target->ToGameObject() && target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)))
  6411. return false;
  6412. return WorldObjectSpellTargetCheck::operator ()(target);
  6413. }
  6414. WorldObjectSpellConeTargetCheck::WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
  6415. SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
  6416. : WorldObjectSpellAreaTargetCheck(range, caster, caster, caster, spellInfo, selectionType, condList), _coneAngle(coneAngle) { }
  6417. bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target)
  6418. {
  6419. if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_BACK)
  6420. {
  6421. if (!_caster->isInBack(target, _coneAngle))
  6422. return false;
  6423. }
  6424. else if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_LINE)
  6425. {
  6426. if (!_caster->HasInLine(target, _caster->GetObjectSize()))
  6427. return false;
  6428. }
  6429. else
  6430. {
  6431. if (!_caster->isInFront(target, _coneAngle))
  6432. return false;
  6433. }
  6434. return WorldObjectSpellAreaTargetCheck::operator ()(target);
  6435. }
  6436. WorldObjectSpellTrajTargetCheck::WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster, SpellInfo const* spellInfo)
  6437. : WorldObjectSpellAreaTargetCheck(range, position, caster, caster, spellInfo, TARGET_CHECK_DEFAULT, NULL) { }
  6438. bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
  6439. {
  6440. // return all targets on missile trajectory (0 - size of a missile)
  6441. if (!_caster->HasInLine(target, 0))
  6442. return false;
  6443. return WorldObjectSpellAreaTargetCheck::operator ()(target);
  6444. }
  6445. } //namespace Trinity