Wichtiger bugfix: borders.

Das ganze ist zu konfus, die hash-struktur hätte nicht in den border-structs mit drin sein sollen, aber das kind ist in den Brunnen gefallen, und heute fixe ich das nicht.
This commit is contained in:
Enno Rehling 2004-05-31 11:50:32 +00:00
parent 887aeb5037
commit c3b66dbe24
6 changed files with 120 additions and 105 deletions

View File

@ -51,18 +51,13 @@ use_questkey(struct unit * u, const struct item_type * itype, int amount, const
r1 = findregion(43,-39); r1 = findregion(43,-39);
r2 = findregion(44,-39); r2 = findregion(44,-39);
key1 = region_hashkey(r1); bo = get_borders(r1, r2);
key2 = region_hashkey(r2);
key = min(key2, key1) % BMAXHASH; while (bo!=NULL) {
bo = borders[key];
while (bo && !((bo->from==r1 && bo->to==r2) || (bo->from==r2 && bo->to==r1))) {
if(bo->type == &bt_questportal) { if(bo->type == &bt_questportal) {
break; break;
} }
bo = bo->nexthash; bo = bo->next;
} }
assert(bo != NULL); assert(bo != NULL);

View File

@ -42,14 +42,17 @@ free_borders(void)
border * border *
find_border(unsigned int id) find_border(unsigned int id)
{ {
int key; int key;
for (key=0;key!=BMAXHASH;key++) { for (key=0;key!=BMAXHASH;key++) {
border * b; border * bhash;
for (b=borders[key];b;b=b->next) { for (bhash=borders[key];bhash!=NULL;bhash=bhash->nexthash) {
if (b->id==id) return b; border * b;
} for (b=bhash;b;b=b->next) {
} if (b->id==id) return b;
return NULL; }
}
}
return NULL;
} }
void * void *
@ -195,33 +198,39 @@ attrib_type at_countdown = {
void void
age_borders(void) age_borders(void)
{ {
int i; border_list * deleted = NULL;
int i;
for (i=0;i!=BMAXHASH;++i) { for (i=0;i!=BMAXHASH;++i) {
border ** bp = &borders[i]; border * bhash = borders[i];
while (*bp) { for (;bhash;bhash=bhash->nexthash) {
border * b = *bp; border * b = bhash;
attrib ** ap = &b->attribs; for (;b;b=b->next) {
while (*ap) { attrib ** ap = &b->attribs;
attrib * a = *ap; while (*ap) {
if (a->type->age && a->type->age(a)==0) { attrib * a = *ap;
if (a->type == &at_countdown) { if (a->type->age && a->type->age(a)==0) {
erase_border(b); if (a->type == &at_countdown) {
b = NULL; border_list * bnew = malloc(sizeof(border_list));
/* bp bleibt, wie es ist, da der bnew->next = deleted;
* nächste border nun hier drin steht. */ bnew->data = b;
break; deleted = bnew;
} break;
a_remove(ap, a); }
} a_remove(ap, a);
else ap=&a->next; }
} else ap=&a->next;
if (b!=NULL) { }
/* bei löschung zeigt bp bereits auf den nächsten */
bp=&b->nexthash;
} }
} }
} }
while (deleted) {
border_list * blist = deleted;
border * b = blist->data;
erase_border(b);
deleted = blist->next;
free(deleted);
}
} }
/******** /********
@ -464,16 +473,18 @@ write_borders(FILE * f)
{ {
int i; int i;
for (i=0;i!=BMAXHASH;++i) { for (i=0;i!=BMAXHASH;++i) {
border * b; border * bhash;
for (b=borders[i];b;b=b->nexthash) { for (bhash=borders[i];bhash;bhash=bhash->nexthash) {
if (b->type->valid && !b->type->valid(b)) continue; border * b;
fprintf(f, "%s %d %d %d %d %d ", b->type->__name, b->id, b->from->x, b->from->y, b->to->x, b->to->y); for (b=bhash;b!=NULL;b=b->next) {
if (b->type->write) b->type->write(b, f); if (b->type->valid && !b->type->valid(b)) continue;
putc('\n', f); fprintf(f, "%s %d %d %d %d %d ", b->type->__name, b->id, b->from->x, b->from->y, b->to->x, b->to->y);
if (b->type->write) b->type->write(b, f);
#if RELEASE_VERSION>BORDER_VERSION #if RELEASE_VERSION>BORDER_VERSION
a_write(f, b->attribs); a_write(f, b->attribs);
putc('\n', f);
#endif #endif
putc('\n', f);
}
} }
} }
fputs("end", f); fputs("end", f);

View File

@ -25,13 +25,18 @@ extern "C" {
typedef struct border { typedef struct border {
struct border_type * type; /* the type of this border */ struct border_type * type; /* the type of this border */
struct border * next; /* next border between these regions */ struct border * next; /* next border between these regions */
struct border * nexthash; /* for internal use only */ struct border * nexthash; /* next border between these regions */
struct region * from, * to; /* borders can be directed edges */ struct region * from, * to; /* borders can be directed edges */
attrib * attribs; attrib * attribs;
void * data; void * data;
unsigned int id; /* unique id */ unsigned int id; /* unique id */
} border; } border;
typedef struct border_list {
struct border_list * next;
struct border * data;
} border_list;
typedef struct border_type { typedef struct border_type {
const char* __name; /* internal use only */ const char* __name; /* internal use only */
boolean (*transparent)(const border *, const struct faction *); boolean (*transparent)(const border *, const struct faction *);

View File

@ -199,7 +199,7 @@ convertunique(faction * f)
strcat(strcpy(zText, basepath()), "/subscriptions"); strcat(strcpy(zText, basepath()), "/subscriptions");
F = fopen(zText, "r"); F = fopen(zText, "r");
if (F==NULL) { if (F==NULL) {
log_error(("could not open %s.\n", zText)); log_warning(("could not open %s.\n", zText));
abort(); abort();
} }
for (;;) { for (;;) {

View File

@ -477,32 +477,32 @@ fix_demand_region(region *r)
static void static void
fix_firewalls(void) fix_firewalls(void)
{ {
region * r = regions; region * r = regions;
while (r) { while (r) {
direction_t d; direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
region * r2 = rconnect(r, d); region * r2 = rconnect(r, d);
if (r2) { if (r2) {
border * b = get_borders(r, r2); border * b = get_borders(r, r2);
while (b) { while (b) {
if (b->type==&bt_firewall) { if (b->type==&bt_firewall) {
attrib * a = a_find(b->attribs, &at_countdown); attrib * a = a_find(b->attribs, &at_countdown);
if (a==NULL || a->data.i <= 0) { if (a==NULL || a->data.i <= 0) {
erase_border(b); erase_border(b);
log_warning(("firewall between regions %s and %s was bugged. removed.\n", log_warning(("firewall between regions %s and %s was bugged. removed.\n",
regionid(r), regionid(r2))); regionid(r), regionid(r2)));
b = get_borders(r, r2); b = get_borders(r, r2);
} else { } else {
b = b->next; b = b->next;
} }
} else { } else {
b = b->next; b = b->next;
} }
} }
} }
} }
r = r->next; r = r->next;
} }
} }
extern attrib * make_atgmcreate(const struct item_type * itype); extern attrib * make_atgmcreate(const struct item_type * itype);
@ -1021,39 +1021,42 @@ extern border *borders[];
static void static void
fix_road_borders(void) fix_road_borders(void)
{ {
border *delete[10000]; border *deleted[10000];
int hash; int hash;
int i = 0; int i = 0;
for(hash=0; hash<BMAXHASH; hash++) { for(hash=0; hash<BMAXHASH; hash++) {
border * b; border * bhash;
for (b=borders[hash];b;b=b->next) { for (bhash=borders[hash];bhash;bhash=bhash->nexthash) {
if(b->type == &bt_road) { border * b;
int x1, x2, y1, y2; for (b=bhash;b;b=b->next) {
region *r1, *r2; if (b->type == &bt_road) {
int x1, x2, y1, y2;
region *r1, *r2;
x1 = b->from->x; x1 = b->from->x;
y1 = b->from->y; y1 = b->from->y;
x2 = b->to->x; x2 = b->to->x;
y2 = b->to->y; y2 = b->to->y;
r1 = findregion(x1, y1); r1 = findregion(x1, y1);
r2 = findregion(x2, y2); r2 = findregion(x2, y2);
if(r1->land == NULL || r2->land == NULL if (r1->land == NULL || r2->land == NULL
|| terrain[r1->terrain].roadreq == 0 || terrain[r1->terrain].roadreq == 0
|| terrain[r2->terrain].roadreq == 0) { || terrain[r2->terrain].roadreq == 0)
delete[i] = b; {
i++; deleted[i++] = b;
} }
} }
} }
} }
}
while(i>0) { while (i>0) {
i--; i--;
erase_border(delete[i]); erase_border(deleted[i]);
} }
} }
#ifdef WDW_PHOENIX #ifdef WDW_PHOENIX

View File

@ -271,6 +271,7 @@ static void
unit_addorder(unit& u, const char * str) unit_addorder(unit& u, const char * str)
{ {
addstrlist(&u.orders, str); addstrlist(&u.orders, str);
u.faction->lastorders = turn;
} }
static void static void