diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9af84f284..a5859afde 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1648,7 +1648,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& if (radius > 0.0f) { // caster included here? - FillAreaTargets(targetUnitMap, dest_x, dest_y, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ALL); + FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ALL); } else targetUnitMap.push_back(m_caster); @@ -1855,7 +1855,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& break; } case TARGET_ALL_ENEMY_IN_AREA: - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_AREAEFFECT_INSTANT: { @@ -1870,7 +1870,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& // fill real target list if no spell script target defined FillAreaTargets(bounds.first != bounds.second ? tempTargetUnitMap : targetUnitMap, - m_caster->GetPositionX(), m_caster->GetPositionY(), radius, PUSH_DEST_CENTER, bounds.first != bounds.second ? SPELL_TARGETS_ALL : targetB); + radius, PUSH_DEST_CENTER, bounds.first != bounds.second ? SPELL_TARGETS_ALL : targetB); if (!tempTargetUnitMap.empty()) { @@ -1919,7 +1919,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& UnitList tempTargetUnitMap; SpellScriptTargetBounds bounds = sSpellMgr.GetSpellScriptTargetBounds(m_spellInfo->Id); // fill real target list if no spell script target defined - FillAreaTargets(bounds.first != bounds.second ? tempTargetUnitMap : targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ALL); + FillAreaTargets(bounds.first != bounds.second ? tempTargetUnitMap : targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_ALL); if (!tempTargetUnitMap.empty()) { @@ -2005,7 +2005,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& targetUnitMap.push_back(m_caster); break; default: - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); break; } break; @@ -2071,13 +2071,13 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& break; } case TARGET_ALL_HOSTILE_UNITS_AROUND_CASTER: - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_SELF_CENTER, SPELL_TARGETS_HOSTILE); + FillAreaTargets(targetUnitMap, radius, PUSH_SELF_CENTER, SPELL_TARGETS_HOSTILE); break; case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER: switch (m_spellInfo->Id) { case 56153: // Guardian Aura - Ahn'Kahet - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY); + FillAreaTargets(targetUnitMap, radius, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY); targetUnitMap.remove(m_caster); break; case 64844: // Divine Hymn @@ -2090,7 +2090,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& break; default: // selected friendly units (for casting objects) around casting object - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY, GetCastingObject()); + FillAreaTargets(targetUnitMap, radius, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY, GetCastingObject()); break; } break; @@ -2128,7 +2128,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& FillRaidOrPartyHealthPriorityTargets(targetUnitMap, m_caster, target, radius, count, true, false, true); } else - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY); + FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_FRIENDLY); break; // TARGET_SINGLE_PARTY means that the spells can only be casted on a party member and not on the caster (some seals, fire shield from imp, etc..) case TARGET_SINGLE_PARTY: @@ -2193,17 +2193,17 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case TARGET_IN_FRONT_OF_CASTER: { bool inFront = m_spellInfo->SpellVisual[0] != 3879; - FillAreaTargets(targetUnitMap, m_caster->GetPositionX(), m_caster->GetPositionY(), radius, inFront ? PUSH_IN_FRONT : PUSH_IN_BACK, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, inFront ? PUSH_IN_FRONT : PUSH_IN_BACK, SPELL_TARGETS_AOE_DAMAGE); break; } case TARGET_LARGE_FRONTAL_CONE: - FillAreaTargets(targetUnitMap, m_caster->GetPositionX(), m_caster->GetPositionY(), radius, PUSH_IN_FRONT_90, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_IN_FRONT_90, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_NARROW_FRONTAL_CONE: - FillAreaTargets(targetUnitMap, m_caster->GetPositionX(), m_caster->GetPositionY(), radius, PUSH_IN_FRONT_15, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_IN_FRONT_15, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_IN_FRONT_OF_CASTER_30: - FillAreaTargets(targetUnitMap, m_caster->GetPositionX(), m_caster->GetPositionY(), radius, PUSH_IN_FRONT_30, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_IN_FRONT_30, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_DUELVSPLAYER: { @@ -2238,7 +2238,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: // targets the ground, not the units in the area if (m_spellInfo->Effect[effIndex]!=SPELL_EFFECT_PERSISTENT_AREA_AURA) - FillAreaTargets(targetUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_MINION: if(m_spellInfo->Effect[effIndex] != SPELL_EFFECT_DUEL) @@ -2345,7 +2345,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& UnitList tempTargetUnitMap; - FillAreaTargets(tempTargetUnitMap, m_caster->GetPositionX(), m_caster->GetPositionY(), max_range, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY); + FillAreaTargets(tempTargetUnitMap, max_range, PUSH_SELF_CENTER, SPELL_TARGETS_FRIENDLY); if (m_caster != pUnitTarget && std::find(tempTargetUnitMap.begin(), tempTargetUnitMap.end(), m_caster) == tempTargetUnitMap.end()) tempTargetUnitMap.push_front(m_caster); @@ -2399,7 +2399,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& targetUnitMap.push_back(currentTarget); m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ()); if(m_spellInfo->EffectImplicitTargetB[effIndex] == TARGET_ALL_ENEMY_IN_AREA_INSTANT) - FillAreaTargets(targetUnitMap, currentTarget->GetPositionX(), currentTarget->GetPositionY(), radius, PUSH_TARGET_CENTER, SPELL_TARGETS_AOE_DAMAGE); + FillAreaTargets(targetUnitMap, radius, PUSH_TARGET_CENTER, SPELL_TARGETS_AOE_DAMAGE); } break; } @@ -6917,10 +6917,10 @@ SpellCastResult Spell::CanOpenLock(SpellEffectIndex effIndex, uint32 lockId, Ski * @param spellTargets Additional rules for target selection base at hostile/friendly state to original spell caster * @param originalCaster If provided set alternative original caster, if =NULL then used Spell::GetAffectiveObject() return */ -void Spell::FillAreaTargets(UnitList &targetUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets, WorldObject* originalCaster /*=NULL*/) +void Spell::FillAreaTargets(UnitList &targetUnitMap, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets, WorldObject* originalCaster /*=NULL*/) { MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, targetUnitMap, radius, pushType, spellTargets, originalCaster); - Cell::VisitAllObjects(x, y, m_caster->GetMap(), notifier, radius); + Cell::VisitAllObjects(notifier.GetCenterX(), notifier.GetCenterY(), m_caster->GetMap(), notifier, radius); } void Spell::FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, bool raid, bool withPets, bool withcaster) diff --git a/src/game/Spell.h b/src/game/Spell.h index 4f3318159..a0dc2a4d5 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -401,7 +401,7 @@ class Spell void FillTargetMap(); void SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList &targetUnitMap); - void FillAreaTargets(UnitList &targetUnitMap, float x, float y, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets, WorldObject* originalCaster = NULL); + void FillAreaTargets(UnitList &targetUnitMap, float radius, SpellNotifyPushType pushType, SpellTargets spellTargets, WorldObject* originalCaster = NULL); void FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, bool raid, bool withPets, bool withcaster); void FillRaidOrPartyManaPriorityTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster); void FillRaidOrPartyHealthPriorityTargets(UnitList &targetUnitMap, Unit* member, Unit* center, float radius, uint32 count, bool raid, bool withPets, bool withcaster); @@ -696,23 +696,58 @@ namespace MaNGOS float i_radius; SpellTargets i_TargetType; WorldObject* i_originalCaster; + WorldObject* i_castingObject; bool i_playerControlled; + float i_centerX; + float i_centerY; + + float GetCenterX() const { return i_centerX; } + float GetCenterY() const { return i_centerY; } SpellNotifierCreatureAndPlayer(Spell &spell, Spell::UnitList &data, float radius, SpellNotifyPushType type, SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY, WorldObject* originalCaster = NULL) : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType), - i_originalCaster(originalCaster) + i_originalCaster(originalCaster), i_castingObject(i_spell.GetCastingObject()) { if (!i_originalCaster) i_originalCaster = i_spell.GetAffectiveCasterObject(); i_playerControlled = i_originalCaster ? i_originalCaster->IsControlledByPlayer() : false; + + switch(i_push_type) + { + case PUSH_IN_FRONT: + case PUSH_IN_FRONT_90: + case PUSH_IN_FRONT_30: + case PUSH_IN_FRONT_15: + case PUSH_IN_BACK: + case PUSH_SELF_CENTER: + if (i_castingObject) + { + i_centerX = i_castingObject->GetPositionX(); + i_centerY = i_castingObject->GetPositionY(); + } + break; + case PUSH_DEST_CENTER: + i_centerX = i_spell.m_targets.m_destX; + i_centerY = i_spell.m_targets.m_destY; + break; + case PUSH_TARGET_CENTER: + if (Unit* target = i_spell.m_targets.getUnitTarget()) + { + i_centerX = target->GetPositionX(); + i_centerY = target->GetPositionY(); + } + break; + default: + sLog.outError("SpellNotifierCreatureAndPlayer: unsupported PUSH_* case %u.", i_push_type); + } } template inline void Visit(GridRefManager &m) { MANGOS_ASSERT(i_data); - if(!i_originalCaster) + if (!i_originalCaster || !i_castingObject) return; for(typename GridRefManager::iterator itr = m.begin(); itr != m.end(); ++itr) @@ -768,35 +803,35 @@ namespace MaNGOS switch(i_push_type) { case PUSH_IN_FRONT: - if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, 2*M_PI_F/3 )) + if (i_castingObject->isInFront((Unit*)(itr->getSource()), i_radius, 2*M_PI_F/3 )) i_data->push_back(itr->getSource()); break; case PUSH_IN_FRONT_90: - if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/2 )) + if (i_castingObject->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/2 )) i_data->push_back(itr->getSource()); break; case PUSH_IN_FRONT_30: - if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/6 )) + if (i_castingObject->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/6 )) i_data->push_back(itr->getSource()); break; case PUSH_IN_FRONT_15: - if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/12 )) + if (i_castingObject->isInFront((Unit*)(itr->getSource()), i_radius, M_PI_F/12 )) i_data->push_back(itr->getSource()); break; case PUSH_IN_BACK: - if(i_spell.GetCaster()->isInBack((Unit*)(itr->getSource()), i_radius, 2*M_PI_F/3 )) + if (i_castingObject->isInBack((Unit*)(itr->getSource()), i_radius, 2*M_PI_F/3 )) i_data->push_back(itr->getSource()); break; case PUSH_SELF_CENTER: - if(i_spell.GetCaster()->IsWithinDist((Unit*)(itr->getSource()), i_radius)) + if (i_castingObject->IsWithinDist((Unit*)(itr->getSource()), i_radius)) i_data->push_back(itr->getSource()); break; case PUSH_DEST_CENTER: - if(itr->getSource()->IsWithinDist3d(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) + if (itr->getSource()->IsWithinDist3d(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) i_data->push_back(itr->getSource()); break; case PUSH_TARGET_CENTER: - if(i_spell.m_targets.getUnitTarget()->IsWithinDist((Unit*)(itr->getSource()), i_radius)) + if (i_spell.m_targets.getUnitTarget() && i_spell.m_targets.getUnitTarget()->IsWithinDist((Unit*)(itr->getSource()), i_radius)) i_data->push_back(itr->getSource()); break; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 61b854f42..0dee5fcfd 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 "11423" + #define REVISION_NR "11424" #endif // __REVISION_NR_H__