CEnemyUnit* CAttackTask::FindBestTarget(CCircuitUnit* unit, float& minSqDist) { CCircuitAI* circuit = manager->GetCircuit(); CTerrainManager* terrainManager = circuit->GetTerrainManager(); CThreatMap* threatMap = circuit->GetThreatMap(); const AIFloat3& pos = unit->GetUnit()->GetPos(); STerrainMapArea* area = unit->GetArea(); float power = threatMap->GetUnitThreat(unit); int canTargetCat = unit->GetCircuitDef()->GetTargetCategory(); CEnemyUnit* bestTarget = nullptr; minSqDist = std::numeric_limits<float>::max(); threatMap->SetThreatType(unit); const CCircuitAI::EnemyUnits& enemies = circuit->GetEnemyUnits(); for (auto& kv : enemies) { CEnemyUnit* enemy = kv.second; if (enemy->IsHidden() || (threatMap->GetThreatAt(enemy->GetPos()) >= power) || !terrainManager->CanMoveToPos(area, enemy->GetPos())) { continue; } if (((canTargetCat & circuit->GetWaterCategory()) == 0) && (enemy->GetPos().y < -SQUARE_SIZE * 4)) { continue; } CCircuitDef* edef = enemy->GetCircuitDef(); if ((edef != nullptr) && ((edef->GetCategory() & canTargetCat) == 0)) { continue; } float sqDist = pos.SqDistance2D(enemy->GetPos()); if (sqDist < minSqDist) { bestTarget = enemy; minSqDist = sqDist; } } return bestTarget; }
/* * Defend buildings handler */ auto structDamagedHandler = [this](CCircuitUnit* unit, CEnemyUnit* attacker) { const AIFloat3& pos = unit->GetPos(this->circuit->GetLastFrame()); CTerrainManager* terrainManager = this->circuit->GetTerrainManager(); CDefendTask* defendTask = nullptr; float minSqDist = std::numeric_limits<float>::max(); const std::set<IFighterTask*>& tasks = GetTasks(IFighterTask::FightType::DEFEND); for (IFighterTask* task : tasks) { CDefendTask* dt = static_cast<CDefendTask*>(task); if (dt->GetTarget() != nullptr) { continue; } const float sqDist = pos.SqDistance2D(dt->GetPosition()); if ((minSqDist < sqDist) && (terrainManager->CanMoveToPos(dt->GetLeader()->GetArea(), pos))) { minSqDist = sqDist; defendTask = dt; } } if (defendTask != nullptr) { defendTask->SetPosition(pos); defendTask->SetWantedTarget(attacker); } }; ReadConfig(); const Json::Value& root = circuit->GetSetupManager()->GetConfig(); const float fighterRet = root["retreat"].get("fighter", 0.5f).asFloat(); float maxRadarDivCost = 0.f;