function WrightAI::checkAdjacentStation(airportTile, airport_type) {
if (!AIController.GetSetting("station_spread")) {
return AIStation.STATION_NEW;
}
local tileList = AITileList();
local spreadrectangle = expandAdjacentStationRect(airportTile, airport_type);
tileList.AddRectangle(spreadrectangle[0], spreadrectangle[1]);
tileList.Valuate(Utils.isTileMyStationWithoutAirport);
tileList.KeepValue(1);
tileList.Valuate(AIStation.GetStationID);
local stationList = AIList();
for(local tile = tileList.Begin(); tileList.HasNext(); tileList.Next()) {
stationList.AddItem(tileList.GetValue(tile), AITile.GetDistanceManhattanToTile(tile, airportTile));
}
local spread_rad = AIGameSettings.GetValue("station_spread");
local airport_x = AIAirport.GetAirportWidth(airport_type);
local airport_y = AIAirport.GetAirportHeight(airport_type);
local list = AIList();
list.AddList(stationList);
for (local stationId = stationList.Begin(); stationList.HasNext(); stationId = stationList.Next()) {
local stationTiles = AITileList_StationType(stationId, AIStation.STATION_ANY);
local station_top_x = AIMap.GetTileX(AIBaseStation.GetLocation(stationId));
local station_top_y = AIMap.GetTileY(AIBaseStation.GetLocation(stationId));
local station_bot_x = AIMap.GetTileX(AIBaseStation.GetLocation(stationId));
local station_bot_y = AIMap.GetTileY(AIBaseStation.GetLocation(stationId));
for (local tile = stationTiles.Begin(); stationTiles.HasNext(); tile = stationTiles.Next()) {
local tile_x = AIMap.GetTileX(tile);
local tile_y = AIMap.GetTileY(tile);
if (tile_x < station_top_x) {
station_top_x = tile_x;
}
if (tile_x > station_bot_x) {
station_bot_x = tile_x;
}
if (tile_y < station_top_y) {
station_top_y = tile_y;
}
if (tile_y > station_bot_y) {
station_bot_y = tile_y;
}
}
local st_size_x = station_bot_x - station_top_x + 1;
local st_size_y = station_bot_y - station_top_y + 1;
// AILog.Info(AIStation.GetName(stationId) + " station size = " + st_size_x + "*" + st_size_y);
if (st_size_x + airport_x > spread_rad || st_size_y + airport_y > spread_rad) {
list.RemoveItem(stationId);
}
}
list.Sort(AIList.SORT_BY_VALUE, true);
local adjacentStation = AIStation.STATION_NEW;
if(list.Count()) {
adjacentStation = list.Begin();
// AILog.Info("adjacentStation = " + AIStation.GetName(adjacentStation) + " ; airportTile = " + AIMap.GetTileX(airportTile) + "," + AIMap.GetTileY(airportTile));
}
return adjacentStation;
}
function WrightAI::expandAdjacentStationRect(airportTile, airport_type) {
local spread_rad = AIGameSettings.GetValue("station_spread");
local airport_x = AIAirport.GetAirportWidth(airport_type);
local airport_y = AIAirport.GetAirportHeight(airport_type);
local remaining_x = spread_rad - airport_x;
local remaining_y = spread_rad - airport_y;
local tile_top_x = AIMap.GetTileX(airportTile);
local tile_top_y = AIMap.GetTileY(airportTile);
local tile_bot_x = AIMap.GetTileX(airportTile) + airport_x - 1;
local tile_bot_y = AIMap.GetTileY(airportTile) + airport_y - 1;
for (local x = remaining_x; x > 0; x--) {
if (AIMap.IsValidTile(AIMap.GetTileIndex(tile_top_x - 1, tile_top_y))) {
tile_top_x = tile_top_x - 1;
}
if (AIMap.IsValidTile(AIMap.GetTileIndex(tile_bot_x + 1, tile_bot_y))) {
tile_bot_x = tile_bot_x + 1;
}
}
for (local y = remaining_y; y > 0; y--) {
if (AIMap.IsValidTile(AIMap.GetTileIndex(tile_top_x, tile_top_y - 1))) {
tile_top_y = tile_top_y - 1;
}
if (AIMap.IsValidTile(AIMap.GetTileIndex(tile_bot_x, tile_bot_y + 1))) {
tile_bot_y = tile_bot_y + 1;
}
}
// AILog.Info("spreadrectangle top = " + tile_top_x + "," + tile_top_y + " ; spreadrectangle bottom = " + tile_bot_x + "," + tile_bot_y);
return [AIMap.GetTileIndex(tile_top_x, tile_top_y), AIMap.GetTileIndex(tile_bot_x, tile_bot_y)];
}
function WrightAI::TownAirportRadRect(airport_type, town_id) {
local town_rectangle = BuildManager.estimateTownRectangle(town_id);
local town_top_x = AIMap.GetTileX(town_rectangle[0]);
local town_top_y = AIMap.GetTileY(town_rectangle[0]);
local town_bot_x = AIMap.GetTileX(town_rectangle[1]);
local town_bot_y = AIMap.GetTileY(town_rectangle[1]);
// AILog.Info("top tile was " + town_top_x + "," + town_top_y + " bottom tile was " + town_bot_x + "," + town_bot_y);
local airport_x = AIAirport.GetAirportWidth(airport_type);
local airport_y = AIAirport.GetAirportHeight(airport_type);
local airport_rad = AIAirport.GetAirportCoverageRadius(airport_type);
for (local x = airport_x; x > 1; x--) {
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_top_x - 1, town_top_y))) {
town_top_x = town_top_x - 1;
}
}
for (local y = airport_y; y > 1; y--) {
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_top_x, town_top_y - 1))) {
town_top_y = town_top_y - 1;
}
}
for (local r = airport_rad; r > 0; r--) {
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_top_x - 1, town_top_y))) {
town_top_x = town_top_x - 1;
}
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_top_x, town_top_y - 1))) {
town_top_y = town_top_y - 1;
}
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_bot_x + 1, town_bot_y))) {
town_bot_x = town_bot_x + 1;
}
if (AIMap.IsValidTile(AIMap.GetTileIndex(town_bot_x, town_bot_y + 1))) {
town_bot_y = town_bot_y + 1;
}
}
// AILog.Info("top tile now " + town_top_x + "," + town_top_y + " bottom tile now " + town_bot_x + "," + town_bot_y);
return [AIMap.GetTileIndex(town_top_x, town_top_y), AIMap.GetTileIndex(town_bot_x, town_bot_y)];
}
////////////////////////////////////
function estimateTownRectangle(town) {
local townId = town;
local townLocation = AITown.GetLocation(town);
local rectangleIncreaseKoeficient = 1;
local topCornerTile = AITown.GetLocation(town);
local bottomCornerTile = AITown.GetLocation(town);
local isMaxExpanded = false;
while(!isMaxExpanded) {
local maxExpandedCounter = 0;
for(local i = 0; i < 4; ++i) {
switch(i) {
case 0:
local offsetTile = Utils.getOffsetTile(topCornerTile, (-1) * rectangleIncreaseKoeficient, 0);
if(offsetTile == AIMap.TILE_INVALID) {
++maxExpandedCounter;
continue;
}
if(AITown.IsWithinTownInfluence(town, offsetTile)) {
topCornerTile = offsetTile;
}
// else if(expandRectangle(town, topCornerTile, bottomCornerTile, "NE")) {
// topCornerTile = Utils.getOffsetTile(topCornerTile, (-1) * rectangleIncreaseKoeficient, 0);
// }
else {
++maxExpandedCounter;
continue;
}
break;
case 1:
local offsetTile = Utils.getOffsetTile(bottomCornerTile, 0, rectangleIncreaseKoeficient);
if(offsetTile == AIMap.TILE_INVALID) {
++maxExpandedCounter;
continue;
}
if(AITown.IsWithinTownInfluence(town, offsetTile)) {
bottomCornerTile = offsetTile;
}
// else if(expandRectangle(town, topCornerTile, bottomCornerTile, "SE")) {
// bottomCornerTile = Utils.getOffsetTile(bottomCornerTile, 0, rectangleIncreaseKoeficient);
// }
else {
++maxExpandedCounter;
continue;
}
break;
case 2:
local offsetTile = Utils.getOffsetTile(bottomCornerTile, rectangleIncreaseKoeficient, 0);
if(offsetTile == AIMap.TILE_INVALID) {
++maxExpandedCounter;
continue;
}
if(AITown.IsWithinTownInfluence(town, offsetTile)) {
bottomCornerTile = offsetTile;
}
// else if(expandRectangle(town, topCornerTile, bottomCornerTile, "SW")) {
// bottomCornerTile = Utils.getOffsetTile(bottomCornerTile, rectangleIncreaseKoeficient, 0);
// }
else {
++maxExpandedCounter;
continue;
}
break;
case 3:
local offsetTile = Utils.getOffsetTile(topCornerTile, 0, (-1) * rectangleIncreaseKoeficient);
if(offsetTile == AIMap.TILE_INVALID) {
++maxExpandedCounter;
}
if(AITown.IsWithinTownInfluence(town, offsetTile)) {
topCornerTile = offsetTile;
}
// else if(expandRectangle(town, topCornerTile, bottomCornerTile, "NW")) {
// topCornerTile = Utils.getOffsetTile(topCornerTile, 0, (-1) * rectangleIncreaseKoeficient);
// }
else {
++maxExpandedCounter;
}
break;
default:
break;
}
}
if(maxExpandedCounter == 4) {
isMaxExpanded = true;
}
}
return [topCornerTile, bottomCornerTile];
}