From 9d3a08523addb530bec6d02c09c1858856baca2f Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 15 Apr 2008 22:27:28 +0000 Subject: [PATCH] (svn r12726) -Fix [FS#1877]: overflow causing strange building behaviour in towns. --- src/newgrf_town.cpp | 20 ++++++++++---------- src/town.h | 2 +- src/town_cmd.cpp | 30 ++++++++++++++---------------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index d28fe99383..a15203fb74 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -36,16 +36,16 @@ uint32 TownGetVariable(byte variable, byte parameter, bool *available, const Tow case 0x8A: return t->grow_counter; case 0x92: return t->flags12; // In original game, 0x92 and 0x93 are really one word. Since flags12 is a byte, this is to adjust case 0x93: return 0; - case 0x94: return t->radius[0]; - case 0x95: return GB(t->radius[0], 8, 8); - case 0x96: return t->radius[1]; - case 0x97: return GB(t->radius[1], 8, 8); - case 0x98: return t->radius[2]; - case 0x99: return GB(t->radius[2], 8, 8); - case 0x9A: return t->radius[3]; - case 0x9B: return GB(t->radius[3], 8, 8); - case 0x9C: return t->radius[4]; - case 0x9D: return GB(t->radius[4], 8, 8); + case 0x94: return ClampToU16(t->squared_town_zone_radius[0]); + case 0x95: return GB(ClampToU16(t->squared_town_zone_radius[0]), 8, 8); + case 0x96: return ClampToU16(t->squared_town_zone_radius[1]); + case 0x97: return GB(ClampToU16(t->squared_town_zone_radius[1]), 8, 8); + case 0x98: return ClampToU16(t->squared_town_zone_radius[2]); + case 0x99: return GB(ClampToU16(t->squared_town_zone_radius[2]), 8, 8); + case 0x9A: return ClampToU16(t->squared_town_zone_radius[3]); + case 0x9B: return GB(ClampToU16(t->squared_town_zone_radius[3]), 8, 8); + case 0x9C: return ClampToU16(t->squared_town_zone_radius[4]); + case 0x9D: return GB(ClampToU16(t->squared_town_zone_radius[4]), 8, 8); case 0x9E: return t->ratings[0]; case 0x9F: return GB(t->ratings[0], 8, 8); case 0xA0: return t->ratings[1]; diff --git a/src/town.h b/src/town.h index 9e01b77718..e85307edd7 100644 --- a/src/town.h +++ b/src/town.h @@ -163,7 +163,7 @@ struct Town : PoolItem { bool larger_town; /* NOSAVE: UpdateTownRadius updates this given the house count. */ - uint16 radius[HZB_END]; + uint32 squared_town_zone_radius[HZB_END]; /* NOSAVE: The number of each type of building in the town. */ BuildingCounts building_counts; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 156eb66de5..2c77eb0096 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1301,7 +1301,7 @@ static bool GrowTown(Town *t) void UpdateTownRadius(Town *t) { - static const uint16 _town_radius_data[23][5] = { + static const uint16 _town_squared_town_zone_radius_data[23][5] = { { 4, 0, 0, 0, 0}, // 0 { 16, 0, 0, 0, 0}, { 25, 0, 0, 0, 0}, @@ -1328,19 +1328,17 @@ void UpdateTownRadius(Town *t) }; if (t->num_houses < 92) { - memcpy(t->radius, _town_radius_data[t->num_houses / 4], sizeof(t->radius)); + memcpy(t->squared_town_zone_radius, _town_squared_town_zone_radius_data[t->num_houses / 4], sizeof(t->squared_town_zone_radius)); } else { int mass = t->num_houses / 8; - /* At least very roughly extrapolate. Empirical numbers dancing between - * overwhelming by cottages and skyscrapers outskirts. */ - t->radius[0] = mass * mass; - /* Actually we are proportional to sqrt() but that's right because - * we are covering an area. */ - t->radius[1] = mass * 7; - t->radius[2] = 0; - t->radius[3] = mass * 4; - t->radius[4] = mass * 3; - //debug("%d (->%d): %d %d %d %d\n", t->num_houses, mass, t->radius[0], t->radius[1], t->radius[3], t->radius[4]); + /* Actually we are proportional to sqrt() but that's right because we are covering an area. + * The offsets are to make sure the radii do not decrease in size when going from the table + * to the calculated value.*/ + t->squared_town_zone_radius[0] = mass * 15 - 40; + t->squared_town_zone_radius[1] = mass * 9 - 15; + t->squared_town_zone_radius[2] = 0; + t->squared_town_zone_radius[3] = mass * 5 - 5; + t->squared_town_zone_radius[4] = mass * 3 + 5; } } @@ -1603,8 +1601,8 @@ bool GenerateTowns() /** Returns the bit corresponding to the town zone of the specified tile - * @param t Town on which radius is to be found - * @param tile TileIndex where radius needs to be found + * @param t Town on which town zone is to be found + * @param tile TileIndex where town zone needs to be found * @return the bit position of the given zone, as defined in HouseZones */ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile) @@ -1615,7 +1613,7 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile) HouseZonesBits smallest = HZB_TOWN_EDGE; for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) { - if (dist < t->radius[i]) smallest = i; + if (dist < t->squared_town_zone_radius[i]) smallest = i; } return smallest; @@ -2298,7 +2296,7 @@ static void UpdateTownGrowRate(Town *t) const Station *st; FOR_ALL_STATIONS(st) { - if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) { + if (DistanceSquare(st->xy, t->xy) <= t->squared_town_zone_radius[0]) { if (st->time_since_load <= 20 || st->time_since_unload <= 20) { n++; if (IsValidPlayer(st->owner)) {