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]; }