Changeset - r15438:0fdaf92abff1
[Not reviewed]
master
0 3 0
alberth - 14 years ago 2010-07-09 12:14:02
alberth@openttd.org
(svn r20097) -Codechange: Share constant bitset of safe level crossing slopes.
3 files changed with 6 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/rail_cmd.cpp
Show inline comments
 
@@ -363,102 +363,98 @@ CommandCost CmdBuildSingleRail(TileIndex
 
{
 
	RailType railtype = Extract<RailType, 0, 4>(p1);
 
	Track track = Extract<Track, 0, 3>(p2);
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 

	
 
	if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
 

	
 
	Slope tileh = GetTileSlope(tile, NULL);
 
	TrackBits trackbit = TrackToTrackBits(track);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY: {
 
			CommandCost ret = CheckTileOwnership(tile);
 
			if (ret.Failed()) return ret;
 

	
 
			if (!IsPlainRail(tile)) return CMD_ERROR;
 

	
 
			if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION);
 

	
 
			ret = CheckTrackCombination(tile, trackbit, flags);
 
			if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
 
			if (ret.Failed()) return ret;
 

	
 
			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
 
			if (ret.Failed()) return ret;
 
			cost.AddCost(ret);
 

	
 
			/* If the rail types don't match, try to convert only if engines of
 
			 * the new rail type are not powered on the present rail type and engines of
 
			 * the present rail type are powered on the new rail type. */
 
			if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) {
 
				if (HasPowerOnRail(GetRailType(tile), railtype)) {
 
					ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
 
					if (ret.Failed()) return ret;
 
					cost.AddCost(ret);
 
				} else {
 
					return CMD_ERROR;
 
				}
 
			}
 

	
 
			if (flags & DC_EXEC) {
 
				SetRailGroundType(tile, RAIL_GROUND_BARREN);
 
				SetTrackBits(tile, GetTrackBits(tile) | trackbit);
 
			}
 
			break;
 
		}
 

	
 
		case MP_ROAD: {
 
#define M(x) (1 << (x))
 
			/* Level crossings may only be built on these slopes */
 
			if (!HasBit(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
 
				return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 
#undef M
 
			if (!HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh)) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
 

	
 
			CommandCost ret = EnsureNoVehicleOnGround(tile);
 
			if (ret.Failed()) return ret;
 

	
 
			if (IsNormalRoad(tile)) {
 
				if (HasRoadWorks(tile)) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS);
 

	
 
				if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERROR_CROSSING_ON_ONEWAY_ROAD);
 

	
 
				if (RailNoLevelCrossings(railtype)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED);
 

	
 
				RoadTypes roadtypes = GetRoadTypes(tile);
 
				RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
 
				RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
 
				switch (roadtypes) {
 
					default: break;
 
					case ROADTYPES_TRAM:
 
						/* Tram crossings must always have road. */
 
						if (flags & DC_EXEC) SetRoadOwner(tile, ROADTYPE_ROAD, _current_company);
 
						roadtypes |= ROADTYPES_ROAD;
 
						break;
 

	
 
					case ROADTYPES_ALL:
 
						if (road != tram) return CMD_ERROR;
 
						break;
 
				}
 

	
 
				road |= tram;
 

	
 
				if ((track == TRACK_X && road == ROAD_Y) ||
 
						(track == TRACK_Y && road == ROAD_X)) {
 
					if (flags & DC_EXEC) {
 
						MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
 
						UpdateLevelCrossing(tile, false);
 
					}
 
					break;
 
				}
 
			}
 

	
 
			if (IsLevelCrossing(tile) && GetCrossingRailBits(tile) == trackbit) {
 
				return_cmd_error(STR_ERROR_ALREADY_BUILT);
 
			}
 
			/* FALLTHROUGH */
 
		}
 

	
 
		default: {
 
			/* Will there be flat water on the lower halftile? */
 
			bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
src/road_cmd.cpp
Show inline comments
 
@@ -7,101 +7,96 @@
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file road_cmd.cpp Commands related to road tiles. */
 

	
 
#include "stdafx.h"
 
#include "cmd_helper.h"
 
#include "road_internal.h"
 
#include "landscape.h"
 
#include "viewport_func.h"
 
#include "command_func.h"
 
#include "pathfinder/yapf/yapf_cache.h"
 
#include "depot_base.h"
 
#include "newgrf.h"
 
#include "variables.h"
 
#include "autoslope.h"
 
#include "tunnelbridge_map.h"
 
#include "window_func.h"
 
#include "strings_func.h"
 
#include "vehicle_func.h"
 
#include "sound_func.h"
 
#include "tunnelbridge.h"
 
#include "cheat_type.h"
 
#include "functions.h"
 
#include "effectvehicle_func.h"
 
#include "effectvehicle_base.h"
 
#include "elrail_func.h"
 
#include "roadveh.h"
 
#include "town.h"
 
#include "company_base.h"
 
#include "core/random_func.hpp"
 
#include "newgrf_railtype.h"
 
#include "date_func.h"
 

	
 
#include "table/strings.h"
 

	
 
/**
 
 * Verify whether a road vehicle is available.
 
 * @return \c true if at least one road vehicle is available, \c false if not
 
 */
 
bool RoadVehiclesAreBuilt()
 
{
 
	const RoadVehicle *rv;
 
	FOR_ALL_ROADVEHICLES(rv) return true;
 

	
 
	return false;
 
}
 

	
 
#define M(x) (1 << (x))
 
/* Level crossings may only be built on these slopes */
 
static const uint32 VALID_LEVEL_CROSSING_SLOPES = (M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT));
 
#undef M
 

	
 
/* Invalid RoadBits on slopes  */
 
static const RoadBits _invalid_tileh_slopes_road[2][15] = {
 
	/* The inverse of the mixable RoadBits on a leveled slope */
 
	{
 
		ROAD_NONE,         // SLOPE_FLAT
 
		ROAD_NE | ROAD_SE, // SLOPE_W
 
		ROAD_NE | ROAD_NW, // SLOPE_S
 

	
 
		ROAD_NE,           // SLOPE_SW
 
		ROAD_NW | ROAD_SW, // SLOPE_E
 
		ROAD_NONE,         // SLOPE_EW
 

	
 
		ROAD_NW,           // SLOPE_SE
 
		ROAD_NONE,         // SLOPE_WSE
 
		ROAD_SE | ROAD_SW, // SLOPE_N
 

	
 
		ROAD_SE,           // SLOPE_NW
 
		ROAD_NONE,         // SLOPE_NS
 
		ROAD_NONE,         // SLOPE_ENW
 

	
 
		ROAD_SW,           // SLOPE_NE
 
		ROAD_NONE,         // SLOPE_SEN
 
		ROAD_NONE          // SLOPE_NWS
 
	},
 
	/* The inverse of the allowed straight roads on a slope
 
	 * (with and without a foundation). */
 
	{
 
		ROAD_NONE, // SLOPE_FLAT
 
		ROAD_NONE, // SLOPE_W    Foundation
 
		ROAD_NONE, // SLOPE_S    Foundation
 

	
 
		ROAD_Y,    // SLOPE_SW
 
		ROAD_NONE, // SLOPE_E    Foundation
 
		ROAD_ALL,  // SLOPE_EW
 

	
 
		ROAD_X,    // SLOPE_SE
 
		ROAD_ALL,  // SLOPE_WSE
 
		ROAD_NONE, // SLOPE_N    Foundation
 

	
 
		ROAD_X,    // SLOPE_NW
 
		ROAD_ALL,  // SLOPE_NS
 
		ROAD_ALL,  // SLOPE_ENW
 

	
 
		ROAD_Y,    // SLOPE_NE
 
		ROAD_ALL,  // SLOPE_SEN
 
		ROAD_ALL   // SLOPE_NW
 
	}
 
};
src/slope_type.h
Show inline comments
 
@@ -34,76 +34,81 @@ enum Corner {
 
/**
 
 * Enumeration for the slope-type.
 
 *
 
 * This enumeration use the chars N,E,S,W corresponding the
 
 * direction north, east, south and west. The top corner of a tile
 
 * is the north-part of the tile. The whole slope is encoded with
 
 * 5 bits, 4 bits for each corner and 1 bit for a steep-flag.
 
 *
 
 * For halftile slopes an extra 3 bits are used to represent this
 
 * properly; 1 bit for a halftile-flag and 2 bits to encode which
 
 * extra side (corner) is leveled when the slope of the first 5
 
 * bits is applied. This means that there can only be one leveled
 
 * slope for steep slopes, which is logical because two leveled
 
 * slopes would mean that it is not a steep slope as halftile
 
 * slopes only span one height level.
 
 */
 
enum Slope {
 
	SLOPE_FLAT     = 0x00,                                  ///< a flat tile
 
	SLOPE_W        = 0x01,                                  ///< the west corner of the tile is raised
 
	SLOPE_S        = 0x02,                                  ///< the south corner of the tile is raised
 
	SLOPE_E        = 0x04,                                  ///< the east corner of the tile is raised
 
	SLOPE_N        = 0x08,                                  ///< the north corner of the tile is raised
 
	SLOPE_STEEP    = 0x10,                                  ///< indicates the slope is steep
 
	SLOPE_NW       = SLOPE_N | SLOPE_W,                     ///< north and west corner are raised
 
	SLOPE_SW       = SLOPE_S | SLOPE_W,                     ///< south and west corner are raised
 
	SLOPE_SE       = SLOPE_S | SLOPE_E,                     ///< south and east corner are raised
 
	SLOPE_NE       = SLOPE_N | SLOPE_E,                     ///< north and east corner are raised
 
	SLOPE_EW       = SLOPE_E | SLOPE_W,                     ///< east and west corner are raised
 
	SLOPE_NS       = SLOPE_N | SLOPE_S,                     ///< north and south corner are raised
 
	SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W, ///< bit mask containing all 'simple' slopes
 
	SLOPE_NWS      = SLOPE_N | SLOPE_W | SLOPE_S,           ///< north, west and south corner are raised
 
	SLOPE_WSE      = SLOPE_W | SLOPE_S | SLOPE_E,           ///< west, south and east corner are raised
 
	SLOPE_SEN      = SLOPE_S | SLOPE_E | SLOPE_N,           ///< south, east and north corner are raised
 
	SLOPE_ENW      = SLOPE_E | SLOPE_N | SLOPE_W,           ///< east, north and west corner are raised
 
	SLOPE_STEEP_W  = SLOPE_STEEP | SLOPE_NWS,               ///< a steep slope falling to east (from west)
 
	SLOPE_STEEP_S  = SLOPE_STEEP | SLOPE_WSE,               ///< a steep slope falling to north (from south)
 
	SLOPE_STEEP_E  = SLOPE_STEEP | SLOPE_SEN,               ///< a steep slope falling to west (from east)
 
	SLOPE_STEEP_N  = SLOPE_STEEP | SLOPE_ENW,               ///< a steep slope falling to south (from north)
 

	
 
	SLOPE_HALFTILE = 0x20,                                  ///< one halftile is leveled (non continuous slope)
 
	SLOPE_HALFTILE_MASK = 0xE0,                             ///< three bits used for halftile slopes
 
	SLOPE_HALFTILE_W = SLOPE_HALFTILE | (CORNER_W << 6),    ///< the west halftile is leveled (non continuous slope)
 
	SLOPE_HALFTILE_S = SLOPE_HALFTILE | (CORNER_S << 6),    ///< the south halftile is leveled (non continuous slope)
 
	SLOPE_HALFTILE_E = SLOPE_HALFTILE | (CORNER_E << 6),    ///< the east halftile is leveled (non continuous slope)
 
	SLOPE_HALFTILE_N = SLOPE_HALFTILE | (CORNER_N << 6),    ///< the north halftile is leveled (non continuous slope)
 
};
 
DECLARE_ENUM_AS_BIT_SET(Slope)
 

	
 
#define M(x) (1 << (x))
 
/** Constant bitset with safe slopes for building a level crossing. */
 
static const uint32 VALID_LEVEL_CROSSING_SLOPES = M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT);
 
#undef M
 

	
 

	
 
/**
 
 * Enumeration for Foundations.
 
 */
 
enum Foundation {
 
	FOUNDATION_NONE,             ///< The tile has no foundation, the slope remains unchanged.
 
	FOUNDATION_LEVELED,          ///< The tile is leveled up to a flat slope.
 
	FOUNDATION_INCLINED_X,       ///< The tile has an along X-axis inclined foundation.
 
	FOUNDATION_INCLINED_Y,       ///< The tile has an along Y-axis inclined foundation.
 
	FOUNDATION_STEEP_LOWER,      ///< The tile has a steep slope. The lowest corner is raised by a foundation to allow building railroad on the lower halftile.
 

	
 
	/* Halftile foundations */
 
	FOUNDATION_STEEP_BOTH,       ///< The tile has a steep slope. The lowest corner is raised by a foundation and the upper halftile is leveled.
 
	FOUNDATION_HALFTILE_W,       ///< Level west halftile non-continuously.
 
	FOUNDATION_HALFTILE_S,       ///< Level south halftile non-continuously.
 
	FOUNDATION_HALFTILE_E,       ///< Level east halftile non-continuously.
 
	FOUNDATION_HALFTILE_N,       ///< Level north halftile non-continuously.
 

	
 
	/* Special anti-zig-zag foundations for single horizontal/vertical track */
 
	FOUNDATION_RAIL_W,           ///< Foundation for TRACK_BIT_LEFT, but not a leveled foundation.
 
	FOUNDATION_RAIL_S,           ///< Foundation for TRACK_BIT_LOWER, but not a leveled foundation.
 
	FOUNDATION_RAIL_E,           ///< Foundation for TRACK_BIT_RIGHT, but not a leveled foundation.
 
	FOUNDATION_RAIL_N,           ///< Foundation for TRACK_BIT_UPPER, but not a leveled foundation.
 

	
 
	FOUNDATION_INVALID = 0xFF    ///< Used inside "rail_cmd.cpp" to indicate invalid slope/track combination.
 
};
 

	
 
#endif /* SLOPE_TYPE_H */
0 comments (0 inline, 0 general)