ai_pathfinder.c
changeset 1035 812f837ee03f
parent 979 11ea18598e16
child 1047 df93a1386892
equal deleted inserted replaced
1034:e761d474e204 1035:812f837ee03f
    34 int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current) {
    34 int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current) {
    35 	Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
    35 	Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
    36 	// It is not allowed to have a station on the end of a bridge or tunnel ;)
    36 	// It is not allowed to have a station on the end of a bridge or tunnel ;)
    37 	if (current->path.node.user_data[0] != 0) return AYSTAR_DONE;
    37 	if (current->path.node.user_data[0] != 0) return AYSTAR_DONE;
    38 	if (TILES_BETWEEN(current->path.node.tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br))
    38 	if (TILES_BETWEEN(current->path.node.tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br))
    39 		if (IS_TILETYPE(current->path.node.tile, MP_CLEAR) || IS_TILETYPE(current->path.node.tile, MP_TREES))
    39 		if (IsTileType(current->path.node.tile, MP_CLEAR) || IsTileType(current->path.node.tile, MP_TREES))
    40 			if (current->path.parent == NULL || TestCanBuildStationHere(current->path.node.tile,AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile)))
    40 			if (current->path.parent == NULL || TestCanBuildStationHere(current->path.node.tile,AiNew_GetDirection(current->path.parent->node.tile, current->path.node.tile)))
    41     			return AYSTAR_FOUND_END_NODE;
    41     			return AYSTAR_FOUND_END_NODE;
    42 
    42 
    43 	return AYSTAR_DONE;
    43 	return AYSTAR_DONE;
    44 }
    44 }
   117 	start_node.node.tile = PathFinderInfo->start_tile_tl;
   117 	start_node.node.tile = PathFinderInfo->start_tile_tl;
   118 
   118 
   119 	// Now we add all the starting tiles
   119 	// Now we add all the starting tiles
   120 	for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
   120 	for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
   121 		for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
   121 		for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
   122 			if (!(IS_TILETYPE(TILE_XY(x,y), MP_CLEAR) || IS_TILETYPE(TILE_XY(x,y), MP_TREES))) continue;
   122 			if (!(IsTileType(TILE_XY(x,y), MP_CLEAR) || IsTileType(TILE_XY(x,y), MP_TREES))) continue;
   123 			if (!TestCanBuildStationHere(TILE_XY(x,y),TEST_STATION_NO_DIR)) continue;
   123 			if (!TestCanBuildStationHere(TILE_XY(x,y),TEST_STATION_NO_DIR)) continue;
   124 			start_node.node.tile = TILE_XY(x,y);
   124 			start_node.node.tile = TILE_XY(x,y);
   125 			aystar->addstart(aystar, &start_node.node);
   125 			aystar->addstart(aystar, &start_node.node);
   126 		}
   126 		}
   127 	}
   127 	}
   185        		// We also directly test if the current tile can connect to this tile..
   185        		// We also directly test if the current tile can connect to this tile..
   186        		//  We do this simply by just building the tile!
   186        		//  We do this simply by just building the tile!
   187 
   187 
   188        		// If the next step is a bridge, we have to enter it the right way
   188        		// 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))) {
   189        		if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile + TileOffsByDir(i))) {
   190        			if (IS_TILETYPE(current->path.node.tile + TileOffsByDir(i), MP_TUNNELBRIDGE)) {
   190        			if (IsTileType(current->path.node.tile + TileOffsByDir(i), MP_TUNNELBRIDGE)) {
   191        				// An existing bridge... let's test the direction ;)
   191        				// An existing bridge... let's test the direction ;)
   192        				if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 1U) != (i & 1)) continue;
   192        				if ((_map5[current->path.node.tile + TileOffsByDir(i)] & 1U) != (i & 1)) continue;
   193    					// This problem only is valid for tunnels:
   193    					// 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..
   194        				// When the last tile was not yet a tunnel, check if we enter from the right side..
   195        				if (!IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE) && (_map5[current->path.node.tile + TileOffsByDir(i)] & 0x80) == 0) {
   195        				if (!IsTileType(current->path.node.tile, MP_TUNNELBRIDGE) && (_map5[current->path.node.tile + TileOffsByDir(i)] & 0x80) == 0) {
   196        					if (i != (_map5[current->path.node.tile + TileOffsByDir(i)] & 3U)) continue;
   196        					if (i != (_map5[current->path.node.tile + TileOffsByDir(i)] & 3U)) continue;
   197        				}
   197        				}
   198        			}
   198        			}
   199        		}
   199        		}
   200        		// But also if we are on a bridge, we can only move a certain direction
   200        		// 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)) {
   201        		if (!PathFinderInfo->rail_or_road && AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
   202        			if (IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE)) {
   202        			if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   203        				// An existing bridge/tunnel... let's test the direction ;)
   203        				// An existing bridge/tunnel... let's test the direction ;)
   204        				if ((_map5[current->path.node.tile] & 1U) != (i & 1)) continue;
   204        				if ((_map5[current->path.node.tile] & 1U) != (i & 1)) continue;
   205        			}
   205        			}
   206        		}
   206        		}
   207 
   207 
   239 #endif
   239 #endif
   240        			} else {
   240        			} else {
   241        				// Road check
   241        				// Road check
   242        				dir = AiNew_GetRoadDirection(current->path.parent->node.tile, current->path.node.tile, current->path.node.tile + TileOffsByDir(i));
   242        				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)) {
   243        				if (AI_PATHFINDER_IS_ROAD(current->path.node.tile)) {
   244        					if (IS_TILETYPE(current->path.node.tile, MP_TUNNELBRIDGE)) {
   244        					if (IsTileType(current->path.node.tile, MP_TUNNELBRIDGE)) {
   245        						// We have a bridge, how nicely! We should mark it...
   245        						// We have a bridge, how nicely! We should mark it...
   246        						dir = 0;
   246        						dir = 0;
   247        					} else {
   247        					} else {
   248 	       					// It already has road.. check if we miss any bits!
   248 	       					// It already has road.. check if we miss any bits!
   249 	       					if ((_map5[current->path.node.tile] & dir) != dir) {
   249 	       					if ((_map5[current->path.node.tile] & dir) != dir) {
   283     	FindLandscapeHeightByTile(&ti, tile);
   283     	FindLandscapeHeightByTile(&ti, tile);
   284 
   284 
   285    		// Bridges can only be build on land that is not flat
   285    		// Bridges can only be build on land that is not flat
   286    		//  And if there is a road or rail blocking
   286    		//  And if there is a road or rail blocking
   287    		if (ti.tileh != 0 ||
   287    		if (ti.tileh != 0 ||
   288      		(PathFinderInfo->rail_or_road && IS_TILETYPE(tile + TileOffsByDir(dir), MP_STREET)) ||
   288      		(PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_STREET)) ||
   289        		(!PathFinderInfo->rail_or_road && IS_TILETYPE(tile + TileOffsByDir(dir), MP_RAILWAY))) {
   289        		(!PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_RAILWAY))) {
   290 
   290 
   291     		for (;;) {
   291     		for (;;) {
   292     			new_tile += TileOffsByDir(dir);
   292     			new_tile += TileOffsByDir(dir);
   293 
   293 
   294     	    	// Precheck, is the length allowed?
   294     	    	// Precheck, is the length allowed?
   376 				// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
   376 				// 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)))) {
   377 				if (r >= 15 || (r == 0 && (BRIDGE_NO_FOUNDATION & (1 << ti.tileh)))) {
   378 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   378 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   379 				}
   379 				}
   380 			} else {
   380 			} else {
   381 				if (!(AI_PATHFINDER_IS_ROAD(parent->path.node.tile) && IS_TILETYPE(parent->path.node.tile, MP_TUNNELBRIDGE))) {
   381 				if (!(AI_PATHFINDER_IS_ROAD(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));
   382 					r = GetRoadFoundation(parent_ti.tileh, AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
   383 					if (r >= 15 || r == 0)
   383 					if (r >= 15 || r == 0)
   384 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   384 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
   385 				}
   385 				}
   386 			}
   386 			}