197 |
197 |
198 aystar->num_neighbours = 0; |
198 aystar->num_neighbours = 0; |
199 |
199 |
200 // Go through all surrounding tiles and check if they are within the limits |
200 // Go through all surrounding tiles and check if they are within the limits |
201 for (i = 0; i < 4; i++) { |
201 for (i = 0; i < 4; i++) { |
202 if (TileX(TileOffsByDir(i) + current->path.node.tile) > 1 && |
202 TileIndex ctile = current->path.node.tile; // Current tile |
203 TileX(TileOffsByDir(i) + current->path.node.tile) < MapMaxX() - 1 && |
203 TileIndex atile = ctile + TileOffsByDir(i); // Adjacent tile |
204 TileY(TileOffsByDir(i) + current->path.node.tile) > 1 && |
204 |
205 TileY(TileOffsByDir(i) + current->path.node.tile) < MapMaxY() - 1) { |
205 if (TileX(atile) > 1 && |
|
206 TileX(atile) < MapMaxX() - 1 && |
|
207 TileY(atile) > 1 && |
|
208 TileY(atile) < MapMaxY() - 1) { |
206 // We also directly test if the current tile can connect to this tile.. |
209 // We also directly test if the current tile can connect to this tile.. |
207 // We do this simply by just building the tile! |
210 // We do this simply by just building the tile! |
208 |
211 |
209 // If the next step is a bridge, we have to enter it the right way |
212 // If the next step is a bridge, we have to enter it the right way |
210 if (!PathFinderInfo->rail_or_road && IsRoad(current->path.node.tile + TileOffsByDir(i))) { |
213 if (!PathFinderInfo->rail_or_road && IsRoad(atile)) { |
211 if (IsTileType(current->path.node.tile + TileOffsByDir(i), MP_TUNNELBRIDGE)) { |
214 if (IsTileType(atile, MP_TUNNELBRIDGE)) { |
212 // An existing bridge... let's test the direction ;) |
215 // An existing bridge... let's test the direction ;) |
213 if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 1U) != (i & 1)) continue; |
216 if ((_map5[atile] & 1U) != (i & 1)) continue; |
214 // This problem only is valid for tunnels: |
217 // This problem only is valid for tunnels: |
215 // When the last tile was not yet a tunnel, check if we enter from the right side.. |
218 // When the last tile was not yet a tunnel, check if we enter from the right side.. |
216 if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 0x80) == 0) { |
219 if ((_map5[atile] & 0x80) == 0) { |
217 if (i != (_map5[current->path.node.tile + TileOffsByDir(i)] & 3U)) continue; |
220 if (i != (_map5[atile] & 3U)) continue; |
218 } |
221 } |
219 } |
222 } |
220 } |
223 } |
221 // But also if we are on a bridge, we can only move a certain direction |
224 // But also if we are on a bridge, we can only move a certain direction |
222 if (!PathFinderInfo->rail_or_road && IsRoad(current->path.node.tile)) { |
225 if (!PathFinderInfo->rail_or_road && IsRoad(ctile)) { |
223 if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) { |
226 if (IsTileType(ctile, MP_TUNNELBRIDGE)) { |
224 // An existing bridge/tunnel... let's test the direction ;) |
227 // An existing bridge/tunnel... let's test the direction ;) |
225 if ((_map5[current->path.node.tile] & 1U) != (i & 1)) continue; |
228 if ((_map5[ctile] & 1U) != (i & 1)) continue; |
226 } |
229 } |
227 } |
230 } |
228 |
231 |
229 if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 || |
232 if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 || |
230 (AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) { |
233 (AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) { |
237 // First, check if we have a parent |
240 // First, check if we have a parent |
238 if (current->path.parent == NULL && current->path.node.user_data[0] == 0) { |
241 if (current->path.parent == NULL && current->path.node.user_data[0] == 0) { |
239 // If not, this means we are at the starting station |
242 // If not, this means we are at the starting station |
240 if (PathFinderInfo->start_direction != AI_PATHFINDER_NO_DIRECTION) { |
243 if (PathFinderInfo->start_direction != AI_PATHFINDER_NO_DIRECTION) { |
241 // We do need a direction? |
244 // We do need a direction? |
242 if (AiNew_GetDirection(current->path.node.tile, current->path.node.tile + TileOffsByDir(i)) != PathFinderInfo->start_direction) { |
245 if (AiNew_GetDirection(ctile, atile) != PathFinderInfo->start_direction) { |
243 // We are not pointing the right way, invalid tile |
246 // We are not pointing the right way, invalid tile |
244 continue; |
247 continue; |
245 } |
248 } |
246 } |
249 } |
247 } else if (current->path.node.user_data[0] == 0) { |
250 } else if (current->path.node.user_data[0] == 0) { |
248 if (PathFinderInfo->rail_or_road) { |
251 if (PathFinderInfo->rail_or_road) { |
249 // Rail check |
252 // Rail check |
250 dir = AiNew_GetRailDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + TileOffsByDir(i)); |
253 dir = AiNew_GetRailDirection(current->path.parent->node.tile, ctile, atile); |
251 ret = DoCommandByTile(current->path.node.tile, 0, dir, DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL); |
254 ret = DoCommandByTile(ctile, 0, dir, DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL); |
252 if (CmdFailed(ret)) continue; |
255 if (CmdFailed(ret)) continue; |
253 #ifdef AI_PATHFINDER_NO_90DEGREES_TURN |
256 #ifdef AI_PATHFINDER_NO_90DEGREES_TURN |
254 if (current->path.parent->parent != NULL) { |
257 if (current->path.parent->parent != NULL) { |
255 // Check if we don't make a 90degree curve |
258 // Check if we don't make a 90degree curve |
256 int dir1 = AiNew_GetRailDirection(current->path.parent->parent->node.tile, current->path.parent->node.tile, current->path.node.tile); |
259 int dir1 = AiNew_GetRailDirection(current->path.parent->parent->node.tile, current->path.parent->node.tile, ctile); |
257 if (_illegal_curves[dir1] == dir || _illegal_curves[dir] == dir1) { |
260 if (_illegal_curves[dir1] == dir || _illegal_curves[dir] == dir1) { |
258 continue; |
261 continue; |
259 } |
262 } |
260 } |
263 } |
261 #endif |
264 #endif |
262 } else { |
265 } else { |
263 // Road check |
266 // Road check |
264 dir = AiNew_GetRoadDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + TileOffsByDir(i)); |
267 dir = AiNew_GetRoadDirection(current->path.parent->node.tile, ctile, atile); |
265 if (IsRoad(current->path.node.tile)) { |
268 if (IsRoad(ctile)) { |
266 if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) { |
269 if (IsTileType(ctile, MP_TUNNELBRIDGE)) { |
267 // We have a bridge, how nicely! We should mark it... |
270 // We have a bridge, how nicely! We should mark it... |
268 dir = 0; |
271 dir = 0; |
269 } else { |
272 } else { |
270 // It already has road.. check if we miss any bits! |
273 // It already has road.. check if we miss any bits! |
271 if ((_map5[current->path.node.tile] & dir) != dir) { |
274 if ((_map5[ctile] & dir) != dir) { |
272 // We do miss some pieces :( |
275 // We do miss some pieces :( |
273 dir &= ~_map5[current->path.node.tile]; |
276 dir &= ~_map5[ctile]; |
274 } else { |
277 } else { |
275 dir = 0; |
278 dir = 0; |
276 } |
279 } |
277 } |
280 } |
278 } |
281 } |
279 // Only destruct things if it is MP_CLEAR of MP_TREES |
282 // Only destruct things if it is MP_CLEAR of MP_TREES |
280 if (dir != 0) { |
283 if (dir != 0) { |
281 ret = DoCommandByTile(current->path.node.tile, dir, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD); |
284 ret = DoCommandByTile(ctile, dir, 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD); |
282 if (CmdFailed(ret)) continue; |
285 if (CmdFailed(ret)) continue; |
283 } |
286 } |
284 } |
287 } |
285 } |
288 } |
286 |
289 |
287 // The tile can be connected |
290 // The tile can be connected |
288 aystar->neighbours[aystar->num_neighbours].tile = TileOffsByDir(i) + current->path.node.tile; |
291 aystar->neighbours[aystar->num_neighbours].tile = atile; |
289 aystar->neighbours[aystar->num_neighbours].user_data[0] = 0; |
292 aystar->neighbours[aystar->num_neighbours].user_data[0] = 0; |
290 aystar->neighbours[aystar->num_neighbours++].direction = 0; |
293 aystar->neighbours[aystar->num_neighbours++].direction = 0; |
291 } |
294 } |
292 } |
295 } |
293 |
296 |