From fa5fa4abcc41ff4b11cce852e3aa30c735e659c8 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 15 Apr 2008 07:57:03 +0200 Subject: [PATCH] Don't store RAILWAYS track in sectors Storing track in sectors is problematic, because we need to update adjacent sectors when updating a sector in a way that changes its capability to extend railway into its neighbors. This invalidates cached adjacent sectors, and calling code may not be prepared for that. Specifically, bridge building caches the bridge head, and writes it back later, wiping out the track update. Replace struct sctstr member sct_track by new sct_rail_track(). Make selector track virtual. Remove the code to keep sct_track up-to-date: set_railway(), update_railway(). Unfortunately, this causes cyclic dependencies between link libraries: the virtual selector needs to be referenced from src/lib/global/nsc.c, and it needs to reference stuff from src/lib/common/file.c. Hack around it in Make.mk for now. --- Make.mk | 1 + include/prototypes.h | 1 - include/sect.h | 4 +-- src/lib/commands/sinf.c | 2 +- src/lib/commands/spy.c | 2 +- src/lib/common/move.c | 31 +++++++++++++++++++ src/lib/global/nsc.c | 10 +++++- src/lib/subs/satmap.c | 2 +- src/lib/subs/sect.c | 67 ----------------------------------------- src/lib/update/finish.c | 5 --- 10 files changed, 46 insertions(+), 79 deletions(-) diff --git a/Make.mk b/Make.mk index 97e44e5d8..269855159 100644 --- a/Make.mk +++ b/Make.mk @@ -284,6 +284,7 @@ ifeq ($(empthread),Windows) $(client): src/lib/w32/getopt.o endif +$(util): src/lib/common/move.o # FIXME hack for opt_RAILWAYS $(util): $(libs) lib/libas.a: $(filter src/lib/as/%, $(obj)) diff --git a/include/prototypes.h b/include/prototypes.h index a82f9f7ae..cc4fd26a9 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -627,7 +627,6 @@ extern void sathead(void); extern int sct_postread(int, void *); extern int sct_prewrite(int, void *); extern void item_prewrite(short *); -extern void set_railway(struct sctstr *); extern int issector(char *); /* sectdamage.c */ extern int sect_damage(struct sctstr *, int); diff --git a/include/sect.h b/include/sect.h index 408b1600b..b0237a3c4 100644 --- a/include/sect.h +++ b/include/sect.h @@ -77,7 +77,6 @@ struct sctstr { natid sct_oldown; /* old owner of sector (for liberation) */ unsigned char sct_updated; /* Has this sect been updated? */ unsigned char sct_off; /* Should this sector produce? */ - unsigned char sct_track; /* nearby railways (RAILWAYS) */ short sct_item[I_MAX+1]; /* amount of items stored here */ short sct_del[I_MAX+1]; /* delivieries */ short sct_dist[I_MAX+1]; /* distribution thresholds */ @@ -189,7 +188,7 @@ extern struct dchrstr bigcity_dchr; /* Can trains enter sector SP? */ #define SCT_HAS_RAIL(sp) \ - (opt_RAILWAYS ? (sp)->sct_track != 0 \ + (opt_RAILWAYS ? sct_rail_track((sp)) != 0 \ : intrchr[INT_RAIL].in_enable && (sp)->sct_rail != 0) #define MOB_MOVE 0 @@ -227,5 +226,6 @@ struct sctintrins { extern struct sctintrins intrchr[INT_DEF + 2]; extern int fort_fire(struct sctstr *); +extern int sct_rail_track(struct sctstr *); #endif diff --git a/src/lib/commands/sinf.c b/src/lib/commands/sinf.c index e316f9822..43780c6ee 100644 --- a/src/lib/commands/sinf.c +++ b/src/lib/commands/sinf.c @@ -74,7 +74,7 @@ sinfra(void) pr("%4d%% ", sect.sct_road); prmobcost(§, MOB_MOVE); if (opt_RAILWAYS) - pr(sect.sct_track ? " yes " : " no "); + pr(sct_rail_track(§) ? " yes " : " no "); else pr("%4d%% ", sect.sct_rail); prmobcost(§, MOB_RAIL); diff --git a/src/lib/commands/spy.c b/src/lib/commands/spy.c index 8c3151f38..020b42c8a 100644 --- a/src/lib/commands/spy.c +++ b/src/lib/commands/spy.c @@ -224,7 +224,7 @@ spyline(struct sctstr *sp) sp->sct_oldown, roundintby((int)sp->sct_effic, 10), roundintby((int)sp->sct_road, 10), - opt_RAILWAYS ? !!sp->sct_track : roundintby(sp->sct_rail, 10), + opt_RAILWAYS ? !!sct_rail_track(sp) : roundintby(sp->sct_rail, 10), roundintby((int)sp->sct_defense, 10), roundintby(sp->sct_item[I_CIVIL], 10), roundintby(sp->sct_item[I_MILIT], 10), diff --git a/src/lib/common/move.c b/src/lib/common/move.c index f3377fe6d..7cbabf824 100644 --- a/src/lib/common/move.c +++ b/src/lib/common/move.c @@ -33,6 +33,7 @@ #include +#include "file.h" #include "misc.h" #include "nat.h" #include "optlist.h" @@ -90,3 +91,33 @@ speed_factor(double effspd, int tech) { return 480.0 / (effspd + techfact(tech, effspd)); } + +/* Minimal efficiency for railway and railway extension (opt_RAILWAYS) */ +#define SCT_RAIL_EFF 5 +#define SCT_RAIL_EXT_EFF 60 + +/* Is sector SP a railway? */ +#define SCT_IS_RAILWAY(sp) \ + (dchr[(sp)->sct_type].d_mob1 == 0 && (sp)->sct_effic >= SCT_RAIL_EFF) +/* May sector SP have a railway extension? */ +#define SCT_MAY_HAVE_RAIL_EXT(sp) \ + ((sp)->sct_effic >= SCT_RAIL_EXT_EFF) +/* Does railway sector SP extend railway track into sector TOSP? */ +#define SCT_EXTENDS_RAIL(sp, tosp) \ + ((sp)->sct_own == (tosp)->sct_own && SCT_MAY_HAVE_RAIL_EXT(tosp)) + +int +sct_rail_track(struct sctstr *sp) +{ + int i, res; + struct sctstr *nsp; + + res = !!SCT_IS_RAILWAY(sp); + for (i = DIR_FIRST; i <= DIR_LAST; i++) { + nsp = getsectp(sp->sct_x + diroff[i][0], + sp->sct_y + diroff[i][1]); + if (SCT_IS_RAILWAY(nsp) && SCT_EXTENDS_RAIL(nsp, sp)) + res++; + } + return res; +} diff --git a/src/lib/global/nsc.c b/src/lib/global/nsc.c index c2bd8faa1..0abe19acc 100644 --- a/src/lib/global/nsc.c +++ b/src/lib/global/nsc.c @@ -47,6 +47,7 @@ static void *nsc_ver(struct valstr *, struct natstr *, void *); static void *nsc_ver_maxnoc(struct valstr *, struct natstr *, void *); +static void *nsc_sct_track(struct valstr *, struct natstr *, void *); static void *nsc_pln_att(struct valstr *, struct natstr *, void *); static void *nsc_pln_def(struct valstr *, struct natstr *, void *); static void *nsc_lnd_att(struct valstr *, struct natstr *, void *); @@ -153,7 +154,7 @@ struct castr sect_ca[] = { {"uran", fldoff(sct_uran), NSC_UCHAR, 0, NULL, EF_BAD, 0}, {"oldown", fldoff(sct_oldown), NSC_NATID, 0, NULL, EF_NATION, 0}, {"off", fldoff(sct_off), NSC_UCHAR, 0, NULL, EF_BAD, 0}, - {"track", fldoff(sct_track), NSC_UCHAR, 0, NULL, EF_BAD, NSC_EXTRA}, + {"track", 0, NSC_LONG, 0, nsc_sct_track, EF_BAD, NSC_EXTRA}, NSC_IVEC(fldoff(sct_item), ""), NSC_IVEC(fldoff(sct_dist), "_dist"), NSC_IVEC(fldoff(sct_del), "_del"), @@ -766,6 +767,13 @@ nsc_ver_maxnoc(struct valstr *val, struct natstr *np, void *ptr) return NULL; } +static void * +nsc_sct_track(struct valstr *val, struct natstr *np, void *ptr) +{ + val->val_as.lng = sct_rail_track(ptr); + return NULL; +} + static void * nsc_pln_def(struct valstr *val, struct natstr *np, void *ptr) { diff --git a/src/lib/subs/satmap.c b/src/lib/subs/satmap.c index 8e5fcb4fd..f4def5dff 100644 --- a/src/lib/subs/satmap.c +++ b/src/lib/subs/satmap.c @@ -285,7 +285,7 @@ satdisp_sect(struct sctstr *sp, int acc) dchr[sp->sct_type].d_mnem, sp->sct_own, roundintby((int)sp->sct_effic, acc / 2), roundintby((int)sp->sct_road, acc / 2), - opt_RAILWAYS ? !!sp->sct_track : roundintby(sp->sct_rail, acc / 2), + opt_RAILWAYS ? !!sct_rail_track(sp) : roundintby(sp->sct_rail, acc / 2), roundintby((int)sp->sct_defense, acc / 2), roundintby(sp->sct_item[I_CIVIL], acc), roundintby(sp->sct_item[I_MILIT], acc), diff --git a/src/lib/subs/sect.c b/src/lib/subs/sect.c index 87dd3fed7..541b9b9ba 100644 --- a/src/lib/subs/sect.c +++ b/src/lib/subs/sect.c @@ -42,7 +42,6 @@ #include "nat.h" #include "nsc.h" #include "optlist.h" -#include "path.h" #include "plane.h" #include "player.h" #include "prototypes.h" @@ -50,7 +49,6 @@ #include "xy.h" static int checksect(struct sctstr *); -static void update_railway(struct sctstr *, struct sctstr *); int sct_postread(int id, void *ptr) @@ -73,8 +71,6 @@ sct_prewrite(int id, void *ptr) bridge_damaged(sp); checksect(sp); getsect(sp->sct_x, sp->sct_y, §); - if (opt_RAILWAYS) - update_railway(sp, §); return 1; } @@ -132,69 +128,6 @@ checksect(struct sctstr *sp) return 1; } -/* Minimal efficiency for railway and railway extension (opt_RAILWAYS) */ -#define SCT_RAIL_EFF 5 -#define SCT_RAIL_EXT_EFF 60 - -/* Is sector SP a railway? */ -#define SCT_IS_RAILWAY(sp) \ - (dchr[(sp)->sct_type].d_mob1 == 0 && (sp)->sct_effic >= SCT_RAIL_EFF) -/* May sector SP have a railway extension? */ -#define SCT_MAY_HAVE_RAIL_EXT(sp) \ - ((sp)->sct_effic >= SCT_RAIL_EXT_EFF) -/* Does railway sector SP extend railway track into sector TOSP? */ -#define SCT_EXTENDS_RAIL(sp, tosp) \ - ((sp)->sct_own == (tosp)->sct_own && SCT_MAY_HAVE_RAIL_EXT(tosp)) - -static void -update_railway(struct sctstr *sp, struct sctstr *oldsp) -{ - struct sctstr sect; - int was_railway = SCT_IS_RAILWAY(oldsp); - int is_railway = SCT_IS_RAILWAY(sp); - int i; - - if (was_railway == is_railway - && sp->sct_own == oldsp->sct_own - && SCT_MAY_HAVE_RAIL_EXT(sp) == SCT_MAY_HAVE_RAIL_EXT(oldsp)) - return; - - if (was_railway) - sp->sct_track--; - if (is_railway) - sp->sct_track++; - - for (i = DIR_FIRST; i <= DIR_LAST; i++) { - getsect(sp->sct_x + diroff[i][0], - sp->sct_y + diroff[i][1], - §); - if (SCT_IS_RAILWAY(§) && SCT_EXTENDS_RAIL(§, oldsp)) - sp->sct_track--; - if (SCT_IS_RAILWAY(§) && SCT_EXTENDS_RAIL(§, sp)) - sp->sct_track++; - if (was_railway && SCT_EXTENDS_RAIL(oldsp, §)) - sect.sct_track--; - if (is_railway && SCT_EXTENDS_RAIL(sp, §)) - sect.sct_track++; - putsect(§); - } -} - -void -set_railway(struct sctstr *sp) -{ - int i; - struct sctstr *nsp; - - sp->sct_track = !!SCT_IS_RAILWAY(sp); - for (i = DIR_FIRST; i <= DIR_LAST; i++) { - nsp = getsectp(sp->sct_x + diroff[i][0], - sp->sct_y + diroff[i][1]); - if (SCT_IS_RAILWAY(nsp) && SCT_EXTENDS_RAIL(nsp, sp)) - sp->sct_track++; - } -} - int issector(char *arg) { diff --git a/src/lib/update/finish.c b/src/lib/update/finish.c index 8c2693ce9..da03cee16 100644 --- a/src/lib/update/finish.c +++ b/src/lib/update/finish.c @@ -87,11 +87,6 @@ finish_sects(int etu) /* Wipe it clean */ memset(g_distptrs, 0, WORLD_SZ() * sizeof(*g_distptrs)); - if (opt_RAILWAYS) { - for (n = 0; NULL != (sp = getsectid(n)); n++) - set_railway(sp); - } - logerror("delivering...\n"); /* Do deliveries */ for (n = 0; NULL != (sp = getsectid(n)); n++) { -- 2.43.0