forked from 0ad/0ad
Improve MoveToTarget when the target is moving, fixes #2253
This was SVN commit r14168.
This commit is contained in:
parent
4915116ccc
commit
321e61617b
@ -340,11 +340,8 @@ var UnitFsmSpec = {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO improve these movements in case of ship: the MoveToTarget of the units brings
|
||||
// them to the nearest point-on-land from the ship, while the MoveToPoint of the ship
|
||||
// brings it to the nearest point-on-water from the units, and these can be quite
|
||||
// different in some cases leading to weird movements. MoveToTarget should update its path
|
||||
// according to the target movement more often.
|
||||
// TODO: what if the units are on a cliff ? the ship will go below the cliff
|
||||
// and the units won't be able to garrison. Should go to the nearest (accessible) shore
|
||||
if (this.MoveToTarget(this.order.data.target))
|
||||
{
|
||||
this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING");
|
||||
|
@ -96,6 +96,14 @@ static const entity_pos_t CHECK_TARGET_MOVEMENT_MIN_DELTA_FORMATION = entity_pos
|
||||
*/
|
||||
static const entity_pos_t CHECK_TARGET_MOVEMENT_AT_MAX_DIST = entity_pos_t::FromInt(TERRAIN_TILE_SIZE*16);
|
||||
|
||||
/**
|
||||
* If we're following something and the angle between the (straight-line) directions to its previous target
|
||||
* position and its present target position is greater than a given angle, recompute the path even far away
|
||||
* (i.e. even if CHECK_TARGET_MOVEMENT_AT_MAX_DIST condition is not fulfilled). The actual check is done
|
||||
* on the cosine of this angle, with a PI/6 angle.
|
||||
*/
|
||||
static const fixed CHECK_TARGET_MOVEMENT_MIN_COS = fixed::FromInt(866)/1000;
|
||||
|
||||
static const CColor OVERLAY_COLOUR_LONG_PATH(1, 1, 1, 1);
|
||||
static const CColor OVERLAY_COLOUR_SHORT_PATH(1, 0, 0, 1);
|
||||
|
||||
@ -540,6 +548,8 @@ private:
|
||||
GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
|
||||
}
|
||||
|
||||
bool MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange, entity_id_t target);
|
||||
|
||||
/**
|
||||
* Handle the result of an asynchronous path query.
|
||||
*/
|
||||
@ -1088,8 +1098,18 @@ bool CCmpUnitMotion::CheckTargetMovement(CFixedVector2D from, entity_pos_t minDe
|
||||
if ((targetPos - oldTargetPos).CompareLength(minDelta) < 0)
|
||||
return false;
|
||||
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
|
||||
if (!cmpPosition || !cmpPosition->IsInWorld())
|
||||
return false;
|
||||
CFixedVector2D pos = cmpPosition->GetPosition2D();
|
||||
CFixedVector2D oldDir = (oldTargetPos - pos);
|
||||
CFixedVector2D newDir = (targetPos - pos);
|
||||
oldDir.Normalize();
|
||||
newDir.Normalize();
|
||||
|
||||
// Fail unless we're close enough to the target to care about its movement
|
||||
if (!PathIsShort(m_LongPath, from, CHECK_TARGET_MOVEMENT_AT_MAX_DIST))
|
||||
// and the angle between the (straight-line) directions of the previous and new target positions is small
|
||||
if (oldDir.Dot(newDir) > CHECK_TARGET_MOVEMENT_MIN_COS && !PathIsShort(m_LongPath, from, CHECK_TARGET_MOVEMENT_AT_MAX_DIST))
|
||||
return false;
|
||||
|
||||
// Fail if the target is no longer visible to this entity's owner
|
||||
@ -1280,8 +1300,12 @@ bool CCmpUnitMotion::PickNextLongWaypoint(const CFixedVector2D& pos, bool avoidM
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CCmpUnitMotion::MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange)
|
||||
{
|
||||
return MoveToPointRange(x, z, minRange, maxRange, INVALID_ENTITY);
|
||||
}
|
||||
|
||||
bool CCmpUnitMotion::MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos_t minRange, entity_pos_t maxRange, entity_id_t target)
|
||||
{
|
||||
PROFILE("MoveToPointRange");
|
||||
|
||||
@ -1357,7 +1381,7 @@ bool CCmpUnitMotion::MoveToPointRange(entity_pos_t x, entity_pos_t z, entity_pos
|
||||
}
|
||||
|
||||
m_State = STATE_INDIVIDUAL_PATH;
|
||||
m_TargetEntity = INVALID_ENTITY;
|
||||
m_TargetEntity = target;
|
||||
m_TargetOffset = CFixedVector2D();
|
||||
m_TargetMinRange = minRange;
|
||||
m_TargetMaxRange = maxRange;
|
||||
@ -1574,7 +1598,7 @@ bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange
|
||||
|
||||
CFixedVector2D targetPos = cmpTargetPosition->GetPosition2D();
|
||||
|
||||
return MoveToPointRange(targetPos.X, targetPos.Y, minRange, maxRange);
|
||||
return MoveToPointRange(targetPos.X, targetPos.Y, minRange, maxRange, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user