]> git.pond.sub.org Git - empserver/commitdiff
New option RAILWAYS
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 26 Oct 2008 17:24:41 +0000 (13:24 -0400)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 1 Nov 2008 15:40:15 +0000 (11:40 -0400)
With RAILWAYS, highway-like sectors double as rail.  They need to be
at least 5% efficient to be operational, and then they additionally
extend rail into adjacent sectors that are at least 60% efficient.

New opt_RAILWAYS, SCT_HAS_RAIL(), sct_rail_track().  Update
sector_mcost(), bp_neighbors(), lnd_mar_one_sector() for RAILWAYS
mobility rules.  Update sinfra(), spyline(), satdisp_sect() to show
rail track instead of rail infrastructure for RAILWAYS.

New virtual sector selector track, implemented by nsc_sct_track().

13 files changed:
include/econfig-spec.h
include/sect.h
info/Options.t
info/Railroad.t [new file with mode: 0644]
info/Unit-types.t
src/lib/commands/sinf.c
src/lib/commands/spy.c
src/lib/common/move.c
src/lib/common/nsc.c
src/lib/common/path.c
src/lib/global/options.c
src/lib/subs/lndsub.c
src/lib/subs/satmap.c

index 756bed167a5cf87790ccc6fa620484fbcf6d9440..e52ecc11a5f84c1824ad81172c858e9ec7c175a6 100644 (file)
@@ -177,6 +177,8 @@ EMPCF_OPT("NO_PLAGUE", opt_NO_PLAGUE,
     "Disable plague")
 EMPCF_OPT("PINPOINTMISSILE", opt_PINPOINTMISSILE,
     "Enable marine missiles")
+EMPCF_OPT("RAILWAYS", opt_RAILWAYS,
+    "Highways double as rail")
 EMPCF_OPT("RES_POP", opt_RES_POP,
     "Population is limited by research")
 EMPCF_OPT("SAIL", opt_SAIL,
index 2c682961689f500b3bc218356b9274431800c074..fb437c964df0c7b99e70aaff2906a462bdca6128 100644 (file)
@@ -183,6 +183,11 @@ extern struct dchrstr bigcity_dchr;
 
 #define FORTEFF 5              /* forts must be 5% efficient to fire. */
 
+/* Can trains enter sector SP? */
+#define SCT_HAS_RAIL(sp)                                       \
+    (opt_RAILWAYS ? sct_rail_track((sp)) != 0                  \
+     : intrchr[INT_RAIL].in_enable && (sp)->sct_rail != 0)
+
 #define MOB_MOVE    0
 #define MOB_MARCH   1
 #define MOB_RAIL    2
@@ -218,5 +223,6 @@ struct sctintrins {
 extern struct sctintrins intrchr[INT_DEF + 2];
 
 extern int fort_fire(struct sctstr *);
+extern int sct_rail_track(struct sctstr *);
 
 #endif
index c5b199dc830188074a4e890dd925e2c99e2dffa8..e70591939f50cdcbedeaff74add228d6c1c4c86b 100644 (file)
@@ -41,6 +41,7 @@ MARKET:         Time-delay market and trade.
 LOANS:          Allows S&L type interaction between countries.
 LANDSPIES:      Creates land unit style spies.
 NO_FORT_FIRE:   Forts cannot fire.
+RAILWAYS       Highways double as rail
 TECH_POP:       Technology costs more to make as your civilian population
                  grows past 50,000 civilians.
 TREATIES:       Sign treaties with your friends and enemies, and breaking of
diff --git a/info/Railroad.t b/info/Railroad.t
new file mode 100644 (file)
index 0000000..8864999
--- /dev/null
@@ -0,0 +1,27 @@
+.TH Concept "Railroad"
+.NA Railroad "How railroads work"
+.LV Expert
+Trains are land units with capability \*Qtrain\*U.  They can't be
+loaded on land units, but they can be loaded on ships, subject to the
+usual restrictions for non-light and heavy land units.
+.s1
+Unlike other units, trains can enter a sector only if it has
+(operational) railroad track.
+.s1
+If option RAILWAYS is disabled, a sector has railroad track as long as
+its rail infrastructure efficiency is non-zero.  Train mobility cost
+depends on rail infrastructure efficiency (see \*Qinfo Mobility\*U).
+Spy and satellite reports show approximate rail infrastructure
+efficiency in column \*Qrl eff\*U.
+.s1
+If option RAILWAYS is enabled, all highway-like sectors are railways,
+and the track is operational as long as the sector is at least 5%
+efficient.  A sector is highway-like if its mobility cost at 100% is
+zero (column mob cost in \*Qshow sect s\*u).  Operational railways
+additionally extend track into adjacent sectors that are at least 60%
+efficient and owned by the same nation.  Sector selector track gives
+the number of operational railways within one sector range.  Spy and
+satellite reports show the presence of track in column \*Qrl eff\*U.
+To visualize your railway network, try \*Qsect # ?track#0\*U.
+.s1
+.SA "LandUnits"
index a2761dceb0afc110f32805f099c6855c7984c179..e72282d127b9b985df1e3a9b5e83b3900c3dd686 100644 (file)
@@ -193,6 +193,7 @@ the unit can fire 'general unit flak' (see "info Flak")
 the unit is a spy
 .L train
 the unit is a train, and can't be loaded on land units
+(see "info Railroad")
 .L heavy
 the unit cannot be carried on land units or ships, not even supply ships
 .in
@@ -235,4 +236,3 @@ marines 1                  5f 10s xlight light marine
 .FI
 .s1
 .SA "land, LandUnits"
-
index 5d01ecd50037e2a284db4b04ab3afd16ee3adfeb..32e8fc1ff9e5a095943b4d6ea14816d7869389ea 100644 (file)
@@ -73,7 +73,10 @@ sinfra(void)
        pr("%4d%% ", sect.sct_effic);
        pr("%4d%% ", sect.sct_road);
        prmobcost(&sect, MOB_MOVE);
-       pr("%4d%% ", sect.sct_rail);
+       if (opt_RAILWAYS)
+           pr(sct_rail_track(&sect) ? "  yes " : "   no ");
+       else
+           pr("%4d%% ", sect.sct_rail);
        prmobcost(&sect, MOB_RAIL);
        pr("%4d%% ", SCT_DEFENSE(&sect));
        pr("%5.2f\n", sector_strength(&sect));
index 5c31d243327257d7bc71b383354e56c5d5d4b168..8d65dea4c65ff3b93ede00ec5eebe9d16987611c 100644 (file)
@@ -189,7 +189,7 @@ spy_report(struct sctstr *sp)
        sp->sct_oldown,
        roundintby((int)sp->sct_effic, 10),
        roundintby((int)sp->sct_road, 10),
-       roundintby((int)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),
index 3257acb97ecf45c9d08d29e11ad16e36a0f192a9..c648bef3e961beea71aea1929eaf41e471c27a2c 100644 (file)
 
 #include <config.h>
 
+#include "file.h"
 #include "misc.h"
 #include "nat.h"
+#include "optlist.h"
 #include "path.h"
 #include "sect.h"
 #include "xy.h"
@@ -48,6 +50,12 @@ sector_mcost(struct sctstr *sp, int mobtype)
     if (base < 0)
        return -1.0;
 
+    if (mobtype == MOB_RAIL && opt_RAILWAYS) {
+       if (!SCT_HAS_RAIL(sp))
+           return -1;
+       mobtype = MOB_MARCH;
+    }
+
     /* linear function in eff, d_mob0 at 0%, d_mob1 at 100% */
     base += (dchr[sp->sct_type].d_mob1 - base) * sp->sct_effic / 100;
     if (CANT_HAPPEN(base < 0))
@@ -83,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;
+}
index 15e7d8099273ce666b1724f4d63e89c50983bcb5..d507e30b858b94d1f6f003c409b57cb826c77895 100644 (file)
@@ -49,6 +49,7 @@
 static void *nsc_ver(struct valstr *, struct natstr *, void *);
 static void *nsc_ver_maxnoc(struct valstr *, struct natstr *, void *);
 static void *nsc_sct_terr(struct valstr *, struct natstr *, void *);
+static void *nsc_sct_track(struct valstr *, struct natstr *, void *);
 static void *nsc_cargo_nplane(struct valstr *, struct natstr *, void *);
 static void *nsc_cargo_nchopper(struct valstr *, struct natstr *, void *);
 static void *nsc_cargo_nxlight(struct valstr *, struct natstr *, void *);
@@ -160,6 +161,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", 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"),
@@ -772,6 +774,13 @@ nsc_sct_terr(struct valstr *val, struct natstr *np, void *ptr)
     return ptr;
 }
 
+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_cargo_nplane(struct valstr *val, struct natstr *np, void *ptr)
 {
index 103d3b0ae80c8a240834e522a5d7b6fd6deb8d87..b2e9b5ed722c59366a076fb4c69423366cd10083 100644 (file)
@@ -218,8 +218,7 @@ bp_neighbors(struct as_coord c, struct as_coord *cp, void *pp)
           move through it.  We calculate it later. */
        if (dchr[sp->sct_type].d_mob0 < 0)
            continue;
-       if (bp->bp_mobtype == MOB_RAIL
-           && (!intrchr[INT_RAIL].in_enable || sp->sct_rail == 0))
+       if (bp->bp_mobtype == MOB_RAIL && !SCT_HAS_RAIL(sp))
            continue;
        if (sp->sct_own != from->sct_own)
            continue;
index 3cab294c228b4bec124e3c604b2e1252d9d2b127..f06af5928e379caac5aca89b64591b13a25a78ce 100644 (file)
@@ -57,6 +57,7 @@ int opt_NOMOBCOST = 1;
 int opt_NO_FORT_FIRE = 0;
 int opt_NO_PLAGUE = 1;
 int opt_PINPOINTMISSILE = 1;
+int opt_RAILWAYS = 0;
 int opt_RES_POP = 0;
 int opt_SAIL = 1;
 int opt_SLOW_WAR = 0;
index 548877efcee4bff06a82dab1d9f28eb824e3cd9a..69c1998f3fd5516c89934f190815146e73113070 100644 (file)
@@ -915,7 +915,7 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor,
                continue;
            }
        }
-       if ((!intrchr[INT_RAIL].in_enable || sect.sct_rail == 0)
+       if (!SCT_HAS_RAIL(&sect)
            && lnd_mobtype(&llp->unit.land) == MOB_RAIL) {
            if (together) {
                pr("no rail system in %s\n", xyas(newx, newy, actor));
index fd29c8eb598e9c0c471a10de6b339904534d1f8d..20a5726dba4fb0d1e46ac44a41cf61497e11d4c6 100644 (file)
@@ -265,7 +265,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),
-       roundintby((int)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),