(svn r2595) -Codechange: Introduced "IsSteepTileh" to find whether a tile is steep

(i.e. spans two height levels) and use it throughout the code.
-Codechange: Add CanBuildDepotByTileh to find if a tile is suitable to
build a depot on it. Wraps some bitmagic which seems quite unreadable at
first glance
This commit is contained in:
celestar 2005-07-16 23:47:37 +00:00
parent 64f6839816
commit 9ca761b065
11 changed files with 87 additions and 19 deletions

25
depot.h
View File

@ -1,6 +1,9 @@
#ifndef DEPOT_H #ifndef DEPOT_H
#define DEPOT_H #define DEPOT_H
/** @file depot.h Header files for depots (not hangars)
* @see depot.c */
#include "pool.h" #include "pool.h"
#include "tile.h" #include "tile.h"
@ -112,6 +115,28 @@ static inline DiagDirection GetDepotDirection(TileIndex tile, TransportType type
} }
} }
/**
Find out if the slope of the tile is suitable to build a depot of given direction
@param direction The direction in which the depot's exit points. Starts with 0 as NE and goes Clockwise
@param tileh The slope of the tile in question
@return true if the construction is possible
This is checked by the ugly 0x4C >> direction magic, which does the following:
0x4C is 0100 1100 and tileh has only bits 0..3 set (steep tiles are ruled out)
So: for direction (only the significant bits are shown)<p>
00 (exit towards NE) we need either bit 2 or 3 set in tileh: 0x4C >> 0 = 1100<p>
01 (exit towards SE) we need either bit 1 or 2 set in tileh: 0x4C >> 1 = 0110<p>
02 (exit towards SW) we need either bit 0 or 1 set in tileh: 0x4C >> 2 = 0011<p>
03 (exit towards NW) we need either bit 0 or 4 set in tileh: 0x4C >> 3 = 1001<p>
So ((0x4C >> p2) & tileh) determines whether the depot can be built on the current tileh
*/
static inline bool CanBuildDepotByTileh(uint32 direction, uint tileh)
{
return (0x4C >> direction) & tileh;
}
Depot *GetDepotByTile(TileIndex tile); Depot *GetDepotByTile(TileIndex tile);
void InitializeDepot(void); void InitializeDepot(void);
Depot *AllocateDepot(void); Depot *AllocateDepot(void);

View File

@ -1339,7 +1339,7 @@ static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable
} else { } else {
if (ti.type == MP_WATER && ti.map5 == 0) if (ti.type == MP_WATER && ti.map5 == 0)
return false; return false;
if (ti.tileh & 0x10) if (IsSteepTileh(ti.tileh))
return false; return false;
if (ti.tileh != 0) { if (ti.tileh != 0) {

View File

@ -1218,7 +1218,7 @@ static void PlaceProc_LightHouse(TileIndex tile)
TileInfo ti; TileInfo ti;
FindLandscapeHeightByTile(&ti, tile); FindLandscapeHeightByTile(&ti, tile);
if (ti.type != MP_CLEAR || (ti.tileh & 0x10)) if (IsTileType(tile, MP_CLEAR) || IsSteepTileh(ti.tileh))
return; return;
ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 1); ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 1);
@ -1230,7 +1230,7 @@ static void PlaceProc_Transmitter(TileIndex tile)
TileInfo ti; TileInfo ti;
FindLandscapeHeightByTile(&ti, tile); FindLandscapeHeightByTile(&ti, tile);
if (ti.type != MP_CLEAR || (ti.tileh & 0x10)) if (IsTileType(tile, MP_CLEAR) || IsSteepTileh(ti.tileh))
return; return;
ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 0); ModifyTile(tile, MP_SETTYPE(MP_UNMOVABLE) | MP_MAP5, 0);

View File

@ -217,7 +217,7 @@ uint GetRailFoundation(uint tileh, uint bits)
static uint32 CheckRailSlope(uint tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) static uint32 CheckRailSlope(uint tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
{ {
// never allow building on top of steep tiles // never allow building on top of steep tiles
if (!(tileh & 0x10)) { if (!IsSteepTileh(tileh)) {
rail_bits |= existing; rail_bits |= existing;
// don't allow building on the lower side of a coast // don't allow building on the lower side of a coast
@ -634,7 +634,10 @@ int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
/** Build a train depot /** Build a train depot
* @param x,y position of the train depot * @param x,y position of the train depot
* @param p1 rail type * @param p1 rail type
* @param p2 depot direction (0 through 3), where 0 is NW, 1 is NE, etc. * @param p2 depot direction (0 through 3), where 0 is NE, 1 is SE, 2 is SW, 3 is NW
*
* @todo When checking for the tile slope,
* distingush between "Flat land required" and "land sloped in wrong direction"
*/ */
int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
@ -650,8 +653,23 @@ int32 CmdBuildTrainDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR; if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
tileh = GetTileSlope(tile, NULL); tileh = GetTileSlope(tile, NULL);
if (tileh != 0) {
if ((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes || (tileh & 0x10 || !((0x4C >> p2) & tileh) )) /* Prohibit construction if
The tile is non-flat AND
1) The AI is "old-school"
2) build-on-slopes is disabled
3) the tile is steep i.e. spans two height levels
4) the exit points in the wrong direction
*/
if (tileh != 0 && (
(!_patches.ainew_active && _is_ai_player) ||
!_patches.build_on_slopes ||
IsSteepTileh(tileh) ||
!CanBuildDepotByTileh(p2, tileh)
)
) {
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
} }

View File

@ -322,7 +322,7 @@ static const byte _valid_tileh_slopes_road[3][15] = {
static uint32 CheckRoadSlope(int tileh, byte *pieces, byte existing) static uint32 CheckRoadSlope(int tileh, byte *pieces, byte existing)
{ {
if (!(tileh & 0x10)) { if (!IsSteepTileh(tileh)) {
byte road_bits = *pieces | existing; byte road_bits = *pieces | existing;
// no special foundation // no special foundation
@ -385,7 +385,7 @@ int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
} else if (ti.type == MP_RAILWAY) { } else if (ti.type == MP_RAILWAY) {
byte m5; byte m5;
if (ti.tileh & 0x10) // very steep tile if (IsSteepTileh(ti.tile)) // very steep tile
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
if(!_valid_tileh_slopes_road[2][ti.tileh]) // prevent certain slopes if(!_valid_tileh_slopes_road[2][ti.tileh]) // prevent certain slopes
@ -417,7 +417,7 @@ int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
} else if (ti.type == MP_TUNNELBRIDGE) { } else if (ti.type == MP_TUNNELBRIDGE) {
/* check for flat land */ /* check for flat land */
if (ti.tileh & 0x10) // very steep tile if (IsSteepTileh(ti.tileh)) // very steep tile
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
/* is this middle part of a bridge? */ /* is this middle part of a bridge? */
@ -620,6 +620,9 @@ int32 CmdRemoveLongRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
* @param x,y tile coordinates where the depot will be built * @param x,y tile coordinates where the depot will be built
* @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc. * @param p1 depot direction (0 through 3), where 0 is NW, 1 is NE, etc.
* @param p2 unused * @param p2 unused
*
* @todo When checking for the tile slope,
* distingush between "Flat land required" and "land sloped in wrong direction"
*/ */
int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
@ -639,8 +642,12 @@ int32 CmdBuildRoadDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
if (!EnsureNoVehicle(tile)) if (!EnsureNoVehicle(tile))
return CMD_ERROR; return CMD_ERROR;
if (ti.tileh != 0) { if ((ti.tileh != 0) && (
if (!_patches.build_on_slopes || (ti.tileh & 0x10 || !((0x4C >> p1) & ti.tileh) )) !_patches.build_on_slopes ||
IsSteepTileh(ti.tileh) ||
!CanBuildDepotByTileh(p1, ti.tileh)
)
) {
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
} }

View File

@ -764,8 +764,18 @@ int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invali
tileh = GetTileSlope(tile_cur, &z); tileh = GetTileSlope(tile_cur, &z);
// steep slopes are completely prohibited /* Prohibit building if
if (tileh & 0x10 || (((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes) && tileh != 0)) { 1) The tile is "steep" (i.e. stretches two height levels)
-OR-
2) The tile is non-flat if
a) the player building is an "old-school" AI
-OR-
b) the build_on_slopes switch is disabled
*/
if (IsSteepTileh(tileh) ||
(((!_patches.ainew_active && _is_ai_player) || !_patches.build_on_slopes)
&& tileh != 0)) {
_error_message = STR_0007_FLAT_LAND_REQUIRED; _error_message = STR_0007_FLAT_LAND_REQUIRED;
return CMD_ERROR; return CMD_ERROR;
} }

5
tile.h
View File

@ -61,6 +61,11 @@ static inline uint TileHeight(TileIndex tile)
return GB(_m[tile].type_height, 0, 4); return GB(_m[tile].type_height, 0, 4);
} }
static inline bool IsSteepTileh(uint tileh)
{
return (tileh & 0x10);
}
static inline void SetTileHeight(TileIndex tile, uint height) static inline void SetTileHeight(TileIndex tile, uint height)
{ {
assert(tile < MapSize()); assert(tile < MapSize());

View File

@ -289,7 +289,7 @@ static void DrawTile_Trees(TileInfo *ti)
z = ti->z; z = ti->z;
if (ti->tileh != 0) { if (ti->tileh != 0) {
z += 4; z += 4;
if (ti->tileh & 0x10) if (IsSteepTileh(ti->tileh))
z += 4; z += 4;
} }

View File

@ -88,7 +88,7 @@ enum {
*/ */
static uint32 CheckBridgeSlope(uint direction, uint tileh, bool is_start_tile) static uint32 CheckBridgeSlope(uint direction, uint tileh, bool is_start_tile)
{ {
if (!(tileh & 0x10)) { // disable building on very steep slopes if (!IsSteepTileh(tileh)) { // disable building on very steep slopes
if (is_start_tile) { if (is_start_tile) {
/* check slope at start tile /* check slope at start tile
@ -981,7 +981,7 @@ static void DrawBridgePillars(TileInfo *ti, int x, int y, int z)
p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)]; p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)];
front_height = ti->z + ((ti->tileh & p[0])?8:0); front_height = ti->z + ((ti->tileh & p[0])?8:0);
back_height = ti->z + ((ti->tileh & p[1])?8:0); back_height = ti->z + ((ti->tileh & p[1])?8:0);
if (ti->tileh & 0x10) { if (IsSteepTileh(ti->tileh)) {
if (!(ti->tileh & p[2])) front_height += 8; if (!(ti->tileh & p[2])) front_height += 8;
if (!(ti->tileh & p[3])) back_height += 8; if (!(ti->tileh & p[3])) back_height += 8;
} }

View File

@ -669,7 +669,7 @@ static void DrawTileSelection(const TileInfo *ti)
byte z = ti->z; byte z = ti->z;
if (ti->tileh & 8) { if (ti->tileh & 8) {
z += 8; z += 8;
if (!(ti->tileh & 2) && (ti->tileh & 0x10)) { if (!(ti->tileh & 2) && (IsSteepTileh(ti->tileh))) {
z += 8; z += 8;
} }
} }

View File

@ -152,6 +152,9 @@ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
* @param x,y coordinates where waypoint will be built * @param x,y coordinates where waypoint will be built
* @param p1 graphics for waypoint type, bit 8 signifies custom waypoint gfx (& 0x100) * @param p1 graphics for waypoint type, bit 8 signifies custom waypoint gfx (& 0x100)
* @param p2 unused * @param p2 unused
*
* @todo When checking for the tile slope,
* distingush between "Flat land required" and "land sloped in wrong direction"
*/ */
int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2) int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{ {
@ -175,7 +178,7 @@ int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
tileh = GetTileSlope(tile, NULL); tileh = GetTileSlope(tile, NULL);
if (tileh != 0) { if (tileh != 0) {
if (!_patches.build_on_slopes || tileh & 0x10 || !(tileh & (0x3 << dir)) || !(tileh & ~(0x3 << dir))) if (!_patches.build_on_slopes || IsSteepTileh(tileh) || !(tileh & (0x3 << dir)) || !(tileh & ~(0x3 << dir)))
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
} }