603 if (b & TRACK_BIT_UPPER) r |= ROAD_NE | ROAD_NW; |
611 if (b & TRACK_BIT_UPPER) r |= ROAD_NE | ROAD_NW; |
604 if (b & TRACK_BIT_LOWER) r |= ROAD_SE | ROAD_SW; |
612 if (b & TRACK_BIT_LOWER) r |= ROAD_SE | ROAD_SW; |
605 if (b & TRACK_BIT_LEFT) r |= ROAD_NW | ROAD_SW; |
613 if (b & TRACK_BIT_LEFT) r |= ROAD_NW | ROAD_SW; |
606 if (b & TRACK_BIT_RIGHT) r |= ROAD_NE | ROAD_SE; |
614 if (b & TRACK_BIT_RIGHT) r |= ROAD_NE | ROAD_SE; |
607 return r; |
615 return r; |
|
616 } |
|
617 |
|
618 /** |
|
619 * Check if a neighboring tile has a road |
|
620 * |
|
621 * @param tile curent tile |
|
622 * @param dir target direction |
|
623 * @param dist_multi distance multiplyer |
|
624 * @return true if one of the neighboring tiles at the |
|
625 * given distance is a road tile else |
|
626 */ |
|
627 static bool NeighborIsRoadTile(TileIndex tile, int dir, RoadBlockTitleDistance dist_multi) |
|
628 { |
|
629 return (HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * ToTileIndexDiff(_roadblock_tileadd[dir + 1]))), dir ^ 2) || |
|
630 HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * ToTileIndexDiff(_roadblock_tileadd[dir + 3]))), dir ^ 2) || |
|
631 HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * (ToTileIndexDiff(_roadblock_tileadd[dir + 1]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2])))), dir) || |
|
632 HASBIT(GetTownRoadMask(TILE_ADD(tile, dist_multi * (ToTileIndexDiff(_roadblock_tileadd[dir + 3]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2])))), dir)); |
608 } |
633 } |
609 |
634 |
610 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
635 static bool IsRoadAllowedHere(TileIndex tile, int dir) |
611 { |
636 { |
612 Slope k; |
637 Slope k; |
628 } |
653 } |
629 |
654 |
630 slope = GetTileSlope(tile, NULL); |
655 slope = GetTileSlope(tile, NULL); |
631 if (slope == SLOPE_FLAT) { |
656 if (slope == SLOPE_FLAT) { |
632 no_slope: |
657 no_slope: |
633 /* Tile has no slope |
658 /* Tile has no slope */ |
634 * Disallow the road if any neighboring tile has a road. */ |
659 switch (_patches.town_layout) { |
635 if (HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 1]))), dir ^ 2) || |
660 default: NOT_REACHED(); |
636 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 3]))), dir ^ 2) || |
661 |
637 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 1]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2]))), dir) || |
662 case TL_ORIGINAL: /* Disallow the road if any neighboring tile has a road (distance: 1) */ |
638 HASBIT(GetTownRoadMask(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[dir + 3]) + ToTileIndexDiff(_roadblock_tileadd[dir + 2]))), dir)) |
663 return !NeighborIsRoadTile(tile, dir, RB_TILE_DIST1); |
639 return false; |
664 |
640 |
665 case TL_BETTER_ROADS: /* Disallow the road if any neighboring tile has a road (distance: 1 and 2). */ |
641 /* Otherwise allow */ |
666 return !(NeighborIsRoadTile(tile, dir, RB_TILE_DIST1) || |
642 return true; |
667 NeighborIsRoadTile(tile, dir, RB_TILE_DIST2)); |
|
668 } |
643 } |
669 } |
644 |
670 |
645 /* If the tile is not a slope in the right direction, then |
671 /* If the tile is not a slope in the right direction, then |
646 * maybe terraform some. */ |
672 * maybe terraform some. */ |
647 k = (dir & 1) ? SLOPE_NE : SLOPE_NW; |
673 k = (dir & 1) ? SLOPE_NE : SLOPE_NW; |
696 if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) { |
722 if (!TerraformTownTile(tile, ~tileh & 0xF, 1)) { |
697 TerraformTownTile(tile, tileh & 0xF, 0); |
723 TerraformTownTile(tile, tileh & 0xF, 0); |
698 } |
724 } |
699 } |
725 } |
700 |
726 |
|
727 /** |
|
728 * Generate the RoadBits of a grid tile |
|
729 * |
|
730 * @param t current town |
|
731 * @param tile tile in reference to the town |
|
732 * @return the RoadBit of the current tile regarding |
|
733 * the selected town layout |
|
734 */ |
|
735 static RoadBits GetTownRoadGridElement(Town* t, TileIndex tile) |
|
736 { |
|
737 /* align the grid to the downtown */ |
|
738 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); ///< Vector from downtown to the tile |
|
739 |
|
740 /* lx, ly description: |
|
741 * @li lx and ly are true if the tile is a crossing tile. |
|
742 * @li lx xor ly are true if the tile is a straight road tile. |
|
743 * @li lx and ly are false if the tile is a house tile. |
|
744 */ |
|
745 bool lx, ly; |
|
746 |
|
747 switch (_patches.town_layout) { |
|
748 default: NOT_REACHED(); |
|
749 |
|
750 case TL_2X2_GRID: |
|
751 lx = ((grid_pos.x % 3) == 0); |
|
752 ly = ((grid_pos.y % 3) == 0); |
|
753 break; |
|
754 |
|
755 case TL_3X3_GRID: |
|
756 lx = ((grid_pos.x % 4) == 0); |
|
757 ly = ((grid_pos.y % 4) == 0); |
|
758 break; |
|
759 } |
|
760 |
|
761 /* generate the basic grid structure */ |
|
762 if (!lx && !ly) { ///< It is a house tile |
|
763 return ROAD_NONE; |
|
764 } else if (lx && !ly) { ///< It is a Y-dir road tile |
|
765 return ROAD_Y; |
|
766 } else if (!lx && ly) { ///< It is a X-dir road tile |
|
767 return ROAD_X; |
|
768 } else { ///< It is a crossing tile |
|
769 /* Presets for junctions on slopes |
|
770 * not nice :( */ |
|
771 switch (GetTileSlope(tile, NULL)) { |
|
772 case SLOPE_W: |
|
773 return ROAD_NW | ROAD_SW; |
|
774 case SLOPE_S: |
|
775 return ROAD_SE | ROAD_SW; |
|
776 case SLOPE_SW: |
|
777 return ROAD_Y | ROAD_SW; |
|
778 case SLOPE_E: |
|
779 return ROAD_NE | ROAD_SE; |
|
780 case SLOPE_SE: |
|
781 return ROAD_X | ROAD_SE; |
|
782 case SLOPE_N: |
|
783 return ROAD_NW | ROAD_NE; |
|
784 case SLOPE_NW: |
|
785 return ROAD_X | ROAD_NW; |
|
786 case SLOPE_NE: |
|
787 return ROAD_Y | ROAD_NE; |
|
788 case SLOPE_STEEP_W: |
|
789 case SLOPE_STEEP_N: |
|
790 return ROAD_X; |
|
791 case SLOPE_STEEP_S: |
|
792 case SLOPE_STEEP_E: |
|
793 return ROAD_Y; |
|
794 default: |
|
795 return ROAD_ALL; |
|
796 } |
|
797 } |
|
798 } |
|
799 |
|
800 /** |
|
801 * Check there are enougth neighbor house tiles next to the current tile |
|
802 * |
|
803 * @param tile current tile |
|
804 * @return true if there are more than 2 house tiles next |
|
805 * to the current one |
|
806 */ |
|
807 static bool NeighborsAreHouseTiles(TileIndex tile) |
|
808 { |
|
809 uint counter = 0; ///< counts the house neighbor tiles |
|
810 |
|
811 /* We can't look further than that. */ |
|
812 if (TileX(tile) < 1 || TileY(tile) < 1) { |
|
813 return false; |
|
814 } |
|
815 |
|
816 /* Check the tiles E,N,W and S of the current tile. */ |
|
817 for (uint i = 0; i < 4; i++) { |
|
818 if (IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])), MP_HOUSE)) { |
|
819 counter++; |
|
820 } |
|
821 |
|
822 /* If there are enougth neighbor's stop it here */ |
|
823 if (counter >= 3) { |
|
824 return true; |
|
825 } |
|
826 } |
|
827 return false; |
|
828 } |
|
829 |
|
830 /** |
|
831 * Grows the given town. |
|
832 * There are at the moment 3 possible way's for |
|
833 * the town expansion: |
|
834 * @li Generate a random tile and check if there is a road allowed |
|
835 * @li TL_ORIGINAL |
|
836 * @li TL_BETTER_ROADS |
|
837 * @li Check if the town geometry allows a road and which one |
|
838 * @li TL_2X2_GRID |
|
839 * @li TL_3X3_GRID |
|
840 * @li Forbid roads, only build houses |
|
841 * @li TL_NO_ROADS |
|
842 * |
|
843 * @param tile_ptr current tile |
|
844 * @param mask current tiles RoadBits |
|
845 * @param block road block |
|
846 * @param t1 current town |
|
847 */ |
701 static void GrowTownInTile(TileIndex* tile_ptr, RoadBits mask, int block, Town* t1) |
848 static void GrowTownInTile(TileIndex* tile_ptr, RoadBits mask, int block, Town* t1) |
702 { |
849 { |
703 RoadBits rcmd; |
850 RoadBits rcmd; |
704 TileIndex tmptile; |
851 TileIndex tmptile; |
705 DiagDirection i; |
852 DiagDirection i; |
718 |
865 |
719 /* Remove hills etc */ |
866 /* Remove hills etc */ |
720 LevelTownLand(tile); |
867 LevelTownLand(tile); |
721 |
868 |
722 /* Is a road allowed here? */ |
869 /* Is a road allowed here? */ |
723 if (!IsRoadAllowedHere(tile, block)) return; |
870 switch (_patches.town_layout) { |
724 |
871 default: NOT_REACHED(); |
725 /* Randomize new road block numbers */ |
872 |
726 a = block; |
873 case TL_NO_ROADS: /* Disallow Roads */ |
727 b = block ^ 2; |
|
728 if (CHANCE16(1, 4)) { |
|
729 do { |
|
730 a = GB(Random(), 0, 2); |
|
731 } while (a == b); |
|
732 } |
|
733 |
|
734 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
|
735 /* A road is not allowed to continue the randomized road, |
|
736 * return if the road we're trying to build is curved. */ |
|
737 if (a != (b ^ 2)) return; |
|
738 |
|
739 /* Return if neither side of the new road is a house */ |
|
740 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
|
741 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) |
|
742 return; |
874 return; |
743 |
875 |
744 /* That means that the road is only allowed if there is a house |
876 case TL_3X3_GRID: |
745 * at any side of the new road. */ |
877 case TL_2X2_GRID: |
746 } |
878 rcmd = GetTownRoadGridElement(t1, tile); |
747 rcmd = (RoadBits)((1 << a) + (1 << b)); |
879 if (rcmd == ROAD_NONE) { |
|
880 return; |
|
881 } |
|
882 break; |
|
883 |
|
884 case TL_BETTER_ROADS: |
|
885 case TL_ORIGINAL: |
|
886 if (!IsRoadAllowedHere(tile, block)) { |
|
887 return; |
|
888 } |
|
889 |
|
890 /* Randomize new road block numbers */ |
|
891 a = block; |
|
892 b = block ^ 2; |
|
893 if (CHANCE16(1, 4)) { |
|
894 do { |
|
895 a = GB(Random(), 0, 2); |
|
896 } while (a == b); |
|
897 } |
|
898 |
|
899 if (!IsRoadAllowedHere(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a])), a)) { |
|
900 /* A road is not allowed to continue the randomized road, |
|
901 * return if the road we're trying to build is curved. */ |
|
902 if (a != (b ^ 2)) { |
|
903 return; |
|
904 } |
|
905 |
|
906 /* Return if neither side of the new road is a house */ |
|
907 if (!IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 1])), MP_HOUSE) && |
|
908 !IsTileType(TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[a + 3])), MP_HOUSE)) { |
|
909 return; |
|
910 } |
|
911 |
|
912 /* That means that the road is only allowed if there is a house |
|
913 * at any side of the new road. */ |
|
914 } |
|
915 |
|
916 rcmd = (RoadBits)((1 << a) + (1 << b)); |
|
917 break; |
|
918 } |
748 |
919 |
749 } else if (block < 5 && !HASBIT(mask, block ^ 2)) { |
920 } else if (block < 5 && !HASBIT(mask, block ^ 2)) { |
750 /* Continue building on a partial road. |
921 /* Continue building on a partial road. |
751 * Always OK. */ |
922 * Always OK. */ |
752 _grow_town_result = 0; |
923 _grow_town_result = 0; |
753 rcmd = (RoadBits)(1 << (block ^ 2)); |
924 |
|
925 switch (_patches.town_layout) { |
|
926 default: NOT_REACHED(); |
|
927 |
|
928 case TL_NO_ROADS: /* Disallow Roads */ |
|
929 return; |
|
930 |
|
931 case TL_3X3_GRID: |
|
932 case TL_2X2_GRID: |
|
933 rcmd = GetTownRoadGridElement(t1, tile); |
|
934 break; |
|
935 |
|
936 case TL_BETTER_ROADS: |
|
937 case TL_ORIGINAL: |
|
938 rcmd = (RoadBits)(1 << (block ^ 2)); |
|
939 break; |
|
940 } |
754 } else { |
941 } else { |
755 int i; |
942 int i; |
|
943 bool allow_house = false; |
|
944 TileIndex tmptile2; |
756 |
945 |
757 /* Reached a tunnel/bridge? Then continue at the other side of it. */ |
946 /* Reached a tunnel/bridge? Then continue at the other side of it. */ |
758 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
947 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
759 if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) { |
948 if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) { |
760 *tile_ptr = GetOtherTunnelEnd(tile); |
949 *tile_ptr = GetOtherTunnelEnd(tile); |
773 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
962 tmptile = TILE_ADD(tile, ToTileIndexDiff(_roadblock_tileadd[i])); |
774 |
963 |
775 /* Don't do it if it reaches to water. */ |
964 /* Don't do it if it reaches to water. */ |
776 if (IsClearWaterTile(tmptile)) return; |
965 if (IsClearWaterTile(tmptile)) return; |
777 |
966 |
778 /* Build a house at the edge. 60% chance or |
967 switch (_patches.town_layout) { |
779 * always ok if no road allowed. */ |
968 default: NOT_REACHED(); |
780 if (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)) { |
969 |
781 /* But not if there already is a house there. */ |
970 case TL_NO_ROADS: |
|
971 allow_house = true; |
|
972 break; |
|
973 |
|
974 case TL_3X3_GRID: /* Use 2x2 grid afterwards! */ |
|
975 /* Fill gap if house has enougth neighbors */ |
|
976 tmptile2 = TILE_ADD(tmptile, ToTileIndexDiff(_roadblock_tileadd[i])); |
|
977 if (NeighborsAreHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) { |
|
978 _grow_town_result = -1; |
|
979 } |
|
980 |
|
981 case TL_2X2_GRID: |
|
982 rcmd = GetTownRoadGridElement(t1, tmptile); |
|
983 allow_house = (rcmd == ROAD_NONE); |
|
984 break; |
|
985 |
|
986 case TL_BETTER_ROADS: /* Use original afterwards! */ |
|
987 /* Fill gap if house has enougth neighbors */ |
|
988 tmptile2 = TILE_ADD(tmptile, ToTileIndexDiff(_roadblock_tileadd[i])); |
|
989 if (NeighborsAreHouseTiles(tmptile2) && BuildTownHouse(t1, tmptile2)) { |
|
990 _grow_town_result = -1; |
|
991 } |
|
992 |
|
993 case TL_ORIGINAL: |
|
994 /* Allow a house at the edge. 60% chance or |
|
995 * always ok if no road allowed. */ |
|
996 allow_house = (!IsRoadAllowedHere(tmptile, i) || CHANCE16(6, 10)); |
|
997 break; |
|
998 } |
|
999 |
|
1000 |
|
1001 if (allow_house) { |
|
1002 /* Build a house, but not if there already is a house there. */ |
782 if (!IsTileType(tmptile, MP_HOUSE)) { |
1003 if (!IsTileType(tmptile, MP_HOUSE)) { |
783 /* Level the land if possible */ |
1004 /* Level the land if possible */ |
784 LevelTownLand(tmptile); |
1005 LevelTownLand(tmptile); |
785 |
1006 |
786 /* And build a house. |
1007 /* And build a house. |
787 * Set result to -1 if we managed to build it. */ |
1008 * Set result to -1 if we managed to build it. */ |
788 if (BuildTownHouse(t1, tmptile)) _grow_town_result = -1; |
1009 if (BuildTownHouse(t1, tmptile)) { |
|
1010 _grow_town_result = -1; |
|
1011 } |
789 } |
1012 } |
790 return; |
1013 return; |
791 } |
1014 } |
792 |
1015 |
793 _grow_town_result = 0; |
1016 _grow_town_result = 0; |
809 build_road_and_exit: |
1032 build_road_and_exit: |
810 if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) { |
1033 if (!CmdFailed(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) { |
811 _grow_town_result = -1; |
1034 _grow_town_result = -1; |
812 } |
1035 } |
813 return; |
1036 return; |
|
1037 } |
|
1038 |
|
1039 /* Check if the bridge is in the right direction */ |
|
1040 if ((rcmd == ROAD_X && (i == DIAGDIR_NW || i == DIAGDIR_SE)) || |
|
1041 (rcmd == ROAD_Y && (i == DIAGDIR_NE || i == DIAGDIR_SW))) { |
|
1042 goto build_road_and_exit; |
814 } |
1043 } |
815 |
1044 |
816 tmptile = tile; |
1045 tmptile = tile; |
817 |
1046 |
818 /* Now it contains the direction of the slope */ |
1047 /* Now it contains the direction of the slope */ |
853 { |
1082 { |
854 int block = 5; // special case |
1083 int block = 5; // special case |
855 |
1084 |
856 TILE_ASSERT(tile); |
1085 TILE_ASSERT(tile); |
857 |
1086 |
858 /* Number of times to search. */ |
1087 /* Number of times to search. |
859 _grow_town_result = 10 + t->num_houses * 4 / 9; |
1088 * Better roads, 2X2 and 3X3 grid grow quite fast so we give |
|
1089 * them a little handicap. */ |
|
1090 switch (_patches.town_layout) { |
|
1091 case TL_BETTER_ROADS: |
|
1092 _grow_town_result = 10 + t->num_houses * 2 / 9; |
|
1093 break; |
|
1094 |
|
1095 case TL_3X3_GRID: |
|
1096 case TL_2X2_GRID: |
|
1097 _grow_town_result = 10 + t->num_houses * 1 / 9; |
|
1098 break; |
|
1099 |
|
1100 default: |
|
1101 _grow_town_result = 10 + t->num_houses * 4 / 9; |
|
1102 break; |
|
1103 } |
860 |
1104 |
861 do { |
1105 do { |
862 /* Get a bitmask of the road blocks on a tile */ |
1106 /* Get a bitmask of the road blocks on a tile */ |
863 RoadBits mask = GetTownRoadMask(tile); |
1107 RoadBits mask = GetTownRoadMask(tile); |
864 |
1108 |