The issue is, as was already guessed in a few threads, that the loop that destroys and rebuilds buildings works with ticks, not days (btw, the entire concept of ticks is so stone age that it is really horrifying that this game still uses that as a concept of time at all. That's causing all kinds of bugs and problems and limitations for extensibility. You guys should really re-design that at some point)
Anyway, the fix is to change the tile variable time_until_rebuild from uint16 in the strange unit "number of tile loop updates" to int32 and store a date instead.
Since the value was decremented before only when evaluated (if my C++ is still right, god who writes such unreadable code), that SHOULD mean that this counter only started decreasing AFTER the minimum lifetime of the house in question was reached. Strangely enough that minimum seems to be mostly 0... is that value unused?
The code is like this: (the appropriate changes to the savegame loading etc have to be done also of course). I can't specify that code since I'm using all kinds of patches and I have my own savegame versioning for that. But anyone knowing how to handle patches will know how to adjust this to a trunk patch:
Code: Select all
--- src/town.h (revision 26273)
+++ src/town.h (working copy)
@@ -89,7 +89,7 @@
AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 map square of the town.
uint32 cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town.
- uint16 time_until_rebuild; ///< time until we rebuild a house
+ int32 time_until_rebuild; ///< date at which we we rebuild a house
uint16 grow_counter; ///< counter to count when to grow
uint16 growth_rate; ///< town growth rate
Code: Select all
Index: src/town_cmd.cpp
===================================================================
--- src/town_cmd.cpp (revision 26273)
+++ src/town_cmd.cpp (working copy)
Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
+ const int32 ticks_per_tile_loop = 256;
+
if ((hs->building_flags & BUILDING_HAS_1_TILE) &&
HasBit(t->flags, TOWN_IS_GROWING) &&
CanDeleteHouse(tile) &&
GetHouseAge(tile) >= hs->minimum_life &&
- --t->time_until_rebuild == 0) {
- t->time_until_rebuild = GB(r, 16, 8) + 192;
+ t->time_until_rebuild <= (_date - (hs->minimum_life * DAYS_IN_YEAR))) {
+
+ int32 tile_loops_until_rebuild = GB(r, 16, 8) + 192;
+ t->time_until_rebuild = _date + ((tile_loops_until_rebuild * ticks_per_tile_loop) / DEFAULT_DAY_TICKS);
ClearTownHouse(t, tile);
Code: Select all
static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
{
+ const int32 tile_loops_until_rebuild = 10;
+ const int32 ticks_per_tile_loop = 256;
+
t->xy = tile;
t->cache.num_houses = 0;
- t->time_until_rebuild = 10;
+ t->time_until_rebuild = _date + ((tile_loops_until_rebuild * ticks_per_tile_loop) / DEFAULT_DAY_TICKS);
UpdateTownRadius(t);
t->flags = 0;
t->cache.population = 0;
DEFAULT_DAY_TICKS here is btw the old 74 ticks independent of any daylength factor.
Any authors of daylength patches should try to incorporate this fix in their patches as otherwise the shrinking of towns is really a major issue. I had towns halve their size in less than 10 years.