road_cmd.c
changeset 3098 4c1320da876d
parent 3097 6cb1b1c2ae6d
child 3099 374e275300e3
equal deleted inserted replaced
3097:6cb1b1c2ae6d 3098:4c1320da876d
   222 
   222 
   223 					if (flags & DC_EXEC) {
   223 					if (flags & DC_EXEC) {
   224 						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   224 						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   225 
   225 
   226 						_m[tile].m5 ^= c;
   226 						_m[tile].m5 ^= c;
   227 						if (GB(_m[tile].m5, 0, 4) == 0) {
   227 						if (GetRoadBits(tile) == 0) {
   228 							DoClearSquare(tile);
   228 							DoClearSquare(tile);
   229 						} else {
   229 						} else {
   230 							MarkTileDirtyByTile(tile);
   230 							MarkTileDirtyByTile(tile);
   231 						}
   231 						}
   232 					}
   232 					}
   268 			return_cmd_error(INVALID_STRING_ID);
   268 			return_cmd_error(INVALID_STRING_ID);
   269 	}
   269 	}
   270 }
   270 }
   271 
   271 
   272 
   272 
   273 static const byte _valid_tileh_slopes_road[3][15] = {
   273 static const RoadBits _valid_tileh_slopes_road[3][15] = {
   274 	// set of normal ones
   274 	// set of normal ones
   275 	{
   275 	{
   276 		ROAD_ALL, 0, 0,
   276 		ROAD_ALL, 0, 0,
   277 		ROAD_SW | ROAD_NE, 0, 0,  // 3, 4, 5
   277 		ROAD_X,   0, 0,  // 3, 4, 5
   278 		ROAD_NW | ROAD_SE, 0, 0,
   278 		ROAD_Y,   0, 0,
   279 		ROAD_NW | ROAD_SE, 0, 0,  // 9, 10, 11
   279 		ROAD_Y,   0, 0,  // 9, 10, 11
   280 		ROAD_SW | ROAD_NE, 0, 0
   280 		ROAD_X,   0, 0
   281 	},
   281 	},
   282 	// allowed road for an evenly raised platform
   282 	// allowed road for an evenly raised platform
   283 	{
   283 	{
   284 		0,
   284 		0,
   285 		ROAD_SW | ROAD_NW,
   285 		ROAD_SW | ROAD_NW,
   286 		ROAD_SW | ROAD_SE,
   286 		ROAD_SW | ROAD_SE,
   287 		ROAD_NW | ROAD_SE | ROAD_SW,
   287 		ROAD_Y  | ROAD_SW,
   288 
   288 
   289 		ROAD_SE | ROAD_NE, // 4
   289 		ROAD_SE | ROAD_NE, // 4
   290 		ROAD_ALL,
   290 		ROAD_ALL,
   291 		ROAD_SW | ROAD_NE | ROAD_SE,
   291 		ROAD_X  | ROAD_SE,
   292 		ROAD_ALL,
   292 		ROAD_ALL,
   293 
   293 
   294 		ROAD_NW | ROAD_NE, // 8
   294 		ROAD_NW | ROAD_NE, // 8
   295 		ROAD_SW | ROAD_NE | ROAD_NW,
   295 		ROAD_X  | ROAD_NW,
   296 		ROAD_ALL,
   296 		ROAD_ALL,
   297 		ROAD_ALL,
   297 		ROAD_ALL,
   298 
   298 
   299 		ROAD_NW | ROAD_SE | ROAD_NE, // 12
   299 		ROAD_Y  | ROAD_NE, // 12
   300 		ROAD_ALL,
   300 		ROAD_ALL,
   301 		ROAD_ALL
   301 		ROAD_ALL
   302 	},
   302 	},
   303 	// valid railway crossings on slopes
   303 	// valid railway crossings on slopes
   304 	{
   304 	{
   547 
   547 
   548 	cost = 0;
   548 	cost = 0;
   549 	tile = start_tile;
   549 	tile = start_tile;
   550 	// Start tile is the small number.
   550 	// Start tile is the small number.
   551 	for (;;) {
   551 	for (;;) {
   552 		uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
   552 		RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
       
   553 
   553 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
   554 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
   554 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   555 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   555 
   556 
   556 		ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD);
   557 		ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD);
   557 		if (CmdFailed(ret)) {
   558 		if (CmdFailed(ret)) {
   602 
   603 
   603 	cost = 0;
   604 	cost = 0;
   604 	tile = start_tile;
   605 	tile = start_tile;
   605 	// Start tile is the small number.
   606 	// Start tile is the small number.
   606 	for (;;) {
   607 	for (;;) {
   607 		uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE;
   608 		RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X;
       
   609 
   608 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
   610 		if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
   609 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   611 		if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   610 
   612 
   611 		// try to remove the halves.
   613 		// try to remove the halves.
   612 		if (bits) {
   614 		if (bits != 0) {
   613 			ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD);
   615 			ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD);
   614 			if (!CmdFailed(ret)) cost += ret;
   616 			if (!CmdFailed(ret)) cost += ret;
   615 		}
   617 		}
   616 
   618 
   617 		if (tile == end_tile) break;
   619 		if (tile == end_tile) break;
   667 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   669 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   668 
   670 
   669 		ModifyTile(tile,
   671 		ModifyTile(tile,
   670 			MP_SETTYPE(MP_STREET) |
   672 			MP_SETTYPE(MP_STREET) |
   671 			MP_MAPOWNER_CURRENT | MP_MAP5,
   673 			MP_MAPOWNER_CURRENT | MP_MAP5,
   672 			(p1 | 0x20) /* map5 */
   674 			(ROAD_DEPOT << 4) | p1 /* map5 */
   673 		);
   675 		);
   674 
   676 
   675 	}
   677 	}
   676 	return cost + _price.build_road_depot;
   678 	return cost + _price.build_road_depot;
   677 }
   679 }
   743 } DrawRoadSeqStruct;
   745 } DrawRoadSeqStruct;
   744 
   746 
   745 #include "table/road_land.h"
   747 #include "table/road_land.h"
   746 
   748 
   747 
   749 
   748 uint GetRoadFoundation(uint tileh, uint bits)
   750 uint GetRoadFoundation(uint tileh, RoadBits bits)
   749 {
   751 {
   750 	int i;
   752 	int i;
   751 	// normal level sloped building
   753 	// normal level sloped building
   752 	if ((~_valid_tileh_slopes_road[1][tileh] & bits) == 0) return tileh;
   754 	if ((~_valid_tileh_slopes_road[1][tileh] & bits) == 0) return tileh;
   753 
   755 
   756 				(i  = 0, tileh == 1) ||
   758 				(i  = 0, tileh == 1) ||
   757 				(i += 2, tileh == 2) ||
   759 				(i += 2, tileh == 2) ||
   758 				(i += 2, tileh == 4) ||
   760 				(i += 2, tileh == 4) ||
   759 				(i += 2, tileh == 8)
   761 				(i += 2, tileh == 8)
   760 			) && (
   762 			) && (
   761 				(     bits == (ROAD_SW | ROAD_NE)) ||
   763 				(     bits == ROAD_X) ||
   762 				(i++, bits == (ROAD_NW | ROAD_SE))
   764 				(i++, bits == ROAD_Y)
   763 			)) {
   765 			)) {
   764 		return i + 15;
   766 		return i + 15;
   765 	}
   767 	}
   766 
   768 
   767 	return 0;
   769 	return 0;
   780  * @param road RoadBits to draw
   782  * @param road RoadBits to draw
   781  * @param ground_type Ground type
   783  * @param ground_type Ground type
   782  * @param snow Draw snow
   784  * @param snow Draw snow
   783  * @param flat Draw foundation
   785  * @param flat Draw foundation
   784  */
   786  */
   785 static void DrawRoadBits(TileInfo *ti, byte road, byte ground_type, bool snow, bool flat)
   787 static void DrawRoadBits(TileInfo* ti, RoadBits road, byte ground_type, bool snow, bool flat)
   786 {
   788 {
   787 	const DrawRoadTileStruct *drts;
   789 	const DrawRoadTileStruct *drts;
   788 	PalSpriteID image = 0;
   790 	PalSpriteID image = 0;
   789 
   791 
   790 	if (ti->tileh != 0) {
   792 	if (ti->tileh != 0) {
   818 	// Return if full detail is disabled, or we are zoomed fully out.
   820 	// Return if full detail is disabled, or we are zoomed fully out.
   819 	if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return;
   821 	if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return;
   820 
   822 
   821 	if (ground_type >= 6) {
   823 	if (ground_type >= 6) {
   822 		// Road works
   824 		// Road works
   823 		DrawGroundSprite(HASBIT(road, 3) ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y);
   825 		DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y);
   824 		return;
   826 		return;
   825 	}
   827 	}
   826 
   828 
   827 	// Draw extra details.
   829 	// Draw extra details.
   828 	for (drts = _road_display_table[ground_type][road]; drts->image != 0; drts++) {
   830 	for (drts = _road_display_table[ground_type][road]; drts->image != 0; drts++) {
   837 static void DrawTile_Road(TileInfo *ti)
   839 static void DrawTile_Road(TileInfo *ti)
   838 {
   840 {
   839 	PalSpriteID image;
   841 	PalSpriteID image;
   840 	uint16 m2;
   842 	uint16 m2;
   841 
   843 
   842 	switch (GB(ti->map5, 4, 4)) {
   844 	switch (GetRoadType(ti->tile)) {
   843 		case 0: // normal road
   845 		case ROAD_NORMAL:
   844 			DrawRoadBits(ti, GB(ti->map5, 0, 4), GB(_m[ti->tile].m4, 4, 3), HASBIT(_m[ti->tile].m4, 7), false);
   846 			DrawRoadBits(ti, GetRoadBits(ti->tile), GB(_m[ti->tile].m4, 4, 3), HASBIT(_m[ti->tile].m4, 7), false);
   845 			break;
   847 			break;
   846 
   848 
   847 		case 1: { // level crossing
   849 		case ROAD_CROSSING: {
   848 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   850 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   849 
   851 
   850 			image = GetRailTypeInfo(GB(_m[ti->tile].m4, 0, 4))->base_sprites.crossing;
   852 			image = GetRailTypeInfo(GB(_m[ti->tile].m4, 0, 4))->base_sprites.crossing;
   851 
   853 
   852 			if (GB(ti->map5, 3, 1) == 0) image++; /* direction */
   854 			if (GB(ti->map5, 3, 1) == 0) image++; /* direction */
   863 
   865 
   864 			DrawGroundSprite(image);
   866 			DrawGroundSprite(image);
   865 			break;
   867 			break;
   866 		}
   868 		}
   867 
   869 
   868 		default: { // depot
   870 		default:
       
   871 		case ROAD_DEPOT: {
   869 			uint32 ormod;
   872 			uint32 ormod;
   870 			PlayerID player;
   873 			PlayerID player;
   871 			const DrawRoadSeqStruct* drss;
   874 			const DrawRoadSeqStruct* drss;
   872 
   875 
   873 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   876 			if (ti->tileh != 0) DrawFoundation(ti, ti->tileh);
   924 	uint z = ti->z;
   927 	uint z = ti->z;
   925 	int th = ti->tileh;
   928 	int th = ti->tileh;
   926 
   929 
   927 	// check if it's a foundation
   930 	// check if it's a foundation
   928 	if (ti->tileh != 0) {
   931 	if (ti->tileh != 0) {
   929 		switch (GB(ti->map5, 4, 4)) {
   932 		switch (GetRoadType(ti->tile)) {
   930 			case 0: { // normal road
   933 			case ROAD_NORMAL: {
   931 				uint f = GetRoadFoundation(ti->tileh, GB(ti->map5, 0, 4));
   934 				uint f = GetRoadFoundation(ti->tileh, GetRoadBits(ti->tile));
       
   935 
   932 				if (f != 0) {
   936 				if (f != 0) {
   933 					if (f < 15) {
   937 					if (f < 15) {
   934 						// leveled foundation
   938 						// leveled foundation
   935 						return z + 8;
   939 						return z + 8;
   936 					}
   940 					}
   939 				}
   943 				}
   940 				break;
   944 				break;
   941 			}
   945 			}
   942 
   946 
   943 			// if these are on a slope then there's a level foundation
   947 			// if these are on a slope then there's a level foundation
   944 			case 1: // level crossing
   948 			case ROAD_DEPOT:
   945 			case 2: // depot
   949 			case ROAD_CROSSING:
   946 				return z + 8;
   950 				return z + 8;
   947 
   951 
   948 			default: break;
   952 			default: break;
   949 		}
   953 		}
   950 		return GetPartialZ(ti->x&0xF, ti->y&0xF, th) + z;
   954 		return GetPartialZ(ti->x&0xF, ti->y&0xF, th) + z;
   954 
   958 
   955 static uint GetSlopeTileh_Road(const TileInfo *ti)
   959 static uint GetSlopeTileh_Road(const TileInfo *ti)
   956 {
   960 {
   957 	// check if it's a foundation
   961 	// check if it's a foundation
   958 	if (ti->tileh != 0) {
   962 	if (ti->tileh != 0) {
   959 		switch (GB(ti->map5, 4, 4)) {
   963 		switch (GetRoadType(ti->tile)) {
   960 			case 0: { // normal road
   964 			case ROAD_NORMAL: {
   961 				uint f = GetRoadFoundation(ti->tileh, GB(ti->map5, 0, 4));
   965 				uint f = GetRoadFoundation(ti->tileh, GetRoadBits(ti->tile));
       
   966 
   962 				if (f != 0) {
   967 				if (f != 0) {
   963 					if (f < 15) {
   968 					if (f < 15) {
   964 						// leveled foundation
   969 						// leveled foundation
   965 						return 0;
   970 						return 0;
   966 					}
   971 					}
   969 				}
   974 				}
   970 				break;
   975 				break;
   971 			}
   976 			}
   972 
   977 
   973 			// if these are on a slope then there's a level foundation
   978 			// if these are on a slope then there's a level foundation
   974 			case 1: // level crossing
   979 			case ROAD_CROSSING:
   975 			case 2: // depot
   980 			case ROAD_DEPOT:
   976 				return 0;
   981 				return 0;
   977 
   982 
   978 			default: break;
   983 			default: break;
   979 		}
   984 		}
   980 	}
   985 	}
  1211 
  1216 
  1212 			case ROAD_CROSSING:
  1217 			case ROAD_CROSSING:
  1213 				SetTileOwner(tile, _m[tile].m3);
  1218 				SetTileOwner(tile, _m[tile].m3);
  1214 				_m[tile].m3 = 0;
  1219 				_m[tile].m3 = 0;
  1215 				_m[tile].m4 &= 0x80;
  1220 				_m[tile].m4 &= 0x80;
  1216 				_m[tile].m5 = GetCrossingRoadBits(tile);
  1221 				_m[tile].m5 = (ROAD_NORMAL << 4) | GetCrossingRoadBits(tile);
  1217 				break;
  1222 				break;
  1218 
  1223 
  1219 			default:
  1224 			default:
  1220 			case ROAD_DEPOT:
  1225 			case ROAD_DEPOT:
  1221 				DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1226 				DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);