1
0
Fork 0

(svn r27273) [1.5] -Backport from trunk:

- Fix: Do not consider road junctions with trivial dead ends as branch points during town growth [FS#6245] (r27260, r27259, r27244)
- Fix: In some cases town growth failure was considered as success [FS#6240] (r27249, r27247)
release/1.5
frosch 2015-05-08 17:37:48 +00:00
parent 622ea4406d
commit a622403be6
1 changed files with 55 additions and 9 deletions

View File

@ -1297,13 +1297,51 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
GrowTownWithRoad(t1, tile, rcmd); GrowTownWithRoad(t1, tile, rcmd);
} }
/**
* Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
* This only checks trivial but often cases.
* @param tile Start tile for road.
* @param dir Direction for road to follow or build.
* @return true If road is or can be connected in the specified direction.
*/
static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
{
TileIndex target_tile = tile + TileOffsByDiagDir(dir);
if (!IsValidTile(target_tile)) return false;
if (HasTileWaterGround(target_tile)) return false;
RoadBits target_rb = GetTownRoadBits(target_tile);
if (_settings_game.economy.allow_town_roads || _generating_world) {
/* Check whether a road connection exists or can be build. */
switch (GetTileType(target_tile)) {
case MP_ROAD:
return target_rb != ROAD_NONE;
case MP_HOUSE:
case MP_STATION:
case MP_INDUSTRY:
case MP_OBJECT:
return false;
default:
/* Checked for void and water earlier */
return true;
}
} else {
/* Check whether a road connection already exists,
* and it leads somewhere else. */
RoadBits back_rb = DiagDirToRoadBits(ReverseDiagDir(dir));
return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
}
}
/** /**
* Returns "growth" if a house was built, or no if the build failed. * Returns "growth" if a house was built, or no if the build failed.
* @param t town to inquiry * @param t town to inquiry
* @param tile to inquiry * @param tile to inquiry
* @return something other than zero(0)if town expansion was possible * @return true if town expansion was possible
*/ */
static int GrowTownAtRoad(Town *t, TileIndex tile) static bool GrowTownAtRoad(Town *t, TileIndex tile)
{ {
/* Special case. /* Special case.
* @see GrowTownInTile Check the else if * @see GrowTownInTile Check the else if
@ -1340,7 +1378,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
* and return if no more road blocks available */ * and return if no more road blocks available */
if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir)); if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
if (cur_rb == ROAD_NONE) { if (cur_rb == ROAD_NONE) {
return _grow_town_result; return _grow_town_result == GROWTH_SUCCEED;
} }
if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (IsTileType(tile, MP_TUNNELBRIDGE)) {
@ -1349,14 +1387,22 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
} else { } else {
/* Select a random bit from the blockmask, walk a step /* Select a random bit from the blockmask, walk a step
* and continue the search from there. */ * and continue the search from there. */
do target_dir = RandomDiagDir(); while (!(cur_rb & DiagDirToRoadBits(target_dir))); do {
if (cur_rb == ROAD_NONE) return false;
RoadBits target_bits;
do {
target_dir = RandomDiagDir();
target_bits = DiagDirToRoadBits(target_dir);
} while (!(cur_rb & target_bits));
cur_rb &= ~target_bits;
} while (!CanFollowRoad(tile, target_dir));
} }
tile = TileAddByDiagDir(tile, target_dir); tile = TileAddByDiagDir(tile, target_dir);
if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, ROADTYPE_ROAD)) { if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, ROADTYPE_ROAD)) {
/* Don't allow building over roads of other cities */ /* Don't allow building over roads of other cities */
if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) { if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
_grow_town_result = GROWTH_SUCCEED; return false;
} else if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) { } else if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
/* If we are in the SE, and this road-piece has no town owner yet, it just found an /* If we are in the SE, and this road-piece has no town owner yet, it just found an
* owner :) (happy happy happy road now) */ * owner :) (happy happy happy road now) */
@ -1368,7 +1414,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
/* Max number of times is checked. */ /* Max number of times is checked. */
} while (--_grow_town_result >= 0); } while (--_grow_town_result >= 0);
return (_grow_town_result == -2); return _grow_town_result == GROWTH_SUCCEED - 1;
} }
/** /**
@ -1390,7 +1436,7 @@ static RoadBits GenRandomRoadBits()
/** /**
* Grow the town * Grow the town
* @param t town to grow * @param t town to grow
* @return true iff a house was built * @return true iff something (house, road, bridge, ...) was built
*/ */
static bool GrowTown(Town *t) static bool GrowTown(Town *t)
{ {
@ -1419,9 +1465,9 @@ static bool GrowTown(Town *t)
const TileIndexDiffC *ptr; const TileIndexDiffC *ptr;
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
if (GetTownRoadBits(tile) != ROAD_NONE) { if (GetTownRoadBits(tile) != ROAD_NONE) {
int r = GrowTownAtRoad(t, tile); bool success = GrowTownAtRoad(t, tile);
cur_company.Restore(); cur_company.Restore();
return r != 0; return success;
} }
tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
} }