Compare commits

...
Sign in to create a new pull request.

22 commits

Author SHA1 Message Date
62b93e56e2 Fix test for capability engineer in lnd_hit_mine()
Bogus array index, unpredictable result, can crash the server.  Broken
in commit ef7ea893, v4.3.24.
(cherry picked from commit 7506039f1b)
2010-04-07 23:45:21 +02:00
b62025e82c Fix test for capability sweep in shp_hit_mine()
Bogus array index, unpredictable result, can crash the server.  Broken
in commit ef7ea893, v4.3.24.
(cherry picked from commit 054eba7a1d)
2010-03-21 09:34:42 +01:00
e0b21266ce Fix interdiction not to wipe out target ship updates
Ships can expend shells to defend against missiles, in
shp_missile_defense().  Any shell use by the target ship got wiped out
when shp_missile_interdiction() wrote back the target ship, triggering
a seqno mismatch oops.

Ships get updated when they launch planes to intercept interdicting
planes, in mission_pln_equip().  Any petrol use by the target ship got
wiped out when shp_mission_interdiction() wrote back the target ship,
triggering a seqno mismatch oops.

Fix by re-reading the target ship in shp_damage_one().  This also
affects shp_fort_interdiction(), where it is not necessary.  A bit
inefficient, but let's keep this fix simple.
(cherry picked from commit 1d4fea32b8)
2010-03-21 09:34:35 +01:00
03a9ab2cf6 Fix navigate and march not to lay mines free of charge
do_unit_move() reads the ships into a list.  It re-reads them when it
prompts for sub-commands.  shp_nav_one_sector() writes them back when
it moves ships.

Mine-laying (sub-command 'd') updates the minelayer, invalidating the
copy in the list.  Any movement sub-command before the next prompt for
sub-commands wiped out this update, triggering a seno mismatch oops.

Happens only if 'd' is used without arguments, because remaining
sub-commands are discarded when there are arguments.

Broken when mine-laying was added in commits 2438fe7c, v4.3.7.

Same for march, commit 274c8e42, v4.3.7.

Fix by stopping after 'd' regardless of arguments.
(cherry picked from commit 28cc236e12)
2010-03-21 09:34:29 +01:00
8999261119 Fix navigate and march not to prompt for number of mines to lay
When sub-command 'd' was used without arguments, do_unit_move() failed
to supply the second argument to mine(), which duly prompted for it.
This contracticted info, and could trigger a generation oops.

do_unit_move() reads the ships into a list.  It re-reads them when it
prompts for sub-commands.  shp_nav_one_sector() writes them back when
it moves ships.

The mine prompt made the list stale.  Movement sub-commands before the
next prompt for sub-commands wrote back stale ships, triggering a
generation oops.  Example: "nav 15 dg".

Broken when mine-laying was added in commits 2438fe7c, v4.3.7.

Same for march, commit 274c8e42, v4.3.7.
(cherry picked from commit 45106ab91f)
2010-03-21 09:34:23 +01:00
7f3f9c6726 Nuclear-tipped missile exploding on launch could not damage base
Commit a269cdd7 (v4.3.23) removed the nuclear damage.  But it left the
nuke on the missile, which made pln_damage() oops and return zero
damage.

Fix by destroying the nuke separately.
(cherry picked from commit 876f3424b0)
2010-03-21 09:34:09 +01:00
b14edd0f7c Fix news for torpedo attack's return torpedo
When a torpedo attack triggered a return torpedo, the news reported it
to be fired by the attacker instead of the defender.
(cherry picked from commit bb5abd95e0)
2010-03-21 09:33:54 +01:00
bd07ee186b Interdiction attacked submarines with surface-only weapons
shp_mission_interdiction() used MI_INTERDICT instead of MI_SINTERDICT.
Broken in commit cd8fe31e, v4.3.24.
(cherry picked from commit 2dd97dbd00)
2010-03-10 09:44:31 +01:00
1f2865387a Fix unsafe use of shared buffers in commands drawing maps
Maps are generally drawn into static scratch buffers.  Each command
has its own buffers.

Static scratch buffers are safe as long as they're never used across
yields.  Player output can yield unless the command has flag C_MOD
set.  Commands lradar, path, radar, route, satellite, sect, survey
hadn't.  If such a command yields while using scratch buffers, another
instance of the command can clobber them.

Abuse seems tricky, but possible: if a malicious player stalls output
just right, a command yields while printing a map from the scratch
buffer.  It resumes only when the malicious player reads some output.
If another player runs the same command before that, it overwrites the
same static scratch buffer with its map.  The malicious player
receives the last such run's map.

4.2.8 fixed the same bug for bmap, lbmap, lmap, map, nmap, pbmap,
pmap, sbmap and smap.

All were broken in 4.2.0.  Except radar maps (lradar and radar) were
already broken in Empire 2 for AIX.
(cherry picked from commit 8bdb5c5c1b)
2010-03-10 09:44:27 +01:00
069fb10409 Generation numbers didn't catch all potential yields on output
io_output_if_queue_long() called ef_make_stale() only for long queues.
Missed in commit 2fa5f652, v4.3.24.
(cherry picked from commit a38c47a22c)
2010-03-10 09:44:22 +01:00
065881143e Change fairland not to reject small worlds without trying
Instead, print a warning and try.  It may well work, and when it
doesn't, it fails cleanly.
(cherry picked from commit de81e4e20a)
2010-02-06 21:38:04 +01:00
aab337d2e3 Document fortress maintenance cost in info Hvy-Plastic 2010-01-26 22:49:51 +01:00
1227140c67 Update game name and URL for Hvy Plastic 2 in info Hvy-Plastic 2010-01-26 22:49:51 +01:00
48b72af69a Document server time in info Hvy-Plastic 2010-01-26 22:49:51 +01:00
3def3727f8 New info Hvy-Plastic 2010-01-26 22:49:51 +01:00
29d2f5ccfe Change fairland island size probability distribution
Island size is randomly chosen from the interval [1..2*is+1], with
expected value is.  Use two dice to roll the size instead of one.
This makes extreme sizes much less likely.
2010-01-26 22:49:51 +01:00
880f3856d1 Make fairland record the island number in the deity territory
Can be useful for deities when further customizing their game setup.
2010-01-26 22:49:51 +01:00
d1bde67589 Fix recipient thread in output journal
Output journaling was cherry-picked from Hvy Metal II.  However, how
threads are identified in the journal changed since then.
journal_output_1() needs updating for that.
2010-01-26 22:49:51 +01:00
1cd3179b82 Fix journalling of output ids 2010-01-26 22:49:40 +01:00
6be2e3f8c5 Journal output lines instead of chunks
Output often arrives in chunks other than lines.  Hard to read in the
journal.  Delay journalling until we got a full line or our buffer is
exhausted.  This is less precise, but it'll do for now.
2010-01-26 22:44:20 +01:00
221471af6f New journal event output
To enable, set econfig key keep_journal to at least 2.  Output events
are *not* flushed to disk immediately.

Put it in Hvy Metal II now to gather real data for future testing of a
journal replay tool.
2010-01-26 22:44:20 +01:00
83fcc79bca New journal event command
Redundant information, but makes the journal easier to read.  The
redundancy might help making a journal replay tool robust.

Put it in Hvy Metal II now to gather some real data.
2010-01-26 22:44:20 +01:00
14 changed files with 148 additions and 20 deletions

View file

@ -34,13 +34,17 @@
#ifndef JOURNAL_H #ifndef JOURNAL_H
#define JOURNAL_H #define JOURNAL_H
struct player; /* FIXME temporary hack */
int journal_startup(void); int journal_startup(void);
void journal_shutdown(void); void journal_shutdown(void);
int journal_reopen(void); int journal_reopen(void);
void journal_login(void); void journal_login(void);
void journal_logout(void); void journal_logout(void);
void journal_prng(unsigned); void journal_prng(unsigned);
void journal_output(struct player *, int, char *);
void journal_input(char *); void journal_input(char *);
void journal_command(char *);
void journal_update(int); void journal_update(int);
#endif #endif

54
info/Hvy-Plastic.t Normal file
View file

@ -0,0 +1,54 @@
.TH Concept "Hvy-Plastic"
.NA Hvy-Plastic "Special rules for Hvy Plastic 2"
.LV Basic
.s1
Ship types are customized. Better check show for the details.
.s1
Dreadnoughts are more heavily armored. Frigates are more fragile.
.s1
More ships can carry choppers. Some ships are not ideal for this, and
this is reflected by the lack of large petrol and shell storage.
.s1
Land unit types are heavily customized. Better check show for the
details. Non-mechanized units are slower and more vulnerable,
artillery firing ranges differ, few units are light (but troop
transports and landing ships can carry non-light units).
.s1
Planes are tweaked somewhat. show is your friend.
.s1
Nukes are on sale, but nuclear plants are not. Did I mention the show
command?
.s1
Infrastructure is disabled.
.s1
Fortresses cost maintenance, like capitals.
.s1
Your refineries make less petrol from each barrel of oil than usual.
.s1
Natural resources gold, oil and uran deplete much slower than usual.
A 100% gold resource contains 2500d, a 100% oil resource contains
2500o, and a 100% uranium resource contains 500u. Fully depleting a
sector will take you several updates, and a small fraction of the
resource contents will be lost.
.s1
Gold in mountains does not deplete at all.
.s1
Oil production does not depend on tech; you don't have to micro-manage
to conserve oil.
.s1
Server time is in UTC, which means there will be no daylight savings
time.
.s1
Missed updates due to server problems will be forced if caught within
15 minutes of planned update time or skipped otherwise.
.s1
Everything you do in this game is logged by the deities for their own
nefarious purposes. However, the logs are treated confidentially.
.s1
Make the deity laugh and get up to 5 gold bars.
.s1
Source code and configuration is available from
.br
http://www.pond.sub.org/~armbru/empire/hvy-plastic-2/
.s1
.SA "Introduction, Server, show"

View file

@ -244,8 +244,8 @@ do_unit_move(struct emp_qelem *ulist, int *together,
skip = 1; skip = 1;
continue; continue;
case 'd': case 'd':
if (ac == 2) { if (ac < 3) {
player->argp[2] = player->argp[1]; player->argp[2] = ac < 2 ? "1" : player->argp[1];
sprintf(dp, "%d", leader->uid); sprintf(dp, "%d", leader->uid);
player->argp[1] = dp; player->argp[1] = dp;
} }
@ -253,6 +253,7 @@ do_unit_move(struct emp_qelem *ulist, int *together,
mine(); mine();
else else
landmine(); landmine();
stopping = 1;
skip = 1; skip = 1;
player->btused++; player->btused++;
continue; continue;

View file

@ -319,7 +319,7 @@ fire_torp(struct shpstr *sp, struct shpstr *targ, int ntargets)
if (mchr[(int)sp->shp_type].m_flags & M_SUB) if (mchr[(int)sp->shp_type].m_flags & M_SUB)
nreport(targ->shp_own, N_TORP_SHIP, 0, 1); nreport(targ->shp_own, N_TORP_SHIP, 0, 1);
else else
nreport(targ->shp_own, N_SHIP_TORP, player->cnum, 1); nreport(targ->shp_own, N_SHIP_TORP, sp->shp_own, 1);
} else { } else {
pr("Missed!\n"); pr("Missed!\n");
if (sp->shp_own != 0) if (sp->shp_own != 0)

View file

@ -250,8 +250,11 @@ io_output_if_queue_long(struct iop *iop, int wait)
if (CANT_HAPPEN(iop->last_out > len)) if (CANT_HAPPEN(iop->last_out > len))
iop->last_out = 0; iop->last_out = 0;
if (len - iop->last_out < iop->bufsize) if (len - iop->last_out < iop->bufsize) {
if (wait)
ef_make_stale();
return 0; return 0;
}
return io_output(iop, wait); return io_output(iop, wait);
} }

View file

@ -38,6 +38,7 @@
#include "com.h" #include "com.h"
#include "empio.h" #include "empio.h"
#include "file.h" #include "file.h"
#include "journal.h"
#include "match.h" #include "match.h"
#include "misc.h" #include "misc.h"
#include "nat.h" #include "nat.h"
@ -94,6 +95,7 @@ dispatch(char *buf, char *redir)
uprnf(buf); uprnf(buf);
pr("\n"); pr("\n");
} }
journal_command(command->c_form);
switch (command->c_addr()) { switch (command->c_addr()) {
case RET_OK: case RET_OK:
player->btused += command->c_cost; player->btused += command->c_cost;

View file

@ -141,7 +141,7 @@ struct cmndstr player_coms[] = {
1, load, C_MOD, NORM + CAP}, 1, load, C_MOD, NORM + CAP},
{"lookout <SHIPS>", 1, look, 0, NORM + CAP}, {"lookout <SHIPS>", 1, look, 0, NORM + CAP},
{"lost", 0, lost, 0, NORM}, {"lost", 0, lost, 0, NORM},
{"lradar <UNITS | SECTS>", 1, lrad, 0, NORM + CAP}, {"lradar <UNITS | SECTS>", 1, lrad, C_MOD, NORM + CAP},
{"lretreat <UNITS|ARMY> <PATH> [i|h|b|c]", {"lretreat <UNITS|ARMY> <PATH> [i|h|b|c]",
1, lretr, C_MOD, NORM + CAP}, 1, lretr, C_MOD, NORM + CAP},
{"lstat <UNITS>", 0, lsta, C_MOD, NORM}, {"lstat <UNITS>", 0, lsta, C_MOD, NORM},
@ -176,7 +176,7 @@ struct cmndstr player_coms[] = {
{"origin <SECT|COUNTRY|~>", 1, orig, C_MOD, NORM}, {"origin <SECT|COUNTRY|~>", 1, orig, C_MOD, NORM},
{"paradrop <cargo-PLANES> <fighter-PLANES> <ap-SECT> <PATH|DESTINATION>", {"paradrop <cargo-PLANES> <fighter-PLANES> <ap-SECT> <PATH|DESTINATION>",
3, para, C_MOD, NORM + MONEY + CAP}, 3, para, C_MOD, NORM + MONEY + CAP},
{"path <SECT>", 0, path, 0, NORM}, {"path <SECT>", 0, path, C_MOD, NORM},
{"payoff <SHIPS>", 0, payo, C_MOD, NORM}, {"payoff <SHIPS>", 0, payo, C_MOD, NORM},
{"pbmap <SECTS|PLANE> [s|l|n|p|r|t|*|h]", 0, map, C_MOD, NORM}, {"pbmap <SECTS|PLANE> [s|l|n|p|r|t|*|h]", 0, map, C_MOD, NORM},
{"pboard <PLANES>", 3, pboa, C_MOD, NORM + MONEY + CAP}, {"pboard <PLANES>", 3, pboa, C_MOD, NORM + MONEY + CAP},
@ -192,7 +192,7 @@ struct cmndstr player_coms[] = {
{"pstat <PLANES>", 0, pstat, 0, NORM}, {"pstat <PLANES>", 0, pstat, 0, NORM},
{"qorder <SHIPS>", 0, qorde, C_MOD, NORM + CAP}, {"qorder <SHIPS>", 0, qorde, C_MOD, NORM + CAP},
{"quit", 0, quit, 0, VIS}, {"quit", 0, quit, 0, VIS},
{"radar <SHIPS | SECTS>", 1, rada, 0, NORM + CAP}, {"radar <SHIPS | SECTS>", 1, rada, C_MOD, NORM + CAP},
{"range <PLANES> <range>", 1, range, C_MOD, NORM + CAP}, {"range <PLANES> <range>", 1, range, C_MOD, NORM + CAP},
{"read [yes|no|<CNUM/CNAME>]", 0, rea, C_MOD, VIS}, {"read [yes|no|<CNUM/CNAME>]", 0, rea, C_MOD, VIS},
{"realm <number> [<SECTS>]", 0, real, C_MOD, NORM}, {"realm <number> [<SECTS>]", 0, real, C_MOD, NORM},
@ -208,17 +208,17 @@ struct cmndstr player_coms[] = {
{"resource <SECTS>", 0, reso, 0, NORM}, {"resource <SECTS>", 0, reso, 0, NORM},
{"retreat <SHIPS|FLEET> <PATH> [i|t|s|h|b|d|u|c]", {"retreat <SHIPS|FLEET> <PATH> [i|t|s|h|b|d|u|c]",
1, retr, C_MOD, NORM + CAP}, 1, retr, C_MOD, NORM + CAP},
{"route <COMM> <SECTS>", 1, rout, 0, NORM}, {"route <COMM> <SECTS>", 1, rout, C_MOD, NORM},
{"sabotage <UNITS>", 1, sabo, C_MOD, NORM + MONEY + CAP}, {"sabotage <UNITS>", 1, sabo, C_MOD, NORM + MONEY + CAP},
{"sail <SHIPS> <PATH>", 1, sail, C_MOD, NORM + CAP}, {"sail <SHIPS> <PATH>", 1, sail, C_MOD, NORM + CAP},
{"satellite <PLANE> [<se|sh|l> [?cond&cond&...]]", {"satellite <PLANE> [<se|sh|l> [?cond&cond&...]]",
1, sate, 0, NORM + MONEY + CAP}, 1, sate, C_MOD, NORM + MONEY + CAP},
{"sbmap <SECTS|SHIP> [s|l|n|p|r|t|*|h]", 0, map, C_MOD, NORM}, {"sbmap <SECTS|SHIP> [s|l|n|p|r|t|*|h]", 0, map, C_MOD, NORM},
{"scrap <s|p|l> <SHIPS|PLANES|UNITS>", {"scrap <s|p|l> <SHIPS|PLANES|UNITS>",
2, scra, C_MOD, NORM + MONEY + CAP}, 2, scra, C_MOD, NORM + MONEY + CAP},
{"scuttle <s|p|l> <SHIPS|PLANES|UNITS>", 5, scut, C_MOD, NORM + CAP}, {"scuttle <s|p|l> <SHIPS|PLANES|UNITS>", 5, scut, C_MOD, NORM + CAP},
{"sdump <SHIPS> [<fields>]", 0, sdump, 0, NORM}, {"sdump <SHIPS> [<fields>]", 0, sdump, 0, NORM},
{"sect <SECTS>", 0, sct, 0, NORM}, {"sect <SECTS>", 0, sct, C_MOD, NORM},
{"sell <COMM> <SECTS> <NUM> <NUM>", 1, sell, C_MOD, NORM + CAP}, {"sell <COMM> <SECTS> <NUM> <NUM>", 1, sell, C_MOD, NORM + CAP},
{"set <TYPE> <SHIPS|PLANES|UNITS|NUKES> <PRICE>", {"set <TYPE> <SHIPS|PLANES|UNITS|NUKES> <PRICE>",
1, set, C_MOD, NORM + CAP}, 1, set, C_MOD, NORM + CAP},
@ -245,7 +245,7 @@ struct cmndstr player_coms[] = {
{"stop <TYPE> <SECTS|PLANES|SHIPS|UNITS>", 1, stop, C_MOD, NORM + CAP}, {"stop <TYPE> <SECTS|PLANES|SHIPS|UNITS>", 1, stop, C_MOD, NORM + CAP},
{"strength <SECTS>", 1, stre, C_MOD, NORM}, {"strength <SECTS>", 1, stre, C_MOD, NORM},
{"supply <LAND UNITS>", 1, supp, C_MOD, NORM + CAP}, {"supply <LAND UNITS>", 1, supp, C_MOD, NORM + CAP},
{"survey <SELECTOR> <SECTS>", 0, surv, 0, NORM + CAP}, {"survey <SELECTOR> <SECTS>", 0, surv, C_MOD, NORM + CAP},
{"swapsector <SECT> <SECT>", 0, swaps, C_MOD, GOD}, {"swapsector <SECT> <SECT>", 0, swaps, C_MOD, GOD},
{"sweep <sweep-PLANES> <fighter-PLANES> <ap-SECT> <PATH|DESTINATION>", {"sweep <sweep-PLANES> <fighter-PLANES> <ap-SECT> <PATH|DESTINATION>",
3, reco, C_MOD, NORM + MONEY + CAP}, 3, reco, C_MOD, NORM + MONEY + CAP},

View file

@ -44,7 +44,9 @@
* prng NAME SEED * prng NAME SEED
* login CNUM HOSTADDR USER * login CNUM HOSTADDR USER
* logout CNUM * logout CNUM
* command NAME
* input INPUT * input INPUT
* output THREAD ID OUTPUT
* update ETU * update ETU
*/ */
@ -67,6 +69,7 @@ static FILE *journal;
static void journal_entry(char *fmt, ...) static void journal_entry(char *fmt, ...)
ATTRIBUTE((format (printf, 1, 2))); ATTRIBUTE((format (printf, 1, 2)));
static void journal_output_1(struct player *, int, char *, char *, int);
static FILE * static FILE *
journal_open(void) journal_open(void)
@ -98,7 +101,8 @@ journal_entry(char *fmt, ...)
fprintf(journal, "\\%03o", *p); fprintf(journal, "\\%03o", *p);
} }
fputs("\n", journal); fputs("\n", journal);
fflush(journal); if (fmt[0] != 'o') /* FIXME disgusting hack */
fflush(journal);
if (ferror(journal)) { if (ferror(journal)) {
logerror("Error writing journal (%s)", strerror(errno)); logerror("Error writing journal (%s)", strerror(errno));
clearerr(journal); clearerr(journal);
@ -167,12 +171,57 @@ journal_logout(void)
journal_entry("logout %d", player->cnum); journal_entry("logout %d", player->cnum);
} }
void
journal_output(struct player *pl, int id, char *output)
{
static char buf[1024];
static struct player *bpl;
static int bid;
char *s, *e;
if (keep_journal < 2)
return;
if (buf[0] && (pl != bpl && id != bid)) {
journal_output_1(bpl, bid, buf, "", -1);
buf[0] = 0;
}
for (s = output; (e = strchr(s, '\n')); s = e + 1) {
journal_output_1(pl, id, buf, s, (int)(e + 1 - s));
buf[0] = 0;
}
if (strlen(buf) + strlen(s) < 1024) {
strcpy(buf + strlen(buf), s);
bpl = pl;
bid = id;
} else {
journal_output_1(pl, id, buf, s, -1);
buf[0] = 0;
}
}
static void
journal_output_1(struct player *pl, int id,
char *buf1, char *buf2, int buf2prec)
{
journal_entry("output %s %d %s%.*s",
empth_name(empth_self()), id, buf1, buf2prec, buf2);
}
void void
journal_input(char *input) journal_input(char *input)
{ {
journal_entry("input %s", input); journal_entry("input %s", input);
} }
void
journal_command(char *cmd)
{
char *eptr = strchr(cmd, ' ');
journal_entry("command %.*s", eptr ? (int)(eptr - cmd) : -1, cmd);
}
void void
journal_update(int etu) journal_update(int etu)
{ {

View file

@ -862,7 +862,7 @@ lnd_hit_mine(struct lndstr *lp)
nreport(lp->lnd_own, N_LHIT_MINE, 0, 1); nreport(lp->lnd_own, N_LHIT_MINE, 0, 1);
m = MINE_LDAMAGE(); m = MINE_LDAMAGE();
if (lchr[lp->lnd_uid].l_flags & L_ENGINEER) if (lchr[lp->lnd_type].l_flags & L_ENGINEER)
m /= 2; m /= 2;
landdamage(lp, m); landdamage(lp, m);

View file

@ -59,6 +59,7 @@ msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y,
natid victim, int *sublaunchp) natid victim, int *sublaunchp)
{ {
struct shpstr ship; struct shpstr ship;
struct nukstr nuke;
struct sctstr sect; struct sctstr sect;
int sublaunch = 0; int sublaunch = 0;
char *from; char *from;
@ -93,6 +94,11 @@ msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y,
if (chance((0.05 + (100 - pp->pln_effic) / 100.0) if (chance((0.05 + (100 - pp->pln_effic) / 100.0)
* (1 - techfact(pp->pln_tech, 1.0)))) { * (1 - techfact(pp->pln_tech, 1.0)))) {
mpr(pp->pln_own, "KABOOOOM! Missile explodes %s!\n", from); mpr(pp->pln_own, "KABOOOOM! Missile explodes %s!\n", from);
if (getnuke(nuk_on_plane(pp), &nuke)) {
pr("%s lost!\n", prnuke(&nuke));
nuke.nuk_effic = 0;
putnuke(nuke.nuk_uid, &nuke);
}
if (chance(0.33)) { if (chance(0.33)) {
dam = pln_damage(pp, 'p', 1) / 2; dam = pln_damage(pp, 'p', 1) / 2;
if (pp->pln_ship >= 0) { if (pp->pln_ship >= 0) {

View file

@ -988,7 +988,7 @@ pln_damage(struct plnstr *pp, char type, int noisy)
int effective = 1; int effective = 1;
int pinbomber = 0; int pinbomber = 0;
if (CANT_HAPPEN(nuk_on_plane(pp) >= 0)) /* FIXME check uses! */ if (CANT_HAPPEN(nuk_on_plane(pp) >= 0))
return 0; return 0;
load = pln_load(pp); load = pln_load(pp);

View file

@ -56,6 +56,7 @@
#include "com.h" #include "com.h"
#include "empio.h" #include "empio.h"
#include "file.h" #include "file.h"
#include "journal.h"
#include "misc.h" #include "misc.h"
#include "nat.h" #include "nat.h"
#include "player.h" #include "player.h"
@ -124,6 +125,7 @@ pr_id(struct player *p, int id, char *format, ...)
if (p->curid >= 0) { if (p->curid >= 0) {
io_puts(p->iop, "\n"); io_puts(p->iop, "\n");
journal_output(p, p->curid, "\n");
p->curid = -1; p->curid = -1;
} }
va_start(ap, format); va_start(ap, format);
@ -242,6 +244,8 @@ pr_player(struct player *pl, int id, char *buf)
} }
} }
journal_output(pl, id, buf);
if (player == pl) { if (player == pl) {
while (io_output_if_queue_long(pl->iop, while (io_output_if_queue_long(pl->iop,
pl->may_sleep == PLAYER_SLEEP_FREELY) > 0) pl->may_sleep == PLAYER_SLEEP_FREELY) > 0)
@ -298,6 +302,8 @@ upr_player(struct player *pl, int id, char *buf)
} }
} }
journal_output(pl, id, buf);
if (player == pl) { if (player == pl) {
while (io_output_if_queue_long(pl->iop, while (io_output_if_queue_long(pl->iop,
pl->may_sleep == PLAYER_SLEEP_FREELY) > 0) pl->may_sleep == PLAYER_SLEEP_FREELY) > 0)

View file

@ -354,6 +354,8 @@ shp_count(struct emp_qelem *list, int wantflags, int nowantflags,
static void static void
shp_damage_one(struct ulist *mlp, int dam) shp_damage_one(struct ulist *mlp, int dam)
{ {
/* ship might have changed (launched interceptors, missile defense) */
getship(mlp->unit.ship.shp_uid, &mlp->unit.ship);
shipdamage(&mlp->unit.ship, dam); shipdamage(&mlp->unit.ship, dam);
putship(mlp->unit.ship.shp_uid, &mlp->unit.ship); putship(mlp->unit.ship.shp_uid, &mlp->unit.ship);
if (!mlp->unit.ship.shp_own) { if (!mlp->unit.ship.shp_own) {
@ -649,11 +651,12 @@ shp_mission_interdiction(struct emp_qelem *list, coord x, coord y,
char *what = subs ? "subs" : "ships"; char *what = subs ? "subs" : "ships";
int wantflags = subs ? M_SUB : 0; int wantflags = subs ? M_SUB : 0;
int nowantflags = subs ? 0 : M_SUB; int nowantflags = subs ? 0 : M_SUB;
int mission = subs ? MI_SINTERDICT : MI_INTERDICT;
int dam; int dam;
dam = unit_interdict(x, y, victim, what, dam = unit_interdict(x, y, victim, what,
shp_easiest_target(list, wantflags, nowantflags), shp_easiest_target(list, wantflags, nowantflags),
MI_INTERDICT); mission);
if (dam >= 0) if (dam >= 0)
shp_damage(list, dam, wantflags, nowantflags, x, y); shp_damage(list, dam, wantflags, nowantflags, x, y);
return dam >= 0; return dam >= 0;
@ -705,7 +708,7 @@ shp_hit_mine(struct shpstr *sp)
nreport(sp->shp_own, N_HIT_MINE, 0, 1); nreport(sp->shp_own, N_HIT_MINE, 0, 1);
m = MINE_DAMAGE(); m = MINE_DAMAGE();
if (mchr[sp->shp_uid].m_flags & M_SWEEP) if (mchr[sp->shp_type].m_flags & M_SWEEP)
m /= 2.0; m /= 2.0;
shipdamage(sp, ldround(m, 1)); shipdamage(sp, ldround(m, 1));

View file

@ -420,10 +420,9 @@ parse_args(int argc, char *argv[])
exit(1); exit(1);
} }
if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) { if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
puts("fairland: error -- world not big enough to fit continents."); puts("fairland: warning -- world might be too small to fit continents.");
puts("arguments must satisfy:"); puts("arguments should satisfy:");
puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y"); puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
exit(1);
} }
} }
@ -821,7 +820,7 @@ grow_islands(void)
secs = 0; secs = 0;
if (!place_island(c, &x, &y)) if (!place_island(c, &x, &y))
return; return;
isiz = 1 + rnd(2 * is - 1); isiz = 1 + rnd(is) + rnd(is);
do { do {
++secs; ++secs;
find_coast(c); find_coast(c);
@ -1092,6 +1091,7 @@ write_sects(void)
sct->sct_type = SCT_MOUNT; sct->sct_type = SCT_MOUNT;
sct->sct_elev = total; sct->sct_elev = total;
sct->sct_newtype = sct->sct_type; sct->sct_newtype = sct->sct_type;
sct->sct_dterr = own[sct->sct_x][y] + 1;
if (ORE) if (ORE)
add_resources(sct); add_resources(sct);
} }