mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 13:37:00 +00:00
[9323] Fixes in code work with original caster guid.
* Add 2 function for 2 used way for original caster
- GetAffectiveCaster(), is posible NULL unit as source spell affects
(explcit caster, GO owner, caster of aura that trigering affect)..
- GetCastingObject(), possible NULL world object as in game spell effects
source, cast center, etc, need because original caster can store GO
guid that apply effect around. In other cases m_caster
* Use functions and avoid use explicitly m_originalCaster
* Use GetAffectiveCaster() for fix explicit GO cast at near unit, like now fixed campfire bonus.
This commit is contained in:
parent
a8de1c0ad4
commit
2a01c79609
4 changed files with 63 additions and 56 deletions
|
|
@ -373,13 +373,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
||||||
else
|
else
|
||||||
m_originalCasterGUID = m_caster->GetGUID();
|
m_originalCasterGUID = m_caster->GetGUID();
|
||||||
|
|
||||||
if(m_originalCasterGUID == m_caster->GetGUID())
|
UpdateOriginalCasterPointer();
|
||||||
m_originalCaster = m_caster;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
|
|
||||||
if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
m_currentBasePoints[i] = m_spellInfo->EffectBasePoints[i];
|
m_currentBasePoints[i] = m_spellInfo->EffectBasePoints[i];
|
||||||
|
|
@ -947,9 +941,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get original caster (if exist) and calculate damage/healing from him data
|
// Get original caster (if exist) and calculate damage/healing from him data
|
||||||
Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
|
Unit *caster = GetAffectiveCaster();
|
||||||
|
|
||||||
// Skip if m_originalCaster not available
|
|
||||||
if (!caster)
|
if (!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1061,7 +1053,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||||
if (!unit || !effectMask)
|
if (!unit || !effectMask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* realCaster = m_originalCaster ? m_originalCaster : m_caster;
|
Unit* realCaster = GetAffectiveCaster();
|
||||||
|
if (!realCaster)
|
||||||
|
return;
|
||||||
|
|
||||||
// Recheck immune (only for delayed spells)
|
// Recheck immune (only for delayed spells)
|
||||||
if (m_spellInfo->speed && (
|
if (m_spellInfo->speed && (
|
||||||
|
|
@ -1308,9 +1302,9 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
||||||
|
|
||||||
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[effIndex];
|
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[effIndex];
|
||||||
|
|
||||||
if(m_originalCaster)
|
if (Unit* realCaster = GetAffectiveCaster())
|
||||||
{
|
{
|
||||||
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
|
if(Player* modOwner = realCaster->GetSpellModOwner())
|
||||||
{
|
{
|
||||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
|
||||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
|
||||||
|
|
@ -1593,7 +1587,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Unit* pUnitTarget = m_targets.getUnitTarget();
|
Unit* pUnitTarget = m_targets.getUnitTarget();
|
||||||
Unit* originalCaster = GetOriginalCaster();
|
Unit* originalCaster = GetAffectiveCaster();
|
||||||
if(!pUnitTarget || !originalCaster)
|
if(!pUnitTarget || !originalCaster)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1722,13 +1716,8 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
||||||
case TARGET_CASTER_COORDINATES:
|
case TARGET_CASTER_COORDINATES:
|
||||||
{
|
{
|
||||||
// Check original caster is GO - set its coordinates as dst cast
|
// Check original caster is GO - set its coordinates as dst cast
|
||||||
WorldObject *caster = NULL;
|
if (WorldObject *caster = GetCastingObject())
|
||||||
if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
|
m_targets.setDestination(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
|
||||||
caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
|
||||||
if (!caster)
|
|
||||||
caster = m_caster;
|
|
||||||
// Set dest for targets
|
|
||||||
m_targets.setDestination(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TARGET_ALL_HOSTILE_UNITS_AROUND_CASTER:
|
case TARGET_ALL_HOSTILE_UNITS_AROUND_CASTER:
|
||||||
|
|
@ -2819,8 +2808,8 @@ void Spell::_handle_immediate_phase()
|
||||||
m_needSpellLog = false;
|
m_needSpellLog = false;
|
||||||
|
|
||||||
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[j];
|
uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[j];
|
||||||
if(m_originalCaster)
|
if (Unit* realCaster = GetAffectiveCaster())
|
||||||
if(Player* modOwner = m_originalCaster->GetSpellModOwner())
|
if(Player* modOwner = realCaster->GetSpellModOwner())
|
||||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this);
|
||||||
|
|
||||||
// initialize multipliers
|
// initialize multipliers
|
||||||
|
|
@ -4511,9 +4500,8 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
case SPELL_EFFECT_TAMECREATURE:
|
case SPELL_EFFECT_TAMECREATURE:
|
||||||
{
|
{
|
||||||
// Spell can be triggered, we need to check original caster prior to caster
|
// Spell can be triggered, we need to check original caster prior to caster
|
||||||
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
|
Unit* caster = GetAffectiveCaster();
|
||||||
|
if (!caster || caster->GetTypeId() != TYPEID_PLAYER ||
|
||||||
if (caster->GetTypeId() != TYPEID_PLAYER ||
|
|
||||||
!m_targets.getUnitTarget() ||
|
!m_targets.getUnitTarget() ||
|
||||||
m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
|
m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
|
||||||
return SPELL_FAILED_BAD_TARGETS;
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
@ -5891,15 +5879,25 @@ void Spell::DelayedChannel()
|
||||||
SendChannelUpdate(m_timer);
|
SendChannelUpdate(m_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::UpdatePointers()
|
void Spell::UpdateOriginalCasterPointer()
|
||||||
{
|
{
|
||||||
if(m_originalCasterGUID == m_caster->GetGUID())
|
if(m_originalCasterGUID == m_caster->GetGUID())
|
||||||
m_originalCaster = m_caster;
|
m_originalCaster = m_caster;
|
||||||
|
else if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
|
||||||
|
{
|
||||||
|
GameObject* go = m_caster->IsInWorld() ? m_caster->GetMap()->GetGameObject(m_originalCasterGUID) : NULL;
|
||||||
|
m_originalCaster = go ? go->GetOwner() : NULL;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
|
Unit* unit = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
|
||||||
if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL;
|
m_originalCaster = unit && unit->IsInWorld() ? unit : NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Spell::UpdatePointers()
|
||||||
|
{
|
||||||
|
UpdateOriginalCasterPointer();
|
||||||
|
|
||||||
m_targets.Update(m_caster);
|
m_targets.Update(m_caster);
|
||||||
}
|
}
|
||||||
|
|
@ -6023,13 +6021,10 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
|
||||||
break;
|
break;
|
||||||
default: // normal case
|
default: // normal case
|
||||||
// Get GO cast coordinates if original caster -> GO
|
// Get GO cast coordinates if original caster -> GO
|
||||||
WorldObject *caster = NULL;
|
if (target != m_caster)
|
||||||
if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
|
if (WorldObject *caster = GetCastingObject())
|
||||||
caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
if (!target->IsWithinLOSInMap(caster))
|
||||||
if (!caster)
|
return false;
|
||||||
caster = m_caster;
|
|
||||||
if(target != m_caster && !target->IsWithinLOSInMap(caster))
|
|
||||||
return false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6336,3 +6331,11 @@ void Spell::FillRaidOrPartyHealthPriorityTargets(UnitList &targetUnitMap, Unit*
|
||||||
healthQueue.pop();
|
healthQueue.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldObject* Spell::GetCastingObject() const
|
||||||
|
{
|
||||||
|
if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
|
||||||
|
return m_caster->IsInWorld() ? m_caster->GetMap()->GetGameObject(m_originalCasterGUID) : NULL;
|
||||||
|
else
|
||||||
|
return m_caster;
|
||||||
|
}
|
||||||
|
|
@ -436,8 +436,14 @@ class Spell
|
||||||
|
|
||||||
CurrentSpellTypes GetCurrentContainer();
|
CurrentSpellTypes GetCurrentContainer();
|
||||||
|
|
||||||
|
// caster types:
|
||||||
|
// formal spell caster, in game source of spell affects cast
|
||||||
Unit* GetCaster() const { return m_caster; }
|
Unit* GetCaster() const { return m_caster; }
|
||||||
Unit* GetOriginalCaster() const { return m_originalCaster; }
|
// real source of cast affects, explcit caster, or DoT/HoT applier, or GO owner, etc. Can be NULL
|
||||||
|
Unit* GetAffectiveCaster() const { return m_originalCasterGUID ? m_originalCaster : m_caster; }
|
||||||
|
// m_originalCasterGUID can store GO guid, and in this case this is visual caster
|
||||||
|
WorldObject* GetCastingObject() const;
|
||||||
|
|
||||||
int32 GetPowerCost() const { return m_powerCost; }
|
int32 GetPowerCost() const { return m_powerCost; }
|
||||||
|
|
||||||
void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
|
void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
|
||||||
|
|
@ -458,6 +464,7 @@ class Spell
|
||||||
|
|
||||||
void SendLoot(uint64 guid, LootType loottype);
|
void SendLoot(uint64 guid, LootType loottype);
|
||||||
bool IgnoreItemRequirements() const; // some item use spells have unexpected reagent data
|
bool IgnoreItemRequirements() const; // some item use spells have unexpected reagent data
|
||||||
|
void UpdateOriginalCasterPointer();
|
||||||
|
|
||||||
Unit* m_caster;
|
Unit* m_caster;
|
||||||
|
|
||||||
|
|
@ -611,7 +618,7 @@ namespace MaNGOS
|
||||||
SpellNotifierPlayer(Spell &spell, std::list<Unit*> &data, const uint32 &i, float radius)
|
SpellNotifierPlayer(Spell &spell, std::list<Unit*> &data, const uint32 &i, float radius)
|
||||||
: i_data(data), i_spell(spell), i_index(i), i_radius(radius)
|
: i_data(data), i_spell(spell), i_index(i), i_radius(radius)
|
||||||
{
|
{
|
||||||
i_originalCaster = i_spell.GetOriginalCaster();
|
i_originalCaster = i_spell.GetAffectiveCaster();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Visit(PlayerMapType &m)
|
void Visit(PlayerMapType &m)
|
||||||
|
|
@ -648,7 +655,7 @@ namespace MaNGOS
|
||||||
SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY)
|
SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY)
|
||||||
: i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType)
|
: i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType)
|
||||||
{
|
{
|
||||||
i_originalCaster = spell.GetOriginalCaster();
|
i_originalCaster = spell.GetAffectiveCaster();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline void Visit(GridRefManager<T> &m)
|
template<class T> inline void Visit(GridRefManager<T> &m)
|
||||||
|
|
|
||||||
|
|
@ -841,14 +841,16 @@ void Spell::EffectDummy(uint32 i)
|
||||||
}
|
}
|
||||||
case 17251: // Spirit Healer Res
|
case 17251: // Spirit Healer Res
|
||||||
{
|
{
|
||||||
if (!unitTarget || !m_originalCaster)
|
if (!unitTarget)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_originalCaster->GetTypeId() == TYPEID_PLAYER)
|
Unit* caster = GetAffectiveCaster();
|
||||||
|
|
||||||
|
if (caster && caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8);
|
WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8);
|
||||||
data << uint64(unitTarget->GetGUID());
|
data << uint64(unitTarget->GetGUID());
|
||||||
((Player*)m_originalCaster)->GetSession()->SendPacket( &data );
|
((Player*)caster)->GetSession()->SendPacket( &data );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2518,7 +2520,7 @@ void Spell::EffectApplyAura(uint32 i)
|
||||||
(unitTarget->GetTypeId() != TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
|
(unitTarget->GetTypeId() != TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
|
Unit* caster = GetAffectiveCaster();
|
||||||
if(!caster)
|
if(!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -2668,9 +2670,7 @@ void Spell::EffectHeal( uint32 /*i*/ )
|
||||||
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
||||||
{
|
{
|
||||||
// Try to get original caster
|
// Try to get original caster
|
||||||
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
Unit *caster = GetAffectiveCaster();
|
||||||
|
|
||||||
// Skip if m_originalCaster not available
|
|
||||||
if (!caster)
|
if (!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -2752,9 +2752,7 @@ void Spell::EffectHealPct( uint32 /*i*/ )
|
||||||
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
||||||
{
|
{
|
||||||
// Try to get original caster
|
// Try to get original caster
|
||||||
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
Unit *caster = GetAffectiveCaster();
|
||||||
|
|
||||||
// Skip if m_originalCaster not available
|
|
||||||
if (!caster)
|
if (!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -2773,9 +2771,7 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )
|
||||||
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
if (unitTarget && unitTarget->isAlive() && damage >= 0)
|
||||||
{
|
{
|
||||||
// Try to get original caster
|
// Try to get original caster
|
||||||
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
Unit *caster = GetAffectiveCaster();
|
||||||
|
|
||||||
// Skip if m_originalCaster not available
|
|
||||||
if (!caster)
|
if (!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -4265,7 +4261,7 @@ void Spell::EffectTameCreature(uint32 /*i*/)
|
||||||
{
|
{
|
||||||
// Caster must be player, checked in Spell::CheckCast
|
// Caster must be player, checked in Spell::CheckCast
|
||||||
// Spell can be triggered, we need to check original caster prior to caster
|
// Spell can be triggered, we need to check original caster prior to caster
|
||||||
Player* plr = (Player*)(m_originalCaster ? m_originalCaster : m_caster);
|
Player* plr = (Player*)GetAffectiveCaster();
|
||||||
|
|
||||||
Creature* creatureTarget = (Creature*)unitTarget;
|
Creature* creatureTarget = (Creature*)unitTarget;
|
||||||
|
|
||||||
|
|
@ -5162,10 +5158,11 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||||
// Emblazon Runeblade
|
// Emblazon Runeblade
|
||||||
case 51770:
|
case 51770:
|
||||||
{
|
{
|
||||||
if(!m_originalCaster)
|
Unit* caster = GetAffectiveCaster();
|
||||||
|
if(!caster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_originalCaster->CastSpell(m_originalCaster, damage, false);
|
caster->CastSpell(caster, damage, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Death Gate
|
// Death Gate
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "9322"
|
#define REVISION_NR "9323"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue