- regions get a unique id (uid)

- new data format
- not in the CR yet
- fix for terrain (tutorial crash)
This commit is contained in:
Enno Rehling 2008-04-22 10:06:53 +00:00
parent 36812c1168
commit 2557e013fa
15 changed files with 68 additions and 33 deletions

View File

@ -46,6 +46,10 @@ extern "C" {
#include <settings.h>
#ifndef MAXREGIONS
# define MAXREGIONS 262139 /* must be prime for hashing. 262139=last<2^18 */
#endif
#define MONSTER_FACTION 0 /* Die Partei, in der die Monster sind. */
#define MAXPEASANTS_PER_AREA 10 /* number of peasants per region-size */
#define TREESIZE (MAXPEASANTS_PER_AREA-2) /* space used by trees (in #peasants) */

View File

@ -379,8 +379,28 @@ attrib_type at_moveblock = {
};
#define RMAXHASH 65521
region *regionhash[RMAXHASH];
#define RMAXHASH 65521 /* last prime <2^16 */
static region *regionhash[RMAXHASH];
static unsigned int uidhash[MAXREGIONS];
unsigned int
generate_region_id(void)
{
unsigned int uid;
for (;;) {
int key;
do {
uid = rng_int();
} while (uid==0);
key = uid % MAXREGIONS;
while (uidhash[key]!=0 && uidhash[key]!=uid) ++key;
if (uidhash[key]==0) {
uidhash[key] = uid;
break;
}
}
return uid;
}
static region *
rfindhash(short x, short y)
@ -789,7 +809,7 @@ static region *last;
static unsigned int max_index = 0;
region *
new_region(short x, short y)
new_region(short x, short y, unsigned int uid)
{
region *r = rfindhash(x, y);
@ -802,6 +822,8 @@ new_region(short x, short y)
r = calloc(1, sizeof(region));
r->x = x;
r->y = y;
if (uid==0) uid = generate_region_id();
r->uid = uid;
r->age = 1;
r->planep = findplane(x, y);
rhash(r);

View File

@ -96,6 +96,7 @@ typedef struct region {
/* an ascending number, to improve the speed of determining the interval in
which a faction has its units. See the implementations of firstregion
and lastregion */
unsigned int uid; /* a unique id */
short x, y;
struct plane *planep;
char *display;
@ -221,7 +222,7 @@ extern const char * regionname(const struct region * r, const struct faction * f
extern const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size);
extern void * resolve_region(variant data);
extern struct region * new_region(short x, short y);
extern struct region * new_region(short x, short y, unsigned int uid);
extern void terraform(struct region * r, terrain_t terrain);
extern void terraform_region(struct region * r, const struct terrain_type * terrain);
@ -242,6 +243,8 @@ extern struct region * r_connect(const struct region *, direction_t dir);
# define rconnect(r, dir) r_connect(r, dir)
#endif
extern unsigned int generate_region_id(void);
#ifdef __cplusplus
}
#endif

View File

@ -1113,10 +1113,18 @@ readregion(FILE * F, int encoding, short x, short y)
region * r = findregion(x, y);
const terrain_type * terrain;
char token[32];
unsigned int uid = 0;
if (global.data_version>=UID_VERSION) {
uid = ri(F);
} else {
uid = generate_region_id();
}
if (r==NULL) {
r = new_region(x, y);
r = new_region(x, y, uid);
} else {
r->uid = uid;
current_region = r;
while (r->attribs) a_remove(&r->attribs, r->attribs);
if (r->land) {
@ -1257,6 +1265,7 @@ readregion(FILE * F, int encoding, short x, short y)
void
writeregion(FILE * F, const region * r)
{
wi(F, r->uid);
fwritestr(F, r->display?(const char *)r->display:"");
fputc(' ', F);
ws(F, r->terrain->_name);
@ -1659,6 +1668,7 @@ readgame(const char * filename, int backup)
/* Regionen */
n = ri(F);
assert(n<MAXREGIONS);
if (rmax<0) rmax = n;
if (quiet<2) printf(" - Einzulesende Regionen: %d/%d\r", rmax, n);
if (loadplane || dirtyload || firstx || firsty || maxregions>=0) {

View File

@ -209,7 +209,7 @@ create_teleport_plane(void)
plane * pl = findplane(x, y);
if (pl==aplane) {
ra = new_region(x, y);
ra = new_region(x, y, 0);
if (fval(r->terrain, FORBIDDEN_REGION)) {
terraform_region(ra, thickfog);

View File

@ -51,12 +51,7 @@
#define ATTRIBREAD_VERSION 324 /* remove a_readint */
#define CURSEFLAGS_VERSION 325 /* remove a_readint */
#define UNICODE_VERSION 326 /* everything is stored as UTF8 */
#define UID_VERSION 327 /* everything is stored as UTF8 */
#define MIN_VERSION CURSETYPE_VERSION
#define REGIONOWNERS_VERSION 400
#ifdef ENEMIES
# define RELEASE_VERSION ENEMIES_VERSION
#else
# define RELEASE_VERSION UNICODE_VERSION
#endif
#define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */
#define RELEASE_VERSION UID_VERSION /* current datafile */

View File

@ -362,7 +362,7 @@ block_create(short x1, short y1, char terrain)
short x, y;
for (x=0;x!=BLOCKSIZE;++x) {
for (y=0;y!=BLOCKSIZE;++y) {
region * r = new_region(x1 + x, y1 + y);
region * r = new_region(x1 + x, y1 + y, 0);
terraform(r, terrain);
}
}

View File

@ -591,7 +591,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
assert(virgin_region(rconnect(rmin, dmin)));
x = rmin->x + delta_x[dmin];
y = rmin->y + delta_y[dmin];
r = new_region(x, y);
r = new_region(x, y, 0);
terraform(r, T_OCEAN); /* we change the terrain later */
}
}
@ -618,7 +618,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
if (rn && fval(rn, RF_MARK)) continue;
if (virgin_region(rn)) {
if (rn==NULL) {
rn = new_region(r->x + delta_x[d], r->y + delta_y[d]);
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0);
terraform(rn, T_OCEAN);
}
add_regionlist(&rlist, rn);
@ -711,7 +711,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
region * rn = rconnect(r, d);
if (rn==NULL) {
const struct terrain_type * terrain = newterrain(T_OCEAN);
rn = new_region(r->x + delta_x[d], r->y + delta_y[d]);
rn = new_region(r->x + delta_x[d], r->y + delta_y[d], 0);
if (rng_int() % SPECIALCHANCE < special) {
terrain = random_terrain(true);
special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */
@ -740,7 +740,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island)
}
if (i!=MAXFILLDIST) {
while (--i) {
region * rn = new_region(r->x + i*delta_x[d], r->y + i*delta_y[d]);
region * rn = new_region(r->x + i*delta_x[d], r->y + i*delta_y[d], 0);
terraform(rn, T_OCEAN);
}
}

View File

@ -650,12 +650,12 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl
maxx = minx+2*radius; cx = minx+radius;
maxy = miny+2*radius; cy = miny+radius;
p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags);
center = new_region(cx, cy);
center = new_region(cx, cy, 0);
for (x=0;x<=2*radius;++x) {
short y;
for (y=0;y<=2*radius;++y) {
region * r = findregion(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y, 0);
freset(r, RF_ENCOUNTER);
r->planep = p;
if (distance(r, center)==radius) {
@ -763,12 +763,12 @@ gm_addplane(short radius, unsigned int flags, const char * name)
maxx = minx+2*radius; cx = minx+radius;
maxy = miny+2*radius; cy = miny+radius;
p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags);
center = new_region(cx, cy);
center = new_region(cx, cy, 0);
for (x=0;x<=2*radius;++x) {
short y;
for (y=0;y<=2*radius;++y) {
region * r = findregion(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y);
if (!r) r = new_region(minx+x, miny+y, 0);
freset(r, RF_ENCOUNTER);
r->planep = p;
if (distance(r, center)==radius) {

View File

@ -204,7 +204,7 @@ create_museum(void)
if (findregion(9525, 9525) == NULL) {
/* Eingangshalle */
r = new_region(9525, 9525);
r = new_region(9525, 9525, 0);
terraform_region(r, terrain_hall);
r->planep = museum;
rsetname(r, "Eingangshalle");
@ -217,7 +217,7 @@ create_museum(void)
r = findregion(9526, 9525);
if(!r) {
/* Lounge */
r = new_region(9526, 9525);
r = new_region(9526, 9525, 0);
terraform_region(r, terrain_hall);
r->planep = museum;
rsetname(r, "Lounge");
@ -261,7 +261,7 @@ create_museum(void)
r = findregion(9524, 9526);
if(!r) {
r = new_region(9524, 9526);
r = new_region(9524, 9526, 0);
terraform_region(r, terrain_corridor);
r->planep = museum;
rsetname(r, "Nördliche Promenade");
@ -272,7 +272,7 @@ create_museum(void)
}
r = findregion(9525, 9524);
if(!r) {
r = new_region(9525, 9524);
r = new_region(9525, 9524, 0);
terraform_region(r, terrain_corridor);
r->planep = museum;
rsetname(r, "Südliche Promenade");

View File

@ -49,7 +49,7 @@ make_block(short x, short y, short radius, const struct terrain_type * terrain)
for (cy = y - radius; cy != y+radius; ++cy) {
if (koor_distance(cx, cy, x, y) < radius) {
if (!findregion(cx, cy)) {
r = new_region(cx, cy);
r = new_region(cx, cy, 0);
terraform_region(r, terrain);
}
}

View File

@ -440,7 +440,7 @@ terraform_at(coordinate * c, const terrain_type *terrain)
if (terrain!=NULL) {
short x = (short)c->x, y = (short)c->y;
region * r = findregion(x, y);
if (r==NULL) r = new_region(x, y);
if (r==NULL) r = new_region(x, y, 0);
terraform_region(r, terrain);
}
}
@ -457,7 +457,7 @@ terraform_selection(selection * selected, const terrain_type *terrain)
tag * t = *tp;
short x = (short)t->coord.x, y = (short)t->coord.y;
region * r = findregion(x, y);
if (r==NULL) r = new_region(x, y);
if (r==NULL) r = new_region(x, y, 0);
terraform_region(r, terrain);
tp = &t->nexthash;
}

View File

@ -597,7 +597,7 @@ frame_regions(void)
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r, d);
if (rn==NULL) {
rn = new_region(r->x+delta_x[d], r->y+delta_y[d]);
rn = new_region(r->x+delta_x[d], r->y+delta_y[d], 0);
terraform(rn, T_FIREWALL);
rn->age=r->age;
}

View File

@ -221,7 +221,7 @@ region_terraform(short x, short y, const char * tname)
}
return NULL;
}
if (r==NULL) r = new_region(x, y);
if (r==NULL) r = new_region(x, y, 0);
terraform_region(r, terrain);
return r;
}
@ -380,6 +380,7 @@ bind_region(lua_State * L)
.def("set_resource", &region_setresource)
.def_readonly("x", &region::x)
.def_readonly("y", &region::y)
.def_readonly("id", &region::uid)
.def_readwrite("age", &region::age)
.def("add_item", &region_additem)
.property("items", &region_items, return_stl_iterator)

View File

@ -84,5 +84,5 @@
<!-- used for the museum only -->
<terrain name="hall1" fly="no" size="0" />
<terrain name="corridor1" fly="no" size="0" />
<terrain name="wall1" sail="no" land="no" walk="no" sail="no" fly="no" forbidden="yes" size="0" />
<terrain name="wall1" sail="no" walk="no" fly="no" forbidden="yes" size="0" />
</terrains>