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;
          }
       }
}
예제 #3
0
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;
}