Changed cPath to have a reset method.
Also reverts "Changed raw cPath to an unique_ptr, fixes memory leak"
This reverts commit 1515d37684
.
This commit is contained in:
parent
0fb8646198
commit
2c0ca0b4c3
@ -39,34 +39,7 @@ cPath::cPath(
|
|||||||
m_Chunk(&a_Chunk),
|
m_Chunk(&a_Chunk),
|
||||||
m_BadChunkFound(false)
|
m_BadChunkFound(false)
|
||||||
{
|
{
|
||||||
// TODO: if src not walkable OR dest not walkable, then abort.
|
ResetImpl(a_StartingPoint, a_EndingPoint, a_BoundingBoxWidth, a_BoundingBoxHeight);
|
||||||
// Borrow a new "isWalkable" from ProcessIfWalkable, make ProcessIfWalkable also call isWalkable
|
|
||||||
|
|
||||||
a_BoundingBoxWidth = 1; // Until we improve physics, if ever.
|
|
||||||
|
|
||||||
m_BoundingBoxWidth = CeilC(a_BoundingBoxWidth);
|
|
||||||
m_BoundingBoxHeight = CeilC(a_BoundingBoxHeight);
|
|
||||||
m_HalfWidth = a_BoundingBoxWidth / 2;
|
|
||||||
|
|
||||||
int HalfWidthInt = FloorC(a_BoundingBoxWidth / 2);
|
|
||||||
m_Source.x = FloorC(a_StartingPoint.x - HalfWidthInt);
|
|
||||||
m_Source.y = FloorC(a_StartingPoint.y);
|
|
||||||
m_Source.z = FloorC(a_StartingPoint.z - HalfWidthInt);
|
|
||||||
|
|
||||||
m_Destination.x = FloorC(a_EndingPoint.x - HalfWidthInt);
|
|
||||||
m_Destination.y = FloorC(a_EndingPoint.y);
|
|
||||||
m_Destination.z = FloorC(a_EndingPoint.z - HalfWidthInt);
|
|
||||||
|
|
||||||
if (GetCell(m_Source)->m_IsSolid || GetCell(m_Destination)->m_IsSolid)
|
|
||||||
{
|
|
||||||
m_Status = ePathFinderStatus::PATH_NOT_FOUND;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_NearestPointToTarget = GetCell(m_Source);
|
|
||||||
m_Status = ePathFinderStatus::CALCULATING;
|
|
||||||
|
|
||||||
ProcessCell(GetCell(m_Source), nullptr, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cPath::cPath() : m_IsValid(false)
|
cPath::cPath() : m_IsValid(false)
|
||||||
@ -497,3 +470,64 @@ cPathCell * cPath::GetCell(const Vector3i & a_Location)
|
|||||||
return &m_Map[a_Location];
|
return &m_Map[a_Location];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPath::ResetImpl(
|
||||||
|
const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint,
|
||||||
|
double a_BoundingBoxWidth, double a_BoundingBoxHeight
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// TODO: if src not walkable OR dest not walkable, then abort.
|
||||||
|
// Borrow a new "isWalkable" from ProcessIfWalkable, make ProcessIfWalkable also call isWalkable
|
||||||
|
|
||||||
|
a_BoundingBoxWidth = 1; // Until we improve physics, if ever.
|
||||||
|
|
||||||
|
m_BoundingBoxWidth = CeilC(a_BoundingBoxWidth);
|
||||||
|
m_BoundingBoxHeight = CeilC(a_BoundingBoxHeight);
|
||||||
|
m_HalfWidth = a_BoundingBoxWidth / 2;
|
||||||
|
|
||||||
|
int HalfWidthInt = FloorC(a_BoundingBoxWidth / 2);
|
||||||
|
m_Source.x = FloorC(a_StartingPoint.x - HalfWidthInt);
|
||||||
|
m_Source.y = FloorC(a_StartingPoint.y);
|
||||||
|
m_Source.z = FloorC(a_StartingPoint.z - HalfWidthInt);
|
||||||
|
|
||||||
|
m_Destination.x = FloorC(a_EndingPoint.x - HalfWidthInt);
|
||||||
|
m_Destination.y = FloorC(a_EndingPoint.y);
|
||||||
|
m_Destination.z = FloorC(a_EndingPoint.z - HalfWidthInt);
|
||||||
|
|
||||||
|
if (GetCell(m_Source)->m_IsSolid || GetCell(m_Destination)->m_IsSolid)
|
||||||
|
{
|
||||||
|
m_Status = ePathFinderStatus::PATH_NOT_FOUND;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_NearestPointToTarget = GetCell(m_Source);
|
||||||
|
m_Status = ePathFinderStatus::CALCULATING;
|
||||||
|
|
||||||
|
ProcessCell(GetCell(m_Source), nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPath::Reset(
|
||||||
|
cChunk & a_Chunk,
|
||||||
|
const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint, int a_MaxSteps,
|
||||||
|
double a_BoundingBoxWidth, double a_BoundingBoxHeight,
|
||||||
|
int a_MaxUp, int a_MaxDown
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_Map.clear();
|
||||||
|
m_OpenList = decltype(m_OpenList){};
|
||||||
|
m_StepsLeft = a_MaxSteps;
|
||||||
|
m_IsValid = true;
|
||||||
|
m_CurrentPoint = 0; // GetNextPoint increments this to 1, but that's fine, since the first cell is always a_StartingPoint
|
||||||
|
m_Chunk = &a_Chunk;
|
||||||
|
m_BadChunkFound = false;
|
||||||
|
ResetImpl(a_StartingPoint, a_EndingPoint, a_BoundingBoxWidth, a_BoundingBoxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ public:
|
|||||||
cPath(const cPath & a_other) = delete;
|
cPath(const cPath & a_other) = delete;
|
||||||
cPath(cPath && a_other) = delete;
|
cPath(cPath && a_other) = delete;
|
||||||
|
|
||||||
|
/** delete default assignment operators */
|
||||||
cPath & operator=(const cPath & a_other) = delete;
|
cPath & operator=(const cPath & a_other) = delete;
|
||||||
cPath & operator=(cPath && a_other) = delete;
|
cPath & operator=(cPath && a_other) = delete;
|
||||||
|
|
||||||
@ -136,6 +137,31 @@ public:
|
|||||||
return m_PathPoints.size() - m_CurrentPoint;
|
return m_PathPoints.size() - m_CurrentPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Recreates a pathfinder instance. A Mob will probably need a single pathfinder instance for its entire life.
|
||||||
|
|
||||||
|
Note that if you have a man-sized mob (1x1x2, zombies, etc), you are advised to call this function without parameters
|
||||||
|
because the declaration might change in later version of the pathFinder, and a parameter-less call always assumes a man-sized mob.
|
||||||
|
|
||||||
|
If your mob is not man-sized, you are advised to use cPath(width, height), this would be compatible with future versions,
|
||||||
|
but please be aware that as of now those parameters will be ignored and your mob will be assumed to be man sized.
|
||||||
|
|
||||||
|
@param a_BoundingBoxWidth the character's boundingbox width in blocks. Currently the parameter is ignored and 1 is assumed.
|
||||||
|
@param a_BoundingBoxHeight the character's boundingbox width in blocks. Currently the parameter is ignored and 2 is assumed.
|
||||||
|
@param a_MaxUp the character's max jump height in blocks. Currently the parameter is ignored and 1 is assumed.
|
||||||
|
@param a_MaxDown How far is the character willing to fall? Currently the parameter is ignored and 1 is assumed. */
|
||||||
|
/** Attempts to find a path starting from source to destination.
|
||||||
|
After calling this, you are expected to call Step() once per tick or once per several ticks until it returns true. You should then call getPath() to obtain the path.
|
||||||
|
Calling this before a path is found resets the current path and starts another search.
|
||||||
|
@param a_StartingPoint The function expects this position to be the lowest block the mob is in, a rule of thumb: "The block where the Zombie's knees are at".
|
||||||
|
@param a_EndingPoint "The block where the Zombie's knees want to be".
|
||||||
|
@param a_MaxSteps The maximum steps before giving up. */
|
||||||
|
void Reset(
|
||||||
|
cChunk & a_Chunk,
|
||||||
|
const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint, int a_MaxSteps,
|
||||||
|
double a_BoundingBoxWidth, double a_BoundingBoxHeight,
|
||||||
|
int a_MaxUp = 1, int a_MaxDown = 1
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +174,11 @@ private:
|
|||||||
void FinishCalculation(ePathFinderStatus a_NewStatus); // Clears the memory used for calculating the path and changes the status.
|
void FinishCalculation(ePathFinderStatus a_NewStatus); // Clears the memory used for calculating the path and changes the status.
|
||||||
void AttemptToFindAlternative();
|
void AttemptToFindAlternative();
|
||||||
void BuildPath();
|
void BuildPath();
|
||||||
|
/** Handles all logic associated with reseting the path to a clean state */
|
||||||
|
void ResetImpl(
|
||||||
|
const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint,
|
||||||
|
double a_BoundingBoxWidth, double a_BoundingBoxHeight
|
||||||
|
);
|
||||||
|
|
||||||
/* Openlist and closedlist management */
|
/* Openlist and closedlist management */
|
||||||
void OpenListAdd(cPathCell * a_Cell);
|
void OpenListAdd(cPathCell * a_Cell);
|
||||||
|
@ -46,17 +46,17 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If m_Path has not been initialized yet, initialize it.
|
// If m_Path has not been initialized yet, initialize it.
|
||||||
if (!m_Path->IsValid())
|
if (!m_Path.IsValid())
|
||||||
{
|
{
|
||||||
ResetPathFinding(a_Chunk);
|
ResetPathFinding(a_Chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_Path->CalculationStep(a_Chunk))
|
switch (m_Path.CalculationStep(a_Chunk))
|
||||||
{
|
{
|
||||||
case ePathFinderStatus::NEARBY_FOUND:
|
case ePathFinderStatus::NEARBY_FOUND:
|
||||||
{
|
{
|
||||||
m_NoPathToTarget = true;
|
m_NoPathToTarget = true;
|
||||||
m_PathDestination = m_Path->AcceptNearbyPath();
|
m_PathDestination = m_Path.AcceptNearbyPath();
|
||||||
if (a_DontCare)
|
if (a_DontCare)
|
||||||
{
|
{
|
||||||
m_FinalDestination = m_PathDestination;
|
m_FinalDestination = m_PathDestination;
|
||||||
@ -89,7 +89,7 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d
|
|||||||
return ePathFinderStatus::CALCULATING;
|
return ePathFinderStatus::CALCULATING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Path->NoMoreWayPoints())
|
if (m_Path.NoMoreWayPoints())
|
||||||
{
|
{
|
||||||
// We're always heading towards m_PathDestination.
|
// We're always heading towards m_PathDestination.
|
||||||
// If m_PathDestination is exactly m_FinalDestination, then we're about to reach the destination.
|
// If m_PathDestination is exactly m_FinalDestination, then we're about to reach the destination.
|
||||||
@ -108,10 +108,10 @@ ePathFinderStatus cPathFinder::GetNextWayPoint(cChunk & a_Chunk, const Vector3d
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (m_Path->IsFirstPoint() || ((m_WayPoint - m_Source).SqrLength() < WAYPOINT_RADIUS))
|
if (m_Path.IsFirstPoint() || ((m_WayPoint - m_Source).SqrLength() < WAYPOINT_RADIUS))
|
||||||
{
|
{
|
||||||
// if the mob has just started or if the mob reached a waypoint, give them a new waypoint.
|
// if the mob has just started or if the mob reached a waypoint, give them a new waypoint.
|
||||||
m_WayPoint = m_Path->GetNextPoint();
|
m_WayPoint = m_Path.GetNextPoint();
|
||||||
m_GiveUpCounter = 40;
|
m_GiveUpCounter = 40;
|
||||||
return ePathFinderStatus::PATH_FOUND;
|
return ePathFinderStatus::PATH_FOUND;
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ void cPathFinder::ResetPathFinding(cChunk &a_Chunk)
|
|||||||
m_NoPathToTarget = false;
|
m_NoPathToTarget = false;
|
||||||
m_PathDestination = m_FinalDestination;
|
m_PathDestination = m_FinalDestination;
|
||||||
m_DeviationOrigin = m_PathDestination;
|
m_DeviationOrigin = m_PathDestination;
|
||||||
m_Path.reset(new cPath(a_Chunk, m_Source, m_PathDestination, 20, m_Width, m_Height));
|
m_Path.Reset(a_Chunk, m_Source, m_PathDestination, 20, m_Width, m_Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ bool cPathFinder::EnsureProperDestination(cChunk & a_Chunk)
|
|||||||
|
|
||||||
bool cPathFinder::PathIsTooOld() const
|
bool cPathFinder::PathIsTooOld() const
|
||||||
{
|
{
|
||||||
size_t acceptableDeviation = m_Path->WayPointsLeft() / 2;
|
size_t acceptableDeviation = m_Path.WayPointsLeft() / 2;
|
||||||
if (acceptableDeviation == 0)
|
if (acceptableDeviation == 0)
|
||||||
{
|
{
|
||||||
acceptableDeviation = 1;
|
acceptableDeviation = 1;
|
||||||
|
@ -52,7 +52,7 @@ private:
|
|||||||
double m_Height;
|
double m_Height;
|
||||||
|
|
||||||
/** The current cPath instance we have. This is discarded and recreated when a path recalculation is needed. */
|
/** The current cPath instance we have. This is discarded and recreated when a path recalculation is needed. */
|
||||||
std::unique_ptr<cPath> m_Path;
|
cPath m_Path;
|
||||||
|
|
||||||
/** If 0, will give up reaching the next m_WayPoint and will recalculate path. */
|
/** If 0, will give up reaching the next m_WayPoint and will recalculate path. */
|
||||||
int m_GiveUpCounter;
|
int m_GiveUpCounter;
|
||||||
|
Loading…
Reference in New Issue
Block a user