Code-Vereinfachung: regionlist und region_list zu einem Typ gemerged

Code-Beschleunigung: Pathfinding schneller und schlauer
This commit is contained in:
Enno Rehling 2004-02-21 12:18:29 +00:00
parent d1751cb0a3
commit 6ccb1b9bf6
15 changed files with 162 additions and 339 deletions

View File

@ -1335,12 +1335,12 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
if (sd->mode==see_unit && r->planep && r->planep->id == 1 && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) if (sd->mode==see_unit && r->planep && r->planep->id == 1 && !is_cursed(r->attribs, C_ASTRALBLOCK, 0))
{ {
/* Sonderbehandlung Teleport-Ebene */ /* Sonderbehandlung Teleport-Ebene */
regionlist *rl = allinhab_in_range(r_astral_to_standard(r),TP_RADIUS); region_list *rl = allinhab_in_range(r_astral_to_standard(r),TP_RADIUS);
if (rl) { if (rl) {
regionlist *rl2 = rl; region_list *rl2 = rl;
while(rl2) { while(rl2) {
region * r = rl2->region; region * r = rl2->data;
fprintf(F, "SCHEMEN %d %d\n", region_x(r, f), region_y(r, f)); fprintf(F, "SCHEMEN %d %d\n", region_x(r, f), region_y(r, f));
fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); fprintf(F, "\"%s\";Name\n", rname(r, f->locale));
rl2 = rl2->next; rl2 = rl2->next;

View File

@ -380,27 +380,39 @@ dragon_affinity_value(region *r, unit *u)
static attrib * static attrib *
set_new_dragon_target(unit * u, region * r, int range) set_new_dragon_target(unit * u, region * r, int range)
{ {
region *r2; int max_affinity = 0;
int x, y;
int affinity, max_affinity = 0;
region *max_region = NULL; region *max_region = NULL;
for (x = r->x - range; x < r->x + range; x++) { #if 1
region_list * rptr, * rlist = regions_in_range(r, range, allowed_dragon);
for (rptr=rlist;rptr;rptr=rptr->next) {
region * r2 = rptr->data;
int affinity = dragon_affinity_value(r2, u);
if (affinity > max_affinity) {
max_affinity = affinity;
max_region = r2;
}
}
free_regionlist(rlist);
#else
int x, y;
for (x = r->x - range; x < r->x + range; x++) {
for (y = r->y - range; y < r->y + range; y++) { for (y = r->y - range; y < r->y + range; y++) {
if (koor_distance (r->x, r->y, x, y) <= range region * r2 = findregion(x, y);
&& (r2 = findregion(x, y)) != 0 if (r2!=NULL) {
&& int affinity = dragon_affinity_value(r2, u);
path_exists(r, r2, range, allowed_dragon) if (affinity > max_affinity) {
) { if (koor_distance (r->x, r->y, x, y) <= range && path_exists(r, r2, range, allowed_dragon))
affinity = dragon_affinity_value(r2, u); {
if(affinity > max_affinity) { max_affinity = affinity;
max_affinity = affinity; max_region = r2;
max_region = r2; }
} }
} }
} }
} }
#endif
if (max_region && max_region != r) { if (max_region && max_region != r) {
attrib * a = a_find(u->attribs, &at_targetregion); attrib * a = a_find(u->attribs, &at_targetregion);
if (!a) { if (!a) {
@ -1063,7 +1075,6 @@ plan_monsters(void)
} }
} }
if (tr!=NULL) { if (tr!=NULL) {
#ifdef NEW_PATH
switch(old_race(u->race)) { switch(old_race(u->race)) {
case RC_FIREDRAGON: case RC_FIREDRAGON:
set_movement_order(u, tr, 4, allowed_dragon); set_movement_order(u, tr, 4, allowed_dragon);
@ -1075,19 +1086,6 @@ plan_monsters(void)
set_movement_order(u, tr, 1, allowed_dragon); set_movement_order(u, tr, 1, allowed_dragon);
break; break;
} }
#else
switch(old_race(u->race)) {
case RC_FIREDRAGON:
set_movement_order(u, r, ta->data.sa[0], ta->data.sa[1], 4);
break;
case RC_DRAGON:
set_movement_order(u, r, ta->data.sa[0], ta->data.sa[1], 3);
break;
case RC_WYRM:
set_movement_order(u, r, ta->data.sa[0], ta->data.sa[1], 1);
break;
}
#endif
if (rand()%100 < 15) { if (rand()%100 < 15) {
/* do a growl */ /* do a growl */
if (rname(tr, u->faction->locale)) { if (rname(tr, u->faction->locale)) {

View File

@ -1532,7 +1532,7 @@ randomevents(void)
#if NEW_LAEN #if NEW_LAEN
void growlaen(void) { void growlaen(void) {
region *r; region *r;
regionlist *Berge=NULL, *rl; region_list *Berge=NULL, *rl;
unit *u; unit *u;
int b=0, Laen, z, add; int b=0, Laen, z, add;
short *add_laen; short *add_laen;

View File

@ -1366,14 +1366,14 @@ describe(FILE * F, const region * r, int partial, faction * f)
if (partial==0 && r->planep && r->planep->id == 1 && if (partial==0 && r->planep && r->planep->id == 1 &&
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
/* Sonderbehandlung Teleport-Ebene */ /* Sonderbehandlung Teleport-Ebene */
regionlist *rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS); region_list *rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
regionlist *rl2; region_list *rl2;
if (rl) { if (rl) {
strcpy(buf, "Schemen der Regionen "); strcpy(buf, "Schemen der Regionen ");
rl2 = rl; rl2 = rl;
while(rl2) { while(rl2) {
scat(f_regionid(rl2->region, f)); scat(f_regionid(rl2->data, f));
rl2 = rl2->next; rl2 = rl2->next;
if(rl2) scat(", "); if(rl2) scat(", ");
} }

View File

@ -38,8 +38,8 @@ const int FIREWORK_RANGE=10;
static int static int
use_birthday_firework(struct unit * u, const struct item_type * itype, int amount, const char *cm) use_birthday_firework(struct unit * u, const struct item_type * itype, int amount, const char *cm)
{ {
regionlist *rlist = all_in_range(u->region, FIREWORK_RANGE); region_list *rlist = all_in_range(u->region, FIREWORK_RANGE);
regionlist *rl; region_list *rl;
message *m; message *m;
const char *name; const char *name;
@ -62,8 +62,8 @@ use_birthday_firework(struct unit * u, const struct item_type * itype, int amoun
add_message(&u->region->msgs, new_message(u->faction, "birthday_firework_noname_local%u:unit%s:name",u)); add_message(&u->region->msgs, new_message(u->faction, "birthday_firework_noname_local%u:unit%s:name",u));
} }
for(rl = rlist; rl; rl=rl->next) if(rl->region != u->region) { for(rl = rlist; rl; rl=rl->next) if(rl->data != u->region) {
add_message(&rl->region->msgs, m); add_message(&rl->data->msgs, m);
} }
msg_release(m); msg_release(m);

View File

@ -1160,15 +1160,7 @@ farcasting(unit *magician, region *r)
mult = (int)pow(2.0,(double)dist); mult = (int)pow(2.0,(double)dist);
if (dist > 1) { if (dist > 1) {
#ifdef NEW_PATH
if (!path_exists(magician->region, r, dist*2, allowed_fly)) mult = 1025; if (!path_exists(magician->region, r, dist*2, allowed_fly)) mult = 1025;
#else
region *rn;
for (rn=regions;rn;rn=rn->next) freset(rn, FL_DH);
if (step(magician->region,r,FLY,dist*2) == false) {
mult = 1025;
}
#endif
} }
return mult; return mult;

View File

@ -28,7 +28,6 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef NEW_PATH
boolean boolean
allowed_swim(const region * src, const region * target) allowed_swim(const region * src, const region * target)
{ {
@ -50,8 +49,6 @@ allowed_fly(const region * src, const region * target)
return false; return false;
} }
#define FAST_PATH
#ifdef FAST_PATH
typedef struct node { typedef struct node {
struct node * next; struct node * next;
region * r; region * r;
@ -86,6 +83,53 @@ free_node(node * n)
return s; return s;
} }
static void
free_nodes(node * root)
{
while (root!=NULL) {
region * r = root->r;
freset(r, FL_MARK);
root = free_node(root);
}
}
struct region_list *
regions_in_range(struct region * start, int maxdist, boolean (*allowed)(const struct region*, const struct region*))
{
region_list * rlist = NULL;
node * root = new_node(start, 0, NULL);
node ** end = &root->next;
node * n = root;
while (n!=NULL) {
region * r = n->r;
int depth = n->distance+1;
direction_t d;
if (n->distance >= maxdist) break;
for (d=0;d!=MAXDIRECTIONS; ++d) {
region * rn = rconnect(r, d);
region_list * rnew;
if (rn==NULL) continue;
if (fval(rn, FL_MARK)) continue; /* already been there */
if (!allowed(r, rn)) continue; /* can't go there */
/* add the region to the list of available ones. */
add_regionlist(&rlist, rn);
/* make sure we don't go here again, and put the region into the set for
further BFS'ing */
fset(rn, FL_MARK);
*end = new_node(rn, depth, n);
end = &(*end)->next;
}
n = n->next;
}
free_nodes(root);
return rlist;
}
static region ** static region **
internal_path_find(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*)) internal_path_find(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*))
{ {
@ -126,11 +170,7 @@ internal_path_find(region *start, const region *target, int maxlen, boolean (*al
if (found) break; if (found) break;
n = n->next; n = n->next;
} }
while (root!=NULL) { free_nodes(root);
region * r = root->r;
freset(r, FL_MARK);
root = free_node(root);
}
if (found) return path; if (found) return path;
return NULL; return NULL;
} }
@ -150,198 +190,3 @@ path_find(region *start, const region *target, int maxlen, boolean (*allowed)(co
assert((!fval(start, FL_MARK) && !fval(target, FL_MARK)) || !"Did you call path_init()?"); assert((!fval(start, FL_MARK) && !fval(target, FL_MARK)) || !"Did you call path_init()?");
return internal_path_find(start, target, maxlen, allowed); return internal_path_find(start, target, maxlen, allowed);
} }
#else
static boolean
internal_path_exists(region *start, const region *target, int maxlen, int * depth, boolean (*allowed)(const region*, const region*))
{
int position = *depth;
direction_t dir;
assert(maxlen<=MAXDEPTH);
assert(position<=maxlen);
*depth = INT_MAX;
if (start==target) {
*depth = position;
return true;
} else if (position==maxlen) {
return false; /* not found */
}
position++;
fset(start, FL_MARK);
for (dir=0; dir != MAXDIRECTIONS; dir++) {
int deep = position;
region * rn = rconnect(start, dir);
if (rn==NULL) continue;
if (fval(rn, FL_MARK)) continue; /* already been there */
if (!allowed(start, rn)) continue; /* can't go there */
if (internal_path_exists(rn, target, maxlen, &deep, allowed)) {
*depth = deep;
break;
}
}
freset(start, FL_MARK);
return (dir!=MAXDIRECTIONS);
}
static region **
internal_path_find(region *start, const region *target, int maxlen, int * depth, boolean (*allowed)(const region*, const region*))
{
static region * path[MAXDEPTH+2];
static region * bestpath[MAXDEPTH+2];
int position = *depth;
direction_t dir;
assert(maxlen<=MAXDEPTH);
assert(position<=maxlen);
*depth = INT_MAX;
path[position] = start;
if (start==target) {
*depth = position;
path[position+1] = NULL;
return path;
} else if (position==maxlen) {
return NULL; /* not found */
}
position++;
bestpath[position] = NULL;
fset(start, FL_MARK);
for (dir=0; dir != MAXDIRECTIONS; dir++) {
int deep = position;
region * rn = rconnect(start, dir);
region ** findpath;
if (rn==NULL) continue;
if (fval(rn, FL_MARK)) continue;
if (!allowed(start, rn)) continue;
findpath = internal_path_find(rn, target, maxlen, &deep, allowed);
if (deep<=maxlen) {
assert(findpath);
maxlen = deep;
memcpy(bestpath, findpath, sizeof(region*)*(maxlen+2));
}
}
freset(start, FL_MARK);
if (bestpath[position]!=NULL) return bestpath;
return NULL;
}
boolean
path_exists(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*))
{
int len = 0;
boolean exist;
assert((!fval(start, FL_MARK) && !fval(target, FL_MARK)) || !"Did you call path_init()?");
exist = internal_path_exists(start, target, maxlen, &len, allowed);
assert(exist == (path_find(start, target, maxlen, allowed)!=NULL));
return exist;
}
region **
path_find(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*))
{
int depth = 0;
assert((!fval(start, FL_MARK) && !fval(target, FL_MARK)) || !"Did you call path_init()?");
return internal_path_find(start, target, maxlen, &depth, allowed);
}
#endif
#else
static boolean
step_store(region *r, region *target, int t, int depth)
{
direction_t dir;
search[depth][0] = r->x;
search[depth][1] = r->y;
fset(r, FL_MARK);
if(depth > MAXDEPTH) return false;
for(dir=0; dir < MAXDIRECTIONS; dir++) {
region * rn = rconnect(r, dir);
if (rn==NULL) continue;
if(rn && !fval(rn, FL_MARK) && allowed_terrain(rn->terrain, r->terrain, t)) {
if(rn == target) {
search[depth+1][0] = rn->x;
search[depth+1][1] = rn->y;
search_len = depth+1;
return true;
}
if(step_store(rn, target, t, depth+1)) return true;
}
}
return false;
}
boolean
path_find(region *start, region *target, int t)
{
region *r;
for(r=regions;r;r=r->next) freset(r, FL_MARK);
return step_store(start, target, t, 0);
}
int search[MAXDEPTH][2];
int search_len;
static boolean
allowed_terrain(terrain_t ter, terrain_t ter_last, int t)
{
if((t & DRAGON_LIMIT) && ter == T_OCEAN && ter_last == T_GLACIER)
return false;
if(t & FLY && terrain[ter].flags & FLY_INTO) return true;
if(t & SWIM && terrain[ter].flags & SWIM_INTO) return true;
if(t & WALK && terrain[ter].flags & WALK_INTO) return true;
/* Alte Variante:
if(terrain[ter].flags & FORBIDDEN_LAND) return false;
if(t & FLY) return true;
if(t & SWIM && !(t & WALK) && ter == T_OCEAN) return true;
if(t & SWIM && t & WALK) return true;
if(t & WALK && ter != T_OCEAN) return true;
*/
return false;
}
boolean
step(region *r, region *target, int t, int depth)
{
direction_t dir;
region *rn;
fset(r, FL_MARK);
if(depth > MAXDEPTH) return false;
for(dir=0; dir < MAXDIRECTIONS; dir++) {
rn = rconnect(r, dir);
if(rn && !fval(rn, FL_MARK) && allowed_terrain(rn->terrain, r->terrain, t)) {
if(rn == target) return true;
if(step(rn, target, t, depth+1)) return true;
}
}
return false;
}
boolean
path_exists(region *start, region *target, int t)
{
region *r;
for(r=regions;r;r=r->next) freset(r, FL_MARK);
return step(start, target, t, 0);
}
#endif

View File

@ -23,19 +23,12 @@ extern "C" {
extern int search[MAXDEPTH][2]; extern int search[MAXDEPTH][2];
extern int search_len; extern int search_len;
#define NEW_PATH
#ifdef NEW_PATH
extern struct region ** path_find(struct region *start, const struct region *target, int maxlen, boolean (*allowed)(const struct region*, const struct region*)); extern struct region ** path_find(struct region *start, const struct region *target, int maxlen, boolean (*allowed)(const struct region*, const struct region*));
extern boolean path_exists(struct region *start, const struct region *target, int maxlen, boolean (*allowed)(const struct region*, const struct region*)); extern boolean path_exists(struct region *start, const struct region *target, int maxlen, boolean (*allowed)(const struct region*, const struct region*));
extern boolean allowed_swim(const struct region * src, const struct region * target); extern boolean allowed_swim(const struct region * src, const struct region * target);
extern boolean allowed_fly(const struct region * src, const struct region * target); extern boolean allowed_fly(const struct region * src, const struct region * target);
extern boolean allowed_walk(const struct region * src, const struct region * target); extern boolean allowed_walk(const struct region * src, const struct region * target);
#else extern struct region_list * regions_in_range(struct region * src, int maxdist, boolean (*allowed)(const struct region*, const struct region*));
extern boolean path_find(struct region *start, struct region *target, int t);
extern boolean path_exists(struct region *start, struct region *target, int t);
extern boolean step(struct region *r, struct region *target, int t, int depth);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -360,22 +360,22 @@ reldirection(region * from, region * to)
} }
void void
free_regionlist(regionlist *rl) free_regionlist(region_list *rl)
{ {
while (rl) { while (rl) {
regionlist * rl2 = rl->next; region_list * rl2 = rl->next;
free(rl); free(rl);
rl = rl2; rl = rl2;
} }
} }
void void
add_regionlist(regionlist **rl, region *r) add_regionlist(region_list **rl, region *r)
{ {
regionlist *rl2 = (regionlist*)malloc(sizeof(regionlist)); region_list *rl2 = (region_list*)malloc(sizeof(region_list));
rl2->region = r; rl2->data = r;
rl2->next = *rl; rl2->next = *rl;
*rl = rl2; *rl = rl2;
} }

View File

@ -148,13 +148,8 @@ void initrhash(void);
void rhash(struct region * r); void rhash(struct region * r);
void runhash(struct region * r); void runhash(struct region * r);
typedef struct regionlist { void free_regionlist(region_list *rl);
struct regionlist *next; void add_regionlist(region_list **rl, struct region *r);
struct region *region;
} regionlist;
void free_regionlist(regionlist *rl);
void add_regionlist(regionlist **rl, struct region *r);
int woodcount(const struct region * r); int woodcount(const struct region * r);
int deathcount(const struct region * r); int deathcount(const struct region * r);

View File

@ -1911,7 +1911,7 @@ static int
sp_treewalkexit(castorder *co) sp_treewalkexit(castorder *co)
{ {
region *rt; region *rt;
regionlist *rl, *rl2; region_list *rl, *rl2;
int tax, tay; int tax, tay;
unit *u, *u2; unit *u, *u2;
int remaining_cap; int remaining_cap;
@ -1951,8 +1951,8 @@ sp_treewalkexit(castorder *co)
rl2 = rl; rl2 = rl;
while(rl2) { while(rl2) {
if(rl2->region->x == tax && rl2->region->y == tay) { if(rl2->data->x == tax && rl2->data->y == tay) {
rt = rl2->region; rt = rl2->data;
break; break;
} }
rl2 = rl2->next; rl2 = rl2->next;
@ -2234,7 +2234,7 @@ sp_fog_of_confusion(castorder *co)
double power = co->force; double power = co->force;
double range; double range;
int duration; int duration;
regionlist *rl,*rl2; region_list *rl,*rl2;
range = (power-11)/3-1; range = (power-11)/3-1;
duration = (int)((power-11)/1.5)+1; duration = (int)((power-11)/1.5)+1;
@ -2243,8 +2243,8 @@ sp_fog_of_confusion(castorder *co)
for(rl2 = rl; rl2; rl2 = rl2->next) { for(rl2 = rl; rl2; rl2 = rl2->next) {
curse * c; curse * c;
if(rterrain(rl2->region) != T_OCEAN if(rterrain(rl2->data) != T_OCEAN
&& !r_isforest(rl2->region)) continue; && !r_isforest(rl2->data)) continue;
/* Magieresistenz jeder Region prüfen */ /* Magieresistenz jeder Region prüfen */
if (target_resists_magic(mage, r, TYP_REGION, 0)){ if (target_resists_magic(mage, r, TYP_REGION, 0)){
@ -2252,18 +2252,18 @@ sp_fog_of_confusion(castorder *co)
continue; continue;
} }
c = create_curse(mage, &rl2->region->attribs, c = create_curse(mage, &rl2->data->attribs,
ct_find("disorientationzone"), power, duration, cast_level*5, 0); ct_find("disorientationzone"), power, duration, cast_level*5, 0);
/* Soll der schon in der Zauberrunde wirken? */ /* Soll der schon in der Zauberrunde wirken? */
curse_setflag(c, CURSE_ISNEW); curse_setflag(c, CURSE_ISNEW);
for (u = rl2->region->units; u; u = u->next) freset(u->faction, FL_DH); for (u = rl2->data->units; u; u = u->next) freset(u->faction, FL_DH);
for(u = rl2->region->units; u; u = u->next ) { for (u = rl2->data->units; u; u = u->next ) {
if(!fval(u->faction, FL_DH) ) { if(!fval(u->faction, FL_DH) ) {
fset(u->faction, FL_DH); fset(u->faction, FL_DH);
sprintf(buf, "%s beschwört einen Schleier der Verwirrung.", sprintf(buf, "%s beschwört einen Schleier der Verwirrung.",
cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand"); cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand");
addmessage(rl2->region, u->faction, buf, MSG_EVENT, ML_INFO); addmessage(rl2->data, u->faction, buf, MSG_EVENT, ML_INFO);
} }
} }
if(!fval(mage->faction, FL_DH)){ if(!fval(mage->faction, FL_DH)){
@ -2774,7 +2774,7 @@ sp_summondragon(castorder *co)
unit *u; unit *u;
int cast_level = co->level; int cast_level = co->level;
double power = co->force; double power = co->force;
regionlist *rl,*rl2; region_list *rl,*rl2;
faction *f; faction *f;
int time; int time;
int number; int number;
@ -2817,7 +2817,7 @@ sp_summondragon(castorder *co)
rl = all_in_range(r, (int)power); rl = all_in_range(r, (int)power);
for(rl2 = rl; rl2; rl2 = rl2->next) { for(rl2 = rl; rl2; rl2 = rl2->next) {
for(u = rl2->region->units; u; u = u->next) { for(u = rl2->data->units; u; u = u->next) {
if (u->race == new_race[RC_WYRM] || u->race == new_race[RC_DRAGON]) { if (u->race == new_race[RC_WYRM] || u->race == new_race[RC_DRAGON]) {
attrib * a = a_find(u->attribs, &at_targetregion); attrib * a = a_find(u->attribs, &at_targetregion);
if (!a) { if (!a) {
@ -2825,7 +2825,7 @@ sp_summondragon(castorder *co)
} else { } else {
a->data.v = co->rt; a->data.v = co->rt;
} }
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->region), regionid(co->rt)); sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->data), regionid(co->rt));
usetprivate(u, buf); usetprivate(u, buf);
} }
} }
@ -4971,7 +4971,7 @@ sp_dragonsong(castorder *co)
unit *u; unit *u;
int cast_level = co->level; int cast_level = co->level;
double power = co->force; double power = co->force;
regionlist *rl,*rl2; region_list *rl,*rl2;
faction *f; faction *f;
/* TODO HP-Effekt */ /* TODO HP-Effekt */
@ -4981,7 +4981,7 @@ sp_dragonsong(castorder *co)
rl = all_in_range(r, (int)power); rl = all_in_range(r, (int)power);
for(rl2 = rl; rl2; rl2 = rl2->next) { for(rl2 = rl; rl2; rl2 = rl2->next) {
for(u = rl2->region->units; u; u = u->next) { for(u = rl2->data->units; u; u = u->next) {
if (u->race->flags & RCF_DRAGON) { if (u->race->flags & RCF_DRAGON) {
attrib * a = a_find(u->attribs, &at_targetregion); attrib * a = a_find(u->attribs, &at_targetregion);
if (!a) { if (!a) {
@ -4989,7 +4989,7 @@ sp_dragonsong(castorder *co)
} else { } else {
a->data.v = r; a->data.v = r;
} }
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->region), regionid(r)); sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->data), regionid(r));
usetprivate(u, buf); usetprivate(u, buf);
} }
} }
@ -5536,7 +5536,7 @@ int
sp_dream_of_confusion(castorder *co) sp_dream_of_confusion(castorder *co)
{ {
unit *u; unit *u;
regionlist *rl,*rl2; region_list *rl,*rl2;
region *r = co->rt; region *r = co->rt;
unit *mage = (unit *)co->magician; unit *mage = (unit *)co->magician;
int cast_level = co->level; int cast_level = co->level;
@ -5547,25 +5547,26 @@ sp_dream_of_confusion(castorder *co)
rl = all_in_range(r, (int)range); rl = all_in_range(r, (int)range);
for(rl2 = rl; rl2; rl2 = rl2->next) { for(rl2 = rl; rl2; rl2 = rl2->next) {
region * r2 = rl2->data;
curse * c; curse * c;
/* Magieresistenz jeder Region prüfen */ /* Magieresistenz jeder Region prüfen */
if (target_resists_magic(mage, rl2->region, TYP_REGION, 0)){ if (target_resists_magic(mage, r2, TYP_REGION, 0)){
report_failure(mage, co->order); report_failure(mage, co->order);
continue; continue;
} }
c = create_curse(mage, &rl2->region->attribs, c = create_curse(mage, &r2->attribs,
ct_find("disorientationzone"), power, duration, cast_level*5, 0); ct_find("disorientationzone"), power, duration, cast_level*5, 0);
/* soll der Zauber schon in der Zauberrunde wirken? */ /* soll der Zauber schon in der Zauberrunde wirken? */
curse_setflag(c, CURSE_ISNEW); curse_setflag(c, CURSE_ISNEW);
for (u = rl2->region->units; u; u = u->next) freset(u->faction, FL_DH); for (u = r2->units; u; u = u->next) freset(u->faction, FL_DH);
for (u = rl2->region->units; u; u = u->next ) { for (u = r2->units; u; u = u->next ) {
if(!fval(u->faction, FL_DH) ) { if(!fval(u->faction, FL_DH) ) {
fset(u->faction, FL_DH); fset(u->faction, FL_DH);
sprintf(buf, "%s beschwört einen Schleier der Verwirrung.", sprintf(buf, "%s beschwört einen Schleier der Verwirrung.",
cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand"); cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand");
addmessage(rl2->region, u->faction, buf, MSG_EVENT, ML_INFO); addmessage(r2, u->faction, buf, MSG_EVENT, ML_INFO);
} }
} }
if(!fval(mage->faction, FL_DH)){ if(!fval(mage->faction, FL_DH)){
@ -5865,7 +5866,7 @@ sp_pullastral(castorder *co)
{ {
region *rt, *ro; region *rt, *ro;
unit *u, *u2; unit *u, *u2;
regionlist *rl, *rl2; region_list *rl, *rl2;
int remaining_cap; int remaining_cap;
int n, w; int n, w;
region *r = co->rt; region *r = co->rt;
@ -5881,9 +5882,10 @@ sp_pullastral(castorder *co)
ro = pa->param[0]->data.r; ro = pa->param[0]->data.r;
rl = all_in_range(r_astral_to_standard(r), TP_RADIUS); rl = all_in_range(r_astral_to_standard(r), TP_RADIUS);
rl2 = rl; rl2 = rl;
while(rl2) { while (rl2!=NULL) {
if(rl2->region->x == ro->x && rl2->region->y == ro->y) { region * r2 = rl2->data;
ro = rl2->region; if (r2->x == ro->x && r2->y == ro->y) {
ro = r2;
break; break;
} }
rl2 = rl2->next; rl2 = rl2->next;
@ -5991,7 +5993,7 @@ int
sp_leaveastral(castorder *co) sp_leaveastral(castorder *co)
{ {
region *rt, *ro; region *rt, *ro;
regionlist *rl, *rl2; region_list *rl, *rl2;
unit *u, *u2; unit *u, *u2;
int remaining_cap; int remaining_cap;
int n, w; int n, w;
@ -6012,11 +6014,11 @@ sp_leaveastral(castorder *co)
} }
rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS); rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
rl2 = rl; rl2 = rl;
while(rl2) { while (rl2!=NULL) {
if(rl2->region == rt) break; if (rl2->data == rt) break;
rl2 = rl2->next; rl2 = rl2->next;
} }
if(!rl2) { if (rl2==NULL) {
addmessage(r, mage->faction, "Dorthin führt kein Weg.", addmessage(r, mage->faction, "Dorthin führt kein Weg.",
MSG_MAGIC, ML_MISTAKE); MSG_MAGIC, ML_MISTAKE);
free_regionlist(rl); free_regionlist(rl);
@ -6230,7 +6232,7 @@ sp_showastral(castorder *co)
region *rt; region *rt;
int n = 0; int n = 0;
int c = 0; int c = 0;
regionlist *rl, *rl2; region_list *rl, *rl2;
region *r = co->rt; region *r = co->rt;
unit *mage = (unit *)co->magician; unit *mage = (unit *)co->magician;
int cast_level = co->level; int cast_level = co->level;
@ -6259,8 +6261,8 @@ sp_showastral(castorder *co)
/* Erst Einheiten zählen, für die Grammatik. */ /* Erst Einheiten zählen, für die Grammatik. */
for(rl2=rl; rl2; rl2=rl2->next) { for(rl2=rl; rl2; rl2=rl2->next) {
if(!is_cursed(rl2->region->attribs, C_ASTRALBLOCK, 0)) { if(!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) {
for(u = rl2->region->units; u; u=u->next) { for(u = rl2->data->units; u; u=u->next) {
if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) n++; if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) n++;
} }
} }
@ -6278,8 +6280,8 @@ sp_showastral(castorder *co)
"Nebel zu erkennen sind ", unitname(mage)); "Nebel zu erkennen sind ", unitname(mage));
for(rl2=rl; rl2; rl2=rl2->next) { for(rl2=rl; rl2; rl2=rl2->next) {
if(!is_cursed(rl2->region->attribs, C_ASTRALBLOCK, 0)) { if(!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) {
for(u = rl2->region->units; u; u=u->next) { for(u = rl2->data->units; u; u=u->next) {
if(u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) { if(u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) {
c++; c++;
scat(unitname(u)); scat(unitname(u));
@ -6292,7 +6294,7 @@ sp_showastral(castorder *co)
scat(" "); scat(" ");
scat(LOC(mage->faction->locale, rc_name(u->race, u->number!=1))); scat(LOC(mage->faction->locale, rc_name(u->race, u->number!=1)));
scat(", Entfernung "); scat(", Entfernung ");
icat(distance(rl2->region, rt)); icat(distance(rl2->data, rt));
scat(")"); scat(")");
if(c == n-1) { if(c == n-1) {
scat(" und "); scat(" und ");
@ -6319,7 +6321,7 @@ sp_showastral(castorder *co)
int int
sp_viewreality(castorder *co) sp_viewreality(castorder *co)
{ {
regionlist *rl, *rl2; region_list *rl, *rl2;
unit *u; unit *u;
region *r = co->rt; region *r = co->rt;
unit *mage = (unit *)co->magician; unit *mage = (unit *)co->magician;
@ -6341,7 +6343,7 @@ sp_viewreality(castorder *co)
/* Irgendwann mal auf Curses u/o Attribut umstellen. */ /* Irgendwann mal auf Curses u/o Attribut umstellen. */
for(rl2=rl; rl2; rl2=rl2->next) { for(rl2=rl; rl2; rl2=rl2->next) {
u = createunit(rl2->region, mage->faction, RS_FARVISION, new_race[RC_SPELL]); u = createunit(rl2->data, mage->faction, RS_FARVISION, new_race[RC_SPELL]);
set_string(&u->name, "Zauber: Blick in die Realität"); set_string(&u->name, "Zauber: Blick in die Realität");
u->age = 2; u->age = 2;
} }
@ -6358,7 +6360,7 @@ sp_viewreality(castorder *co)
int int
sp_disruptastral(castorder *co) sp_disruptastral(castorder *co)
{ {
regionlist *rl, *rl2; region_list *rl, *rl2;
region *rt; region *rt;
unit *u; unit *u;
region *r = co->rt; region *r = co->rt;
@ -6389,16 +6391,17 @@ sp_disruptastral(castorder *co)
for (rl2=rl; rl2!=NULL; rl2=rl2->next) { for (rl2=rl; rl2!=NULL; rl2=rl2->next) {
attrib *a, *a2; attrib *a, *a2;
region * r2 = rl2->data;
spec_direction *sd; spec_direction *sd;
int inhab_regions = 0; int inhab_regions = 0;
regionlist * trl = NULL; region_list * trl = NULL;
if (is_cursed(rl2->region->attribs, C_ASTRALBLOCK, 0)) continue; if (is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) continue;
if (rl2->region->units!=NULL) { if (r2->units!=NULL) {
regionlist * trl2; region_list * trl2;
trl = allinhab_in_range(r_astral_to_standard(rl2->region), TP_RADIUS); trl = allinhab_in_range(r_astral_to_standard(rl2->data), TP_RADIUS);
for (trl2 = trl; trl2; trl2 = trl2->next) ++inhab_regions; for (trl2 = trl; trl2; trl2 = trl2->next) ++inhab_regions;
} }
@ -6415,15 +6418,15 @@ sp_disruptastral(castorder *co)
/* Einheiten auswerfen */ /* Einheiten auswerfen */
if (trl!=NULL) { if (trl!=NULL) {
for (u=rl2->region->units;u;u=u->next) { for (u=r2->units;u;u=u->next) {
if (u->race != new_race[RC_SPELL]) { if (u->race != new_race[RC_SPELL]) {
regionlist *trl2 = trl; region_list *trl2 = trl;
region *tr; region *tr;
int c = rand() % inhab_regions; int c = rand() % inhab_regions;
/* Zufällige Zielregion suchen */ /* Zufällige Zielregion suchen */
while (c--!=0) trl2 = trl2->next; while (c--!=0) trl2 = trl2->next;
tr = trl2->region; tr = trl2->data;
if(!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { if(!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) {
move_unit(u, tr, NULL); move_unit(u, tr, NULL);
@ -6437,9 +6440,9 @@ sp_disruptastral(castorder *co)
} }
/* Kontakt unterbinden */ /* Kontakt unterbinden */
create_curse(mage, &rl2->region->attribs, ct_find("astralblock"), create_curse(mage, &rl2->data->attribs, ct_find("astralblock"),
power, duration, 100, 0); power, duration, 100, 0);
addmessage(rl2->region, 0, "Mächtige Magie verhindert den Kontakt zur Realität.", addmessage(r2, 0, "Mächtige Magie verhindert den Kontakt zur Realität.",
MSG_COMMENT, ML_IMPORTANT); MSG_COMMENT, ML_IMPORTANT);
} }

View File

@ -88,11 +88,11 @@ r_astral_to_standard(const region *r)
return r2; return r2;
} }
regionlist * region_list *
all_in_range(region *r, int n) all_in_range(region *r, int n)
{ {
int x,y; int x,y;
regionlist *rlist = NULL; region_list *rlist = NULL;
region *r2; region *r2;
if(r == NULL) return NULL; /* Um Probleme abzufangen, if(r == NULL) return NULL; /* Um Probleme abzufangen,
@ -178,11 +178,11 @@ create_teleport_plane(void)
} }
} }
regionlist * region_list *
allinhab_in_range(const region *r, int n) allinhab_in_range(const region *r, int n)
{ {
int x,y; int x,y;
regionlist *rlist = NULL; region_list *rlist = NULL;
region *r2; region *r2;
if(r == NULL) return NULL; /* Um Probleme abzufangen, if(r == NULL) return NULL; /* Um Probleme abzufangen,

View File

@ -29,8 +29,8 @@ extern "C" {
#endif #endif
struct region *r_standard_to_astral(const struct region *r); struct region *r_standard_to_astral(const struct region *r);
struct region *r_astral_to_standard(const struct region *); struct region *r_astral_to_standard(const struct region *);
struct regionlist *all_in_range(struct region *r, int n); struct region_list *all_in_range(struct region *r, int n);
struct regionlist *allinhab_in_range(const struct region *r, int n); struct region_list *allinhab_in_range(const struct region *r, int n);
void create_teleport_plane(void); void create_teleport_plane(void);
void set_teleport_plane_regiontypes(void); void set_teleport_plane_regiontypes(void);

View File

@ -90,7 +90,7 @@ make_dungeon(const dungeon * data)
plane * p; plane * p;
region *r, *center; region *r, *center;
region * rnext; region * rnext;
regionlist * iregion, * rlist = NULL; region_list * iregion, * rlist = NULL;
sprintf(name, "Die Höhlen von %s", bossrace->generate_name(NULL)); sprintf(name, "Die Höhlen von %s", bossrace->generate_name(NULL));
p = gm_addplane(data->radius, flags, name); p = gm_addplane(data->radius, flags, name);
@ -137,7 +137,7 @@ make_dungeon(const dungeon * data)
for (iregion=rlist;iregion;iregion=iregion->next) { for (iregion=rlist;iregion;iregion=iregion->next) {
monster * m = data->monsters; monster * m = data->monsters;
region * r = iregion->region; region * r = iregion->data;
while (m) { while (m) {
if ((rand() % 100) < (m->chance * 100)) { if ((rand() % 100) < (m->chance * 100)) {
/* TODO: check maxunits. */ /* TODO: check maxunits. */

View File

@ -373,15 +373,15 @@ count_demand(const region *r)
#endif #endif
static int static int
recurse_regions(region * r, regionlist **rlist, boolean(*fun)(const region * r)) recurse_regions(region * r, region_list **rlist, boolean(*fun)(const region * r))
{ {
if (!fun(r)) return 0; if (!fun(r)) return 0;
else { else {
int len = 0; int len = 0;
direction_t d; direction_t d;
regionlist * rl = calloc(sizeof(regionlist), 1); region_list * rl = calloc(sizeof(region_list), 1);
rl->next = *rlist; rl->next = *rlist;
rl->region = r; rl->data = r;
(*rlist) = rl; (*rlist) = rl;
fset(r, FL_MARK); fset(r, FL_MARK);
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
@ -406,7 +406,7 @@ f_nolux(const region * r)
static int static int
fix_demand_region(region *r) fix_demand_region(region *r)
{ {
regionlist *rl, *rlist = NULL; region_list *rl, *rlist = NULL;
static const luxury_type **mlux = 0, ** ltypes; static const luxury_type **mlux = 0, ** ltypes;
const luxury_type *sale = NULL; const luxury_type *sale = NULL;
int maxlux = 0; int maxlux = 0;
@ -428,7 +428,7 @@ fix_demand_region(region *r)
for (i=0;i!=maxluxuries;++i) mlux[i] = 0; for (i=0;i!=maxluxuries;++i) mlux[i] = 0;
} }
for (rl=rlist;rl;rl=rl->next) { for (rl=rlist;rl;rl=rl->next) {
region * r = rl->region; region * r = rl->data;
direction_t d; direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d=0;d!=MAXDIRECTIONS;++d) {
region * nr = rconnect(r, d); region * nr = rconnect(r, d);
@ -468,7 +468,7 @@ fix_demand_region(region *r)
maxlux=2; maxlux=2;
} }
for (rl=rlist;rl;rl=rl->next) { for (rl=rlist;rl;rl=rl->next) {
region * r = rl->region; region * r = rl->data;
if (!fval(r, RF_CHAOTIC)) log_warning(("fixing demand in %s\n", regionname(r, NULL))); if (!fval(r, RF_CHAOTIC)) log_warning(("fixing demand in %s\n", regionname(r, NULL)));
setluxuries(r, mlux[rand() % maxlux]); setluxuries(r, mlux[rand() % maxlux]);
} }
@ -974,10 +974,7 @@ fix_astralplane(void)
if (r->terrain!=T_FIREWALL) continue; if (r->terrain!=T_FIREWALL) continue;
if (ra->terrain==T_ASTRALB) continue; if (ra->terrain==T_ASTRALB) continue;
if (ra->units!=NULL) { if (ra->units!=NULL) {
region_list * rnew = malloc(sizeof(region_list)); add_regionlist(&rlist, ra);
rnew->data = ra;
rnew->next = rlist;
rlist = rnew;
} }
terraform(ra, T_ASTRALB); terraform(ra, T_ASTRALB);
} }
@ -1134,7 +1131,7 @@ fix_dissolve(unit * u, int value, char mode)
if (a!=NULL) return; if (a!=NULL) return;
a = a_add(&u->attribs, a_new(&at_unitdissolve)); a = a_add(&u->attribs, a_new(&at_unitdissolve));
a->data.ca[0] = mode; a->data.ca[0] = mode;
a->data.ca[1] = value; a->data.ca[1] = (char)value;
log_warning(("unit %s has race %s and no dissolve-attrib\n", unitname(u), rc_name(u->race, 0))); log_warning(("unit %s has race %s and no dissolve-attrib\n", unitname(u), rc_name(u->race, 0)));
} }