aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorHelloKitty <andrew.blakely@ymail.com>2017-01-21 14:44:31 +0100
committerShauren <shauren.trinity@gmail.com>2018-12-09 14:18:42 +0100
commit46c69df3a7cd3f863a7a3cca59a136a0a5cdec9d (patch)
tree4c7c6df7b9ca316c3086478b5a69127d4a64a769 /src/server
parentda3783876b141f716d5daf09f9d69d8248a8382a (diff)
Core/Vmaps: Stop M2s from occluding for spellcast LoS
Closes #18528 (cherry-picked from 01d715eaef99e91f0959dc85fb7f69eb26d01a22)
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Entities/Object/Object.cpp8
-rw-r--r--src/server/game/Entities/Object/Object.h5
-rw-r--r--src/server/game/Maps/Map.cpp4
-rw-r--r--src/server/game/Maps/Map.h3
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp18
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp1
7 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 359f0ef0652..47e07803819 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1671,7 +1671,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;
@@ -1682,7 +1682,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
@@ -1759,7 +1759,7 @@ bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare,
return obj && IsInMap(obj) && IsInPhase(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);
@@ -1773,7 +1773,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
else
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
- return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f);
+ return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, ignoreFlags);
}
return true;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 2ebea15a58d..7823a2a2a68 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -22,6 +22,7 @@
#include "Common.h"
#include "GridReference.h"
#include "GridRefManager.h"
+#include "ModelIgnoreFlags.h"
#include "MovementInfo.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
@@ -449,8 +450,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 e840569672e..dfd8b7fd5b7 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2878,9 +2878,9 @@ float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const
return 0;
}
-bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const
+bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, VMAP::ModelIgnoreFlags ignoreFlags) const
{
- return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2)
+ return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags)
&& _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift);
}
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 7d453f0406a..5498b097b54 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -67,6 +67,7 @@ enum WeatherState : uint32;
namespace Trinity { struct ObjectUpdater; }
namespace G3D { class Plane; }
+namespace VMAP { enum class ModelIgnoreFlags : uint32; }
struct ScriptAction
{
@@ -493,7 +494,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
- bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const;
+ bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, 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 c4cd065ccbf..f3e3f7db303 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -54,7 +54,7 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
Position mypos = owner->GetPosition();
bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(
PhasingHandler::GetTerrainMapId(owner->GetPhaseShift(), owner->GetMap(), mypos.m_positionX, mypos.m_positionY),
- mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 2.0f, x, y, z + 2.0f);
+ mypos.m_positionX, mypos.m_positionY, mypos.m_positionZ + 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 5775b5e496a..e6130a9d08a 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1958,7 +1958,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;
@@ -1973,10 +1973,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;
}
}
@@ -5071,7 +5071,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;
}
}
@@ -5083,7 +5083,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;
}
@@ -5366,6 +5366,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
@@ -6916,7 +6920,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect,
/// @todo shit below shouldn't be here, but it's temporary
//Check targets for LOS visibility
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
@@ -6925,7 +6929,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect,
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;
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
index a3d600830f5..79a0f293fb2 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
@@ -20,6 +20,7 @@
#include "MotionMaster.h"
#include "ruby_sanctum.h"
#include "ScriptedCreature.h"
+#include "SpellMgr.h"
#include "SpellScript.h"
enum Texts