bool AIConstruction::MinorRoadImprovements(const noRoadNode* start, const noRoadNode* target, std::vector<Direction>& route) { return BuildRoad(start, target, route); // TODO: Enable later after checking for performance and correctness RTTR_IGNORE_UNREACHABLE_CODE MapPoint pStart = start->GetPos(); //-V779 for(unsigned i = 0; i + 1 < route.size(); i++) { // switching current and next route element will result in the same position after building both if((route[i] + 1u == route[i + 1]) || (route[i] - 1u == route[i + 1])) { MapPoint t(pStart); t = aii.gwb.GetNeighbour(t, route[i + 1]); pStart = aii.gwb.GetNeighbour(pStart, route[i]); // can the alternative road be build? if(aii.gwb.IsRoadAvailable(false, t) && aii.IsOwnTerritory(t)) { // does the alternative road block a lower buildingquality point than the normal planned route? if(aii.CalcBQSumDifference(pStart, t)) { // LOG.write(("AIConstruction::road improvements p%i from %i,%i moved node %i,%i to %i,%i i:%i, i+1:%i\n",playerID, // start->GetX(), start->GetY(), ptx, pt.y, t.x, t.y,route[i],route[i+1]); pStart = t; // we move the alternative path so move x&y and switch the route entries std::swap(route[i], route[i + 1]); } } } else pStart = aii.gwb.GetNeighbour(pStart, route[i]); } return BuildRoad(start, target, route); RTTR_POP_DIAGNOSTIC }
//--------------------------------------------------------------------------- // Description: Handle mouse clicks on the cities. // [Ctrl] + [LeftClick]: build route // [RightClick]: set a city as the Nest // [Ctrl] + [RightClick]: set a city as the Food Source void __fastcall Civilization::CityMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if(Button == mbLeft) { // If Ctrl is down, we are creating a road... if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift)) if (CityBuildingRoad!=NULL) { BuildRoad( GetCityAddress( ((TShape*)Sender)->Tag ) ); } else CityBuildingRoad = GetCityAddress( ((TShape*)Sender)->Tag ); } else if(Button == mbRight) { if(Shift.Contains(ssCtrl)) { FoodSourceCity = GetCityAddress( ((TShape*)Sender)->Tag ); ((TShape*)Sender)->Brush->Color = clRed; } else { Nest = GetCityAddress( ((TShape*)Sender)->Tag ); ((TShape*)Sender)->Brush->Color = clBlue; } } }
void JohanCity::BuildType(POINT from,POINT to,MenuType type) { switch(type) { case mtResidential: { BuildZone(from,to,ttResidential); break; } case mtCommercial: { BuildZone(from,to,ttCommercial); break; } case mtIndustrial: { BuildZone(from,to,ttIndustrial); break; } case mtRoad: { BuildRoad(from,to,ttRoad); break; } case mtBulldoze: { Bulldoze(from,to); break; } case mtPowerPlant: { AddBuilding(new Building(from.x,from.y,2,2,0,0,btPowerPlant)); break; } case mtPowerLine: { AddBuilding(new Building(from.x,from.y,1,1,0,0,btPowerLine)); break; } } UpdateBuffers(); }
//--------------------------------------------------------------------------- // File Map: // int: index of the Anthill // int: index of the FoodSourceCity // int: number of cities // .... // int: X coordinate of the city // int: Y coordinate of the city // .... // int: number of roads // .... // int: index of city A (begin of the road) // int: index of city B (end of the road) // .... // Description: Load an environment from a file void Civilization::LoadFromFile(FILE *stream) { int AnthillIndex = -1; fread(&AnthillIndex,sizeof(int),1,stream); int FoodSourceIndex = -1; fread(&FoodSourceIndex,sizeof(int),1,stream); int CitiesCount = -1; fread(&CitiesCount,sizeof(int),1,stream); int A = 0; int B = 0; for(int i=0; i<CitiesCount; i++) { fread(&A,sizeof(int),1,stream); fread(&B,sizeof(int),1,stream); AddCity(A,B); // if the current city being loaded is the Nest... if(i==AnthillIndex) { Nest = ((City*)Cities->Items[i]); Nest->SetColor(clBlue); } // if the current city being loaded is the Food Source... if(i==FoodSourceIndex) { FoodSourceCity = ((City*)Cities->Items[i]); FoodSourceCity->SetColor(clRed); } } int RoadsCount = -1; fread(&RoadsCount,sizeof(int),1,stream); for(int i=0; i<RoadsCount; i++) { fread(&A,sizeof(int),1,stream); fread(&B,sizeof(int),1,stream); CityBuildingRoad = (City*)Cities->Items[A]; BuildRoad((City*)Cities->Items[B]); } }
bool AIConstruction::BuildAlternativeRoad(const noFlag* flag, std::vector<Direction>& route) { // LOG.write(("ai build alt road player %i at %i %i\n", flag->GetPlayer(), flag->GetPos()); // Radius in dem nach würdigen Fahnen gesucht wird const unsigned short maxRoadLength = 10; // Faktor um den der Weg kürzer sein muss als ein vorhander Pfad, um gebaut zu werden const unsigned short lengthFactor = 5; // Flaggen in der Umgebung holen std::vector<const noFlag*> flags = FindFlags(flag->GetPos(), maxRoadLength); std::vector<Direction> mainroad = route; // targetflag for mainroad MapPoint t = flag->GetPos(); for(auto i : mainroad) { t = aii.gwb.GetNeighbour(t, i); } const auto* mainflag = aii.gwb.GetSpecObj<noFlag>(t); // Jede Flagge testen... for(auto& i : flags) { const noFlag& curFlag = *i; // When the current flag is the end of the main route, we skip it as crossing the main route is dissallowed by crossmainpath check a // bit below if(mainflag && &curFlag == mainflag) continue; route.clear(); unsigned newLength; // the flag should not be at a military building! if(aii.gwb.IsMilitaryBuildingOnNode(aii.gwb.GetNeighbour(curFlag.GetPos(), Direction::NORTHWEST), true)) continue; if(!IsConnectedToRoadSystem(&curFlag)) continue; // Gibts überhaupt einen Pfad zu dieser Flagge if(!aii.FindFreePathForNewRoad(flag->GetPos(), curFlag.GetPos(), &route, &newLength)) continue; // Wenn ja, dann gucken ob unser momentaner Weg zu dieser Flagge vielleicht voll weit ist und sich eine Straße lohnt unsigned oldLength = 0; // Aktuelle Strecke zu der Flagge bool pathAvailable = aii.FindPathOnRoads(curFlag, *flag, &oldLength); if(!pathAvailable && mainflag) { pathAvailable = aii.FindPathOnRoads(curFlag, *mainflag, &oldLength); if(pathAvailable) oldLength += mainroad.size(); } bool crossmainpath = false; unsigned size = 0; // more than 5 nonflaggable spaces on the route -> not really valid path unsigned temp = 0; t = flag->GetPos(); for(auto j : route) { t = aii.gwb.GetNeighbour(t, j); MapPoint t2 = flag->GetPos(); // check if we cross the planned main road for(auto k : mainroad) { t2 = aii.gwb.GetNeighbour(t2, k); if(t2 == t) { crossmainpath = true; break; } } RTTR_Assert(aii.GetBuildingQuality(t) == aijh.GetAINode(t).bq); if(aii.GetBuildingQuality(t) == BQ_NOTHING) temp++; else { if(size < temp) size = temp; temp = 0; } } if(size > 2 || crossmainpath) continue; // Lohnt sich die Straße? if(!pathAvailable || newLength * lengthFactor < oldLength) { if(BuildRoad(flag, &curFlag, route)) { constructionlocations.push_back(flag->GetPos()); return true; } } } return false; }