firstregion/lastregion beschleunigungen und bugfix

This commit is contained in:
Enno Rehling 2005-04-27 21:03:08 +00:00
parent c97d520bc6
commit 8fd95421ca
16 changed files with 305 additions and 244 deletions

View File

@ -1016,7 +1016,7 @@ report_resource(char * buf, const char * name, const struct locale * loc, int am
} }
static void static void
cr_borders(const region * r, const faction * f, int seemode, FILE * F) cr_borders(seen_region ** seen, const region * r, const faction * f, int seemode, FILE * F)
{ {
direction_t d; direction_t d;
int g = 0; int g = 0;
@ -1026,7 +1026,7 @@ cr_borders(const region * r, const faction * f, int seemode, FILE * F)
const border * b; const border * b;
if (!r2) continue; if (!r2) continue;
if (seemode==see_neighbour) { if (seemode==see_neighbour) {
seen_region * sr = find_seen(r2); seen_region * sr = find_seen(seen, r2);
if (sr==NULL || sr->mode<=see_neighbour) continue; if (sr==NULL || sr->mode<=see_neighbour) continue;
} }
b = get_borders(r, r2); b = get_borders(r, r2);
@ -1063,18 +1063,20 @@ cr_borders(const region * r, const faction * f, int seemode, FILE * F)
} }
void void
get_seen_interval(region ** first, region ** last) get_seen_interval(struct seen_region ** seen, region ** first, region ** last)
{ {
/* #ifdef ENUM_REGIONS : can speed stuff up */
region * r = regions; region * r = regions;
while (r!=NULL) { while (r!=NULL) {
if (find_seen(r)!=NULL) { if (find_seen(seen, r)!=NULL) {
*first = r; *first = r;
break; break;
} }
r = r->next; r = r->next;
} }
while (r!=NULL) { while (r!=NULL) {
if (find_seen(r)!=NULL) { if (find_seen(seen, r)!=NULL) {
*last = r->next; *last = r->next;
} }
r = r->next; r = r->next;
@ -1083,7 +1085,7 @@ get_seen_interval(region ** first, region ** last)
/* main function of the creport. creates the header and traverses all regions */ /* main function of the creport. creates the header and traverses all regions */
int int
report_computer(FILE * F, faction * f, const faction_list * addresses, report_computer(FILE * F, faction * f, struct seen_region ** seen, const faction_list * addresses,
const time_t report_time) const time_t report_time)
{ {
int i; int i;
@ -1098,7 +1100,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
region * first = NULL, * last = NULL; region * first = NULL, * last = NULL;
const attrib * a; const attrib * a;
get_seen_interval(&first, &last); get_seen_interval(seen, &first, &last);
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* initialisations, header and lists */ /* initialisations, header and lists */
@ -1246,7 +1248,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
for (r=first;r!=last;r=r->next) { for (r=first;r!=last;r=r->next) {
int modifier = 0; int modifier = 0;
const char * tname; const char * tname;
const seen_region * sd = find_seen(r); const seen_region * sd = find_seen(seen, r);
if (sd==NULL) continue; if (sd==NULL) continue;
@ -1291,7 +1293,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
} }
} }
if (sd->mode == see_neighbour) { if (sd->mode == see_neighbour) {
cr_borders(r, f, sd->mode, F); cr_borders(seen, r, f, sd->mode, F);
} else { } else {
#define RESOURCECOMPAT #define RESOURCECOMPAT
char cbuf[8192], *pos = cbuf; char cbuf[8192], *pos = cbuf;
@ -1421,7 +1423,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
if (pos!=cbuf) fputs(cbuf, F); if (pos!=cbuf) fputs(cbuf, F);
} }
print_curses(F, f, r, TYP_REGION); print_curses(F, f, r, TYP_REGION);
cr_borders(r, f, sd->mode, F); cr_borders(seen, r, f, sd->mode, F);
if (sd->mode==see_unit && rplane(r)==get_astralplane() && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) if (sd->mode==see_unit && rplane(r)==get_astralplane() && !is_cursed(r->attribs, C_ASTRALBLOCK, 0))
{ {
/* Sonderbehandlung Teleport-Ebene */ /* Sonderbehandlung Teleport-Ebene */

View File

@ -20,7 +20,7 @@ extern "C" {
struct faction_list; struct faction_list;
struct seen_region; struct seen_region;
struct faction; struct faction;
extern int report_computer(FILE * F, struct faction * f, extern int report_computer(FILE * F, struct faction * f, struct seen_region ** seen,
const struct faction_list * addresses, const time_t report_time); const struct faction_list * addresses, const time_t report_time);
extern void creport_cleanup(void); extern void creport_cleanup(void);
extern void creport_init(void); extern void creport_init(void);

View File

@ -172,22 +172,17 @@ dissolve_units(void)
static int static int
improve_all(faction * f, skill_t sk, int weeks) improve_all(faction * f, skill_t sk, int weeks)
{ {
region *r;
unit *u; unit *u;
int n = 0;
region *last = lastregion(f);
for (r = firstregion(f); r != last; r = r->next) { for (u = f->units; u; u = u->nextF) {
for (u = r->units; u; u = u->next) { if (has_skill(u, sk)) {
if (u->faction == f && has_skill(u, sk)) { while (weeks--) {
for (n=0;n!=weeks;++n) { learn_skill(u, sk, 1.0);
learn_skill(u, sk, 1.0);
}
} }
} }
} }
return n; return weeks;
} }
void void
@ -295,7 +290,7 @@ find_manual(region * r, unit * u)
scat(". Der Wissensschub ist enorm."); scat(". Der Wissensschub ist enorm.");
addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT); addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT);
if (improve_all(u->faction, skill, 3) == 0) { if (improve_all(u->faction, skill, 3) == 3) {
int i; int i;
for (i=0;i!=9;++i) learn_skill(u, skill, 1.0); for (i=0;i!=9;++i) learn_skill(u, skill, 1.0);
} }

View File

@ -1978,7 +1978,7 @@ report_building(FILE *F, const region * r, const building * b, const faction * f
} }
static int static int
report(FILE *F, faction * f, const faction_list * addresses, report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * addresses,
const char * pzTime) const char * pzTime)
{ {
#ifndef NEW_ITEMS #ifndef NEW_ITEMS
@ -2234,7 +2234,7 @@ report(FILE *F, faction * f, const faction_list * addresses,
boolean unit_in_region = false; boolean unit_in_region = false;
boolean durchgezogen_in_region = false; boolean durchgezogen_in_region = false;
int turm_sieht_region = false; int turm_sieht_region = false;
seen_region * sd = find_seen(r); seen_region * sd = find_seen(seen, r);
if (sd==NULL) continue; if (sd==NULL) continue;
switch (sd->mode) { switch (sd->mode) {
@ -2469,13 +2469,27 @@ base36conversion(void)
extern void init_intervals(void); extern void init_intervals(void);
#define DBG_CACHE 1
#if DBG_CACHE
int chits = 0;
int ctries = 0;
#endif
static void static void
view_default(region *r, faction *f) view_lighthouse(struct seen_region ** seen, region *r, faction *f)
{
/* TODO */
direction_t dir;
assert(!"must implement this");
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
region * r2 = rconnect(r, dir);
if (r2) {
border * b = get_borders(r, r2);
while (b) {
if (!b->type->transparent(b, f)) break;
b = b->next;
}
if (!b) add_seen(seen, r2, see_lighthouse, false);
}
}
}
static void
view_default(struct seen_region ** seen, region *r, faction *f)
{ {
direction_t dir; direction_t dir;
for (dir=0;dir!=MAXDIRECTIONS;++dir) { for (dir=0;dir!=MAXDIRECTIONS;++dir) {
@ -2486,13 +2500,13 @@ view_default(region *r, faction *f)
if (!b->type->transparent(b, f)) break; if (!b->type->transparent(b, f)) break;
b = b->next; b = b->next;
} }
if (!b) add_seen(r2, see_neighbour, false); if (!b) add_seen(seen, r2, see_neighbour, false);
} }
} }
} }
static void static void
view_neighbours(region * r, faction * f) view_neighbours(struct seen_region ** seen, region * r, faction * f)
{ {
direction_t dir; direction_t dir;
for (dir=0;dir!=MAXDIRECTIONS;++dir) { for (dir=0;dir!=MAXDIRECTIONS;++dir) {
@ -2504,7 +2518,7 @@ view_neighbours(region * r, faction * f)
b = b->next; b = b->next;
} }
if (!b) { if (!b) {
if (add_seen(r2, see_far, false)) { if (add_seen(seen, r2, see_far, false)) {
if (!(terrain[rterrain(r2)].flags & FORBIDDEN_LAND)) { if (!(terrain[rterrain(r2)].flags & FORBIDDEN_LAND)) {
direction_t dir; direction_t dir;
for (dir=0;dir!=MAXDIRECTIONS;++dir) { for (dir=0;dir!=MAXDIRECTIONS;++dir) {
@ -2515,7 +2529,7 @@ view_neighbours(region * r, faction * f)
if (!b->type->transparent(b, f)) break; if (!b->type->transparent(b, f)) break;
b = b->next; b = b->next;
} }
if (!b) add_seen(r3, see_neighbour, false); if (!b) add_seen(seen, r3, see_neighbour, false);
} }
} }
} }
@ -2526,7 +2540,7 @@ view_neighbours(region * r, faction * f)
} }
static void static void
recurse_regatta(region *center, region *r, faction *f, int maxdist) recurse_regatta(struct seen_region ** seen, region *center, region *r, faction *f, int maxdist)
{ {
direction_t dir; direction_t dir;
int dist = distance(center, r); int dist = distance(center, r);
@ -2542,10 +2556,10 @@ recurse_regatta(region *center, region *r, faction *f, int maxdist)
} }
if (!b) { if (!b) {
if (ndist<maxdist) { if (ndist<maxdist) {
if (add_seen(r2, see_far, false)) { if (add_seen(seen, r2, see_far, false)) {
recurse_regatta(center, r2, f, maxdist); recurse_regatta(seen, center, r2, f, maxdist);
} }
} else add_seen(r2, see_neighbour, false); } else add_seen(seen, r2, see_neighbour, false);
} }
} }
} }
@ -2553,7 +2567,7 @@ recurse_regatta(region *center, region *r, faction *f, int maxdist)
} }
static void static void
view_regatta(region * r, faction * f) view_regatta(struct seen_region ** seen, region * r, faction * f)
{ {
unit *u; unit *u;
int skill = 0; int skill = 0;
@ -2563,7 +2577,7 @@ view_regatta(region * r, faction * f)
if (es>skill) skill=es; if (es>skill) skill=es;
} }
} }
recurse_regatta(r, r, f, skill/2); recurse_regatta(seen, r, r, f, skill/2);
} }
static void static void
@ -2574,15 +2588,12 @@ global_report(const char * filename)
faction * f; faction * f;
faction * monsters = findfaction(MONSTER_FACTION); faction * monsters = findfaction(MONSTER_FACTION);
faction_list * addresses = NULL; faction_list * addresses = NULL;
struct seen_region ** seen;
if (!monsters) return; if (!monsters) return;
if (!F) return; if (!F) return;
seen_init(); /* list of all addresses */
for (r = regions; r; r = r->next) {
add_seen(r, see_unit, true);
}
for (f=factions;f;f=f->next) { for (f=factions;f;f=f->next) {
faction_list * flist = calloc(1, sizeof(faction_list)); faction_list * flist = calloc(1, sizeof(faction_list));
flist->data = f; flist->data = f;
@ -2590,25 +2601,59 @@ global_report(const char * filename)
addresses = flist; addresses = flist;
} }
report_computer(F, monsters, addresses, time(NULL)); seen = seen_init();
for (r = regions; r; r = r->next) {
add_seen(seen, r, see_unit, true);
}
report_computer(F, monsters, seen, addresses, time(NULL));
seen_done(seen);
fclose(F); fclose(F);
} }
static void region_list *
get_regions_distance(region * root, int radius)
{
region_list * rptr, * rlist = NULL;
region_list ** rp = &rlist;
add_regionlist(rp, root);
fset(root, FL_MARK);
while (*rp) {
region_list * r = *rp;
direction_t d;
rp = &r->next;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rn = rconnect(r->data, d);
if (!fval(rn, FL_MARK) && distance(rn, root)<=radius) {
add_regionlist(rp, rn);
fset(rn, FL_MARK);
}
}
}
for (rptr=rlist;rptr;rptr=rptr->next) {
freset(rptr->data, FL_MARK);
}
return rlist;
}
static struct seen_region **
prepare_report(faction * f) prepare_report(faction * f)
{ {
region * r; region * r;
region * end = lastregion(f); region * end = lastregion(f);
seen_init(); struct seen_region ** seen = seen_init();
static const struct building_type * bt_lighthouse = NULL;
if (bt_lighthouse==NULL) bt_lighthouse = bt_find("lighthouse");
for (r = firstregion(f); r != end; r = r->next) { for (r = firstregion(f); r != end; r = r->next) {
attrib *ru; attrib *ru;
unit * u; unit * u;
plane * p = rplane(r); plane * p = rplane(r);
unsigned char mode = see_none; unsigned char mode = see_none;
boolean dis = false; boolean dis = false;
#if DBG_CACHE int light = 0;
++ctries;
#endif
if (p) { if (p) {
watcher * w = p->watchers; watcher * w = p->watchers;
while (w) { while (w) {
@ -2619,8 +2664,13 @@ prepare_report(faction * f)
w = w->next; w = w->next;
} }
} }
if (mode<see_unit) for (u = r->units; u; u = u->next) {
if (u->faction == f) { for (u = r->units; u; u = u->next) {
if (u->faction == f) {
if (u->building && u->building->type==bt_lighthouse) {
int r = lighthouse_range(u->building, f);
if (r>light) light = r;
}
if (u->race != new_race[RC_SPELL] || u->number == RS_FARVISION) { if (u->race != new_race[RC_SPELL] || u->number == RS_FARVISION) {
mode = see_unit; mode = see_unit;
if (fval(u, UFL_DISBELIEVES)) { if (fval(u, UFL_DISBELIEVES)) {
@ -2631,6 +2681,20 @@ prepare_report(faction * f)
} }
} }
if (light) {
/* we are in a lighthouse. add the others! */
region_list * rlist = get_regions_distance(r, light);
region_list * rp = rlist;
while (rp) {
region * r = rp->data;
if (rterrain(r) == T_OCEAN) {
add_seen(seen, r, see_lighthouse, false);
}
rp = rp->next;
}
free_regionlist(rlist);
}
if (mode<see_travel) for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { if (mode<see_travel) for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
unit * u = (unit*)ru->data.v; unit * u = (unit*)ru->data.v;
if (u->faction == f) { if (u->faction == f) {
@ -2639,31 +2703,21 @@ prepare_report(faction * f)
} }
} }
if (mode<see_lighthouse && rterrain(r) == T_OCEAN) {
if (check_leuchtturm(r, f)) mode = see_lighthouse;
}
if (mode == see_none) if (mode == see_none)
continue; continue;
#if DBG_CACHE
else ++chits;
#endif
add_seen(r, mode, dis); add_seen(seen, r, mode, dis);
/* nicht, wenn Verwirrung herrscht: */ /* nicht, wenn Verwirrung herrscht: */
if (!is_cursed(r->attribs, C_REGCONF, 0)) { if (!is_cursed(r->attribs, C_REGCONF, 0)) {
void (*view)(region * r, faction * f) = view_default; void (*view)(struct seen_region **, region * r, faction * f) = view_default;
if (p && fval(p, PFL_SEESPECIAL)) { if (p && fval(p, PFL_SEESPECIAL)) {
attrib * a = a_find(p->attribs, &at_viewrange); attrib * a = a_find(p->attribs, &at_viewrange);
if (a) view = (void (*)(region * r, faction * f))a->data.f; if (a) view = (void (*)(struct seen_region **, region * r, faction * f))a->data.f;
} }
view(r, f); view(seen, r, f);
} }
} }
#if DBG_CACHE return seen;
if (!quiet)
printf(" - cache hits: %.2f%%\n", 100*chits/(double)ctries);
#endif
} }
#define FMAXHASH 1021 #define FMAXHASH 1021
@ -2691,12 +2745,12 @@ write_reports(faction * f, time_t ltime)
boolean gotit = false; boolean gotit = false;
faction_list * addresses; faction_list * addresses;
char zTime[64]; char zTime[64];
struct seen_region ** seen = prepare_report(f);
strftime(zTime, sizeof(zTime), "%A, %d. %B %Y, %H:%M", localtime(&ltime)); strftime(zTime, sizeof(zTime), "%A, %d. %B %Y, %H:%M", localtime(&ltime));
printf("Reports for %s: \r", factionname(f)); printf("Reports for %s: \r", factionname(f));
fflush(stdout); fflush(stdout);
prepare_report(f); addresses = get_addresses(f, seen);
addresses = get_addresses(f);
/* NR schreiben: */ /* NR schreiben: */
if (!nonr && (f->options & REPORT_NR)) { if (!nonr && (f->options & REPORT_NR)) {
@ -2706,10 +2760,13 @@ write_reports(faction * f, time_t ltime)
sprintf(buf, "%s/%d-%s.nr", reportpath(), turn, factionid(f)); sprintf(buf, "%s/%d-%s.nr", reportpath(), turn, factionid(f));
F = cfopen(buf, "wt"); F = cfopen(buf, "wt");
if (F) { if (F) {
int status = report(F, f, addresses, zTime); int status = report(F, f, seen, addresses, zTime);
fclose(F); fclose(F);
gotit = true; gotit = true;
if (status!=0) return status; /* catch errors */ if (status!=0) {
seen_done(seen);
return status; /* catch errors */
}
} }
} }
/* CR schreiben: */ /* CR schreiben: */
@ -2720,10 +2777,13 @@ write_reports(faction * f, time_t ltime)
sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f)); sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f));
F = cfopen(buf, "wt"); F = cfopen(buf, "wt");
if (F) { if (F) {
int status = report_computer(F, f, addresses, ltime); int status = report_computer(F, f, seen, addresses, ltime);
fclose(F); fclose(F);
gotit = true; gotit = true;
if (status!=0) return status; /* catch errors */ if (status!=0) {
seen_done(seen);
return status; /* catch errors */
}
} }
} }
/* ZV schreiben: */ /* ZV schreiben: */
@ -2736,7 +2796,10 @@ write_reports(faction * f, time_t ltime)
if (F) { if (F) {
int status = order_template(F, f); int status = order_template(F, f);
fclose(F); fclose(F);
if (status!=0) return status; /* catch errors */ if (status!=0) {
seen_done(seen);
return status; /* catch errors */
}
} }
} }
fprintf(stdout, "Reports for %s: DONE\n", factionname(f)); fprintf(stdout, "Reports for %s: DONE\n", factionname(f));
@ -2746,6 +2809,7 @@ write_reports(faction * f, time_t ltime)
} }
freelist(addresses); freelist(addresses);
seen_done(seen);
return 0; return 0;
} }
@ -2904,7 +2968,7 @@ reports(void)
} }
/* schliesst BAT und verschickt Zeitungen und Kommentare */ /* schliesst BAT und verschickt Zeitungen und Kommentare */
closebatch(BAT); closebatch(BAT);
seen_done(); free_seen();
return retval; return retval;
} }

View File

@ -570,16 +570,12 @@ int
count_skill(faction * f, skill_t sk) count_skill(faction * f, skill_t sk)
{ {
int n = 0; int n = 0;
region *r;
unit *u; unit *u;
region *last = lastregion(f);
for (r =firstregion(f); r != last; r = r->next) { for (u = f->units; u; u = u->nextF) {
for (u = r->units; u; u = u->next) { if (has_skill(u, sk)) {
if (u->faction == f && has_skill(u, sk)) { if (!is_familiar(u)) n += u->number;
if (!is_familiar(u)) n += u->number;
} }
}
} }
return n; return n;
} }
@ -2006,6 +2002,32 @@ get_lighthouses(const region * r)
return ulist; return ulist;
} }
int
lighthouse_range(const building * b, const faction * f)
{
int d = 0;
if (fval(b, BLD_WORKING) && b->size >= 10) {
region * r = b->region;
unit *u;
int maxd = (int)log10(b->size) + 1;
int c = 0;
for (u = r->units; u; u = u->next) {
if (u->building == b) {
c += u->number;
if (c > buildingcapacity(b)) break;
if (f==NULL || u->faction == f) {
int sk = eff_skill(u, SK_OBSERVATION, r) / 3;
d = max(d, sk);
d = min(maxd, d);
if (d==maxd) break;
}
} else if (c) break; /* first unit that's no longer in the house ends the search */
}
}
return d;
}
boolean boolean
check_leuchtturm(region * r, faction * f) check_leuchtturm(region * r, faction * f)
{ {
@ -2045,102 +2067,67 @@ region *
lastregion (faction * f) lastregion (faction * f)
{ {
#ifdef SMART_INTERVALS #ifdef SMART_INTERVALS
unit * u = f->units;
region *r = f->last; region *r = f->last;
if (r==NULL && f->units!=NULL) {
for (r = f->units->region; r; r = r->next) { if (u==NULL) return NULL;
plane * p = rplane(r); if (r!=NULL) return r->next;
unit *u;
attrib *ru; /* it is safe to start in the region of the first unit. */
for (u = r->units; u; u = u->next) { f->last = u->region;
if (u->faction == f) { #ifdef ENUM_REGIONS
f->last = r->next; /* if regions have indices, we can skip ahead: */
break; for (u=u->nextF; u!=NULL; u=u->nextF) {
} r = u->region;
} if (r->index > f->last->index) f->last = r;
if (f->last == r->next) }
continue; #endif
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { /* we continue from the best region and look for travelthru etc. */
u = (unit*)ru->data.v; for (r = f->last->next; r; r = r->next) {
if (u->faction == f) { plane * p = rplane(r);
f->last = r->next; attrib *ru;
break;
} #ifndef ENUM_REGIONS
} /* for index-regions we don't need this, we already did it earlier */
if (f->last == r->next) for (u = r->units; u; u = u->next) {
continue; if (u->faction == f) {
if (check_leuchtturm(r, f)) f->last = r;
f->last = r->next; break;
if (p && is_watcher(p, f)) {
f->last = r->next;
} }
} }
if (f->last == r) continue;
#endif
/* search the region for travelthru-attributes: */
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
u = (unit*)ru->data.v;
if (u->faction == f) {
f->last = r;
break;
}
}
if (f->last == r) continue;
if (check_leuchtturm(r, f))
f->last = r;
if (p && is_watcher(p, f)) {
f->last = r;
}
} }
return f->last; return f->last->next;
#else #else
return NULL; return NULL;
#endif #endif
} }
void
update_intervals(void)
{
#ifdef SMART_INTERVALS
region *r;
for (r = regions; r; r = r->next) {
plane * p = rplane(r);
attrib *ru;
unit *u;
unit_list * ulist, *uptr;
for (u = r->units; u; u = u->next) {
faction * f = u->faction;
if (f->first==NULL) f->first = r;
f->last = r->next;
}
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
faction * f = ((unit*)ru->data.v)->faction;
if (f!=NULL) {
if (f->first==NULL) f->first = r;
f->last = r->next;
}
}
ulist = get_lighthouses(r);
for (uptr=ulist;uptr!=NULL;uptr=uptr->next) {
/* check lighthouse warden's faction */
unit * u = uptr->data;
faction * f = u->faction;
if (f->first==NULL) {
f->first = r;
}
f->last = r->next;
}
unitlist_clear(&ulist);
if (p!=NULL) {
struct watcher * w = p->watchers;
while (w) {
faction * f = w->faction;
if (f!=NULL) {
if (f->first==NULL) f->first = r;
f->last = r->next;
}
w = w->next;
}
}
}
#endif
}
region * region *
firstregion (faction * f) firstregion (faction * f)
{ {
#ifdef SMART_INTERVALS #ifdef SMART_INTERVALS
region *r; region *r = f->first;
if (f->first || !f->units)
return f->first;
if (f->units==NULL) return NULL;
if (r!=NULL) return r;
#ifndef ENUM_REGIONS
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
attrib *ru; attrib *ru;
unit *u; unit *u;
@ -2165,12 +2152,34 @@ firstregion (faction * f)
return f->first = r; return f->first = r;
} }
} }
#endif
return f->first = regions; return f->first = regions;
#else #else
return regions; return regions;
#endif #endif
} }
void
update_intervals(void)
{
#ifdef SMART_INTERVALS
region *r;
for (r = regions; r; r = r->next) {
plane * p = rplane(r);
if (p!=NULL) {
struct watcher * w = p->watchers;
while (w) {
if (w->faction!=NULL) {
update_interval(w->faction, r);
}
w = w->next;
}
}
}
#endif
}
void ** blk_list[1024]; void ** blk_list[1024];
int list_index; int list_index;
int blk_index; int blk_index;
@ -3120,9 +3129,6 @@ attrib_init(void)
/* neue REGION-Attribute */ /* neue REGION-Attribute */
at_register(&at_direction); at_register(&at_direction);
at_register(&at_moveblock); at_register(&at_moveblock);
#if AT_SALARY
at_register(&at_salary);
#endif
at_register(&at_deathcount); at_register(&at_deathcount);
at_register(&at_chaoscount); at_register(&at_chaoscount);
at_register(&at_woodcount); at_register(&at_woodcount);

View File

@ -95,7 +95,6 @@ struct building_type;
#define OLD_FAMILIAR_MOD /* conversion required */ #define OLD_FAMILIAR_MOD /* conversion required */
/* feature-dis/en-able */ /* feature-dis/en-able */
#undef WEATHER /* Kein Wetter-Modul */
#define NEW_DRIVE /* Neuer Algorithmus Transportiere/Fahre */ #define NEW_DRIVE /* Neuer Algorithmus Transportiere/Fahre */
#define PARTIAL_STUDY /* Wenn nicht genug Silber vorhanden, wird ein Talent anteilig gelernt */ #define PARTIAL_STUDY /* Wenn nicht genug Silber vorhanden, wird ein Talent anteilig gelernt */
#define NEW_RECEIPIES /* Vereinfachte, besser verteilte Kräuterzutaten für Tränke */ #define NEW_RECEIPIES /* Vereinfachte, besser verteilte Kräuterzutaten für Tränke */
@ -903,6 +902,7 @@ extern boolean faction_id_is_unused(int);
extern boolean check_leuchtturm(struct region * r, struct faction * f); extern boolean check_leuchtturm(struct region * r, struct faction * f);
extern void update_lighthouse(struct building * lh); extern void update_lighthouse(struct building * lh);
extern struct unit_list * get_lighthouses(const struct region * r); extern struct unit_list * get_lighthouses(const struct region * r);
extern int lighthouse_range(const struct building * b, const struct faction * f);
/* skills */ /* skills */
extern int max_skill(struct faction * f, skill_t sk); extern int max_skill(struct faction * f, skill_t sk);

View File

@ -340,6 +340,24 @@ set_alliance(faction * a, faction * b, int status)
(*sfp)->status |= status; (*sfp)->status |= status;
} }
#ifdef SMART_INTERVALS
void
update_interval(struct faction * f, struct region * r)
{
#ifdef ENUM_REGIONS
if (f->first==NULL || f->first->index>r->index) {
f->first = r;
}
if (f->last==NULL || f->last->index<=r->index) {
f->last = r;
}
#else
f->first = 0;
f->last = 0;
#endif
}
#endif
#ifdef REGIONOWNERS #ifdef REGIONOWNERS
boolean boolean
is_enemy(const struct faction * f, const struct faction * enemy) is_enemy(const struct faction * f, const struct faction * enemy)

View File

@ -19,7 +19,9 @@ extern "C" {
struct player; struct player;
struct alliance; struct alliance;
#undef SMART_INTERVALS /* define to speed up finding the interval of regions that a faction is in */ /* SMART_INTERVALS: define to speed up finding the interval of regions that a
faction is in. defining this speeds up the turn by 30-40% */
#define SMART_INTERVALS
#ifdef SHORTPWDS #ifdef SHORTPWDS
typedef struct shortpwd { typedef struct shortpwd {
@ -128,6 +130,10 @@ extern void add_enemy(struct faction * f, struct faction * enemy);
extern void remove_enemy(struct faction * f, struct faction * enemy); extern void remove_enemy(struct faction * f, struct faction * enemy);
#endif #endif
#ifdef SMART_INTERVALS
extern void update_interval(struct faction * f, struct region * r);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -506,8 +506,7 @@ travelthru(const unit * u, region * r)
* could be in regions that are located before the [first, last] interval, * could be in regions that are located before the [first, last] interval,
* and recalculation is needed */ * and recalculation is needed */
#ifdef SMART_INTERVALS #ifdef SMART_INTERVALS
u->faction->first = 0; update_interval(u->faction, r);
u->faction->last = 0;
#endif #endif
} }

View File

@ -432,20 +432,6 @@ add_regionlist(region_list **rl, region *r)
*rl = rl2; *rl = rl2;
} }
#if AT_SALARY
/*****************/
/* at_salary */
/*****************/
attrib_type at_salary = {
"salary",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
NO_WRITE,
NO_READ,
ATF_UNIQUE
};
#endif
/********************/ /********************/
/* at_horseluck */ /* at_horseluck */
/********************/ /********************/
@ -764,6 +750,9 @@ rsettrees(const region *r, int value)
static region *last; static region *last;
#ifdef ENUM_REGIONS
static unsigned int max_index = 0;
#endif
region * region *
new_region(int x, int y) new_region(int x, int y)
{ {
@ -786,6 +775,10 @@ new_region(int x, int y)
else else
addlist(&regions, r); addlist(&regions, r);
last = r; last = r;
#ifdef ENUM_REGIONS
assert(r->next==NULL);
r->index = ++max_index;
#endif
return r; return r;
} }

View File

@ -21,8 +21,15 @@ extern "C" {
#include "language.h" #include "language.h"
#include <assert.h> #include <assert.h>
/* FAST_CONNECT: regions are directly connected to neighbours, saves doing
a hash-access each time a neighbour is needed */
#define FAST_CONNECT #define FAST_CONNECT
/* ENUM_REGIONS: regions have 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 */
#define ENUM_REGIONS
#define RF_CHAOTIC (1<<0) #define RF_CHAOTIC (1<<0)
#define RF_MALLORN (1<<1) #define RF_MALLORN (1<<1)
#define RF_BLOCKED (1<<2) #define RF_BLOCKED (1<<2)
@ -94,15 +101,15 @@ typedef struct region {
struct attrib *attribs; struct attrib *attribs;
struct region *nexthash; struct region *nexthash;
terrain_t terrain; terrain_t terrain;
#ifdef WEATHER
weather_t weathertype;
#endif
#if NEW_RESOURCEGROWTH #if NEW_RESOURCEGROWTH
struct rawmaterial * resources; struct rawmaterial * resources;
#endif #endif
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
struct region * connect[MAXDIRECTIONS]; struct region * connect[MAXDIRECTIONS];
#endif #endif
#ifdef ENUM_REGIONS
unsigned int index;
#endif
} region; } region;
typedef struct region_list { typedef struct region_list {
@ -135,9 +142,6 @@ extern struct region * findregion(int x, int y);
extern attrib_type at_direction; extern attrib_type at_direction;
extern attrib_type at_moveblock; extern attrib_type at_moveblock;
/* new: */ /* new: */
#if AT_SALARY
extern attrib_type at_salary;
#endif
extern attrib_type at_peasantluck; extern attrib_type at_peasantluck;
extern attrib_type at_horseluck; extern attrib_type at_horseluck;
extern attrib_type at_chaoscount; extern attrib_type at_chaoscount;

View File

@ -864,7 +864,7 @@ visible_faction(const faction *f, const unit * u)
} }
faction_list * faction_list *
get_addresses(faction * f) get_addresses(faction * f, struct seen_region * seehash[])
{ {
/* "TODO: travelthru" */ /* "TODO: travelthru" */
region *r, *last = lastregion(f); region *r, *last = lastregion(f);
@ -874,7 +874,7 @@ get_addresses(faction * f)
for (r=firstregion(f);r!=last;r=r->next) { for (r=firstregion(f);r!=last;r=r->next) {
const unit * u = r->units; const unit * u = r->units;
const seen_region * sr = find_seen(r); const seen_region * sr = find_seen(seehash, r);
if (sr==NULL) continue; if (sr==NULL) continue;
while (u!=NULL) { while (u!=NULL) {
@ -918,12 +918,17 @@ get_addresses(faction * f)
return flist; return flist;
} }
seen_region * reuse;
#define MAXSEEHASH 10007 #define MAXSEEHASH 10007
seen_region * seehash[MAXSEEHASH]; seen_region * reuse;
void seen_region **
seen_init(void) seen_init(void)
{
return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region*));
}
void
seen_done(seen_region * seehash[])
{ {
int i; int i;
for (i=0;i!=MAXSEEHASH;++i) { for (i=0;i!=MAXSEEHASH;++i) {
@ -937,18 +942,17 @@ seen_init(void)
} }
void void
seen_done(void) free_seen(void)
{ {
seen_init(); while (reuse) {
while (reuse) { seen_region * r = reuse;
seen_region * r = reuse; reuse = reuse->nextHash;
reuse = reuse->nextHash; free(r);
free(r); }
}
} }
seen_region * seen_region *
find_seen(const region * r) find_seen(struct seen_region * seehash[], const region * r)
{ {
int index = ((int)r) % MAXSEEHASH; int index = ((int)r) % MAXSEEHASH;
seen_region * find=seehash[index]; seen_region * find=seehash[index];
@ -960,9 +964,9 @@ find_seen(const region * r)
} }
boolean boolean
add_seen(const struct region * r, unsigned char mode, boolean dis) add_seen(struct seen_region * seehash[], const struct region * r, unsigned char mode, boolean dis)
{ {
seen_region * find = find_seen(r); seen_region * find = find_seen(seehash, r);
if (find==NULL) { if (find==NULL) {
int index = ((int)r) % MAXSEEHASH; int index = ((int)r) % MAXSEEHASH;
if (!reuse) reuse = (seen_region*)calloc(1, sizeof(struct seen_region)); if (!reuse) reuse = (seen_region*)calloc(1, sizeof(struct seen_region));

View File

@ -80,10 +80,11 @@ typedef struct seen_region {
boolean disbelieves; boolean disbelieves;
} seen_region; } seen_region;
extern struct seen_region * find_seen(const struct region * r); extern struct seen_region * find_seen(struct seen_region * seehash[], const struct region * r);
extern boolean add_seen(const struct region * r, unsigned char mode, boolean dis); extern boolean add_seen(struct seen_region * seehash[], const struct region * r, unsigned char mode, boolean dis);
extern void seen_done(void); extern struct seen_region ** seen_init(void);
extern void seen_init(void); extern void seen_done(struct seen_region * seehash[]);
extern void free_seen(void);
extern const char* resname(resource_t res, int i); extern const char* resname(resource_t res, int i);
@ -106,7 +107,7 @@ extern int bufunit_ugroupleader(const struct faction * f, const struct unit * u,
extern const char * reportpath(void); extern const char * reportpath(void);
extern struct faction * visible_faction(const struct faction *f, const struct unit * u); extern struct faction * visible_faction(const struct faction *f, const struct unit * u);
extern struct faction_list * get_addresses(struct faction * f); extern struct faction_list * get_addresses(struct faction * f, struct seen_region * seehash[]);
extern const char * trailinto(const struct region * r, const struct locale * lang); extern const char * trailinto(const struct region * r, const struct locale * lang);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1959,30 +1959,6 @@ readgame(const char * filename, int backup)
#endif #endif
} }
#ifdef WEATHER
/* Wetter lesen */
weathers = NULL;
if (global.data_version >= 81) {
n = ri(F);
while(--n >= 0) {
weather *w;
w = calloc(1, sizeof(weather));
w->type = ri(F);
w->radius = ri(F);
w->center[0] = ri(F);
w->center[1] = ri(F);
w->move[0] = ri(F);
w->move[1] = ri(F);
addlist(&weathers, w);
}
}
#endif
fclose(F); fclose(F);
/* Unaufgeloeste Zeiger initialisieren */ /* Unaufgeloeste Zeiger initialisieren */

View File

@ -666,8 +666,7 @@ move_unit(unit * u, region * r, unit ** ulist)
addlist(ulist, u); addlist(ulist, u);
#ifdef SMART_INTERVALS #ifdef SMART_INTERVALS
u->faction->first = 0; update_interval(u->faction, r);
u->faction->last = 0;
#endif #endif
u->region = r; u->region = r;
/* keine automatische hp reduzierung bei bewegung */ /* keine automatische hp reduzierung bei bewegung */

View File

@ -192,9 +192,6 @@
<File <File
RelativePath=".\score.h"> RelativePath=".\score.h">
</File> </File>
<File
RelativePath=".\weather.h">
</File>
<File <File
RelativePath=".\wormhole.h"> RelativePath=".\wormhole.h">
</File> </File>
@ -226,9 +223,6 @@
<File <File
RelativePath=".\score.c"> RelativePath=".\score.c">
</File> </File>
<File
RelativePath=".\weather.c">
</File>
<File <File
RelativePath=".\wormhole.c"> RelativePath=".\wormhole.c">
</File> </File>