Core/MMaps: Add several safety checks to confirm a valid path generation.

- Address some issues in TargetMovementGenerator. Thanks Chevron
This commit is contained in:
kaelima
2012-09-07 04:21:11 +02:00
parent 0522e50c86
commit a2d533752c
8 changed files with 46 additions and 40 deletions

View File

@@ -295,4 +295,4 @@ namespace MMAP
return mmap->navMeshQueries[instanceId];
}
}
}

View File

@@ -2780,7 +2780,7 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
desty = pos.m_positionY + dist * sin(angle);
// Prevent invalid coordinates here, position is unchanged
if (!Trinity::IsValidMapCoord(destx, desty))
if (!Trinity::IsValidMapCoord(destx, desty, pos.m_positionZ))
{
sLog->outFatal(LOG_FILTER_GENERAL, "WorldObject::MovePosition invalid coordinates X: %f and Y: %f were passed!", destx, desty);
return;

View File

@@ -78,8 +78,8 @@ bool ConfusedMovementGenerator<T>::Update(T* unit, const uint32& diff)
PathGenerator path(unit);
path.SetPathLengthLimit(30.0f);
path.CalculatePath(x, y, z);
if (path.GetPathType() & PATHFIND_NOPATH)
bool result = path.CalculatePath(x, y, z);
if (!result || path.GetPathType() & PATHFIND_NOPATH)
{
i_nextMoveTime.Reset(urand(800, 1000));
return true;

View File

@@ -45,8 +45,8 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
PathGenerator path(owner);
path.SetPathLengthLimit(30.0f);
path.CalculatePath(x, y, z);
if (path.GetPathType() & PATHFIND_NOPATH)
bool result = path.CalculatePath(x, y, z);
if (!result || path.GetPathType() & PATHFIND_NOPATH)
{
i_nextCheckTime.Reset(urand(1000, 1500));
return;

View File

@@ -35,30 +35,28 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner)
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))
return;
if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()))
return;
float x, y, z;
//! Following block of code deleted by MrSmite in issue 4891
//! Code kept for learning and diagnostical purposes
//
// if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
// {
// if (!owner.movespline->Finalized())
// return;
//
// owner.GetPosition(x, y, z);
// }
// else
if (!i_offset)
{
if (i_target->IsWithinMeleeRange(owner))
return;
float dist = 0.0f;
// to nearest random contact position
i_target->GetRandomContactPoint(owner, x, y, z, 0, MELEE_RANGE - 0.5f);
if (owner->getVictim() && owner->getVictim()->GetGUID() == i_target->GetGUID())
dist = owner->GetFloatValue(UNIT_FIELD_COMBATREACH) + i_target->GetFloatValue(UNIT_FIELD_COMBATREACH) - i_target->GetObjectSize() - owner->GetObjectSize() - 1.0f;
if (dist < 0.5f)
dist = 0.5f;
if (owner->IsWithinLOSInMap(owner->getVictim()))
i_target->GetContactPoint(owner, x, y, z, dist);
else
i_target->GetPosition(x, y, z);
}
else
{
if (i_target->IsWithinDistInMap(owner, i_offset + 1.0f))
return;
// to at i_offset distance from target and i_angle from target facing
i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle);
}
@@ -69,8 +67,9 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner)
// allow pets following their master to cheat while generating paths
bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet()
&& owner->HasUnitState(UNIT_STATE_FOLLOW));
i_path->CalculatePath(x, y, z, forceDest);
if (i_path->GetPathType() & PATHFIND_NOPATH)
bool result = i_path->CalculatePath(x, y, z, forceDest);
if (!result || i_path->GetPathType() & PATHFIND_NOPATH)
return;
D::_addUnitStateMove(owner);
@@ -117,7 +116,7 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T* owner, const uint32& time_d
return false;
if (!owner || !owner->isAlive())
return true;
return false;
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))
{
@@ -154,7 +153,7 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T* owner, const uint32& time_d
else
targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist);
if (targetMoved)
if (targetMoved || !owner->IsWithinLOSInMap(owner->getVictim()))
_setTargetLocation(owner);
}

View File

@@ -58,8 +58,12 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z))
return false;
float newDestZ = _sourceUnit->GetBaseMap()->GetHeight(_sourceUnit->GetPhaseMask(), x, y, z, true, MAX_FALL_DISTANCE);
if (newDestZ >= INVALID_HEIGHT)
return false;
Vector3 oldDest = GetEndPosition();
Vector3 dest(destX, destY, destZ);
Vector3 dest(destX, destY, newDestZ);
SetEndPosition(dest);
Vector3 start(x, y, z);
@@ -124,7 +128,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32
minDist3d = dtVdistSqr(point, closestPoint);
}
if(minDist2d < 1.0f) // shortcut out - close enough for us
if (minDist2d < 1.0f) // shortcut out - close enough for us
break;
}

View File

@@ -153,16 +153,18 @@ namespace Movement
if (generatePath)
{
PathGenerator path(unit);
path.CalculatePath(dest.x, dest.y, dest.z, forceDestination);
MovebyPath(path.GetPath());
}
else
{
args.path_Idx_offset = 0;
args.path.resize(2);
TransportPathTransform transform(unit, args.TransformForTransport);
args.path[1] = transform(dest);
bool result = path.CalculatePath(dest.x, dest.y, dest.z, forceDestination);
if (result && path.GetPathType() & ~PATHFIND_NOPATH)
{
MovebyPath(path.GetPath());
return;
}
}
args.path_Idx_offset = 0;
args.path.resize(2);
TransportPathTransform transform(unit, args.TransformForTransport);
args.path[1] = transform(dest);
}
Vector3 TransportPathTransform::operator()(Vector3 input)

View File

@@ -5162,10 +5162,11 @@ SpellCastResult Spell::CheckCast(bool strict)
target->GetFirstCollisionPosition(pos, CONTACT_DISTANCE, target->GetRelativeAngle(m_caster));
m_preGeneratedPath.SetPathLengthLimit(m_spellInfo->GetMaxRange(true) * 1.5f);
m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize());
bool result = m_preGeneratedPath.CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + target->GetObjectSize());
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
else if (!result)
return SPELL_FAILED_NOPATH;
break;
}