ai_pathfinder.c
changeset 1047 df93a1386892
parent 1035 812f837ee03f
child 1095 b59632d9df1b
equal deleted inserted replaced
1046:f1d46abf7d35 1047:df93a1386892
    25         	return false;
    25         	return false;
    26     }
    26     }
    27     return true;
    27     return true;
    28 }
    28 }
    29 
    29 
       
    30 
       
    31 static bool IsRoad(TileIndex tile)
       
    32 {
       
    33 	return
       
    34 		// MP_STREET, but not a road depot?
       
    35 		(IsTileType(tile, MP_STREET) && !(_map5[tile] & 0x20)) ||
       
    36 		(IsTileType(tile, MP_TUNNELBRIDGE) && (
       
    37 			// road tunnel?
       
    38 			((_map5[tile] & 0x80) == 0 && (_map5[tile] & 0x4) == 0x4) ||
       
    39 			// road bridge?
       
    40 			((_map5[tile] & 0x80) != 0 && (_map5[tile] & 0x2) == 0x2)
       
    41 		));
       
    42 }
       
    43 
       
    44 
    30 // Checks if a tile 'a' is between the tiles 'b' and 'c'
    45 // Checks if a tile 'a' is between the tiles 'b' and 'c'
    31 #define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
    46 #define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
    32 
    47 
    33 // Check if the current tile is in our end-area
    48 // Check if the current tile is in our end-area
    34 int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current) {
    49 int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current) {
   184 					TileY(TileOffsByDir(i) + current->path.node.tile) < MapMaxY() - 1) {
   199 					TileY(TileOffsByDir(i) + current->path.node.tile) < MapMaxY() - 1) {
   185        		// We also directly test if the current tile can connect to this tile..
   200        		// We also directly test if the current tile can connect to this tile..
   186        		//  We do this simply by just building the tile!
   201        		//  We do this simply by just building the tile!
   187 
   202 
   188        		// If the next step is a bridge, we have to enter it the right way
   203        		// If the next step is a bridge, we have to enter it the right way
   189        		if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile + TileOffsByDir(i))) {
   204        		if (!PathFinderInfo->rail_or_road && IsRoad(current->path.node.tile + TileOffsByDir(i))) {
   190        			if (IsTileType(current->path.node.tile + TileOffsByDir(i), MP_TUNNELBRIDGE)) {
   205        			if (IsTileType(current->path.node.tile + TileOffsByDir(i), MP_TUNNELBRIDGE)) {
   191        				// An existing bridge... let's test the direction ;)
   206        				// An existing bridge... let's test the direction ;)
   192        				if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 1U) != (i & 1)) continue;
   207        				if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 1U) != (i & 1)) continue;
   193    					// This problem only is valid for tunnels:
   208    					// This problem only is valid for tunnels:
   194        				// When the last tile was not yet a tunnel, check if we enter from the right side..
   209        				// When the last tile was not yet a tunnel, check if we enter from the right side..
   196        					if (i != (_map5[current->path.node.tile + TileOffsByDir(i)] & 3U)) continue;
   211        					if (i != (_map5[current->path.node.tile + TileOffsByDir(i)] & 3U)) continue;
   197        				}
   212        				}
   198        			}
   213        			}
   199        		}
   214        		}
   200        		// But also if we are on a bridge, we can only move a certain direction
   215        		// But also if we are on a bridge, we can only move a certain direction
   201        		if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
   216        		if (!PathFinderInfo->rail_or_road && IsRoad(current->path.node.tile)) {
   202        			if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   217        			if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   203        				// An existing bridge/tunnel... let's test the direction ;)
   218        				// An existing bridge/tunnel... let's test the direction ;)
   204        				if ((_map5[current->path.node.tile] & 1U) != (i & 1)) continue;
   219        				if ((_map5[current->path.node.tile] & 1U) != (i & 1)) continue;
   205        			}
   220        			}
   206        		}
   221        		}
   238        				}
   253        				}
   239 #endif
   254 #endif
   240        			} else {
   255        			} else {
   241        				// Road check
   256        				// Road check
   242        				dir = AiNew_GetRoadDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + TileOffsByDir(i));
   257        				dir = AiNew_GetRoadDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + TileOffsByDir(i));
   243        				if (AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
   258        				if (IsRoad(current->path.node.tile)) {
   244        					if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   259        					if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   245        						// We have a bridge, how nicely! We should mark it...
   260        						// We have a bridge, how nicely! We should mark it...
   246        						dir = 0;
   261        						dir = 0;
   247        					} else {
   262        					} else {
   248 	       					// It already has road.. check if we miss any bits!
   263 	       					// It already has road.. check if we miss any bits!
   359 	res += AI_PATHFINDER_PENALTY;
   374 	res += AI_PATHFINDER_PENALTY;
   360 
   375 
   361 	if (!PathFinderInfo->rail_or_road) {
   376 	if (!PathFinderInfo->rail_or_road) {
   362 		// Road has the lovely advantage it can use other road... check if
   377 		// Road has the lovely advantage it can use other road... check if
   363 		//  the current tile is road, and if so, give a good bonus
   378 		//  the current tile is road, and if so, give a good bonus
   364 		if (AI_PATHFINDER_IS_ROAD(current->tile)) {
   379 		if (IsRoad(current->tile)) {
   365 			res -= AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS;
   380 			res -= AI_PATHFINDER_ROAD_ALREADY_EXISTS_BONUS;
   366 		}
   381 		}
   367 	}
   382 	}
   368 
   383 
   369 	// We should give a penalty when the tile is going up or down.. this is one way to do so!
   384 	// We should give a penalty when the tile is going up or down.. this is one way to do so!
   376 				// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
   391 				// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
   377 				if (r >= 15 || (r == 0 && (BRIDGE_NO_FOUNDATION & (1 << ti.tileh)))) {
   392 				if (r >= 15 || (r == 0 && (BRIDGE_NO_FOUNDATION & (1 << ti.tileh)))) {
   378 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   393 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   379 				}
   394 				}
   380 			} else {
   395 			} else {
   381 				if (!(AI_PATHFINDER_IS_ROAD(parent->path.node.tile) && IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE))) {
   396 				if (!(IsRoad(parent->path.node.tile) && IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE))) {
   382 					r = GetRoadFoundation(parent_ti.tileh, AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
   397 					r = GetRoadFoundation(parent_ti.tileh, AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
   383 					if (r >= 15 || r == 0)
   398 					if (r >= 15 || r == 0)
   384 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   399 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   385 				}
   400 				}
   386 			}
   401 			}
   421 	//  This way, we get almost the fastest way in tiles, and a very good speed on the track
   436 	//  This way, we get almost the fastest way in tiles, and a very good speed on the track
   422 	if (!PathFinderInfo->rail_or_road) {
   437 	if (!PathFinderInfo->rail_or_road) {
   423 		if (parent->path.parent != NULL &&
   438 		if (parent->path.parent != NULL &&
   424 			AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
   439 			AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
   425 			// When road exists, we don't like turning, but its free, so don't be to piggy about it
   440 			// When road exists, we don't like turning, but its free, so don't be to piggy about it
   426 			if (AI_PATHFINDER_IS_ROAD(parent->path.node.tile))
   441 			if (IsRoad(parent->path.node.tile))
   427 				res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
   442 				res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
   428 			else
   443 			else
   429 				res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
   444 				res += AI_PATHFINDER_DIRECTION_CHANGE_PENALTY;
   430 		}
   445 		}
   431 	} else {
   446 	} else {