New option RAILWAYS

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().
This commit is contained in:
Markus Armbruster 2008-10-26 13:24:41 -04:00
parent cacc393c53
commit b27298d4c5
13 changed files with 93 additions and 7 deletions

View 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,

View 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

View 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

27
info/Railroad.t Normal file
View file

@ -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"

View 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"

View 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));

View 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),

View file

@ -33,8 +33,10 @@
#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;
}

View 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)
{

View 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;

View 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;

View 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));

View 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),