diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index aefe57b09..31968e956 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -354,7 +354,7 @@ void GameObject::Update(uint32 /*p_time*/) { Unit *caster = owner ? owner : ok; - caster->CastSpell(ok, goInfo->trap.spellId, true); + caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID()); m_cooldownTime = time(NULL) + 4; // 4 seconds if(NeedDespawn) @@ -404,7 +404,7 @@ void GameObject::Update(uint32 /*p_time*/) for (; it != end; it++) { Unit* owner = Unit::GetUnit(*this, uint64(*it)); - if (owner) owner->CastSpell(owner, spellId, false); + if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID()); } m_unique_users.clear(); @@ -809,7 +809,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) // found correct GO // FIXME: when GO casting will be implemented trap must cast spell to target if(trapGO) - target->CastSpell(target,trapSpell,true); + target->CastSpell(target,trapSpell,true, 0, 0, GetGUID()); } GameObject* GameObject::LookupFishingHoleAround(float range) diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 17318740c..3ae24e1d8 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -171,11 +171,16 @@ Corpse* ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid) { Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL); - if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + if(!ret) + return NULL; + if(ret->GetMapId() != u.GetMapId()) + ret = NULL; + if(ret->GetInstanceId() != u.GetInstanceId()) + return NULL; return ret; } -Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask) +Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask) { Object *obj = NULL; @@ -203,9 +208,9 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 if(obj) return obj; } - if(typemask & TYPEMASK_ITEM) + if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER) { - obj = p.GetItemByGuid( guid ); + obj = ((Player const &)p).GetItemByGuid( guid ); if(obj) return obj; } @@ -216,15 +221,25 @@ GameObject* ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid) { GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL); - if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + if(!ret) + return NULL; + if(ret->GetMapId() != u.GetMapId()) + ret = NULL; + if(ret->GetInstanceId() != u.GetInstanceId()) + return NULL; return ret; } DynamicObject* -ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid) +ObjectAccessor::GetDynamicObject(WorldObject const &u, uint64 guid) { DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL); - if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL; + if(!ret) + return NULL; + if(ret->GetMapId() != u.GetMapId()) + ret = NULL; + if(ret->GetInstanceId() != u.GetInstanceId()) + return NULL; return ret; } diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 20bb8ec61..77ffb3d60 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -136,7 +136,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::SingletonEffectImplicitTargetA[i]) { - case TARGET_ALL_AROUND_CASTER: - if( m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_PARTY || - m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER || - m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_RAID_AROUND_CASTER ) - { - SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap); - } + case TARGET_CASTER_COORDINATES: // Note: this hack with search required until GO casting not implemented // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support // currently each enemy selected explicitly and self cast damage - else if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) + if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) { if(m_targets.getUnitTarget()) tmpUnitMap.push_back(m_targets.getUnitTarget()); @@ -919,7 +921,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) return; // Get original caster (if exist) and calculate damage/healing from him data - Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster; + Unit *caster = m_originalCaster ? m_originalCaster : m_caster; // Skip if m_originalCaster not avaiable if (!caster) @@ -1471,6 +1473,19 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) }break; case TARGET_ALL_ENEMY_IN_AREA: { + CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE); + + TypeContainerVisitor world_object_notifier(notifier); + TypeContainerVisitor grid_object_notifier(notifier); + + CellLock cell_lock(cell, p); + cell_lock->Visit(cell_lock, world_object_notifier, *m_caster->GetMap()); + cell_lock->Visit(cell_lock, grid_object_notifier, *m_caster->GetMap()); }break; case TARGET_ALL_ENEMY_IN_AREA_INSTANT: { @@ -1555,25 +1570,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET) TagUnitMap.push_back(target); }break; - case TARGET_ALL_AROUND_CASTER: + case TARGET_CASTER_COORDINATES: { - CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_AOE_DAMAGE); - - TypeContainerVisitor world_object_notifier(notifier); - TypeContainerVisitor grid_object_notifier(notifier); - - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, world_object_notifier, *m_caster->GetMap()); - cell_lock->Visit(cell_lock, grid_object_notifier, *m_caster->GetMap()); + m_targets.setDestination(m_targets.m_srcX, m_targets.m_srcY, m_targets.m_srcZ); }break; case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: { - CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); @@ -1716,7 +1719,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) // targets the ground, not the units in the area if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) { - CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); + CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY)); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); @@ -2041,6 +2044,16 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura) m_spellState = SPELL_STATE_PREPARING; + // Check original caster is GO - set its coordinates as src cast + WorldObject *caster = NULL; + if (m_originalCasterGUID) + caster = (WorldObject *)ObjectAccessor::GetObjectByTypeMask(*m_caster, m_originalCasterGUID, TYPEMASK_GAMEOBJECT); + if (!caster) + caster = m_caster; + + // Set cast source for targets + m_targets.setSource(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); + m_castPositionX = m_caster->GetPositionX(); m_castPositionY = m_caster->GetPositionY(); m_castPositionZ = m_caster->GetPositionZ(); @@ -2892,6 +2905,7 @@ void Spell::SendSpellGo() } WorldPacket data(SMSG_SPELL_GO, 50); // guess size + if(m_CastItem) data.append(m_CastItem->GetPackGUID()); else diff --git a/src/game/Spell.h b/src/game/Spell.h index 858e9e8f5..a443c212d 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -150,6 +150,7 @@ class SpellCastTargets Unit *getUnitTarget() const { return m_unitTarget; } void setUnitTarget(Unit *target); void setDestination(float x, float y, float z); + void setSource(float x, float y, float z); uint64 getGOTargetGUID() const { return m_GOTargetGUID; } GameObject *getGOTarget() const { return m_GOTarget; } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 6ee0f7d42..4ce2ada80 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2218,7 +2218,7 @@ void Spell::EffectApplyAura(uint32 i) (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) return; - Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster; + Unit* caster = m_originalCaster ? m_originalCaster : m_caster; if(!caster) return; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 46a9bce20..7e270e19c 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -273,7 +273,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB) case TARGET_CURRENT_ENEMY_COORDINATES: case TARGET_SINGLE_ENEMY: return false; - case TARGET_ALL_AROUND_CASTER: + case TARGET_CASTER_COORDINATES: return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER); default: break; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 7f2b8803b..62f73f9b7 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -367,7 +367,6 @@ inline bool IsAreaEffectTarget( Targets target ) case TARGET_ALL_ENEMY_IN_AREA: case TARGET_ALL_ENEMY_IN_AREA_INSTANT: case TARGET_ALL_PARTY_AROUND_CASTER: - case TARGET_ALL_AROUND_CASTER: case TARGET_IN_FRONT_OF_CASTER: case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7f75b49b7..8cb3d9af2 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7158" + #define REVISION_NR "7159" #endif // __REVISION_NR_H__