29 #include "industry_map.h" |
29 #include "industry_map.h" |
30 #include "newgrf.h" |
30 #include "newgrf.h" |
31 #include "newgrf_canal.h" |
31 #include "newgrf_canal.h" |
32 #include "misc/autoptr.hpp" |
32 #include "misc/autoptr.hpp" |
33 |
33 |
|
34 /** Array for the shore sprites */ |
34 static const SpriteID _water_shore_sprites[] = { |
35 static const SpriteID _water_shore_sprites[] = { |
35 0, |
36 0, |
36 SPR_SHORE_TILEH_1, |
37 SPR_SHORE_TILEH_1, // SLOPE_W |
37 SPR_SHORE_TILEH_2, |
38 SPR_SHORE_TILEH_2, // SLOPE_S |
38 SPR_SHORE_TILEH_3, |
39 SPR_SHORE_TILEH_3, // SLOPE_SW |
39 SPR_SHORE_TILEH_4, |
40 SPR_SHORE_TILEH_4, // SLOPE_E |
40 0, |
41 0, |
41 SPR_SHORE_TILEH_6, |
42 SPR_SHORE_TILEH_6, // SLOPE_SE |
42 0, |
43 0, |
43 SPR_SHORE_TILEH_8, |
44 SPR_SHORE_TILEH_8, // SLOPE_N |
44 SPR_SHORE_TILEH_9, |
45 SPR_SHORE_TILEH_9, // SLOPE_NW |
45 0, |
46 0, |
46 0, |
47 0, |
47 SPR_SHORE_TILEH_12, |
48 SPR_SHORE_TILEH_12, // SLOPE_NE |
48 0, |
49 0, |
49 0 |
50 0 |
50 }; |
51 }; |
51 |
52 |
52 |
53 |
69 |
70 |
70 Axis axis = Extract<Axis, 0>(p1); |
71 Axis axis = Extract<Axis, 0>(p1); |
71 |
72 |
72 tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); |
73 tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); |
73 |
74 |
74 if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2)) |
75 if (!IsWaterTile(tile) || !IsWaterTile(tile2)) |
75 return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER); |
76 return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER); |
76 |
77 |
77 if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
78 if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
78 |
79 |
79 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
80 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
300 !IS_INT_INSIDE(TileY(tile), 1, MapMaxY() - 1)) { |
301 !IS_INT_INSIDE(TileY(tile), 1, MapMaxY() - 1)) { |
301 return_cmd_error(STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP); |
302 return_cmd_error(STR_0002_TOO_CLOSE_TO_EDGE_OF_MAP); |
302 } |
303 } |
303 |
304 |
304 /* Make sure no vehicle is on the tile */ |
305 /* Make sure no vehicle is on the tile */ |
305 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
306 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
306 |
307 |
307 if (GetTileOwner(tile) != OWNER_WATER && GetTileOwner(tile) != OWNER_NONE && !CheckTileOwnership(tile)) return CMD_ERROR; |
308 if (GetTileOwner(tile) != OWNER_WATER && GetTileOwner(tile) != OWNER_NONE && !CheckTileOwnership(tile)) return CMD_ERROR; |
308 |
309 |
309 if (flags & DC_EXEC) DoClearSquare(tile); |
310 if (flags & DC_EXEC) DoClearSquare(tile); |
310 return CommandCost(_price.clear_water); |
311 return CommandCost(_price.clear_water); |
311 |
312 |
312 case WATER_TILE_COAST: { |
313 case WATER_TILE_COAST: { |
313 Slope slope = GetTileSlope(tile, NULL); |
314 Slope slope = GetTileSlope(tile, NULL); |
314 |
315 |
315 /* Make sure no vehicle is on the tile */ |
316 /* Make sure no vehicle is on the tile */ |
316 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
317 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
317 |
318 |
318 if (flags & DC_EXEC) DoClearSquare(tile); |
319 if (flags & DC_EXEC) DoClearSquare(tile); |
319 if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) { |
320 if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) { |
320 return CommandCost(_price.clear_water); |
321 return CommandCost(_price.clear_water); |
321 } else { |
322 } else { |
706 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
707 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
707 SndPlayVehicleFx(SND_12_EXPLOSION, v); |
708 SndPlayVehicleFx(SND_12_EXPLOSION, v); |
708 } |
709 } |
709 } |
710 } |
710 |
711 |
711 /** called from tunnelbridge_cmd, and by TileLoop_Industry() */ |
712 /** |
|
713 * Let a water tile floods its diagonal adjoining tiles |
|
714 * called from tunnelbridge_cmd, and by TileLoop_Industry() |
|
715 * |
|
716 * @param tile the water/shore tile that floods |
|
717 */ |
712 void TileLoop_Water(TileIndex tile) |
718 void TileLoop_Water(TileIndex tile) |
713 { |
719 { |
714 static const TileIndexDiffC _tile_loop_offs_array[][5] = { |
720 static const TileIndexDiffC _tile_loop_offs_array[][5] = { |
715 // tile to mod shore? shore? |
721 // tile to mod shore? shore? |
716 {{-1, 0}, {0, 0}, {0, 1}, {-1, 0}, {-1, 1}}, |
722 {{-1, 0}, {0, 0}, {0, 1}, {-1, 0}, {-1, 1}}, |
717 {{ 0, 1}, {0, 1}, {1, 1}, { 0, 2}, { 1, 2}}, |
723 {{ 0, 1}, {0, 1}, {1, 1}, { 0, 2}, { 1, 2}}, |
718 {{ 1, 0}, {1, 0}, {1, 1}, { 2, 0}, { 2, 1}}, |
724 {{ 1, 0}, {1, 0}, {1, 1}, { 2, 0}, { 2, 1}}, |
719 {{ 0, -1}, {0, 0}, {1, 0}, { 0, -1}, { 1, -1}} |
725 {{ 0, -1}, {0, 0}, {1, 0}, { 0, -1}, { 1, -1}} |
720 }; |
726 }; |
721 |
727 |
722 /* Ensure sea-level canals and buoys on canal borders do not flood */ |
728 /* Ensure buoys on canal borders do not flood */ |
723 if ((IsTileType(tile, MP_WATER) || IsBuoyTile(tile)) && !IsTileOwner(tile, OWNER_WATER)) return; |
729 if (IsCanalBuoyTile(tile)) return; |
724 |
730 /* Ensure only sea and coast floods, not canals or rivers */ |
|
731 if (IsTileType(tile, MP_WATER) && !(IsSea(tile) || IsCoast(tile))) return; |
|
732 |
|
733 /* floods in all four diagonal directions with the exception of the edges */ |
725 if (IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1) && |
734 if (IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1) && |
726 IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { |
735 IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { |
727 uint i; |
736 uint i; |
728 |
737 |
729 for (i = 0; i != lengthof(_tile_loop_offs_array); i++) { |
738 for (i = 0; i != lengthof(_tile_loop_offs_array); i++) { |
730 TileLoopWaterHelper(tile, _tile_loop_offs_array[i]); |
739 TileLoopWaterHelper(tile, _tile_loop_offs_array[i]); |
731 } |
740 } |
732 } |
741 } |
|
742 |
733 /* _current_player can be changed by TileLoopWaterHelper.. reset it back here */ |
743 /* _current_player can be changed by TileLoopWaterHelper.. reset it back here */ |
734 _current_player = OWNER_NONE; |
744 _current_player = OWNER_NONE; |
735 |
745 |
736 /* edges */ |
746 /* edges */ |
737 if (TileX(tile) == 0 && IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { //NE |
747 if (TileX(tile) == 0 && IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) { //NE |