(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 ;))
pull/155/head
truelight 20 years ago
parent 567224e940
commit 59ac6e8c4b

@ -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;

@ -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;

@ -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;

@ -17,6 +17,27 @@
#include "gui.h"
#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)

@ -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);

Loading…
Cancel
Save