Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/components/CCmpUnitMotion.cpp
Show First 20 Lines • Show All 628 Lines • ▼ Show 20 Lines | private: | ||||
* Update other components on our speed. | * Update other components on our speed. | ||||
* (For performance, this should try to avoid sending messages). | * (For performance, this should try to avoid sending messages). | ||||
*/ | */ | ||||
void UpdateMovementState(entity_pos_t speed); | void UpdateMovementState(entity_pos_t speed); | ||||
/** | /** | ||||
* React if our move was obstructed. | * React if our move was obstructed. | ||||
* @param moved - true if the unit still managed to move. | * @param moved - true if the unit still managed to move. | ||||
* @param notify - true if we possibly should increment movement fails and notify | |||||
* @returns true if the obstruction required handling, false otherwise. | * @returns true if the obstruction required handling, false otherwise. | ||||
*/ | */ | ||||
bool HandleObstructedMove(bool moved); | bool HandleObstructedMove(bool moved, bool notify); | ||||
/** | /** | ||||
* Returns true if the target position is valid. False otherwise. | * Returns true if the target position is valid. False otherwise. | ||||
* (this may indicate that the target is e.g. out of the world/dead). | * (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. | * NB: for code-writing convenience, if we have no target, this returns true. | ||||
*/ | */ | ||||
bool TargetHasValidPosition(const MoveRequest& moveRequest) const; | bool TargetHasValidPosition(const MoveRequest& moveRequest) const; | ||||
bool TargetHasValidPosition() const | bool TargetHasValidPosition() const | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | void CCmpUnitMotion::PathResult(u32 ticket, const WaypointPath& path) | ||||
bool shortPathHack = false; | bool shortPathHack = false; | ||||
if (path.m_Waypoints.empty()) | if (path.m_Waypoints.empty()) | ||||
{ | { | ||||
// No waypoints means pathing failed. If this was a long-path, try the short-path hack. | // No waypoints means pathing failed. If this was a long-path, try the short-path hack. | ||||
if (!pathedTowardsGoal) | if (!pathedTowardsGoal) | ||||
return; | return; | ||||
shortPathHack = ticketType == Ticket::LONG_PATH; | shortPathHack = ticketType == Ticket::LONG_PATH; | ||||
} | } | ||||
else if (PathGoal goal; pathedTowardsGoal && ComputeGoal(goal, m_MoveRequest) && RejectFartherPaths(goal, path, pos)) | else if (PathGoal goal; pathedTowardsGoal && ComputeGoal(goal, m_MoveRequest) && RejectFartherPaths(goal, path, pos)) | ||||
Lint: CPPCheckBear (syntaxError): `syntax error` | |||||
{ | { | ||||
// Reject paths that would take the unit further away from the goal. | // Reject paths that would take the unit further away from the goal. | ||||
// This assumes that we prefer being closer 'as the crow flies' to unreachable goals. | // This assumes that we prefer being closer 'as the crow flies' to unreachable goals. | ||||
// This is a hack of sorts around units 'dancing' between two positions (see e.g. #3144), | // This is a hack of sorts around units 'dancing' between two positions (see e.g. #3144), | ||||
// but never actually failing to move, ergo never actually informing unitAI that it succeeds/fails. | // but never actually failing to move, ergo never actually informing unitAI that it succeeds/fails. | ||||
// (for short paths, only do so if aiming directly for the goal | // (for short paths, only do so if aiming directly for the goal | ||||
// as sub-goals may be farther than we are). | // as sub-goals may be farther than we are). | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | else | ||||
CFixedVector2D offset = pos - initialPos; | CFixedVector2D offset = pos - initialPos; | ||||
angle = atan2_approx(offset.X, offset.Y); | angle = atan2_approx(offset.X, offset.Y); | ||||
cmpPosition->MoveAndTurnTo(pos.X, pos.Y, angle); | cmpPosition->MoveAndTurnTo(pos.X, pos.Y, angle); | ||||
// Calculate the mean speed over this past turn. | // Calculate the mean speed over this past turn. | ||||
UpdateMovementState(offset.Length() / dt); | UpdateMovementState(offset.Length() / dt); | ||||
} | } | ||||
if (wasObstructed && HandleObstructedMove(pos != initialPos)) | bool willBeObstructed = false; | ||||
if (!wasObstructed && m_ShortPath.m_Waypoints.empty() && !m_LongPath.m_Waypoints.empty()) | |||||
{ | |||||
CFixedVector2D target = CFixedVector2D(m_LongPath.m_Waypoints.back().x, m_LongPath.m_Waypoints.back().z); | |||||
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity()); | |||||
if (cmpPathfinder) | |||||
willBeObstructed = !cmpPathfinder->CheckMovement(GetObstructionFilter(), pos.X, pos.Y, target.X, target.Y, m_Clearance, m_PassClass); | |||||
} | |||||
if ((wasObstructed || willBeObstructed) && HandleObstructedMove(pos != initialPos || angle != initialAngle, wasObstructed)) | |||||
return; | return; | ||||
else if (!wasObstructed && pos != initialPos) | else if (!wasObstructed && (pos != initialPos || angle != initialAngle)) | ||||
wraitiiUnsubmitted Not Done Inline ActionsI'm pretty sure the angle shouldn't be added to this check. This increases jitteriness and doesn't help movement. wraitii: I'm pretty sure the angle shouldn't be added to this check. This increases jitteriness and… | |||||
m_FailedMovements = 0; | m_FailedMovements = 0; | ||||
// We may need to recompute our path sometimes (e.g. if our target moves). | // We may need to recompute our path sometimes (e.g. if our target moves). | ||||
// Since we request paths asynchronously anyways, this does not need to be done before moving. | // Since we request paths asynchronously anyways, this does not need to be done before moving. | ||||
if (!wentStraight && PathingUpdateNeeded(pos)) | if (!wentStraight && PathingUpdateNeeded(pos)) | ||||
{ | { | ||||
PathGoal goal; | PathGoal goal; | ||||
if (ComputeGoal(goal, m_MoveRequest)) | if (ComputeGoal(goal, m_MoveRequest)) | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | void CCmpUnitMotion::UpdateMovementState(entity_pos_t speed) | ||||
} | } | ||||
// Speed change, update the visual actor if necessary. | // Speed change, update the visual actor if necessary. | ||||
else if (speed != m_CurSpeed && cmpVisual) | else if (speed != m_CurSpeed && cmpVisual) | ||||
cmpVisual->SelectMovementAnimation(speed > m_WalkSpeed ? "run" : "walk", speed); | cmpVisual->SelectMovementAnimation(speed > m_WalkSpeed ? "run" : "walk", speed); | ||||
m_CurSpeed = speed; | m_CurSpeed = speed; | ||||
} | } | ||||
bool CCmpUnitMotion::HandleObstructedMove(bool moved) | bool CCmpUnitMotion::HandleObstructedMove(bool moved, bool notify) | ||||
{ | { | ||||
CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); | CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); | ||||
if (!cmpPosition || !cmpPosition->IsInWorld()) | if (!cmpPosition || !cmpPosition->IsInWorld()) | ||||
return false; | return false; | ||||
// We failed to move, inform other components as they might handle it. | // We failed to move, inform other components as they might handle it. | ||||
// (don't send messages on the first failure, as that would be too noisy). | // (don't send messages on the first failure, as that would be too noisy). | ||||
// Also don't increment above the initial MoveObstructed message if we actually manage to move a little. | // Also don't increment above the initial MoveObstructed message if we actually manage to move a little. | ||||
if (!moved || m_FailedMovements < 2) | if (notify && (!moved || m_FailedMovements < 2)) | ||||
{ | { | ||||
if (!IncrementFailedMovementsAndMaybeNotify() && m_FailedMovements >= 2) | if (!IncrementFailedMovementsAndMaybeNotify() && m_FailedMovements >= 2) | ||||
MoveObstructed(); | MoveObstructed(); | ||||
} | } | ||||
PathGoal goal; | PathGoal goal; | ||||
if (!ComputeGoal(goal, m_MoveRequest)) | if (!ComputeGoal(goal, m_MoveRequest)) | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 529 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
syntax error