src/water_cmd.cpp
branchnoai
changeset 9718 f82a4facea8b
parent 9703 d2a6acdbd665
child 9722 ebf0ece7d8f6
equal deleted inserted replaced
9717:2c27f9be3fb9 9718:f82a4facea8b
    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);
   102 {
   103 {
   103 	TileIndex tile2;
   104 	TileIndex tile2;
   104 
   105 
   105 	if (!IsShipDepot(tile)) return CMD_ERROR;
   106 	if (!IsShipDepot(tile)) return CMD_ERROR;
   106 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   107 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   107 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   108 	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   108 
   109 
   109 	tile2 = GetOtherShipDepotTile(tile);
   110 	tile2 = GetOtherShipDepotTile(tile);
   110 
   111 
   111 	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
   112 	if (!EnsureNoVehicleOnGround(tile2)) return CMD_ERROR;
   112 
   113 
   113 	if (flags & DC_EXEC) {
   114 	if (flags & DC_EXEC) {
   114 		/* Kill the depot, which is registered at the northernmost tile. Use that one */
   115 		/* Kill the depot, which is registered at the northernmost tile. Use that one */
   115 		delete GetDepotByTile(tile2 < tile ? tile2 : tile);
   116 		delete GetDepotByTile(tile2 < tile ? tile2 : tile);
   116 
   117 
   169 	TileIndexDiff delta = TileOffsByDiagDir(GetLockDirection(tile));
   170 	TileIndexDiff delta = TileOffsByDiagDir(GetLockDirection(tile));
   170 
   171 
   171 	if (!CheckTileOwnership(tile) && GetTileOwner(tile) != OWNER_NONE) return CMD_ERROR;
   172 	if (!CheckTileOwnership(tile) && GetTileOwner(tile) != OWNER_NONE) return CMD_ERROR;
   172 
   173 
   173 	/* make sure no vehicle is on the tile. */
   174 	/* make sure no vehicle is on the tile. */
   174 	if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(tile + delta) || !EnsureNoVehicle(tile - delta))
   175 	if (!EnsureNoVehicleOnGround(tile) || !EnsureNoVehicleOnGround(tile + delta) || !EnsureNoVehicleOnGround(tile - delta))
   175 		return CMD_ERROR;
   176 		return CMD_ERROR;
   176 
   177 
   177 	if (flags & DC_EXEC) {
   178 	if (flags & DC_EXEC) {
   178 		DoClearSquare(tile);
   179 		DoClearSquare(tile);
   179 		DoClearSquare(tile + delta);
   180 		DoClearSquare(tile + delta);
   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 {
   455 static void DrawTile_Water(TileInfo *ti)
   456 static void DrawTile_Water(TileInfo *ti)
   456 {
   457 {
   457 	switch (GetWaterTileType(ti->tile)) {
   458 	switch (GetWaterTileType(ti->tile)) {
   458 		case WATER_TILE_CLEAR:
   459 		case WATER_TILE_CLEAR:
   459 			DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
   460 			DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
   460 			if (ti->z != 0 || !IsTileOwner(ti->tile, OWNER_WATER)) DrawCanalWater(ti->tile);
   461 			if (IsCanal(ti->tile)) DrawCanalWater(ti->tile);
   461 			DrawBridgeMiddle(ti);
   462 			DrawBridgeMiddle(ti);
   462 			break;
   463 			break;
   463 
   464 
   464 		case WATER_TILE_COAST:
   465 		case WATER_TILE_COAST:
   465 			assert(!IsSteepSlope(ti->tileh));
   466 			assert(!IsSteepSlope(ti->tileh));
   515 
   516 
   516 static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
   517 static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
   517 {
   518 {
   518 	switch (GetWaterTileType(tile)) {
   519 	switch (GetWaterTileType(tile)) {
   519 		case WATER_TILE_CLEAR:
   520 		case WATER_TILE_CLEAR:
   520 			if (TilePixelHeight(tile) == 0 || IsTileOwner(tile, OWNER_WATER)) {
   521 			if (!IsCanal(tile)) {
   521 				td->str = STR_3804_WATER;
   522 				td->str = STR_3804_WATER;
   522 			} else {
   523 			} else {
   523 				td->str = STR_LANDINFO_CANAL;
   524 				td->str = STR_LANDINFO_CANAL;
   524 			}
   525 			}
   525 			break;
   526 			break;
   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
   805 }
   815 }
   806 
   816 
   807 static CommandCost TerraformTile_Water(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
   817 static CommandCost TerraformTile_Water(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
   808 {
   818 {
   809 	/* Canals can't be terraformed */
   819 	/* Canals can't be terraformed */
   810 	if (IsClearWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_MUST_DEMOLISH_CANAL_FIRST);
   820 	if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_MUST_DEMOLISH_CANAL_FIRST);
   811 
   821 
   812 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   822 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   813 }
   823 }
   814 
   824 
   815 
   825