forked from github/server
firstregion/lastregion beschleunigungen und bugfix
This commit is contained in:
parent
c97d520bc6
commit
8fd95421ca
|
@ -1016,7 +1016,7 @@ report_resource(char * buf, const char * name, const struct locale * loc, int am
|
|||
}
|
||||
|
||||
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;
|
||||
int g = 0;
|
||||
|
@ -1026,7 +1026,7 @@ cr_borders(const region * r, const faction * f, int seemode, FILE * F)
|
|||
const border * b;
|
||||
if (!r2) continue;
|
||||
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;
|
||||
}
|
||||
b = get_borders(r, r2);
|
||||
|
@ -1063,18 +1063,20 @@ cr_borders(const region * r, const faction * f, int seemode, FILE * F)
|
|||
}
|
||||
|
||||
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;
|
||||
while (r!=NULL) {
|
||||
if (find_seen(r)!=NULL) {
|
||||
if (find_seen(seen, r)!=NULL) {
|
||||
*first = r;
|
||||
break;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
while (r!=NULL) {
|
||||
if (find_seen(r)!=NULL) {
|
||||
if (find_seen(seen, r)!=NULL) {
|
||||
*last = 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 */
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
@ -1098,7 +1100,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
|
|||
region * first = NULL, * last = NULL;
|
||||
const attrib * a;
|
||||
|
||||
get_seen_interval(&first, &last);
|
||||
get_seen_interval(seen, &first, &last);
|
||||
|
||||
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
||||
/* 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) {
|
||||
int modifier = 0;
|
||||
const char * tname;
|
||||
const seen_region * sd = find_seen(r);
|
||||
const seen_region * sd = find_seen(seen, r);
|
||||
|
||||
if (sd==NULL) continue;
|
||||
|
||||
|
@ -1291,7 +1293,7 @@ report_computer(FILE * F, faction * f, const faction_list * addresses,
|
|||
}
|
||||
}
|
||||
if (sd->mode == see_neighbour) {
|
||||
cr_borders(r, f, sd->mode, F);
|
||||
cr_borders(seen, r, f, sd->mode, F);
|
||||
} else {
|
||||
#define RESOURCECOMPAT
|
||||
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);
|
||||
}
|
||||
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))
|
||||
{
|
||||
/* Sonderbehandlung Teleport-Ebene */
|
||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
|||
struct faction_list;
|
||||
struct seen_region;
|
||||
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);
|
||||
extern void creport_cleanup(void);
|
||||
extern void creport_init(void);
|
||||
|
|
|
@ -172,22 +172,17 @@ dissolve_units(void)
|
|||
static int
|
||||
improve_all(faction * f, skill_t sk, int weeks)
|
||||
{
|
||||
region *r;
|
||||
unit *u;
|
||||
int n = 0;
|
||||
region *last = lastregion(f);
|
||||
|
||||
for (r = firstregion(f); r != last; r = r->next) {
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f && has_skill(u, sk)) {
|
||||
for (n=0;n!=weeks;++n) {
|
||||
learn_skill(u, sk, 1.0);
|
||||
}
|
||||
for (u = f->units; u; u = u->nextF) {
|
||||
if (has_skill(u, sk)) {
|
||||
while (weeks--) {
|
||||
learn_skill(u, sk, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
return weeks;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -295,7 +290,7 @@ find_manual(region * r, unit * u)
|
|||
scat(". Der Wissensschub ist enorm.");
|
||||
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;
|
||||
for (i=0;i!=9;++i) learn_skill(u, skill, 1.0);
|
||||
}
|
||||
|
|
|
@ -1978,7 +1978,7 @@ report_building(FILE *F, const region * r, const building * b, const faction * f
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#ifndef NEW_ITEMS
|
||||
|
@ -2234,7 +2234,7 @@ report(FILE *F, faction * f, const faction_list * addresses,
|
|||
boolean unit_in_region = false;
|
||||
boolean durchgezogen_in_region = false;
|
||||
int turm_sieht_region = false;
|
||||
seen_region * sd = find_seen(r);
|
||||
seen_region * sd = find_seen(seen, r);
|
||||
if (sd==NULL) continue;
|
||||
|
||||
switch (sd->mode) {
|
||||
|
@ -2469,13 +2469,27 @@ base36conversion(void)
|
|||
|
||||
extern void init_intervals(void);
|
||||
|
||||
#define DBG_CACHE 1
|
||||
#if DBG_CACHE
|
||||
int chits = 0;
|
||||
int ctries = 0;
|
||||
#endif
|
||||
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;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
|
@ -2486,13 +2500,13 @@ view_default(region *r, faction *f)
|
|||
if (!b->type->transparent(b, f)) break;
|
||||
b = b->next;
|
||||
}
|
||||
if (!b) add_seen(r2, see_neighbour, false);
|
||||
if (!b) add_seen(seen, r2, see_neighbour, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
view_neighbours(region * r, faction * f)
|
||||
view_neighbours(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
|
@ -2504,7 +2518,7 @@ view_neighbours(region * r, faction * f)
|
|||
b = b->next;
|
||||
}
|
||||
if (!b) {
|
||||
if (add_seen(r2, see_far, false)) {
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
if (!(terrain[rterrain(r2)].flags & FORBIDDEN_LAND)) {
|
||||
direction_t dir;
|
||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
||||
|
@ -2515,7 +2529,7 @@ view_neighbours(region * r, faction * f)
|
|||
if (!b->type->transparent(b, f)) break;
|
||||
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
|
||||
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;
|
||||
int dist = distance(center, r);
|
||||
|
@ -2542,10 +2556,10 @@ recurse_regatta(region *center, region *r, faction *f, int maxdist)
|
|||
}
|
||||
if (!b) {
|
||||
if (ndist<maxdist) {
|
||||
if (add_seen(r2, see_far, false)) {
|
||||
recurse_regatta(center, r2, f, maxdist);
|
||||
if (add_seen(seen, r2, see_far, false)) {
|
||||
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
|
||||
view_regatta(region * r, faction * f)
|
||||
view_regatta(struct seen_region ** seen, region * r, faction * f)
|
||||
{
|
||||
unit *u;
|
||||
int skill = 0;
|
||||
|
@ -2563,7 +2577,7 @@ view_regatta(region * r, faction * f)
|
|||
if (es>skill) skill=es;
|
||||
}
|
||||
}
|
||||
recurse_regatta(r, r, f, skill/2);
|
||||
recurse_regatta(seen, r, r, f, skill/2);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2574,15 +2588,12 @@ global_report(const char * filename)
|
|||
faction * f;
|
||||
faction * monsters = findfaction(MONSTER_FACTION);
|
||||
faction_list * addresses = NULL;
|
||||
struct seen_region ** seen;
|
||||
|
||||
if (!monsters) return;
|
||||
if (!F) return;
|
||||
|
||||
seen_init();
|
||||
for (r = regions; r; r = r->next) {
|
||||
add_seen(r, see_unit, true);
|
||||
}
|
||||
|
||||
/* list of all addresses */
|
||||
for (f=factions;f;f=f->next) {
|
||||
faction_list * flist = calloc(1, sizeof(faction_list));
|
||||
flist->data = f;
|
||||
|
@ -2590,25 +2601,59 @@ global_report(const char * filename)
|
|||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
region * r;
|
||||
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) {
|
||||
attrib *ru;
|
||||
unit * u;
|
||||
plane * p = rplane(r);
|
||||
unsigned char mode = see_none;
|
||||
boolean dis = false;
|
||||
#if DBG_CACHE
|
||||
++ctries;
|
||||
#endif
|
||||
int light = 0;
|
||||
|
||||
if (p) {
|
||||
watcher * w = p->watchers;
|
||||
while (w) {
|
||||
|
@ -2619,8 +2664,13 @@ prepare_report(faction * f)
|
|||
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) {
|
||||
mode = see_unit;
|
||||
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) {
|
||||
unit * u = (unit*)ru->data.v;
|
||||
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)
|
||||
continue;
|
||||
#if DBG_CACHE
|
||||
else ++chits;
|
||||
#endif
|
||||
|
||||
add_seen(r, mode, dis);
|
||||
add_seen(seen, r, mode, dis);
|
||||
/* nicht, wenn Verwirrung herrscht: */
|
||||
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)) {
|
||||
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
|
||||
if (!quiet)
|
||||
printf(" - cache hits: %.2f%%\n", 100*chits/(double)ctries);
|
||||
#endif
|
||||
return seen;
|
||||
}
|
||||
|
||||
#define FMAXHASH 1021
|
||||
|
@ -2691,12 +2745,12 @@ write_reports(faction * f, time_t ltime)
|
|||
boolean gotit = false;
|
||||
faction_list * addresses;
|
||||
char zTime[64];
|
||||
struct seen_region ** seen = prepare_report(f);
|
||||
|
||||
strftime(zTime, sizeof(zTime), "%A, %d. %B %Y, %H:%M", localtime(<ime));
|
||||
printf("Reports for %s: \r", factionname(f));
|
||||
fflush(stdout);
|
||||
prepare_report(f);
|
||||
addresses = get_addresses(f);
|
||||
addresses = get_addresses(f, seen);
|
||||
|
||||
/* NR schreiben: */
|
||||
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));
|
||||
F = cfopen(buf, "wt");
|
||||
if (F) {
|
||||
int status = report(F, f, addresses, zTime);
|
||||
int status = report(F, f, seen, addresses, zTime);
|
||||
fclose(F);
|
||||
gotit = true;
|
||||
if (status!=0) return status; /* catch errors */
|
||||
if (status!=0) {
|
||||
seen_done(seen);
|
||||
return status; /* catch errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* CR schreiben: */
|
||||
|
@ -2720,10 +2777,13 @@ write_reports(faction * f, time_t ltime)
|
|||
sprintf(buf, "%s/%d-%s.cr", reportpath(), turn, factionid(f));
|
||||
F = cfopen(buf, "wt");
|
||||
if (F) {
|
||||
int status = report_computer(F, f, addresses, ltime);
|
||||
int status = report_computer(F, f, seen, addresses, ltime);
|
||||
fclose(F);
|
||||
gotit = true;
|
||||
if (status!=0) return status; /* catch errors */
|
||||
if (status!=0) {
|
||||
seen_done(seen);
|
||||
return status; /* catch errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ZV schreiben: */
|
||||
|
@ -2736,7 +2796,10 @@ write_reports(faction * f, time_t ltime)
|
|||
if (F) {
|
||||
int status = order_template(F, 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));
|
||||
|
@ -2746,6 +2809,7 @@ write_reports(faction * f, time_t ltime)
|
|||
}
|
||||
freelist(addresses);
|
||||
|
||||
seen_done(seen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2904,7 +2968,7 @@ reports(void)
|
|||
}
|
||||
/* schliesst BAT und verschickt Zeitungen und Kommentare */
|
||||
closebatch(BAT);
|
||||
seen_done();
|
||||
free_seen();
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -570,16 +570,12 @@ int
|
|||
count_skill(faction * f, skill_t sk)
|
||||
{
|
||||
int n = 0;
|
||||
region *r;
|
||||
unit *u;
|
||||
region *last = lastregion(f);
|
||||
|
||||
for (r =firstregion(f); r != last; r = r->next) {
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f && has_skill(u, sk)) {
|
||||
if (!is_familiar(u)) n += u->number;
|
||||
for (u = f->units; u; u = u->nextF) {
|
||||
if (has_skill(u, sk)) {
|
||||
if (!is_familiar(u)) n += u->number;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -2006,6 +2002,32 @@ get_lighthouses(const region * r)
|
|||
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
|
||||
check_leuchtturm(region * r, faction * f)
|
||||
{
|
||||
|
@ -2045,102 +2067,67 @@ region *
|
|||
lastregion (faction * f)
|
||||
{
|
||||
#ifdef SMART_INTERVALS
|
||||
unit * u = f->units;
|
||||
region *r = f->last;
|
||||
if (r==NULL && f->units!=NULL) {
|
||||
for (r = f->units->region; r; r = r->next) {
|
||||
plane * p = rplane(r);
|
||||
unit *u;
|
||||
attrib *ru;
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
f->last = r->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->last == r->next)
|
||||
continue;
|
||||
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
|
||||
u = (unit*)ru->data.v;
|
||||
if (u->faction == f) {
|
||||
f->last = r->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->last == r->next)
|
||||
continue;
|
||||
if (check_leuchtturm(r, f))
|
||||
f->last = r->next;
|
||||
if (p && is_watcher(p, f)) {
|
||||
f->last = r->next;
|
||||
|
||||
if (u==NULL) return NULL;
|
||||
if (r!=NULL) return r->next;
|
||||
|
||||
/* it is safe to start in the region of the first unit. */
|
||||
f->last = u->region;
|
||||
#ifdef ENUM_REGIONS
|
||||
/* if regions have indices, we can skip ahead: */
|
||||
for (u=u->nextF; u!=NULL; u=u->nextF) {
|
||||
r = u->region;
|
||||
if (r->index > f->last->index) f->last = r;
|
||||
}
|
||||
#endif
|
||||
/* we continue from the best region and look for travelthru etc. */
|
||||
for (r = f->last->next; r; r = r->next) {
|
||||
plane * p = rplane(r);
|
||||
attrib *ru;
|
||||
|
||||
#ifndef ENUM_REGIONS
|
||||
/* for index-regions we don't need this, we already did it earlier */
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == f) {
|
||||
f->last = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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
|
||||
return NULL;
|
||||
#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 *
|
||||
firstregion (faction * f)
|
||||
{
|
||||
#ifdef SMART_INTERVALS
|
||||
region *r;
|
||||
if (f->first || !f->units)
|
||||
return f->first;
|
||||
region *r = f->first;
|
||||
|
||||
if (f->units==NULL) return NULL;
|
||||
if (r!=NULL) return r;
|
||||
|
||||
#ifndef ENUM_REGIONS
|
||||
for (r = regions; r; r = r->next) {
|
||||
attrib *ru;
|
||||
unit *u;
|
||||
|
@ -2165,12 +2152,34 @@ firstregion (faction * f)
|
|||
return f->first = r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return f->first = regions;
|
||||
#else
|
||||
return regions;
|
||||
#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];
|
||||
int list_index;
|
||||
int blk_index;
|
||||
|
@ -3120,9 +3129,6 @@ attrib_init(void)
|
|||
/* neue REGION-Attribute */
|
||||
at_register(&at_direction);
|
||||
at_register(&at_moveblock);
|
||||
#if AT_SALARY
|
||||
at_register(&at_salary);
|
||||
#endif
|
||||
at_register(&at_deathcount);
|
||||
at_register(&at_chaoscount);
|
||||
at_register(&at_woodcount);
|
||||
|
|
|
@ -95,7 +95,6 @@ struct building_type;
|
|||
|
||||
#define OLD_FAMILIAR_MOD /* conversion required */
|
||||
/* feature-dis/en-able */
|
||||
#undef WEATHER /* Kein Wetter-Modul */
|
||||
#define NEW_DRIVE /* Neuer Algorithmus Transportiere/Fahre */
|
||||
#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 */
|
||||
|
@ -903,6 +902,7 @@ extern boolean faction_id_is_unused(int);
|
|||
extern boolean check_leuchtturm(struct region * r, struct faction * f);
|
||||
extern void update_lighthouse(struct building * lh);
|
||||
extern struct unit_list * get_lighthouses(const struct region * r);
|
||||
extern int lighthouse_range(const struct building * b, const struct faction * f);
|
||||
|
||||
/* skills */
|
||||
extern int max_skill(struct faction * f, skill_t sk);
|
||||
|
|
|
@ -340,6 +340,24 @@ set_alliance(faction * a, faction * b, int 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
|
||||
boolean
|
||||
is_enemy(const struct faction * f, const struct faction * enemy)
|
||||
|
|
|
@ -19,7 +19,9 @@ extern "C" {
|
|||
struct player;
|
||||
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
|
||||
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);
|
||||
#endif
|
||||
|
||||
#ifdef SMART_INTERVALS
|
||||
extern void update_interval(struct faction * f, struct region * r);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -506,8 +506,7 @@ travelthru(const unit * u, region * r)
|
|||
* could be in regions that are located before the [first, last] interval,
|
||||
* and recalculation is needed */
|
||||
#ifdef SMART_INTERVALS
|
||||
u->faction->first = 0;
|
||||
u->faction->last = 0;
|
||||
update_interval(u->faction, r);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -432,20 +432,6 @@ add_regionlist(region_list **rl, region *r)
|
|||
*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 */
|
||||
/********************/
|
||||
|
@ -764,6 +750,9 @@ rsettrees(const region *r, int value)
|
|||
|
||||
static region *last;
|
||||
|
||||
#ifdef ENUM_REGIONS
|
||||
static unsigned int max_index = 0;
|
||||
#endif
|
||||
region *
|
||||
new_region(int x, int y)
|
||||
{
|
||||
|
@ -786,6 +775,10 @@ new_region(int x, int y)
|
|||
else
|
||||
addlist(®ions, r);
|
||||
last = r;
|
||||
#ifdef ENUM_REGIONS
|
||||
assert(r->next==NULL);
|
||||
r->index = ++max_index;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,15 @@ extern "C" {
|
|||
#include "language.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
|
||||
|
||||
/* 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_MALLORN (1<<1)
|
||||
#define RF_BLOCKED (1<<2)
|
||||
|
@ -94,15 +101,15 @@ typedef struct region {
|
|||
struct attrib *attribs;
|
||||
struct region *nexthash;
|
||||
terrain_t terrain;
|
||||
#ifdef WEATHER
|
||||
weather_t weathertype;
|
||||
#endif
|
||||
#if NEW_RESOURCEGROWTH
|
||||
struct rawmaterial * resources;
|
||||
#endif
|
||||
#ifdef FAST_CONNECT
|
||||
struct region * connect[MAXDIRECTIONS];
|
||||
#endif
|
||||
#ifdef ENUM_REGIONS
|
||||
unsigned int index;
|
||||
#endif
|
||||
} region;
|
||||
|
||||
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_moveblock;
|
||||
/* new: */
|
||||
#if AT_SALARY
|
||||
extern attrib_type at_salary;
|
||||
#endif
|
||||
extern attrib_type at_peasantluck;
|
||||
extern attrib_type at_horseluck;
|
||||
extern attrib_type at_chaoscount;
|
||||
|
|
|
@ -864,7 +864,7 @@ visible_faction(const faction *f, const unit * u)
|
|||
}
|
||||
|
||||
faction_list *
|
||||
get_addresses(faction * f)
|
||||
get_addresses(faction * f, struct seen_region * seehash[])
|
||||
{
|
||||
/* "TODO: travelthru" */
|
||||
region *r, *last = lastregion(f);
|
||||
|
@ -874,7 +874,7 @@ get_addresses(faction * f)
|
|||
|
||||
for (r=firstregion(f);r!=last;r=r->next) {
|
||||
const unit * u = r->units;
|
||||
const seen_region * sr = find_seen(r);
|
||||
const seen_region * sr = find_seen(seehash, r);
|
||||
|
||||
if (sr==NULL) continue;
|
||||
while (u!=NULL) {
|
||||
|
@ -918,12 +918,17 @@ get_addresses(faction * f)
|
|||
return flist;
|
||||
}
|
||||
|
||||
seen_region * reuse;
|
||||
#define MAXSEEHASH 10007
|
||||
seen_region * seehash[MAXSEEHASH];
|
||||
seen_region * reuse;
|
||||
|
||||
void
|
||||
seen_region **
|
||||
seen_init(void)
|
||||
{
|
||||
return (seen_region **)calloc(MAXSEEHASH, sizeof(seen_region*));
|
||||
}
|
||||
|
||||
void
|
||||
seen_done(seen_region * seehash[])
|
||||
{
|
||||
int i;
|
||||
for (i=0;i!=MAXSEEHASH;++i) {
|
||||
|
@ -937,18 +942,17 @@ seen_init(void)
|
|||
}
|
||||
|
||||
void
|
||||
seen_done(void)
|
||||
free_seen(void)
|
||||
{
|
||||
seen_init();
|
||||
while (reuse) {
|
||||
seen_region * r = reuse;
|
||||
reuse = reuse->nextHash;
|
||||
free(r);
|
||||
}
|
||||
while (reuse) {
|
||||
seen_region * r = reuse;
|
||||
reuse = reuse->nextHash;
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
|
||||
seen_region *
|
||||
find_seen(const region * r)
|
||||
find_seen(struct seen_region * seehash[], const region * r)
|
||||
{
|
||||
int index = ((int)r) % MAXSEEHASH;
|
||||
seen_region * find=seehash[index];
|
||||
|
@ -960,9 +964,9 @@ find_seen(const region * r)
|
|||
}
|
||||
|
||||
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) {
|
||||
int index = ((int)r) % MAXSEEHASH;
|
||||
if (!reuse) reuse = (seen_region*)calloc(1, sizeof(struct seen_region));
|
||||
|
|
|
@ -80,10 +80,11 @@ typedef struct seen_region {
|
|||
boolean disbelieves;
|
||||
} seen_region;
|
||||
|
||||
extern struct seen_region * find_seen(const struct region * r);
|
||||
extern boolean add_seen(const struct region * r, unsigned char mode, boolean dis);
|
||||
extern void seen_done(void);
|
||||
extern void seen_init(void);
|
||||
extern struct seen_region * find_seen(struct seen_region * seehash[], const struct region * r);
|
||||
extern boolean add_seen(struct seen_region * seehash[], const struct region * r, unsigned char mode, boolean dis);
|
||||
extern struct seen_region ** 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);
|
||||
|
||||
|
@ -106,7 +107,7 @@ extern int bufunit_ugroupleader(const struct faction * f, const struct unit * u,
|
|||
|
||||
extern const char * reportpath(void);
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1959,30 +1959,6 @@ readgame(const char * filename, int backup)
|
|||
#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);
|
||||
|
||||
/* Unaufgeloeste Zeiger initialisieren */
|
||||
|
|
|
@ -666,8 +666,7 @@ move_unit(unit * u, region * r, unit ** ulist)
|
|||
addlist(ulist, u);
|
||||
|
||||
#ifdef SMART_INTERVALS
|
||||
u->faction->first = 0;
|
||||
u->faction->last = 0;
|
||||
update_interval(u->faction, r);
|
||||
#endif
|
||||
u->region = r;
|
||||
/* keine automatische hp reduzierung bei bewegung */
|
||||
|
|
|
@ -192,9 +192,6 @@
|
|||
<File
|
||||
RelativePath=".\score.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\weather.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wormhole.h">
|
||||
</File>
|
||||
|
@ -226,9 +223,6 @@
|
|||
<File
|
||||
RelativePath=".\score.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\weather.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wormhole.c">
|
||||
</File>
|
||||
|
|
Loading…
Reference in New Issue