diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 5 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.h | 3 | ||||
| -rw-r--r-- | src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 18 |
6 files changed, 24 insertions, 17 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cc95820d97d..d90a5873f92 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1149,7 +1149,7 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool return distsq < maxdist * maxdist; } -bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const +bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlags ignoreFlags) const { if (!IsInMap(obj)) return false; @@ -1160,7 +1160,7 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const else obj->GetHitSpherePointFor(GetPosition(), x, y, z); - return IsWithinLOS(x, y, z); + return IsWithinLOS(x, y, z, ignoreFlags); } float WorldObject::GetDistance(const WorldObject* obj) const @@ -1237,7 +1237,7 @@ bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); } -bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const +bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFlags ignoreFlags) const { /*float x, y, z; GetPosition(x, y, z); @@ -1251,7 +1251,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const else GetHitSpherePointFor({ ox, oy, oz }, x, y, z); - return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhaseMask()); + return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhaseMask(), ignoreFlags); } return true; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 018964000b5..2dfb671353a 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -25,6 +25,7 @@ #include "GridReference.h" #include "ObjectDefines.h" #include "Map.h" +#include "ModelIgnoreFlags.h" #include <set> #include <string> @@ -489,8 +490,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation // use only if you will sure about placing both object at same map bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const; bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const; - bool IsWithinLOS(float x, float y, float z) const; - bool IsWithinLOSInMap(WorldObject const* obj) const; + bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; + bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; Position GetHitSpherePointFor(Position const& dest) const; void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const; bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 262597fd608..d649a12227f 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2593,9 +2593,9 @@ float Map::GetWaterLevel(float x, float y) const return 0; } -bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const +bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, VMAP::ModelIgnoreFlags ignoreFlags) const { - return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2) + return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2, ignoreFlags) && _dynamicTree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask); } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 14d56af7ecf..c87726bba57 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -55,6 +55,7 @@ class BattlegroundMap; class InstanceMap; class Transport; namespace Trinity { struct ObjectUpdater; } +namespace VMAP { enum class ModelIgnoreFlags : uint32; } struct ScriptAction { @@ -496,7 +497,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground = NULL, bool swim = false) const; float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; - bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const; + bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, VMAP::ModelIgnoreFlags ignoreFlags) const; void Balance() { _dynamicTree.balance(); } void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); } void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index e082e5f8ff2..6bf8d0affdd 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -55,7 +55,8 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner) mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 2.0f, - x, y, z + 2.0f); + x, y, z + 2.0f, + VMAP::ModelIgnoreFlags::Nothing); if (!isInLOS) { i_nextCheckTime.Reset(200); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d2612ba1bdf..48de05493e4 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1895,7 +1895,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar if (Unit* unit = (*itr)->ToUnit()) { uint32 deficit = unit->GetMaxHealth() - unit->GetHealth(); - if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit)) + if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2)) { foundItr = itr; maxHPDeficit = deficit; @@ -1910,10 +1910,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar { if (foundItr == tempTargets.end()) { - if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr)) + if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2)) foundItr = itr; } - else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr)) + else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2)) foundItr = itr; } } @@ -5004,7 +5004,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)) + 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, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } } @@ -5016,7 +5016,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)) + 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, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } @@ -5258,6 +5258,10 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (!target) return SPELL_FAILED_DONT_REPORT; + // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells + if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2 + return SPELL_FAILED_LINE_OF_SIGHT; + float objSize = target->GetObjectSize(); float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict @@ -6786,7 +6790,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo default: // normal case { if (losPosition) - return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ()); + return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ(), VMAP::ModelIgnoreFlags::M2); else { // Get GO cast coordinates if original caster -> GO @@ -6795,7 +6799,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID); if (!caster) caster = m_caster; - if (target != m_caster && !target->IsWithinLOSInMap(caster)) + if (target != m_caster && !target->IsWithinLOSInMap(caster, VMAP::ModelIgnoreFlags::M2)) return false; } break; |
