diff options
author | truelight <truelight@openttd.org> | 2005-02-01 18:32:01 +0000 |
---|---|---|
committer | truelight <truelight@openttd.org> | 2005-02-01 18:32:01 +0000 |
commit | 59ac6e8c4b2e564a864260d6715d2128a291b1d0 (patch) | |
tree | b7d40aab99c9bff1a5304e4659c8cc7748b8a881 | |
parent | 567224e94089f26e0c64aa37c7c40937285fb8fa (diff) | |
download | openttd-59ac6e8c4b2e564a864260d6715d2128a291b1d0.tar.xz |
(svn r1764) -Add: dynamic towns, you can now have up to 64k towns (let me know when
you have that amount of towns in a map ;))
-rw-r--r-- | ai_new.c | 28 | ||||
-rw-r--r-- | oldloader.c | 3 | ||||
-rw-r--r-- | saveload.c | 6 | ||||
-rw-r--r-- | town.h | 25 | ||||
-rw-r--r-- | town_cmd.c | 69 | ||||
-rw-r--r-- | town_gui.c | 12 | ||||
-rw-r--r-- | ttd.c | 3 |
7 files changed, 105 insertions, 41 deletions
@@ -366,11 +366,11 @@ static void AiNew_State_LocateRoute(Player *p) { // increase the temp with one, and return. We will come back later here // to try again p->ainew.temp++; - if (p->ainew.from_type == AI_CITY) { - if (p->ainew.temp >= _total_towns) p->ainew.temp = 0; - } else { - if (p->ainew.temp >= _total_industries) p->ainew.temp = 0; - } + if (p->ainew.from_type == AI_CITY) { + if (p->ainew.temp >= (int)_total_towns) p->ainew.temp = 0; + } else { + if (p->ainew.temp >= _total_industries) p->ainew.temp = 0; + } // Don't do an attempt if we are trying the same id as the last time... if (p->ainew.last_id == p->ainew.temp) return; @@ -489,15 +489,15 @@ static void AiNew_State_LocateRoute(Player *p) { } } - // It was not a valid city - // increase the temp with one, and return. We will come back later here - // to try again - p->ainew.temp++; - if (p->ainew.to_type == AI_CITY) { - if (p->ainew.temp >= _total_towns) p->ainew.temp = 0; - } else { - if (p->ainew.temp >= _total_industries) p->ainew.temp = 0; - } + // It was not a valid city + // increase the temp with one, and return. We will come back later here + // to try again + p->ainew.temp++; + if (p->ainew.to_type == AI_CITY) { + if (p->ainew.temp >= (int)_total_towns) p->ainew.temp = 0; + } else { + if (p->ainew.temp >= _total_industries) p->ainew.temp = 0; + } // Don't do an attempt if we are trying the same id as the last time... if (p->ainew.last_id == p->ainew.temp) return; diff --git a/oldloader.c b/oldloader.c index 4862c14a2..1b8bca9c2 100644 --- a/oldloader.c +++ b/oldloader.c @@ -595,6 +595,9 @@ static void FixTown(OldTown *o, int num, byte town_name_type) if (o->xy == 0) continue; + if (!AddBlockIfNeeded(&_town_pool, i)) + error("Towns: failed loading savegame: too many towns"); + t = GetTown(i); t->xy = o->xy; diff --git a/saveload.c b/saveload.c index 54931a2bb..6378ea0ff 100644 --- a/saveload.c +++ b/saveload.c @@ -944,7 +944,11 @@ static void *IntToReference(uint r, uint t) case REF_ORDER: return GetOrder(r - 1); case REF_VEHICLE: return GetVehicle(r - 1); case REF_STATION: return GetStation(r - 1); - case REF_TOWN: return GetTown(r - 1); + case REF_TOWN: { + if (!AddBlockIfNeeded(&_town_pool, r - 1)) + error("Towns: failed loading savegame: too many towns"); + return GetTown(r - 1); + } case REF_ROADSTOPS: //return (byte*)_roadstops + (r - 1) * sizeof(_roadstops[0]); @@ -1,6 +1,7 @@ #ifndef TOWN_H #define TOWN_H +#include "pool.h" #include "player.h" struct Town { @@ -128,20 +129,30 @@ enum { bool CheckforTownRating(uint tile, uint32 flags, Town *t, byte type); -VARDEF Town _towns[250]; -VARDEF uint _towns_size; - VARDEF uint16 *_town_sort; +extern MemoryPool _town_pool; + +/** + * Get the pointer to the town with index 'index' + */ static inline Town *GetTown(uint index) { - assert(index < _towns_size); - return &_towns[index]; + return (Town*)GetItemFromPool(&_town_pool, index); +} + +/** + * Get the current size of the TownPool + */ +static inline uint16 GetTownPoolSize(void) +{ + return _town_pool.total_items; } -#define FOR_ALL_TOWNS(t) for(t = _towns; t != &_towns[_towns_size]; t++) +#define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1 < GetTownPoolSize()) ? GetTown(t->index + 1) : NULL) +#define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0) -VARDEF int _total_towns; // For the AI: the amount of towns active +VARDEF uint _total_towns; // For the AI: the amount of towns active VARDEF bool _town_sort_dirty; VARDEF byte _town_sort_order; 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) diff --git a/town_gui.c b/town_gui.c index 96922d357..cd08386b1 100644 --- a/town_gui.c +++ b/town_gui.c @@ -367,14 +367,18 @@ static int CDECL TownNameSorter(const void *a, const void *b) { char buf1[64]; const Town *t; - byte val; + uint16 val; int r; t = GetTown(*(const uint16*)a); SetDParam(0, t->townnameparts); GetString(buf1, t->townnametype); - if ( (val=*(const uint16*)b) != _last_town_idx) { + /* If 'b' is the same town as in the last round, use the cached value + * We do this to speed stuff up ('b' is called with the same value a lot of + * times after eachother) */ + val = *(const uint16*)b; + if (val != _last_town_idx) { _last_town_idx = val; t = GetTown(val); SetDParam(0, t->townnameparts); @@ -401,12 +405,12 @@ static void MakeSortedTownList(void) int n = 0; /* Create array for sorting */ - _town_sort = realloc(_town_sort, _towns_size * sizeof(_town_sort[0])); + _town_sort = realloc(_town_sort, GetTownPoolSize() * sizeof(_town_sort[0])); if (_town_sort == NULL) error("Could not allocate memory for the town-sorting-list"); FOR_ALL_TOWNS(t) - if(t->xy) + if (t->xy) _town_sort[n++] = t->index; _num_town_sort = n; @@ -503,7 +503,6 @@ static void InitializeDynamicVariables(void) _vehicles_size = lengthof(_vehicles); _vehicle_sort = NULL; - _towns_size = lengthof(_towns); _town_sort = NULL; _industries_size = lengthof(_industries); @@ -516,6 +515,8 @@ static void InitializeDynamicVariables(void) static void UnInitializeDynamicVariables(void) { /* Dynamic stuff needs to be free'd somewhere... */ + CleanPool(&_town_pool); + free(_station_sort); free(_vehicle_sort); |