38 * NPF scale, ie the number of full tiles multiplied by NPF_TILE_LENGTH to |
38 * NPF scale, ie the number of full tiles multiplied by NPF_TILE_LENGTH to |
39 * prevent rounding. |
39 * prevent rounding. |
40 */ |
40 */ |
41 static uint NPFDistanceTrack(TileIndex t0, TileIndex t1) |
41 static uint NPFDistanceTrack(TileIndex t0, TileIndex t1) |
42 { |
42 { |
43 const uint dx = delta(TileX(t0), TileX(t1)); |
43 const uint dx = Delta(TileX(t0), TileX(t1)); |
44 const uint dy = delta(TileY(t0), TileY(t1)); |
44 const uint dy = Delta(TileY(t0), TileY(t1)); |
45 |
45 |
46 const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */ |
46 const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */ |
47 /* OPTIMISATION: |
47 /* OPTIMISATION: |
48 * Original: diagTracks = max(dx, dy) - min(dx,dy); |
48 * Original: diagTracks = max(dx, dy) - min(dx,dy); |
49 * Proof: |
49 * Proof: |
102 uint x; |
102 uint x; |
103 uint y; |
103 uint y; |
104 |
104 |
105 /* we are going the aim for the x coordinate of the closest corner |
105 /* we are going the aim for the x coordinate of the closest corner |
106 * but if we are between those coordinates, we will aim for our own x coordinate */ |
106 * but if we are between those coordinates, we will aim for our own x coordinate */ |
107 x = clamp(TileX(tile), minx, maxx); |
107 x = Clamp(TileX(tile), minx, maxx); |
108 |
108 |
109 /* same for y coordinate, see above comment */ |
109 /* same for y coordinate, see above comment */ |
110 y = clamp(TileY(tile), miny, maxy); |
110 y = Clamp(TileY(tile), miny, maxy); |
111 |
111 |
112 /* return the tile of our target coordinates */ |
112 /* return the tile of our target coordinates */ |
113 return TileXY(x, y); |
113 return TileXY(x, y); |
114 } |
114 } |
115 |
115 |
190 } |
190 } |
191 |
191 |
192 static uint NPFSlopeCost(AyStarNode* current) |
192 static uint NPFSlopeCost(AyStarNode* current) |
193 { |
193 { |
194 TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir((Trackdir)current->direction)); |
194 TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir((Trackdir)current->direction)); |
195 int x,y; |
195 |
196 int8 z1,z2; |
196 /* Get center of tiles */ |
197 |
197 int x1 = TileX(current->tile) * TILE_SIZE + TILE_SIZE / 2; |
198 x = TileX(current->tile) * TILE_SIZE; |
198 int y1 = TileY(current->tile) * TILE_SIZE + TILE_SIZE / 2; |
199 y = TileY(current->tile) * TILE_SIZE; |
199 int x2 = TileX(next) * TILE_SIZE + TILE_SIZE / 2; |
200 /* get the height of the center of the current tile */ |
200 int y2 = TileY(next) * TILE_SIZE + TILE_SIZE / 2; |
201 z1 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2); |
201 |
202 |
202 int dx4 = (x2 - x1) / 4; |
203 x = TileX(next) * TILE_SIZE; |
203 int dy4 = (y2 - y1) / 4; |
204 y = TileY(next) * TILE_SIZE; |
204 |
205 /* get the height of the center of the next tile */ |
205 /* Get the height on both sides of the tile edge. |
206 z2 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2); |
206 * Avoid testing the height on the tile-center. This will fail for halftile-foundations. |
|
207 */ |
|
208 int z1 = GetSlopeZ(x1 + dx4, y1 + dy4); |
|
209 int z2 = GetSlopeZ(x2 - dx4, y2 - dy4); |
207 |
210 |
208 if (z2 - z1 > 1) { |
211 if (z2 - z1 > 1) { |
209 /* Slope up */ |
212 /* Slope up */ |
210 return _patches.npf_rail_slope_penalty; |
213 return _patches.npf_rail_slope_penalty; |
211 } |
214 } |
597 } |
600 } |
598 |
601 |
599 /* check correct rail type (mono, maglev, etc) */ |
602 /* check correct rail type (mono, maglev, etc) */ |
600 if (type == TRANSPORT_RAIL) { |
603 if (type == TRANSPORT_RAIL) { |
601 RailType dst_type = GetTileRailType(dst_tile); |
604 RailType dst_type = GetTileRailType(dst_tile); |
602 if (!HASBIT(aystar->user_data[NPF_RAILTYPES], dst_type)) |
605 if (!HasBit(aystar->user_data[NPF_RAILTYPES], dst_type)) |
603 return; |
606 return; |
604 } |
607 } |
605 |
608 |
606 /* Check the owner of the tile */ |
609 /* Check the owner of the tile */ |
607 if (!VehicleMayEnterTile((Owner)aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) { |
610 if (!VehicleMayEnterTile((Owner)aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) { |