508 case TRANSPORT_WATER: return GetShipDepotDirection(tile); |
507 case TRANSPORT_WATER: return GetShipDepotDirection(tile); |
509 default: return INVALID_DIAGDIR; /* Not reached */ |
508 default: return INVALID_DIAGDIR; /* Not reached */ |
510 } |
509 } |
511 } |
510 } |
512 |
511 |
|
512 /** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */ |
|
513 static DiagDirection GetSingleTramBit(TileIndex tile) |
|
514 { |
|
515 if (IsNormalRoadTile(tile)) { |
|
516 RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM); |
|
517 switch (rb) { |
|
518 case ROAD_NW: return DIAGDIR_NW; |
|
519 case ROAD_SW: return DIAGDIR_SW; |
|
520 case ROAD_SE: return DIAGDIR_SE; |
|
521 case ROAD_NE: return DIAGDIR_NE; |
|
522 default: break; |
|
523 } |
|
524 } |
|
525 return INVALID_DIAGDIR; |
|
526 } |
|
527 |
|
528 /** |
|
529 * Tests if a tile can be entered or left only from one side. |
|
530 * |
|
531 * Depots, non-drive-through roadstops, and tiles with single trambits are tested. |
|
532 * |
|
533 * @param tile The tile of interest. |
|
534 * @param type The transporttype of the vehicle. |
|
535 * @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle. |
|
536 * @return The single entry/exit-direction of the tile, or INVALID_DIAGDIR if there are more or less directions |
|
537 */ |
|
538 static DiagDirection GetTileSingleEntry(TileIndex tile, TransportType type, uint subtype) |
|
539 { |
|
540 if (type != TRANSPORT_WATER && IsTileDepotType(tile, type)) return GetDepotDirection(tile, type); |
|
541 |
|
542 if (type == TRANSPORT_ROAD) { |
|
543 if (IsStandardRoadStopTile(tile)) return GetRoadStopDir(tile); |
|
544 if (HasBit(subtype, ROADTYPE_TRAM)) return GetSingleTramBit(tile); |
|
545 } |
|
546 |
|
547 return INVALID_DIAGDIR; |
|
548 } |
|
549 |
|
550 /** |
|
551 * Tests if a vehicle must reverse on a tile. |
|
552 * |
|
553 * @param tile The tile of interest. |
|
554 * @param dir The direction in which the vehicle drives on a tile. |
|
555 * @param type The transporttype of the vehicle. |
|
556 * @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle. |
|
557 * @return true iff the vehicle must reverse on the tile. |
|
558 */ |
|
559 static inline bool ForceReverse(TileIndex tile, DiagDirection dir, TransportType type, uint subtype) |
|
560 { |
|
561 DiagDirection single_entry = GetTileSingleEntry(tile, type, subtype); |
|
562 return single_entry != INVALID_DIAGDIR && single_entry != dir; |
|
563 } |
|
564 |
|
565 /** |
|
566 * Tests if a vehicle can enter a tile. |
|
567 * |
|
568 * @param tile The tile of interest. |
|
569 * @param dir The direction in which the vehicle drives onto a tile. |
|
570 * @param type The transporttype of the vehicle. |
|
571 * @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle. |
|
572 * @param railtypes For TRANSPORT_RAIL the compatible RailTypes of the vehicle. |
|
573 * @param owner The owner of the vehicle. |
|
574 * @return true iff the vehicle can enter the tile. |
|
575 */ |
|
576 static bool CanEnterTile(TileIndex tile, DiagDirection dir, TransportType type, uint subtype, RailTypes railtypes, Owner owner) |
|
577 { |
|
578 /* Check tunnel entries and bridge ramps */ |
|
579 if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) != dir) return false; |
|
580 |
|
581 /* Test ownership */ |
|
582 if (!CanEnterTileOwnerCheck(owner, tile, dir)) return false; |
|
583 |
|
584 /* check correct rail type (mono, maglev, etc) */ |
|
585 if (type == TRANSPORT_RAIL) { |
|
586 RailType rail_type = GetTileRailType(tile); |
|
587 if (!HasBit(railtypes, rail_type)) return false; |
|
588 } |
|
589 |
|
590 /* Depots, standard roadstops and single tram bits can only be entered from one direction */ |
|
591 DiagDirection single_entry = GetTileSingleEntry(tile, type, subtype); |
|
592 if (single_entry != INVALID_DIAGDIR && single_entry != ReverseDiagDir(dir)) return false; |
|
593 |
|
594 return true; |
|
595 } |
|
596 |
|
597 /** |
|
598 * Returns the driveable Trackdirs on a tile. |
|
599 * |
|
600 * One-way-roads are taken into account. Signals are not tested. |
|
601 * |
|
602 * @param dst_tile The tile of interest. |
|
603 * @param src_trackdir The direction the vehicle is currently moving. |
|
604 * @param type The transporttype of the vehicle. |
|
605 * @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle. |
|
606 * @return The Trackdirs the vehicle can continue moving on. |
|
607 */ |
|
608 static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_trackdir, TransportType type, uint subtype) |
|
609 { |
|
610 TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, type, subtype)); |
|
611 |
|
612 if (trackdirbits == 0 && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) { |
|
613 /* GetTileTrackStatus() returns 0 for single tram bits. |
|
614 * As we cannot change it there (easily) without breaking something, change it here */ |
|
615 switch (GetSingleTramBit(dst_tile)) { |
|
616 case DIAGDIR_NE: |
|
617 case DIAGDIR_SW: |
|
618 trackdirbits = TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW; |
|
619 break; |
|
620 |
|
621 case DIAGDIR_NW: |
|
622 case DIAGDIR_SE: |
|
623 trackdirbits = TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_Y_SE; |
|
624 break; |
|
625 |
|
626 default: break; |
|
627 } |
|
628 } |
|
629 |
|
630 DEBUG(npf, 4, "Next node: (%d, %d) [%d], possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits); |
|
631 |
|
632 /* Select only trackdirs we can reach from our current trackdir */ |
|
633 trackdirbits &= TrackdirReachesTrackdirs(src_trackdir); |
|
634 |
|
635 /* Filter out trackdirs that would make 90 deg turns for trains */ |
|
636 if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir); |
|
637 |
|
638 DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits); |
|
639 |
|
640 return trackdirbits; |
|
641 } |
|
642 |
513 |
643 |
514 /* Will just follow the results of GetTileTrackStatus concerning where we can |
644 /* Will just follow the results of GetTileTrackStatus concerning where we can |
515 * go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and |
645 * go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and |
516 * an argument to GetTileTrackStatus. Will skip tunnels, meaning that the |
646 * an argument to GetTileTrackStatus. Will skip tunnels, meaning that the |
517 * entry and exit are neighbours. Will fill |
647 * entry and exit are neighbours. Will fill |
518 * AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and |
648 * AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and |
519 * copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */ |
649 * copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */ |
520 static void NPFFollowTrack(AyStar* aystar, OpenListNode* current) |
650 static void NPFFollowTrack(AyStar* aystar, OpenListNode* current) |
521 { |
651 { |
|
652 /* We leave src_tile on track src_trackdir in direction src_exitdir */ |
522 Trackdir src_trackdir = (Trackdir)current->path.node.direction; |
653 Trackdir src_trackdir = (Trackdir)current->path.node.direction; |
523 TileIndex src_tile = current->path.node.tile; |
654 TileIndex src_tile = current->path.node.tile; |
524 DiagDirection src_exitdir = TrackdirToExitdir(src_trackdir); |
655 DiagDirection src_exitdir = TrackdirToExitdir(src_trackdir); |
525 TileIndex dst_tile = INVALID_TILE; |
656 |
526 int i; |
657 /* Is src_tile valid, and can be used? |
527 uint32 ts; |
658 * When choosing track on a junction src_tile is the tile neighboured to the junction wrt. exitdir. |
528 TrackdirBits trackdirbits; |
659 * But we must not check the validity of this move, as src_tile is totally unrelated to the move, if a roadvehicle reversed on a junction. */ |
|
660 bool ignore_src_tile = (current->path.parent == NULL && NPFGetFlag(¤t->path.node, NPF_FLAG_IGNORE_START_TILE)); |
|
661 |
|
662 /* Information about the vehicle: TransportType (road/rail/water) and SubType (compatible rail/road types) */ |
529 TransportType type = (TransportType)aystar->user_data[NPF_TYPE]; |
663 TransportType type = (TransportType)aystar->user_data[NPF_TYPE]; |
530 uint subtype = aystar->user_data[NPF_SUB_TYPE]; |
664 uint subtype = aystar->user_data[NPF_SUB_TYPE]; |
531 bool override_dst_check = false; |
665 |
532 /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ |
666 /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ |
533 aystar->num_neighbours = 0; |
667 aystar->num_neighbours = 0; |
534 DEBUG(npf, 4, "Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile); |
668 DEBUG(npf, 4, "Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile); |
535 |
669 |
|
670 /* We want to determine the tile we arrive, and which choices we have there */ |
|
671 TileIndex dst_tile; |
|
672 TrackdirBits trackdirbits; |
|
673 |
536 /* Find dest tile */ |
674 /* Find dest tile */ |
537 if (IsTileType(src_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(src_tile) == src_exitdir) { |
675 if (ignore_src_tile) { |
538 /* This is a tunnel/bridge. We know this tunnel/bridge is our type, |
676 /* Do not perform any checks that involve src_tile */ |
539 * otherwise we wouldn't have got here. It is also facing us, |
677 dst_tile = src_tile + TileOffsByDiagDir(src_exitdir); |
540 * so we should skip it's body */ |
678 trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); |
|
679 } else if (IsTileType(src_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(src_tile) == src_exitdir) { |
|
680 /* We drive through the wormhole and arrive on the other side */ |
541 dst_tile = GetOtherTunnelBridgeEnd(src_tile); |
681 dst_tile = GetOtherTunnelBridgeEnd(src_tile); |
542 override_dst_check = true; |
682 trackdirbits = TrackdirToTrackdirBits(src_trackdir); |
543 } else if (type != TRANSPORT_WATER && (IsStandardRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) { |
683 } else if (ForceReverse(src_tile, src_exitdir, type, subtype)) { |
544 /* This is a road station (non drive-through) or a train or road depot. We can enter and exit |
684 /* We can only reverse on this tile */ |
545 * those from one side only. Trackdirs don't support that (yet), so we'll |
685 dst_tile = src_tile; |
546 * do this here. */ |
686 src_trackdir = ReverseTrackdir(src_trackdir); |
547 |
687 trackdirbits = TrackdirToTrackdirBits(src_trackdir); |
548 DiagDirection exitdir; |
688 } else { |
549 /* Find out the exit direction first */ |
689 /* We leave src_tile in src_exitdir and reach dst_tile */ |
550 if (IsRoadStopTile(src_tile)) { |
690 dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(src_exitdir)); |
551 exitdir = GetRoadStopDir(src_tile); |
691 |
552 } else { // Train or road depot |
692 if (dst_tile != INVALID_TILE && !CanEnterTile(dst_tile, src_exitdir, type, subtype, (RailTypes)aystar->user_data[NPF_RAILTYPES], (Owner)aystar->user_data[NPF_OWNER])) dst_tile = INVALID_TILE; |
553 exitdir = GetDepotDirection(src_tile, type); |
693 |
|
694 if (dst_tile == INVALID_TILE) { |
|
695 /* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */ |
|
696 if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return; |
|
697 |
|
698 dst_tile = src_tile; |
|
699 src_trackdir = ReverseTrackdir(src_trackdir); |
554 } |
700 } |
555 |
701 |
556 /* Let's see if were headed the right way into the depot */ |
702 trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); |
557 if (src_trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(exitdir))) { |
703 |
558 /* We are headed inwards. We cannot go through the back of the depot. |
704 if (trackdirbits == 0) { |
559 * For rail, we can now reverse. Reversing for road vehicles is never |
705 /* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */ |
560 * useful, since you cannot take paths you couldn't take before |
706 if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return; |
561 * reversing (as with rail). */ |
707 |
562 if (type == TRANSPORT_RAIL) { |
708 dst_tile = src_tile; |
563 /* We can only reverse here, so we'll not consider this direction, but |
709 src_trackdir = ReverseTrackdir(src_trackdir); |
564 * jump ahead to the reverse direction. It would be nicer to return |
710 |
565 * one neighbour here (the reverse trackdir of the one we are |
711 trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); |
566 * considering now) and then considering that one to return the tracks |
|
567 * outside of the depot. But, because the code layout is cleaner this |
|
568 * way, we will just pretend we are reversed already */ |
|
569 src_trackdir = ReverseTrackdir(src_trackdir); |
|
570 dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(exitdir)); |
|
571 } else { |
|
572 dst_tile = INVALID_TILE; /* Road vehicle heading inwards: dead end */ |
|
573 } |
|
574 } else { |
|
575 dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(exitdir)); |
|
576 } |
712 } |
577 } else { |
713 } |
578 /* This a normal tile, a bridge, a tunnel exit, etc. */ |
714 |
579 dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(TrackdirToExitdir(src_trackdir))); |
|
580 } |
|
581 if (dst_tile == INVALID_TILE) { |
|
582 /* We reached the border of the map */ |
|
583 /* TODO Nicer control flow for this */ |
|
584 return; |
|
585 } |
|
586 |
|
587 /* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note |
|
588 * that I can enter the tunnel from a tile below the tunnel entrance. This |
|
589 * solves the problem of vehicles wanting to drive off a tunnel entrance */ |
|
590 if (!override_dst_check && IsTileType(dst_tile, MP_TUNNELBRIDGE) && |
|
591 GetTunnelBridgeDirection(dst_tile) != src_exitdir) { |
|
592 return; |
|
593 } |
|
594 |
|
595 /* check correct rail type (mono, maglev, etc) */ |
|
596 if (type == TRANSPORT_RAIL) { |
|
597 RailType dst_type = GetTileRailType(dst_tile); |
|
598 if (!HasBit(aystar->user_data[NPF_RAILTYPES], dst_type)) |
|
599 return; |
|
600 } |
|
601 |
|
602 /* Check the owner of the tile */ |
|
603 if (!VehicleMayEnterTile((Owner)aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) { |
|
604 return; |
|
605 } |
|
606 |
|
607 /* Determine available tracks */ |
|
608 if (type != TRANSPORT_WATER && (IsStandardRoadStopTile(dst_tile) || IsTileDepotType(dst_tile, type))){ |
|
609 /* Road stations and road and train depots return 0 on GTTS, so we have to do this by hand... */ |
|
610 DiagDirection exitdir; |
|
611 if (IsRoadStopTile(dst_tile)) { |
|
612 exitdir = GetRoadStopDir(dst_tile); |
|
613 } else { // Road or train depot |
|
614 exitdir = GetDepotDirection(dst_tile, type); |
|
615 } |
|
616 /* Find the trackdirs that are available for a depot or station with this |
|
617 * orientation. They are only "inwards", since we are reaching this tile |
|
618 * from some other tile. This prevents vehicles driving into depots from |
|
619 * the back */ |
|
620 ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagDir(exitdir))); |
|
621 } else { |
|
622 ts = GetTileTrackStatus(dst_tile, type, subtype); |
|
623 } |
|
624 trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); /* Filter out signal status and the unused bits */ |
|
625 |
|
626 DEBUG(npf, 4, "Next node: (%d, %d) [%d], possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits); |
|
627 /* Select only trackdirs we can reach from our current trackdir */ |
|
628 trackdirbits &= TrackdirReachesTrackdirs(src_trackdir); |
|
629 if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */ |
|
630 trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir); |
|
631 |
|
632 DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits); |
|
633 |
|
634 i = 0; |
|
635 /* Enumerate possible track */ |
715 /* Enumerate possible track */ |
|
716 uint i = 0; |
636 while (trackdirbits != 0) { |
717 while (trackdirbits != 0) { |
637 Trackdir dst_trackdir = RemoveFirstTrackdir(&trackdirbits); |
718 Trackdir dst_trackdir = RemoveFirstTrackdir(&trackdirbits); |
638 DEBUG(npf, 5, "Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits); |
719 DEBUG(npf, 5, "Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits); |
639 |
720 |
640 /* Check for oneway signal against us */ |
721 /* Check for oneway signal against us */ |