(svn r11983) -Codechange: Add some helper functions for slopes and use them.

This commit is contained in:
frosch 2008-01-25 15:47:58 +00:00
parent d11aeb118c
commit 6f6708e844
11 changed files with 150 additions and 107 deletions

View File

@ -341,14 +341,11 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
// Next, check for tunnels!
// Tunnels can only be built on slopes corresponding to the direction
// For now, we check both sides for this tile.. terraforming gives fuzzy result
if ((dir == DIAGDIR_NE && tileh == SLOPE_NE) ||
(dir == DIAGDIR_SE && tileh == SLOPE_SE) ||
(dir == DIAGDIR_SW && tileh == SLOPE_SW) ||
(dir == DIAGDIR_NW && tileh == SLOPE_NW)) {
if (tileh == InclinedSlope(dir)) {
// Now simply check if a tunnel can be build
ret = AI_DoCommand(tile, (PathFinderInfo->rail_or_road?0:0x200), 0, DC_AUTO, CMD_BUILD_TUNNEL);
tileh = GetTileSlope(_build_tunnel_endtile, NULL);
if (CmdSucceeded(ret) && (tileh == SLOPE_SW || tileh == SLOPE_SE || tileh == SLOPE_NW || tileh == SLOPE_NE)) {
if (CmdSucceeded(ret) && IsInclinedSlope(tileh)) {
aystar->neighbours[aystar->num_neighbours].tile = _build_tunnel_endtile;
aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_TUNNEL + (dir << 8);
aystar->neighbours[aystar->num_neighbours++].direction = 0;
@ -400,10 +397,9 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
if (parent_tileh != SLOPE_FLAT && parent->path.parent != NULL) {
// Skip if the tile was from a bridge or tunnel
if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
static const uint32 SLOPED_TILEHS = (1 << SLOPE_NW) | (1 << SLOPE_SW) | (1 << SLOPE_SE) | (1 << SLOPE_NE);
if (PathFinderInfo->rail_or_road) {
Foundation f = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(SLOPED_TILEHS, parent_tileh))) {
if (IsInclinedFoundation(f) || (!IsFoundation(f) && IsInclinedSlope(parent_tileh))) {
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
} else {
res += AI_PATHFINDER_FOUNDATION_PENALTY;
@ -411,7 +407,7 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
} else {
if (!IsRoad(parent->path.node.tile) || !IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE)) {
Foundation f = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(SLOPED_TILEHS, parent_tileh))) {
if (IsInclinedFoundation(f) || (!IsFoundation(f) && IsInclinedSlope(parent_tileh))) {
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
} else {
res += AI_PATHFINDER_FOUNDATION_PENALTY;

View File

@ -19,6 +19,7 @@
#include "viewport_func.h"
#include "gfx_func.h"
#include "player_func.h"
#include "slope_func.h"
#include "table/sprites.h"
#include "table/strings.h"
@ -189,14 +190,11 @@ static void BuildDocksToolbWndProc(Window *w, WindowEvent *e)
TileIndex tile_from;
TileIndex tile_to;
tile_from = tile_to = e->we.place.tile;
switch (GetTileSlope(tile_from, NULL)) {
case SLOPE_SW: tile_to += TileDiffXY(-1, 0); break;
case SLOPE_SE: tile_to += TileDiffXY( 0, -1); break;
case SLOPE_NW: tile_to += TileDiffXY( 0, 1); break;
case SLOPE_NE: tile_to += TileDiffXY( 1, 0); break;
default: break;
}
tile_from = e->we.place.tile;
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile_from, NULL));
tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile_from, ReverseDiagDir(dir)) : tile_from);
VpSetPresizeRange(tile_from, tile_to);
} break;

View File

@ -130,13 +130,7 @@ static void AdjustTileh(TileIndex tile, Slope *tileh)
} else if (*tileh != SLOPE_FLAT) {
*tileh = SLOPE_FLAT;
} else {
switch (GetTunnelBridgeDirection(tile)) {
case DIAGDIR_NE: *tileh = SLOPE_NE; break;
case DIAGDIR_SE: *tileh = SLOPE_SE; break;
case DIAGDIR_SW: *tileh = SLOPE_SW; break;
case DIAGDIR_NW: *tileh = SLOPE_NW; break;
default: NOT_REACHED();
}
*tileh = InclinedSlope(GetTunnelBridgeDirection(tile));
}
}
}

View File

@ -142,7 +142,7 @@ uint GetPartialZ(int x, int y, Slope corners)
int z = 0;
switch (corners & ~SLOPE_HALFTILE_MASK) {
switch (RemoveHalftileSlope(corners)) {
case SLOPE_W:
if (x - y >= 0)
z = (x - y) >> 1;
@ -254,10 +254,7 @@ uint GetSlopeZ(int x, int y)
int GetSlopeZInCorner(Slope tileh, Corner corner)
{
assert(!IsHalftileSlope(tileh));
static const int _corner_slopes[4][2] = {
{ SLOPE_W, SLOPE_STEEP_W }, { SLOPE_S, SLOPE_STEEP_S }, { SLOPE_E, SLOPE_STEEP_E }, { SLOPE_N, SLOPE_STEEP_N }
};
return ((tileh & _corner_slopes[corner][0]) != 0 ? TILE_HEIGHT : 0) + (tileh == _corner_slopes[corner][1] ? TILE_HEIGHT : 0);
return ((tileh & SlopeWithOneCornerRaised(corner)) != 0 ? TILE_HEIGHT : 0) + (tileh == SteepSlope(corner) ? TILE_HEIGHT : 0);
}
/**
@ -289,10 +286,18 @@ void GetSlopeZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2)
if ((tileh & corners[edge][0]) != 0) *z1 += TILE_HEIGHT; // z1 is raised
if ((tileh & corners[edge][1]) != 0) *z2 += TILE_HEIGHT; // z2 is raised
if ((tileh & ~SLOPE_HALFTILE_MASK) == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
if ((tileh & ~SLOPE_HALFTILE_MASK) == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
if (RemoveHalftileSlope(tileh) == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
if (RemoveHalftileSlope(tileh) == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
}
/**
* Get slope of a tile on top of a (possible) foundation
* If a tile does not have a foundation, the function returns the same as GetTileSlope.
*
* @param tile The tile of interest.
* @param z returns the z of the foundation slope. (Can be NULL, if not needed)
* @return The slope on top of the foundation.
*/
Slope GetFoundationSlope(TileIndex tile, uint* z)
{
Slope tileh = GetTileSlope(tile, z);

View File

@ -239,11 +239,11 @@ Foundation GetRailFoundation(Slope tileh, TrackBits bits)
return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
case TRACK_BIT_X:
if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X;
if (IsSlopeWithOneCornerRaised(tileh)) return FOUNDATION_INCLINED_X;
return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
case TRACK_BIT_Y:
if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_Y;
if (IsSlopeWithOneCornerRaised(tileh)) return FOUNDATION_INCLINED_Y;
return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
default:
@ -255,7 +255,7 @@ Foundation GetRailFoundation(Slope tileh, TrackBits bits)
if (!valid_on_leveled) return FOUNDATION_INVALID;
/* If slope has three raised corners, build leveled foundation */
if (HasSlopeHighestCorner(ComplementSlope(tileh))) return FOUNDATION_LEVELED;
if (IsSlopeWithThreeCornersRaised(tileh)) return FOUNDATION_LEVELED;
/* If neighboured corners of track_corner are lowered, build halftile foundation */
if ((tileh & SlopeWithThreeCornersRaised(OppositeCorner(track_corner))) == SlopeWithOneCornerRaised(track_corner)) return HalftileFoundation(track_corner);
@ -396,7 +396,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
/* FALLTHROUGH */
default:
bool water_ground = IsTileType(tile, MP_WATER) && !IsSteepSlope(tileh) && HasSlopeHighestCorner(tileh);
bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
if (CmdFailed(ret)) return ret;
@ -540,7 +540,7 @@ bool FloodHalftile(TileIndex t)
Slope tileh = GetTileSlope(t, NULL);
TrackBits rail_bits = GetTrackBits(t);
if (!IsSteepSlope(tileh) && HasSlopeHighestCorner(tileh)) {
if (IsSlopeWithOneCornerRaised(tileh)) {
TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
TrackBits to_remove = lower_track & rail_bits;
@ -1497,9 +1497,7 @@ static void DrawTrackFence_NE_SW(const TileInfo *ti)
*/
static void DrawTrackFence_NS_1(const TileInfo *ti)
{
int z = ti->z;
if (ti->tileh & SLOPE_W) z += TILE_HEIGHT;
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
uint z = ti->z + GetSlopeZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_W);
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
}
@ -1509,9 +1507,7 @@ static void DrawTrackFence_NS_1(const TileInfo *ti)
*/
static void DrawTrackFence_NS_2(const TileInfo *ti)
{
int z = ti->z;
if (ti->tileh & SLOPE_E) z += TILE_HEIGHT;
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
uint z = ti->z + GetSlopeZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_E);
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
}
@ -1521,9 +1517,7 @@ static void DrawTrackFence_NS_2(const TileInfo *ti)
*/
static void DrawTrackFence_WE_1(const TileInfo *ti)
{
int z = ti->z;
if (ti->tileh & SLOPE_N) z += TILE_HEIGHT;
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
uint z = ti->z + GetSlopeZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_N);
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
}
@ -1533,9 +1527,7 @@ static void DrawTrackFence_WE_1(const TileInfo *ti)
*/
static void DrawTrackFence_WE_2(const TileInfo *ti)
{
int z = ti->z;
if (ti->tileh & SLOPE_S) z += TILE_HEIGHT;
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
uint z = ti->z + GetSlopeZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_S);
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
}
@ -2217,8 +2209,8 @@ static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, uint z_ol
}
/* The height of the track_corner must not be changed. The rest ensures GetRailFoundation() already. */
z_old += GetSlopeZInCorner((Slope)(tileh_old & ~SLOPE_HALFTILE_MASK), track_corner);
z_new += GetSlopeZInCorner((Slope)(tileh_new & ~SLOPE_HALFTILE_MASK), track_corner);
z_old += GetSlopeZInCorner(RemoveHalftileSlope(tileh_old), track_corner);
z_new += GetSlopeZInCorner(RemoveHalftileSlope(tileh_new), track_corner);
if (z_old != z_new) return CMD_ERROR;
CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);

View File

@ -376,7 +376,7 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existi
*pieces |= MirrorRoadBits(*pieces);
/* partly leveled up tile, only if there's no road on that tile */
if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
if ((existing == ROAD_NONE || existing == *pieces) && IsSlopeWithOneCornerRaised(tileh)) {
if (*pieces == ROAD_X || *pieces == ROAD_Y) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
}
return CMD_ERROR;

View File

@ -44,6 +44,19 @@ static inline bool IsHalftileSlope(Slope s)
return (s & SLOPE_HALFTILE) != 0;
}
/**
* Removes a halftile slope from a slope
*
* Non-halftile slopes remain unmodified.
*
* @param s A #Slope.
* @return The slope s without it's halftile slope.
*/
static inline Slope RemoveHalftileSlope(Slope s)
{
return (Slope)(s & ~SLOPE_HALFTILE_MASK);
}
/**
* Return the complement of a slope.
*
@ -61,6 +74,29 @@ static inline Slope ComplementSlope(Slope s)
return (Slope)(0xF ^ s);
}
/**
* Tests if a specific slope has exactly one corner raised.
*
* @param s The #Slope
* @return true iff exactly one corner is raised
*/
static inline bool IsSlopeWithOneCornerRaised(Slope s)
{
return (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N);
}
/**
* Returns the slope with a specific corner raised.
*
* @param corner The #Corner.
* @return The #Slope with corner "corner" raised.
*/
static inline Slope SlopeWithOneCornerRaised(Corner corner)
{
assert(IsValidCorner(corner));
return (Slope)(1 << corner);
}
/**
* Tests if a slope has a highest corner (i.e. one corner raised or a steep slope).
*
@ -71,8 +107,8 @@ static inline Slope ComplementSlope(Slope s)
*/
static inline bool HasSlopeHighestCorner(Slope s)
{
s = (Slope)(s & ~SLOPE_HALFTILE_MASK);
return IsSteepSlope(s) || (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N);
s = RemoveHalftileSlope(s);
return IsSteepSlope(s) || IsSlopeWithOneCornerRaised(s);
}
/**
@ -84,7 +120,7 @@ static inline bool HasSlopeHighestCorner(Slope s)
*/
static inline Corner GetHighestSlopeCorner(Slope s)
{
switch (s & ~SLOPE_HALFTILE_MASK) {
switch (RemoveHalftileSlope(s)) {
case SLOPE_W:
case SLOPE_STEEP_W: return CORNER_W;
case SLOPE_S:
@ -135,15 +171,14 @@ static inline Corner OppositeCorner(Corner corner)
}
/**
* Returns the slope with a specific corner raised.
* Tests if a specific slope has exactly three corners raised.
*
* @param corner The #Corner.
* @return The #Slope with corner "corner" raised.
* @param s The #Slope
* @return true iff exactly three corners are raised
*/
static inline Slope SlopeWithOneCornerRaised(Corner corner)
static inline bool IsSlopeWithThreeCornersRaised(Slope s)
{
assert(IsValidCorner(corner));
return (Slope)(1 << corner);
return !IsHalftileSlope(s) && !IsSteepSlope(s) && IsSlopeWithOneCornerRaised(ComplementSlope(s));
}
/**
@ -157,6 +192,62 @@ static inline Slope SlopeWithThreeCornersRaised(Corner corner)
return ComplementSlope(SlopeWithOneCornerRaised(corner));
}
/**
* Returns a specific steep slope
*
* @param corner A #Corner.
* @return The steep #Slope with "corner" as highest corner.
*/
static inline Slope SteepSlope(Corner corner)
{
return (Slope)(SLOPE_STEEP | SlopeWithThreeCornersRaised(OppositeCorner(corner)));
}
/**
* Tests if a specific slope is an inclined slope.
*
* @param s The #Slope
* @return true iff the slope is inclined.
*/
static inline bool IsInclinedSlope(Slope s)
{
return (s == SLOPE_NW) || (s == SLOPE_SW) || (s == SLOPE_SE) || (s == SLOPE_NE);
}
/**
* Returns the direction of an inclined slope.
*
* @param s A #Slope
* @return The direction the slope goes up in. Or INVALID_DIAGDIR if the slope is not an inclined slope.
*/
static inline DiagDirection GetInclinedSlopeDirection(Slope s)
{
switch (s) {
case SLOPE_NE: return DIAGDIR_NE;
case SLOPE_SE: return DIAGDIR_SE;
case SLOPE_SW: return DIAGDIR_SW;
case SLOPE_NW: return DIAGDIR_NW;
default: return INVALID_DIAGDIR;
}
}
/**
* Returns the slope, that is inclined in a specific direction.
*
* @param dir A #DiagDirection
* @return The #Slope that goes up in direction dir.
*/
static inline Slope InclinedSlope(DiagDirection dir)
{
switch (dir) {
case DIAGDIR_NE: return SLOPE_NE;
case DIAGDIR_SE: return SLOPE_SE;
case DIAGDIR_SW: return SLOPE_SW;
case DIAGDIR_NW: return SLOPE_NW;
default: NOT_REACHED();
}
}
/**
* Adds a halftile slope to a slope.
*

View File

@ -1945,14 +1945,9 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
CommandCost cost;
DiagDirection direction;
switch (GetTileSlope(tile, NULL)) {
case SLOPE_SW: direction = DIAGDIR_NE; break;
case SLOPE_SE: direction = DIAGDIR_NW; break;
case SLOPE_NW: direction = DIAGDIR_SE; break;
case SLOPE_NE: direction = DIAGDIR_SW; break;
default: return_cmd_error(STR_304B_SITE_UNSUITABLE);
}
DiagDirection direction = GetInclinedSlopeDirection(GetTileSlope(tile, NULL));
if (direction == INVALID_DIAGDIR) return_cmd_error(STR_304B_SITE_UNSUITABLE);
direction = ReverseDiagDir(direction);
/* Docks cannot be placed on rapids */
if (IsRiverTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE);

View File

@ -465,14 +465,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
}
start_tileh = GetTileSlope(start_tile, &start_z);
switch (start_tileh) {
case SLOPE_SW: direction = DIAGDIR_SW; break;
case SLOPE_SE: direction = DIAGDIR_SE; break;
case SLOPE_NW: direction = DIAGDIR_NW; break;
case SLOPE_NE: direction = DIAGDIR_NE; break;
default: return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL);
}
direction = GetInclinedSlopeDirection(start_tileh);
if (direction == INVALID_DIAGDIR) return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL);
if (IsRiverTile(start_tile)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);

View File

@ -909,7 +909,7 @@ static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type)
int offset;
FoundationPart foundation_part = FOUNDATION_PART_NORMAL;
Slope autorail_tileh = (Slope)(ti->tileh & ~SLOPE_HALFTILE_MASK);
Slope autorail_tileh = RemoveHalftileSlope(ti->tileh);
if (IsHalftileSlope(ti->tileh)) {
static const uint _lower_rail[4] = { 5U, 2U, 4U, 3U };
Corner halftile_corner = GetHalftileSlopeCorner(ti->tileh);
@ -958,7 +958,7 @@ static void DrawTileSelection(const TileInfo *ti)
FoundationPart foundation_part = FOUNDATION_PART_NORMAL;
if (ti->tileh & SLOPE_N) {
z += TILE_HEIGHT;
if ((ti->tileh & ~SLOPE_HALFTILE_MASK) == SLOPE_STEEP_N) z += TILE_HEIGHT;
if (RemoveHalftileSlope(ti->tileh) == SLOPE_STEEP_N) z += TILE_HEIGHT;
}
if (IsHalftileSlope(ti->tileh)) {
Corner halftile_corner = GetHalftileSlopeCorner(ti->tileh);

View File

@ -69,11 +69,6 @@ static const uint8 _flood_from_dirs[] = {
(1 << DIR_W ) | (1 << DIR_SW) | (1 << DIR_NW), // SLOPE_SEN, SLOPE_STEEP_E
};
/**
* Slopes that contain flat water and not only shore.
*/
static const uint32 _active_water_slopes = (1 << SLOPE_FLAT) | (1 << SLOPE_W) | (1 << SLOPE_S) | (1 << SLOPE_E) | (1 << SLOPE_N);
/**
* Makes a tile canal or water depending on the surroundings.
* This as for example docks and shipdepots do not store
@ -276,15 +271,8 @@ static void MarkTilesAroundDirty(TileIndex tile)
*/
CommandCost CmdBuildLock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
DiagDirection dir;
switch (GetTileSlope(tile, NULL)) {
case SLOPE_SW: dir = DIAGDIR_SW; break;
case SLOPE_SE: dir = DIAGDIR_SE; break;
case SLOPE_NW: dir = DIAGDIR_NW; break;
case SLOPE_NE: dir = DIAGDIR_NE; break;
default: return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
}
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile, NULL));
if (dir == INVALID_DIAGDIR) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
/* Disallow building of locks on river rapids */
if (IsRiverTile(tile)) return_cmd_error(STR_0239_SITE_UNSUITABLE);
@ -296,7 +284,7 @@ CommandCost CmdBuildLock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
* @param tile end tile of stretch-dragging
* @param flags type of operation
* @param p1 start tile of stretch-dragging
* @param p2 ctrl pressed - toggles ocean / canals at sealevel (ocean only allowed in the scenario editor)
* @param p2 specifies canal (0), water (1) or river (2); last two can only be built in scenario editor
*/
CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
@ -328,7 +316,7 @@ CommandCost CmdBuildCanal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CommandCost ret;
Slope slope = GetTileSlope(tile, NULL);
if (slope != SLOPE_FLAT && (p2 != 2 || (slope != SLOPE_NW && slope != SLOPE_NE && slope != SLOPE_SW && slope != SLOPE_SE))) {
if (slope != SLOPE_FLAT && (p2 != 2 || !IsInclinedSlope(slope))) {
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
}
@ -389,7 +377,7 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
if (flags & DC_EXEC) DoClearSquare(tile);
if (slope == SLOPE_N || slope == SLOPE_E || slope == SLOPE_S || slope == SLOPE_W) {
if (IsSlopeWithOneCornerRaised(slope)) {
return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_water);
} else {
return CommandCost(EXPENSES_CONSTRUCTION, _price.clear_roughland);
@ -424,17 +412,7 @@ static bool IsWateredTile(TileIndex tile)
switch (GetTileType(tile)) {
case MP_WATER:
if (!IsCoast(tile)) return true;
switch (GetTileSlope(tile, NULL)) {
case SLOPE_W:
case SLOPE_S:
case SLOPE_E:
case SLOPE_N:
return true;
default:
return false;
}
return IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL));
case MP_RAILWAY: return GetRailGroundType(tile) == RAIL_GROUND_WATER;
case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy(tile);
@ -811,7 +789,7 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
case MP_WATER:
if (IsCoast(tile)) {
Slope tileh = GetTileSlope(tile, NULL);
return (HasBit(_active_water_slopes, tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP);
return (IsSlopeWithOneCornerRaised(tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP);
} else {
return ((IsSea(tile) || (IsShipDepot(tile) && (GetShipDepotWaterOwner(tile) == OWNER_WATER))) ? FLOOD_ACTIVE : FLOOD_NONE);
}
@ -984,7 +962,7 @@ void ConvertGroundTilesIntoWaterTiles()
FOR_EACH_SET_BIT(dir, check_dirs) {
TileIndex dest = TILE_ADD(tile, TileOffsByDir((Direction)dir));
Slope slope_dest = (Slope)(GetTileSlope(dest, NULL) & ~SLOPE_STEEP);
if (HasBit(_active_water_slopes, slope_dest)) {
if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest)) {
MakeShore(tile);
break;
}