mirror of https://github.com/OpenTTD/OpenTTD
(svn r12161) -Fix: towns will no longer build houses > 1x1 there where should be road (with 2x2, 3x3 grid town layouts)
parent
058f39fe18
commit
4b7a812e55
137
src/town_cmd.cpp
137
src/town_cmd.cpp
|
@ -1617,7 +1617,6 @@ HouseZonesBits GetTownRadiusGroup(const Town* t, TileIndex tile)
|
||||||
* @param random_bits required for newgrf houses
|
* @param random_bits required for newgrf houses
|
||||||
* @pre house can be built here
|
* @pre house can be built here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void ClearMakeHouseTile(TileIndex tile, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
|
static inline void ClearMakeHouseTile(TileIndex tile, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
|
||||||
{
|
{
|
||||||
CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
|
CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
|
||||||
|
@ -1626,6 +1625,7 @@ static inline void ClearMakeHouseTile(TileIndex tile, TownID tid, byte counter,
|
||||||
MakeHouseTile(tile, tid, counter, stage, type, random_bits);
|
MakeHouseTile(tile, tid, counter, stage, type, random_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write house information into the map. For houses > 1 tile, all tiles are marked.
|
* Write house information into the map. For houses > 1 tile, all tiles are marked.
|
||||||
* @param t tile index
|
* @param t tile index
|
||||||
|
@ -1709,6 +1709,116 @@ static bool CheckFree2x2Area(TileIndex tile, uint z, bool noslope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if current town layout allows building here
|
||||||
|
* @param t town
|
||||||
|
* @param tile tile to check
|
||||||
|
* @return true iff town layout allows building here
|
||||||
|
* @note see layouts
|
||||||
|
*/
|
||||||
|
static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
|
||||||
|
{
|
||||||
|
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
|
||||||
|
|
||||||
|
switch (_patches.town_layout) {
|
||||||
|
case TL_2X2_GRID:
|
||||||
|
if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TL_3X3_GRID:
|
||||||
|
if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if current town layout allows 2x2 building here
|
||||||
|
* @param t town
|
||||||
|
* @param tile tile to check
|
||||||
|
* @return true iff town layout allows 2x2 building here
|
||||||
|
* @note see layouts
|
||||||
|
*/
|
||||||
|
static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
|
||||||
|
{
|
||||||
|
/* MapSize() is sure dividable by both MapSizeX() and MapSizeY(),
|
||||||
|
* so to do only one memory access, use MapSize() */
|
||||||
|
uint dx = MapSize() + TileX(t->xy) - TileX(tile);
|
||||||
|
uint dy = MapSize() + TileY(t->xy) - TileY(tile);
|
||||||
|
|
||||||
|
switch (_patches.town_layout) {
|
||||||
|
case TL_2X2_GRID:
|
||||||
|
if ((dx % 3) != 0 || (dy % 3) != 0) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TL_3X3_GRID:
|
||||||
|
if ((dx % 4) < 2 || (dy % 4) < 2) return false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if 1x2 or 2x1 building is allowed here, also takes into account current town layout
|
||||||
|
* Also, tests both building positions that occupy this tile
|
||||||
|
* @param tile tile where the building should be built
|
||||||
|
* @param t town
|
||||||
|
* @param maxz all tiles should have the same height
|
||||||
|
* @param noslope are slopes forbidden?
|
||||||
|
* @param second diagdir from first tile to second tile
|
||||||
|
**/
|
||||||
|
static bool CheckTownBuild2House(TileIndex *tile, Town *t, uint maxz, bool noslope, DiagDirection second)
|
||||||
|
{
|
||||||
|
/* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
|
||||||
|
|
||||||
|
TileIndex tile2 = *tile + TileOffsByDiagDir(second);
|
||||||
|
if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
|
||||||
|
|
||||||
|
tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
|
||||||
|
if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
|
||||||
|
*tile = tile2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if 2x2 building is allowed here, also takes into account current town layout
|
||||||
|
* Also, tests all four building positions that occupy this tile
|
||||||
|
* @param tile tile where the building should be built
|
||||||
|
* @param t town
|
||||||
|
* @param maxz all tiles should have the same height
|
||||||
|
* @param noslope are slopes forbidden?
|
||||||
|
**/
|
||||||
|
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, uint maxz, bool noslope)
|
||||||
|
{
|
||||||
|
TileIndex tile2 = *tile;
|
||||||
|
|
||||||
|
for (DiagDirection d = DIAGDIR_SE;;d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
|
||||||
|
if (TownLayoutAllows2x2HouseHere(t, tile2) && CheckFree2x2Area(tile2, maxz, noslope)) {
|
||||||
|
*tile = tile2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (d == DIAGDIR_END) break;
|
||||||
|
tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to build a house at this tile
|
* Tries to build a house at this tile
|
||||||
* @param t town the house will belong to
|
* @param t town the house will belong to
|
||||||
|
@ -1717,6 +1827,9 @@ static bool CheckFree2x2Area(TileIndex tile, uint z, bool noslope)
|
||||||
*/
|
*/
|
||||||
static bool BuildTownHouse(Town *t, TileIndex tile)
|
static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
{
|
{
|
||||||
|
/* forbidden building here by town layout */
|
||||||
|
if (!TownLayoutAllowsHouseHere(t, tile)) return false;
|
||||||
|
|
||||||
/* no house allowed at all, bail out */
|
/* no house allowed at all, bail out */
|
||||||
if (!CanBuildHouseHere(tile, false)) return false;
|
if (!CanBuildHouseHere(tile, false)) return false;
|
||||||
|
|
||||||
|
@ -1806,25 +1919,13 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
if (noslope && slope != SLOPE_FLAT) continue;
|
if (noslope && slope != SLOPE_FLAT) continue;
|
||||||
|
|
||||||
if (hs->building_flags & TILE_SIZE_2x2) {
|
if (hs->building_flags & TILE_SIZE_2x2) {
|
||||||
if (!CheckFree2x2Area(tile, maxz, noslope) &&
|
if (!CheckTownBuild2x2House(&tile, t, maxz, noslope)) continue;
|
||||||
!CheckFree2x2Area(tile += TileDiffXY(-1, 0), maxz, noslope) &&
|
|
||||||
!CheckFree2x2Area(tile += TileDiffXY( 0, -1), maxz, noslope) &&
|
|
||||||
!CheckFree2x2Area(tile += TileDiffXY( 1, 0), maxz, noslope)) {
|
|
||||||
/* return to the original tile */
|
|
||||||
tile += TileDiffXY(0, 1);
|
|
||||||
continue; /* continue the while() loop */
|
|
||||||
}
|
|
||||||
} else if (hs->building_flags & TILE_SIZE_2x1) {
|
} else if (hs->building_flags & TILE_SIZE_2x1) {
|
||||||
/* 'tile' is already checked above - CanBuildHouseHere() and slope test */
|
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW)) continue;
|
||||||
if (!CheckBuildHouseSameZ(tile + TileDiffXY(1, 0), maxz, noslope)) {
|
|
||||||
if (!CheckBuildHouseSameZ(tile + TileDiffXY(-1, 0), maxz, noslope)) continue;
|
|
||||||
tile += TileDiffXY(-1, 0);
|
|
||||||
}
|
|
||||||
} else if (hs->building_flags & TILE_SIZE_1x2) {
|
} else if (hs->building_flags & TILE_SIZE_1x2) {
|
||||||
if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, 1), maxz, noslope)) {
|
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE)) continue;
|
||||||
if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, -1), maxz, noslope)) continue;
|
} else {
|
||||||
tile += TileDiffXY(0, -1);
|
/* 1x1 house checks are already done */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the house */
|
/* build the house */
|
||||||
|
|
Loading…
Reference in New Issue