forked from github/server
Code-Vereinfachung: regionlist und region_list zu einem Typ gemerged
Code-Beschleunigung: Pathfinding schneller und schlauer
This commit is contained in:
parent
d1751cb0a3
commit
6ccb1b9bf6
15 changed files with 162 additions and 339 deletions
|
@ -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))
|
||||
{
|
||||
/* 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) {
|
||||
regionlist *rl2 = rl;
|
||||
region_list *rl2 = rl;
|
||||
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, "\"%s\";Name\n", rname(r, f->locale));
|
||||
rl2 = rl2->next;
|
||||
|
|
|
@ -380,27 +380,39 @@ dragon_affinity_value(region *r, unit *u)
|
|||
static attrib *
|
||||
set_new_dragon_target(unit * u, region * r, int range)
|
||||
{
|
||||
region *r2;
|
||||
int x, y;
|
||||
int affinity, max_affinity = 0;
|
||||
int max_affinity = 0;
|
||||
region *max_region = NULL;
|
||||
|
||||
#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++) {
|
||||
if (koor_distance (r->x, r->y, x, y) <= range
|
||||
&& (r2 = findregion(x, y)) != 0
|
||||
&&
|
||||
path_exists(r, r2, range, allowed_dragon)
|
||||
) {
|
||||
affinity = dragon_affinity_value(r2, u);
|
||||
region * r2 = findregion(x, y);
|
||||
if (r2!=NULL) {
|
||||
int affinity = dragon_affinity_value(r2, u);
|
||||
if (affinity > max_affinity) {
|
||||
if (koor_distance (r->x, r->y, x, y) <= range && path_exists(r, r2, range, allowed_dragon))
|
||||
{
|
||||
max_affinity = affinity;
|
||||
max_region = r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
if (max_region && max_region != r) {
|
||||
attrib * a = a_find(u->attribs, &at_targetregion);
|
||||
if (!a) {
|
||||
|
@ -1063,7 +1075,6 @@ plan_monsters(void)
|
|||
}
|
||||
}
|
||||
if (tr!=NULL) {
|
||||
#ifdef NEW_PATH
|
||||
switch(old_race(u->race)) {
|
||||
case RC_FIREDRAGON:
|
||||
set_movement_order(u, tr, 4, allowed_dragon);
|
||||
|
@ -1075,19 +1086,6 @@ plan_monsters(void)
|
|||
set_movement_order(u, tr, 1, allowed_dragon);
|
||||
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) {
|
||||
/* do a growl */
|
||||
if (rname(tr, u->faction->locale)) {
|
||||
|
|
|
@ -1532,7 +1532,7 @@ randomevents(void)
|
|||
#if NEW_LAEN
|
||||
void growlaen(void) {
|
||||
region *r;
|
||||
regionlist *Berge=NULL, *rl;
|
||||
region_list *Berge=NULL, *rl;
|
||||
unit *u;
|
||||
int b=0, Laen, z, add;
|
||||
short *add_laen;
|
||||
|
|
|
@ -1366,14 +1366,14 @@ describe(FILE * F, const region * r, int partial, faction * f)
|
|||
if (partial==0 && r->planep && r->planep->id == 1 &&
|
||||
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||
/* Sonderbehandlung Teleport-Ebene */
|
||||
regionlist *rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
|
||||
regionlist *rl2;
|
||||
region_list *rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
|
||||
region_list *rl2;
|
||||
|
||||
if (rl) {
|
||||
strcpy(buf, "Schemen der Regionen ");
|
||||
rl2 = rl;
|
||||
while(rl2) {
|
||||
scat(f_regionid(rl2->region, f));
|
||||
scat(f_regionid(rl2->data, f));
|
||||
rl2 = rl2->next;
|
||||
if(rl2) scat(", ");
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ const int FIREWORK_RANGE=10;
|
|||
static int
|
||||
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);
|
||||
regionlist *rl;
|
||||
region_list *rlist = all_in_range(u->region, FIREWORK_RANGE);
|
||||
region_list *rl;
|
||||
message *m;
|
||||
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));
|
||||
}
|
||||
|
||||
for(rl = rlist; rl; rl=rl->next) if(rl->region != u->region) {
|
||||
add_message(&rl->region->msgs, m);
|
||||
for(rl = rlist; rl; rl=rl->next) if(rl->data != u->region) {
|
||||
add_message(&rl->data->msgs, m);
|
||||
}
|
||||
|
||||
msg_release(m);
|
||||
|
|
|
@ -1160,15 +1160,7 @@ farcasting(unit *magician, region *r)
|
|||
|
||||
mult = (int)pow(2.0,(double)dist);
|
||||
if (dist > 1) {
|
||||
#ifdef NEW_PATH
|
||||
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;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef NEW_PATH
|
||||
boolean
|
||||
allowed_swim(const region * src, const region * target)
|
||||
{
|
||||
|
@ -50,8 +49,6 @@ allowed_fly(const region * src, const region * target)
|
|||
return false;
|
||||
}
|
||||
|
||||
#define FAST_PATH
|
||||
#ifdef FAST_PATH
|
||||
typedef struct node {
|
||||
struct node * next;
|
||||
region * r;
|
||||
|
@ -86,6 +83,53 @@ free_node(node * n)
|
|||
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 **
|
||||
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;
|
||||
n = n->next;
|
||||
}
|
||||
while (root!=NULL) {
|
||||
region * r = root->r;
|
||||
freset(r, FL_MARK);
|
||||
root = free_node(root);
|
||||
}
|
||||
free_nodes(root);
|
||||
if (found) return path;
|
||||
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()?");
|
||||
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
|
||||
|
|
|
@ -23,19 +23,12 @@ extern "C" {
|
|||
extern int search[MAXDEPTH][2];
|
||||
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 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_fly(const struct region * src, const struct region * target);
|
||||
extern boolean allowed_walk(const struct region * src, const struct region * target);
|
||||
#else
|
||||
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
|
||||
|
||||
extern struct region_list * regions_in_range(struct region * src, int maxdist, boolean (*allowed)(const struct region*, const struct region*));
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -360,21 +360,21 @@ reldirection(region * from, region * to)
|
|||
}
|
||||
|
||||
void
|
||||
free_regionlist(regionlist *rl)
|
||||
free_regionlist(region_list *rl)
|
||||
{
|
||||
while (rl) {
|
||||
regionlist * rl2 = rl->next;
|
||||
region_list * rl2 = rl->next;
|
||||
free(rl);
|
||||
rl = rl2;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
*rl = rl2;
|
||||
|
|
|
@ -148,13 +148,8 @@ void initrhash(void);
|
|||
void rhash(struct region * r);
|
||||
void runhash(struct region * r);
|
||||
|
||||
typedef struct regionlist {
|
||||
struct regionlist *next;
|
||||
struct region *region;
|
||||
} regionlist;
|
||||
|
||||
void free_regionlist(regionlist *rl);
|
||||
void add_regionlist(regionlist **rl, struct region *r);
|
||||
void free_regionlist(region_list *rl);
|
||||
void add_regionlist(region_list **rl, struct region *r);
|
||||
|
||||
int woodcount(const struct region * r);
|
||||
int deathcount(const struct region * r);
|
||||
|
|
|
@ -1911,7 +1911,7 @@ static int
|
|||
sp_treewalkexit(castorder *co)
|
||||
{
|
||||
region *rt;
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
int tax, tay;
|
||||
unit *u, *u2;
|
||||
int remaining_cap;
|
||||
|
@ -1951,8 +1951,8 @@ sp_treewalkexit(castorder *co)
|
|||
|
||||
rl2 = rl;
|
||||
while(rl2) {
|
||||
if(rl2->region->x == tax && rl2->region->y == tay) {
|
||||
rt = rl2->region;
|
||||
if(rl2->data->x == tax && rl2->data->y == tay) {
|
||||
rt = rl2->data;
|
||||
break;
|
||||
}
|
||||
rl2 = rl2->next;
|
||||
|
@ -2234,7 +2234,7 @@ sp_fog_of_confusion(castorder *co)
|
|||
double power = co->force;
|
||||
double range;
|
||||
int duration;
|
||||
regionlist *rl,*rl2;
|
||||
region_list *rl,*rl2;
|
||||
|
||||
range = (power-11)/3-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) {
|
||||
curse * c;
|
||||
if(rterrain(rl2->region) != T_OCEAN
|
||||
&& !r_isforest(rl2->region)) continue;
|
||||
if(rterrain(rl2->data) != T_OCEAN
|
||||
&& !r_isforest(rl2->data)) continue;
|
||||
|
||||
/* Magieresistenz jeder Region prüfen */
|
||||
if (target_resists_magic(mage, r, TYP_REGION, 0)){
|
||||
|
@ -2252,18 +2252,18 @@ sp_fog_of_confusion(castorder *co)
|
|||
continue;
|
||||
}
|
||||
|
||||
c = create_curse(mage, &rl2->region->attribs,
|
||||
c = create_curse(mage, &rl2->data->attribs,
|
||||
ct_find("disorientationzone"), power, duration, cast_level*5, 0);
|
||||
/* Soll der schon in der Zauberrunde wirken? */
|
||||
curse_setflag(c, CURSE_ISNEW);
|
||||
|
||||
for (u = rl2->region->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) freset(u->faction, FL_DH);
|
||||
for (u = rl2->data->units; u; u = u->next ) {
|
||||
if(!fval(u->faction, FL_DH) ) {
|
||||
fset(u->faction, FL_DH);
|
||||
sprintf(buf, "%s beschwört einen Schleier der Verwirrung.",
|
||||
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)){
|
||||
|
@ -2774,7 +2774,7 @@ sp_summondragon(castorder *co)
|
|||
unit *u;
|
||||
int cast_level = co->level;
|
||||
double power = co->force;
|
||||
regionlist *rl,*rl2;
|
||||
region_list *rl,*rl2;
|
||||
faction *f;
|
||||
int time;
|
||||
int number;
|
||||
|
@ -2817,7 +2817,7 @@ sp_summondragon(castorder *co)
|
|||
rl = all_in_range(r, (int)power);
|
||||
|
||||
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]) {
|
||||
attrib * a = a_find(u->attribs, &at_targetregion);
|
||||
if (!a) {
|
||||
|
@ -2825,7 +2825,7 @@ sp_summondragon(castorder *co)
|
|||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -4971,7 +4971,7 @@ sp_dragonsong(castorder *co)
|
|||
unit *u;
|
||||
int cast_level = co->level;
|
||||
double power = co->force;
|
||||
regionlist *rl,*rl2;
|
||||
region_list *rl,*rl2;
|
||||
faction *f;
|
||||
|
||||
/* TODO HP-Effekt */
|
||||
|
@ -4981,7 +4981,7 @@ sp_dragonsong(castorder *co)
|
|||
rl = all_in_range(r, (int)power);
|
||||
|
||||
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) {
|
||||
attrib * a = a_find(u->attribs, &at_targetregion);
|
||||
if (!a) {
|
||||
|
@ -4989,7 +4989,7 @@ sp_dragonsong(castorder *co)
|
|||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -5536,7 +5536,7 @@ int
|
|||
sp_dream_of_confusion(castorder *co)
|
||||
{
|
||||
unit *u;
|
||||
regionlist *rl,*rl2;
|
||||
region_list *rl,*rl2;
|
||||
region *r = co->rt;
|
||||
unit *mage = (unit *)co->magician;
|
||||
int cast_level = co->level;
|
||||
|
@ -5547,25 +5547,26 @@ sp_dream_of_confusion(castorder *co)
|
|||
rl = all_in_range(r, (int)range);
|
||||
|
||||
for(rl2 = rl; rl2; rl2 = rl2->next) {
|
||||
region * r2 = rl2->data;
|
||||
curse * c;
|
||||
/* 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);
|
||||
continue;
|
||||
}
|
||||
|
||||
c = create_curse(mage, &rl2->region->attribs,
|
||||
c = create_curse(mage, &r2->attribs,
|
||||
ct_find("disorientationzone"), power, duration, cast_level*5, 0);
|
||||
/* soll der Zauber schon in der Zauberrunde wirken? */
|
||||
curse_setflag(c, CURSE_ISNEW);
|
||||
|
||||
for (u = rl2->region->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) freset(u->faction, FL_DH);
|
||||
for (u = r2->units; u; u = u->next ) {
|
||||
if(!fval(u->faction, FL_DH) ) {
|
||||
fset(u->faction, FL_DH);
|
||||
sprintf(buf, "%s beschwört einen Schleier der Verwirrung.",
|
||||
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)){
|
||||
|
@ -5865,7 +5866,7 @@ sp_pullastral(castorder *co)
|
|||
{
|
||||
region *rt, *ro;
|
||||
unit *u, *u2;
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
int remaining_cap;
|
||||
int n, w;
|
||||
region *r = co->rt;
|
||||
|
@ -5881,9 +5882,10 @@ sp_pullastral(castorder *co)
|
|||
ro = pa->param[0]->data.r;
|
||||
rl = all_in_range(r_astral_to_standard(r), TP_RADIUS);
|
||||
rl2 = rl;
|
||||
while(rl2) {
|
||||
if(rl2->region->x == ro->x && rl2->region->y == ro->y) {
|
||||
ro = rl2->region;
|
||||
while (rl2!=NULL) {
|
||||
region * r2 = rl2->data;
|
||||
if (r2->x == ro->x && r2->y == ro->y) {
|
||||
ro = r2;
|
||||
break;
|
||||
}
|
||||
rl2 = rl2->next;
|
||||
|
@ -5991,7 +5993,7 @@ int
|
|||
sp_leaveastral(castorder *co)
|
||||
{
|
||||
region *rt, *ro;
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
unit *u, *u2;
|
||||
int remaining_cap;
|
||||
int n, w;
|
||||
|
@ -6012,11 +6014,11 @@ sp_leaveastral(castorder *co)
|
|||
}
|
||||
rl = allinhab_in_range(r_astral_to_standard(r), TP_RADIUS);
|
||||
rl2 = rl;
|
||||
while(rl2) {
|
||||
if(rl2->region == rt) break;
|
||||
while (rl2!=NULL) {
|
||||
if (rl2->data == rt) break;
|
||||
rl2 = rl2->next;
|
||||
}
|
||||
if(!rl2) {
|
||||
if (rl2==NULL) {
|
||||
addmessage(r, mage->faction, "Dorthin führt kein Weg.",
|
||||
MSG_MAGIC, ML_MISTAKE);
|
||||
free_regionlist(rl);
|
||||
|
@ -6230,7 +6232,7 @@ sp_showastral(castorder *co)
|
|||
region *rt;
|
||||
int n = 0;
|
||||
int c = 0;
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
region *r = co->rt;
|
||||
unit *mage = (unit *)co->magician;
|
||||
int cast_level = co->level;
|
||||
|
@ -6259,8 +6261,8 @@ sp_showastral(castorder *co)
|
|||
/* Erst Einheiten zählen, für die Grammatik. */
|
||||
|
||||
for(rl2=rl; rl2; rl2=rl2->next) {
|
||||
if(!is_cursed(rl2->region->attribs, C_ASTRALBLOCK, 0)) {
|
||||
for(u = rl2->region->units; u; u=u->next) {
|
||||
if(!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) {
|
||||
for(u = rl2->data->units; u; u=u->next) {
|
||||
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));
|
||||
|
||||
for(rl2=rl; rl2; rl2=rl2->next) {
|
||||
if(!is_cursed(rl2->region->attribs, C_ASTRALBLOCK, 0)) {
|
||||
for(u = rl2->region->units; u; u=u->next) {
|
||||
if(!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) {
|
||||
for(u = rl2->data->units; u; u=u->next) {
|
||||
if(u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) {
|
||||
c++;
|
||||
scat(unitname(u));
|
||||
|
@ -6292,7 +6294,7 @@ sp_showastral(castorder *co)
|
|||
scat(" ");
|
||||
scat(LOC(mage->faction->locale, rc_name(u->race, u->number!=1)));
|
||||
scat(", Entfernung ");
|
||||
icat(distance(rl2->region, rt));
|
||||
icat(distance(rl2->data, rt));
|
||||
scat(")");
|
||||
if(c == n-1) {
|
||||
scat(" und ");
|
||||
|
@ -6319,7 +6321,7 @@ sp_showastral(castorder *co)
|
|||
int
|
||||
sp_viewreality(castorder *co)
|
||||
{
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
unit *u;
|
||||
region *r = co->rt;
|
||||
unit *mage = (unit *)co->magician;
|
||||
|
@ -6341,7 +6343,7 @@ sp_viewreality(castorder *co)
|
|||
|
||||
/* Irgendwann mal auf Curses u/o Attribut umstellen. */
|
||||
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");
|
||||
u->age = 2;
|
||||
}
|
||||
|
@ -6358,7 +6360,7 @@ sp_viewreality(castorder *co)
|
|||
int
|
||||
sp_disruptastral(castorder *co)
|
||||
{
|
||||
regionlist *rl, *rl2;
|
||||
region_list *rl, *rl2;
|
||||
region *rt;
|
||||
unit *u;
|
||||
region *r = co->rt;
|
||||
|
@ -6389,16 +6391,17 @@ sp_disruptastral(castorder *co)
|
|||
|
||||
for (rl2=rl; rl2!=NULL; rl2=rl2->next) {
|
||||
attrib *a, *a2;
|
||||
region * r2 = rl2->data;
|
||||
spec_direction *sd;
|
||||
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) {
|
||||
regionlist * trl2;
|
||||
if (r2->units!=NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -6415,15 +6418,15 @@ sp_disruptastral(castorder *co)
|
|||
/* Einheiten auswerfen */
|
||||
|
||||
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]) {
|
||||
regionlist *trl2 = trl;
|
||||
region_list *trl2 = trl;
|
||||
region *tr;
|
||||
int c = rand() % inhab_regions;
|
||||
|
||||
/* Zufällige Zielregion suchen */
|
||||
while (c--!=0) trl2 = trl2->next;
|
||||
tr = trl2->region;
|
||||
tr = trl2->data;
|
||||
|
||||
if(!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) {
|
||||
move_unit(u, tr, NULL);
|
||||
|
@ -6437,9 +6440,9 @@ sp_disruptastral(castorder *co)
|
|||
}
|
||||
|
||||
/* Kontakt unterbinden */
|
||||
create_curse(mage, &rl2->region->attribs, ct_find("astralblock"),
|
||||
create_curse(mage, &rl2->data->attribs, ct_find("astralblock"),
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -88,11 +88,11 @@ r_astral_to_standard(const region *r)
|
|||
return r2;
|
||||
}
|
||||
|
||||
regionlist *
|
||||
region_list *
|
||||
all_in_range(region *r, int n)
|
||||
{
|
||||
int x,y;
|
||||
regionlist *rlist = NULL;
|
||||
region_list *rlist = NULL;
|
||||
region *r2;
|
||||
|
||||
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)
|
||||
{
|
||||
int x,y;
|
||||
regionlist *rlist = NULL;
|
||||
region_list *rlist = NULL;
|
||||
region *r2;
|
||||
|
||||
if(r == NULL) return NULL; /* Um Probleme abzufangen,
|
||||
|
|
|
@ -29,8 +29,8 @@ extern "C" {
|
|||
#endif
|
||||
struct region *r_standard_to_astral(const struct region *r);
|
||||
struct region *r_astral_to_standard(const struct region *);
|
||||
struct regionlist *all_in_range(struct region *r, int n);
|
||||
struct regionlist *allinhab_in_range(const struct region *r, int n);
|
||||
struct region_list *all_in_range(struct region *r, int n);
|
||||
struct region_list *allinhab_in_range(const struct region *r, int n);
|
||||
void create_teleport_plane(void);
|
||||
void set_teleport_plane_regiontypes(void);
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ make_dungeon(const dungeon * data)
|
|||
plane * p;
|
||||
region *r, *center;
|
||||
region * rnext;
|
||||
regionlist * iregion, * rlist = NULL;
|
||||
region_list * iregion, * rlist = NULL;
|
||||
|
||||
sprintf(name, "Die Höhlen von %s", bossrace->generate_name(NULL));
|
||||
p = gm_addplane(data->radius, flags, name);
|
||||
|
@ -137,7 +137,7 @@ make_dungeon(const dungeon * data)
|
|||
|
||||
for (iregion=rlist;iregion;iregion=iregion->next) {
|
||||
monster * m = data->monsters;
|
||||
region * r = iregion->region;
|
||||
region * r = iregion->data;
|
||||
while (m) {
|
||||
if ((rand() % 100) < (m->chance * 100)) {
|
||||
/* TODO: check maxunits. */
|
||||
|
|
|
@ -373,15 +373,15 @@ count_demand(const region *r)
|
|||
#endif
|
||||
|
||||
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;
|
||||
else {
|
||||
int len = 0;
|
||||
direction_t d;
|
||||
regionlist * rl = calloc(sizeof(regionlist), 1);
|
||||
region_list * rl = calloc(sizeof(region_list), 1);
|
||||
rl->next = *rlist;
|
||||
rl->region = r;
|
||||
rl->data = r;
|
||||
(*rlist) = rl;
|
||||
fset(r, FL_MARK);
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
|
@ -406,7 +406,7 @@ f_nolux(const region * r)
|
|||
static int
|
||||
fix_demand_region(region *r)
|
||||
{
|
||||
regionlist *rl, *rlist = NULL;
|
||||
region_list *rl, *rlist = NULL;
|
||||
static const luxury_type **mlux = 0, ** ltypes;
|
||||
const luxury_type *sale = NULL;
|
||||
int maxlux = 0;
|
||||
|
@ -428,7 +428,7 @@ fix_demand_region(region *r)
|
|||
for (i=0;i!=maxluxuries;++i) mlux[i] = 0;
|
||||
}
|
||||
for (rl=rlist;rl;rl=rl->next) {
|
||||
region * r = rl->region;
|
||||
region * r = rl->data;
|
||||
direction_t d;
|
||||
for (d=0;d!=MAXDIRECTIONS;++d) {
|
||||
region * nr = rconnect(r, d);
|
||||
|
@ -468,7 +468,7 @@ fix_demand_region(region *r)
|
|||
maxlux=2;
|
||||
}
|
||||
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)));
|
||||
setluxuries(r, mlux[rand() % maxlux]);
|
||||
}
|
||||
|
@ -974,10 +974,7 @@ fix_astralplane(void)
|
|||
if (r->terrain!=T_FIREWALL) continue;
|
||||
if (ra->terrain==T_ASTRALB) continue;
|
||||
if (ra->units!=NULL) {
|
||||
region_list * rnew = malloc(sizeof(region_list));
|
||||
rnew->data = ra;
|
||||
rnew->next = rlist;
|
||||
rlist = rnew;
|
||||
add_regionlist(&rlist, ra);
|
||||
}
|
||||
terraform(ra, T_ASTRALB);
|
||||
}
|
||||
|
@ -1134,7 +1131,7 @@ fix_dissolve(unit * u, int value, char mode)
|
|||
if (a!=NULL) return;
|
||||
a = a_add(&u->attribs, a_new(&at_unitdissolve));
|
||||
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)));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue