Sail (Part 2 of 4)
Peter E. Yee
yee at ucbvax.ARPA
Thu Jan 24 14:05:32 AEST 1985
This is part 2 of the SAIL distribution.
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# sail/player.h
# sail/player1.c
# sail/player2.c
# sail/player3.c
# sail/player4.c
# sail/player5.c
# sail/player6.c
# sail/player7.c
# This archive created: Wed Jan 23 19:46:49 1985
cat << \SHAR_EOF > sail/player.h
/*
* sccsid = "@(#)player.h 2.7 2/23/84";
*/
#include <curses.h>
#include "externs.h"
/* sizes and coordinates for the screen */
#define LINE_T 0
#define LINE_L 0
#define LINE_X COLS
#define LINE_Y 1
#define LINE_B (LINE_T+LINE_Y-1)
#define LINE_R (LINE_L+LINE_X-1)
#define BOX_T 1
#define BOX_L 0
#define BOX_X 65
#define BOX_Y 16
#define BOX_B (BOX_T+BOX_Y-1)
#define BOX_R (BOX_L+BOX_X-1)
#define TURN_T BOX_B
#define TURN_Y 1
#define TURN_L ((BOX_L+BOX_R-TURN_X)/2)
#define TURN_X 9
#define TURN_B (TURN_T+TURN_Y+1)
#define TURN_R (TURN_L+TURN_X+1)
#define STAT_T 0
#define STAT_B BOX_B
#define STAT_L (BOX_R+2)
#define STAT_X 14
#define STAT_Y (STAT_B-STAT_T+1)
#define STAT_R (STAT_L+STAT_X-1)
#define STAT_1 0
#define STAT_2 (STAT_1+4)
#define STAT_3 (STAT_2+7)
#define SCROLL_T (BOX_B+1)
#define SCROLL_L 0
#define SCROLL_B (LINES-1)
#define SCROLL_R (COLS-1)
#define SCROLL_X (SCROLL_R-SCROLL_L+1)
#define SCROLL_Y (SCROLL_B-SCROLL_T+1)
#define VIEW_T (BOX_T+1)
#define VIEW_L (BOX_L+1)
#define VIEW_X (BOX_X-5)
#define VIEW_Y (BOX_Y-2)
#define VIEW_B (VIEW_T+VIEW_Y-1)
#define VIEW_R (VIEW_L+VIEW_X-1)
#define SLOT_T VIEW_T
#define SLOT_L (VIEW_R+1)
#define SLOT_X 3
#define SLOT_Y VIEW_Y
#define SLOT_B VIEW_B
#define SLOT_R (SLOT_L+SLOT_X-1)
#ifdef SIGTSTP
#define SCREENTEST() (initscr() != ERR && signal(SIGTSTP, SIG_DFL) != BADSIG && STAT_R < COLS && SCROLL_Y > 0)
#else
#define SCREENTEST() (initscr() != ERR && STAT_R < COLS && SCROLL_Y > 0)
#endif
WINDOW *view_w;
WINDOW *slot_w;
WINDOW *scroll_w;
WINDOW *stat_w;
WINDOW *turn_w;
char done_curses;
char loaded, fired, changed, repaired;
char dont_adjust;
int viewrow, viewcol;
char movebuf[sizeof SHIP(0)->file->movebuf];
char version[];
int player;
struct ship *ms; /* memorial structure, &cc->ship[player] */
struct File *mf; /* ms->file */
struct shipspecs *mc; /* ms->specs */
/* condition codes for leave() */
#define LEAVE_QUIT 0
#define LEAVE_CAPTURED 1
#define LEAVE_HURRICAN 2
#define LEAVE_DRIVER 3
#define LEAVE_FORK 4
#define LEAVE_SYNC 5
SHAR_EOF
if test 2091 -ne "`wc -c sail/player.h`"
then
echo shar: error transmitting sail/player.h '(should have been 2091 characters)'
fi
cat << \SHAR_EOF > sail/player1.c
#ifndef lint
static char *sccsid = "@(#)player1.c 2.8 84/12/12";
#endif
#include "player.h"
#include <sys/types.h>
#include <sys/wait.h>
int choke(), child();
/*ARGSUSED*/
main(argc, argv)
int argc;
char **argv;
{
char nodrive = 0, randomize = 0, debug = 0;
extern char _sobuf[];
setbuf(stdout, _sobuf);
isplayer = 1;
while (*++argv && **argv == '-')
switch (*++*argv) {
case 'd':
nodrive = 1;
break;
case 'D':
debug++;
break;
case 'x':
randomize = 1;
break;
default:
printf("Unknown flag '%s'\n",*argv);
break;
}
if (*argv)
game = atoi(*argv);
else
game = -1;
initialize(nodrive, randomize, debug);
Signal("Aye aye, Sir", (struct ship *)0);
play();
}
initialize(nodriver, randomize, debug)
char randomize, nodriver, debug;
{
register struct File *fp;
register struct ship *sp;
char captain[80];
char message[60];
int load;
register int n;
char *nameptr;
int nat[NNATION];
if (!SCREENTEST()) {
printf("Can't sail on this terminal.\n");
exit(1);
}
(void) srand(getpid());
if (game < 0) {
(void) puts("Choose a scenario:\n");
(void) puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
for (n = 0; n < NSCENE; n++) {
/* ( */
printf("\t%d):\t%d\t%s\t%s\n", n, scene[n].vessels,
sync_exists(n) ? "YES" : "no",
scene[n].name);
}
reprint:
printf("\nScenario number? ");
(void) fflush(stdout);
(void) scanf("%d", &game);
while (getchar() != '\n')
;
}
if (game < 0 || game >= NSCENE) {
(void) puts("Very funny.");
exit(1);
}
cc = &scene[game];
ls = SHIP(cc->vessels);
for (n = 0; n < NNATION; n++)
nat[n] = 0;
foreachship(sp) {
sp->file = (struct File *) calloc(1, sizeof (struct File));
if (sp->file == NULL) {
(void) puts("OUT OF MEMORY");
exit(0);
}
sp->file->index = sp - SHIP(0);
sp->file->stern = nat[sp->nationality]++;
sp->file->dir = sp->shipdir;
sp->file->row = sp->shiprow;
sp->file->col = sp->shipcol;
}
windspeed = cc->windspeed;
winddir = cc->winddir;
(void) signal(SIGHUP, choke);
(void) signal(SIGINT, choke);
hasdriver = sync_exists(game);
if (sync_open() < 0) {
perror("sail: syncfile");
exit(1);
}
if (hasdriver) {
(void) puts("Synchronizing with the other players...");
(void) fflush(stdout);
if (Sync() < 0)
leave(LEAVE_SYNC);
}
for (;;) {
foreachship(sp)
if (sp->file->captain[0] == 0 && !sp->file->struck
&& sp->file->captured == 0)
break;
if (sp >= ls) {
(void) puts("All ships taken in that scenario.");
foreachship(sp)
free((char *)sp->file);
sync_close(0);
people = 0;
goto reprint;
}
if (randomize) {
player = sp - SHIP(0);
} else {
printf("%s\n\n", cc->name);
foreachship(sp)
printf(" %2d: %-10s %-15s (%-2d pts) %s\n",
sp->file->index,
countryname[sp->nationality],
sp->shipname,
sp->specs->pts,
saywhat(sp, 1));
printf("\nWhich ship (0-%d)? ", cc->vessels-1);
(void) fflush(stdout);
if (scanf("%d", &player) != 1 || player < 0
|| player >= cc->vessels) {
while (getchar() != '\n')
;
(void) puts("Say what?");
player = -1;
} else
while (getchar() != '\n')
;
}
if (player < 0)
continue;
if (Sync() < 0)
leave(LEAVE_SYNC);
fp = SHIP(player)->file;
if (fp->captain[0] || fp->struck || fp->captured != 0)
(void) puts("That ship is taken.");
else
break;
}
ms = SHIP(player);
mf = ms->file;
mc = ms->specs;
Write(W_BEGIN, ms, 0, 0, 0, 0, 0);
if (Sync() < 0)
leave(LEAVE_SYNC);
(void) signal(SIGCHLD, child);
if (!hasdriver && !nodriver) {
char num[10];
(void) sprintf(num, "%d", game);
switch (fork()) {
case 0:
execl(DRIVER1, DRIVERNAME, num, 0);
execl(DRIVER2, DRIVERNAME, num, 0);
execl(DRIVER3, DRIVERNAME, num, 0);
perror(DRIVERNAME);
exit(1);
break;
case -1:
perror("fork");
leave(LEAVE_FORK);
break;
default:
hasdriver++;
}
}
printf("Your ship is the %s, a %d gun %s (%s crew).\n",
ms->shipname, mc->guns, classname[mc->class],
qualname[mc->qual]);
if ((nameptr = (char *) getenv("SAILNAME")) && *nameptr)
(void) strncpy(captain, nameptr, sizeof captain);
else {
(void) printf("Your name, Captain? ");
(void) fflush(stdout);
(void) gets(captain);
if (!*captain)
(void) strcpy(captain, "no name");
}
captain[sizeof captain - 1] = '\0';
Write(W_CAPTAIN, ms, 1, (int)captain, 0, 0, 0);
for (n = 0; n < 2; n++) {
char buf[10];
printf("\nInitial broadside %s (grape, chain, round, double): ",
n ? "right" : "left");
(void) fflush(stdout);
(void) scanf("%s", buf);
switch (*buf) {
case 'g':
load = L_GRAPE;
break;
case 'c':
load = L_CHAIN;
break;
case 'r':
load = L_ROUND;
break;
case 'd':
load = L_DOUBLE;
break;
default:
load = L_ROUND;
}
if (n) {
mf->loadR = load;
mf->readyR = R_LOADED|R_INITIAL;
} else {
mf->loadL = load;
mf->readyL = R_LOADED|R_INITIAL;
}
}
initscreen();
draw_board();
(void) sprintf(message, "Captain %s assuming command", captain);
Write(W_SIGNAL, ms, 1, (int)message, 0, 0, 0);
newturn();
}
/*
* If we get here before a ship is chosen, then ms == 0 and
* we don't want to update the score file, or do any Write's either.
* We can assume the sync file is already created and may need
* to be removed.
* Of course, we don't do any more Sync()'s if we got here
* because of a Sync() failure.
*/
leave(conditions)
int conditions;
{
(void) signal(SIGHUP, SIG_IGN);
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
(void) signal(SIGALRM, SIG_IGN);
(void) signal(SIGCHLD, SIG_IGN);
if (done_curses) {
Signal("It looks like you've had it!",
(struct ship *)0);
switch (conditions) {
case LEAVE_QUIT:
break;
case LEAVE_CAPTURED:
Signal("Your ship was captured.",
(struct ship *)0);
break;
case LEAVE_HURRICAN:
Signal("Hurricane! All ships destroyed.",
(struct ship *)0);
break;
case LEAVE_DRIVER:
Signal("The driver died.", (struct ship *)0);
break;
case LEAVE_SYNC:
Signal("Synchronization error.", (struct ship *)0);
break;
default:
Signal("A funny thing happened (%d).",
(struct ship *)0, conditions);
}
} else {
switch (conditions) {
case LEAVE_QUIT:
break;
case LEAVE_DRIVER:
printf("The driver died.\n");
break;
case LEAVE_FORK:
perror("fork");
break;
case LEAVE_SYNC:
printf("Synchronization error\n.");
break;
default:
printf("A funny thing happened (%d).\n",
conditions);
}
}
if (ms != 0) {
log(ms);
if (conditions != LEAVE_SYNC) {
makesignal(ms, "Captain %s relinquishing.",
(struct ship *)0, mf->captain);
Write(W_END, ms, 0, 0, 0, 0, 0);
(void) Sync();
}
}
sync_close(!hasdriver);
cleanupscreen();
exit(0);
}
choke()
{
leave(LEAVE_QUIT);
}
child()
{
union wait status;
int pid;
(void) signal(SIGCHLD, SIG_IGN);
do {
pid = wait3(&status, WNOHANG, (struct rusage *)0);
if (pid < 0 || pid > 0 && !WIFSTOPPED(status))
hasdriver = 0;
} while (pid > 0);
(void) signal(SIGCHLD, child);
}
SHAR_EOF
if test 7085 -ne "`wc -c sail/player1.c`"
then
echo shar: error transmitting sail/player1.c '(should have been 7085 characters)'
fi
cat << \SHAR_EOF > sail/player2.c
#ifndef lint
static char *sccsid = "@(#)player2.c 2.3 83/12/09";
#endif
#include "player.h"
play()
{
register struct ship *sp;
for (;;) {
switch (sgetch("~\b", (struct ship *)0, 0)) {
case 'm':
acceptmove();
break;
case 's':
acceptsignal();
break;
case 'g':
grapungrap();
break;
case 'u':
unfoulplayer();
break;
case 'v':
Signal("%s", (struct ship *)0, version);
break;
case 'b':
acceptboard();
break;
case 'f':
acceptcombat();
break;
case 'l':
loadplayer();
break;
case 'c':
changesail();
break;
case 'r':
repair();
break;
case 'B':
Signal("'Hands to stations!'", (struct ship *)0);
unboard(ms, ms, 1); /* cancel DBP's */
unboard(ms, ms, 0); /* cancel offense */
break;
case '\f':
centerview();
blockalarm();
draw_board();
draw_screen();
unblockalarm();
break;
case 'L':
mf->loadL = L_EMPTY;
mf->loadR = L_EMPTY;
mf->readyL = R_EMPTY;
mf->readyR = R_EMPTY;
Signal("Broadsides unloaded", (struct ship *)0);
break;
case 'q':
Signal("Type 'Q' to quit", (struct ship *)0);
break;
case 'Q':
leave(LEAVE_QUIT);
break;
case 'I':
foreachship(sp)
if (sp != ms)
eyeball(sp);
break;
case 'i':
if ((sp = closestenemy(ms, 0, 1)) == 0)
Signal("No more ships left.");
else
eyeball(sp);
break;
case 'C':
centerview();
blockalarm();
draw_view();
unblockalarm();
break;
case 'U':
upview();
blockalarm();
draw_view();
unblockalarm();
break;
case 'D':
case 'N':
downview();
blockalarm();
draw_view();
unblockalarm();
break;
case 'H':
leftview();
blockalarm();
draw_view();
unblockalarm();
break;
case 'J':
rightview();
blockalarm();
draw_view();
unblockalarm();
break;
case 'F':
lookout();
break;
case 'S':
dont_adjust = !dont_adjust;
blockalarm();
draw_turn();
unblockalarm();
break;
}
}
}
SHAR_EOF
if test 1980 -ne "`wc -c sail/player2.c`"
then
echo shar: error transmitting sail/player2.c '(should have been 1980 characters)'
fi
cat << \SHAR_EOF > sail/player3.c
#ifndef lint
static char *sccsid = "@(#)player3.c 2.3 83/12/17";
#endif
#include "player.h"
acceptcombat()
{
int men = 0;
int target, temp;
int n, r;
int index, rakehim, sternrake;
int hhits = 0, ghits = 0, rhits = 0, chits = 0;
int crew[3];
int load;
int guns, car, ready, shootat, hit;
int roll;
struct ship *closest;
crew[0] = mc->crew1;
crew[1] = mc->crew2;
crew[2] = mc->crew3;
for (n = 0; n < 3; n++) {
if (mf->OBP[n].turnsent)
men += mf->OBP[n].mensent;
}
for (n = 0; n < 3; n++) {
if (mf->DBP[n].turnsent)
men += mf->DBP[n].mensent;
}
if (men) {
crew[0] = men/100 ? 0 : crew[0] != 0;
crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
crew[2] = men%10 ? 0 : crew[2] != 0;
}
for (r = 0; r < 2; r++) {
if (r) {
ready = mf->readyR;
load = mf->loadR;
guns = mc->gunR;
car = mc->carR;
} else {
ready = mf->readyL;
load = mf->loadL;
guns = mc->gunL;
car = mc->carL;
}
if (!guns && !car || load == L_EMPTY || (ready & R_LOADED) == 0)
goto cant;
if (mf->struck || !crew[2])
goto cant;
closest = closestenemy(ms, (r ? 'r' : 'l'), 1);
if (closest == 0)
goto cant;
if (closest->file->struck)
goto cant;
target = range(ms, closest);
if (target > rangeofshot[load] || !guns && target >= 3)
goto cant;
Signal("%s (%c%c) within range of %s broadside.",
closest, r ? "right" : "left");
if (load > L_CHAIN && target < 6) {
switch (sgetch("Aim for hull or rigging? ",
(struct ship *)0, 1)) {
case 'r':
shootat = RIGGING;
break;
case 'h':
shootat = HULL;
break;
default:
shootat = -1;
Signal("'Avast there! Hold your fire.'",
(struct ship *)0);
}
} else {
if (sgetch("Fire? ", (struct ship *)0, 1) == 'n') {
shootat = -1;
Signal("Belay that! Hold your fire.",
(struct ship *)0);
} else
shootat = RIGGING;
}
if (shootat == -1)
continue;
fired = 1;
rakehim = gunsbear(ms, closest) && !gunsbear(closest, ms);
temp = portside(closest, ms, 1) - closest->file->dir + 1;
if (temp < 1)
temp += 8;
else if (temp > 8)
temp -= 8;
sternrake = temp > 4 && temp < 6;
if (rakehim)
if (!sternrake)
Signal("Raking the %s!", closest);
else
Signal("Stern Rake! %s splintering!", closest);
index = guns;
if (target < 3)
index += car;
index = (index - 1)/3;
index = index > 8 ? 8 : index;
if (!rakehim)
hit = HDT[index][target-1];
else
hit = HDTrake[index][target-1];
if (rakehim && sternrake)
hit++;
hit += QUAL[index][mc->qual-1];
for (n = 0; n < 3 && mf->captured == 0; n++)
if (!crew[n])
if (index <= 5)
hit--;
else
hit -= 2;
if (ready & R_INITIAL)
if (index <= 3)
hit++;
else
hit += 2;
if (mf->captured != 0)
if (index <= 1)
hit--;
else
hit -= 2;
hit += AMMO[index][load - 1];
if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5)
hit--;
if (windspeed == 6 && temp == 4)
hit -= 2;
if (windspeed == 6 && temp <= 3)
hit--;
if (hit >= 0) {
roll = die();
if (load == L_GRAPE)
chits = hit;
else {
struct Tables *t;
if (hit > 10)
hit = 10;
t = &(shootat == RIGGING ? RigTable : HullTable)
[hit][roll-1];
chits = t->C;
rhits = t->R;
hhits = t->H;
ghits = t->G;
if (closest->file->FS)
rhits *= 2;
if (load == L_CHAIN) {
ghits = 0;
hhits = 0;
}
}
table(shootat, load, hit, closest, ms, roll);
}
Signal("Damage inflicted on the %s:",
(struct ship *)0, closest->shipname);
Signal("\t%d HULL, %d GUNS, %d CREW, %d RIGGING",
(struct ship *)0, hhits, ghits, chits, rhits);
if (!r) {
mf->loadL = L_EMPTY;
mf->readyL = R_EMPTY;
} else {
mf->loadR = L_EMPTY;
mf->readyR = R_EMPTY;
}
continue;
cant:
Signal("Unable to fire %s broadside",
(struct ship *)0, r ? "right" : "left");
}
blockalarm();
draw_stat();
unblockalarm();
}
grapungrap()
{
register struct ship *sp;
register int i;
foreachship(sp) {
if (sp == ms || sp->file->dir == 0)
continue;
if (range(ms, sp) > 1 && !grappled2(ms, sp))
continue;
switch (sgetch("Attempt to grapple or ungrapple %s (%c%c): ",
sp, 1)) {
case 'g':
if (die() < 3
|| ms->nationality == capship(sp)->nationality) {
Write(W_GRAP, ms, 0, sp->file->index, 0, 0, 0);
Write(W_GRAP, sp, 0, player, 0, 0, 0);
Signal("Attempt succeeds!", (struct ship *)0);
makesignal(ms, "grappled with %s (%c%c)", sp);
} else
Signal("Attempt fails.", (struct ship *)0);
break;
case 'u':
for (i = grappled2(ms, sp); --i >= 0;) {
if (ms->nationality
== capship(sp)->nationality
|| die() < 3) {
cleangrapple(ms, sp, 0);
Signal("Attempt succeeds!",
(struct ship *)0);
makesignal(ms,
"ungrappling with %s (%c%c)",
sp);
} else
Signal("Attempt fails.",
(struct ship *)0);
}
break;
}
}
}
unfoulplayer()
{
register struct ship *to;
register i;
foreachship(to) {
if (fouled2(ms, to) == 0)
continue;
if (sgetch("Attempt to unfoul with the %s (%c%c)? ", to, 1) != 'y')
continue;
for (i = fouled2(ms, to); --i >= 0;) {
if (die() <= 2) {
cleanfoul(ms, to, 0);
Signal("Attempt succeeds!", (struct ship *)0);
makesignal(ms, "Unfouling %s (%c%c)", to);
} else
Signal("Attempt fails.", (struct ship *)0);
}
}
}
SHAR_EOF
if test 5384 -ne "`wc -c sail/player3.c`"
then
echo shar: error transmitting sail/player3.c '(should have been 5384 characters)'
fi
cat << \SHAR_EOF > sail/player4.c
#ifndef lint
static char *sccsid = "@(#)player4.c 2.3 84/12/12";
#endif
#include "player.h"
changesail()
{
int rig, full;
rig = mc->rig1;
full = mf->FS;
if (windspeed == 6 || windspeed == 5 && mc->class > 4)
rig = 0;
if (mc->crew3 && rig) {
if (!full) {
if (sgetch("Increase to Full sails? ",
(struct ship *)0, 1) == 'y') {
changed = 1;
Write(W_FS, ms, 0, 1, 0, 0, 0);
}
} else {
if (sgetch("Reduce to Battle sails? ",
(struct ship *)0, 1) == 'y') {
Write(W_FS, ms, 0, 0, 0, 0, 0);
changed = 1;
}
}
} else if (!rig)
Signal("Sails rent to pieces", (struct ship *)0);
}
acceptsignal()
{
char buf[60];
register char *p = buf;
*p++ = '"';
sgetstr("Message? ", p, sizeof buf - 2);
while (*p++)
;
p[-1] = '"';
*p = 0;
Write(W_SIGNAL, ms, 1, (int)buf, 0, 0, 0);
}
lookout()
{
register struct ship *sp;
char buf[3];
register char c;
sgetstr("What ship? ", buf, sizeof buf);
foreachship(sp) {
c = *countryname[sp->nationality];
if ((c == *buf || tolower(c) == *buf || colours(sp) == *buf)
&& (sp->file->stern == buf[1] || sterncolour(sp) == buf[1]
|| buf[1] == '?')) {
eyeball(sp);
}
}
}
char *
saywhat(sp, flag)
register struct ship *sp;
char flag;
{
if (sp->file->captain[0])
return sp->file->captain;
else if (sp->file->struck)
return "(struck)";
else if (sp->file->captured != 0)
return "(captured)";
else if (flag)
return "(available)";
else
return "(computer)";
}
eyeball(ship)
register struct ship *ship;
{
int i;
if (ship->file->dir != 0) {
Signal("Sail ho! (range %d, %s)",
(struct ship *)0, range(ms, ship), saywhat(ship, 0));
i = portside(ms, ship, 1) - mf->dir;
if (i <= 0)
i += 8;
Signal("%s (%c%c) %s %s %s.",
ship, countryname[ship->nationality],
classname[ship->specs->class], directionname[i]);
}
}
SHAR_EOF
if test 1841 -ne "`wc -c sail/player4.c`"
then
echo shar: error transmitting sail/player4.c '(should have been 1841 characters)'
fi
cat << \SHAR_EOF > sail/player5.c
#ifndef lint
static char *sccsid = "@(#)player5.c 2.5 83/12/21";
#endif
#include "player.h"
#define turnfirst(x) (*x == 'r' || *x == 'l')
acceptmove()
{
int ta;
int ma;
char af;
int moved = 0;
int vma, dir;
char prompt[60];
char buf[60], last = '\0';
register char *p;
if (!mc->crew3 || snagged(ms) || !windspeed) {
Signal("Unable to move", (struct ship *)0);
return;
}
ta = maxturns(ms, &af);
ma = maxmove(ms, mf->dir, 0);
(void) sprintf(prompt, "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta);
sgetstr(prompt, buf, sizeof buf);
dir = mf->dir;
vma = ma;
for (p = buf; *p; p++)
switch (*p) {
case 'l':
dir -= 2;
case 'r':
if (++dir == 0)
dir = 8;
else if (dir == 9)
dir = 1;
if (last == 't') {
Signal("Ship can't turn that fast.",
(struct ship *)0);
*p-- = '\0';
}
last = 't';
ma--;
ta--;
vma = min(ma, maxmove(ms, dir, 0));
if (ta < 0 && moved || vma < 0 && moved)
*p-- = '\0';
break;
case 'b':
ma--;
vma--;
last = 'b';
if (ta < 0 && moved || vma < 0 && moved)
*p-- = '\0';
break;
case '0':
case 'd':
*p-- = '\0';
break;
case '\n':
*p-- = '\0';
break;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
if (last == '0') {
Signal("Can't move that fast.",
(struct ship *)0);
*p-- = '\0';
}
last = '0';
moved = 1;
ma -= *p - '0';
vma -= *p - '0';
if (ta < 0 && moved || vma < 0 && moved)
*p-- = '\0';
break;
default:
if (!isspace(*p)) {
Signal("Input error.", (struct ship *)0);
*p-- = '\0';
}
}
if (ta < 0 && moved || vma < 0 && moved
|| af && turnfirst(buf) && moved) {
Signal("Movement error.", (struct ship *)0);
if (ta < 0 && moved) {
if (mf->FS == 1) {
Write(W_FS, ms, 0, 0, 0, 0, 0);
Signal("No hands to set full sails.",
(struct ship *)0);
}
} else if (ma >= 0)
buf[1] = '\0';
}
if (af && !moved) {
if (mf->FS == 1) {
Write(W_FS, ms, 0, 0, 0, 0, 0);
Signal("No hands to set full sails.",
(struct ship *)0);
}
}
if (*buf)
(void) strcpy(movebuf, buf);
else
(void) strcpy(movebuf, "d");
Write(W_MOVE, ms, 1, (int)movebuf, 0, 0, 0);
Signal("Helm: %s.", (struct ship *)0, movebuf);
}
acceptboard()
{
register struct ship *sp;
register int n;
int crew[3];
int men = 0;
char c;
crew[0] = mc->crew1;
crew[1] = mc->crew2;
crew[2] = mc->crew3;
for (n = 0; n < NBP; n++) {
if (mf->OBP[n].turnsent)
men += mf->OBP[n].mensent;
}
for (n = 0; n < NBP; n++) {
if (mf->DBP[n].turnsent)
men += mf->DBP[n].mensent;
}
if (men) {
crew[0] = men/100 ? 0 : crew[0] != 0;
crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
crew[2] = men%10 ? 0 : crew[2] != 0;
} else {
crew[0] = crew[0] != 0;
crew[1] = crew[1] != 0;
crew[2] = crew[2] != 0;
}
foreachship(sp) {
if (sp == ms || sp->file->dir == 0 || range(ms, sp) > 1)
continue;
if (ms->nationality == capship(sp)->nationality)
continue;
if (meleeing(ms, sp) && crew[2]) {
c = sgetch("How many more to board the %s (%c%c)? ",
sp, 1);
parties(crew, sp, 0, c);
} else if ((fouled2(ms, sp) || grappled2(ms, sp)) && crew[2]) {
c = sgetch("Crew sections to board the %s (%c%c) (3 max) ?", sp, 1);
parties(crew, sp, 0, c);
}
}
if (crew[2]) {
c = sgetch("How many sections to repel boarders? ",
(struct ship *)0, 1);
parties(crew, ms, 1, c);
}
blockalarm();
draw_slot();
unblockalarm();
}
parties(crew, to, isdefense, buf)
register struct ship *to;
int crew[3];
char isdefense;
char buf;
{
register int k, j, men;
struct BP *ptr;
int temp[3];
for (k = 0; k < 3; k++)
temp[k] = crew[k];
if (isdigit(buf)) {
ptr = isdefense ? to->file->DBP : to->file->OBP;
for (j = 0; j < NBP && ptr[j].turnsent; j++)
;
if (!ptr[j].turnsent && buf > '0') {
men = 0;
for (k = 0; k < 3 && buf > '0'; k++) {
men += crew[k]
* (k == 0 ? 100 : (k == 1 ? 10 : 1));
crew[k] = 0;
if (men)
buf--;
}
if (buf > '0')
Signal("Sending all crew sections.",
(struct ship *)0);
Write(isdefense ? W_DBP : W_OBP, ms, 0,
j, turn, to->file->index, men);
if (isdefense) {
(void) wmove(slot_w, 2, 0);
for (k=0; k < NBP; k++)
if (temp[k] && !crew[k])
(void) waddch(slot_w, k + '1');
else
(void) wmove(slot_w, 2, 1 + k);
(void) mvwaddstr(slot_w, 3, 0, "DBP");
makesignal(ms, "repelling boarders",
(struct ship *)0);
} else {
(void) wmove(slot_w, 0, 0);
for (k=0; k < NBP; k++)
if (temp[k] && !crew[k])
(void) waddch(slot_w, k + '1');
else
(void) wmove(slot_w, 0, 1 + k);
(void) mvwaddstr(slot_w, 1, 0, "OBP");
makesignal(ms, "boarding the %s (%c%c)", to);
}
blockalarm();
(void) wrefresh(slot_w);
unblockalarm();
} else
Signal("Sending no crew sections.", (struct ship *)0);
}
}
SHAR_EOF
if test 4885 -ne "`wc -c sail/player5.c`"
then
echo shar: error transmitting sail/player5.c '(should have been 4885 characters)'
fi
cat << \SHAR_EOF > sail/player6.c
#ifndef lint
static char *sccsid = "@(#)player6.c 2.3 84/02/23";
#endif
#include "player.h"
repair()
{
char c;
register char *repairs;
register struct shipspecs *ptr = mc;
register int count;
#define FIX(x, m) (m - ptr->x > count \
? (ptr->x += count, count = 0) : (count -= m - ptr->x, ptr->x = m))
if (repaired || loaded || fired || changed || turned()) {
Signal("No hands free to repair", (struct ship *)0);
return;
}
c = sgetch("Repair (hull, guns, rigging)? ", (struct ship *)0, 1);
switch (c) {
case 'h':
repairs = &mf->RH;
break;
case 'g':
repairs = &mf->RG;
break;
case 'r':
repairs = &mf->RR;
break;
default:
Signal("Avast heaving!", (struct ship *)0);
return;
}
if (++*repairs >= 3) {
count = 2;
switch (c) {
case 'h': {
int max = ptr->guns/4;
if (ptr->hull < max) {
FIX(hull, max);
Write(W_HULL, ms, 0, ptr->hull, 0, 0, 0);
}
break;
}
case 'g':
if (ptr->gunL < ptr->gunR) {
int max = ptr->guns/5 - ptr->carL;
if (ptr->gunL < max) {
FIX(gunL, max);
Write(W_GUNL, ms, 0, ptr->gunL,
ptr->carL, 0, 0);
}
} else {
int max = ptr->guns/5 - ptr->carR;
if (ptr->gunR < max) {
FIX(gunR, max);
Write(W_GUNR, ms, 0, ptr->gunR,
ptr->carR, 0, 0);
}
}
break;
case 'r':
#define X 2
if (ptr->rig4 >= 0 && ptr->rig4 < X) {
FIX(rig4, X);
Write(W_RIG4, ms, 0, ptr->rig4, 0, 0, 0);
}
if (count && ptr->rig3 < X) {
FIX(rig3, X);
Write(W_RIG3, ms, 0, ptr->rig3, 0, 0, 0);
}
if (count && ptr->rig2 < X) {
FIX(rig2, X);
Write(W_RIG2, ms, 0, ptr->rig2, 0, 0, 0);
}
if (count && ptr->rig1 < X) {
FIX(rig1, X);
Write(W_RIG1, ms, 0, ptr->rig1, 0, 0, 0);
}
break;
}
if (count == 2) {
Signal("Repairs completed.", (struct ship *)0);
*repairs = 2;
} else {
*repairs = 0;
blockalarm();
draw_stat();
unblockalarm();
}
}
blockalarm();
draw_slot();
unblockalarm();
repaired = 1;
}
turned()
{
register char *p;
for (p = movebuf; *p; p++)
if (*p == 'r' || *p == 'l')
return 1;
return 0;
}
loadplayer()
{
char c;
register loadL, loadR, ready, load;
if (!mc->crew3) {
Signal("Out of crew", (struct ship *)0);
return;
}
loadL = mf->loadL;
loadR = mf->loadR;
if (!loadL && !loadR) {
c = sgetch("Load which broadside (left or right)? ",
(struct ship *)0, 1);
if (c == 'r')
loadL = 1;
else
loadR = 1;
}
if (!loadL && loadR || loadL && !loadR) {
c = sgetch("Reload with (round, double, chain, grape)? ",
(struct ship *)0, 1);
switch (c) {
case 'r':
load = L_ROUND;
ready = 0;
break;
case 'd':
load = L_DOUBLE;
ready = R_DOUBLE;
break;
case 'c':
load = L_CHAIN;
ready = 0;
break;
case 'g':
load = L_GRAPE;
ready = 0;
break;
default:
Signal("Broadside not loaded.",
(struct ship *)0);
return;
}
if (!loadR) {
mf->loadR = load;
mf->readyR = ready|R_LOADING;
} else {
mf->loadL = load;
mf->readyL = ready|R_LOADING;
}
loaded = 1;
}
}
SHAR_EOF
if test 3064 -ne "`wc -c sail/player6.c`"
then
echo shar: error transmitting sail/player6.c '(should have been 3064 characters)'
fi
cat << \SHAR_EOF > sail/player7.c
#ifndef lint
static char *sccsid = "@(#)player7.c 2.8 84/02/23";
#endif
#include "player.h"
/*
* Display interface
*/
static char sc_hasprompt;
static char *sc_prompt;
static char *sc_buf;
static int sc_line;
initscreen()
{
/* initscr() already done in SCREENTEST() */
view_w = newwin(VIEW_Y, VIEW_X, VIEW_T, VIEW_L);
slot_w = newwin(SLOT_Y, SLOT_X, SLOT_T, SLOT_L);
scroll_w = newwin(SCROLL_Y, SCROLL_X, SCROLL_T, SCROLL_L);
stat_w = newwin(STAT_Y, STAT_X, STAT_T, STAT_L);
turn_w = newwin(TURN_Y, TURN_X, TURN_T, TURN_L);
done_curses++;
(void) leaveok(view_w, 1);
(void) leaveok(slot_w, 1);
(void) leaveok(stat_w, 1);
(void) leaveok(turn_w, 1);
#ifdef SIGTSTP
{
int susp();
(void) signal(SIGTSTP, susp);
}
#endif
noecho();
crmode();
}
cleanupscreen()
{
/* alarm already turned off */
if (done_curses) {
(void) wmove(scroll_w, SCROLL_Y - 1, 0);
(void) wclrtoeol(scroll_w);
draw_screen();
endwin();
}
}
newturn()
{
repaired = loaded = fired = changed = 0;
movebuf[0] = '\0';
(void) alarm(0);
if (mf->readyL & R_LOADING)
if (mf->readyL & R_DOUBLE)
mf->readyL = R_LOADING;
else
mf->readyL = R_LOADED;
if (mf->readyR & R_LOADING)
if (mf->readyR & R_DOUBLE)
mf->readyR = R_LOADING;
else
mf->readyR = R_LOADED;
if (!hasdriver)
Write(W_DDEAD, SHIP(0), 0, 0, 0, 0, 0);
if (sc_hasprompt) {
(void) wmove(scroll_w, sc_line, 0);
(void) wclrtoeol(scroll_w);
}
if (Sync() < 0)
leave(LEAVE_SYNC);
if (!hasdriver)
leave(LEAVE_DRIVER);
if (sc_hasprompt)
(void) wprintw(scroll_w, "%s%s", sc_prompt, sc_buf);
if (turn % 50 == 0)
Write(W_ALIVE, SHIP(0), 0, 0, 0, 0, 0);
if (mf->FS && (!mc->rig1 || windspeed == 6))
Write(W_FS, ms, 0, 0, 0, 0, 0);
if (mf->FS == 1)
Write(W_FS, ms, 0, 2, 0, 0, 0);
if (mf->struck)
leave(LEAVE_QUIT);
if (mf->captured != 0)
leave(LEAVE_CAPTURED);
if (windspeed == 7)
leave(LEAVE_HURRICAN);
adjustview();
draw_screen();
(void) signal(SIGALRM, newturn);
(void) alarm(7);
}
/*VARARGS2*/
Signal(fmt, ship, a, b, c, d)
char *fmt;
register struct ship *ship;
int a, b, c, d;
{
if (!done_curses)
return;
if (*fmt == '\7')
putchar(*fmt++);
if (ship == 0)
(void) wprintw(scroll_w, fmt, a, b, c, d);
else
(void) wprintw(scroll_w, fmt, ship->shipname,
colours(ship), sterncolour(ship), a, b, c, d);
Scroll();
}
Scroll()
{
if (++sc_line >= SCROLL_Y)
sc_line = 0;
(void) wmove(scroll_w, sc_line, 0);
(void) wclrtoeol(scroll_w);
}
prompt(p, ship)
register char *p;
struct ship *ship;
{
static char buf[60];
if (ship != 0)
p = sprintf(buf, p, ship->shipname, colours(ship),
sterncolour(ship));
sc_prompt = p;
sc_buf = "";
sc_hasprompt = 1;
(void) waddstr(scroll_w, p);
}
endprompt(flag)
char flag;
{
sc_hasprompt = 0;
if (flag)
Scroll();
}
sgetch(p, ship, flag)
char *p;
struct ship *ship;
char flag;
{
register c;
prompt(p, ship);
blockalarm();
(void) wrefresh(scroll_w);
unblockalarm();
while ((c = wgetch(scroll_w)) == EOF)
;
if (flag && c >= ' ' && c < 0x7f)
(void) waddch(scroll_w, c);
endprompt(flag);
return c;
}
sgetstr(pr, buf, n)
char *pr;
register char *buf;
register n;
{
register c;
register char *p = buf;
prompt(pr, (struct ship *)0);
sc_buf = buf;
for (;;) {
*p = 0;
blockalarm();
(void) wrefresh(scroll_w);
unblockalarm();
while ((c = wgetch(scroll_w)) == EOF)
;
switch (c) {
case '\n':
case '\r':
endprompt(1);
return;
case '\b':
if (p > buf) {
(void) waddstr(scroll_w, "\b \b");
p--;
}
break;
default:
if (c >= ' ' && c < 0x7f && p < buf + n - 1) {
*p++ = c;
(void) waddch(scroll_w, c);
} else
(void) putchar(CTRL(g));
}
}
}
draw_screen()
{
draw_view();
draw_turn();
draw_stat();
draw_slot();
(void) wrefresh(scroll_w); /* move the cursor */
}
draw_view()
{
register struct ship *sp;
(void) werase(view_w);
foreachship(sp) {
if (sp->file->dir
&& sp->file->row > viewrow
&& sp->file->row < viewrow + VIEW_Y
&& sp->file->col > viewcol
&& sp->file->col < viewcol + VIEW_X) {
(void) wmove(view_w, sp->file->row - viewrow,
sp->file->col - viewcol);
(void) waddch(view_w, colours(sp));
(void) wmove(view_w,
sternrow(sp) - viewrow,
sterncol(sp) - viewcol);
(void) waddch(view_w, sterncolour(sp));
}
}
(void) wrefresh(view_w);
}
draw_turn()
{
(void) wmove(turn_w, 0, 0);
(void) wprintw(turn_w, "%cTurn %d", dont_adjust?'*':'-', turn);
(void) wrefresh(turn_w);
}
draw_stat()
{
(void) wmove(stat_w, STAT_1, 0);
(void) wprintw(stat_w, "Points %3d\n", mf->points);
(void) wprintw(stat_w, "Fouls %2d\n", fouled(ms));
(void) wprintw(stat_w, "Grapples %2d\n", grappled(ms));
(void) wmove(stat_w, STAT_2, 0);
(void) wprintw(stat_w, " 0 %c(%c)\n",
maxmove(ms, winddir + 3, -1) + '0',
maxmove(ms, winddir + 3, 1) + '0');
(void) waddstr(stat_w, " \\|/\n");
(void) wprintw(stat_w, " -^-%c(%c)\n",
maxmove(ms, winddir + 2, -1) + '0',
maxmove(ms, winddir + 2, 1) + '0');
(void) waddstr(stat_w, " /|\\\n");
(void) wprintw(stat_w, " | %c(%c)\n",
maxmove(ms, winddir + 1, -1) + '0',
maxmove(ms, winddir + 1, 1) + '0');
(void) wprintw(stat_w, " %c(%c)\n",
maxmove(ms, winddir, -1) + '0',
maxmove(ms, winddir, 1) + '0');
(void) wmove(stat_w, STAT_3, 0);
(void) wprintw(stat_w, "Load %c%c %c%c\n",
loadname[mf->loadL], readyname(mf->readyL),
loadname[mf->loadR], readyname(mf->readyR));
(void) wprintw(stat_w, "Hull %2d\n", mc->hull);
(void) wprintw(stat_w, "Crew %2d %2d %2d\n",
mc->crew1, mc->crew2, mc->crew3);
(void) wprintw(stat_w, "Guns %2d %2d\n", mc->gunL, mc->gunR);
(void) wprintw(stat_w, "Carr %2d %2d\n", mc->carL, mc->carR);
(void) wprintw(stat_w, "Rigg %d %d %d ", mc->rig1, mc->rig2, mc->rig3);
if (mc->rig4 < 0)
(void) waddch(stat_w, '-');
else
(void) wprintw(stat_w, "%d", mc->rig4);
(void) wrefresh(stat_w);
}
draw_slot()
{
if (!boarding(ms, 0)) {
(void) mvwaddstr(slot_w, 0, 0, " ");
(void) mvwaddstr(slot_w, 1, 0, " ");
} else
(void) mvwaddstr(slot_w, 1, 0, "OBP");
if (!boarding(ms, 1)) {
(void) mvwaddstr(slot_w, 2, 0, " ");
(void) mvwaddstr(slot_w, 3, 0, " ");
} else
(void) mvwaddstr(slot_w, 3, 0, "DBP");
(void) wmove(slot_w, SLOT_Y-4, 0);
if (mf->RH)
(void) wprintw(slot_w, "%dRH", mf->RH);
else
(void) waddstr(slot_w, " ");
(void) wmove(slot_w, SLOT_Y-3, 0);
if (mf->RG)
(void) wprintw(slot_w, "%dRG", mf->RG);
else
(void) waddstr(slot_w, " ");
(void) wmove(slot_w, SLOT_Y-2, 0);
if (mf->RR)
(void) wprintw(slot_w, "%dRR", mf->RR);
else
(void) waddstr(slot_w, " ");
#define Y (SLOT_Y/2)
(void) wmove(slot_w, 7, 1);
(void) wprintw(slot_w,"%d", windspeed);
(void) mvwaddch(slot_w, Y, 0, ' ');
(void) mvwaddch(slot_w, Y, 2, ' ');
(void) mvwaddch(slot_w, Y-1, 0, ' ');
(void) mvwaddch(slot_w, Y-1, 1, ' ');
(void) mvwaddch(slot_w, Y-1, 2, ' ');
(void) mvwaddch(slot_w, Y+1, 0, ' ');
(void) mvwaddch(slot_w, Y+1, 1, ' ');
(void) mvwaddch(slot_w, Y+1, 2, ' ');
(void) wmove(slot_w, Y - dr[winddir], 1 - dc[winddir]);
switch (winddir) {
case 1:
case 5:
(void) waddch(slot_w, '|');
break;
case 2:
case 6:
(void) waddch(slot_w, '/');
break;
case 3:
case 7:
(void) waddch(slot_w, '-');
break;
case 4:
case 8:
(void) waddch(slot_w, '\\');
break;
}
(void) mvwaddch(slot_w, Y + dr[winddir], 1 + dc[winddir], '+');
(void) wrefresh(slot_w);
}
draw_board()
{
register int n;
(void) clear();
(void) werase(view_w);
(void) werase(slot_w);
(void) werase(scroll_w);
(void) werase(stat_w);
(void) werase(turn_w);
sc_line = 0;
(void) move(BOX_T, BOX_L);
for (n = 0; n < BOX_X; n++)
(void) addch('-');
(void) move(BOX_B, BOX_L);
for (n = 0; n < BOX_X; n++)
(void) addch('-');
for (n = BOX_T+1; n < BOX_B; n++) {
(void) mvaddch(n, BOX_L, '|');
(void) mvaddch(n, BOX_R, '|');
}
(void) mvaddch(BOX_T, BOX_L, '+');
(void) mvaddch(BOX_T, BOX_R, '+');
(void) mvaddch(BOX_B, BOX_L, '+');
(void) mvaddch(BOX_B, BOX_R, '+');
(void) refresh();
#define WSaIM "Wooden Ships & Iron Men"
(void) wmove(view_w, 2, (VIEW_X - sizeof WSaIM - 1) / 2);
(void) waddstr(view_w, WSaIM);
(void) wmove(view_w, 4, (VIEW_X - strlen(cc->name)) / 2);
(void) waddstr(view_w, cc->name);
(void) wrefresh(view_w);
(void) move(LINE_T, LINE_L);
(void) printw("Class %d %s (%d guns) '%s' (%c%c)",
mc->class,
classname[mc->class],
mc->guns,
ms->shipname,
colours(ms),
sterncolour(ms));
(void) refresh();
}
centerview()
{
viewrow = mf->row - VIEW_Y / 2;
viewcol = mf->col - VIEW_X / 2;
}
upview()
{
viewrow -= VIEW_Y / 3;
}
downview()
{
viewrow += VIEW_Y / 3;
}
leftview()
{
viewcol -= VIEW_X / 5;
}
rightview()
{
viewcol += VIEW_X / 5;
}
adjustview()
{
if (dont_adjust)
return;
if (mf->row < viewrow + VIEW_Y/4)
viewrow = mf->row - (VIEW_Y - VIEW_Y/4);
else if (mf->row > viewrow + (VIEW_Y - VIEW_Y/4))
viewrow = mf->row - VIEW_Y/4;
if (mf->col < viewcol + VIEW_X/8)
viewcol = mf->col - (VIEW_X - VIEW_X/8);
else if (mf->col > viewcol + (VIEW_X - VIEW_X/8))
viewcol = mf->col - VIEW_X/8;
}
#ifdef SIGTSTP
susp()
{
blockalarm();
tstp();
(void) signal(SIGTSTP, susp);
unblockalarm();
}
#endif
SHAR_EOF
if test 9200 -ne "`wc -c sail/player7.c`"
then
echo shar: error transmitting sail/player7.c '(should have been 9200 characters)'
fi
# End of shell archive
exit 0
More information about the Comp.sources.unix
mailing list