From b329781ab284fb3eb19b60697e54e2bc56bd5d58 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 25 Jan 2008 16:51:35 +0000 Subject: [PATCH] (svn r11984) -Fix: Also draw corner shores under rail tracks. --- docs/landscape.html | 2 +- src/rail_cmd.cpp | 73 ++++++++++++++++++++++++++++++++++----------- src/rail_map.h | 2 +- src/water_cmd.cpp | 61 ++++++++++++++++++++++++++++++------- 4 files changed, 108 insertions(+), 30 deletions(-) diff --git a/docs/landscape.html b/docs/landscape.html index ec208b944b..bf3208c3a1 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -263,7 +263,7 @@ D  - on grass with fence and water on the lower halftile + on grass with fence and shore or water on the free halftile diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 6209b7ef93..e3217ca722 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -396,6 +396,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p /* FALLTHROUGH */ default: + /* Will there be flat water on the lower halftile? */ bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh); ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile); @@ -486,7 +487,9 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 owner = GetTileOwner(tile); present ^= trackbit; if (present == 0) { - if (GetRailGroundType(tile) == RAIL_GROUND_WATER) { + Slope tileh = GetTileSlope(tile, NULL); + /* If there is flat water on the lower halftile, convert the tile to shore so the water remains */ + if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)) { MakeShore(tile); } else { DoClearSquare(tile); @@ -561,6 +564,15 @@ bool FloodHalftile(TileIndex t) SetRailGroundType(t, RAIL_GROUND_WATER); MarkTileDirtyByTile(t); } + } else { + /* Make shore on steep slopes and 'three-corners-raised'-slopes. */ + if (ApplyFoundationToSlope(GetRailFoundation(tileh, rail_bits), &tileh) == 0) { + if (IsSteepSlope(tileh) || IsSlopeWithThreeCornersRaised(tileh)) { + flooded = true; + SetRailGroundType(t, RAIL_GROUND_WATER); + MarkTileDirtyByTile(t); + } + } } return flooded; } @@ -1354,7 +1366,9 @@ static CommandCost ClearTile_Track(TileIndex tile, byte flags) switch (GetRailTileType(tile)) { case RAIL_TILE_SIGNALS: case RAIL_TILE_NORMAL: { - bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER); + Slope tileh = GetTileSlope(tile, NULL); + /* Is there flat water on the lower halftile, that gets cleared expensively? */ + bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)); TrackBits tracks = GetTrackBits(tile); while (tracks != TRACK_BIT_NONE) { @@ -1546,8 +1560,16 @@ static void DrawTrackDetails(const TileInfo* ti) case RAIL_GROUND_FENCE_VERT2: DrawTrackFence_NS_2(ti); break; case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti); break; case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti); break; - case RAIL_GROUND_WATER: - switch (GetHalftileSlopeCorner(ti->tileh)) { + case RAIL_GROUND_WATER: { + Corner track_corner; + if (IsHalftileSlope(ti->tileh)) { + /* Steep slope or one-corner-raised slope with halftile foundation */ + track_corner = GetHalftileSlopeCorner(ti->tileh); + } else { + /* Three-corner-raised slope */ + track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh))); + } + switch (track_corner) { case CORNER_W: DrawTrackFence_NS_1(ti); break; case CORNER_S: DrawTrackFence_WE_2(ti); break; case CORNER_E: DrawTrackFence_NS_2(ti); break; @@ -1555,6 +1577,7 @@ static void DrawTrackDetails(const TileInfo* ti) default: NOT_REACHED(); } break; + } default: break; } } @@ -1567,6 +1590,15 @@ static void DrawTrackDetails(const TileInfo* ti) */ static void DrawTrackBits(TileInfo* ti, TrackBits track) { + /* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */ + static const int INF = 1000; // big number compared to tilesprite size + static const SubSprite _halftile_sub_sprite[4] = { + { -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right + { -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top + { -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left + { -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom + }; + const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); RailGroundType rgt = GetRailGroundType(ti->tile); Foundation f = GetRailFoundation(ti->tileh, track); @@ -1585,13 +1617,19 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track) SpriteID image; SpriteID pal = PAL_NONE; + const SubSprite *sub = NULL; bool junction = false; /* Select the sprite to use. */ if (track == 0) { /* Clear ground (only track on halftile foundation) */ if (rgt == RAIL_GROUND_WATER) { - image = SPR_FLAT_WATER_TILE; + if (IsSteepSlope(ti->tileh)) { + DrawShoreTile(ti->tileh); + image = 0; + } else { + image = SPR_FLAT_WATER_TILE; + } } else { switch (rgt) { case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break; @@ -1628,12 +1666,18 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track) switch (rgt) { case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; - case RAIL_GROUND_WATER: NOT_REACHED(); + case RAIL_GROUND_WATER: { + /* three-corner-raised slope */ + DrawShoreTile(ti->tileh); + Corner track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh))); + sub = &(_halftile_sub_sprite[track_corner]); + break; + } default: break; } } - DrawGroundSprite(image, pal); + if (image != 0) DrawGroundSprite(image, pal, sub); /* Draw track pieces individually for junction tiles */ if (junction) { @@ -1657,15 +1701,6 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track) case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; default: break; } - - static const int INF = 1000; // big number compared to tilesprite size - static const SubSprite _halftile_sub_sprite[4] = { - { -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right - { -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top - { -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left - { -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom - }; - DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner])); } } @@ -2216,7 +2251,8 @@ static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, uint z_ol CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform); /* Make the ground dirty, if surface slope has changed */ if (tileh_old != tileh_new) { - if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water); + /* If there is flat water on the lower halftile add the cost for clearing it */ + if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)) cost.AddCost(_price.clear_water); if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN); } return cost; @@ -2228,7 +2264,8 @@ static CommandCost TerraformTile_Track(TileIndex tile, uint32 flags, uint z_new, Slope tileh_old = GetTileSlope(tile, &z_old); if (IsPlainRailTile(tile)) { TrackBits rail_bits = GetTrackBits(tile); - bool was_water = GetRailGroundType(tile) == RAIL_GROUND_WATER; + /* Is there flat water on the lower halftile, that must be cleared expensively? */ + bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)); _error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK; diff --git a/src/rail_map.h b/src/rail_map.h index d4f63c72b2..edd9faf908 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -408,7 +408,7 @@ enum RailGroundType { RAIL_GROUND_FENCE_HORIZ1 = 10, ///< Grass with a fence at the southern side RAIL_GROUND_FENCE_HORIZ2 = 11, ///< Grass with a fence at the northern side RAIL_GROUND_ICE_DESERT = 12, ///< Icy or sandy - RAIL_GROUND_WATER = 13, ///< Grass with a fence and water on the lower halftile + RAIL_GROUND_WATER = 13, ///< Grass with a fence and shore or water on the free halftile }; static inline void SetRailGroundType(TileIndex t, RailGroundType rgt) diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 580e482d51..34c7098d82 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -94,9 +94,18 @@ void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o) for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { TileIndex neighbour = TileAddByDiagDir(t, dir); - if (IsTileType(neighbour, MP_WATER)) { - has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER); - has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER); + switch (GetTileType(neighbour)) { + case MP_WATER: + has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER); + has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER); + break; + + case MP_RAILWAY: + /* Shore or flooded halftile */ + has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER); + break; + + default: break; } } if (has_canal || !has_water) { @@ -414,7 +423,13 @@ static bool IsWateredTile(TileIndex tile) if (!IsCoast(tile)) return true; return IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL)); - case MP_RAILWAY: return GetRailGroundType(tile) == RAIL_GROUND_WATER; + case MP_RAILWAY: + if (GetRailGroundType(tile) == RAIL_GROUND_WATER) { + assert(IsPlainRailTile(tile)); + return IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL)); + } + return false; + case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy(tile); case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0; default: return false; @@ -781,7 +796,7 @@ static void FloodVehicle(Vehicle *v) static FloodingBehaviour GetFloodingBehaviour(TileIndex tile) { /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, rail with flooded halftile - * FLOOD_DRYUP: coast with more than one corner raised + * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track * FLOOD_PASSIVE: oilrig, dock, water-industries * FLOOD_NONE: canals, rivers, everything else */ @@ -795,7 +810,10 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile) } case MP_RAILWAY: - return ((GetRailGroundType(tile) == RAIL_GROUND_WATER) ? FLOOD_ACTIVE : FLOOD_NONE); + if (GetRailGroundType(tile) == RAIL_GROUND_WATER) { + return (IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL)) ? FLOOD_ACTIVE : FLOOD_DRYUP); + } + return FLOOD_NONE; case MP_STATION: if (IsSeaBuoyTile(tile)) return FLOOD_ACTIVE; @@ -878,12 +896,35 @@ static void DoFloodTile(TileIndex target) */ static void DoDryUp(TileIndex tile) { - assert(IsTileType(tile, MP_WATER) && IsCoast(tile)); _current_player = OWNER_WATER; - if (CmdSucceeded(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) { - MakeClear(tile, CLEAR_GRASS, 3); - MarkTileDirtyByTile(tile); + switch (GetTileType(tile)) { + case MP_RAILWAY: + assert(IsPlainRailTile(tile)); + assert(GetRailGroundType(tile) == RAIL_GROUND_WATER); + + RailGroundType new_ground; + switch (GetTrackBits(tile)) { + case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break; + case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break; + case TRACK_BIT_LEFT: new_ground = RAIL_GROUND_FENCE_VERT1; break; + case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2; break; + default: NOT_REACHED(); + } + SetRailGroundType(tile, new_ground); + MarkTileDirtyByTile(tile); + break; + + case MP_WATER: + assert(IsCoast(tile)); + + if (CmdSucceeded(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) { + MakeClear(tile, CLEAR_GRASS, 3); + MarkTileDirtyByTile(tile); + } + break; + + default: NOT_REACHED(); } _current_player = OWNER_NONE;