road_cmd.c
changeset 3430 b283bb956a36
parent 3421 8ab76c47c72c
child 3434 21094a78dcdb
equal deleted inserted replaced
3429:12d01022976a 3430:b283bb956a36
   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);
   758 }
   750 }
   759 
   751 
   760 static void DrawTile_Road(TileInfo *ti)
   752 static void DrawTile_Road(TileInfo *ti)
   761 {
   753 {
   762 	PalSpriteID image;
   754 	PalSpriteID image;
   763 	uint16 m2;
       
   764 
   755 
   765 	switch (GetRoadType(ti->tile)) {
   756 	switch (GetRoadType(ti->tile)) {
   766 		case ROAD_NORMAL:
   757 		case ROAD_NORMAL:
   767 			DrawRoadBits(ti, GetRoadBits(ti->tile), GB(_m[ti->tile].m4, 4, 3), HASBIT(_m[ti->tile].m4, 7), false);
   758 			DrawRoadBits(ti, GetRoadBits(ti->tile));
   768 			break;
   759 			break;
   769 
   760 
   770 		case ROAD_CROSSING: {
   761 		case ROAD_CROSSING: {
   771 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   762 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   772 
   763 
   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;
  1044 {
  1026 {
  1045 	td->owner = GetTileOwner(tile);
  1027 	td->owner = GetTileOwner(tile);
  1046 	switch (GetRoadType(tile)) {
  1028 	switch (GetRoadType(tile)) {
  1047 		case ROAD_CROSSING: td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; break;
  1029 		case ROAD_CROSSING: td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; break;
  1048 		case ROAD_DEPOT: td->str = STR_1817_ROAD_VEHICLE_DEPOT; break;
  1030 		case ROAD_DEPOT: td->str = STR_1817_ROAD_VEHICLE_DEPOT; break;
  1049 		default: td->str = _road_tile_strings[GB(_m[tile].m4, 4, 3)]; break;
  1031 		default: td->str = _road_tile_strings[GetGroundType(tile)]; break;
  1050 	}
  1032 	}
  1051 }
  1033 }
  1052 
  1034 
  1053 static const byte _roadveh_enter_depot_unk0[4] = {
  1035 static const byte _roadveh_enter_depot_unk0[4] = {
  1054 	8, 9, 0, 1
  1036 	8, 9, 0, 1