Loading

#### Paste #pivfk1xw7

1. function Road::_Cost(self, path, new_tile, new_direction)
2. {
3.     /* path == null means this is the first node of a path, so the cost is 0. */
4.     if (path == null) return 0;
5.
6.     local prev_tile = path.GetTile();
7.
8.     /* If the new tile is a bridge / tunnel tile, check whether we came from the other
9.      * end of the bridge / tunnel or if we just entered the bridge / tunnel. */
10.     if (AIBridge.IsBridgeTile(new_tile)) {
11.         if (AIBridge.GetOtherBridgeEnd(new_tile) != prev_tile) {
12.
13.             /* Check for a turn. We do this by substracting the TileID of the current node from
14.              * the TileID of the previous node and comparing that to the difference between the
15.              * previous node and the node before that. */
16.             local cost = self._cost_tile;
17.             if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) &&
18.                     AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) {
19.                 cost += self._cost_turn;
20.             }
21.
22.             /* Check if the last tile was sloped. */
23.             if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) &&
24.                     AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) {
25.                 cost += self._cost_slope;
26.             }
27.
28.             if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) {
29.                 cost += self._cost_no_existing_road;
30.             }
31.
32.             return path.GetCost() + cost;
33.         }
34.         return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_bridge_per_tile) - self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
35.     }
36.     if (AITunnel.IsTunnelTile(new_tile)) {
37.         if (AITunnel.GetOtherTunnelEnd(new_tile) != prev_tile) {
38.
39.             /* Check for a turn. We do this by substracting the TileID of the current node from
40.              * the TileID of the previous node and comparing that to the difference between the
41.              * previous node and the node before that. */
42.             local cost = self._cost_tile;
43.             if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) &&
44.                     AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) {
45.                 cost += self._cost_turn;
46.             }
47.
48.             /* Check if the last tile was sloped. */
49.             if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) &&
50.                     AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) {
51.                 cost += self._cost_slope;
52.             }
53.
54.             if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) {
55.                 cost += self._cost_no_existing_road;
56.             }
57.
58.             return path.GetCost() + cost;
59.         }
60.         return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_tunnel_per_tile) - self._cost_tile;
61.     }
62.
63.     /* If the two tiles are more than 1 tile apart, the pathfinder wants a bridge or tunnel
64.      * to be built. It isn't an existing bridge / tunnel, as that case is already handled. */
65.     if (AIMap.DistanceManhattan(new_tile, prev_tile) > 1) {
66.         /* Check if we should build a bridge or a tunnel. */
67.         if (AITunnel.GetOtherTunnelEnd(new_tile) == prev_tile) {
68.             return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_tunnel_per_tile + self._cost_no_existing_road) - self._cost_tile;
69.         } else {
70.             local cost = (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_bridge_per_tile + self._cost_no_existing_road) - self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope;
71.             /* Check if the new tile is a coast tile. */
72.             if (AITile.IsCoastTile(new_tile) && AITile.HasTransportType(new_tile, AITile.TRANSPORT_WATER)) {
73.                 cost += self._cost_coast;
74.             }
75.             return path.GetCost() + cost;
76.         }
77.     }
78.
79.     /* Check for a turn. We do this by substracting the TileID of the current node from
80.      * the TileID of the previous node and comparing that to the difference between the
81.      * previous node and the node before that. */
82.     local cost = self._cost_tile;
83.     if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) &&
84.             AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) {
85.         cost += self._cost_turn;
86.     }
87.
88.     /* Check if the new tile is a coast tile. */
89.     if (AITile.IsCoastTile(new_tile) && AITile.HasTransportType(new_tile, AITile.TRANSPORT_WATER)) {
90.         cost += self._cost_coast;
91.     }
92.
93.     /* Check if the last tile was sloped. */
94.     if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) &&
95.             AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) {
96.         cost += self._cost_slope;
97.     }
98.
99.     if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) {
100.         cost += self._cost_no_existing_road;
101.     }
102.
103.     return path.GetCost() + cost;
104. }