src/rail_cmd.cpp
changeset 8910 b261b6cb9b21
parent 8909 fa15e9afad2f
child 9015 4a44c6974ac1
equal deleted inserted replaced
8909:fa15e9afad2f 8910:b261b6cb9b21
   394 				return_cmd_error(STR_1007_ALREADY_BUILT);
   394 				return_cmd_error(STR_1007_ALREADY_BUILT);
   395 			}
   395 			}
   396 			/* FALLTHROUGH */
   396 			/* FALLTHROUGH */
   397 
   397 
   398 		default:
   398 		default:
       
   399 			/* Will there be flat water on the lower halftile? */
   399 			bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
   400 			bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
   400 
   401 
   401 			ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
   402 			ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
   402 			if (CmdFailed(ret)) return ret;
   403 			if (CmdFailed(ret)) return ret;
   403 			cost.AddCost(ret);
   404 			cost.AddCost(ret);
   484 
   485 
   485 			if (flags & DC_EXEC) {
   486 			if (flags & DC_EXEC) {
   486 				owner = GetTileOwner(tile);
   487 				owner = GetTileOwner(tile);
   487 				present ^= trackbit;
   488 				present ^= trackbit;
   488 				if (present == 0) {
   489 				if (present == 0) {
   489 					if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
   490 					Slope tileh = GetTileSlope(tile, NULL);
       
   491 					/* If there is flat water on the lower halftile, convert the tile to shore so the water remains */
       
   492 					if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)) {
   490 						MakeShore(tile);
   493 						MakeShore(tile);
   491 					} else {
   494 					} else {
   492 						DoClearSquare(tile);
   495 						DoClearSquare(tile);
   493 					}
   496 					}
   494 				} else {
   497 				} else {
   558 
   561 
   559 		if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
   562 		if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
   560 			flooded = true;
   563 			flooded = true;
   561 			SetRailGroundType(t, RAIL_GROUND_WATER);
   564 			SetRailGroundType(t, RAIL_GROUND_WATER);
   562 			MarkTileDirtyByTile(t);
   565 			MarkTileDirtyByTile(t);
       
   566 		}
       
   567 	} else {
       
   568 		/* Make shore on steep slopes and 'three-corners-raised'-slopes. */
       
   569 		if (ApplyFoundationToSlope(GetRailFoundation(tileh, rail_bits), &tileh) == 0) {
       
   570 			if (IsSteepSlope(tileh) || IsSlopeWithThreeCornersRaised(tileh)) {
       
   571 				flooded = true;
       
   572 				SetRailGroundType(t, RAIL_GROUND_WATER);
       
   573 				MarkTileDirtyByTile(t);
       
   574 			}
   563 		}
   575 		}
   564 	}
   576 	}
   565 	return flooded;
   577 	return flooded;
   566 }
   578 }
   567 
   579 
  1352 	}
  1364 	}
  1353 
  1365 
  1354 	switch (GetRailTileType(tile)) {
  1366 	switch (GetRailTileType(tile)) {
  1355 		case RAIL_TILE_SIGNALS:
  1367 		case RAIL_TILE_SIGNALS:
  1356 		case RAIL_TILE_NORMAL: {
  1368 		case RAIL_TILE_NORMAL: {
  1357 			bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER);
  1369 			Slope tileh = GetTileSlope(tile, NULL);
       
  1370 			/* Is there flat water on the lower halftile, that gets cleared expensively? */
       
  1371 			bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh));
  1358 
  1372 
  1359 			TrackBits tracks = GetTrackBits(tile);
  1373 			TrackBits tracks = GetTrackBits(tile);
  1360 			while (tracks != TRACK_BIT_NONE) {
  1374 			while (tracks != TRACK_BIT_NONE) {
  1361 				Track track = RemoveFirstTrack(&tracks);
  1375 				Track track = RemoveFirstTrack(&tracks);
  1362 				ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
  1376 				ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
  1544 		case RAIL_GROUND_FENCE_NESW:   DrawTrackFence_NE_SW(ti); break;
  1558 		case RAIL_GROUND_FENCE_NESW:   DrawTrackFence_NE_SW(ti); break;
  1545 		case RAIL_GROUND_FENCE_VERT1:  DrawTrackFence_NS_1(ti);  break;
  1559 		case RAIL_GROUND_FENCE_VERT1:  DrawTrackFence_NS_1(ti);  break;
  1546 		case RAIL_GROUND_FENCE_VERT2:  DrawTrackFence_NS_2(ti);  break;
  1560 		case RAIL_GROUND_FENCE_VERT2:  DrawTrackFence_NS_2(ti);  break;
  1547 		case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti);  break;
  1561 		case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti);  break;
  1548 		case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti);  break;
  1562 		case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti);  break;
  1549 		case RAIL_GROUND_WATER:
  1563 		case RAIL_GROUND_WATER: {
  1550 			switch (GetHalftileSlopeCorner(ti->tileh)) {
  1564 			Corner track_corner;
       
  1565 			if (IsHalftileSlope(ti->tileh)) {
       
  1566 				/* Steep slope or one-corner-raised slope with halftile foundation */
       
  1567 				track_corner = GetHalftileSlopeCorner(ti->tileh);
       
  1568 			} else {
       
  1569 				/* Three-corner-raised slope */
       
  1570 				track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
       
  1571 			}
       
  1572 			switch (track_corner) {
  1551 				case CORNER_W: DrawTrackFence_NS_1(ti); break;
  1573 				case CORNER_W: DrawTrackFence_NS_1(ti); break;
  1552 				case CORNER_S: DrawTrackFence_WE_2(ti); break;
  1574 				case CORNER_S: DrawTrackFence_WE_2(ti); break;
  1553 				case CORNER_E: DrawTrackFence_NS_2(ti); break;
  1575 				case CORNER_E: DrawTrackFence_NS_2(ti); break;
  1554 				case CORNER_N: DrawTrackFence_WE_1(ti); break;
  1576 				case CORNER_N: DrawTrackFence_WE_1(ti); break;
  1555 				default: NOT_REACHED();
  1577 				default: NOT_REACHED();
  1556 			}
  1578 			}
  1557 			break;
  1579 			break;
       
  1580 		}
  1558 		default: break;
  1581 		default: break;
  1559 	}
  1582 	}
  1560 }
  1583 }
  1561 
  1584 
  1562 
  1585 
  1565  * @param ti TileInfo
  1588  * @param ti TileInfo
  1566  * @param track TrackBits to draw
  1589  * @param track TrackBits to draw
  1567  */
  1590  */
  1568 static void DrawTrackBits(TileInfo* ti, TrackBits track)
  1591 static void DrawTrackBits(TileInfo* ti, TrackBits track)
  1569 {
  1592 {
       
  1593 	/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
       
  1594 	static const int INF = 1000; // big number compared to tilesprite size
       
  1595 	static const SubSprite _halftile_sub_sprite[4] = {
       
  1596 		{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
       
  1597 		{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
       
  1598 		{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
       
  1599 		{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
       
  1600 	};
       
  1601 
  1570 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1602 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1571 	RailGroundType rgt = GetRailGroundType(ti->tile);
  1603 	RailGroundType rgt = GetRailGroundType(ti->tile);
  1572 	Foundation f = GetRailFoundation(ti->tileh, track);
  1604 	Foundation f = GetRailFoundation(ti->tileh, track);
  1573 	Corner halftile_corner = CORNER_INVALID;
  1605 	Corner halftile_corner = CORNER_INVALID;
  1574 
  1606 
  1583 	DrawFoundation(ti, f);
  1615 	DrawFoundation(ti, f);
  1584 	/* DrawFoundation modifies ti */
  1616 	/* DrawFoundation modifies ti */
  1585 
  1617 
  1586 	SpriteID image;
  1618 	SpriteID image;
  1587 	SpriteID pal = PAL_NONE;
  1619 	SpriteID pal = PAL_NONE;
       
  1620 	const SubSprite *sub = NULL;
  1588 	bool junction = false;
  1621 	bool junction = false;
  1589 
  1622 
  1590 	/* Select the sprite to use. */
  1623 	/* Select the sprite to use. */
  1591 	if (track == 0) {
  1624 	if (track == 0) {
  1592 		/* Clear ground (only track on halftile foundation) */
  1625 		/* Clear ground (only track on halftile foundation) */
  1593 		if (rgt == RAIL_GROUND_WATER) {
  1626 		if (rgt == RAIL_GROUND_WATER) {
  1594 			image = SPR_FLAT_WATER_TILE;
  1627 			if (IsSteepSlope(ti->tileh)) {
       
  1628 				DrawShoreTile(ti->tileh);
       
  1629 				image = 0;
       
  1630 			} else {
       
  1631 				image = SPR_FLAT_WATER_TILE;
       
  1632 			}
  1595 		} else {
  1633 		} else {
  1596 			switch (rgt) {
  1634 			switch (rgt) {
  1597 				case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
  1635 				case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
  1598 				case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOWY_TILE; break;
  1636 				case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOWY_TILE; break;
  1599 				default:                     image = SPR_FLAT_GRASS_TILE; break;
  1637 				default:                     image = SPR_FLAT_GRASS_TILE; break;
  1626 		}
  1664 		}
  1627 
  1665 
  1628 		switch (rgt) {
  1666 		switch (rgt) {
  1629 			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
  1667 			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
  1630 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
  1668 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
  1631 			case RAIL_GROUND_WATER:      NOT_REACHED();
  1669 			case RAIL_GROUND_WATER: {
       
  1670 				/* three-corner-raised slope */
       
  1671 				DrawShoreTile(ti->tileh);
       
  1672 				Corner track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
       
  1673 				sub = &(_halftile_sub_sprite[track_corner]);
       
  1674 				break;
       
  1675 			}
  1632 			default: break;
  1676 			default: break;
  1633 		}
  1677 		}
  1634 	}
  1678 	}
  1635 
  1679 
  1636 	DrawGroundSprite(image, pal);
  1680 	if (image != 0) DrawGroundSprite(image, pal, sub);
  1637 
  1681 
  1638 	/* Draw track pieces individually for junction tiles */
  1682 	/* Draw track pieces individually for junction tiles */
  1639 	if (junction) {
  1683 	if (junction) {
  1640 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1684 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1641 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1685 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1655 		switch (rgt) {
  1699 		switch (rgt) {
  1656 			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
  1700 			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
  1657 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
  1701 			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
  1658 			default: break;
  1702 			default: break;
  1659 		}
  1703 		}
  1660 
       
  1661 		static const int INF = 1000; // big number compared to tilesprite size
       
  1662 		static const SubSprite _halftile_sub_sprite[4] = {
       
  1663 			{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
       
  1664 			{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
       
  1665 			{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
       
  1666 			{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
       
  1667 		};
       
  1668 
       
  1669 		DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner]));
  1704 		DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner]));
  1670 	}
  1705 	}
  1671 }
  1706 }
  1672 
  1707 
  1673 static void DrawSignals(TileIndex tile, TrackBits rails)
  1708 static void DrawSignals(TileIndex tile, TrackBits rails)
  2214 	if (z_old != z_new) return CMD_ERROR;
  2249 	if (z_old != z_new) return CMD_ERROR;
  2215 
  2250 
  2216 	CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2251 	CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2217 	/* Make the ground dirty, if surface slope has changed */
  2252 	/* Make the ground dirty, if surface slope has changed */
  2218 	if (tileh_old != tileh_new) {
  2253 	if (tileh_old != tileh_new) {
  2219 		if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water);
  2254 		/* If there is flat water on the lower halftile add the cost for clearing it */
       
  2255 		if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)) cost.AddCost(_price.clear_water);
  2220 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2256 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2221 	}
  2257 	}
  2222 	return  cost;
  2258 	return  cost;
  2223 }
  2259 }
  2224 
  2260 
  2226 {
  2262 {
  2227 	uint z_old;
  2263 	uint z_old;
  2228 	Slope tileh_old = GetTileSlope(tile, &z_old);
  2264 	Slope tileh_old = GetTileSlope(tile, &z_old);
  2229 	if (IsPlainRailTile(tile)) {
  2265 	if (IsPlainRailTile(tile)) {
  2230 		TrackBits rail_bits = GetTrackBits(tile);
  2266 		TrackBits rail_bits = GetTrackBits(tile);
  2231 		bool was_water = GetRailGroundType(tile) == RAIL_GROUND_WATER;
  2267 		/* Is there flat water on the lower halftile, that must be cleared expensively? */
       
  2268 		bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old));
  2232 
  2269 
  2233 		_error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
  2270 		_error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK;
  2234 
  2271 
  2235 		/* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */
  2272 		/* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */
  2236 		CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);
  2273 		CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);