ai_pathfinder.c
changeset 1716 943f28e3f2a0
parent 1714 2b8e37f8f18c
child 1729 d27130c7d9ef
equal deleted inserted replaced
1715:fcf19c98d815 1716:943f28e3f2a0
   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