From 8fd95421ca0d05b6e9ce3a31fa99afe98110ecd8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 27 Apr 2005 21:03:08 +0000 Subject: [PATCH] firstregion/lastregion beschleunigungen und bugfix --- src/common/gamecode/creport.c | 22 ++-- src/common/gamecode/creport.h | 2 +- src/common/gamecode/randenc.c | 17 +-- src/common/gamecode/report.c | 172 ++++++++++++++++++--------- src/common/kernel/eressea.c | 190 +++++++++++++++--------------- src/common/kernel/eressea.h | 2 +- src/common/kernel/faction.c | 18 +++ src/common/kernel/faction.h | 8 +- src/common/kernel/movement.c | 3 +- src/common/kernel/region.c | 21 ++-- src/common/kernel/region.h | 16 ++- src/common/kernel/reports.c | 34 +++--- src/common/kernel/reports.h | 11 +- src/common/kernel/save.c | 24 ---- src/common/kernel/unit.c | 3 +- src/common/modules/modules.vcproj | 6 - 16 files changed, 305 insertions(+), 244 deletions(-) diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 1b0ab33d9..1755976e3 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -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 */ diff --git a/src/common/gamecode/creport.h b/src/common/gamecode/creport.h index 66b8be1eb..0a45183ea 100644 --- a/src/common/gamecode/creport.h +++ b/src/common/gamecode/creport.h @@ -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); diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 801dbcb87..664671b22 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -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); } diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 16e67e3c8..c12fcdc03 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -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 (ndistskill) 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 (modeunits; 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 (modeattribs, &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 (modeattribs, 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; } diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index ebed24e78..bc9ed8164 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -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); diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 0bc11914f..4740a52de 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -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); diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 10dd7ab59..891692735 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -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) diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index 873f0db17..e5a2e6c8b 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -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 diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index 81fb60d31..d4042b710 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -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 } diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index f24673113..944cc8033 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -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; } diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index 21adc564c..c314466a2 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -21,8 +21,15 @@ extern "C" { #include "language.h" #include +/* 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; diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 653d1745d..7f7115326 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -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)); diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index 65badca70..ed75f29e0 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -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 diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 7dde7ac25..4a4f86b3c 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -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 */ diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index d3be31d68..a8c9c907f 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -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 */ diff --git a/src/common/modules/modules.vcproj b/src/common/modules/modules.vcproj index 645fd988b..4329128c4 100644 --- a/src/common/modules/modules.vcproj +++ b/src/common/modules/modules.vcproj @@ -192,9 +192,6 @@ - - @@ -226,9 +223,6 @@ - -