bool CBuilderCAI::MoveInBuildRange(const float3& objPos, float objRadius, const bool checkMoveTypeForFailed) { if (!IsInBuildRange(objPos, objRadius)) { // NOTE: // ignore the fail-check if we are an aircraft, movetype code // is unreliable wrt. setting it correctly and causes (landed) // aircraft to discard orders const bool checkFailed = (checkMoveTypeForFailed && !owner->unitDef->IsAirUnit()); // check if the AMoveType::Failed belongs to the same goal position const bool haveFailed = (owner->moveType->progressState == AMoveType::Failed && f3SqDist(owner->moveType->goalPos, objPos) > 1.0f); if (checkFailed && haveFailed) { // don't call SetGoal() it would reset moveType->progressState // and so later code couldn't check if the move command failed return false; } // too far away, start a move command SetGoal(objPos, owner->pos, GetBuildRange(objRadius) * 0.9f); return false; } if (owner->unitDef->IsAirUnit()) { StopMoveAndKeepPointing(objPos, objRadius, false); } else { StopMoveAndKeepPointing(owner->moveType->goalPos, GetBuildRange(objRadius) * 0.9f, false); } return true; }
bool CBuilderCAI::MoveInBuildRange(const float3& pos, float radius, const bool checkMoveTypeForFailed) { if (!IsInBuildRange(pos, radius)) { if ( checkMoveTypeForFailed && owner->moveType->progressState == AMoveType::Failed && f3SqDist(goalPos, pos) > 1.0f // check if the AMoveType::Failed belongs to the same goal position ) { // don't call SetGoal() it would reset moveType->progressState and so later code couldn't check if the movecmd failed return false; } // too far away, start a move command SetGoal(pos, owner->pos, GetBuildRange(radius) * 0.9f); return false; } if (owner->unitDef->IsAirUnit()) { StopMoveAndKeepPointing(pos, radius); } else { StopMoveAndKeepPointing(goalPos, goalRadius); } return true; }
bool CBuilderCAI::IsInBuildRange(const float3& objPos, const float objRadius) const { const float immDistSqr = f3SqDist(owner->pos, objPos); const float buildDist = GetBuildRange(objRadius); return (immDistSqr <= (buildDist * buildDist)); }
inline bool CBuilderCAI::IsInBuildRange(const float3& pos, const float radius) const { const float immDistSqr = f3SqDist(owner->pos, pos); const float buildDist = GetBuildRange(radius); return (immDistSqr < (buildDist * buildDist)); }
void CBuilderCAI::ExecuteRepair(Command& c) { // not all builders are repair-capable by default if (!owner->unitDef->canRepair) return; if (c.params.size() == 1 || c.params.size() == 5) { // repair unit CUnit* unit = unitHandler->GetUnit(c.params[0]); if (unit == NULL) { FinishCommand(); return; } if (tempOrder && owner->moveState <= MOVESTATE_MANEUVER) { // limit how far away we go when not roaming if (LinePointDist(commandPos1, commandPos2, unit->pos) > std::max(500.0f, GetBuildRange(unit->radius))) { StopMove(); FinishCommand(); return; } } if (c.params.size() == 5) { const float3& pos = c.GetPos(1); const float radius = c.params[4] + 100.0f; // do not walk too far outside repair area if ((pos - unit->pos).SqLength2D() > radius * radius || (unit->IsMoving() && (((c.options & INTERNAL_ORDER) && !TargetInterceptable(unit, unit->speed.Length2D())) || ownerBuilder->curBuild == unit) && !IsInBuildRange(unit))) { StopMove(); FinishCommand(); return; } } // do not consider units under construction irreparable // even if they can be repaired bool canRepairUnit = true; canRepairUnit &= ((unit->beingBuilt) || (unit->unitDef->repairable && (unit->health < unit->maxHealth))); canRepairUnit &= ((unit != owner) || owner->unitDef->canSelfRepair); canRepairUnit &= (!unit->soloBuilder || (unit->soloBuilder == owner)); canRepairUnit &= (!(c.options & INTERNAL_ORDER) || (c.options & CONTROL_KEY) || !IsUnitBeingReclaimed(unit, owner)); canRepairUnit &= (UpdateTargetLostTimer(unit->id) != 0); if (canRepairUnit) { if (MoveInBuildRange(unit)) { ownerBuilder->SetRepairTarget(unit); } } else { StopMove(); FinishCommand(); } } else if (c.params.size() == 4) { // area repair const float3 pos = c.GetPos(0); const float radius = c.params[3]; ownerBuilder->StopBuild(); if (FindRepairTargetAndRepair(pos, radius, c.options, false, (c.options & META_KEY))) { inCommand = false; SlowUpdate(); return; } if (!(c.options & ALT_KEY)) { FinishCommand(); } } else { FinishCommand(); } }