private void OnDrawGizmos() { if(startNode.isStartNode != true) startNode.isStartNode = true; if(startNode == null || endNode == null) { nodes = new List<AINode>(transform.childCount); for(int i = 0; i < nodes.Count; i++) { nodes[i] = transform.GetChild(i).GetComponent<AINode>(); } startNode = nodes[0]; endNode = nodes[nodes.Count]; } if (!(road = transform.parent.GetComponent<AIRoad>())) Debug.LogError("AILane: " + transform.parent + " / " + gameObject.name + " Cant find an AIRoad component attached to the parent"); Gizmos.color = Color.green; for(int i = 0; i < nodes.Count -1; i++) { Gizmos.DrawLine(nodes[i].transform.position, nodes[i + 1].transform.position); } }
protected override void Start() { AICompany.SetLoanAmount(0); SignManager signManager = new SignManager(); TownNetwork tn = new TownNetwork(); try { AICompany.SetLoanAmount(AICompany.GetMaxLoanAmount()); AIRoad.SetCurrentRoadType(AIRoad.ROADTYPE_ROAD); foreach (var edge in tn.Graph.Edges) { AILog.Info($"Build road from {edge.Node1.Name} to {edge.Node2.Name}."); var stationInfo1 = tn.EnsureStation(edge.Node1); var stationInfo2 = tn.EnsureStation(edge.Node2); RoadBuilder.BuildRoad( stationInfo1.tile, stationInfo1.entryPoint, stationInfo2.entryPoint, stationInfo2.tile, new HashSet <TileIndex>() ); var depotInfo1 = tn.EnsureDepot(edge.Node1); var depotInfo2 = tn.EnsureDepot(edge.Node2); tn.MakeRoute(edge.Node1, edge.Node2); tn.MakeRoute(edge.Node2, edge.Node1); } } catch { } Sleep(50); signManager.ClearSigns(); var step = 0; while (true) { // Main loop //this.setMinLoan(); CsTestAi.SetMinimumLoanAmount(); tn.UpdateRoutes(); Sleep(100); step++; } }
internal RoadStationInfo EnsureStation(TownNode townNode) { if (this.stations.ContainsKey(townNode.TownId)) { return(this.stations[townNode.TownId]); } var place = RoadStationBuilder.FindPlaceForStation(townNode.Location.Tile); AIRoad.BuildRoadStation(place.tile, place.entryPoint, AIRoad.ROADVEHTYPE_BUS, AIStation.STATION_NEW); AIRoad.BuildRoad(place.tile, place.entryPoint); this.stations.Add(townNode.TownId, place); return(place); }
private static RoadStationInfo TestPlaceForStation(TileIndex tile) { if (AITile.IsBuildable(tile) && (AITile.GetSlope(tile) == AITile.SLOPE_FLAT)) { var other = tile + AIMap.GetTileIndex(0, 1); if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT)) { return(new RoadStationInfo() { tile = tile, entryPoint = other }); } other = tile + AIMap.GetTileIndex(1, 0); if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT)) { return(new RoadStationInfo() { tile = tile, entryPoint = other }); } other = tile + AIMap.GetTileIndex(0, -1); if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT)) { return(new RoadStationInfo() { tile = tile, entryPoint = other }); } other = tile + AIMap.GetTileIndex(-1, 0); if (AIRoad.IsRoadTile(other) && (AITile.GetSlope(other) == AITile.SLOPE_FLAT)) { return(new RoadStationInfo() { tile = tile, entryPoint = other }); } } return(null); }
internal RoadStationInfo EnsureDepot(TownNode townNode) { if (this.depots.ContainsKey(townNode.TownId)) { return(this.depots[townNode.TownId]); } var place = RoadStationBuilder.FindPlaceForStation(townNode.Location.Tile); if (place != null) { AIRoad.BuildRoadDepot(place.tile, place.entryPoint); AIRoad.BuildRoad(place.tile, place.entryPoint); this.depots.Add(townNode.TownId, place); return(place); } else { return(null); } }
internal static bool BuildRoad(TileIndex previous, TileIndex from, TileIndex to, TileIndex next, HashSet <TileIndex> forbidden, Action <TileIndex, string> sign = null) { var path = RoadBuilder.FindPath(from, to, previous, forbidden); if (path == null) { return(false); } for (var i = 0; i < path.Count - 1; i++) { var p = i == 0 ? next : path[i - 1].Tile; var c = path[i].Tile; var n = i == path.Count - 1 ? previous : path[i + 1].Tile; var nt = i == 0 ? BuildType.Basic : path[i - 1].Type; //sign(c, "[" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] " + path[i].type); bool good = false; switch (path[i].Type) { case BuildType.Basic: if (path[i].Length > 1) { AILog.Error($"Length is: {path[i].Length}. ([" + AIMap.GetTileX(p) + ", " + AIMap.GetTileY(p) + "] via [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "])"); continue; //throw new Exception("Should not be Road"); } if (nt != BuildType.Basic) { continue; } //AILog.Info("Build a Road from [" + AIMap.GetTileX(p) + ", " + AIMap.GetTileY(p) + "] via [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "]."); good = AIRoad.BuildRoad(p, c); good = AIRoad.BuildRoad(c, n); break; case BuildType.Bridge: var bridgeTypes = new AIBridgeList_Length(path[i].Length); //AILog.Info("Build a bridge " + bridgeTypes.Begin() + " from [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "] to [" + AIMap.GetTileX(n) + ", " + AIMap.GetTileY(n) + "]."); good = AIBridge.BuildBridge(AIVehicle.VT_ROAD, bridgeTypes.Begin(), c, n); if ((!good) && (sign != null)) { sign(p, "s"); sign(c, "e"); } break; case BuildType.Tunnel: throw new Exception("Tunnels not supported"); } if (!good) { var reason = AIError.GetLastErrorString(); if (reason != "ERR_ALREADY_BUILT") { AILog.Error("Failed to build on [" + AIMap.GetTileX(c) + ", " + AIMap.GetTileY(c) + "]. Reason: " + reason); } } } return(true); }
internal static List <PathInfo> GetNeighbors(TileIndex tile, PathInfo cameFrom, Action <TileIndex, string> sign = null) { var oldcost = cameFrom.Cost; var result = new List <PathInfo>(); var isFlat = AITile.GetSlope(tile) == AITile.SLOPE_FLAT; var dirs = new int[][] { new int[] { 0, 1 }, new int[] { 0, -1 }, new int[] { 1, 0 }, new int[] { -1, 0 } }; var oldDir = (cameFrom.Previous != null) ? Helper.GetDirection(cameFrom.Previous.Tile, tile) : Direction.None; foreach (var dir in dirs) { var x = dir[0]; var y = dir[1]; if (cameFrom.Tile == tile + AIMap.GetTileIndex(x, y)) { continue; } var newDir = Helper.GetDirection(tile, tile + AIMap.GetTileIndex(x, y)); var isCoast = AITile.IsCoastTile(tile); var straight = newDir == oldDir; var maxLength = 20; bool lastWasExistingBridge = false; TileIndex neighbor; for (var length = 1; AIMap.IsValidTile(neighbor = tile + AIMap.GetTileIndex(x * length, y * length)) && length <= maxLength; length++) { if (AIBridge.IsBridgeTile(neighbor)) { var otherEnd = AIBridge.GetOtherBridgeEnd(neighbor); var bridgeDir = Helper.GetDirection(neighbor, otherEnd); if (newDir == bridgeDir) { length += AIMap.DistanceManhattan(neighbor, otherEnd); lastWasExistingBridge = true; continue; } } else if (AIRoad.IsRoadTile(neighbor) && (lastWasExistingBridge || (length == 1))) { result.Add(new PathInfo( neighbor, length, oldcost + (length * 0.5), length > 1 ? BuildType.Bridge : BuildType.Basic, cameFrom )); break; } lastWasExistingBridge = false; if (isCoast) { if (!straight) { break; } if (AITile.IsWaterTile(neighbor)) { continue; } } double multiplier = 1; if (AITile.IsFarmTile(neighbor) || AITile.IsRockTile(neighbor) || AITile.IsRoughTile(tile)) { // Make farms, rocks, etc more expensive. multiplier *= 1.1; } if (AITile.IsBuildable(neighbor)) { if (isCoast) { result.Add(new PathInfo( neighbor, length, oldcost + ((length * multiplier * 2)), BuildType.Bridge, cameFrom )); break; } else if ((isFlat && cameFrom.Length == 1) || ((length == 1) && straight)) { result.Add(new PathInfo( neighbor, length, oldcost + ((length * multiplier)), length == 1 ? BuildType.Basic : BuildType.Bridge, cameFrom )); break; } } else if (!( (AIRoad.IsRoadTile(neighbor) || AIRoad.IsRoadTile(neighbor) || AITile.IsWaterTile(neighbor)) && (AITile.GetSlope(neighbor) == AITile.SLOPE_FLAT) && !AIStation.IsValidStation(AIStation.GetStationID(neighbor)))) { // Can't built over break; } } } return(result); }
internal static List <PathInfo> GetNeighbors(TileIndex tile, PathInfo cameFrom, Action <TileIndex, string> sign = null) { var oldcost = cameFrom.Cost; var result = new List <PathInfo>(); var isFlat = AITile.GetSlope(tile) == AITile.SLOPE_FLAT; var dirs = new int[][] { new int[] { 0, 1 }, new int[] { 0, -1 }, new int[] { 1, 0 }, new int[] { -1, 0 } }; var oldDir = Helper.GetDirection(tile, cameFrom.Previous.Tile); foreach (var dir in dirs) { var x = dir[0]; var y = dir[1]; if (cameFrom.Tile == tile + AIMap.GetTileIndex(x, y)) { continue; } var newDir = Helper.GetDirection(tile + AIMap.GetTileIndex(x, y), tile); var isCoast = AITile.IsCoastTile(tile); var straight = newDir == oldDir; var maxLength = isCoast ? 20 : (straight ? 5 : 1); TileIndex neighbor; for (var length = 1; AIMap.IsValidTile(neighbor = tile + AIMap.GetTileIndex(x * length, y * length)) && length <= maxLength; length++) { if (isCoast) { if (!straight) { break; } if (AITile.IsWaterTile(neighbor)) { continue; } } double multiplier = 1; if (AITile.IsFarmTile(neighbor) || AITile.IsRockTile(neighbor) || AITile.IsRoughTile(tile)) { // Make farms, rocks, etc more expensive. multiplier *= 1.1; } if (AITile.IsBuildable(neighbor)) { double angleFactor = RailBuilder.CalculateAngle(neighbor, tile, cameFrom.Previous); if (isCoast) { result.Add(new PathInfo( neighbor, length, oldcost + ((length * multiplier * 2) + angleFactor), BuildType.Bridge, cameFrom )); break; } else if ((isFlat && cameFrom.Length == 1) || ((length == 1) && straight)) { result.Add(new PathInfo( neighbor, length, oldcost + ((length * multiplier) + angleFactor), length == 1 ? BuildType.Basic : BuildType.Bridge, cameFrom )); break; } } else if (!( (AIRail.IsRailTile(neighbor) || AIRoad.IsRoadTile(neighbor) || AITile.IsWaterTile(neighbor)) && (AITile.GetSlope(neighbor) == AITile.SLOPE_FLAT) && !AIStation.IsValidStation(AIStation.GetStationID(neighbor)))) { // Can't built over break; } } } return(result); }