232 if ((_map5[tile] & 0xF0)==0) { |
232 if ((_map5[tile] & 0xF0)==0) { |
233 cost = NPFTunnelCost(current); |
233 cost = NPFTunnelCost(current); |
234 break; |
234 break; |
235 } |
235 } |
236 /* Fall through if above if is false, it is a bridge |
236 /* Fall through if above if is false, it is a bridge |
237 * then. We treat that as ordinary rail */ |
237 * then. We treat that as ordinary road */ |
238 case MP_STREET: |
238 case MP_STREET: |
239 cost = NPF_TILE_LENGTH; |
239 cost = NPF_TILE_LENGTH; |
|
240 /* Increase the cost for level crossings */ |
|
241 if ((_map5[tile] & 0xF0) == 0x10) |
|
242 cost += _patches.npf_crossing_penalty; |
240 break; |
243 break; |
241 default: |
244 default: |
242 break; |
245 break; |
243 } |
246 } |
244 |
247 |
522 * that I can enter the tunnel from a tile below the tunnel entrance. This |
525 * that I can enter the tunnel from a tile below the tunnel entrance. This |
523 * solves the problem of vehicles wanting to drive off a tunnel entrance */ |
526 * solves the problem of vehicles wanting to drive off a tunnel entrance */ |
524 if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_map5[dst_tile] & 0xF0) == 0 && GetTileZ(dst_tile) < GetTileZ(src_tile)) |
527 if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_map5[dst_tile] & 0xF0) == 0 && GetTileZ(dst_tile) < GetTileZ(src_tile)) |
525 return; |
528 return; |
526 |
529 |
527 /* check correct rail type (mono, maglev, etc) |
530 /* check correct rail type (mono, maglev, etc) */ |
528 * XXX: This now compares with the previous tile, which should not pose a |
|
529 * problem, but it might be nicer to compare with the first tile, or even |
|
530 * the type of the vehicle... Maybe an NPF_RAILTYPE userdata sometime? */ |
|
531 if (type == TRANSPORT_RAIL) { |
531 if (type == TRANSPORT_RAIL) { |
532 RailType src_type = GetTileRailType(src_tile, src_trackdir); |
532 RailType dst_type = GetTileRailType(dst_tile, src_trackdir); |
533 RailType dst_type = GetTileRailType(dst_tile, TrackdirToExitdir(src_trackdir)); |
533 if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type)) |
534 if (src_type != dst_type) { |
|
535 return; |
534 return; |
536 } |
|
537 } |
535 } |
538 |
536 |
539 /* Check the owner of the tile */ |
537 /* Check the owner of the tile */ |
540 if (!VehicleMayEnterTile(aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) { |
538 if (!VehicleMayEnterTile(aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) { |
541 return; |
539 return; |
602 * When we are looking for one specific target (optionally multiple tiles), we |
600 * When we are looking for one specific target (optionally multiple tiles), we |
603 * should use a good heuristic to perform aystar search. When we search for |
601 * should use a good heuristic to perform aystar search. When we search for |
604 * multiple targets that are spread around, we should perform a breadth first |
602 * multiple targets that are spread around, we should perform a breadth first |
605 * search by specifiying CalcZero as our heuristic. |
603 * search by specifiying CalcZero as our heuristic. |
606 */ |
604 */ |
607 static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, uint reverse_penalty) |
605 static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailType railtype, uint reverse_penalty) |
608 { |
606 { |
609 int r; |
607 int r; |
610 NPFFoundTargetData result; |
608 NPFFoundTargetData result; |
611 |
609 |
612 /* Initialize procs */ |
610 /* Initialize procs */ |
644 _npf_aystar.user_target = target; |
642 _npf_aystar.user_target = target; |
645 |
643 |
646 /* Initialize user_data */ |
644 /* Initialize user_data */ |
647 _npf_aystar.user_data[NPF_TYPE] = type; |
645 _npf_aystar.user_data[NPF_TYPE] = type; |
648 _npf_aystar.user_data[NPF_OWNER] = owner; |
646 _npf_aystar.user_data[NPF_OWNER] = owner; |
|
647 _npf_aystar.user_data[NPF_RAILTYPE] = railtype; |
649 |
648 |
650 /* GO! */ |
649 /* GO! */ |
651 r = AyStarMain_Main(&_npf_aystar); |
650 r = AyStarMain_Main(&_npf_aystar); |
652 assert(r != AYSTAR_STILL_BUSY); |
651 assert(r != AYSTAR_STILL_BUSY); |
653 |
652 |
675 start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
674 start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
676 start1.direction = trackdir1; |
675 start1.direction = trackdir1; |
677 start2.direction = trackdir2; |
676 start2.direction = trackdir2; |
678 start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
677 start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
679 |
678 |
680 return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, 0); |
679 return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtype, 0); |
681 } |
680 } |
682 |
681 |
683 NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner) |
682 NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype) |
684 { |
683 { |
685 return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner); |
684 return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtype); |
686 } |
685 } |
687 |
686 |
688 NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, uint reverse_penalty) |
687 NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty) |
689 { |
688 { |
690 AyStarNode start1; |
689 AyStarNode start1; |
691 AyStarNode start2; |
690 AyStarNode start2; |
692 |
691 |
693 start1.tile = tile1; |
692 start1.tile = tile1; |
699 start2.direction = trackdir2; |
698 start2.direction = trackdir2; |
700 start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
699 start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; |
701 |
700 |
702 /* perform a breadth first search. Target is NULL, |
701 /* perform a breadth first search. Target is NULL, |
703 * since we are just looking for any depot...*/ |
702 * since we are just looking for any depot...*/ |
704 return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, reverse_penalty); |
703 return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtype, reverse_penalty); |
705 } |
704 } |
706 |
705 |
707 NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner) |
706 NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype) |
708 { |
707 { |
709 return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, 0); |
708 return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtype, 0); |
710 } |
709 } |
711 |
710 |
712 NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner) |
711 NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype) |
713 { |
712 { |
714 /* Okay, what we're gonna do. First, we look at all depots, calculate |
713 /* Okay, what we're gonna do. First, we look at all depots, calculate |
715 * the manhatten distance to get to each depot. We then sort them by |
714 * the manhatten distance to get to each depot. We then sort them by |
716 * distance. We start by trying to plan a route to the closest, then |
715 * distance. We start by trying to plan a route to the closest, then |
717 * the next closest, etc. We stop when the best route we have found so |
716 * the next closest, etc. We stop when the best route we have found so |