Skip to content

Commit

Permalink
Core/VMaps: Fix some vmap height edge cases
Browse files Browse the repository at this point in the history
Fix Map::GetWaterOrGroundLevel() checking dynamic object only in phase 1 instead of current Unit phase.
Improve DynamicMapTree::getHeight() dynamic object check by casting the ray at +0.5f from the passed Z coordinate, this value will be tuned to improve even more the results.
  • Loading branch information
jackpoz committed Jun 4, 2016
1 parent 911bffd commit 1347d7c
Show file tree
Hide file tree
Showing 7 changed files with 9 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/common/Collision/DynamicTree.cpp
Expand Up @@ -248,7 +248,7 @@ bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, flo

float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
{
G3D::Vector3 v(x, y, z);
G3D::Vector3 v(x, y, z + 0.5f);
G3D::Ray r(v, G3D::Vector3(0, 0, -1));
DynamicTreeIntersectionCallback callback(phasemask);
impl->intersectZAllignedRay(r, callback, maxSearchDist);
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Entities/Object/Object.cpp
Expand Up @@ -1445,7 +1445,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
bool canSwim = ToCreature()->CanSwim();
float ground_z = z;
float max_z = canSwim
? GetMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
? GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
: ((ground_z = GetMap()->GetHeight(GetPhaseMask(), x, y, z, true)));
if (max_z > INVALID_HEIGHT)
{
Expand All @@ -1469,7 +1469,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
if (!ToPlayer()->CanFly())
{
float ground_z = z;
float max_z = GetMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
if (max_z > INVALID_HEIGHT)
{
if (z > max_z)
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Entities/Unit/Unit.cpp
Expand Up @@ -16754,7 +16754,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Movement::MoveSplineInit init(this);

// Creatures without inhabit type air should begin falling after exiting the vehicle
if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
init.SetFall();

init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Maps/Map.cpp
Expand Up @@ -2299,12 +2299,12 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}

float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const
float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(PHASEMASK_NORMAL, x, y, z, true, 50.0f);
float ground_z = GetHeight(phasemask, x, y, z, true, 50.0f);
if (ground)
*ground = ground_z;

Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Maps/Map.h
Expand Up @@ -494,7 +494,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; }
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; }

float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const;
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;
void Balance() { _dynamicTree.balance(); }
Expand Down
Expand Up @@ -57,7 +57,7 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
// Limit height change
const float distanceZ = float(rand_norm()) * travelDistZ/2.0f;
destZ = respZ + distanceZ;
float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);
float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseMask(), destX, destY, destZ-2.5f);

// Problem here, we must fly above the ground and water, not under. Let's try on next tick
if (levelZ >= destZ)
Expand Down
2 changes: 1 addition & 1 deletion src/server/scripts/Northrend/zone_sholazar_basin.cpp
Expand Up @@ -780,7 +780,7 @@ class spell_q12589_shoot_rjr : public SpellScriptLoader

bird->KillSelf();
crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseMask(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
/// @todo Make crunchy perform emote eat when he reaches the bird

break;
Expand Down

0 comments on commit 1347d7c

Please sign in to comment.