summaryrefslogtreecommitdiff
path: root/town_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'town_cmd.c')
-rw-r--r--town_cmd.c69
1 files changed, 55 insertions, 14 deletions
diff --git a/town_cmd.c b/town_cmd.c
index eb6f5eaa6..eeb1aff49 100644
--- a/town_cmd.c
+++ b/town_cmd.c
@@ -18,6 +18,27 @@
#include "network.h"
enum {
+ /* Max towns: 64000 (8 * 8000) */
+ TOWN_POOL_BLOCK_SIZE_BITS = 3, /* In bits, so (1 << 3) == 8 */
+ TOWN_POOL_MAX_BLOCKS = 8000,
+};
+
+/**
+ * Called if a new block is added to the town-pool
+ */
+static void TownPoolNewBlock(uint start_item)
+{
+ Town *t;
+
+ FOR_ALL_TOWNS_FROM(t, start_item)
+ t->index = start_item++;
+}
+
+/* Initialize the town-pool */
+MemoryPool _town_pool = { "Towns", TOWN_POOL_MAX_BLOCKS, TOWN_POOL_BLOCK_SIZE_BITS, sizeof(Town), &TownPoolNewBlock, 0, 0, NULL };
+
+
+enum {
TOWN_HAS_CHURCH = 0x02,
TOWN_HAS_STADIUM = 0x04
};
@@ -413,13 +434,13 @@ void OnTick_Town(void)
return;
i = _cur_town_ctr;
+ if (++_cur_town_ctr >= GetTownPoolSize())
+ _cur_town_ctr = 0;
+
t = GetTown(i);
- if (++i == _towns_size) i = 0;
- _cur_town_ctr = i;
if (t->xy != 0)
TownTickHandler(t);
-
}
static byte GetTownRoadMask(TileIndex tile)
@@ -954,10 +975,22 @@ static Town *AllocateTown(void)
Town *t;
FOR_ALL_TOWNS(t) {
if (t->xy == 0) {
- if (t->index > _total_towns) _total_towns = t->index;
+ uint index = t->index;
+
+ if (t->index > _total_towns)
+ _total_towns = t->index;
+
+ memset(t, 0, sizeof(Town));
+ t->index = index;
+
return t;
}
}
+
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_town_pool))
+ return AllocateTown();
+
return NULL;
}
@@ -1835,22 +1868,18 @@ void TownsMonthlyLoop(void)
void InitializeTowns(void)
{
Subsidy *s;
- Town *t;
- int i;
-
- memset(_towns, 0, sizeof(_towns[0]) * _towns_size);
- i = 0;
- FOR_ALL_TOWNS(t)
- t->index = i++;
+ /* Clean the town pool and create 1 block in it */
+ CleanPool(&_town_pool);
+ AddBlockToPool(&_town_pool);
memset(_subsidies, 0, sizeof(_subsidies));
for (s=_subsidies; s != endof(_subsidies); s++)
s->cargo_type = 0xFF;
_cur_town_ctr = 0;
- _town_sort_dirty = true;
_total_towns = 0;
+ _town_sort_dirty = true;
}
const TileTypeProcs _tile_type_town_procs = {
@@ -1941,12 +1970,24 @@ static void Save_TOWN(void)
static void Load_TOWN(void)
{
int index;
+
while ((index = SlIterateArray()) != -1) {
- Town *t = GetTown(index);
+ Town *t;
+ if (!AddBlockIfNeeded(&_town_pool, index))
+ error("Towns: failed loading savegame: too many towns");
+
+ t = GetTown(index);
SlObject(t, _town_desc);
- if (index > _total_towns) _total_towns = index;
+
+ if ((uint)index > _total_towns)
+ _total_towns = index;
}
+
+ /* This is to ensure all pointers are within the limits of
+ * the size of the TownPool */
+ if (_cur_town_ctr >= GetTownPoolSize())
+ _cur_town_ctr = 0;
}
void AfterLoadTown(void)