void CRetreatTask::CheckRepairer(CCircuitUnit* unit) { CCircuitAI* circuit = manager->GetCircuit(); int frame = circuit->GetLastFrame(); CPathFinder* pathfinder = circuit->GetPathfinder(); AIFloat3 startPos = (*units.begin())->GetPos(frame); AIFloat3 endPos; float range; bool isRepairer = (repairer != nullptr); if (isRepairer) { endPos = repairer->GetPos(frame); range = pathfinder->GetSquareSize(); } else { CFactoryManager* factoryManager = circuit->GetFactoryManager(); endPos = factoryManager->GetClosestHaven(unit); if (endPos == -RgtVector) { endPos = circuit->GetSetupManager()->GetBasePos(); } range = factoryManager->GetAssistDef()->GetBuildDistance() * 0.6f + pathfinder->GetSquareSize(); } circuit->GetTerrainManager()->CorrectPosition(startPos); pathfinder->SetMapData(unit, circuit->GetThreatMap(), frame); float prevCost = pathfinder->PathCost(startPos, endPos, range); if (isRepairer && repairer->GetCircuitDef()->IsMobile()) { prevCost /= 4; } endPos = unit->GetPos(frame); float nextCost = pathfinder->PathCost(startPos, endPos, range); if (unit->GetCircuitDef()->IsMobile()) { nextCost /= 4; } if (prevCost > nextCost) { SetRepairer(unit); } }
void CRetreatTask::Execute(CCircuitUnit* unit) { IUnitAction* act = static_cast<IUnitAction*>(unit->End()); if (!act->IsAny(IUnitAction::Mask::MOVE | IUnitAction::Mask::FIGHT)) { return; } ITravelAction* travelAction = static_cast<ITravelAction*>(act); CCircuitAI* circuit = manager->GetCircuit(); int frame = circuit->GetLastFrame(); CPathFinder* pathfinder = circuit->GetPathfinder(); AIFloat3 startPos = unit->GetPos(frame); AIFloat3 endPos; float range; if (repairer != nullptr) { endPos = repairer->GetPos(frame); range = pathfinder->GetSquareSize(); } else { CFactoryManager* factoryManager = circuit->GetFactoryManager(); endPos = factoryManager->GetClosestHaven(unit); if (endPos == -RgtVector) { endPos = circuit->GetSetupManager()->GetBasePos(); } range = factoryManager->GetAssistDef()->GetBuildDistance() * 0.6f + pathfinder->GetSquareSize(); } std::shared_ptr<F3Vec> pPath = std::make_shared<F3Vec>(); pathfinder->SetMapData(unit, circuit->GetThreatMap(), frame); pathfinder->MakePath(*pPath, startPos, endPos, range); if (pPath->empty()) { pPath->push_back(endPos); } travelAction->SetPath(pPath); unit->Update(circuit); }