142 int y; |
141 int y; |
143 |
142 |
144 const RoadVehicleInfo *rvi = RoadVehInfo(p1); |
143 const RoadVehicleInfo *rvi = RoadVehInfo(p1); |
145 |
144 |
146 v->unitnumber = unit_num; |
145 v->unitnumber = unit_num; |
147 v->direction = 0; |
146 v->direction = INVALID_DIR; |
148 v->owner = _current_player; |
147 v->owner = _current_player; |
149 |
148 |
150 v->tile = tile; |
149 v->tile = tile; |
151 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; |
150 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; |
152 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; |
151 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; |
294 } |
293 } |
295 |
294 |
296 typedef struct RoadFindDepotData { |
295 typedef struct RoadFindDepotData { |
297 uint best_length; |
296 uint best_length; |
298 TileIndex tile; |
297 TileIndex tile; |
299 byte owner; |
298 OwnerByte owner; |
300 } RoadFindDepotData; |
299 } RoadFindDepotData; |
301 |
300 |
302 static const DiagDirection _road_pf_directions[] = { |
301 static const DiagDirection _road_pf_directions[] = { |
303 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 255, 255, |
302 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR, |
304 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, 255, 255 |
303 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR |
305 }; |
304 }; |
306 |
305 |
307 static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, int track, uint length, byte* state) |
306 static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
308 { |
307 { |
309 RoadFindDepotData* rfdd = data; |
308 RoadFindDepotData* rfdd = (RoadFindDepotData*)data; |
310 |
309 |
311 tile += TileOffsByDiagDir(_road_pf_directions[track]); |
310 tile += TileOffsByDiagDir(_road_pf_directions[trackdir]); |
312 |
311 |
313 if (IsTileType(tile, MP_STREET) && |
312 if (IsTileType(tile, MP_STREET) && |
314 GetRoadTileType(tile) == ROAD_TILE_DEPOT && |
313 GetRoadTileType(tile) == ROAD_TILE_DEPOT && |
315 IsTileOwner(tile, rfdd->owner) && |
314 IsTileOwner(tile, rfdd->owner) && |
316 length < rfdd->best_length) { |
315 length < rfdd->best_length) { |
339 return NULL; /* Target not found */ |
338 return NULL; /* Target not found */ |
340 } |
339 } |
341 /* We do not search in two directions here, why should we? We can't reverse right now can we? */ |
340 /* We do not search in two directions here, why should we? We can't reverse right now can we? */ |
342 } else { |
341 } else { |
343 RoadFindDepotData rfdd; |
342 RoadFindDepotData rfdd; |
344 DiagDirection i; |
|
345 |
343 |
346 rfdd.owner = v->owner; |
344 rfdd.owner = v->owner; |
347 rfdd.best_length = (uint)-1; |
345 rfdd.best_length = (uint)-1; |
348 |
346 |
349 /* search in all directions */ |
347 /* search in all directions */ |
350 for (i = 0; i != 4; i++) { |
348 for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) { |
351 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd); |
349 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd); |
352 } |
350 } |
353 |
351 |
354 if (rfdd.best_length == (uint)-1) return NULL; |
352 if (rfdd.best_length == (uint)-1) return NULL; |
355 |
353 |
562 } |
560 } |
563 } |
561 } |
564 |
562 |
565 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data) |
563 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data) |
566 { |
564 { |
567 const Vehicle* u = data; |
565 const Vehicle* u = (Vehicle*)data; |
568 |
566 |
569 return |
567 return |
570 v->type == VEH_Train && |
568 v->type == VEH_Train && |
571 myabs(v->z_pos - u->z_pos) <= 6 && |
569 myabs(v->z_pos - u->z_pos) <= 6 && |
572 myabs(v->x_pos - u->x_pos) <= 4 && |
570 myabs(v->x_pos - u->x_pos) <= 4 && |
787 static void* EnumCheckRoadVehClose(Vehicle *v, void* data) |
785 static void* EnumCheckRoadVehClose(Vehicle *v, void* data) |
788 { |
786 { |
789 static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 }; |
787 static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 }; |
790 static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 }; |
788 static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 }; |
791 |
789 |
792 const RoadVehFindData* rvf = data; |
790 const RoadVehFindData* rvf = (RoadVehFindData*)data; |
793 |
791 |
794 short x_diff = v->x_pos - rvf->x; |
792 short x_diff = v->x_pos - rvf->x; |
795 short y_diff = v->y_pos - rvf->y; |
793 short y_diff = v->y_pos - rvf->y; |
796 |
794 |
797 return |
795 return |
816 |
814 |
817 rvf.x = x; |
815 rvf.x = x; |
818 rvf.y = y; |
816 rvf.y = y; |
819 rvf.dir = dir; |
817 rvf.dir = dir; |
820 rvf.veh = v; |
818 rvf.veh = v; |
821 u = VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose); |
819 u = (Vehicle*)VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose); |
822 |
820 |
823 // This code protects a roadvehicle from being blocked for ever |
821 // This code protects a roadvehicle from being blocked for ever |
824 // If more than 1480 / 74 days a road vehicle is blocked, it will |
822 // If more than 1480 / 74 days a road vehicle is blocked, it will |
825 // drive just through it. The ultimate backup-code of TTD. |
823 // drive just through it. The ultimate backup-code of TTD. |
826 // It can be disabled. |
824 // It can be disabled. |
898 } |
896 } |
899 |
897 |
900 static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y) |
898 static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y) |
901 { |
899 { |
902 static const Direction _roadveh_new_dir[] = { |
900 static const Direction _roadveh_new_dir[] = { |
903 DIR_N , DIR_NW, DIR_W , 0, |
901 DIR_N , DIR_NW, DIR_W , INVALID_DIR, |
904 DIR_NE, DIR_N , DIR_SW, 0, |
902 DIR_NE, DIR_N , DIR_SW, INVALID_DIR, |
905 DIR_E , DIR_SE, DIR_S |
903 DIR_E , DIR_SE, DIR_S |
906 }; |
904 }; |
907 |
905 |
908 x = x - v->x_pos + 1; |
906 x = x - v->x_pos + 1; |
909 y = y - v->y_pos + 1; |
907 y = y - v->y_pos + 1; |
912 return _roadveh_new_dir[y * 4 + x]; |
910 return _roadveh_new_dir[y * 4 + x]; |
913 } |
911 } |
914 |
912 |
915 static Direction RoadVehGetSlidingDirection(const Vehicle* v, int x, int y) |
913 static Direction RoadVehGetSlidingDirection(const Vehicle* v, int x, int y) |
916 { |
914 { |
917 Direction new = RoadVehGetNewDirection(v, x, y); |
915 Direction new_dir = RoadVehGetNewDirection(v, x, y); |
918 Direction old = v->direction; |
916 Direction old_dir = v->direction; |
919 DirDiff delta; |
917 DirDiff delta; |
920 |
918 |
921 if (new == old) return old; |
919 if (new_dir == old_dir) return old_dir; |
922 delta = (DirDifference(new, old) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT); |
920 delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT); |
923 return ChangeDir(old, delta); |
921 return ChangeDir(old_dir, delta); |
924 } |
922 } |
925 |
923 |
926 typedef struct OvertakeData { |
924 typedef struct OvertakeData { |
927 const Vehicle* u; |
925 const Vehicle* u; |
928 const Vehicle* v; |
926 const Vehicle* v; |
1023 TileIndex dest; |
1021 TileIndex dest; |
1024 uint maxtracklen; |
1022 uint maxtracklen; |
1025 uint mindist; |
1023 uint mindist; |
1026 } FindRoadToChooseData; |
1024 } FindRoadToChooseData; |
1027 |
1025 |
1028 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, int track, uint length, byte* state) |
1026 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1029 { |
1027 { |
1030 FindRoadToChooseData* frd = data; |
1028 FindRoadToChooseData* frd = (FindRoadToChooseData*)data; |
1031 uint dist = DistanceManhattan(tile, frd->dest); |
1029 uint dist = DistanceManhattan(tile, frd->dest); |
1032 |
1030 |
1033 if (dist <= frd->mindist) { |
1031 if (dist <= frd->mindist) { |
1034 if (dist != frd->mindist || length < frd->maxtracklen) { |
1032 if (dist != frd->mindist || length < frd->maxtracklen) { |
1035 frd->maxtracklen = length; |
1033 frd->maxtracklen = length; |
1131 if (trackdir != INVALID_TRACKDIR) return_track(trackdir); |
1129 if (trackdir != INVALID_TRACKDIR) return_track(trackdir); |
1132 return_track(PickRandomBit(bitmask)); |
1130 return_track(PickRandomBit(bitmask)); |
1133 } else if (_patches.new_pathfinding_all) { |
1131 } else if (_patches.new_pathfinding_all) { |
1134 NPFFindStationOrTileData fstd; |
1132 NPFFindStationOrTileData fstd; |
1135 NPFFoundTargetData ftd; |
1133 NPFFoundTargetData ftd; |
1136 byte trackdir; |
1134 Trackdir trackdir; |
1137 |
1135 |
1138 NPFFillWithOrderData(&fstd, v); |
1136 NPFFillWithOrderData(&fstd, v); |
1139 trackdir = DiagdirToDiagTrackdir(enterdir); |
1137 trackdir = DiagdirToDiagTrackdir(enterdir); |
1140 //debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir); |
1138 //debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir); |
1141 |
1139 |
1213 // use YAPF |
1211 // use YAPF |
1214 dist = YapfRoadVehDistanceToTile(v, tile); |
1212 dist = YapfRoadVehDistanceToTile(v, tile); |
1215 } else { |
1213 } else { |
1216 // use NPF |
1214 // use NPF |
1217 NPFFindStationOrTileData fstd; |
1215 NPFFindStationOrTileData fstd; |
1218 byte trackdir = GetVehicleTrackdir(v); |
1216 Trackdir trackdir = GetVehicleTrackdir(v); |
1219 assert(trackdir != 0xFF); |
1217 assert(trackdir != 0xFF); |
1220 |
1218 |
1221 fstd.dest_coords = tile; |
1219 fstd.dest_coords = tile; |
1222 fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station |
1220 fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station |
1223 |
1221 |
1361 rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1359 rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1362 |
1360 |
1363 // switch to another tile |
1361 // switch to another tile |
1364 if (rd.x & 0x80) { |
1362 if (rd.x & 0x80) { |
1365 TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3); |
1363 TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3); |
1366 int dir = RoadFindPathToDest(v, tile, rd.x & 3); |
1364 int dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3)); |
1367 uint32 r; |
1365 uint32 r; |
1368 Direction newdir; |
1366 Direction newdir; |
1369 const RoadDriveEntry *rdp; |
1367 const RoadDriveEntry *rdp; |
1370 |
1368 |
1371 if (dir == -1) { |
1369 if (dir == -1) { |
1426 RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); |
1424 RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); |
1427 return; |
1425 return; |
1428 } |
1426 } |
1429 |
1427 |
1430 if (rd.x & 0x40) { |
1428 if (rd.x & 0x40) { |
1431 int dir = RoadFindPathToDest(v, v->tile, rd.x & 3); |
1429 int dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3)); |
1432 uint32 r; |
1430 uint32 r; |
1433 int tmp; |
1431 int tmp; |
1434 Direction newdir; |
1432 Direction newdir; |
1435 const RoadDriveEntry *rdp; |
1433 const RoadDriveEntry *rdp; |
1436 |
1434 |