30 }; |
30 }; |
31 |
31 |
32 /* Maps a trackdir to the trackdirs that can be reached from it (ie, when |
32 /* Maps a trackdir to the trackdirs that can be reached from it (ie, when |
33 * entering the next tile */ |
33 * entering the next tile */ |
34 const uint16 _trackdir_reaches_trackdirs[14] = { |
34 const uint16 _trackdir_reaches_trackdirs[14] = { |
35 0x1009, 0x0016, 0x1009, 0x0016, 0x0520, 0x0016, 0, 0, |
35 0x1009, 0x0016, 0x1009, 0x0016, 0x0520, 0x0016, 0, 0, |
36 0x0520, 0x2A00, 0x2A00, 0x0520, 0x2A00, 0x1009 |
36 0x0520, 0x2A00, 0x2A00, 0x0520, 0x2A00, 0x1009 |
37 }; |
37 }; |
38 |
38 |
39 /* Maps a trackdir to all trackdirs that make 90 deg turns with it. */ |
39 /* Maps a trackdir to all trackdirs that make 90 deg turns with it. */ |
40 const uint16 _trackdir_crosses_trackdirs[14] = { |
40 const uint16 _trackdir_crosses_trackdirs[14] = { |
41 0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C, 0, 0, |
41 0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C, 0, 0, |
42 0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C |
42 0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C |
43 }; |
43 }; |
44 |
44 |
45 /* Maps a track to all tracks that make 90 deg turns with it. */ |
45 /* Maps a track to all tracks that make 90 deg turns with it. */ |
46 const byte _track_crosses_tracks[6] = { |
46 const byte _track_crosses_tracks[6] = { |
47 0x2, /* Track 1 -> Track 2 */ |
47 0x2, /* Track 1 -> Track 2 */ |
93 /* The cost of each trackdir. A diagonal piece is the full NPF_TILE_LENGTH, |
93 /* The cost of each trackdir. A diagonal piece is the full NPF_TILE_LENGTH, |
94 * the shorter piece is sqrt(2)/2*NPF_TILE_LENGTH =~ 0.7071 |
94 * the shorter piece is sqrt(2)/2*NPF_TILE_LENGTH =~ 0.7071 |
95 */ |
95 */ |
96 #define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * 0.7071) |
96 #define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * 0.7071) |
97 static const uint _trackdir_length[14] = { |
97 static const uint _trackdir_length[14] = { |
98 NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, 0, 0, |
98 NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, |
99 NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH |
99 0, 0, |
|
100 NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH |
100 }; |
101 }; |
101 |
102 |
102 uint NTPHash(uint key1, uint key2) |
103 uint NTPHash(uint key1, uint key2) |
103 { |
104 { |
104 return PATHFIND_HASH_TILE(key1); |
105 return PATHFIND_HASH_TILE(key1); |
459 int i = 0; |
460 int i = 0; |
460 uint trackdirs, ts; |
461 uint trackdirs, ts; |
461 TransportType type = aystar->user_data[NPF_TYPE]; |
462 TransportType type = aystar->user_data[NPF_TYPE]; |
462 /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ |
463 /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ |
463 aystar->num_neighbours = 0; |
464 aystar->num_neighbours = 0; |
464 #ifdef NPF_DEBUG |
465 #ifdef NPF_DEBUG |
465 debug("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile); |
466 debug("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile); |
466 #endif |
467 #endif |
467 |
468 |
468 /* Find dest tile */ |
469 /* Find dest tile */ |
469 if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_map5[src_tile] & 0xF0)==0 && (_map5[src_tile] & 3) == src_exitdir) { |
470 if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_map5[src_tile] & 0xF0)==0 && (_map5[src_tile] & 3) == src_exitdir) { |
470 /* This is a tunnel. We know this tunnel is our type, |
471 /* This is a tunnel. We know this tunnel is our type, |
471 * otherwise we wouldn't have got here. It is also facing us, |
472 * otherwise we wouldn't have got here. It is also facing us, |
527 } else { |
528 } else { |
528 ts = GetTileTrackStatus(dst_tile, type); |
529 ts = GetTileTrackStatus(dst_tile, type); |
529 } |
530 } |
530 trackdirs = ts & 0x3F3F; /* Filter out signal status and the unused bits */ |
531 trackdirs = ts & 0x3F3F; /* Filter out signal status and the unused bits */ |
531 |
532 |
532 #ifdef NPF_DEBUG |
533 #ifdef NPF_DEBUG |
533 debug("Next node: (%d, %d) [%d], possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirs); |
534 debug("Next node: (%d, %d) [%d], possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirs); |
534 #endif |
535 #endif |
535 /* Select only trackdirs we can reach from our current trackdir */ |
536 /* Select only trackdirs we can reach from our current trackdir */ |
536 trackdirs &= _trackdir_reaches_trackdirs[src_trackdir]; |
537 trackdirs &= _trackdir_reaches_trackdirs[src_trackdir]; |
537 if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */ |
538 if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */ |
538 trackdirs &= ~_trackdir_crosses_trackdirs[src_trackdir]; |
539 trackdirs &= ~_trackdir_crosses_trackdirs[src_trackdir]; |
539 #ifdef NPF_DEBUG |
540 #ifdef NPF_DEBUG |
540 debug("After filtering: (%d, %d), possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), trackdirs); |
541 debug("After filtering: (%d, %d), possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), trackdirs); |
541 #endif |
542 #endif |
542 |
543 |
543 /* Enumerate possible track */ |
544 /* Enumerate possible track */ |
544 while (trackdirs != 0) { |
545 while (trackdirs != 0) { |
545 byte dst_trackdir; |
546 byte dst_trackdir; |
546 dst_trackdir = FindFirstBit2x64(trackdirs); |
547 dst_trackdir = FindFirstBit2x64(trackdirs); |
547 trackdirs = KillFirstBit2x64(trackdirs); |
548 trackdirs = KillFirstBit2x64(trackdirs); |
548 #ifdef NPF_DEBUG |
549 #ifdef NPF_DEBUG |
549 debug("Expanded into trackdir: %d, remaining trackdirs: %#x", dst_trackdir, trackdirs); |
550 debug("Expanded into trackdir: %d, remaining trackdirs: %#x", dst_trackdir, trackdirs); |
550 #endif |
551 #endif |
551 |
552 |
552 /* Check for oneway signal against us */ |
553 /* Check for oneway signal against us */ |
553 if (IsTileType(dst_tile, MP_RAILWAY) && (_map5[dst_tile]&0xC0) == 0x40) { |
554 if (IsTileType(dst_tile, MP_RAILWAY) && (_map5[dst_tile]&0xC0) == 0x40) { |
554 // the tile has a signal |
555 // the tile has a signal |
555 byte signal_present = _map3_lo[dst_tile]; |
556 byte signal_present = _map3_lo[dst_tile]; |
779 return best_result; |
780 return best_result; |
780 } |
781 } |
781 |
782 |
782 void InitializeNPF(void) |
783 void InitializeNPF(void) |
783 { |
784 { |
784 init_AyStar(&_npf_aystar, NTPHash, 1024); |
785 init_AyStar(&_npf_aystar, NTPHash, 1024); |
785 _npf_aystar.loops_per_tick = 0; |
786 _npf_aystar.loops_per_tick = 0; |
786 _npf_aystar.max_path_cost = 0; |
787 _npf_aystar.max_path_cost = 0; |
787 _npf_aystar.max_search_nodes = 0; |
788 _npf_aystar.max_search_nodes = 0; |
788 /* |
789 #if 0 |
789 init_AyStar(&_train_find_station, NTPHash, 1024); |
790 init_AyStar(&_train_find_station, NTPHash, 1024); |
790 init_AyStar(&_train_find_depot, NTPHash, 1024); |
791 init_AyStar(&_train_find_depot, NTPHash, 1024); |
791 init_AyStar(&_road_find_station, NTPHash, 1024); |
792 init_AyStar(&_road_find_station, NTPHash, 1024); |
792 init_AyStar(&_road_find_depot, NTPHash, 1024); |
793 init_AyStar(&_road_find_depot, NTPHash, 1024); |
793 |
794 |
794 _train_find_station.loops_per_tick = 0; |
795 _train_find_station.loops_per_tick = 0; |
795 _train_find_depot.loops_per_tick = 0; |
796 _train_find_depot.loops_per_tick = 0; |
796 _road_find_station.loops_per_tick = 0; |
797 _road_find_station.loops_per_tick = 0; |
797 _road_find_depot.loops_per_tick = 0; |
798 _road_find_depot.loops_per_tick = 0; |
798 |
799 |
799 _train_find_station.max_path_cost = 0; |
800 _train_find_station.max_path_cost = 0; |
800 _train_find_depot.max_path_cost = 0; |
801 _train_find_depot.max_path_cost = 0; |
801 _road_find_station.max_path_cost = 0; |
802 _road_find_station.max_path_cost = 0; |
802 _road_find_depot.max_path_cost = 0; |
803 _road_find_depot.max_path_cost = 0; |
803 |
804 |
804 _train_find_station.max_search_nodes = 0; |
805 _train_find_station.max_search_nodes = 0; |
805 _train_find_depot.max_search_nodes = 0; |
806 _train_find_depot.max_search_nodes = 0; |
806 _road_find_station.max_search_nodes = 0; |
807 _road_find_station.max_search_nodes = 0; |
807 _road_find_depot.max_search_nodes = 0; |
808 _road_find_depot.max_search_nodes = 0; |
808 |
809 |
809 _train_find_station.CalculateG = NPFRailPathCost; |
810 _train_find_station.CalculateG = NPFRailPathCost; |
810 _train_find_depot.CalculateG = NPFRailPathCost; |
811 _train_find_depot.CalculateG = NPFRailPathCost; |
811 _road_find_station.CalculateG = NPFRoadPathCost; |
812 _road_find_station.CalculateG = NPFRoadPathCost; |
812 _road_find_depot.CalculateG = NPFRoadPathCost; |
813 _road_find_depot.CalculateG = NPFRoadPathCost; |
813 |
814 |
814 _train_find_station.CalculateH = NPFCalcStationHeuristic; |
815 _train_find_station.CalculateH = NPFCalcStationHeuristic; |
815 _train_find_depot.CalculateH = NPFCalcStationHeuristic; |
816 _train_find_depot.CalculateH = NPFCalcStationHeuristic; |
816 _road_find_station.CalculateH = NPFCalcStationHeuristic; |
817 _road_find_station.CalculateH = NPFCalcStationHeuristic; |
817 _road_find_depot.CalculateH = NPFCalcStationHeuristic; |
818 _road_find_depot.CalculateH = NPFCalcStationHeuristic; |
818 |
819 |
819 _train_find_station.EndNodeCheck = NPFFindStationOrTile; |
820 _train_find_station.EndNodeCheck = NPFFindStationOrTile; |
820 _train_find_depot.EndNodeCheck = NPFFindStationOrTile; |
821 _train_find_depot.EndNodeCheck = NPFFindStationOrTile; |
821 _road_find_station.EndNodeCheck = NPFFindStationOrTile; |
822 _road_find_station.EndNodeCheck = NPFFindStationOrTile; |
822 _road_find_depot.EndNodeCheck = NPFFindStationOrTile; |
823 _road_find_depot.EndNodeCheck = NPFFindStationOrTile; |
823 |
824 |
824 _train_find_station.FoundEndNode = NPFSaveTargetData; |
825 _train_find_station.FoundEndNode = NPFSaveTargetData; |
825 _train_find_depot.FoundEndNode = NPFSaveTargetData; |
826 _train_find_depot.FoundEndNode = NPFSaveTargetData; |
826 _road_find_station.FoundEndNode = NPFSaveTargetData; |
827 _road_find_station.FoundEndNode = NPFSaveTargetData; |
827 _road_find_depot.FoundEndNode = NPFSaveTargetData; |
828 _road_find_depot.FoundEndNode = NPFSaveTargetData; |
828 |
829 |
829 _train_find_station.GetNeighbours = NPFFollowTrack; |
830 _train_find_station.GetNeighbours = NPFFollowTrack; |
830 _train_find_depot.GetNeighbours = NPFFollowTrack; |
831 _train_find_depot.GetNeighbours = NPFFollowTrack; |
831 _road_find_station.GetNeighbours = NPFFollowTrack; |
832 _road_find_station.GetNeighbours = NPFFollowTrack; |
832 _road_find_depot.GetNeighbours = NPFFollowTrack; |
833 _road_find_depot.GetNeighbours = NPFFollowTrack; |
833 */ |
834 #endif |
834 } |
835 } |
835 |
836 |
836 void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v) { |
837 void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v) { |
837 /* Ships don't really reach their stations, but the tile in front. So don't |
838 /* Ships don't really reach their stations, but the tile in front. So don't |
838 * save the station id for ships. For roadvehs we don't store it either, |
839 * save the station id for ships. For roadvehs we don't store it either, |