mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 00:18:43 +01:00
Core/MMaps: Add several safety checks to confirm a valid path generation.
- Address some issues in TargetMovementGenerator. Thanks Chevron
This commit is contained in:
@@ -295,4 +295,4 @@ namespace MMAP
|
||||
|
||||
return mmap->navMeshQueries[instanceId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user