12 #include "../../stdafx.h"
13 #include "../../network/network.h"
14 #include "../../viewport_func.h"
15 #include "../../ship.h"
16 #include "../../roadstop_base.h"
17 #include "../pathfinder_func.h"
18 #include "../pathfinder_type.h"
19 #include "../follow_track.hpp"
22 #include "../../safeguards.h"
28 static const uint NPF_HASH_HALFMASK = (1 << NPF_HASH_HALFBITS) - 1;
81 #define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * STRAIGHT_TRACK_LENGTH)
93 return HasBit(node->user_data[NPF_NODE_FLAGS], flag);
101 SB(node->user_data[NPF_NODE_FLAGS], flag, 1, value);
115 const uint straightTracks = 2 *
min(dx, dy);
120 const uint diagTracks = dx + dy - straightTracks;
137 uint part1 =
TileX(key1) & NPF_HASH_HALFMASK;
138 uint part2 =
TileY(key1) & NPF_HASH_HALFMASK;
142 return ((part1 << NPF_HASH_HALFBITS | part2) + (NPF_HASH_SIZE * key2 /
TRACKDIR_END)) % NPF_HASH_SIZE;
175 DEBUG(npf, 4,
"Calculating H for: (%d, %d). Result: %d",
TileX(current->tile),
TileY(current->tile), dist);
177 if (dist < ftd->best_bird_dist) {
178 ftd->best_bird_dist = dist;
190 if (parent->path.
parent == NULL) {
191 Trackdir trackdir = current->direction;
195 DEBUG(npf, 6,
"Saving trackdir: 0x%X", trackdir);
205 static uint NPFTunnelCost(
AyStarNode *current)
221 static inline uint NPFBridgeCost(
AyStarNode *current)
236 int dx4 = (x2 - x1) / 4;
237 int dy4 = (y2 - y1) / 4;
242 int z1 = GetSlopePixelZ(x1 + dx4, y1 + dy4);
243 int z2 = GetSlopePixelZ(x2 - dx4, y2 - dy4);
255 static uint NPFReservedTrackCost(
AyStarNode *current)
278 #ifndef NO_DEBUG_MESSAGES
306 Trackdir trackdir = current->direction;
308 cost = _trackdir_length[trackdir];
332 cost =
IsTunnel(tile) ? NPFTunnelCost(current) : NPFBridgeCost(current);
368 cost += NPFSlopeCost(current);
377 DEBUG(npf, 4,
"Calculating G for: (%d, %d). Result: %d",
TileX(current->tile),
TileY(current->tile), cost);
386 Trackdir trackdir = current->direction;
394 cost =
IsTunnel(tile) ? NPFTunnelCost(current) : NPFBridgeCost(current);
398 cost = _trackdir_length[trackdir];
424 while (ft.Follow(t, td)) {
425 assert(t != ft.m_new_tile);
465 if (!IsPbsSignal(sigtype)) {
502 new_node.path.node = *current;
508 cost += NPFSlopeCost(current);
526 cost += NPFReservedTrackCost(current);
529 DEBUG(npf, 4,
"Calculating G for: (%d, %d). Result: %d",
TileX(current->tile),
TileY(current->tile), cost);
598 bool first_run =
true;
599 for (; start != end; start = start->
parent) {
620 ftd->best_path_dist = current->g;
621 ftd->best_bird_dist = 0;
622 ftd->node = current->path.node;
623 ftd->res_okay =
false;
630 ftd->node = target->node;
639 ftd->node.tile = end_tile;
655 ftd->res_okay =
true;
787 if (!
HasBit(user->railtypes, rail_type))
return false;
830 DEBUG(npf, 4,
"Next node: (%d, %d) [%d], possible trackdirs: 0x%X",
TileX(dst_tile),
TileY(dst_tile), dst_tile, trackdirbits);
838 DEBUG(npf, 6,
"After filtering: (%d, %d), possible trackdirs: 0x%X",
TileX(dst_tile),
TileY(dst_tile), trackdirbits);
854 Trackdir src_trackdir = current->path.node.direction;
855 TileIndex src_tile = current->path.node.tile;
865 uint subtype = user->roadtypes;
868 aystar->num_neighbours = 0;
869 DEBUG(npf, 4,
"Expanding: (%d, %d, %d) [%d]",
TileX(src_tile),
TileY(src_tile), src_trackdir, src_tile);
876 if (ignore_src_tile) {
884 }
else if (
ForceReverse(src_tile, src_exitdir, type, subtype)) {
905 if (trackdirbits == 0) {
929 while (trackdirbits != 0) {
931 DEBUG(npf, 5,
"Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits);
942 AyStarNode *neighbour = &aystar->neighbours[i];
943 neighbour->tile = dst_tile;
944 neighbour->direction = dst_trackdir;
946 neighbour->user_data[NPF_NODE_FLAGS] = current->path.node.user_data[NPF_NODE_FLAGS];
947 NPFFillTrackdirChoice(neighbour, current);
951 aystar->num_neighbours = i;
970 _npf_aystar.CalculateH = heuristic_proc;
971 _npf_aystar.EndNodeCheck = target_proc;
973 _npf_aystar.GetNeighbours = NPFFollowTrack;
974 switch (user->type) {
975 default: NOT_REACHED();
976 case TRANSPORT_RAIL: _npf_aystar.CalculateG = NPFRailPathCost;
break;
977 case TRANSPORT_ROAD: _npf_aystar.CalculateG = NPFRoadPathCost;
break;
978 case TRANSPORT_WATER: _npf_aystar.CalculateG = NPFWaterPathCost;
break;
983 start1->user_data[NPF_NODE_FLAGS] = 0;
986 if (start2 != NULL) {
988 start2->user_data[NPF_NODE_FLAGS] = 0;
1000 _npf_aystar.user_path = &result;
1003 _npf_aystar.user_target = target;
1006 _npf_aystar.user_data = user;
1009 r = _npf_aystar.
Main();
1013 if (target != NULL) {
1014 DEBUG(npf, 1,
"Could not find route to tile 0x%X from 0x%X.", target->
dest_coords, start1->tile);
1017 DEBUG(npf, 1,
"Could not find route to a depot from tile 0x%X.", start1->tile);
1032 start1.tile = tile1;
1033 start2.tile = tile2;
1037 start1.direction = trackdir1;
1038 start2.direction = trackdir2;
1041 return NPFRouteInternal(&start1, ignore_start_tile1, (
IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, user, 0);
1064 start1.tile = tile1;
1065 start2.tile = tile2;
1069 start1.direction = trackdir1;
1070 start2.direction = trackdir2;
1075 return NPFRouteInternal(&start1, ignore_start_tile1, (
IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty);
1078 void InitializeNPF()
1080 static bool first_init =
true;
1085 _npf_aystar.
Clear();
1141 NPFFillWithOrderData(&fstd, v);
1170 NPFFillWithOrderData(&fstd, v);
1189 NPFFillWithOrderData(&fstd, v);
1197 ftd = NPFRouteToStationOrTileTwoWay(v->
tile, trackdir,
false, v->
tile, trackdir_rev,
false, &fstd, &user);
1211 fstd.reserve_path =
false;
1239 start1.user_data[NPF_NODE_FLAGS] = 0;
1240 start1.direction = trackdir;
1243 RailTypes railtypes = v->compatible_railtypes;
1258 NPFFillWithOrderData(&fstd, v);
1266 ftd = NPFRouteToStationOrTileTwoWay(v->
tile, trackdir,
false, last->
tile, trackdir_rev,
false, &fstd, &user);
1274 NPFFillWithOrderData(&fstd, v, reserve_track);
1282 if (target != NULL) {