OpenTTD AI which builds a road network between all towns it can reach.

town_manager.nut 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*--------------------------------------------------------------------
  2. | |
  3. | TownManager |
  4. | |
  5. --------------------------------------------------------------------*/
  6. class TownManager
  7. {
  8. constructor() {
  9. }
  10. function CreateExitRoute(busstop, town1);
  11. function FindLineBusStopLocation(town, pass_cargo_id, estimate);
  12. function EstimateAcceptance(town);
  13. function TryBuildRoadStation(tile);
  14. function BuildBusStop(tile);
  15. }
  16. /*------------------------------------------------------------------*/
  17. function TownManager::CreateExitRoute(busstop, town1)
  18. {
  19. local rtl = AITileList();
  20. rtl.Clear();
  21. rtl.AddRectangle(busstop + AIMap.GetTileIndex(-5,-5), busstop + AIMap.GetTileIndex(5,5));
  22. rtl.Valuate(Tile.IsRoadBuildable);
  23. rtl.KeepValue(1);
  24. rtl.Valuate(AITile.GetSlope);
  25. rtl.KeepValue(0);
  26. rtl.Valuate(AITile.GetDistanceManhattanToTile, AITown.GetLocation(town1));
  27. rtl.KeepBottom(1);
  28. local town_exit0 = rtl.Begin();
  29. return town_exit0;
  30. }
  31. /*------------------------------------------------------------------*/
  32. function TownManager::FindLineBusStopLocation(town, pass_cargo_id, estimate)
  33. {
  34. local tl = AITileList();
  35. local aitile = null;
  36. local tile = AITown.GetLocation(town);
  37. local ret_tile = null;
  38. tl.AddRectangle(tile + AIMap.GetTileIndex(-8, -8), tile + AIMap.GetTileIndex(8, 8));
  39. /* remove all tiles that are already covered by a station */
  40. local tl2 = AITileList();
  41. tl2.AddList(tl);
  42. tl2.Valuate(AIRoad.IsRoadStationTile);
  43. tl2.KeepValue(1);
  44. for (local rstl = tl2.Begin(); !tl2.IsEnd() ; rstl = tl2.Next()){
  45. /* reuse stations */
  46. if (AITile.GetOwner(rstl) == AICompany.ResolveCompanyID(AICompany.COMPANY_SELF)) {
  47. return rstl;
  48. //tl.RemoveRectangle(rstl + AIMap.GetTileIndex(-4, -4), rstl + AIMap.GetTileIndex(4, 4));
  49. }
  50. else { /* dont disturb other players stations ... */
  51. tl.RemoveRectangle(rstl + AIMap.GetTileIndex(-2, -2), rstl + AIMap.GetTileIndex(-2, -2));
  52. }
  53. }
  54. local Walker = MetaLib.SpiralWalker();
  55. Walker.Start(AITown.GetLocation(town));
  56. local built = false;
  57. while (built == false && Walker.GetStage()/4<=16) {
  58. ret_tile = Walker.Walk();
  59. //AISign.BuildSign(ret_tile,"no");
  60. built = TownManager.TryBuildRoadStation(ret_tile, estimate);
  61. }
  62. return ret_tile;
  63. }
  64. /*------------------------------------------------------------------*/
  65. function TownManager::BuildBusStop(tile)
  66. {
  67. local built = false;
  68. /*local Walker = MetaLib.SpiralWalker();
  69. Walker.Start(tile);
  70. local built = false;
  71. while (built == false) {
  72. tile = Walker.Walk();*/
  73. built = TownManager.TryBuildRoadStation(tile, false);
  74. //}
  75. if (!built) {
  76. AILog.Info("Build busstop failed "+ AIError.GetLastErrorString());
  77. // AISign.BuildSign(tile,"bbs");
  78. }
  79. return built;
  80. }
  81. /*------------------------------------------------------------------*/
  82. function TownManager::EstimateAcceptance(town, passenger_cargo_id)
  83. {
  84. local new_location = TownManager.FindLineBusStopLocation(town,
  85. passenger_cargo_id, true);
  86. local acceptance = 0;
  87. if (new_location){
  88. acceptance = AITile.GetCargoAcceptance(new_location, passenger_cargo_id, 1, 1,
  89. AIStation.GetCoverageRadius (AIStation.STATION_BUS_STOP));
  90. }
  91. return acceptance;
  92. }
  93. /**
  94. * Builds a station on the given tile
  95. * @param station Tile to build station on
  96. */
  97. function TownManager::TryBuildRoadStation(tile, estmiate)
  98. {
  99. if(tile == null){throw("tile null in trybuildroadstation");}
  100. if(!AIRoad.IsRoadTile(tile)) {
  101. return false;
  102. }
  103. local adjacent_tiles = Tile.GetAdjacentTiles(tile);
  104. foreach(road, _ in adjacent_tiles) {//check road access
  105. if(AIRoad.IsRoadTile(road)) {
  106. if (estmiate)
  107. return tile;
  108. /*
  109. if(!AIRoad.IsRoadTile(tile)) {//if tile is allready road no need to build road
  110. if (!AIRoad.BuildRoad(tile, road) && AIError.GetLastErrorString() != "ERR_ALREADY_BUILT") {
  111. //AISign.BuildSign(road,"no");
  112. //continue;
  113. }
  114. }
  115. if(!AIRoad.AreRoadTilesConnected(tile,road)){continue;}
  116. */
  117. if (AIRoad.IsDriveThroughRoadStationTile(tile) && AITile.GetOwner(tile) == AICompany.ResolveCompanyID(AICompany.COMPANY_SELF))
  118. return tile;
  119. if (!AIRoad.BuildDriveThroughRoadStation(tile,road,AIRoad.ROADVEHTYPE_TRUCK,AIStation.STATION_NEW)) {
  120. //AISign.BuildSign(road,"bbs");
  121. if (AIError.GetLastErrorString() != "ERR_ALREADY_BUILT" && AITile.GetOwner(tile) == AICompany.ResolveCompanyID(AICompany.COMPANY_SELF))
  122. return tile;
  123. continue;
  124. }
  125. local station_id = AIStation.GetStationID(tile);
  126. AIStation.SetName( station_id, "Post Office "+AITown.GetName(AIStation.GetNearestTown(station_id)) );
  127. road = AIRoad.GetRoadStationFrontTile(tile);
  128. local crossing_tiles = Tile.GetAdjacentTiles(road);
  129. foreach(crossing, _ in crossing_tiles) {
  130. AIRoad.BuildRoadFull(road, crossing);
  131. }
  132. road = AIRoad.GetDriveThroughBackTile(tile);
  133. crossing_tiles = Tile.GetAdjacentTiles(road);
  134. foreach(crossing, _ in crossing_tiles) {
  135. AIRoad.BuildRoadFull(road, crossing);
  136. }
  137. return tile;
  138. }//end if road tile
  139. }//end for each road
  140. return false;
  141. }