- new_border() war verwirrt darüber, wie man borders abspeichert.
This commit is contained in:
Enno Rehling 2004-05-22 21:01:13 +00:00
parent 4f14c6fbfb
commit 51c5570bf2
2 changed files with 143 additions and 146 deletions

View File

@ -57,17 +57,28 @@ resolve_borderid(void * id) {
return (void*)find_border((unsigned int)id); return (void*)find_border((unsigned int)id);
} }
static border **
get_borders_i(const region * r1, const region * r2)
{
border ** bp;
int key = region_hashkey(r1);
int k2 = region_hashkey(r2);
key = min(k2, key) % BMAXHASH;
bp = &borders[key];
while (*bp) {
border * b = *bp;
if ((b->from==r1 && b->to==r2) || (b->from==r2 && b->to==r1)) break;
bp = &b->nexthash;
}
return bp;
}
border * border *
get_borders(const region * r1, const region * r2) get_borders(const region * r1, const region * r2)
{ {
border * b; border ** bp = get_borders_i(r1, r2);
int key = region_hashkey(r1); return *bp;
int k2 = region_hashkey(r2);
key = min(k2, key) % BMAXHASH;
b = borders[key];
while (b && !((b->from==r1 && b->to==r2) || (b->from==r2 && b->to==r1))) b = b->nexthash;
return b;
} }
void void
@ -134,54 +145,40 @@ read_borders(FILE * f)
border * border *
new_border(border_type * type, region * from, region * to) new_border(border_type * type, region * from, region * to)
{ {
border ** bp, * b; border ** bp = get_borders_i(from, to);
int key = region_hashkey(from); border * b = calloc(1, sizeof(struct border));
int k2 = region_hashkey(to);
key = min(k2, key) % BMAXHASH; b->type = type;
bp = &borders[key]; b->nexthash = *bp;
b->next = *bp;
/* find the first border across the same edge, so we can insert before it. b->from = from;
* if there's no border here yet, add the border to the end (this way, the b->to = to;
* b->next pointer will point to *bp, which is NULL). b->id = ++nextborder;
*/ *bp = b;
while (*bp && ((*bp)->from!=from || (*bp)->to!=to)) {
bp = &(*bp)->nexthash;
}
b = calloc(1, sizeof(struct border));
b->type = type;
b->nexthash = *bp;
b->next = *bp;
b->from = from;
b->to = to;
b->id = ++nextborder;
*bp = b;
if (type->init) type->init(b); if (type->init) type->init(b);
return b; return b;
} }
void void
erase_border(border * b) erase_border(border * b)
{ {
border ** np = NULL, ** hp; border ** bp = get_borders_i(b->from, b->to);
int key = region_hashkey(b->from); border ** np = NULL;
int k2 = region_hashkey(b->to); attrib ** ap = &b->attribs;
attrib ** ap = &b->attribs;
while (*ap) a_remove(ap, *ap); while (*ap) a_remove(ap, *ap);
key = min(k2, key) % BMAXHASH;
hp = &borders[key]; while (*bp && *bp != b) {
while (*hp && *hp != b) { border * bprev = *bp;
border * bp = *hp; if (bprev->next==b) np=&bprev->next;
if (bp->next==b) np = &bp->next; bp = &bprev->next;
hp = &(*hp)->nexthash;
} }
assert(*hp!=NULL || !"error: border is not registered"); assert(*bp!=NULL || !"error: border is not registered");
if (np!=NULL) *np = b->next; if (np!=NULL) *np = b->next;
*hp = b->nexthash; *bp = b->nexthash;
if (b->type->destroy) b->type->destroy(b); if (b->type->destroy) b->type->destroy(b);
free(b); free(b);
} }
void void

View File

@ -1,16 +1,16 @@
/* vi: set ts=2: /* vi: set ts=2:
* *
* *
* Eressea PB(E)M host Copyright (C) 1998-2003 * Eressea PB(E)M host Copyright (C) 1998-2003
* Christian Schlittchen (corwin@amber.kn-bremen.de) * Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de)
* Henning Peters (faroul@beyond.kn-bremen.de) * Henning Peters (faroul@beyond.kn-bremen.de)
* Enno Rehling (enno@eressea-pbem.de) * Enno Rehling (enno@eressea-pbem.de)
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
* *
* This program may not be used, modified or distributed without * This program may not be used, modified or distributed without
* prior permission by the authors of Eressea. * prior permission by the authors of Eressea.
*/ */
#ifndef H_KRNL_BORDER #ifndef H_KRNL_BORDER
#define H_KRNL_BORDER #define H_KRNL_BORDER
@ -20,104 +20,104 @@ extern "C" {
#define BMAXHASH 8191 #define BMAXHASH 8191
extern unsigned int nextborder; extern unsigned int nextborder;
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; /* for internal use only */
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_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 *);
/* is it possible to see through this? */ /* is it possible to see through this? */
void (*init)(border *); void (*init)(border *);
/* constructor: initialize the border. allocate extra memory if needed */ /* constructor: initialize the border. allocate extra memory if needed */
void (*destroy)(border *); void (*destroy)(border *);
/* destructor: remove all extra memory for destruction */ /* destructor: remove all extra memory for destruction */
void (*read)(border *, FILE *); void (*read)(border *, FILE *);
void (*write)(const border *, FILE *); void (*write)(const border *, FILE *);
boolean (*block)(const border *, const struct unit *, const struct region * r); boolean (*block)(const border *, const struct unit *, const struct region * r);
/* return true if it blocks movement of u from /* return true if it blocks movement of u from
* r to the opposite struct region. * r to the opposite struct region.
* warning: struct unit may be NULL. * warning: struct unit may be NULL.
*/ */
const char *(*name)(const border * b, const struct region * r, const struct faction * f, int gflags); const char *(*name)(const border * b, const struct region * r, const struct faction * f, int gflags);
/* for example "a wall of fog" or "a doorway from r1 to r2" /* for example "a wall of fog" or "a doorway from r1 to r2"
* may depend on the struct faction, for example "a wall" may * may depend on the struct faction, for example "a wall" may
* turn out to be "an illusionary wall" * turn out to be "an illusionary wall"
*/ */
boolean (*rvisible)(const border *, const struct region *); boolean (*rvisible)(const border *, const struct region *);
/* is it visible to everyone in r ? /* is it visible to everyone in r ?
* if not, it may still be fvisible() for some f. * if not, it may still be fvisible() for some f.
*/ */
boolean (*fvisible)(const border *, const struct faction *, const struct region *); boolean (*fvisible)(const border *, const struct faction *, const struct region *);
/* is it visible to units of f in r? /* is it visible to units of f in r?
* the function shall not check for * the function shall not check for
* existence of a struct unit in r. Example: a spell * existence of a struct unit in r. Example: a spell
* may be visible only to the struct faction that created it and thus * may be visible only to the struct faction that created it and thus
* appear in it's report (if there is a struct unit of f in r, which * appear in it's report (if there is a struct unit of f in r, which
* the reporting function will have to assure). * the reporting function will have to assure).
* if not true, it may still be uvisible() for some u. * if not true, it may still be uvisible() for some u.
*/ */
boolean (*uvisible)(const border *, const struct unit *); boolean (*uvisible)(const border *, const struct unit *);
/* is it visible to u ? /* is it visible to u ?
* a doorway may only be visible to a struct unit with perception > 5 * a doorway may only be visible to a struct unit with perception > 5
*/ */
boolean (*valid)(const border *); boolean (*valid)(const border *);
/* is the border in a valid state, /* is the border in a valid state,
* or should it be erased at the end of this turn to save space? * or should it be erased at the end of this turn to save space?
*/ */
void (*move)(const border *, struct unit * u, const struct region * from, const struct region * to); void (*move)(const border *, struct unit * u, const struct region * from, const struct region * to);
/* executed when the units traverses this border */ /* executed when the units traverses this border */
struct border_type * next; /* for internal use only */ struct border_type * next; /* for internal use only */
} border_type; } border_type;
extern border * find_border(unsigned int id); extern border * find_border(unsigned int id);
void * resolve_borderid(void * data); void * resolve_borderid(void * data);
extern border * get_borders(const struct region * r1, const struct region * r2); extern border * get_borders(const struct region * r1, const struct region * r2);
/* returns the list of borders between r1 and r2 or r2 and r1 */ /* returns the list of borders between r1 and r2 or r2 and r1 */
extern border * new_border(border_type * type, struct region * from, struct region * to); extern border * new_border(border_type * type, struct region * from, struct region * to);
/* creates a border of the specified type */ /* creates a border of the specified type */
extern void erase_border(border * b); extern void erase_border(border * b);
/* remove the border from memory */ /* remove the border from memory */
extern border_type * find_bordertype(const char * name); extern border_type * find_bordertype(const char * name);
extern void register_bordertype(border_type * type); extern void register_bordertype(border_type * type);
/* register a new bordertype */ /* register a new bordertype */
extern void read_borders(FILE * f); extern void read_borders(FILE * f);
extern void write_borders(FILE * f); extern void write_borders(FILE * f);
extern void age_borders(void); extern void age_borders(void);
/* provide default implementations for some member functions: */ /* provide default implementations for some member functions: */
extern void b_read(border * b, FILE *f); extern void b_read(border * b, FILE *f);
extern void b_write(const border * b, FILE *f); extern void b_write(const border * b, FILE *f);
extern boolean b_blockall(const border *, const struct unit *, const struct region *); extern boolean b_blockall(const border *, const struct unit *, const struct region *);
extern boolean b_blocknone(const border *, const struct unit *, const struct region *); extern boolean b_blocknone(const border *, const struct unit *, const struct region *);
extern boolean b_rvisible(const border *, const struct region * r); extern boolean b_rvisible(const border *, const struct region * r);
extern boolean b_fvisible(const border *, const struct faction * f, const struct region *); extern boolean b_fvisible(const border *, const struct faction * f, const struct region *);
extern boolean b_uvisible(const border *, const struct unit * u); extern boolean b_uvisible(const border *, const struct unit * u);
extern boolean b_rinvisible(const border *, const struct region * r); extern boolean b_rinvisible(const border *, const struct region * r);
extern boolean b_finvisible(const border *, const struct faction * f, const struct region *); extern boolean b_finvisible(const border *, const struct faction * f, const struct region *);
extern boolean b_uinvisible(const border *, const struct unit * u); extern boolean b_uinvisible(const border *, const struct unit * u);
extern boolean b_transparent(const border *, const struct faction *); extern boolean b_transparent(const border *, const struct faction *);
extern boolean b_opaque(const border *, const struct faction *); /* !transparent */ extern boolean b_opaque(const border *, const struct faction *); /* !transparent */
extern border_type bt_fogwall; extern border_type bt_fogwall;
extern border_type bt_noway; extern border_type bt_noway;
extern border_type bt_wall; extern border_type bt_wall;
extern border_type bt_illusionwall; extern border_type bt_illusionwall;
extern border_type bt_road; extern border_type bt_road;
extern border_type bt_questportal; extern border_type bt_questportal;
extern attrib_type at_countdown; extern attrib_type at_countdown;
#ifdef __cplusplus #ifdef __cplusplus
} }