(svn r10698) -Codechange [FS#1082]: simplify the code related to foundations. Primarily removal of (duplicated|magic) code and introduction of few helper functions to ease foundation determination. Patch by frosch.

This commit is contained in:
rubidium 2007-07-26 16:51:10 +00:00
parent 5bd241eb5b
commit d624f66c79
23 changed files with 274 additions and 246 deletions

View File

@ -362,9 +362,9 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
}
extern uint GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
extern uint GetRoadFoundation(Slope tileh, RoadBits bits); // XXX function declaration in .c
extern uint GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
extern Foundation GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
extern Foundation GetRoadFoundation(Slope tileh, RoadBits bits); // XXX function declaration in .c
extern Foundation GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
enum BridgeFoundation {
BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
};
@ -373,7 +373,7 @@ enum BridgeFoundation {
static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
{
Ai_PathFinderInfo *PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
int r, res = 0;
int res = 0;
Slope tileh = GetTileSlope(current->tile, NULL);
Slope parent_tileh = GetTileSlope(parent->path.node.tile, NULL);
@ -409,17 +409,17 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
// Skip if the tile was from a bridge or tunnel
if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
if (PathFinderInfo->rail_or_road) {
r = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
Foundation f = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
if (IS_INT_INSIDE(r, 15, 15 + 8) || (r == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
if (IsInclinedFoundation(f) || (!IsFoundation(f) && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
} else {
res += AI_PATHFINDER_FOUNDATION_PENALTY;
}
} else {
if (!IsRoad(parent->path.node.tile) || !IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE)) {
r = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
if (IS_INT_INSIDE(r, 15, 15 + 8) || (r == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
Foundation f = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
if (IsInclinedFoundation(f) || (!IsFoundation(f) == 0 && HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh))) {
res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
} else {
res += AI_PATHFINDER_FOUNDATION_PENALTY;
@ -431,6 +431,7 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
// Are we part of a tunnel?
if ((AI_PATHFINDER_FLAG_TUNNEL & current->user_data[0]) != 0) {
int r;
// Tunnels are very expensive when build on long routes..
// Ironicly, we are using BridgeCode here ;)
r = AI_PATHFINDER_TUNNEL_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
@ -444,13 +445,13 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
// Check if we are going up or down, first for the starting point
// In user_data[0] is at the 8th bit the direction
if (!HASBIT(BRIDGE_NO_FOUNDATION, parent_tileh)) {
if (GetBridgeFoundation(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1)) < 15) {
if (IsLeveledFoundation(GetBridgeFoundation(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
}
}
// Second for the end point
if (!HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
if (GetBridgeFoundation(tileh, (Axis)((current->user_data[0] >> 8) & 1)) < 15) {
if (IsLeveledFoundation(GetBridgeFoundation(tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
}
}

View File

@ -27,7 +27,7 @@ struct Bridge {
extern const Bridge orig_bridge[MAX_BRIDGES];
extern Bridge _bridge[MAX_BRIDGES];
uint GetBridgeFoundation(Slope tileh, Axis axis);
Foundation GetBridgeFoundation(Slope tileh, Axis axis);
static inline const Bridge *GetBridge(uint i)
{

View File

@ -573,9 +573,9 @@ static uint GetSlopeZ_Clear(TileIndex tile, uint x, uint y)
return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
}
static Slope GetSlopeTileh_Clear(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Clear(TileIndex tile, Slope tileh)
{
return tileh;
return FOUNDATION_NONE;
}
static void GetAcceptedCargo_Clear(TileIndex tile, AcceptedCargo ac)
@ -819,5 +819,5 @@ extern const TileTypeProcs _tile_type_clear_procs = {
ChangeTileOwner_Clear, ///< change_tile_owner_clear
NULL, ///< get_produced_cargo_proc
NULL, ///< vehicle_enter_tile_proc
GetSlopeTileh_Clear, ///< get_slope_tileh_proc
GetFoundation_Clear, ///< get_foundation_proc
};

View File

@ -21,9 +21,9 @@ static uint GetSlopeZ_Dummy(TileIndex tile, uint x, uint y)
return 0;
}
static Slope GetSlopeTileh_Dummy(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Dummy(TileIndex tile, Slope tileh)
{
return SLOPE_FLAT;
return FOUNDATION_NONE;
}
static CommandCost ClearTile_Dummy(TileIndex tile, byte flags)
@ -81,5 +81,5 @@ extern const TileTypeProcs _tile_type_dummy_procs = {
ChangeTileOwner_Dummy, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
NULL, /* vehicle_enter_tile_proc */
GetSlopeTileh_Dummy, /* get_slope_tileh_proc */
GetFoundation_Dummy, /* get_foundation_proc */
};

View File

@ -176,7 +176,7 @@ static void DrawCatenaryRailway(const TileInfo *ti)
for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
uint foundation = 0;
Foundation foundation = FOUNDATION_NONE;
int k;
/* Here's one of the main headaches. GetTileSlope does not correct for possibly
@ -225,9 +225,7 @@ static void DrawCatenaryRailway(const TileInfo *ti)
foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour)));
}
if (foundation != 0) {
tileh[TS_NEIGHBOUR] = foundation < 15 ? SLOPE_FLAT : _inclined_tileh[foundation - 15];
}
ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);

View File

@ -255,7 +255,6 @@ static void DrawTile_Industry(TileInfo *ti)
Industry *ind = GetIndustryByTile(ti->tile);
const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
const DrawBuildingsTileStruct *dits;
byte z;
SpriteID image;
SpriteID pal;
@ -287,12 +286,8 @@ static void DrawTile_Industry(TileInfo *ti)
pal = dits->ground.pal;
}
z = ti->z;
/* Add bricks below the industry? */
if (ti->tileh != SLOPE_FLAT) {
DrawFoundation(ti, ti->tileh);
z += TILE_HEIGHT;
}
/* DrawFoundation() modifes ti->z and ti->tileh */
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
DrawGroundSprite(image, pal);
@ -306,7 +301,7 @@ static void DrawTile_Industry(TileInfo *ti)
dits->width + 1,
dits->height + 1,
dits->dz,
z,
ti->z,
HASBIT(_transparent_opt, TO_INDUSTRIES));
if (HASBIT(_transparent_opt, TO_INDUSTRIES)) return;
@ -323,9 +318,9 @@ static uint GetSlopeZ_Industry(TileIndex tile, uint x, uint y)
return GetTileMaxZ(tile);
}
static Slope GetSlopeTileh_Industry(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
{
return SLOPE_FLAT;
return FlatteningFoundation(tileh);
}
static void GetAcceptedCargo_Industry(TileIndex tile, AcceptedCargo ac)
@ -1995,7 +1990,7 @@ extern const TileTypeProcs _tile_type_industry_procs = {
ChangeTileOwner_Industry, /* change_tile_owner_proc */
GetProducedCargo_Industry, /* get_produced_cargo_proc */
NULL, /* vehicle_enter_tile_proc */
GetSlopeTileh_Industry, /* get_slope_tileh_proc */
GetFoundation_Industry, /* get_foundation_proc */
};
static const SaveLoad _industry_desc[] = {

View File

@ -56,14 +56,52 @@ const byte _tileh_to_sprite[32] = {
0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
};
const Slope _inclined_tileh[] = {
SLOPE_SW, SLOPE_NW, SLOPE_SW, SLOPE_SE, SLOPE_NE, SLOPE_SE, SLOPE_NE, SLOPE_NW,
SLOPE_E, SLOPE_N, SLOPE_W, SLOPE_S,
SLOPE_NWS, SLOPE_WSE, SLOPE_SEN, SLOPE_ENW
};
SnowLine *_snow_line = NULL;
/**
* Applys a foundation to a slope.
*
* @pre Foundation and slope must be valid combined.
* @param f The #Foundation.
* @param s The #Slope to modify.
* @return Increment to the tile Z coordinate.
*/
uint ApplyFoundationToSlope(Foundation f, Slope *s)
{
if (!IsFoundation(f)) return 0;
if (IsLeveledFoundation(f)) {
*s = SLOPE_FLAT;
return TILE_HEIGHT;
}
uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
byte highest_corner = GetHighestSlopeCorner(*s);
switch (f) {
case FOUNDATION_INCLINED_X:
*s = (highest_corner <= 1 ? SLOPE_SW : SLOPE_NE);
break;
case FOUNDATION_INCLINED_Y:
*s = (((highest_corner == 1) || (highest_corner == 2)) ? SLOPE_SE : SLOPE_NW);
break;
case FOUNDATION_STEEP_LOWER:
*s = (Slope) (1 << highest_corner);
break;
case FOUNDATION_STEEP_HIGHER:
*s = (Slope) (*s & ~SLOPE_STEEP);
break;
default: NOT_REACHED();
}
return dz;
}
uint GetPartialZ(int x, int y, Slope corners)
{
int z = 0;
@ -172,11 +210,9 @@ uint GetSlopeZ(int x, int y)
static Slope GetFoundationSlope(TileIndex tile, uint* z)
{
Slope tileh = GetTileSlope(tile, z);
Slope slope = _tile_type_procs[GetTileType(tile)]->get_slope_tileh_proc(tile, tileh);
/* Flatter slope -> higher base height */
if (slope < tileh) *z += TILE_HEIGHT;
return slope;
Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh);
*z += ApplyFoundationToSlope(f, &tileh);
return tileh;
}
@ -212,34 +248,43 @@ static bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here)
}
void DrawFoundation(TileInfo *ti, uint f)
void DrawFoundation(TileInfo *ti, Foundation f)
{
SpriteID sprite_base = SPR_SLOPES_BASE - 15;
Slope slope;
uint z;
if (!IsFoundation(f)) return;
slope = GetFoundationSlope(ti->tile, &z);
if (!HasFoundationNW(ti->tile, slope, z)) sprite_base += 22;
if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += 44;
SpriteID sprite_base = SPR_SLOPES_VIRTUAL_BASE;
uint z;
Slope slope = GetFoundationSlope(ti->tile, &z);
if (!HasFoundationNW(ti->tile, slope, z)) sprite_base += SPR_SLOPES_NO_FOUNDATION_NW_OFFSET;
if (!HasFoundationNE(ti->tile, slope, z)) sprite_base += SPR_SLOPES_NO_FOUNDATION_NE_OFFSET;
if (IsSteepSlope(ti->tileh)) {
SpriteID lower_base;
/* Lower part of foundation */
/* Lower part of foundation
* Use the original slope sprites if NW and NE borders should be visible
*/
lower_base = sprite_base;
if (lower_base == SPR_SLOPES_BASE - 15) lower_base = SPR_FOUNDATION_BASE;
if (lower_base == SPR_SLOPES_VIRTUAL_BASE) lower_base = SPR_FOUNDATION_BASE;
AddSortableSpriteToDraw(
lower_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
);
ti->z += TILE_HEIGHT;
ti->tileh = _inclined_tileh[f - 15];
if (f < 15 + 8) {
/* inclined */
AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
byte highest_corner = GetHighestSlopeCorner(ti->tileh);
ti->z += ApplyFoundationToSlope(f, &ti->tileh);
if (IsInclinedFoundation(f)) {
/* inclined foundation */
byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
AddSortableSpriteToDraw(sprite_base + SPR_SLOPES_INCLINED_OFFSET + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
OffsetGroundSprite(31, 9);
} else if (f >= 15 + 8 + 4) {
/* three corners raised */
SpriteID upper = sprite_base + 15 + (f - 15 - 8 - 4) * 2;
} else if (f >= FOUNDATION_STEEP_HIGHER) {
/* three corners raised:
* Draw inclined foundations for both axes, that results in the needed image.
*/
SpriteID upper = sprite_base + SPR_SLOPES_INCLINED_OFFSET + highest_corner * 2;
AddSortableSpriteToDraw(upper, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
AddChildSpriteScreen(upper + 1, PAL_NONE, 31, 9);
@ -249,21 +294,22 @@ void DrawFoundation(TileInfo *ti, uint f)
OffsetGroundSprite(31, 1);
}
} else {
if (f < 15) {
if (IsLeveledFoundation(f)) {
/* leveled foundation
* Use the original slope sprites if NW and NE borders should be visible */
if (sprite_base == SPR_SLOPES_BASE - 15) sprite_base = SPR_FOUNDATION_BASE;
* Use the original slope sprites if NW and NE borders should be visible
*/
if (sprite_base == SPR_SLOPES_VIRTUAL_BASE) sprite_base = SPR_FOUNDATION_BASE;
AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
ti->z += TILE_HEIGHT;
ti->tileh = SLOPE_FLAT;
AddSortableSpriteToDraw(sprite_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
OffsetGroundSprite(31, 1);
} else {
/* inclined foundation */
AddSortableSpriteToDraw(sprite_base + f, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
ti->tileh = _inclined_tileh[f - 15];
byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
AddSortableSpriteToDraw(sprite_base + SPR_SLOPES_INCLINED_OFFSET + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
OffsetGroundSprite(31, 9);
}
ti->z += ApplyFoundationToSlope(f, &ti->tileh);
}
}

View File

@ -39,7 +39,8 @@ static inline Point RemapCoords2(int x, int y)
return RemapCoords(x, y, GetSlopeZ(x, y));
}
void DrawFoundation(TileInfo *ti, uint f);
uint ApplyFoundationToSlope(Foundation f, Slope *s);
void DrawFoundation(TileInfo *ti, Foundation f);
void DoClearSquare(TileIndex tile);
void RunTileLoop();

View File

@ -351,7 +351,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
const SpriteGroup *group;
ResolverObject object;
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
NewHouseResolver(&object, house_id, ti->tile, GetTownByTile(ti->tile));

View File

@ -215,7 +215,7 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus
draw_old_one = callback_res != 0;
}
if (draw_old_one) DrawFoundation(ti, ti->tileh);
if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
}
NewIndustryTileResolver(&object, gfx, ti->tile, i);

View File

@ -472,7 +472,7 @@ typedef void TileLoopProc(TileIndex tile);
typedef void ChangeTileOwnerProc(TileIndex tile, PlayerID old_player, PlayerID new_player);
/** @see VehicleEnterTileStatus to see what the return values mean */
typedef uint32 VehicleEnterTileProc(Vehicle *v, TileIndex tile, int x, int y);
typedef Slope GetSlopeTilehProc(TileIndex, Slope tileh);
typedef Foundation GetFoundationProc(TileIndex tile, Slope tileh);
struct TileTypeProcs {
DrawTileProc *draw_tile_proc;
@ -487,7 +487,7 @@ struct TileTypeProcs {
ChangeTileOwnerProc *change_tile_owner_proc;
GetProducedCargoProc *get_produced_cargo_proc;
VehicleEnterTileProc *vehicle_enter_tile_proc;
GetSlopeTilehProc *get_slope_tileh_proc;
GetFoundationProc *get_foundation_proc;
};

View File

@ -567,7 +567,7 @@ void DrawDefaultWaypointSprite(int x, int y, RailType railtype);
*/
void DrawCatenary(const TileInfo *ti);
uint GetRailFoundation(Slope tileh, TrackBits bits);
Foundation GetRailFoundation(Slope tileh, TrackBits bits);
int32 SettingsDisableElrail(int32 p1); ///< _patches.disable_elrail callback

View File

@ -156,36 +156,22 @@ static const TrackBits _valid_tileh_slopes[][15] = {
}
};
uint GetRailFoundation(Slope tileh, TrackBits bits)
Foundation GetRailFoundation(Slope tileh, TrackBits bits)
{
uint i;
if (!IsSteepSlope(tileh)) {
if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return 0;
if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return tileh;
if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return FOUNDATION_NONE;
if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return FOUNDATION_LEVELED;
}
switch (bits) {
default: NOT_REACHED();
case TRACK_BIT_X: i = 0; break;
case TRACK_BIT_Y: i = 1; break;
case TRACK_BIT_LEFT: return 15 + 8 + (tileh == SLOPE_STEEP_W ? 4 : 0);
case TRACK_BIT_LOWER: return 15 + 8 + (tileh == SLOPE_STEEP_S ? 5 : 1);
case TRACK_BIT_RIGHT: return 15 + 8 + (tileh == SLOPE_STEEP_E ? 6 : 2);
case TRACK_BIT_UPPER: return 15 + 8 + (tileh == SLOPE_STEEP_N ? 7 : 3);
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);
}
switch (tileh) {
case SLOPE_W:
case SLOPE_STEEP_W: i += 0; break;
case SLOPE_S:
case SLOPE_STEEP_S: i += 2; break;
case SLOPE_E:
case SLOPE_STEEP_E: i += 4; break;
case SLOPE_N:
case SLOPE_STEEP_N: i += 6; break;
default: return 0;
}
return i + 15;
}
@ -1362,14 +1348,11 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track)
(image++, true);
if (ti->tileh != SLOPE_FLAT) {
uint foundation = GetRailFoundation(ti->tileh, track);
if (foundation != 0) DrawFoundation(ti, foundation);
DrawFoundation(ti, GetRailFoundation(ti->tileh, track));
/* DrawFoundation() modifies it.
* Default sloped sprites.. */
if (ti->tileh != SLOPE_FLAT)
image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
if (ti->tileh != SLOPE_FLAT) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
}
switch (GetRailGroundType(ti->tile)) {
@ -1446,7 +1429,7 @@ static void DrawTile_Track(TileInfo *ti)
const DrawTileSeqStruct* dtss;
uint32 relocation;
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
if (IsRailDepot(ti->tile)) {
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
@ -1850,34 +1833,16 @@ static uint GetSlopeZ_Track(TileIndex tile, uint x, uint y)
if (tileh == SLOPE_FLAT) return z;
if (IsPlainRailTile(tile)) {
uint f = GetRailFoundation(tileh, GetTrackBits(tile));
if (f != 0) {
if (IsSteepSlope(tileh)) {
z += TILE_HEIGHT;
} else if (f < 15) {
return z + TILE_HEIGHT; // leveled foundation
}
tileh = _inclined_tileh[f - 15]; // inclined foundation
}
z += ApplyFoundationToSlope(GetRailFoundation(tileh, GetTrackBits(tile)), &tileh);
return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
} else {
return z + TILE_HEIGHT;
}
}
static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Track(TileIndex tile, Slope tileh)
{
if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
if (IsPlainRailTile(tile)) {
uint f = GetRailFoundation(tileh, GetTrackBits(tile));
if (f == 0) return tileh;
if (f < 15) return SLOPE_FLAT; // leveled foundation
return _inclined_tileh[f - 15]; // inclined foundation
} else {
return SLOPE_FLAT;
}
return IsPlainRailTile(tile) ? GetRailFoundation(tileh, GetTrackBits(tile)) : FlatteningFoundation(tileh);
}
static void GetAcceptedCargo_Track(TileIndex tile, AcceptedCargo ac)
@ -2186,5 +2151,5 @@ extern const TileTypeProcs _tile_type_rail_procs = {
ChangeTileOwner_Track, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
VehicleEnter_Track, /* vehicle_enter_tile_proc */
GetSlopeTileh_Track, /* get_slope_tileh_proc */
GetFoundation_Track, /* get_foundation_proc */
};

View File

@ -839,34 +839,14 @@ struct DrawRoadTileStruct {
#include "table/road_land.h"
uint GetRoadFoundation(Slope tileh, RoadBits bits)
Foundation GetRoadFoundation(Slope tileh, RoadBits bits)
{
uint i;
/* normal level sloped building */
if (!IsSteepSlope(tileh) &&
(~_valid_tileh_slopes_road[1][tileh] & bits) == 0) {
return tileh;
if (!IsSteepSlope(tileh)) {
if ((~_valid_tileh_slopes_road[0][tileh] & bits) == 0) return FOUNDATION_NONE;
if ((~_valid_tileh_slopes_road[1][tileh] & bits) == 0) return FOUNDATION_LEVELED;
}
/* inclined sloped building */
switch (bits) {
case ROAD_X: i = 0; break;
case ROAD_Y: i = 1; break;
default: return 0;
}
switch (tileh) {
case SLOPE_W:
case SLOPE_STEEP_W: i += 0; break;
case SLOPE_S:
case SLOPE_STEEP_S: i += 2; break;
case SLOPE_E:
case SLOPE_STEEP_E: i += 4; break;
case SLOPE_N:
case SLOPE_STEEP_N: i += 6; break;
default: return 0;
}
return i + 15;
return (bits == ROAD_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
}
const byte _road_sloped_sprites[14] = {
@ -954,9 +934,7 @@ static void DrawRoadBits(TileInfo* ti)
Roadside roadside;
if (ti->tileh != SLOPE_FLAT) {
int foundation = GetRoadFoundation(ti->tileh, road | tram);
if (foundation != 0) DrawFoundation(ti, foundation);
DrawFoundation(ti, GetRoadFoundation(ti->tileh, road | tram));
/* DrawFoundation() modifies ti.
* Default sloped sprites.. */
@ -1029,7 +1007,7 @@ static void DrawTile_Road(TileInfo *ti)
SpriteID pal = PAL_NONE;
Roadside roadside = GetRoadside(ti->tile);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.crossing;
@ -1061,7 +1039,7 @@ static void DrawTile_Road(TileInfo *ti)
const DrawTileSeqStruct* dtss;
SpriteID palette;
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
@ -1123,33 +1101,20 @@ static uint GetSlopeZ_Road(TileIndex tile, uint x, uint y)
if (tileh == SLOPE_FLAT) return z;
if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
if (f != 0) {
if (IsSteepSlope(tileh)) {
z += TILE_HEIGHT;
} else if (f < 15) {
return z + TILE_HEIGHT; // leveled foundation
}
tileh = _inclined_tileh[f - 15]; // inclined foundation
}
Foundation f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
z += ApplyFoundationToSlope(f, &tileh);
return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
} else {
return z + TILE_HEIGHT;
}
}
static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
{
if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
if (f == 0) return tileh;
if (f < 15) return SLOPE_FLAT; // leveled foundation
return _inclined_tileh[f - 15]; // inclined foundation
return GetRoadFoundation(tileh, GetAllRoadBits(tile));
} else {
return SLOPE_FLAT;
return FlatteningFoundation(tileh);
}
}
@ -1407,5 +1372,5 @@ extern const TileTypeProcs _tile_type_road_procs = {
ChangeTileOwner_Road, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
VehicleEnter_Road, /* vehicle_enter_tile_proc */
GetSlopeTileh_Road, /* get_slope_tileh_proc */
GetFoundation_Road, /* get_foundation_proc */
};

View File

@ -68,4 +68,97 @@ static inline Slope ComplementSlope(Slope s)
return (Slope)(0xF ^ s);
}
/**
* Returns the highest corner of a slope (one corner raised or a steep slope).
*
* @pre The slope must be a slope with one corner raised or a steep slope.
* @param s The #Slope.
* @return Number of the highest corner. (0 west, 1 south, 2 east, 3 north)
*/
static inline byte GetHighestSlopeCorner(Slope s)
{
switch (s) {
case SLOPE_W:
case SLOPE_STEEP_W: return 0;
case SLOPE_S:
case SLOPE_STEEP_S: return 1;
case SLOPE_E:
case SLOPE_STEEP_E: return 2;
case SLOPE_N:
case SLOPE_STEEP_N: return 3;
default: NOT_REACHED();
}
}
/**
* 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 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.
};
/**
* Tests for FOUNDATION_NONE.
*
* @param f Maybe a #Foundation.
* @return true iff f is a foundation.
*/
static inline bool IsFoundation(Foundation f)
{
return f != FOUNDATION_NONE;
}
/**
* Tests if the foundation is a leveled foundation.
*
* @param f The #Foundation.
* @return true iff f is a leveled foundation.
*/
static inline bool IsLeveledFoundation(Foundation f)
{
return f == FOUNDATION_LEVELED;
}
/**
* Tests if the foundation is an inclined foundation.
*
* @param f The #Foundation.
* @return true iff f is an inclined foundation.
*/
static inline bool IsInclinedFoundation(Foundation f)
{
return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y);
}
/**
* Returns the foundation needed to flatten a slope.
* The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED.
*
* @pre The slope must not be steep.
* @param s The current #Slope.
* @return The needed #Foundation.
*/
static inline Foundation FlatteningFoundation(Slope s)
{
assert(!IsSteepSlope(s));
return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED);
}
/**
* Returns the along a specific axis inclined foundation.
*
* @param axis The #Axis.
* @return The needed #Foundation.
*/
static inline Foundation InclinedFoundation(Axis axis)
{
return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
}
#endif /* SLOPE_H */

View File

@ -2071,7 +2071,7 @@ static void DrawTile_Station(TileInfo *ti)
// don't show foundation for docks
if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile))
DrawFoundation(ti, ti->tileh);
DrawFoundation(ti, FOUNDATION_LEVELED);
if (IsCustomStationSpecIndex(ti->tile)) {
// look for customization
@ -2176,9 +2176,9 @@ static uint GetSlopeZ_Station(TileIndex tile, uint x, uint y)
return GetTileMaxZ(tile);
}
static Slope GetSlopeTileh_Station(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Station(TileIndex tile, Slope tileh)
{
return SLOPE_FLAT;
return FlatteningFoundation(tileh);
}
static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac)
@ -2921,7 +2921,7 @@ extern const TileTypeProcs _tile_type_station_procs = {
ChangeTileOwner_Station, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
VehicleEnter_Station, /* vehicle_enter_tile_proc */
GetSlopeTileh_Station, /* get_slope_tileh_proc */
GetFoundation_Station, /* get_foundation_proc */
};
static const SaveLoad _roadstop_desc[] = {

View File

@ -50,7 +50,13 @@ enum Sprites {
OPENTTD_SPRITES_COUNT = 112, // number of gfx-sprites in openttd.grf
SPR_SIGNALS_BASE = 4896,
SPR_CANALS_BASE = SPR_SIGNALS_BASE + 486,
SPR_SLOPES_BASE = SPR_CANALS_BASE + 70,
SPR_SLOPES_BASE = SPR_CANALS_BASE + 70,
SPR_SLOPES_INCLINED_OFFSET = 15,
SPR_SLOPES_VIRTUAL_BASE = SPR_SLOPES_BASE - SPR_SLOPES_INCLINED_OFFSET, // The original foundations (see SPR_FOUNDATION_BASE below) are mapped before the additional foundations.
SPR_SLOPES_NO_FOUNDATION_NW_OFFSET = 22, // no wall on the NW edge of the tile.
SPR_SLOPES_NO_FOUNDATION_NE_OFFSET = 44, // no wall on the NE edge of the tile.
SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78,
SPR_ELRAIL_BASE = SPR_AUTORAIL_BASE + 55,
SPR_2CCMAP_BASE = SPR_ELRAIL_BASE + 53,

View File

@ -154,7 +154,7 @@ static void DrawTile_Town(TileInfo *ti)
/* Retrieve pointer to the draw town tile struct */
dcts = &_town_draw_tile_data[house_id << 4 | OriginalTileRandomiser(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
image = dcts->ground.sprite;
pal = dcts->ground.pal;
@ -188,9 +188,9 @@ static uint GetSlopeZ_Town(TileIndex tile, uint x, uint y)
return GetTileMaxZ(tile);
}
static Slope GetSlopeTileh_Town(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
{
return SLOPE_FLAT;
return FlatteningFoundation(tileh);
}
/**
@ -2350,7 +2350,7 @@ extern const TileTypeProcs _tile_type_town_procs = {
ChangeTileOwner_Town, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
NULL, /* vehicle_enter_tile_proc */
GetSlopeTileh_Town, /* get_slope_tileh_proc */
GetFoundation_Town, /* get_foundation_proc */
};

View File

@ -416,9 +416,9 @@ static uint GetSlopeZ_Trees(TileIndex tile, uint x, uint y)
return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
}
static Slope GetSlopeTileh_Trees(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Trees(TileIndex tile, Slope tileh)
{
return tileh;
return FOUNDATION_NONE;
}
static CommandCost ClearTile_Trees(TileIndex tile, byte flags)
@ -670,5 +670,5 @@ extern const TileTypeProcs _tile_type_trees_procs = {
ChangeTileOwner_Trees, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
NULL, /* vehicle_enter_tile_proc */
GetSlopeTileh_Trees, /* get_slope_tileh_proc */
GetFoundation_Trees, /* get_foundation_proc */
};

View File

@ -863,26 +863,11 @@ static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis
}
}
uint GetBridgeFoundation(Slope tileh, Axis axis)
Foundation GetBridgeFoundation(Slope tileh, Axis axis)
{
uint i;
if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
/* inclined sloped building */
switch (tileh) {
case SLOPE_W:
case SLOPE_STEEP_W: i = 0; break;
case SLOPE_S:
case SLOPE_STEEP_S: i = 2; break;
case SLOPE_E:
case SLOPE_STEEP_E: i = 4; break;
case SLOPE_N:
case SLOPE_STEEP_N: i = 6; break;
default: return 0;
}
if (axis != AXIS_X) ++i;
return i + 15;
if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) return FOUNDATION_NONE;
if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return FlatteningFoundation(tileh);
return InclinedFoundation(axis);
}
/**
@ -968,10 +953,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
/* as the lower 3 bits are used for other stuff, make sure they are clear */
assert( (base_offset & 0x07) == 0x00);
if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
if (f != 0) DrawFoundation(ti, f);
}
DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))));
/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
@ -1156,14 +1138,14 @@ static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y)
DiagDirection dir = GetBridgeRampDirection(tile);
uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
z += ApplyFoundationToSlope(GetBridgeFoundation(tileh, DiagDirToAxis(dir)), &tileh);
/* On the bridge ramp? */
if (5 <= pos && pos <= 10) {
uint delta;
if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
switch (dir) {
default: NOT_REACHED();
case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
@ -1172,38 +1154,15 @@ static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y)
case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
}
return z + 1 + delta;
} else {
uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
if (f != 0) {
if (IsSteepSlope(tileh)) {
z += TILE_HEIGHT;
} else if (f < 15) {
return z + TILE_HEIGHT;
}
tileh = (Slope)_inclined_tileh[f - 15];
}
}
}
return z + GetPartialZ(x, y, tileh);
}
static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh)
static Foundation GetFoundation_TunnelBridge(TileIndex tile, Slope tileh)
{
if (IsTunnel(tile)) {
return tileh;
} else {
if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) {
return tileh;
} else {
uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
if (f == 0) return tileh;
if (f < 15) return SLOPE_FLAT;
return (Slope)_inclined_tileh[f - 15];
}
}
return IsTunnel(tile) ? FOUNDATION_NONE : GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
}
@ -1475,5 +1434,5 @@ extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
ChangeTileOwner_TunnelBridge, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
VehicleEnter_TunnelBridge, /* vehicle_enter_tile_proc */
GetSlopeTileh_TunnelBridge, /* get_slope_tileh_proc */
GetFoundation_TunnelBridge, /* get_foundation_proc */
};

View File

@ -118,7 +118,7 @@ static void DrawTile_Unmovable(TileInfo *ti)
case UNMOVABLE_LIGHTHOUSE: {
const DrawTileUnmovableStruct* dtus;
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
DrawClearLandTile(ti, 2);
dtus = &_draw_tile_unmovable_data[GetUnmovableType(ti->tile)];
@ -153,7 +153,7 @@ static void DrawTile_Unmovable(TileInfo *ti)
SpriteID palette;
assert(IsCompanyHQ(ti->tile));
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
@ -186,9 +186,9 @@ static uint GetSlopeZ_Unmovable(TileIndex tile, uint x, uint y)
}
}
static Slope GetSlopeTileh_Unmovable(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Unmovable(TileIndex tile, Slope tileh)
{
return IsOwnedLand(tile) ? tileh : SLOPE_FLAT;
return IsOwnedLand(tile) ? FOUNDATION_NONE : FlatteningFoundation(tileh);
}
static CommandCost ClearTile_Unmovable(TileIndex tile, byte flags)
@ -411,5 +411,5 @@ extern const TileTypeProcs _tile_type_unmovable_procs = {
ChangeTileOwner_Unmovable, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
NULL, /* vehicle_enter_tile_proc */
GetSlopeTileh_Unmovable, /* get_slope_tileh_proc */
GetFoundation_Unmovable, /* get_foundation_proc */
};

View File

@ -330,7 +330,6 @@ VARDEF char *_log_file;
/* landscape.cpp */
extern const byte _tileh_to_sprite[32];
extern const Slope _inclined_tileh[16];
extern const TileTypeProcs * const _tile_type_procs[16];

View File

@ -500,9 +500,9 @@ static uint GetSlopeZ_Water(TileIndex tile, uint x, uint y)
return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
}
static Slope GetSlopeTileh_Water(TileIndex tile, Slope tileh)
static Foundation GetFoundation_Water(TileIndex tile, Slope tileh)
{
return tileh;
return FOUNDATION_NONE;
}
static void GetAcceptedCargo_Water(TileIndex tile, AcceptedCargo ac)
@ -812,5 +812,5 @@ extern const TileTypeProcs _tile_type_water_procs = {
ChangeTileOwner_Water, /* change_tile_owner_clear */
NULL, /* get_produced_cargo_proc */
VehicleEnter_Water, /* vehicle_enter_tile_proc */
GetSlopeTileh_Water, /* get_slope_tileh_proc */
GetFoundation_Water, /* get_foundation_proc */
};