aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp289
1 files changed, 180 insertions, 109 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index d8baf713926..ae65161538b 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -16,46 +16,49 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "Spell.h"
+#include "Battlefield.h"
+#include "BattlefieldMgr.h"
+#include "Battleground.h"
+#include "CellImpl.h"
#include "Common.h"
+#include "ConditionMgr.h"
#include "DatabaseEnv.h"
-#include "WorldPacket.h"
-#include "WorldSession.h"
-#include "GameTime.h"
+#include "DBCStores.h"
+#include "DisableMgr.h"
+#include "DynamicObject.h"
+#include "GameObjectAI.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
-#include "Opcodes.h"
+#include "GameTime.h"
+#include "InstanceScript.h"
+#include "Item.h"
#include "Log.h"
-#include "UpdateMask.h"
-#include "World.h"
+#include "LootMgr.h"
+#include "ObjectAccessor.h"
#include "ObjectMgr.h"
-#include "SpellMgr.h"
-#include "Player.h"
+#include "Opcodes.h"
+#include "PathGenerator.h"
#include "Pet.h"
-#include "Unit.h"
-#include "Spell.h"
-#include "DynamicObject.h"
-#include "UpdateData.h"
-#include "ObjectAccessor.h"
-#include "CellImpl.h"
+#include "Player.h"
+#include "ScriptMgr.h"
#include "SharedDefines.h"
-#include "LootMgr.h"
-#include "VMapFactory.h"
-#include "Battleground.h"
-#include "Util.h"
-#include "TemporarySummon.h"
-#include "Vehicle.h"
#include "SpellAuraEffects.h"
-#include "ScriptMgr.h"
-#include "ConditionMgr.h"
-#include "DisableMgr.h"
-#include "SpellScript.h"
-#include "InstanceScript.h"
-#include "SpellInfo.h"
#include "SpellHistory.h"
-#include "Battlefield.h"
-#include "BattlefieldMgr.h"
+#include "SpellInfo.h"
+#include "SpellMgr.h"
+#include "SpellScript.h"
+#include "TemporarySummon.h"
#include "TradeData.h"
-#include "GameObjectAI.h"
+#include "Unit.h"
+#include "UpdateData.h"
+#include "UpdateMask.h"
+#include "Util.h"
+#include "Vehicle.h"
+#include "VMapFactory.h"
+#include "World.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -109,8 +112,8 @@ void SpellDestination::RelocateOffset(Position const& offset)
SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()
{
- m_objectTarget = NULL;
- m_itemTarget = NULL;
+ m_objectTarget = nullptr;
+ m_itemTarget = nullptr;
m_itemTargetEntry = 0;
@@ -244,7 +247,7 @@ Unit* SpellCastTargets::GetUnitTarget() const
if (m_objectTarget)
return m_objectTarget->ToUnit();
- return NULL;
+ return nullptr;
}
void SpellCastTargets::SetUnitTarget(Unit* target)
@@ -270,7 +273,7 @@ GameObject* SpellCastTargets::GetGOTarget() const
if (m_objectTarget)
return m_objectTarget->ToGameObject();
- return NULL;
+ return nullptr;
}
void SpellCastTargets::SetGOTarget(GameObject* target)
@@ -296,7 +299,7 @@ Corpse* SpellCastTargets::GetCorpseTarget() const
if (m_objectTarget)
return m_objectTarget->ToCorpse();
- return NULL;
+ return nullptr;
}
WorldObject* SpellCastTargets::GetObjectTarget() const
@@ -311,7 +314,7 @@ ObjectGuid SpellCastTargets::GetObjectTargetGUID() const
void SpellCastTargets::RemoveObjectTarget()
{
- m_objectTarget = NULL;
+ m_objectTarget = nullptr;
m_objectTargetGUID.Clear();
m_targetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_GAMEOBJECT_MASK);
}
@@ -441,11 +444,21 @@ void SpellCastTargets::RemoveDst()
m_targetMask &= ~(TARGET_FLAG_DEST_LOCATION);
}
+bool SpellCastTargets::HasSrc() const
+{
+ return (GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION) != 0;
+}
+
+bool SpellCastTargets::HasDst() const
+{
+ return (GetTargetMask() & TARGET_FLAG_DEST_LOCATION) != 0;
+}
+
void SpellCastTargets::Update(Unit* caster)
{
- m_objectTarget = m_objectTargetGUID ? ((m_objectTargetGUID == caster->GetGUID()) ? caster : ObjectAccessor::GetWorldObject(*caster, m_objectTargetGUID)) : NULL;
+ m_objectTarget = m_objectTargetGUID ? ((m_objectTargetGUID == caster->GetGUID()) ? caster : ObjectAccessor::GetWorldObject(*caster, m_objectTargetGUID)) : nullptr;
- m_itemTarget = NULL;
+ m_itemTarget = nullptr;
if (caster->GetTypeId() == TYPEID_PLAYER)
{
Player* player = caster->ToPlayer();
@@ -511,14 +524,28 @@ SpellValue::SpellValue(SpellInfo const* proto)
AuraStackAmount = 1;
}
+class TC_GAME_API SpellEvent : public BasicEvent
+{
+ public:
+ SpellEvent(Spell* spell);
+ virtual ~SpellEvent();
+
+ bool Execute(uint64 e_time, uint32 p_time) override;
+ void Abort(uint64 e_time) override;
+ bool IsDeletable() const override;
+
+ protected:
+ Spell* m_Spell;
+};
+
Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) :
m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
-, m_spellValue(new SpellValue(m_spellInfo)), _spellEvent(nullptr), m_preGeneratedPath(PathGenerator(m_caster))
+, m_spellValue(new SpellValue(m_spellInfo)), _spellEvent(nullptr)
{
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
- m_selfContainer = NULL;
+ m_selfContainer = nullptr;
m_referencedFromCurrentSpell = false;
m_executedCurrently = false;
m_needComboPoints = m_spellInfo->NeedsComboPoints();
@@ -552,7 +579,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
{
m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
if (m_originalCaster && !m_originalCaster->IsInWorld())
- m_originalCaster = NULL;
+ m_originalCaster = nullptr;
}
m_spellState = SPELL_STATE_NULL;
@@ -560,14 +587,14 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
if (info->HasAttribute(SPELL_ATTR4_CAN_CAST_WHILE_CASTING))
_triggeredCastFlags = TriggerCastFlags(uint32(_triggeredCastFlags) | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY);
- m_CastItem = NULL;
+ m_CastItem = nullptr;
m_castItemGUID.Clear();
m_castItemEntry = 0;
- unitTarget = NULL;
- itemTarget = NULL;
- gameObjTarget = NULL;
- destTarget = NULL;
+ unitTarget = nullptr;
+ itemTarget = nullptr;
+ gameObjTarget = nullptr;
+ destTarget = nullptr;
damage = 0;
targetMissInfo = SPELL_MISS_NONE;
effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH;
@@ -576,12 +603,12 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
m_procAttacker = 0;
m_procVictim = 0;
m_hitMask = 0;
- focusObject = NULL;
+ focusObject = nullptr;
m_cast_count = 0;
m_glyphIndex = 0;
m_preCastSpell = 0;
- m_triggeredByAuraSpell = NULL;
- m_spellAura = NULL;
+ m_triggeredByAuraSpell = nullptr;
+ m_spellAura = nullptr;
//Auto Shot & Shoot (wand)
m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell();
@@ -622,7 +649,7 @@ Spell::~Spell()
// Clean the reference to avoid later crash.
// If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
TC_LOG_ERROR("spells", "SPELL: deleting spell for spell ID %u. However, spell still referenced.", m_spellInfo->Id);
- *m_selfContainer = NULL;
+ *m_selfContainer = nullptr;
}
if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -657,7 +684,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets)
// try to select correct unit target if not provided by client or by serverside cast
if (neededTargets & (TARGET_FLAG_UNIT_MASK))
{
- Unit* unit = NULL;
+ Unit* unit = nullptr;
// try to use player selection as a target
if (Player* playerCaster = m_caster->ToPlayer())
{
@@ -724,7 +751,7 @@ void Spell::SelectExplicitTargets()
redirect = m_caster->GetMeleeHitRedirectTarget(target, m_spellInfo);
break;
default:
- redirect = NULL;
+ redirect = nullptr;
break;
}
if (redirect && (redirect != target))
@@ -1171,7 +1198,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
{
- Unit* referer = NULL;
+ Unit* referer = nullptr;
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_SRC:
@@ -1202,7 +1229,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
if (!referer)
return;
- Position const* center = NULL;
+ Position const* center = nullptr;
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_SRC:
@@ -1429,7 +1456,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
- WorldObject* target = NULL;
+ WorldObject* target = nullptr;
bool checkIfValid = true;
switch (targetType.GetTarget())
@@ -1498,7 +1525,7 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg
{
uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_JUMP_TARGETS>(m_spellInfo->Id, maxTargets, this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
if (maxTargets > 1)
{
@@ -1646,7 +1673,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
if (!targetMask)
return;
- WorldObject* target = NULL;
+ WorldObject* target = nullptr;
switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
{
@@ -1759,10 +1786,10 @@ void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* refere
WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList)
{
- WorldObject* target = NULL;
+ WorldObject* target = nullptr;
uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
if (!containerTypeMask)
- return NULL;
+ return nullptr;
Trinity::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> searcher(m_caster, target, check, containerTypeMask);
SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
@@ -1877,7 +1904,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
GameObject* Spell::SearchSpellFocus()
{
- GameObject* focus = NULL;
+ GameObject* focus = nullptr;
Trinity::GameObjectFocusCheck check(m_caster, m_spellInfo->RequiresSpellFocus);
Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> searcher(m_caster, focus, check);
SearchTargets<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> > (searcher, GRID_MAP_TYPE_MASK_GAMEOBJECT, m_caster, m_caster, m_caster->GetVisibilityRange());
@@ -2217,7 +2244,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// can't use default call because of threading, do stuff as fast as possible
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (farMask & (1 << i))
- HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
return;
}
@@ -2656,7 +2683,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
if (effectMask & (1 << effectNumber))
- HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
return SPELL_MISS_NONE;
}
@@ -2752,7 +2779,7 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target)
for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
if (effectMask & (1 << effectNumber))
- HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
if (go->AI())
go->AI()->SpellHit(m_caster, m_spellInfo);
@@ -2772,7 +2799,7 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target)
for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
if (effectMask & (1 << effectNumber))
- HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
CallScriptOnHitHandlers();
@@ -2798,7 +2825,7 @@ bool Spell::UpdateChanneledTargetList()
{
range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive());
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, range, this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
// add little tolerance level
range += std::min(MAX_SPELL_RANGE_TOLERANCE, range*0.1f); // 10% but no more than MAX_SPELL_RANGE_TOLERANCE
@@ -3051,7 +3078,7 @@ void Spell::cancel()
SetReferencedFromCurrent(false);
if (m_selfContainer && *m_selfContainer == this)
- *m_selfContainer = NULL;
+ *m_selfContainer = nullptr;
m_caster->RemoveDynObject(m_spellInfo->Id);
if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
@@ -3106,7 +3133,7 @@ void Spell::_cast(bool skipCheck)
// As of 3.0.2 pets begin attacking their owner's target immediately
// Let any pets know we've attacked something. Check DmgClass for harmful spells only
// This prevents spells such as Hunter's Mark from triggering pet attack
- if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
+ if (GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
if (Unit* unitTarget = m_targets.GetUnitTarget())
for (Unit* controlled : playerCaster->m_Controlled)
if (Creature* cControlled = controlled->ToCreature())
@@ -3317,7 +3344,7 @@ void Spell::handle_immediate()
// First mod_duration then haste - see Missile Barrage
// Apply duration mod
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
// Apply haste mods
m_caster->ModSpellDurationTime(m_spellInfo, duration, this);
@@ -3445,7 +3472,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
void Spell::_handle_immediate_phase()
{
- m_spellAura = NULL;
+ m_spellAura = nullptr;
// handle some immediate features of the spell here
HandleThreatSpells();
@@ -3460,7 +3487,7 @@ void Spell::_handle_immediate_phase()
continue;
// call effect handlers to handle destination hit
- HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT);
+ HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
}
// process items
@@ -3897,7 +3924,7 @@ void Spell::SendPetCastResult(SpellCastResult result)
WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
WriteCastResultInfo(data, player, m_spellInfo, m_cast_count, result, m_customError);
- player->GetSession()->SendPacket(&data);
+ player->SendDirectMessage(&data);
}
void Spell::SendSpellStart()
@@ -4221,7 +4248,7 @@ void Spell::SendLogExecute()
data.append(*m_effectExecuteData[i]);
delete m_effectExecuteData[i];
- m_effectExecuteData[i] = NULL;
+ m_effectExecuteData[i] = nullptr;
}
m_caster->SendMessageToSet(&data, true);
}
@@ -4367,7 +4394,7 @@ void Spell::SendResurrectRequest(Player* target)
data << uint8(m_caster->IsSpiritHealer()); // "you'll be afflicted with resurrection sickness"
// override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
data << uint8(!m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER));
- target->GetSession()->SendPacket(&data);
+ target->SendDirectMessage(&data);
}
void Spell::TakeCastItem()
@@ -4430,9 +4457,9 @@ void Spell::TakeCastItem()
// prevent crash at access to deleted m_targets.GetItemTarget
if (m_CastItem == m_targets.GetItemTarget())
- m_targets.SetItemTarget(NULL);
+ m_targets.SetItemTarget(nullptr);
- m_CastItem = NULL;
+ m_CastItem = nullptr;
m_castItemGUID.Clear();
m_castItemEntry = 0;
}
@@ -4455,8 +4482,11 @@ void Spell::TakePower()
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNE)
+ {
if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
- for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ {
+ for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ {
if (ihit->targetGUID == targetGUID)
{
if (ihit->missCondition != SPELL_MISS_NONE)
@@ -4464,10 +4494,13 @@ void Spell::TakePower()
hit = false;
//lower spell cost on fail (by talent aura)
if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_SPELL_COST_REFUND_ON_FAIL>(m_spellInfo->Id, m_powerCost);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost);
}
break;
}
+ }
+ }
+ }
}
if (powerType == POWER_RUNE)
@@ -4556,7 +4589,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID) const
{
runeCost[i] = src->RuneCost[i];
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], const_cast<Spell*>(this));
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], const_cast<Spell*>(this));
}
runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
@@ -4596,7 +4629,7 @@ void Spell::TakeRunePower(bool didHit)
{
runeCost[i] = runeCostData->RuneCost[i];
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
}
// Let's say we use a skill that requires a Frost rune. This is the order:
@@ -4673,7 +4706,7 @@ void Spell::TakeReagents()
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : NULL;
+ ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
// do not take reagents for these item casts
if (castItemTemplate && castItemTemplate->Flags & ITEM_FLAG_NO_REAGENT_COST)
@@ -4705,14 +4738,14 @@ void Spell::TakeReagents()
}
}
- m_CastItem = NULL;
+ m_CastItem = nullptr;
m_castItemGUID.Clear();
m_castItemEntry = 0;
}
// if GetItemTarget is also spell reagent
if (m_targets.GetItemTargetEntry() == itemid)
- m_targets.SetItemTarget(NULL);
+ m_targets.SetItemTarget(nullptr);
p_caster->DestroyItemCount(itemid, itemcount, true);
}
@@ -4782,7 +4815,7 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff);
// we do not need DamageMultiplier here.
- damage = CalculateDamage(i, NULL);
+ damage = CalculateDamage(i, nullptr);
bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
@@ -4888,7 +4921,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
m_needComboPoints = false;
if ((*j)->GetMiscValue() == 1)
{
- reqCombat=false;
+ reqCombat = false;
break;
}
}
@@ -4989,7 +5022,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id))
losTarget = dynObj;
- if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2))
+ if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2))
return SPELL_FAILED_LINE_OF_SIGHT;
}
}
@@ -5001,7 +5034,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
float x, y, z;
m_targets.GetDstPos()->GetPosition(x, y, z);
- if (!m_spellInfo->HasAttribute(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, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2))
+ if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2))
return SPELL_FAILED_LINE_OF_SIGHT;
}
@@ -5262,26 +5295,27 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
float objSize = target->GetCombatReach();
float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
- m_preGeneratedPath.SetPathLengthLimit(range);
+ m_preGeneratedPath = Trinity::make_unique<PathGenerator>(m_caster);
+ m_preGeneratedPath->SetPathLengthLimit(range);
// first try with raycast, if it fails fall back to normal path
float targetObjectSize = std::min(target->GetCombatReach(), 4.0f);
- bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true);
- if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
+ bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true);
+ if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
- else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
+ else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
{
- result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, false);
- if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
+ result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, false);
+ if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
- else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
+ else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
return SPELL_FAILED_NOPATH;
- else if (m_preGeneratedPath.IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
+ else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
return SPELL_FAILED_NOPATH;
}
- else if (m_preGeneratedPath.IsInvalidDestinationZ(target)) // Check position z, if in a straight line
+ else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if in a straight line
return SPELL_FAILED_NOPATH;
- m_preGeneratedPath.ReducePathLenghtByDist(objSize); // move back
+ m_preGeneratedPath->ReducePathLenghtByDist(objSize); // move back
}
break;
}
@@ -5324,7 +5358,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|| (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
return SPELL_FAILED_BAD_TARGETS;
- Item* pTempItem = NULL;
+ Item* pTempItem = nullptr;
if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM)
{
if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
@@ -5424,7 +5458,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
{
if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
if (Pet* pet = m_caster->ToPlayer()->GetPet())
- pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
+ pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID());
}
else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET))
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -5938,6 +5972,11 @@ bool Spell::CheckSpellCancelsConfuse(uint32* param1) const
return CheckSpellCancelsAuraEffect(SPELL_AURA_MOD_CONFUSE, param1);
}
+int32 Spell::CalculateDamage(uint8 i, Unit const* target) const
+{
+ return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]);
+}
+
bool Spell::CanAutoCast(Unit* target)
{
if (!target)
@@ -5994,6 +6033,18 @@ bool Spell::CanAutoCast(Unit* target)
return false;
}
+void Spell::CheckSrc()
+{
+ if (!m_targets.HasSrc())
+ m_targets.SetSrc(*m_caster);
+}
+
+void Spell::CheckDst()
+{
+ if (!m_targets.HasDst())
+ m_targets.SetDst(*m_caster);
+}
+
SpellCastResult Spell::CheckRange(bool strict) const
{
// Don't check for instant cast spells
@@ -6083,7 +6134,7 @@ std::pair<float, float> Spell::GetMinMaxRange(bool strict) const
maxRange *= ranged->GetTemplate()->RangedModRange * 0.01f;
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, maxRange, const_cast<Spell*>(this));
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, maxRange, const_cast<Spell*>(this));
maxRange += rangeMod;
@@ -6693,7 +6744,7 @@ void Spell::Delayed() // only called in DealDamage()
//check pushback reduce
int32 delaytime = 500; // spellcasting delay is normally 500ms
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
- m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this);
+ m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if (delayReduce >= 100)
return;
@@ -6731,7 +6782,7 @@ void Spell::DelayedChannel()
int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
- m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this);
+ m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if (delayReduce >= 100)
return;
@@ -6768,7 +6819,7 @@ bool Spell::UpdatePointers()
{
m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
if (m_originalCaster && !m_originalCaster->IsInWorld())
- m_originalCaster = NULL;
+ m_originalCaster = nullptr;
}
if (m_castItemGUID && m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -6790,7 +6841,7 @@ bool Spell::UpdatePointers()
return true;
// cache last transport
- WorldObject* transport = NULL;
+ WorldObject* transport = nullptr;
// update effect destinations (in case of moved transport dest target)
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
@@ -6847,11 +6898,11 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo
}
// check for ignore LOS on the effect itself
- if (m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS))
+ if (m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS))
return true;
// if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
- if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, NULL, SPELL_DISABLE_LOS)))
+ if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, nullptr, SPELL_DISABLE_LOS)))
return true;
/// @todo shit below shouldn't be here, but it's temporary
@@ -6910,7 +6961,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo
else
{
// Get GO cast coordinates if original caster -> GO
- WorldObject* caster = NULL;
+ WorldObject* caster = nullptr;
if (m_originalCasterGUID.IsGameObject())
caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
if (!caster)
@@ -6925,6 +6976,26 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo
return true;
}
+bool Spell::IsTriggered() const
+{
+ return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0;
+}
+
+bool Spell::IsIgnoringCooldowns() const
+{
+ return (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) != 0;
+}
+
+bool Spell::IsProcDisabled() const
+{
+ return (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) != 0;
+}
+
+bool Spell::IsChannelActive() const
+{
+ return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0;
+}
+
bool Spell::IsAutoActionResetSpell() const
{
/// @todo changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
@@ -7099,7 +7170,7 @@ void Spell::HandleLaunchPhase()
if (!m_spellInfo->Effects[i].IsEffect())
continue;
- HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH);
+ HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
}
float multiplier[MAX_SPELL_EFFECTS];
@@ -7155,7 +7226,7 @@ void Spell::HandleLaunchPhase()
void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
{
- Unit* unit = NULL;
+ Unit* unit = nullptr;
// In case spell hit target, do all effect on that target
if (targetInfo.missCondition == SPELL_MISS_NONE)
unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
@@ -7172,7 +7243,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
m_damage = 0;
m_healing = 0;
- HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
+ HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
if (m_damage > 0)
{
@@ -7662,7 +7733,7 @@ void Spell::TriggerGlobalCooldown()
{
// gcd modifier auras are applied only to own spells and only players have such mods
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod<SPELLMOD_GLOBAL_COOLDOWN>(m_spellInfo->Id, gcd, this);
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
// Apply haste rating
gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));