Changeset - r7770:09918df1f6fd
[Not reviewed]
master
0 4 0
rubidium - 17 years ago 2007-10-20 21:04:14
rubidium@openttd.org
(svn r11319) -Add: halftile- and anti-zig-zag-foundations. Patch by frosch.
4 files changed with 273 insertions and 88 deletions:
0 comments (0 inline, 0 general)
src/landscape.cpp
Show inline comments
 
@@ -76,6 +76,16 @@ uint ApplyFoundationToSlope(Foundation f
 
		return TILE_HEIGHT;
 
	}
 

	
 
	if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
 
		*s = HalftileSlope(*s, GetHalftileFoundationCorner(f));
 
		return 0;
 
	}
 

	
 
	if (IsSpecialRailFoundation(f)) {
 
		*s = SlopeWithThreeCornersRaised(OppositeCorner(GetRailFoundationCorner(f)));
 
		return 0;
 
	}
 

	
 
	uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
 
	Corner highest_corner = GetHighestSlopeCorner(*s);
 

	
 
@@ -92,8 +102,8 @@ uint ApplyFoundationToSlope(Foundation f
 
			*s = SlopeWithOneCornerRaised(highest_corner);
 
			break;
 

	
 
		case FOUNDATION_STEEP_HIGHER:
 
			*s = SlopeWithThreeCornersRaised(OppositeCorner(highest_corner));
 
		case FOUNDATION_STEEP_BOTH:
 
			*s = HalftileSlope(SlopeWithOneCornerRaised(highest_corner), highest_corner);
 
			break;
 

	
 
		default: NOT_REACHED();
 
@@ -229,6 +239,24 @@ uint GetSlopeZ(int x, int y)
 
}
 

	
 
/**
 
 * Determine the Z height of a corner relative to TileZ.
 
 *
 
 * @pre The slope must not be a halftile slope.
 
 *
 
 * @param tileh The slope.
 
 * @param corner The corner.
 
 * @return Z position of corner relative to TileZ.
 
 */
 
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);
 
}
 

	
 
/**
 
 * Determine the Z height of the corners of a specific tile edge
 
 *
 
 * @note If a tile has a non-continuous halftile foundation, a corner can have different heights wrt. it's edges.
 
@@ -308,6 +336,9 @@ void DrawFoundation(TileInfo *ti, Founda
 
{
 
	if (!IsFoundation(f)) return;
 

	
 
	/* Two part foundations must be drawn separately */
 
	assert(f != FOUNDATION_STEEP_BOTH);
 

	
 
	uint sprite_block = 0;
 
	uint z;
 
	Slope slope = GetFoundationSlope(ti->tile, &z);
 
@@ -324,13 +355,15 @@ void DrawFoundation(TileInfo *ti, Founda
 
	/* Use the original slope sprites if NW and NE borders should be visible */
 
	SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * SPR_TRKFOUND_BLOCK_SIZE));
 
	SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SPR_SLOPES_INCLINED_OFFSET + sprite_block * SPR_TRKFOUND_BLOCK_SIZE;
 
	//SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
 
	SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
 

	
 
	if (IsSteepSlope(ti->tileh)) {
 
		/* Lower part of foundation */
 
		AddSortableSpriteToDraw(
 
			leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
 
		);
 
		if (!IsNonContinuousFoundation(f)) {
 
			/* Lower part of foundation */
 
			AddSortableSpriteToDraw(
 
				leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
 
			);
 
		}
 

	
 
		Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
 
		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
 
@@ -341,24 +374,42 @@ void DrawFoundation(TileInfo *ti, Founda
 

	
 
			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 
			OffsetGroundSprite(31, 9);
 
		} else if (f >= FOUNDATION_STEEP_HIGHER) {
 
			/* three corners raised:
 
			 * Draw inclined foundations for both axes, that results in the needed image.
 
			 */
 
			SpriteID upper = inclined_base + highest_corner * 2;
 

	
 
			AddSortableSpriteToDraw(upper, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 
			AddChildSpriteScreen(upper + 1, PAL_NONE, 31, 9);
 
			OffsetGroundSprite(31, 9);
 
		} else {
 
		} else if (f == FOUNDATION_STEEP_LOWER) {
 
			/* one corner raised */
 
			OffsetGroundSprite(31, 1);
 
		} else {
 
			/* halftile foundation */
 
			int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0);
 
			int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0);
 

	
 
			AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT);
 
			OffsetGroundSprite(31, 9);
 
		}
 
	} else {
 
		if (IsLeveledFoundation(f)) {
 
			/* leveled foundation */
 
			AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
 
			OffsetGroundSprite(31, 1);
 
		} else if (IsNonContinuousFoundation(f)) {
 
			/* halftile foundation */
 
			Corner halftile_corner = GetHalftileFoundationCorner(f);
 
			int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0);
 
			int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0);
 

	
 
			AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z);
 
			OffsetGroundSprite(31, 9);
 
		} else if (IsSpecialRailFoundation(f)) {
 
			/* anti-zig-zag foundation */
 
			SpriteID spr;
 
			if (ti->tileh == SLOPE_NS || ti->tileh == SLOPE_EW) {
 
				/* half of leveled foundation under track corner */
 
				spr = leveled_base + SlopeWithThreeCornersRaised(GetRailFoundationCorner(f));
 
			} else {
 
				/* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
 
				spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
 
			}
 
			AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
 
			OffsetGroundSprite(31, 9);
 
		} else {
 
			/* inclined foundation */
 
			byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
src/landscape.h
Show inline comments
 
@@ -26,6 +26,7 @@ bool IsValidTile(TileIndex tile);
 
uint GetPartialZ(int x, int y, Slope corners);
 
uint GetSlopeZ(int x, int y);
 
void GetSlopeZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2);
 
int GetSlopeZInCorner(Slope tileh, Corner corner);
 

	
 
static inline Point RemapCoords(int x, int y, int z)
 
{
src/rail_cmd.cpp
Show inline comments
 
@@ -215,19 +215,35 @@ Foundation GetRailFoundation(Slope tileh
 
		TrackBits higher_track = CornerToTrackBits(highest_corner);
 

	
 
		/* Only higher track? */
 
		if (bits == higher_track) return FOUNDATION_STEEP_HIGHER;
 
		if (bits == higher_track) return HalftileFoundation(highest_corner);
 

	
 
		/* 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);
 
		return ((bits & higher_track) != 0 ? FOUNDATION_STEEP_BOTH : 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);
 

	
 
		Corner track_corner;
 
		switch (bits) {
 
			case TRACK_BIT_LEFT:  track_corner = CORNER_W; break;
 
			case TRACK_BIT_LOWER: track_corner = CORNER_S; break;
 
			case TRACK_BIT_RIGHT: track_corner = CORNER_E; break;
 
			case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
 

	
 
			case TRACK_BIT_HORZ:
 
				if (tileh == SLOPE_N) return HalftileFoundation(CORNER_N);
 
				if (tileh == SLOPE_S) return HalftileFoundation(CORNER_S);
 
				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
 

	
 
			case TRACK_BIT_VERT:
 
				if (tileh == SLOPE_W) return HalftileFoundation(CORNER_W);
 
				if (tileh == SLOPE_E) return HalftileFoundation(CORNER_E);
 
				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
 

	
 
			case TRACK_BIT_X:
 
				if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X;
 
				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
 
@@ -239,6 +255,19 @@ Foundation GetRailFoundation(Slope tileh
 
			default:
 
				return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
 
		}
 
		/* Single diagonal track */
 

	
 
		/* Track must be at least valid on leveled foundation */
 
		if (!valid_on_leveled) return FOUNDATION_INVALID;
 

	
 
		/* If slope has three raised corners, build leveled foundation */
 
		if (HasSlopeHighestCorner(ComplementSlope(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);
 

	
 
		/* else special anti-zig-zag foundation */
 
		return SpecialRailFoundation(track_corner);
 
	}
 
}
 

	
 
@@ -1422,41 +1451,64 @@ static void DrawTrackDetails(const TileI
 
static void DrawTrackBits(TileInfo* ti, TrackBits track)
 
{
 
	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
	RailGroundType rgt = GetRailGroundType(ti->tile);
 
	Foundation f = GetRailFoundation(ti->tileh, track);
 
	Corner halftile_corner = CORNER_INVALID;
 

	
 
	if (IsNonContinuousFoundation(f)) {
 
		/* Save halftile corner */
 
		halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f));
 
		/* Draw lower part first */
 
		track &= ~CornerToTrackBits(halftile_corner);
 
		f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE);
 
	}
 

	
 
	DrawFoundation(ti, f);
 
	/* DrawFoundation modifies ti */
 

	
 
	SpriteID image;
 
	SpriteID pal = PAL_NONE;
 
	bool junction = false;
 

	
 
	/* Select the sprite to use. */
 
	(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
 
	(image++,                           track == TRACK_BIT_X) ||
 
	(image++,                           track == TRACK_BIT_UPPER) ||
 
	(image++,                           track == TRACK_BIT_LOWER) ||
 
	(image++,                           track == TRACK_BIT_RIGHT) ||
 
	(image++,                           track == TRACK_BIT_LEFT) ||
 
	(image++,                           track == TRACK_BIT_CROSS) ||
 

	
 
	(image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) ||
 
	(image++,                            track == TRACK_BIT_VERT) ||
 
	if (track == 0) {
 
		/* Clear ground (only track on halftile foundation) */
 
		switch (rgt) {
 
			case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
 
			case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOWY_TILE; break;
 
			default:                     image = SPR_FLAT_GRASS_TILE; break;
 
		}
 
		image += _tileh_to_sprite[ti->tileh];
 
	} else {
 
		if (ti->tileh != SLOPE_FLAT) {
 
			/* track on non-flat ground */
 
			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
 
		} else {
 
			/* track on flat ground */
 
			(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
 
			(image++,                           track == TRACK_BIT_X) ||
 
			(image++,                           track == TRACK_BIT_UPPER) ||
 
			(image++,                           track == TRACK_BIT_LOWER) ||
 
			(image++,                           track == TRACK_BIT_RIGHT) ||
 
			(image++,                           track == TRACK_BIT_LEFT) ||
 
			(image++,                           track == TRACK_BIT_CROSS) ||
 

	
 
	(junction = true, false) ||
 
	(image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) ||
 
	(image++,                          (track & TRACK_BIT_3WAY_SW) == 0) ||
 
	(image++,                          (track & TRACK_BIT_3WAY_NW) == 0) ||
 
	(image++,                          (track & TRACK_BIT_3WAY_SE) == 0) ||
 
	(image++, true);
 

	
 
	if (ti->tileh != SLOPE_FLAT) {
 
		DrawFoundation(ti, GetRailFoundation(ti->tileh, track));
 
			(image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) ||
 
			(image++,                            track == TRACK_BIT_VERT) ||
 

	
 
		/* DrawFoundation() modifies it.
 
		 * Default sloped sprites.. */
 
		if (ti->tileh != SLOPE_FLAT) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
 
	}
 
			(junction = true, false) ||
 
			(image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) ||
 
			(image++,                          (track & TRACK_BIT_3WAY_SW) == 0) ||
 
			(image++,                          (track & TRACK_BIT_3WAY_NW) == 0) ||
 
			(image++,                          (track & TRACK_BIT_3WAY_SE) == 0) ||
 
			(image++, true);
 
		}
 

	
 
	switch (GetRailGroundType(ti->tile)) {
 
		case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
 
		case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break;
 
		default: break;
 
		switch (rgt) {
 
			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
 
			case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset;  break;
 
			default: break;
 
		}
 
	}
 

	
 
	DrawGroundSprite(image, pal);
 
@@ -1470,6 +1522,30 @@ static void DrawTrackBits(TileInfo* ti, 
 
		if (track & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE);
 
		if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE);
 
	}
 

	
 
	if (IsValidCorner(halftile_corner)) {
 
		DrawFoundation(ti, HalftileFoundation(halftile_corner));
 

	
 
		/* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
 
		Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
 
		image = _track_sloped_sprites[fake_slope - 1] + rti->base_sprites.track_y;
 
		pal = PAL_NONE;
 
		switch (rgt) {
 
			case RAIL_GROUND_BARREN:     pal = PALETTE_TO_BARE_LAND; break;
 
			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]));
 
	}
 
}
 

	
 
static void DrawSignals(TileIndex tile, TrackBits rails)
 
@@ -2289,52 +2365,24 @@ static CommandCost TerraformTile_Track(T
 
		CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);
 

	
 
		/* When there is only a single horizontal/vertical track, one corner can be terraformed. */
 
		Slope allowed_corner;
 
		Corner allowed_corner;
 
		switch (rail_bits) {
 
			case TRACK_BIT_RIGHT: allowed_corner = SLOPE_W; break;
 
			case TRACK_BIT_UPPER: allowed_corner = SLOPE_S; break;
 
			case TRACK_BIT_LEFT:  allowed_corner = SLOPE_E; break;
 
			case TRACK_BIT_LOWER: allowed_corner = SLOPE_N; break;
 
			case TRACK_BIT_RIGHT: allowed_corner = CORNER_W; break;
 
			case TRACK_BIT_UPPER: allowed_corner = CORNER_S; break;
 
			case TRACK_BIT_LEFT:  allowed_corner = CORNER_E; break;
 
			case TRACK_BIT_LOWER: allowed_corner = CORNER_N; break;
 
			default: return autoslope_result;
 
		}
 

	
 
		Slope track_corners = ComplementSlope(allowed_corner);
 

	
 
		Foundation f_old = GetRailFoundation(tileh_old, rail_bits);
 
		switch (f_old) {
 
			case FOUNDATION_NONE:
 
				/* Everything is valid, which only changes allowed_corner */
 

	
 
				/* Compute height of track */
 
				if (tileh_old == track_corners) z_old += TILE_HEIGHT;
 
				if (tileh_new == track_corners) {
 
					z_new += TILE_HEIGHT;
 
				} else {
 
					/* do not build a foundation */
 
					if ((tileh_new != SLOPE_FLAT) && (tileh_new != allowed_corner)) return autoslope_result;
 
				}
 
		/* Do not allow terraforming if allowed_corner is part of anti-zig-zag foundations */
 
		if (tileh_old != SLOPE_NS && tileh_old != SLOPE_EW && IsSpecialRailFoundation(f_old)) return autoslope_result;
 

	
 
				/* Track height must remain unchanged */
 
				if (z_old != z_new) return autoslope_result;
 
				break;
 

	
 
			case FOUNDATION_LEVELED:
 
				/* Is allowed_corner covered by the foundation? */
 
				if ((tileh_old & allowed_corner) == 0) return autoslope_result;
 

	
 
				/* allowed_corner may only be raised -> steep slope */
 
				if ((z_old != z_new) || (tileh_new != (tileh_old | SLOPE_STEEP))) return autoslope_result;
 
				break;
 

	
 
			case FOUNDATION_STEEP_LOWER:
 
				/* Only allow to lower highest corner */
 
				if ((z_old != z_new) || (tileh_new != (tileh_old & ~SLOPE_STEEP))) return autoslope_result;
 
				break;
 

	
 
			case FOUNDATION_STEEP_HIGHER:
 
				return autoslope_result;
 

	
 
			default: NOT_REACHED();
 
		/* Everything is valid, which only changes allowed_corner */
 
		for (Corner corner = (Corner)0; corner < CORNER_END; corner = (Corner)(corner + 1)) {
 
			if (allowed_corner == corner) continue;
 
			if (z_old + GetSlopeZInCorner(tileh_old, corner) != z_new + GetSlopeZInCorner(tileh_new, corner)) return autoslope_result;
 
		}
 

	
 
		/* Make the ground dirty */
src/slope.h
Show inline comments
 
@@ -16,7 +16,8 @@ enum Corner {
 
	CORNER_S = 1,
 
	CORNER_E = 2,
 
	CORNER_N = 3,
 
	CORNER_END
 
	CORNER_END,
 
	CORNER_INVALID = 0xFF
 
};
 

	
 
/**
 
@@ -234,8 +235,20 @@ enum Foundation {
 
	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 lowerst corner is raised by a foundation to allow building railroad on the lower halftile.
 
	FOUNDATION_STEEP_HIGHER,     ///< The tile has a steep slope. Three corners are raised by a foundation to allow building railroad on the higher halftile.
 
	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.
 
};
 
@@ -274,6 +287,54 @@ static inline bool IsInclinedFoundation(
 
}
 

	
 
/**
 
 * Tests if a foundation is a non-continuous foundation, i.e. halftile-foundation or FOUNDATION_STEEP_BOTH.
 
 *
 
 * @param f  The #Foundation.
 
 * @return   true iff f is a non-continuous foundation
 
 */
 
static inline bool IsNonContinuousFoundation(Foundation f)
 
{
 
	return IS_INT_INSIDE(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1);
 
}
 

	
 
/**
 
 * Returns the halftile corner of a halftile-foundation
 
 *
 
 * @pre f != FOUNDATION_STEEP_BOTH
 
 *
 
 * @param f  The #Foundation.
 
 * @return   The #Corner with track.
 
 */
 
static inline Corner GetHalftileFoundationCorner(Foundation f)
 
{
 
	assert(IS_INT_INSIDE(f, FOUNDATION_HALFTILE_W, FOUNDATION_HALFTILE_N + 1));
 
	return (Corner)(f - FOUNDATION_HALFTILE_W);
 
}
 

	
 
/**
 
 * Tests if a foundation is a special rail foundation for single horizontal/vertical track.
 
 *
 
 * @param f  The #Foundation.
 
 * @return   true iff f is a special rail foundation for single horizontal/vertical track.
 
 */
 
static inline bool IsSpecialRailFoundation(Foundation f)
 
{
 
	return IS_INT_INSIDE(f, FOUNDATION_RAIL_W, FOUNDATION_RAIL_N + 1);
 
}
 

	
 
/**
 
 * Returns the track corner of a special rail foundation
 
 *
 
 * @param f  The #Foundation.
 
 * @return   The #Corner with track.
 
 */
 
static inline Corner GetRailFoundationCorner(Foundation f)
 
{
 
	assert(IsSpecialRailFoundation(f));
 
	return (Corner)(f - FOUNDATION_RAIL_W);
 
}
 

	
 
/**
 
 * Returns the foundation needed to flatten a slope.
 
 * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED.
 
 *
 
@@ -298,4 +359,28 @@ static inline Foundation InclinedFoundat
 
	return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
 
}
 

	
 
/**
 
 * Returns the halftile foundation for single horizontal/vertical track.
 
 *
 
 * @param corner The #Corner with the track.
 
 * @return       The wanted #Foundation.
 
 */
 
static inline Foundation HalftileFoundation(Corner corner)
 
{
 
	assert(IsValidCorner(corner));
 
	return (Foundation)(FOUNDATION_HALFTILE_W + corner);
 
}
 

	
 
/**
 
 * Returns the special rail foundation for single horizontal/vertical track.
 
 *
 
 * @param corner The #Corner with the track.
 
 * @return       The wanted #Foundation.
 
 */
 
static inline Foundation SpecialRailFoundation(Corner corner)
 
{
 
	assert(IsValidCorner(corner));
 
	return (Foundation)(FOUNDATION_RAIL_W + corner);
 
}
 

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