1
0
forked from 0ad/0ad

Unit Motion - Stop when targets have an invalid position.

Previously, unitMotion had no code that checked particularly if the
target was still in the world.
When the target moved out of the world, unitMotion would follow the path
to its last known position, then send a "MoveSucceeded" message once
there.

Following 98f609df1d, this message was no longer sent. Thus unit would
follow their path to its last waypoint and stay there, unable to carry
on or finish the order. UnitMotion now explcitly sends a "MoveFailed"
message.

This still changes behaviour from A23, requiring further revisions to
UnitAI (see D1992 for one such case).

Minohaka tested an earlier version of this change (which incorporated
D1992) and accepted it.

Differential Revision: https://code.wildfiregames.com/D1979
This was SVN commit r22415.
This commit is contained in:
wraitii 2019-06-30 19:00:27 +00:00
parent 3e43ddd869
commit 69d3e76fd2

View File

@ -633,6 +633,13 @@ private:
*/
bool ShouldTreatTargetAsCircle(entity_pos_t range, entity_pos_t circleRadius) const;
/**
* Returns true if the target position is valid. False otherwise.
* (this may indicate that the target is e.g. out of the world/dead).
* NB: for code-writing convenience, if we have no target, this returns true.
*/
bool TargetHasValidPosition() const;
/**
* Computes the current location of our target entity (plus offset).
* Returns false if no target entity or no valid position.
@ -818,6 +825,18 @@ void CCmpUnitMotion::Move(fixed dt)
if (PossiblyAtDestination())
MoveSucceeded();
else if (!TargetHasValidPosition())
{
// Scrap waypoints - we don't know where to go.
// If the move request remains unchanged and the target again has a valid position later on,
// moving will be resumed.
// Units may want to move to move to the target's last known position,
// but that should be decided by UnitAI (handling MoveFailed), not UnitMotion.
m_LongPath.m_Waypoints.clear();
m_ShortPath.m_Waypoints.clear();
MoveFailed();
}
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
if (!cmpPosition || !cmpPosition->IsInWorld())
@ -1057,6 +1076,15 @@ bool CCmpUnitMotion::HandleObstructedMove()
return true;
}
bool CCmpUnitMotion::TargetHasValidPosition() const
{
if (m_MoveRequest.m_Type != MoveRequest::ENTITY)
return true;
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), m_MoveRequest.m_Entity);
return cmpPosition && cmpPosition->IsInWorld();
}
bool CCmpUnitMotion::ComputeTargetPosition(CFixedVector2D& out) const
{
if (m_MoveRequest.m_Entity == INVALID_ENTITY)