diff options
author | rubidium <rubidium@openttd.org> | 2007-10-09 21:11:23 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2007-10-09 21:11:23 +0000 |
commit | 6cebf4aa53a4eafb79b8ea9969aafda44d4fb0cd (patch) | |
tree | d69b1fe2ef975540df49a98c7d877a8a4287a30b /src/rail_cmd.cpp | |
parent | a71b7226c58d9a71d017721ffc6fdd875bbfe68e (diff) | |
download | openttd-6cebf4aa53a4eafb79b8ea9969aafda44d4fb0cd.tar.xz |
(svn r11237) -Codechange: reduce code duplication between GetRailFoundation() and CheckRailSlope(). Patch by frosch.
Diffstat (limited to 'src/rail_cmd.cpp')
-rw-r--r-- | src/rail_cmd.cpp | 116 |
1 files changed, 67 insertions, 49 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index a2f07fd5a..92753c05c 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -150,10 +150,8 @@ static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags } -static const TrackBits _valid_tileh_slopes[][15] = { - -/* set of normal ones */ -{ +/** Valid TrackBits on a specific (non-steep)-slope without foundation */ +static const TrackBits _valid_tracks_without_foundation[15] = { TRACK_BIT_ALL, TRACK_BIT_RIGHT, TRACK_BIT_UPPER, @@ -172,10 +170,10 @@ static const TrackBits _valid_tileh_slopes[][15] = { TRACK_BIT_X, TRACK_BIT_UPPER, TRACK_BIT_RIGHT, -}, +}; -/* allowed rail for an evenly raised platform */ -{ +/** Valid TrackBits on a specific (non-steep)-slope with leveled foundation */ +static const TrackBits _valid_tracks_on_leveled_foundation[15] = { TRACK_BIT_NONE, TRACK_BIT_LEFT, TRACK_BIT_LOWER, @@ -194,62 +192,82 @@ static const TrackBits _valid_tileh_slopes[][15] = { TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_RIGHT, TRACK_BIT_ALL, TRACK_BIT_ALL -} }; +/** + * Checks if a track combination is valid on a specific slope and returns the needed foundation. + * + * @param tileh Tile slope. + * @param bits Trackbits. + * @return Needed foundation or FOUNDATION_INVALID if track/slope combination is not allowed. + */ Foundation GetRailFoundation(Slope tileh, TrackBits bits) { - if (!IsSteepSlope(tileh)) { - if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return FOUNDATION_NONE; - if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return FOUNDATION_LEVELED; - } + if (bits == TRACK_BIT_NONE) return FOUNDATION_NONE; - switch (bits) { - default: NOT_REACHED(); - case TRACK_BIT_X: return FOUNDATION_INCLINED_X; - case TRACK_BIT_Y: return FOUNDATION_INCLINED_Y; - case TRACK_BIT_LEFT: return (tileh == SLOPE_STEEP_W ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); - case TRACK_BIT_LOWER: return (tileh == SLOPE_STEEP_S ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); - case TRACK_BIT_RIGHT: return (tileh == SLOPE_STEEP_E ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); - case TRACK_BIT_UPPER: return (tileh == SLOPE_STEEP_N ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); + if (IsSteepSlope(tileh)) { + /* Test for inclined foundations */ + if (bits == TRACK_BIT_X) return FOUNDATION_INCLINED_X; + if (bits == TRACK_BIT_Y) return FOUNDATION_INCLINED_Y; + + /* Get higher track */ + Corner highest_corner = GetHighestSlopeCorner(tileh); + TrackBits higher_track = CornerToTrackBits(highest_corner); + + /* Only higher track? */ + if (bits == higher_track) return FOUNDATION_STEEP_HIGHER; + + /* Overlap with higher track? */ + if (TracksOverlap(bits | higher_track)) return FOUNDATION_INVALID; + + /* either lower track or both higher and lower track */ + return ((bits & higher_track) != 0 ? FOUNDATION_INVALID : FOUNDATION_STEEP_LOWER); + } else { + if ((~_valid_tracks_without_foundation[tileh] & bits) == 0) return FOUNDATION_NONE; + + bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0); + + switch (bits) { + case TRACK_BIT_X: + if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X; + return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); + + case TRACK_BIT_Y: + if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_Y; + return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); + + default: + return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); + } } } +/** + * Tests if a track can be build on a tile. + * + * @param tileh Tile slope. + * @param rail_bits Tracks to build. + * @param existing Tracks already built. + * @param tile Tile (used for water test) + * @return Error message or cost for foundation building. + */ static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) { - if (IsSteepSlope(tileh)) { - if (_patches.build_on_slopes && existing == 0) { - /* There may only be one track on steep slopes. (Autoslope calls with multiple bits in rail_bits) */ - if (KILL_FIRST_BIT(rail_bits & TRACK_BIT_MASK) == 0) { - TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ); - if (valid & rail_bits) return _price.terraform; - } - } - } else { - rail_bits |= existing; + /* don't allow building on the lower side of a coast */ + if (IsTileType(tile, MP_WATER)) { + if (!IsSteepSlope(tileh) && ((~_valid_tracks_on_leveled_foundation[tileh] & (rail_bits | existing)) != 0)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); + } - /* don't allow building on the lower side of a coast */ - if (IsTileType(tile, MP_WATER) && - ~_valid_tileh_slopes[1][tileh] & rail_bits) { - return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); - } + Foundation f_new = GetRailFoundation(tileh, rail_bits | existing); - /* no special foundation */ - if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) { - return CommandCost(); - } else if (!_patches.build_on_slopes || _is_old_ai_player) { - return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); - } + /* check track/slope combination */ + if ((f_new == FOUNDATION_INVALID) || + ((f_new != FOUNDATION_NONE) && (!_patches.build_on_slopes || _is_old_ai_player)) + ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); - if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up - (rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) && - (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N) - )) { // partly up - return CommandCost((existing != 0) ? 0 : _price.terraform); - } - } - return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); + Foundation f_old = GetRailFoundation(tileh, existing); + return CommandCost(f_new != f_old ? _price.terraform : 0); } /* Validate functions for rail building */ |