27 #include "newgrf_text.h" |
27 #include "newgrf_text.h" |
28 #include "newgrf_sound.h" |
28 #include "newgrf_sound.h" |
29 #include "date.h" |
29 #include "date.h" |
30 |
30 |
31 static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D}; |
31 static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D}; |
32 static const byte _ship_sometracks[4] = {0x19, 0x16, 0x25, 0x2A}; |
32 |
33 |
33 static const TrackBits _ship_sometracks[4] = { |
34 static byte GetTileShipTrackStatus(TileIndex tile) |
34 TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_LEFT, // 0x19, // DIAGDIR_NE |
|
35 TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_LEFT, // 0x16, // DIAGDIR_SE |
|
36 TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT, // 0x25, // DIAGDIR_SW |
|
37 TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT, // 0x2A, // DIAGDIR_NW |
|
38 }; |
|
39 |
|
40 static TrackBits GetTileShipTrackStatus(TileIndex tile) |
35 { |
41 { |
36 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); |
42 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); |
37 return r | r >> 8; |
43 return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8))); |
38 } |
44 } |
39 |
45 |
40 void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod) |
46 void DrawShipEngine(int x, int y, EngineID engine, uint32 image_ormod) |
41 { |
47 { |
42 int spritenum = ShipVehInfo(engine)->image_index; |
48 int spritenum = ShipVehInfo(engine)->image_index; |
445 { 9, 9, 1, 0 }, |
451 { 9, 9, 1, 0 }, |
446 }; |
452 }; |
447 |
453 |
448 static const byte _pick_shiptrack_table[6] = {1, 3, 2, 2, 0, 0}; |
454 static const byte _pick_shiptrack_table[6] = {1, 3, 2, 2, 0, 0}; |
449 |
455 |
450 static uint FindShipTrack(Vehicle *v, TileIndex tile, int dir, uint bits, TileIndex skiptile, int *track) |
456 static uint FindShipTrack(Vehicle *v, TileIndex tile, DiagDirection dir, TrackBits bits, TileIndex skiptile, Track *track) |
451 { |
457 { |
452 PathFindShip pfs; |
458 PathFindShip pfs; |
453 int i, best_track; |
459 Track i, best_track; |
454 uint best_bird_dist = 0; |
460 uint best_bird_dist = 0; |
455 uint best_length = 0; |
461 uint best_length = 0; |
456 uint r; |
462 uint r; |
457 byte ship_dir = v->direction & 3; |
463 byte ship_dir = v->direction & 3; |
458 |
464 |
459 pfs.dest_coords = v->dest_tile; |
465 pfs.dest_coords = v->dest_tile; |
460 pfs.skiptile = skiptile; |
466 pfs.skiptile = skiptile; |
461 |
467 |
462 best_track = -1; |
468 best_track = INVALID_TRACK; |
463 |
469 |
464 do { |
470 do { |
465 i = FIND_FIRST_BIT(bits); |
471 i = RemoveFirstTrack(bits); |
466 bits = KILL_FIRST_BIT(bits); |
|
467 |
472 |
468 pfs.best_bird_dist = (uint)-1; |
473 pfs.best_bird_dist = (uint)-1; |
469 pfs.best_length = (uint)-1; |
474 pfs.best_length = (uint)-1; |
470 |
475 |
471 FollowTrack(tile, 0x3800 | TRANSPORT_WATER, _ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); |
476 FollowTrack(tile, 0x3800 | TRANSPORT_WATER, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); |
472 |
477 |
473 if (best_track >= 0) { |
478 if (best_track != INVALID_TRACK) { |
474 if (pfs.best_bird_dist != 0) { |
479 if (pfs.best_bird_dist != 0) { |
475 /* neither reached the destination, pick the one with the smallest bird dist */ |
480 /* neither reached the destination, pick the one with the smallest bird dist */ |
476 if (pfs.best_bird_dist > best_bird_dist) goto bad; |
481 if (pfs.best_bird_dist > best_bird_dist) goto bad; |
477 if (pfs.best_bird_dist < best_bird_dist) goto good; |
482 if (pfs.best_bird_dist < best_bird_dist) goto good; |
478 } else { |
483 } else { |
510 } |
515 } |
511 |
516 |
512 /* returns the track to choose on the next tile, or -1 when it's better to |
517 /* returns the track to choose on the next tile, or -1 when it's better to |
513 * reverse. The tile given is the tile we are about to enter, enterdir is the |
518 * reverse. The tile given is the tile we are about to enter, enterdir is the |
514 * direction in which we are entering the tile */ |
519 * direction in which we are entering the tile */ |
515 static int ChooseShipTrack(Vehicle *v, TileIndex tile, int enterdir, uint tracks) |
520 static Track ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks) |
516 { |
521 { |
517 assert(enterdir>=0 && enterdir<=3); |
522 assert(enterdir>=0 && enterdir<=3); |
518 |
523 |
519 if (_patches.yapf.ship_use_yapf) { |
524 if (_patches.yapf.ship_use_yapf) { |
520 Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks); |
525 Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks); |
521 return (trackdir != INVALID_TRACKDIR) ? (int)TrackdirToTrack(trackdir) : -1; |
526 return (trackdir != INVALID_TRACKDIR) ? TrackdirToTrack(trackdir) : INVALID_TRACK; |
522 } else if (_patches.new_pathfinding_all) { |
527 } else if (_patches.new_pathfinding_all) { |
523 NPFFindStationOrTileData fstd; |
528 NPFFindStationOrTileData fstd; |
524 NPFFoundTargetData ftd; |
529 NPFFoundTargetData ftd; |
525 TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir))); |
530 TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir))); |
526 byte trackdir = GetVehicleTrackdir(v); |
531 Trackdir trackdir = GetVehicleTrackdir(v); |
527 assert (trackdir != 0xFF); /* Check that we are not in a depot */ |
532 assert(trackdir != INVALID_TRACKDIR); /* Check that we are not in a depot */ |
528 |
533 |
529 NPFFillWithOrderData(&fstd, v); |
534 NPFFillWithOrderData(&fstd, v); |
530 |
535 |
531 ftd = PerfNPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); |
536 ftd = PerfNPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); |
532 |
537 |
533 if (ftd.best_trackdir != 0xff) { |
538 if (ftd.best_trackdir != 0xff) { |
534 /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains |
539 /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains |
535 the direction we need to take to get there, if ftd.best_bird_dist is not 0, |
540 the direction we need to take to get there, if ftd.best_bird_dist is not 0, |
536 we did not find our target, but ftd.best_trackdir contains the direction leading |
541 we did not find our target, but ftd.best_trackdir contains the direction leading |
537 to the tile closest to our target. */ |
542 to the tile closest to our target. */ |
538 return ftd.best_trackdir & 7; /* TODO: Wrapper function? */ |
543 return TrackdirToTrack(ftd.best_trackdir); /* TODO: Wrapper function? */ |
539 } else { |
544 } else { |
540 return -1; /* Already at target, reverse? */ |
545 return INVALID_TRACK; /* Already at target, reverse? */ |
541 } |
546 } |
542 } else { |
547 } else { |
543 uint b; |
|
544 uint tot_dist, dist; |
548 uint tot_dist, dist; |
545 int track; |
549 Track track; |
546 TileIndex tile2; |
550 TileIndex tile2; |
547 |
551 |
548 tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir)); |
552 tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir)); |
549 tot_dist = (uint)-1; |
553 tot_dist = (uint)-1; |
550 |
554 |
551 /* Let's find out how far it would be if we would reverse first */ |
555 /* Let's find out how far it would be if we would reverse first */ |
552 b = GetTileShipTrackStatus(tile2) & _ship_sometracks[ReverseDiagDir(enterdir)] & v->u.ship.state; |
556 TrackBits b = GetTileShipTrackStatus(tile2) & _ship_sometracks[ReverseDiagDir(enterdir)] & v->u.ship.state; |
553 if (b != 0) { |
557 if (b != 0) { |
554 dist = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track); |
558 dist = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track); |
555 if (dist != (uint)-1) |
559 if (dist != (uint)-1) |
556 tot_dist = dist + 1; |
560 tot_dist = dist + 1; |
557 } |
561 } |
558 /* And if we would not reverse? */ |
562 /* And if we would not reverse? */ |
559 dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track); |
563 dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track); |
560 if (dist > tot_dist) |
564 if (dist > tot_dist) |
561 /* We could better reverse */ |
565 /* We could better reverse */ |
562 return -1; |
566 return INVALID_TRACK; |
563 return track; |
567 return track; |
564 } |
568 } |
565 } |
569 } |
566 |
570 |
567 static const Direction _new_vehicle_direction_table[] = { |
571 static const Direction _new_vehicle_direction_table[] = { |
568 DIR_N , DIR_NW, DIR_W , 0, |
572 DIR_N , DIR_NW, DIR_W , INVALID_DIR, |
569 DIR_NE, DIR_N , DIR_SW, 0, |
573 DIR_NE, DIR_N , DIR_SW, INVALID_DIR, |
570 DIR_E , DIR_SE, DIR_S |
574 DIR_E , DIR_SE, DIR_S |
571 }; |
575 }; |
572 |
576 |
573 static int ShipGetNewDirectionFromTiles(TileIndex new_tile, TileIndex old_tile) |
577 static Direction ShipGetNewDirectionFromTiles(TileIndex new_tile, TileIndex old_tile) |
574 { |
578 { |
575 uint offs = (TileY(new_tile) - TileY(old_tile) + 1) * 4 + |
579 uint offs = (TileY(new_tile) - TileY(old_tile) + 1) * 4 + |
576 TileX(new_tile) - TileX(old_tile) + 1; |
580 TileX(new_tile) - TileX(old_tile) + 1; |
577 assert(offs < 11 && offs != 3 && offs != 7); |
581 assert(offs < 11 && offs != 3 && offs != 7); |
578 return _new_vehicle_direction_table[offs]; |
582 return _new_vehicle_direction_table[offs]; |
579 } |
583 } |
580 |
584 |
581 static int ShipGetNewDirection(Vehicle *v, int x, int y) |
585 static Direction ShipGetNewDirection(Vehicle *v, int x, int y) |
582 { |
586 { |
583 uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1); |
587 uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1); |
584 assert(offs < 11 && offs != 3 && offs != 7); |
588 assert(offs < 11 && offs != 3 && offs != 7); |
585 return _new_vehicle_direction_table[offs]; |
589 return _new_vehicle_direction_table[offs]; |
586 } |
590 } |
587 |
591 |
588 static int GetAvailShipTracks(TileIndex tile, int dir) |
592 static TrackBits GetAvailShipTracks(TileIndex tile, int dir) |
589 { |
593 { |
590 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); |
594 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); |
591 return (byte) ((r | r >> 8)) & _ship_sometracks[dir]; |
595 return (TrackBits)((r | r >> 8) & _ship_sometracks[dir]); |
592 } |
596 } |
593 |
597 |
594 static const byte _ship_subcoord[4][6][3] = { |
598 static const byte _ship_subcoord[4][6][3] = { |
595 { |
599 { |
596 {15, 8, 1}, |
600 {15, 8, 1}, |