699 |
699 |
700 /** |
700 /** |
701 * Draw ground sprite and road pieces |
701 * Draw ground sprite and road pieces |
702 * @param ti TileInfo |
702 * @param ti TileInfo |
703 * @param road RoadBits to draw |
703 * @param road RoadBits to draw |
704 * @param ground_type Ground type |
|
705 * @param snow Draw snow |
|
706 * @param flat Draw foundation |
|
707 */ |
704 */ |
708 static void DrawRoadBits(TileInfo* ti, RoadBits road, byte ground_type, bool snow, bool flat) |
705 static void DrawRoadBits(TileInfo* ti, RoadBits road) |
709 { |
706 { |
710 const DrawRoadTileStruct *drts; |
707 const DrawRoadTileStruct *drts; |
711 PalSpriteID image = 0; |
708 PalSpriteID image = 0; |
712 |
709 |
713 if (ti->tileh != 0) { |
710 if (ti->tileh != 0) { |
714 int foundation; |
711 int foundation = GetRoadFoundation(ti->tileh, road); |
715 if (flat) { |
|
716 foundation = ti->tileh; |
|
717 } else { |
|
718 foundation = GetRoadFoundation(ti->tileh, road); |
|
719 } |
|
720 |
712 |
721 if (foundation != 0) DrawFoundation(ti, foundation); |
713 if (foundation != 0) DrawFoundation(ti, foundation); |
722 |
714 |
723 // DrawFoundation() modifies ti. |
715 // DrawFoundation() modifies ti. |
724 // Default sloped sprites.. |
716 // Default sloped sprites.. |
725 if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F; |
717 if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F; |
726 } |
718 } |
727 |
719 |
728 if (image == 0) image = _road_tile_sprites_1[road]; |
720 if (image == 0) image = _road_tile_sprites_1[road]; |
729 |
721 |
730 if (ground_type == 0) image |= PALETTE_TO_BARE_LAND; |
722 if (GetGroundType(ti->tile) == RGT_BARREN) image |= PALETTE_TO_BARE_LAND; |
731 |
723 |
732 if (snow) { |
724 if (IsOnSnow(ti->tile)) { |
733 image += 19; |
725 image += 19; |
734 } else if (ground_type > 1 && ground_type != 6) { |
726 } else if (HasPavement(ti->tile)) { |
735 // Pavement tiles. |
727 // Pavement tiles. |
736 image -= 19; |
728 image -= 19; |
737 } |
729 } |
738 |
730 |
739 DrawGroundSprite(image); |
731 DrawGroundSprite(image); |
740 |
732 |
741 // Return if full detail is disabled, or we are zoomed fully out. |
733 // Return if full detail is disabled, or we are zoomed fully out. |
742 if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return; |
734 if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return; |
743 |
735 |
744 if (ground_type >= 6) { |
736 if (HasRoadWorks(ti->tile)) { |
745 // Road works |
737 // Road works |
746 DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y); |
738 DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y); |
747 return; |
739 return; |
748 } |
740 } |
749 |
741 |
750 // Draw extra details. |
742 // Draw extra details. |
751 for (drts = _road_display_table[ground_type][road]; drts->image != 0; drts++) { |
743 for (drts = _road_display_table[GetGroundType(ti->tile)][road]; drts->image != 0; drts++) { |
752 int x = ti->x | drts->subcoord_x; |
744 int x = ti->x | drts->subcoord_x; |
753 int y = ti->y | drts->subcoord_y; |
745 int y = ti->y | drts->subcoord_y; |
754 byte z = ti->z; |
746 byte z = ti->z; |
755 if (ti->tileh != 0) z = GetSlopeZ(x, y); |
747 if (ti->tileh != 0) z = GetSlopeZ(x, y); |
756 AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z); |
748 AddSortableSpriteToDraw(drts->image, x, y, 2, 2, 0x10, z); |
774 |
765 |
775 if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++; |
766 if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++; |
776 |
767 |
777 if (IsCrossingBarred(ti->tile)) image += 2; |
768 if (IsCrossingBarred(ti->tile)) image += 2; |
778 |
769 |
779 if ( _m[ti->tile].m4 & 0x80) { |
770 if (IsOnSnow(ti->tile)) { |
780 image += 8; |
771 image += 8; |
781 } else { |
772 } else { |
782 m2 = GB(_m[ti->tile].m4, 4, 3); |
773 if (GetGroundType(ti->tile) == RGT_BARREN) image |= PALETTE_TO_BARE_LAND; |
783 if (m2 == 0) image |= PALETTE_TO_BARE_LAND; |
774 if (HasPavement(ti->tile)) image += 4; |
784 if (m2 > 1) image += 4; |
|
785 } |
775 } |
786 |
776 |
787 DrawGroundSprite(image); |
777 DrawGroundSprite(image); |
788 if (GetRailTypeCrossing(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
778 if (GetRailTypeCrossing(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
789 break; |
779 break; |
885 static void AnimateTile_Road(TileIndex tile) |
875 static void AnimateTile_Road(TileIndex tile) |
886 { |
876 { |
887 if (IsLevelCrossing(tile)) MarkTileDirtyByTile(tile); |
877 if (IsLevelCrossing(tile)) MarkTileDirtyByTile(tile); |
888 } |
878 } |
889 |
879 |
890 static const byte _town_road_types[5][2] = { |
880 static const RoadGroundType _town_road_types[5][2] = { |
891 {1,1}, |
881 {RGT_GRASS,RGT_GRASS}, |
892 {2,2}, |
882 {RGT_PAVED,RGT_PAVED}, |
893 {2,2}, |
883 {RGT_PAVED,RGT_PAVED}, |
894 {5,5}, |
884 {RGT_ALLEY,RGT_ALLEY}, |
895 {3,2}, |
885 {RGT_LIGHT,RGT_PAVED}, |
896 }; |
886 }; |
897 |
887 |
898 static const byte _town_road_types_2[5][2] = { |
888 static const RoadGroundType _town_road_types_2[5][2] = { |
899 {1,1}, |
889 {RGT_GRASS,RGT_GRASS}, |
900 {2,2}, |
890 {RGT_PAVED,RGT_PAVED}, |
901 {3,2}, |
891 {RGT_LIGHT,RGT_PAVED}, |
902 {3,2}, |
892 {RGT_LIGHT,RGT_PAVED}, |
903 {3,2}, |
893 {RGT_LIGHT,RGT_PAVED}, |
904 }; |
894 }; |
905 |
895 |
906 |
896 |
907 static void TileLoop_Road(TileIndex tile) |
897 static void TileLoop_Road(TileIndex tile) |
908 { |
898 { |
909 Town *t; |
899 Town *t; |
910 int grp; |
900 int grp; |
911 |
901 |
912 switch (_opt.landscape) { |
902 switch (_opt.landscape) { |
913 case LT_HILLY: |
903 case LT_HILLY: |
914 if ((_m[tile].m4 & 0x80) != (GetTileZ(tile) > _opt.snow_line ? 0x80 : 0x00)) { |
904 if (IsOnSnow(tile) != (GetTileZ(tile) > _opt.snow_line)) { |
915 _m[tile].m4 ^= 0x80; |
905 ToggleSnow(tile); |
916 MarkTileDirtyByTile(tile); |
906 MarkTileDirtyByTile(tile); |
917 } |
907 } |
918 break; |
908 break; |
919 |
909 |
920 case LT_DESERT: |
910 case LT_DESERT: |
921 if (GetTropicZone(tile) == TROPICZONE_DESERT && !(_m[tile].m4 & 0x80)) { |
911 if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsOnDesert(tile)) { |
922 _m[tile].m4 |= 0x80; |
912 ToggleDesert(tile); |
923 MarkTileDirtyByTile(tile); |
913 MarkTileDirtyByTile(tile); |
924 } |
914 } |
925 break; |
915 break; |
926 } |
916 } |
927 |
917 |
928 if (GetRoadType(tile) == ROAD_DEPOT) return; |
918 if (GetRoadType(tile) == ROAD_DEPOT) return; |
929 |
919 |
930 if (GB(_m[tile].m4, 4, 3) < 6) { |
920 if (!HasRoadWorks(tile)) { |
931 t = ClosestTownFromTile(tile, (uint)-1); |
921 t = ClosestTownFromTile(tile, (uint)-1); |
932 |
922 |
933 grp = 0; |
923 grp = 0; |
934 if (t != NULL) { |
924 if (t != NULL) { |
935 grp = GetTownRadiusGroup(t, tile); |
925 grp = GetTownRadiusGroup(t, tile); |
936 |
926 |
937 // Show an animation to indicate road work |
927 // Show an animation to indicate road work |
938 if (t->road_build_months != 0 && |
928 if (t->road_build_months != 0 && |
939 !(DistanceManhattan(t->xy, tile) >= 8 && grp == 0) && |
929 !(DistanceManhattan(t->xy, tile) >= 8 && grp == 0) && |
940 (_m[tile].m5 == ROAD_Y || _m[tile].m5 == ROAD_X)) { |
930 GetRoadType(tile) == ROAD_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) { |
941 if (GetTileSlope(tile, NULL) == 0 && EnsureNoVehicle(tile) && CHANCE16(1, 20)) { |
931 if (GetTileSlope(tile, NULL) == 0 && EnsureNoVehicle(tile) && CHANCE16(1, 20)) { |
942 SB(_m[tile].m4, 4, 3, (GB(_m[tile].m4, 4, 3) <= 1 ? 6 : 7)); |
932 StartRoadWorks(tile); |
943 |
933 |
944 SndPlayTileFx(SND_21_JACKHAMMER, tile); |
934 SndPlayTileFx(SND_21_JACKHAMMER, tile); |
945 CreateEffectVehicleAbove( |
935 CreateEffectVehicleAbove( |
946 TileX(tile) * TILE_SIZE + 7, |
936 TileX(tile) * TILE_SIZE + 7, |
947 TileY(tile) * TILE_SIZE + 7, |
937 TileY(tile) * TILE_SIZE + 7, |
952 } |
942 } |
953 } |
943 } |
954 } |
944 } |
955 |
945 |
956 { |
946 { |
957 const byte *p = (_opt.landscape == LT_CANDY) ? _town_road_types_2[grp] : _town_road_types[grp]; |
947 /* Adjust road ground type depending on 'grp' (grp is the distance to the center) */ |
958 byte b = GB(_m[tile].m4, 4, 3); |
948 const RoadGroundType *target_rgt = (_opt.landscape == LT_CANDY) ? _town_road_types_2[grp] : _town_road_types[grp]; |
959 |
949 RoadGroundType rgt = GetGroundType(tile); |
960 if (b == p[0]) return; |
950 |
961 |
951 /* We have our desired type, do nothing */ |
962 if (b == p[1]) { |
952 if (rgt == target_rgt[0]) return; |
963 b = p[0]; |
953 |
964 } else if (b == 0) { |
954 /* We have the pre-type of the desired type, switch to the desired type */ |
965 b = p[1]; |
955 if (rgt == target_rgt[1]) { |
|
956 rgt = target_rgt[0]; |
|
957 /* We have barren land, install the pre-type */ |
|
958 } else if (rgt == RGT_BARREN) { |
|
959 rgt = target_rgt[1]; |
|
960 /* We're totally off limits, remove any installation and make barren land */ |
966 } else { |
961 } else { |
967 b = 0; |
962 rgt = RGT_BARREN; |
968 } |
963 } |
969 SB(_m[tile].m4, 4, 3, b); |
964 SetGroundType(tile, rgt); |
970 MarkTileDirtyByTile(tile); |
965 MarkTileDirtyByTile(tile); |
971 } |
966 } |
972 } else { |
967 } else if (IncreaseRoadWorksCounter(tile)) { |
973 // Handle road work |
968 TerminateRoadWorks(tile); |
974 //XXX undocumented |
|
975 |
|
976 byte b = _m[tile].m4; |
|
977 //roadworks take place only |
|
978 //keep roadworks running for 16 loops |
|
979 //lower 4 bits of map3_hi store the counter now |
|
980 if ((b & 0xF) != 0xF) { |
|
981 _m[tile].m4 = b + 1; |
|
982 return; |
|
983 } |
|
984 //roadworks finished |
|
985 _m[tile].m4 = (GB(b, 4, 3) == 6 ? 1 : 2) << 4; |
|
986 MarkTileDirtyByTile(tile); |
969 MarkTileDirtyByTile(tile); |
987 } |
970 } |
988 } |
971 } |
989 |
972 |
990 void ShowRoadDepotWindow(TileIndex tile); |
973 void ShowRoadDepotWindow(TileIndex tile); |
1006 return GetCrossingRailBits(tile) * 0x101; |
989 return GetCrossingRailBits(tile) * 0x101; |
1007 |
990 |
1008 case TRANSPORT_ROAD: |
991 case TRANSPORT_ROAD: |
1009 switch (GetRoadType(tile)) { |
992 switch (GetRoadType(tile)) { |
1010 case ROAD_NORMAL: |
993 case ROAD_NORMAL: |
1011 return GB(_m[tile].m4, 4, 3) >= 6 ? |
994 return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101; |
1012 0 : _road_trackbits[GetRoadBits(tile)] * 0x101; |
|
1013 |
995 |
1014 case ROAD_CROSSING: { |
996 case ROAD_CROSSING: { |
1015 uint32 r = (GetCrossingRoadAxis(tile) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101; |
997 uint32 r = (GetCrossingRoadAxis(tile) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101; |
1016 |
998 |
1017 if (IsCrossingBarred(tile)) r *= 0x10001; |
999 if (IsCrossingBarred(tile)) r *= 0x10001; |