aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxinef1 <w.szyszko2@gmail.com>2017-02-19 06:10:50 +0100
committerShauren <shauren.trinity@gmail.com>2019-07-21 21:06:54 +0200
commitfb5c07ffe8d72d32a2c47cfa41dfb3a952160b72 (patch)
tree36b03852e0c1aaa03f991ff3a667ceb85fae11ba
parent146e93b5639a9908b9c38f521aa5d1bdf7db89c4 (diff)
Fixed setting and unsetting of m_spellModTakingSpell (#19116)
- A problem when a different spell tries to overwrite existing ModTakingSpell should no longer happen (cherrypicked from e261754c9cd8b14a0555e866b4e193e1fe3c25ae)
-rw-r--r--src/server/game/Entities/Player/Player.cpp16
-rw-r--r--src/server/game/Spells/Spell.cpp42
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellInfo.cpp8
-rw-r--r--src/server/game/Spells/SpellInfo.h6
5 files changed, 29 insertions, 44 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0f3a258a411..b911134d741 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1029,18 +1029,6 @@ void Player::Update(uint32 p_time)
m_nextMailDelivereTime = 0;
}
- // If this is set during update SetSpellModTakingSpell call is missing somewhere in the code
- // Having this would prevent more aura charges to be dropped, so let's crash
- //ASSERT (!m_spellModTakingSpell);
- if (m_spellModTakingSpell)
- {
- //TC_LOG_FATAL("entities.player", "Player has m_pad %u during update!", m_pad);
- //if (m_spellModTakingSpell)
- TC_LOG_FATAL("spells", "Player::Update: Player '%s' (%s) has m_spellModTakingSpell (SpellID: %u) during update!",
- GetName().c_str(), GetGUID().ToString().c_str(), m_spellModTakingSpell->m_spellInfo->Id);
- m_spellModTakingSpell = nullptr;
- }
-
// Update cinematic location, if 500ms have passed and we're doing a cinematic now.
_cinematicMgr->m_cinematicDiff += p_time;
if (_cinematicMgr->m_activeCinematicCameraId != 0 && GetMSTimeDiffToNow(_cinematicMgr->m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF)
@@ -21907,10 +21895,10 @@ void Player::ApplyModToSpell(SpellModifier* mod, Spell* spell)
void Player::SetSpellModTakingSpell(Spell* spell, bool apply)
{
- if (!spell || (m_spellModTakingSpell && m_spellModTakingSpell != spell))
+ if (apply && m_spellModTakingSpell != nullptr)
return;
- if (apply && spell->getState() == SPELL_STATE_FINISHED)
+ if (!apply && (!m_spellModTakingSpell || m_spellModTakingSpell != spell))
return;
m_spellModTakingSpell = apply ? spell : nullptr;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index b66570a58d8..67cafa53df6 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2878,13 +2878,9 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
}
LoadScripts();
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->SetSpellModTakingSpell(this, true);
// Fill cost data (do not use power for item casts)
- if (!m_CastItem)
- m_powerCost = m_spellInfo->CalcPowerCost(m_caster, m_spellSchoolMask);
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
+ if (m_CastItem)
+ m_powerCost = m_spellInfo->CalcPowerCost(m_caster, m_spellSchoolMask, this);
// Set combo point requirement
if ((_triggeredCastFlags & TRIGGERED_IGNORE_COMBO_POINTS) || m_CastItem || !m_caster->m_playerMovingMe)
@@ -2908,11 +2904,6 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
triggeredByAura->GetBase()->SetDuration(0);
}
- // cleanup after mod system
- // triggered spell pointer can be not removed in some cases
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
-
if (param1 || param2)
SendCastResult(result, &param1, &param2);
else
@@ -2929,10 +2920,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
{
if (!player->GetCommandStatus(CHEAT_CASTTIME))
{
- player->SetSpellModTakingSpell(this, true);
// calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
m_casttime = m_spellInfo->CalcCastTime(player->getLevel(), this);
- player->SetSpellModTakingSpell(this, false);
}
else
m_casttime = 0; // Set cast time to 0 if .cheat casttime is enabled.
@@ -3058,6 +3047,23 @@ void Spell::cancel()
void Spell::cast(bool skipCheck)
{
+ Player* modOwner = m_caster->GetSpellModOwner();
+ Spell* lastSpellMod = nullptr;
+ if (modOwner)
+ {
+ lastSpellMod = modOwner->m_spellModTakingSpell;
+ if (lastSpellMod)
+ modOwner->SetSpellModTakingSpell(lastSpellMod, false);
+ }
+
+ _cast(skipCheck);
+
+ if (lastSpellMod)
+ modOwner->SetSpellModTakingSpell(lastSpellMod, true);
+}
+
+void Spell::_cast(bool skipCheck)
+{
// update pointers base at GUIDs to prevent access to non-existed already object
if (!UpdatePointers())
{
@@ -3114,8 +3120,6 @@ void Spell::cast(bool skipCheck)
SendCastResult(castResult, &param1, &param2);
SendInterrupted(0);
- // cleanup after mod system
- // triggered spell pointer can be not removed in some cases
if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
@@ -3139,8 +3143,6 @@ void Spell::cast(bool skipCheck)
SendCastResult(SPELL_FAILED_DONT_REPORT);
SendInterrupted(0);
- // cleanup after mod system
- // triggered spell pointer can be not removed in some cases
m_caster->ToPlayer()->SetSpellModTakingSpell(this, false);
finish(false);
@@ -7241,13 +7243,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
- if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->SetSpellModTakingSpell(this, true);
-
targetInfo.crit = m_caster->IsSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
-
- if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->SetSpellModTakingSpell(this, false);
}
SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 4f8ca3b3caa..d7500f3b69d 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -704,6 +704,7 @@ class TC_GAME_API Spell
bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();
void CancelGlobalCooldown();
+ void _cast(bool skipCheck = false);
void SendLoot(ObjectGuid guid, LootType loottype);
std::pair<float, float> GetMinMaxRange(bool strict) const;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index cc44b171d3a..ab364042f68 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -3741,10 +3741,10 @@ uint32 SpellInfo::GetRecoveryTime() const
return RecoveryTime > CategoryRecoveryTime ? RecoveryTime : CategoryRecoveryTime;
}
-std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const
+std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, Spell* spell) const
{
std::vector<SpellPowerCost> costs;
- auto collector = [this, caster, schoolMask, &costs](std::vector<SpellPowerEntry const*> const& powers)
+ auto collector = [this, caster, schoolMask, spell, &costs](std::vector<SpellPowerEntry const*> const& powers)
{
costs.reserve(powers.size());
int32 healthCost = 0;
@@ -3861,9 +3861,9 @@ std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(Unit const* caster, SpellSc
if (Player* modOwner = caster->GetSpellModOwner())
{
if (power->OrderIndex == 0)
- modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost);
+ modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost, spell);
else if (power->OrderIndex == 1)
- modOwner->ApplySpellMod(Id, SPELLMOD_SPELL_COST2, powerCost);
+ modOwner->ApplySpellMod(Id, SPELLMOD_SPELL_COST2, powerCost, spell);
}
if (!caster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel)
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 04a7aec72f5..004189fc028 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -630,7 +630,7 @@ class TC_GAME_API SpellInfo
SpellSpecificType GetSpellSpecific() const;
float GetMinRange(bool positive = false) const;
- float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
+ float GetMaxRange(bool positive = false, Unit* caster = nullptr, Spell* spell = nullptr) const;
int32 CalcDuration(Unit* caster = nullptr) const;
int32 GetDuration() const;
@@ -638,10 +638,10 @@ class TC_GAME_API SpellInfo
uint32 GetMaxTicks(uint32 difficulty) const;
- uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
+ uint32 CalcCastTime(uint8 level = 0, Spell* spell = nullptr) const;
uint32 GetRecoveryTime() const;
- std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
+ std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
float CalcProcPPM(Unit* caster, int32 itemLevel) const;