mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(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 ;))
This commit is contained in:
parent
6d5fdc2b68
commit
777dd99585
28
ai_new.c
28
ai_new.c
@ -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]);
|
||||
|
25
town.h
25
town.h
@ -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);
|
||||
}
|
||||
|
||||
#define FOR_ALL_TOWNS(t) for(t = _towns; t != &_towns[_towns_size]; t++)
|
||||
/**
|
||||
* Get the current size of the TownPool
|
||||
*/
|
||||
static inline uint16 GetTownPoolSize(void)
|
||||
{
|
||||
return _town_pool.total_items;
|
||||
}
|
||||
|
||||
VARDEF int _total_towns; // For the AI: the amount of towns active
|
||||
#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 uint _total_towns; // For the AI: the amount of towns active
|
||||
|
||||
VARDEF bool _town_sort_dirty;
|
||||
VARDEF byte _town_sort_order;
|
||||
|
71
town_cmd.c
71
town_cmd.c
@ -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);
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
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)
|
||||
|
12
town_gui.c
12
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;
|
||||
|
3
ttd.c
3
ttd.c
@ -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…
Reference in New Issue
Block a user