Partial revert of #2446
This commit is contained in:
parent
30849b056f
commit
db40172b64
@ -78,6 +78,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A
|
|||||||
, m_IsFollowingPath(false)
|
, m_IsFollowingPath(false)
|
||||||
, m_PathfinderActivated(false)
|
, m_PathfinderActivated(false)
|
||||||
, m_GiveUpCounter(0)
|
, m_GiveUpCounter(0)
|
||||||
|
, m_TicksSinceLastPathReset(1000)
|
||||||
, m_LastGroundHeight(POSY_TOINT)
|
, m_LastGroundHeight(POSY_TOINT)
|
||||||
, m_JumpCoolDown(0)
|
, m_JumpCoolDown(0)
|
||||||
, m_IdleInterval(0)
|
, m_IdleInterval(0)
|
||||||
@ -128,6 +129,11 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (m_TicksSinceLastPathReset < 1000)
|
||||||
|
{
|
||||||
|
// No need to count beyond 1000. 1000 is arbitary here.
|
||||||
|
++m_TicksSinceLastPathReset;
|
||||||
|
}
|
||||||
|
|
||||||
if (ReachedFinalDestination())
|
if (ReachedFinalDestination())
|
||||||
{
|
{
|
||||||
@ -135,6 +141,26 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((m_FinalDestination - m_PathFinderDestination).Length() > 0.25) // if the distance between where we're going and where we should go is too big.
|
||||||
|
{
|
||||||
|
/* If we reached the last path waypoint,
|
||||||
|
Or if we haven't re-calculated for too long.
|
||||||
|
Interval is proportional to distance squared, and its minimum is 10.
|
||||||
|
(Recalculate lots when close, calculate rarely when far) */
|
||||||
|
if (
|
||||||
|
((GetPosition() - m_PathFinderDestination).Length() < 0.25) ||
|
||||||
|
((m_TicksSinceLastPathReset > 10) && (m_TicksSinceLastPathReset > (0.4 * (m_FinalDestination - GetPosition()).SqrLength())))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Re-calculating is expensive when there's no path to target, and it results in mobs freezing very often as a result of always recalculating.
|
||||||
|
This is a workaround till we get better path recalculation. */
|
||||||
|
if (!m_NoPathToTarget)
|
||||||
|
{
|
||||||
|
ResetPathFinding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_Path == nullptr)
|
if (m_Path == nullptr)
|
||||||
{
|
{
|
||||||
if (!EnsureProperDestination(a_Chunk))
|
if (!EnsureProperDestination(a_Chunk))
|
||||||
@ -143,16 +169,21 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_GiveUpCounter = 40;
|
m_GiveUpCounter = 40;
|
||||||
m_Path = new cPath(a_Chunk, GetPosition(), m_FinalDestination, 20, GetWidth(), GetHeight());
|
m_NoPathToTarget = false;
|
||||||
|
m_NoMoreWayPoints = false;
|
||||||
|
m_PathFinderDestination = m_FinalDestination;
|
||||||
|
m_Path = new cPath(a_Chunk, GetPosition(), m_PathFinderDestination, 20, GetWidth(), GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_Path->Step(a_Chunk))
|
switch (m_Path->Step(a_Chunk))
|
||||||
{
|
{
|
||||||
case ePathFinderStatus::NEARBY_FOUND:
|
case ePathFinderStatus::NEARBY_FOUND:
|
||||||
{
|
{
|
||||||
m_FinalDestination = m_Path->AcceptNearbyPath();
|
m_NoPathToTarget = true;
|
||||||
|
m_PathFinderDestination = m_Path->AcceptNearbyPath();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ePathFinderStatus::PATH_NOT_FOUND:
|
case ePathFinderStatus::PATH_NOT_FOUND:
|
||||||
{
|
{
|
||||||
StopMovingToPosition(); // Try to calculate a path again.
|
StopMovingToPosition(); // Try to calculate a path again.
|
||||||
@ -166,10 +197,9 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
|
|||||||
}
|
}
|
||||||
case ePathFinderStatus::PATH_FOUND:
|
case ePathFinderStatus::PATH_FOUND:
|
||||||
{
|
{
|
||||||
if ((--m_GiveUpCounter) == 0)
|
if (m_NoMoreWayPoints || (--m_GiveUpCounter == 0))
|
||||||
{
|
{
|
||||||
// Failed to reach a waypoint - that's a failure condition whichever point we're at
|
if (m_EMState == ATTACKING)
|
||||||
if (m_EMState == CHASING)
|
|
||||||
{
|
{
|
||||||
ResetPathFinding(); // Try to calculate a path again.
|
ResetPathFinding(); // Try to calculate a path again.
|
||||||
// This results in mobs hanging around an unreachable target (player).
|
// This results in mobs hanging around an unreachable target (player).
|
||||||
@ -188,6 +218,10 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
|
|||||||
m_GiveUpCounter = 40; // Give up after 40 ticks (2 seconds) if failed to reach m_NextWayPointPosition.
|
m_GiveUpCounter = 40; // Give up after 40 ticks (2 seconds) if failed to reach m_NextWayPointPosition.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_NoMoreWayPoints = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_IsFollowingPath = true;
|
m_IsFollowingPath = true;
|
||||||
return true;
|
return true;
|
||||||
@ -379,6 +413,7 @@ void cMonster::StopMovingToPosition()
|
|||||||
|
|
||||||
void cMonster::ResetPathFinding(void)
|
void cMonster::ResetPathFinding(void)
|
||||||
{
|
{
|
||||||
|
m_TicksSinceLastPathReset = 0;
|
||||||
m_IsFollowingPath = false;
|
m_IsFollowingPath = false;
|
||||||
if (m_Path != nullptr)
|
if (m_Path != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -120,8 +120,8 @@ public:
|
|||||||
char GetAge (void) const { return m_Age; }
|
char GetAge (void) const { return m_Age; }
|
||||||
void SetAge(char a_Age) { m_Age = a_Age; }
|
void SetAge(char a_Age) { m_Age = a_Age; }
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
/** Returns true if the monster has a custom name. */
|
/** Returns true if the monster has a custom name. */
|
||||||
@ -178,6 +178,7 @@ protected:
|
|||||||
|
|
||||||
/* If 0, will give up reaching the next m_NextWayPointPosition and will re-compute path. */
|
/* If 0, will give up reaching the next m_NextWayPointPosition and will re-compute path. */
|
||||||
int m_GiveUpCounter;
|
int m_GiveUpCounter;
|
||||||
|
int m_TicksSinceLastPathReset;
|
||||||
|
|
||||||
/** Coordinates of the next position that should be reached */
|
/** Coordinates of the next position that should be reached */
|
||||||
Vector3d m_NextWayPointPosition;
|
Vector3d m_NextWayPointPosition;
|
||||||
@ -185,6 +186,16 @@ protected:
|
|||||||
/** Coordinates for the ultimate, final destination. */
|
/** Coordinates for the ultimate, final destination. */
|
||||||
Vector3d m_FinalDestination;
|
Vector3d m_FinalDestination;
|
||||||
|
|
||||||
|
/** Coordinates for the ultimate, final destination last given to the pathfinder. */
|
||||||
|
Vector3d m_PathFinderDestination;
|
||||||
|
|
||||||
|
/** True if there's no path to target and we're walking to an approximated location. */
|
||||||
|
bool m_NoPathToTarget;
|
||||||
|
|
||||||
|
/** Whether The mob has finished their path, note that this does not imply reaching the destination,
|
||||||
|
the destination may sometimes differ from the current path. */
|
||||||
|
bool m_NoMoreWayPoints;
|
||||||
|
|
||||||
/** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does)
|
/** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does)
|
||||||
If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1
|
If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1
|
||||||
If current Y is solid, goes up to find first nonsolid block, and returns that.
|
If current Y is solid, goes up to find first nonsolid block, and returns that.
|
||||||
|
Loading…
Reference in New Issue
Block a user