Guest User

Untitled

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