aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Object/Object.cpp35
-rw-r--r--src/server/game/Entities/Object/Object.h2
-rw-r--r--src/server/game/Maps/Map.cpp25
-rw-r--r--src/server/game/Maps/Map.h1
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Spells/Spell.cpp3
9 files changed, 56 insertions, 20 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index cbc607e7b66..0b53fa7cf4b 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1250,11 +1250,16 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
z = new_z + (isType(TYPEMASK_UNIT) ? static_cast<Unit const*>(this)->GetHoverOffset() : 0.0f);
}
-void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
+void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ) const
{
// TODO: Allow transports to be part of dynamic vmap tree
if (GetTransport())
+ {
+ if (groundZ)
+ *groundZ = z;
+
return;
+ }
if (Unit const* unit = ToUnit())
{
@@ -1280,12 +1285,18 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
else if (z < ground_z)
z = ground_z;
}
+
+ if (groundZ)
+ *groundZ = ground_z;
}
else
{
float ground_z = GetMapHeight(x, y, z) + unit->GetHoverOffset();
if (z < ground_z)
z = ground_z;
+
+ if (groundZ)
+ *groundZ = ground_z;
}
}
else
@@ -1293,6 +1304,9 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
float ground_z = GetMapHeight(x, y, z);
if (ground_z > INVALID_HEIGHT)
z = ground_z;
+
+ if (groundZ)
+ *groundZ = ground_z;
}
}
@@ -3102,10 +3116,27 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
}
}
+ float groundZ = VMAP_INVALID_HEIGHT_VALUE;
Trinity::NormalizeMapCoord(pos.m_positionX);
Trinity::NormalizeMapCoord(pos.m_positionY);
- UpdateAllowedPositionZ(destx, desty, pos.m_positionZ);
+ UpdateAllowedPositionZ(destx, desty, pos.m_positionZ, &groundZ);
pos.SetOrientation(GetOrientation());
+
+ // position has no ground under it (or is too far away)
+ if (groundZ <= INVALID_HEIGHT)
+ {
+ if (Unit const* unit = ToUnit())
+ {
+ // unit can fly, ignore.
+ if (unit->CanFly())
+ return;
+
+ // fall back to gridHeight if any
+ float gridHeight = GetMap()->GetGridHeight(GetPhaseShift(), pos.m_positionX, pos.m_positionY);
+ if (gridHeight > INVALID_HEIGHT)
+ pos.m_positionZ = gridHeight + unit->GetHoverOffset();
+ }
+ }
}
void WorldObject::PlayDistanceSound(uint32 soundId, Player* target /*= nullptr*/)
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 8af47209787..24c48e8ccb6 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -433,7 +433,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
virtual float GetCombatReach() const { return 0.0f; } // overridden (only) in Unit
void UpdateGroundPositionZ(float x, float y, float &z) const;
- void UpdateAllowedPositionZ(float x, float y, float &z) const;
+ void UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ = nullptr) const;
void GetRandomPoint(Position const& srcPos, float distance, float& rand_x, float& rand_y, float& rand_z) const;
Position GetRandomPoint(Position const& srcPos, float distance) const;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 20a8a3b32bf..8b72da34de0 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2537,12 +2537,9 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
// find raw .map surface under Z coordinates
float mapHeight = VMAP_INVALID_HEIGHT_VALUE;
uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y);
- if (GridMap* gmap = GetGrid(terrainMapId, x, y))
- {
- float gridHeight = gmap->getHeight(x, y);
- if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE))
- mapHeight = gridHeight;
- }
+ float gridHeight = GetGridHeight(phaseShift, x, y);
+ if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE))
+ mapHeight = gridHeight;
float vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
if (checkVMap)
@@ -2564,16 +2561,24 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float
// or if the distance of the vmap height is less the land height distance
if (vmapHeight > mapHeight || std::fabs(mapHeight - z) > std::fabs(vmapHeight - z))
return vmapHeight;
- else
- return mapHeight; // better use .map surface height
+
+ return mapHeight; // better use .map surface height
}
- else
- return vmapHeight; // we have only vmapHeight (if have)
+
+ return vmapHeight; // we have only vmapHeight (if have)
}
return mapHeight; // explicitly use map data
}
+float Map::GetGridHeight(PhaseShift const& phaseShift, float x, float y)
+{
+ if (GridMap* gmap = GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
+ return gmap->getHeight(x, y);
+
+ return VMAP_INVALID_HEIGHT_VALUE;
+}
+
float Map::GetMinHeight(PhaseShift const& phaseShift, float x, float y)
{
if (GridMap const* grid = GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 15b986cad26..ee6f0b293be 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -495,6 +495,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, float collisionHeight = 2.03128f); // DEFAULT_COLLISION_HEIGHT in Object.h
float GetMinHeight(PhaseShift const& phaseShift, float x, float y);
+ float GetGridHeight(PhaseShift const& phaseShift, float x, float y);
float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH);
float GetStaticHeight(PhaseShift const& phaseShift, Position const& pos, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) { return GetStaticHeight(phaseShift, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), checkVMap, maxSearchDist); }
float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) { return std::max<float>(GetStaticHeight(phaseShift, x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phaseShift, x, y, z, maxSearchDist)); }
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
index 0f6c2a0f1f1..b7a9ab32f13 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
@@ -99,7 +99,7 @@ bool ConfusedMovementGenerator<T>::DoUpdate(T* owner, uint32 diff)
}
bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
- if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT))
{
_timer.Reset(100);
return true;
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index 88eb379e1a2..26aaf495c2e 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -165,7 +165,7 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
}
bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
- if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT))
{
_timer.Reset(100);
return;
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 663b86e7145..130a9dc5e8f 100644
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -107,7 +107,7 @@ void RandomMovementGenerator<Creature>::SetRandomLocation(Creature* owner)
}
bool result = _path->CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
- if (!result || (_path->GetPathType() & PATHFIND_NOPATH))
+ if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT))
{
_timer.Reset(100);
return;
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index fd1ebf73c9f..e8c64195910 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -536,14 +536,14 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
/// @todo check the exact cases
TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount);
BuildShortcut();
- _type = PATHFIND_NOPATH;
+ _type = PathType(_type | PATHFIND_NOPATH);
return;
}
else if (pointCount == _pointPathLimit)
{
TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d", pointCount, _pointPathLimit);
BuildShortcut();
- _type = PATHFIND_SHORT;
+ _type = PathType(_type | PATHFIND_SHORT);
return;
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 48fac208658..40949c52d6b 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1374,9 +1374,8 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectIn
pos.m_positionX = m_preGeneratedPath->GetActualEndPosition().x;
pos.m_positionY = m_preGeneratedPath->GetActualEndPosition().y;
pos.m_positionZ = m_preGeneratedPath->GetActualEndPosition().z;
+ dest.Relocate(pos);
}
-
- dest.Relocate(pos);
break;
}
case TARGET_DEST_CASTER_GROUND: