void CSReclaimTask::Update() { CCircuitAI* circuit = manager->GetCircuit(); if (circuit->GetEconomyManager()->IsMetalFull()) { manager->AbortTask(this); } else if ((++updCount % 4 == 0) && !units.empty()) { // Check for damaged units CBuilderManager* builderManager = circuit->GetBuilderManager(); CAllyUnit* repairTarget = nullptr; circuit->UpdateFriendlyUnits(); auto us = std::move(circuit->GetCallback()->GetFriendlyUnitsIn(position, radius * 0.9f)); for (Unit* u : us) { CAllyUnit* candUnit = circuit->GetFriendlyUnit(u); if ((candUnit == nullptr) || builderManager->IsReclaimed(candUnit)) { continue; } if (!u->IsBeingBuilt() && (u->GetHealth() < u->GetMaxHealth())) { repairTarget = candUnit; break; } } utils::free_clear(us); if (repairTarget != nullptr) { // Repair task IBuilderTask* task = circuit->GetFactoryManager()->EnqueueRepair(IBuilderTask::Priority::NORMAL, repairTarget); decltype(units) tmpUnits = units; for (CCircuitUnit* unit : tmpUnits) { manager->AssignTask(unit, task); } manager->AbortTask(this); } } }
CCircuitUnit* CBRepairTask::FindUnitToAssist(CCircuitUnit* unit) { CCircuitUnit* target = nullptr; Unit* su = unit->GetUnit(); const AIFloat3& pos = su->GetPos(); float maxSpeed = su->GetMaxSpeed(); float radius = unit->GetCircuitDef()->GetBuildDistance() + maxSpeed * FRAMES_PER_SEC * 30; CCircuitAI* circuit = manager->GetCircuit(); circuit->UpdateFriendlyUnits(); auto units = std::move(circuit->GetCallback()->GetFriendlyUnitsIn(pos, radius)); for (auto u : units) { if ((u != nullptr) && u->GetHealth() < u->GetMaxHealth() && u->GetVel().Length() <= maxSpeed * 1.5f) { target = circuit->GetFriendlyUnit(u); if (target != nullptr) { break; } } } utils::free_clear(units); return target; }