SAIFloat3 ConstructionUnitGroup::FindGoodBuildSite(SAIFloat3 builderPos, UnitDef* building, float radius) { SAIFloat3 bestBuildSpot=builderPos; float bestDistance = radius*radius+1; bool foundBuildSite = false; Map *map = ai->callback->GetMap(); vector<Unit*> nearByBuildings = ai->knowledge->selfInfo->baseInfo->GetUnitsInRange(builderPos, radius); vector<Unit*>::iterator it; for(it = nearByBuildings.begin(); it != nearByBuildings.end(); it++) { UnitDef* ud = (*it)->GetDef(); if(!ud->IsBuilder()) { SAIFloat3 unitPos = (*it)->GetPos(); float muls[][2] = {{-1,0},{1,0},{0,-1},{0,1}};//left, right, up, down for(int i=0; i<4;i++) { SAIFloat3 newPos = unitPos; newPos.x += muls[i][0]*((ud->GetXSize()*8/2)+(building->GetXSize()*8/2)); newPos.z += muls[i][1]*((ud->GetZSize()*8/2)+(building->GetZSize()*8/2)); float newDist = ai->utility->EuclideanDistance(builderPos,newPos); if(newDist < bestDistance && map->IsPossibleToBuildAt(*building, newPos, 0) && !IsMetalExtracitonSite(building, newPos) && !BuildBlocksSelf(building, newPos, 0) ) { //TODO: test if it is blocking a contruction yard bestBuildSpot = newPos; bestDistance = newDist; foundBuildSite = true; } } } delete (*it); delete ud; } delete map; if (!foundBuildSite) { //We didn't find a good BuildSite (e.g. no non-builder buildings) bestBuildSpot = FindClosestNonConflictingBuildSite(building, builderPos, radius, 0, 0); } return bestBuildSpot; }
bool ConstructionUnitGroup::InersectsWithMex(UnitDef *unitDef, SAIFloat3 pos, SAIFloat3 mexPos) { if (ai->utility->IsMetalMap()) { return false;//Since metal can be extracted from all spots, there are no limited metal extraction sites } UnitDef *mexDef = ai->utility->GetMexDef(); bool retVal = ai->math->BoxIntersect( pos, unitDef->GetXSize()*8, unitDef->GetZSize()*8, mexPos, mexDef->GetXSize()*8, mexDef->GetZSize()*8); ai->utility->Log(ALL, MISC, "Mex intersect box 1 at (%f,%f,%f): %ix%i", pos.x, pos.y, pos.z, unitDef->GetXSize()*8, unitDef->GetZSize()*8); ai->utility->Log(ALL, MISC, "Mex intersect box 2 at (%f,%f,%f): %ix%i", mexPos.x, mexPos.y, mexPos.z, mexDef->GetXSize()*8, mexDef->GetZSize()*8); ai->utility->Log(ALL, MISC, "Checking InersectsWithMex: %i", retVal); return retVal; }