mirror of https://github.com/OpenTTD/OpenTTD
(svn r12062) -Fix: possible deadlock when there are no houses available to build at given tile
-Fix: houses with zero probability could be builtrelease/0.6
parent
23c669fe50
commit
146779b158
|
@ -1748,7 +1748,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
{
|
{
|
||||||
HouseID houses[HOUSE_MAX];
|
HouseID houses[HOUSE_MAX];
|
||||||
int num = 0;
|
int num = 0;
|
||||||
uint cumulative_probs[HOUSE_MAX];
|
uint probs[HOUSE_MAX];
|
||||||
uint probability_max = 0;
|
uint probability_max = 0;
|
||||||
|
|
||||||
/* Generate a list of all possible houses that can be built. */
|
/* Generate a list of all possible houses that can be built. */
|
||||||
|
@ -1756,25 +1756,30 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
hs = GetHouseSpecs(i);
|
hs = GetHouseSpecs(i);
|
||||||
/* Verify that the candidate house spec matches the current tile status */
|
/* Verify that the candidate house spec matches the current tile status */
|
||||||
if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
|
if ((~hs->building_availability & bitmask) == 0 && hs->enabled) {
|
||||||
if (_loaded_newgrf_features.has_newhouses) {
|
/* Without NewHouses, all houses have probability '1' */
|
||||||
probability_max += hs->probability;
|
uint cur_prob = (_loaded_newgrf_features.has_newhouses ? hs->probability : 1);
|
||||||
cumulative_probs[num] = probability_max;
|
probability_max += cur_prob;
|
||||||
}
|
probs[num] = cur_prob;
|
||||||
houses[num++] = (HouseID)i;
|
houses[num++] = (HouseID)i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint maxz = GetTileMaxZ(tile);
|
uint maxz = GetTileMaxZ(tile);
|
||||||
|
|
||||||
for (;;) {
|
while (probability_max > 0) {
|
||||||
if (_loaded_newgrf_features.has_newhouses) {
|
|
||||||
uint r = RandomRange(probability_max);
|
uint r = RandomRange(probability_max);
|
||||||
for (i = 0; i < num; i++) if (cumulative_probs[i] >= r) break;
|
for (i = 0; i < num; i++) {
|
||||||
|
if (probs[i] > r) break;
|
||||||
|
r -= probs[i];
|
||||||
|
}
|
||||||
|
|
||||||
house = houses[i];
|
house = houses[i];
|
||||||
} else {
|
probability_max -= probs[i];
|
||||||
house = houses[RandomRange(num)];
|
|
||||||
}
|
/* remove tested house from the set */
|
||||||
|
num--;
|
||||||
|
houses[i] = houses[num];
|
||||||
|
probs[i] = probs[num];
|
||||||
|
|
||||||
hs = GetHouseSpecs(house);
|
hs = GetHouseSpecs(house);
|
||||||
|
|
||||||
|
@ -1810,35 +1815,28 @@ 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 (!CheckFree2x2Area(tile, maxz, noslope) &&
|
||||||
CheckFree2x2Area(tile += TileDiffXY(-1, 0), maxz, noslope) ||
|
!CheckFree2x2Area(tile += TileDiffXY(-1, 0), maxz, noslope) &&
|
||||||
CheckFree2x2Area(tile += TileDiffXY( 0, -1), maxz, noslope) ||
|
!CheckFree2x2Area(tile += TileDiffXY( 0, -1), maxz, noslope) &&
|
||||||
CheckFree2x2Area(tile += TileDiffXY( 1, 0), maxz, noslope)) {
|
!CheckFree2x2Area(tile += TileDiffXY( 1, 0), maxz, noslope)) {
|
||||||
break;
|
/* return to the original tile */
|
||||||
}
|
|
||||||
/* return to original tile */
|
|
||||||
tile += TileDiffXY(0, 1);
|
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 */
|
/* 'tile' is already checked above - CanBuildHouseHere() and slope test */
|
||||||
if (CheckBuildHouseSameZ(tile + TileDiffXY(1, 0), maxz, noslope)) break;
|
if (!CheckBuildHouseSameZ(tile + TileDiffXY(1, 0), maxz, noslope)) {
|
||||||
|
if (!CheckBuildHouseSameZ(tile + TileDiffXY(-1, 0), maxz, noslope)) continue;
|
||||||
if (CheckBuildHouseSameZ(tile + TileDiffXY(-1, 0), maxz, noslope)) {
|
|
||||||
tile += TileDiffXY(-1, 0);
|
tile += TileDiffXY(-1, 0);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else if (hs->building_flags & TILE_SIZE_1x2) {
|
} else if (hs->building_flags & TILE_SIZE_1x2) {
|
||||||
if (CheckBuildHouseSameZ(tile + TileDiffXY(0, 1), maxz, noslope)) break;
|
if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, 1), maxz, noslope)) {
|
||||||
|
if (!CheckBuildHouseSameZ(tile + TileDiffXY(0, -1), maxz, noslope)) continue;
|
||||||
if (CheckBuildHouseSameZ(tile + TileDiffXY(0, -1), maxz, noslope)) {
|
|
||||||
tile += TileDiffXY(0, -1);
|
tile += TileDiffXY(0, -1);
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* build the house */
|
||||||
t->num_houses++;
|
t->num_houses++;
|
||||||
IncreaseBuildingCount(t, house);
|
IncreaseBuildingCount(t, house);
|
||||||
|
|
||||||
|
@ -1865,6 +1863,10 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DoClearTownHouseHelper(TileIndex tile)
|
static void DoClearTownHouseHelper(TileIndex tile)
|
||||||
|
|
Loading…
Reference in New Issue