summaryrefslogtreecommitdiffstats
path: root/games/sail
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1994-09-04 04:03:31 +0000
committerjkh <jkh@FreeBSD.org>1994-09-04 04:03:31 +0000
commit057afceb86e030ad65b0130436860d9a18066186 (patch)
treea0ced9c9b9278eb776d89cd2565c27ddcf020b51 /games/sail
parenteedec95276cdb8aef98e92c5371000f10b8d6ba7 (diff)
downloadFreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.zip
FreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.tar.gz
Bring in the 4.4 Lite games directory, modulo man page changes and segregation
of the x11 based games. I'm not going to tag the originals with bsd_44_lite and do this in two stages since it's just not worth it for this collection, and I've got directory renames to deal with that way. Bleah. Submitted by: jkh
Diffstat (limited to 'games/sail')
-rw-r--r--games/sail/:file10
-rw-r--r--games/sail/:scene3
-rw-r--r--games/sail/:ship4
-rw-r--r--games/sail/:specs3
-rw-r--r--games/sail/Makefile12
-rw-r--r--games/sail/assorted.c274
-rw-r--r--games/sail/dr_1.c461
-rw-r--r--games/sail/dr_2.c275
-rw-r--r--games/sail/dr_3.c346
-rw-r--r--games/sail/dr_4.c65
-rw-r--r--games/sail/dr_5.c93
-rw-r--r--games/sail/dr_main.c108
-rw-r--r--games/sail/driver.h38
-rw-r--r--games/sail/externs.h310
-rw-r--r--games/sail/game.c87
-rw-r--r--games/sail/globals.c507
-rw-r--r--games/sail/lo_main.c91
-rw-r--r--games/sail/machdep.h46
-rw-r--r--games/sail/main.c108
-rw-r--r--games/sail/misc.c233
-rw-r--r--games/sail/parties.c76
-rw-r--r--games/sail/pathnames.h36
-rw-r--r--games/sail/pl_1.c135
-rw-r--r--games/sail/pl_2.c154
-rw-r--r--games/sail/pl_3.c272
-rw-r--r--games/sail/pl_4.c129
-rw-r--r--games/sail/pl_5.c254
-rw-r--r--games/sail/pl_6.c196
-rw-r--r--games/sail/pl_7.c466
-rw-r--r--games/sail/pl_main.c244
-rw-r--r--games/sail/player.h122
-rw-r--r--games/sail/sail.6896
-rw-r--r--games/sail/sync.c421
-rw-r--r--games/sail/version.c38
34 files changed, 6513 insertions, 0 deletions
diff --git a/games/sail/:file b/games/sail/:file
new file mode 100644
index 0000000..dd5762f
--- /dev/null
+++ b/games/sail/:file
@@ -0,0 +1,10 @@
+./"index"16t"captain"nD20C
++/"points"8t"loadL"8t"loadR"8t"readyL"8t"readyL"ndbbbb2+36+36+
++/"struck"8t"capture"8t"pcrew"8t"movebuf"nb3+pd10C
++/"drift"8t"nfoul"8t"ngrap"nb1+dd
++/"foul:"8t"count"8t"turn"16t"count"8t"turn"
++,5/8tdd16tddn
++/"grap:"8t"count"8t"turn"16t"count"8t"turn"
++,5/8tdd16tddn
++/"RH"8t"RG"8t"RR"8t"FS"8t"explode"8t"sink"n6b
++/"dir"8t"col"8t"row"8t"loadwit"8t"stern"nb+2d2b
diff --git a/games/sail/:scene b/games/sail/:scene
new file mode 100644
index 0000000..43c4d81
--- /dev/null
+++ b/games/sail/:scene
@@ -0,0 +1,3 @@
+./"winddir windspd windchg vessels"n4b
+.+8/"ship: "a
+*(.-4)/S
diff --git a/games/sail/:ship b/games/sail/:ship
new file mode 100644
index 0000000..fdf9dd0
--- /dev/null
+++ b/games/sail/:ship
@@ -0,0 +1,4 @@
+./"name"16t"specs"16t"nation"nppb+
++/"row"8t"col"8t"dir"nddb+
++/"file"np
++/t
diff --git a/games/sail/:specs b/games/sail/:specs
new file mode 100644
index 0000000..2a71f70
--- /dev/null
+++ b/games/sail/:specs
@@ -0,0 +1,3 @@
+./"bs bs ta guns class hull qual"n3b+d3b
++/"crew1 crew2 crew3 gunL gunR carL carR"n8b
++/"rig1 rig2 rig3 rig4 pts"n4b+d
diff --git a/games/sail/Makefile b/games/sail/Makefile
new file mode 100644
index 0000000..722190b
--- /dev/null
+++ b/games/sail/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 8.1 (Berkeley) 5/31/93
+
+PROG= sail
+SRCS= main.c pl_main.c pl_1.c pl_2.c pl_3.c pl_4.c pl_5.c pl_6.c pl_7.c \
+ dr_main.c dr_1.c dr_2.c dr_3.c dr_4.c dr_5.c lo_main.c \
+ assorted.c game.c globals.c misc.c parties.c sync.c version.c
+MAN6= sail.6
+DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT}
+LDADD= -lcurses -ltermlib -lcompat
+HIDEGAME=hidegame
+
+.include <bsd.prog.mk>
diff --git a/games/sail/assorted.c b/games/sail/assorted.c
new file mode 100644
index 0000000..2fb12ac
--- /dev/null
+++ b/games/sail/assorted.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)assorted.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+table(rig, shot, hittable, on, from, roll)
+struct ship *on, *from;
+int rig, shot, hittable, roll;
+{
+ register int hhits = 0, chits = 0, ghits = 0, rhits = 0;
+ int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0;
+ int guns, car, pc, hull;
+ int crew[3];
+ register int n;
+ int rigg[4];
+ char *message;
+ struct Tables *tp;
+
+ pc = on->file->pcrew;
+ hull = on->specs->hull;
+ crew[0] = on->specs->crew1;
+ crew[1] = on->specs->crew2;
+ crew[2] = on->specs->crew3;
+ rigg[0] = on->specs->rig1;
+ rigg[1] = on->specs->rig2;
+ rigg[2] = on->specs->rig3;
+ rigg[3] = on->specs->rig4;
+ if (shot == L_GRAPE)
+ Chit = chits = hittable;
+ else {
+ tp = &(rig ? RigTable : HullTable)[hittable][roll-1];
+ Chit = chits = tp->C;
+ Rhit = rhits = tp->R;
+ Hhit = hhits = tp->H;
+ Ghit = ghits = tp->G;
+ if (on->file->FS)
+ rhits *= 2;
+ if (shot == L_CHAIN) {
+ Ghit = ghits = 0;
+ Hhit = hhits = 0;
+ }
+ }
+ if (on->file->captured != 0) {
+ pc -= (chits + 1) / 2;
+ chits /= 2;
+ }
+ for (n = 0; n < 3; n++)
+ if (chits > crew[n]) {
+ chits -= crew[n];
+ crew[n] = 0;
+ } else {
+ crew[n] -= chits;
+ chits = 0;
+ }
+ for (n = 0; n < 3; n++)
+ if (rhits > rigg[n]){
+ rhits -= rigg[n];
+ rigg[n] = 0;
+ } else {
+ rigg[n] -= rhits;
+ rhits = 0;
+ }
+ if (rigg[3] != -1 && rhits > rigg[3]) {
+ rhits -= rigg[3];
+ rigg[3] = 0;
+ } else if (rigg[3] != -1) {
+ rigg[3] -= rhits;
+ }
+ if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1))
+ makesignal(on, "dismasted!", (struct ship *)0);
+ if (portside(from, on, 0)) {
+ guns = on->specs->gunR;
+ car = on->specs->carR;
+ } else {
+ guns = on->specs->gunL;
+ car = on->specs->carL;
+ }
+ if (ghits > car) {
+ ghits -= car;
+ car = 0;
+ } else {
+ car -= ghits;
+ ghits = 0;
+ }
+ if (ghits > guns){
+ ghits -= guns;
+ guns = 0;
+ } else {
+ guns -= ghits;
+ ghits = 0;
+ }
+ hull -= ghits;
+ if (Ghit)
+ Write(portside(from, on, 0) ? W_GUNR : W_GUNL,
+ on, 0, guns, car, 0, 0);
+ hull -= hhits;
+ hull = hull < 0 ? 0 : hull;
+ if (on->file->captured != 0 && Chit)
+ Write(W_PCREW, on, 0, pc, 0, 0, 0);
+ if (Hhit)
+ Write(W_HULL, on, 0, hull, 0, 0, 0);
+ if (Chit)
+ Write(W_CREW, on, 0, crew[0], crew[1], crew[2], 0);
+ if (Rhit)
+ Write(W_RIGG, on, 0, rigg[0], rigg[1], rigg[2], rigg[3]);
+ switch (shot) {
+ case L_ROUND:
+ message = "firing round shot on %s (%c%c)";
+ break;
+ case L_GRAPE:
+ message = "firing grape shot on %s (%c%c)";
+ break;
+ case L_CHAIN:
+ message = "firing chain shot on %s (%c%c)";
+ break;
+ case L_DOUBLE:
+ message = "firing double shot on %s (%c%c)";
+ break;
+ case L_EXPLODE:
+ message = "exploding shot on %s (%c%c)";
+ }
+ makesignal(from, message, on);
+ if (roll == 6 && rig) {
+ switch(Rhit) {
+ case 0:
+ message = "fore topsail sheets parted";
+ break;
+ case 1:
+ message = "mizzen shrouds parted";
+ break;
+ case 2:
+ message = "main topsail yard shot away";
+ break;
+ case 4:
+ message = "fore topmast and foremast shrouds shot away";
+ break;
+ case 5:
+ message = "mizzen mast and yard shot through";
+ break;
+ case 6:
+ message = "foremast and spritsail yard shattered";
+ break;
+ case 7:
+ message = "main topmast and mizzen mast shattered";
+ break;
+ }
+ makesignal(on, message, (struct ship *)0);
+ } else if (roll == 6) {
+ switch (Hhit) {
+ case 0:
+ message = "anchor cables severed";
+ break;
+ case 1:
+ message = "two anchor stocks shot away";
+ break;
+ case 2:
+ message = "quarterdeck bulwarks damaged";
+ break;
+ case 3:
+ message = "three gun ports shot away";
+ break;
+ case 4:
+ message = "four guns dismounted";
+ break;
+ case 5:
+ message = "rudder cables shot through";
+ Write(W_TA, on, 0, 0, 0, 0, 0);
+ break;
+ case 6:
+ message = "shot holes below the water line";
+ break;
+ }
+ makesignal(on, message, (struct ship *)0);
+ }
+ /*
+ if (Chit > 1 && on->file->readyL&R_INITIAL && on->file->readyR&R_INITIAL) {
+ on->specs->qual--;
+ if (on->specs->qual <= 0) {
+ makesignal(on, "crew mutinying!", (struct ship *)0);
+ on->specs->qual = 5;
+ Write(W_CAPTURED, on, 0, on->file->index, 0, 0, 0);
+ } else
+ makesignal(on, "crew demoralized", (struct ship *)0);
+ Write(W_QUAL, on, 0, on->specs->qual, 0, 0, 0);
+ }
+ */
+ if (!hull)
+ strike(on, from);
+}
+
+Cleansnag(from, to, all, flag)
+register struct ship *from, *to;
+char all, flag;
+{
+ if (flag & 1) {
+ Write(W_UNGRAP, from, 0, to->file->index, all, 0, 0);
+ Write(W_UNGRAP, to, 0, from->file->index, all, 0, 0);
+ }
+ if (flag & 2) {
+ Write(W_UNFOUL, from, 0, to->file->index, all, 0, 0);
+ Write(W_UNFOUL, to, 0, from->file->index, all, 0, 0);
+ }
+ if (!snagged2(from, to)) {
+ if (!snagged(from)) {
+ unboard(from, from, 1); /* defense */
+ unboard(from, from, 0); /* defense */
+ } else
+ unboard(from, to, 0); /* offense */
+ if (!snagged(to)) {
+ unboard(to, to, 1); /* defense */
+ unboard(to, to, 0); /* defense */
+ } else
+ unboard(to, from, 0); /* offense */
+ }
+}
+
+strike(ship, from)
+register struct ship *ship, *from;
+{
+ int points;
+
+ if (ship->file->struck)
+ return;
+ Write(W_STRUCK, ship, 0, 1, 0, 0, 0);
+ points = ship->specs->pts + from->file->points;
+ Write(W_POINTS, from, 0, points, 0, 0, 0);
+ unboard(ship, ship, 0); /* all offense */
+ unboard(ship, ship, 1); /* all defense */
+ switch (die()) {
+ case 3:
+ case 4: /* ship may sink */
+ Write(W_SINK, ship, 0, 1, 0, 0, 0);
+ break;
+ case 5:
+ case 6: /* ship may explode */
+ Write(W_EXPLODE, ship, 0, 1, 0, 0, 0);
+ break;
+ }
+ Write(W_SIGNAL, ship, 1, (int) "striking her colours!", 0, 0, 0);
+}
diff --git a/games/sail/dr_1.c b/games/sail/dr_1.c
new file mode 100644
index 0000000..170e5d9
--- /dev/null
+++ b/games/sail/dr_1.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_1.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "driver.h"
+
+unfoul()
+{
+ register struct ship *sp;
+ struct ship *to;
+ register int nat;
+ register i;
+
+ foreachship(sp) {
+ if (sp->file->captain[0])
+ continue;
+ nat = capship(sp)->nationality;
+ foreachship(to) {
+ if (nat != capship(to)->nationality &&
+ !toughmelee(sp, to, 0, 0))
+ continue;
+ for (i = fouled2(sp, to); --i >= 0;)
+ if (die() <= 2)
+ cleanfoul(sp, to, 0);
+ }
+ }
+}
+
+boardcomp()
+{
+ int crew[3];
+ register struct ship *sp, *sq;
+
+ foreachship(sp) {
+ if (*sp->file->captain)
+ continue;
+ if (sp->file->dir == 0)
+ continue;
+ if (sp->file->struck || sp->file->captured != 0)
+ continue;
+ if (!snagged(sp))
+ continue;
+ crew[0] = sp->specs->crew1 != 0;
+ crew[1] = sp->specs->crew2 != 0;
+ crew[2] = sp->specs->crew3 != 0;
+ foreachship(sq) {
+ if (!Xsnagged2(sp, sq))
+ continue;
+ if (meleeing(sp, sq))
+ continue;
+ if (!sq->file->dir
+ || sp->nationality == capship(sq)->nationality)
+ continue;
+ switch (sp->specs->class - sq->specs->class) {
+ case -3: case -4: case -5:
+ if (crew[0]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100, 0);
+ crew[0] = 0;
+ } else if (crew[1]){
+ /* OBP */
+ sendbp(sp, sq, crew[1]*10, 0);
+ crew[1] = 0;
+ }
+ break;
+ case -2:
+ if (crew[0] || crew[1]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10,
+ 0);
+ crew[0] = crew[1] = 0;
+ }
+ break;
+ case -1: case 0: case 1:
+ if (crew[0]) {
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10,
+ 0);
+ crew[0] = crew[1] = 0;
+ }
+ break;
+ case 2: case 3: case 4: case 5:
+ /* OBP */
+ sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
+ 0);
+ crew[0] = crew[1] = crew[2] = 0;
+ break;
+ }
+ }
+ }
+}
+
+fightitout(from, to, key)
+struct ship *from, *to;
+int key;
+{
+ struct ship *fromcap, *tocap;
+ int crewfrom[3], crewto[3], menfrom, mento;
+ int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
+ int topoints;
+ int index, totalfrom = 0, totalto = 0;
+ int count;
+ char message[60];
+
+ menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
+ mento = mensent(to, from, crewto, &tocap, &pcto, 0);
+ if (fromcap == 0)
+ fromcap = from;
+ if (tocap == 0)
+ tocap = to;
+ if (key) {
+ if (!menfrom) { /* if crew surprised */
+ if (fromcap == from)
+ menfrom = from->specs->crew1
+ + from->specs->crew2
+ + from->specs->crew3;
+ else
+ menfrom = from->file->pcrew;
+ } else {
+ menfrom *= 2; /* DBP's fight at an advantage */
+ }
+ }
+ fromstrength = menfrom * fromcap->specs->qual;
+ strengthto = mento * tocap->specs->qual;
+ for (count = 0;
+ (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
+ || fromstrength == -1) && count < 4;
+ count++) {
+ index = fromstrength/10;
+ if (index > 8)
+ index = 8;
+ toinjured = MT[index][2 - die() / 3];
+ totalto += toinjured;
+ index = strengthto/10;
+ if (index > 8)
+ index = 8;
+ frominjured = MT[index][2 - die() / 3];
+ totalfrom += frominjured;
+ menfrom -= frominjured;
+ mento -= toinjured;
+ fromstrength = menfrom * fromcap->specs->qual;
+ strengthto = mento * tocap->specs->qual;
+ }
+ if (fromstrength >= strengthto * 3 || count == 4) {
+ unboard(to, from, 0);
+ subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
+ subtract(to, totalto, crewto, tocap, pcto);
+ makesignal(from, "boarders from %s repelled", to);
+ (void) sprintf(message, "killed in melee: %d. %s: %d",
+ totalto, from->shipname, totalfrom);
+ Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
+ if (key)
+ return 1;
+ } else if (strengthto >= fromstrength * 3) {
+ unboard(from, to, 0);
+ subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
+ subtract(to, totalto, crewto, tocap, pcto);
+ if (key) {
+ if (fromcap != from)
+ Write(W_POINTS, fromcap, 0,
+ fromcap->file->points -
+ from->file->struck
+ ? from->specs->pts
+ : 2 * from->specs->pts,
+ 0, 0, 0);
+
+/* ptr1 points to the shipspec for the ship that was just unboarded.
+ I guess that what is going on here is that the pointer is multiplied
+ or something. */
+
+ Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
+ topoints = 2 * from->specs->pts + to->file->points;
+ if (from->file->struck)
+ topoints -= from->specs->pts;
+ Write(W_POINTS, to, 0, topoints, 0, 0, 0);
+ mento = crewto[0] ? crewto[0] : crewto[1];
+ if (mento) {
+ subtract(to, mento, crewto, tocap, pcto);
+ subtract(from, - mento, crewfrom, to, 0);
+ }
+ (void) sprintf(message, "captured by the %s!",
+ to->shipname);
+ Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
+ (void) sprintf(message, "killed in melee: %d. %s: %d",
+ totalto, from->shipname, totalfrom);
+ Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
+ mento = 0;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+resolve()
+{
+ int thwart;
+ register struct ship *sp, *sq;
+
+ foreachship(sp) {
+ if (sp->file->dir == 0)
+ continue;
+ for (sq = sp + 1; sq < ls; sq++)
+ if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
+ (void) fightitout(sp, sq, 0);
+ thwart = 2;
+ foreachship(sq) {
+ if (sq->file->dir && meleeing(sq, sp))
+ thwart = fightitout(sp, sq, 1);
+ if (!thwart)
+ break;
+ }
+ if (!thwart) {
+ foreachship(sq) {
+ if (sq->file->dir && meleeing(sq, sp))
+ unboard(sq, sp, 0);
+ unboard(sp, sq, 0);
+ }
+ unboard(sp, sp, 1);
+ } else if (thwart == 2)
+ unboard(sp, sp, 1);
+ }
+}
+
+compcombat()
+{
+ register n;
+ register struct ship *sp;
+ struct ship *closest;
+ int crew[3], men = 0, target, temp;
+ int r, guns, ready, load, car;
+ int index, rakehim, sternrake;
+ int shootat, hit;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ crew[0] = sp->specs->crew1;
+ crew[1] = sp->specs->crew2;
+ crew[2] = sp->specs->crew3;
+ for (n = 0; n < 3; n++) {
+ if (sp->file->OBP[n].turnsent)
+ men += sp->file->OBP[n].mensent;
+ }
+ for (n = 0; n < 3; n++) {
+ if (sp->file->DBP[n].turnsent)
+ men += sp->file->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 (!crew[2])
+ continue;
+ if (sp->file->struck)
+ continue;
+ if (r) {
+ ready = sp->file->readyR;
+ guns = sp->specs->gunR;
+ car = sp->specs->carR;
+ } else {
+ ready = sp->file->readyL;
+ guns = sp->specs->gunL;
+ car = sp->specs->carL;
+ }
+ if (!guns && !car)
+ continue;
+ if ((ready & R_LOADED) == 0)
+ continue;
+ closest = closestenemy(sp, r ? 'r' : 'l', 0);
+ if (closest == 0)
+ continue;
+ if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
+ continue;
+ if (closest->file->struck)
+ continue;
+ target = range(sp, closest);
+ if (target > 10)
+ continue;
+ if (!guns && target >= 3)
+ continue;
+ load = L_ROUND;
+ if (target == 1 && sp->file->loadwith == L_GRAPE)
+ load = L_GRAPE;
+ if (target <= 3 && closest->file->FS)
+ load = L_CHAIN;
+ if (target == 1 && load != L_GRAPE)
+ load = L_DOUBLE;
+ if (load > L_CHAIN && target < 6)
+ shootat = HULL;
+ else
+ shootat = RIGGING;
+ rakehim = gunsbear(sp, closest)
+ && !gunsbear(closest, sp);
+ temp = portside(closest, sp, 1)
+ - closest->file->dir + 1;
+ if (temp < 1)
+ temp += 8;
+ if (temp > 8)
+ temp -= 8;
+ sternrake = temp > 4 && temp < 6;
+ 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][capship(sp)->specs->qual - 1];
+ for (n = 0; n < 3 && sp->file->captured == 0; n++)
+ if (!crew[n])
+ if (index <= 5)
+ hit--;
+ else
+ hit -= 2;
+ if (ready & R_INITIAL) {
+ if (!r)
+ sp->file->readyL &= ~R_INITIAL;
+ else
+ sp->file->readyR &= ~R_INITIAL;
+ if (index <= 3)
+ hit++;
+ else
+ hit += 2;
+ }
+ if (sp->file->captured != 0)
+ if (index <= 1)
+ hit--;
+ else
+ hit -= 2;
+ hit += AMMO[index][load - 1];
+ temp = sp->specs->class;
+ if ((temp >= 5 || temp == 1) && windspeed == 5)
+ hit--;
+ if (windspeed == 6 && temp == 4)
+ hit -= 2;
+ if (windspeed == 6 && temp <= 3)
+ hit--;
+ if (hit >= 0) {
+ if (load != L_GRAPE)
+ hit = hit > 10 ? 10 : hit;
+ table(shootat, load, hit, closest, sp, die());
+ }
+ }
+ }
+}
+
+next()
+{
+ if (++turn % 55 == 0)
+ if (alive)
+ alive = 0;
+ else
+ people = 0;
+ if (people <= 0 || windspeed == 7) {
+ register struct ship *s;
+ struct ship *bestship;
+ float net, best = 0.0;
+ foreachship(s) {
+ if (*s->file->captain)
+ continue;
+ net = (float)s->file->points / s->specs->pts;
+ if (net > best) {
+ best = net;
+ bestship = s;
+ }
+ }
+ if (best > 0.0) {
+ char *p = getenv("WOTD");
+ if (p == 0)
+ p = "Driver";
+ if (islower(*p))
+ *p = toupper(*p);
+ (void) strncpy(bestship->file->captain, p,
+ sizeof bestship->file->captain);
+ bestship->file->captain
+ [sizeof bestship->file->captain - 1] = 0;
+ log(bestship);
+ }
+ return -1;
+ }
+ Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
+ if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) {
+ switch (die()) {
+ case 1:
+ winddir = 1;
+ break;
+ case 2:
+ break;
+ case 3:
+ winddir++;
+ break;
+ case 4:
+ winddir--;
+ break;
+ case 5:
+ winddir += 2;
+ break;
+ case 6:
+ winddir -= 2;
+ break;
+ }
+ if (winddir > 8)
+ winddir -= 8;
+ if (winddir < 1)
+ winddir += 8;
+ if (windspeed)
+ switch (die()) {
+ case 1:
+ case 2:
+ windspeed--;
+ break;
+ case 5:
+ case 6:
+ windspeed++;
+ break;
+ }
+ else
+ windspeed++;
+ Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
+ }
+ return 0;
+}
diff --git a/games/sail/dr_2.c b/games/sail/dr_2.c
new file mode 100644
index 0000000..472db84
--- /dev/null
+++ b/games/sail/dr_2.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_2.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "driver.h"
+
+#define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
+
+thinkofgrapples()
+{
+ register struct ship *sp, *sq;
+ char friendly;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ foreachship(sq) {
+ friendly = sp->nationality == capship(sq)->nationality;
+ if (!friendly) {
+ if (sp->file->struck || sp->file->captured != 0)
+ continue;
+ if (range(sp, sq) != 1)
+ continue;
+ if (grappled2(sp, sq))
+ if (toughmelee(sp, sq, 0, 0))
+ ungrap(sp, sq);
+ else
+ grap(sp, sq);
+ else if (couldwin(sp, sq)) {
+ grap(sp, sq);
+ sp->file->loadwith = L_GRAPE;
+ }
+ } else
+ ungrap(sp, sq);
+ }
+ }
+}
+
+checkup()
+{
+ register struct ship *sp, *sq;
+ register char explode, sink;
+
+ foreachship(sp) {
+ if (sp->file->dir == 0)
+ continue;
+ explode = sp->file->explode;
+ sink = sp->file->sink;
+ if (explode != 1 && sink != 1)
+ continue;
+ if (die() < 5)
+ continue;
+ Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0);
+ Write(W_DIR, sp, 0, 0, 0, 0, 0);
+ if (snagged(sp))
+ foreachship(sq)
+ cleansnag(sp, sq, 1);
+ if (sink != 1) {
+ makesignal(sp, "exploding!", (struct ship *)0);
+ foreachship(sq) {
+ if (sp != sq && sq->file->dir && range(sp, sq) < 4)
+ table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6);
+ }
+ } else
+ makesignal(sp, "sinking!", (struct ship *)0);
+ }
+}
+
+prizecheck()
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ if (sp->file->captured == 0)
+ continue;
+ if (sp->file->struck || sp->file->dir == 0)
+ continue;
+ if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) {
+ Write(W_SIGNAL, sp, 1,
+ (int)"prize crew overthrown", 0, 0, 0);
+ Write(W_POINTS, sp->file->captured, 0, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0);
+ Write(W_CAPTURED, sp, 0, -1, 0, 0, 0);
+ }
+ }
+}
+
+strend(str)
+char *str;
+{
+ register char *p;
+
+ for (p = str; *p; p++)
+ ;
+ return p == str ? 0 : p[-1];
+}
+
+closeon(from, to, command, ta, ma, af)
+register struct ship *from, *to;
+char command[];
+int ma, ta, af;
+{
+ int high;
+ char temp[10];
+
+ temp[0] = command[0] = '\0';
+ high = -30000;
+ try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0);
+}
+
+int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */
+
+score(movement, ship, to, onlytemp)
+char movement[];
+register struct ship *ship, *to;
+char onlytemp;
+{
+ char drift;
+ int row, col, dir, total, ran;
+ register struct File *fp = ship->file;
+
+ if ((dir = fp->dir) == 0)
+ return 0;
+ row = fp->row;
+ col = fp->col;
+ drift = fp->drift;
+ move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
+ if (!*movement)
+ (void) strcpy(movement, "d");
+
+ ran = range(ship, to);
+ total = -50 * ran;
+ if (ran < 4 && gunsbear(ship, to))
+ total += 60;
+ if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
+ total = -30000;
+
+ if (!onlytemp) {
+ fp->row = row;
+ fp->col = col;
+ fp->dir = dir;
+ }
+ return total;
+}
+
+move(p, ship, dir, row, col, drift)
+register char *p;
+register struct ship *ship;
+register char *dir;
+register short *row, *col;
+register char *drift;
+{
+ int dist;
+ char moved = 0;
+
+ for (; *p; p++) {
+ switch (*p) {
+ case 'r':
+ if (++*dir == 9)
+ *dir = 1;
+ break;
+ case 'l':
+ if (--*dir == 0)
+ *dir = 8;
+ break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ moved++;
+ if (*dir % 2 == 0)
+ dist = dtab[*p - '0'];
+ else
+ dist = *p - '0';
+ *row -= dr[*dir] * dist;
+ *col -= dc[*dir] * dist;
+ break;
+ }
+ }
+ if (!moved) {
+ if (windspeed != 0 && ++*drift > 2) {
+ if (ship->specs->class >= 3 && !snagged(ship)
+ || (turn & 1) == 0) {
+ *row -= dr[winddir];
+ *col -= dc[winddir];
+ }
+ }
+ } else
+ *drift = 0;
+}
+
+try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme)
+register struct ship *f, *t;
+int ma, ta, af, *high, rakeme;
+char command[], temp[];
+{
+ register int new, n;
+ char st[4];
+#define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
+
+ if ((n = strend(temp)) < '1' || n > '9')
+ for (n = 1; vma - n >= 0; n++) {
+ (void) sprintf(st, "%d", n);
+ (void) strcat(temp, st);
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || rakeyou)) {
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-n, ta, af, vma-n,
+ dir, f, t, high, rakeme);
+ rmend(temp);
+ }
+ if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) {
+ (void) strcat(temp, "r");
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) {
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1),f,t,high,rakeme);
+ rmend(temp);
+ }
+ if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){
+ (void) strcat(temp, "l");
+ new = score(temp, f, t, rakeme);
+ if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
+ *high = new;
+ (void) strcpy(command, temp);
+ }
+ try(command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), f, t, high, rakeme);
+ rmend(temp);
+ }
+}
+
+rmend(str)
+char *str;
+{
+ register char *p;
+
+ for (p = str; *p; p++)
+ ;
+ if (p != str)
+ *--p = 0;
+}
diff --git a/games/sail/dr_3.c b/games/sail/dr_3.c
new file mode 100644
index 0000000..a0ceb72
--- /dev/null
+++ b/games/sail/dr_3.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_3.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "driver.h"
+
+moveall() /* move all comp ships */
+{
+ register struct ship *sp, *sq; /* r11, r10 */
+ register int n; /* r9 */
+ register int k, l; /* r8, r7 */
+ int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
+ char moved[NSHIP];
+
+ /*
+ * first try to create moves for OUR ships
+ */
+ foreachship(sp) {
+ struct ship *closest;
+ int ma, ta;
+ char af;
+
+ if (sp->file->captain[0] || sp->file->dir == 0)
+ continue;
+ if (!sp->file->struck && windspeed && !snagged(sp)
+ && sp->specs->crew3) {
+ ta = maxturns(sp, &af);
+ ma = maxmove(sp, sp->file->dir, 0);
+ closest = closestenemy(sp, 0, 0);
+ if (closest == 0)
+ *sp->file->movebuf = '\0';
+ else
+ closeon(sp, closest, sp->file->movebuf,
+ ta, ma, af);
+ } else
+ *sp->file->movebuf = '\0';
+ }
+ /*
+ * Then execute the moves for ALL ships (dead ones too),
+ * checking for collisions and snags at each step.
+ * The old positions are saved in row[], col[], dir[].
+ * At the end, we compare and write out the changes.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (snagged(sp))
+ (void) strcpy(sp->file->movebuf, "d");
+ else
+ if (*sp->file->movebuf != 'd')
+ (void) strcat(sp->file->movebuf, "d");
+ row[n] = sp->file->row;
+ col[n] = sp->file->col;
+ dir[n] = sp->file->dir;
+ drift[n] = sp->file->drift;
+ moved[n] = 0;
+ n++;
+ }
+ /*
+ * Now resolve collisions.
+ * This is the tough part.
+ */
+ for (k = 0; stillmoving(k); k++) {
+ /*
+ * Step once.
+ * And propagate the nulls at the end of sp->file->movebuf.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (!sp->file->movebuf[k])
+ sp->file->movebuf[k+1] = '\0';
+ else if (sp->file->dir)
+ step(sp->file->movebuf[k], sp, &moved[n]);
+ n++;
+ }
+ /*
+ * The real stuff.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (sp->file->dir == 0 || isolated(sp))
+ goto cont1;
+ l = 0;
+ foreachship(sq) {
+ char snap = 0;
+
+ if (sp == sq)
+ goto cont2;
+ if (sq->file->dir == 0)
+ goto cont2;
+ if (!push(sp, sq))
+ goto cont2;
+ if (snagged2(sp, sq) && range(sp, sq) > 1)
+ snap++;
+ if (!range(sp, sq) && !fouled2(sp, sq)) {
+ makesignal(sp,
+ "collision with %s (%c%c)", sq);
+ if (die() < 4) {
+ makesignal(sp,
+ "fouled with %s (%c%c)",
+ sq);
+ Write(W_FOUL, sp, 0, l, 0, 0, 0);
+ Write(W_FOUL, sq, 0, n, 0, 0, 0);
+ }
+ snap++;
+ }
+ if (snap) {
+ sp->file->movebuf[k + 1] = 0;
+ sq->file->movebuf[k + 1] = 0;
+ sq->file->row = sp->file->row - 1;
+ if (sp->file->dir == 1
+ || sp->file->dir == 5)
+ sq->file->col =
+ sp->file->col - 1;
+ else
+ sq->file->col = sp->file->col;
+ sq->file->dir = sp->file->dir;
+ }
+ cont2:
+ l++;
+ }
+ cont1:
+ n++;
+ }
+ }
+ /*
+ * Clear old moves. And write out new pos.
+ */
+ n = 0;
+ foreachship(sp) {
+ if (sp->file->dir != 0) {
+ *sp->file->movebuf = 0;
+ if (row[n] != sp->file->row)
+ Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
+ if (col[n] != sp->file->col)
+ Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
+ if (dir[n] != sp->file->dir)
+ Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
+ if (drift[n] != sp->file->drift)
+ Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
+ }
+ n++;
+ }
+}
+
+stillmoving(k)
+register int k;
+{
+ register struct ship *sp;
+
+ foreachship(sp)
+ if (sp->file->movebuf[k])
+ return 1;
+ return 0;
+}
+
+isolated(ship)
+register struct ship *ship;
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ if (ship != sp && range(ship, sp) <= 10)
+ return 0;
+ }
+ return 1;
+}
+
+push(from, to)
+register struct ship *from, *to;
+{
+ register int bs, sb;
+
+ sb = to->specs->guns;
+ bs = from->specs->guns;
+ if (sb > bs)
+ return 1;
+ if (sb < bs)
+ return 0;
+ return from < to;
+}
+
+step(com, sp, moved)
+char com;
+register struct ship *sp;
+char *moved;
+{
+ register int dist;
+
+ switch (com) {
+ case 'r':
+ if (++sp->file->dir == 9)
+ sp->file->dir = 1;
+ break;
+ case 'l':
+ if (--sp->file->dir == 0)
+ sp->file->dir = 8;
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ if (sp->file->dir % 2 == 0)
+ dist = dtab[com - '0'];
+ else
+ dist = com - '0';
+ sp->file->row -= dr[sp->file->dir] * dist;
+ sp->file->col -= dc[sp->file->dir] * dist;
+ *moved = 1;
+ break;
+ case 'b':
+ break;
+ case 'd':
+ if (!*moved) {
+ if (windspeed != 0 && ++sp->file->drift > 2 &&
+ (sp->specs->class >= 3 && !snagged(sp)
+ || (turn & 1) == 0)) {
+ sp->file->row -= dr[winddir];
+ sp->file->col -= dc[winddir];
+ }
+ } else
+ sp->file->drift = 0;
+ break;
+ }
+}
+
+sendbp(from, to, sections, isdefense)
+register struct ship *from, *to;
+int sections;
+char isdefense;
+{
+ int n;
+ register struct BP *bp;
+
+ bp = isdefense ? from->file->DBP : from->file->OBP;
+ for (n = 0; n < NBP && bp[n].turnsent; n++)
+ ;
+ if (n < NBP && sections) {
+ Write(isdefense ? W_DBP : W_OBP, from, 0,
+ n, turn, to->file->index, sections);
+ if (isdefense)
+ makesignal(from, "repelling boarders",
+ (struct ship *)0);
+ else
+ makesignal(from, "boarding the %s (%c%c)", to);
+ }
+}
+
+toughmelee(ship, to, isdefense, count)
+register struct ship *ship, *to;
+int isdefense, count;
+{
+ register struct BP *bp;
+ register obp = 0;
+ int n, OBP = 0, DBP = 0, dbp = 0;
+ int qual;
+
+ qual = ship->specs->qual;
+ bp = isdefense ? ship->file->DBP : ship->file->OBP;
+ for (n = 0; n < NBP; n++, bp++) {
+ if (bp->turnsent && (to == bp->toship || isdefense)) {
+ obp += bp->mensent / 100
+ ? ship->specs->crew1 * qual : 0;
+ obp += (bp->mensent % 100)/10
+ ? ship->specs->crew2 * qual : 0;
+ obp += bp->mensent % 10
+ ? ship->specs->crew3 * qual : 0;
+ }
+ }
+ if (count || isdefense)
+ return obp;
+ OBP = toughmelee(to, ship, 0, count + 1);
+ dbp = toughmelee(ship, to, 1, count + 1);
+ DBP = toughmelee(to, ship, 1, count + 1);
+ if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
+ return 1;
+ else
+ return 0;
+}
+
+reload()
+{
+ register struct ship *sp;
+
+ foreachship(sp) {
+ sp->file->loadwith = 0;
+ }
+}
+
+checksails()
+{
+ register struct ship *sp;
+ register int rig, full;
+ struct ship *close;
+
+ foreachship(sp) {
+ if (sp->file->captain[0] != 0)
+ continue;
+ rig = sp->specs->rig1;
+ if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
+ rig = 0;
+ if (rig && sp->specs->crew3) {
+ close = closestenemy(sp, 0, 0);
+ if (close != 0) {
+ if (range(sp, close) > 9)
+ full = 1;
+ else
+ full = 0;
+ } else
+ full = 0;
+ } else
+ full = 0;
+ if ((sp->file->FS != 0) != full)
+ Write(W_FS, sp, 0, full, 0, 0, 0);
+ }
+}
diff --git a/games/sail/dr_4.c b/games/sail/dr_4.c
new file mode 100644
index 0000000..5252c44
--- /dev/null
+++ b/games/sail/dr_4.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_4.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+ungrap(from, to)
+register struct ship *from, *to;
+{
+ register k;
+ char friend;
+
+ if ((k = grappled2(from, to)) == 0)
+ return;
+ friend = capship(from)->nationality == capship(to)->nationality;
+ while (--k >= 0) {
+ if (friend || die() < 3) {
+ cleangrapple(from, to, 0);
+ makesignal(from, "ungrappling %s (%c%c)", to);
+ }
+ }
+}
+
+grap(from, to)
+register struct ship *from, *to;
+{
+ if (capship(from)->nationality != capship(to)->nationality && die() > 2)
+ return;
+ Write(W_GRAP, from, 0, to->file->index, 0, 0, 0);
+ Write(W_GRAP, to, 0, from->file->index, 0, 0, 0);
+ makesignal(from, "grappled with %s (%c%c)", to);
+}
diff --git a/games/sail/dr_5.c b/games/sail/dr_5.c
new file mode 100644
index 0000000..7e1e3c4
--- /dev/null
+++ b/games/sail/dr_5.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_5.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+subtract(from, totalfrom, crewfrom, fromcap, pcfrom)
+struct ship *from, *fromcap;
+int pcfrom;
+register int totalfrom, crewfrom[3];
+{
+ register int n;
+
+ if (fromcap == from && totalfrom) { /* if not captured */
+ for (n = 0; n < 3; n++) {
+ if (totalfrom > crewfrom[n]) {
+ totalfrom -= crewfrom[n];
+ crewfrom[n] = 0;
+ } else {
+ crewfrom[n] -= totalfrom;
+ totalfrom = 0;
+ }
+ }
+ Write(W_CREW, from, 0, crewfrom[0], crewfrom[1], crewfrom[2], 0);
+ } else if (totalfrom) {
+ pcfrom -= totalfrom;
+ pcfrom = pcfrom < 0 ? 0 : pcfrom;
+ Write(W_PCREW, from, 0, pcfrom, 0, 0, 0);
+ }
+}
+
+mensent(from, to, crew, captured, pc, isdefense)
+struct ship *from, *to, **captured;
+int crew[3], *pc;
+char isdefense;
+{ /* returns # of crew squares sent */
+ int men = 0;
+ register int n;
+ int c1, c2, c3;
+ register struct BP *bp;
+
+ *pc = from->file->pcrew;
+ *captured = from->file->captured;
+ crew[0] = from->specs->crew1;
+ crew[1] = from->specs->crew2;
+ crew[2] = from->specs->crew3;
+ bp = isdefense ? from->file->DBP : from->file->OBP;
+ for (n=0; n < NBP; n++, bp++) {
+ if (bp->turnsent && bp->toship == to)
+ men += bp->mensent;
+ }
+ if (men) {
+ c1 = men/100 ? crew[0] : 0;
+ c2 = (men%100)/10 ? crew[1] : 0;
+ c3 = men/10 ? crew[2] : 0;
+ c3 = *captured == 0 ? crew[2] : *pc;
+ } else
+ c1 = c2 = c3 = 0;
+ return(c1 + c2 + c3);
+}
diff --git a/games/sail/dr_main.c b/games/sail/dr_main.c
new file mode 100644
index 0000000..efaf275
--- /dev/null
+++ b/games/sail/dr_main.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dr_main.c 8.2 (Berkeley) 4/16/94";
+#endif /* not lint */
+
+#include "driver.h"
+
+dr_main()
+{
+ register int n;
+ register struct ship *sp;
+ int nat[NNATION];
+ int value = 0;
+
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ (void) signal(SIGTSTP, SIG_IGN);
+ if (issetuid)
+ (void) setuid(geteuid());
+ if (game < 0 || game >= NSCENE) {
+ fprintf(stderr, "DRIVER: Bad game number %d\n", game);
+ exit(1);
+ }
+ cc = &scene[game];
+ ls = SHIP(cc->vessels);
+ if (sync_open() < 0) {
+ perror("driver: syncfile");
+ exit(1);
+ }
+ for (n = 0; n < NNATION; n++)
+ nat[n] = 0;
+ foreachship(sp) {
+ if (sp->file == NULL &&
+ (sp->file = (struct File *)calloc(1, sizeof (struct File))) == NULL) {
+ (void) fprintf(stderr, "DRIVER: Out of memory.\n");
+ exit(1);
+ }
+ sp->file->index = sp - SHIP(0);
+ sp->file->loadL = L_ROUND;
+ sp->file->loadR = L_ROUND;
+ sp->file->readyR = R_LOADED|R_INITIAL;
+ sp->file->readyL = R_LOADED|R_INITIAL;
+ 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;
+ people = 0;
+ for (;;) {
+ sleep(7);
+ if (Sync() < 0) {
+ value = 1;
+ break;
+ }
+ if (next() < 0)
+ break;
+ unfoul();
+ checkup();
+ prizecheck();
+ moveall();
+ thinkofgrapples();
+ boardcomp();
+ compcombat();
+ resolve();
+ reload();
+ checksails();
+ if (Sync() < 0) {
+ value = 1;
+ break;
+ }
+ }
+ sync_close(1);
+ return value;
+}
diff --git a/games/sail/driver.h b/games/sail/driver.h
new file mode 100644
index 0000000..3a75424
--- /dev/null
+++ b/games/sail/driver.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)driver.h 8.1 (Berkeley) 5/31/93
+ */
+
+#include "externs.h"
+
+int dtab[];
diff --git a/games/sail/externs.h b/games/sail/externs.h
new file mode 100644
index 0000000..4ee8075
--- /dev/null
+++ b/games/sail/externs.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)externs.h 8.1 (Berkeley) 5/31/93
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "machdep.h"
+
+ /* program mode */
+int mode;
+jmp_buf restart;
+#define MODE_PLAYER 1
+#define MODE_DRIVER 2
+#define MODE_LOGGER 3
+
+ /* command line flags */
+char debug; /* -D */
+char randomize; /* -x, give first available ship */
+char longfmt; /* -l, print score in long format */
+char nobells; /* -b, don't ring bell before Signal */
+
+ /* other initial modes */
+char issetuid; /* running setuid */
+
+#define die() ((rand() >> 3) % 6 + 1)
+#define sqr(a) ((a) * (a))
+#define abs(a) ((a) > 0 ? (a) : -(a))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+#define grappled(a) ((a)->file->ngrap)
+#define fouled(a) ((a)->file->nfoul)
+#define snagged(a) (grappled(a) + fouled(a))
+
+#define grappled2(a, b) ((a)->file->grap[(b)->file->index].sn_count)
+#define fouled2(a, b) ((a)->file->foul[(b)->file->index].sn_count)
+#define snagged2(a, b) (grappled2(a, b) + fouled2(a, b))
+
+#define Xgrappled2(a, b) ((a)->file->grap[(b)->file->index].sn_turn < turn-1 ? grappled2(a, b) : 0)
+#define Xfouled2(a, b) ((a)->file->foul[(b)->file->index].sn_turn < turn-1 ? fouled2(a, b) : 0)
+#define Xsnagged2(a, b) (Xgrappled2(a, b) + Xfouled2(a, b))
+
+#define cleangrapple(a, b, c) Cleansnag(a, b, c, 1)
+#define cleanfoul(a, b, c) Cleansnag(a, b, c, 2)
+#define cleansnag(a, b, c) Cleansnag(a, b, c, 3)
+
+#define sterncolour(sp) ((sp)->file->stern+'0'-((sp)->file->captured?10:0))
+#define sternrow(sp) ((sp)->file->row + dr[(sp)->file->dir])
+#define sterncol(sp) ((sp)->file->col + dc[(sp)->file->dir])
+
+#define capship(sp) ((sp)->file->captured?(sp)->file->captured:(sp))
+
+#define readyname(r) ((r) & R_LOADING ? '*' : ((r) & R_INITIAL ? '!' : ' '))
+
+/* loadL and loadR, should match loadname[] */
+#define L_EMPTY 0 /* should be 0, don't change */
+#define L_GRAPE 1
+#define L_CHAIN 2
+#define L_ROUND 3
+#define L_DOUBLE 4
+#define L_EXPLODE 5
+
+/*
+ * readyL and readyR, these are bits, except R_EMPTY
+ */
+#define R_EMPTY 0 /* not loaded and not loading */
+#define R_LOADING 1 /* loading */
+#define R_DOUBLE 2 /* loading double */
+#define R_LOADED 4 /* loaded */
+#define R_INITIAL 8 /* loaded initial */
+
+#define HULL 0
+#define RIGGING 1
+
+#define W_CAPTAIN 1
+#define W_CAPTURED 2
+#define W_CLASS 3
+#define W_CREW 4
+#define W_DBP 5
+#define W_DRIFT 6
+#define W_EXPLODE 7
+#define W_FILE 8
+#define W_FOUL 9
+#define W_GUNL 10
+#define W_GUNR 11
+#define W_HULL 12
+#define W_MOVE 13
+#define W_OBP 14
+#define W_PCREW 15
+#define W_UNFOUL 16
+#define W_POINTS 17
+#define W_QUAL 18
+#define W_UNGRAP 19
+#define W_RIGG 20
+#define W_COL 21
+#define W_DIR 22
+#define W_ROW 23
+#define W_SIGNAL 24
+#define W_SINK 25
+#define W_STRUCK 26
+#define W_TA 27
+#define W_ALIVE 28
+#define W_TURN 29
+#define W_WIND 30
+#define W_FS 31
+#define W_GRAP 32
+#define W_RIG1 33
+#define W_RIG2 34
+#define W_RIG3 35
+#define W_RIG4 36
+#define W_BEGIN 37
+#define W_END 38
+#define W_DDEAD 39
+
+#define NLOG 10
+struct logs {
+ char l_name[20];
+ int l_uid;
+ int l_shipnum;
+ int l_gamenum;
+ int l_netpoints;
+};
+
+struct BP {
+ short turnsent;
+ struct ship *toship;
+ short mensent;
+};
+
+struct snag {
+ short sn_count;
+ short sn_turn;
+};
+
+#define NSCENE nscene
+#define NSHIP 10
+#define NBP 3
+
+#define NNATION 8
+#define N_A 0
+#define N_B 1
+#define N_S 2
+#define N_F 3
+#define N_J 4
+#define N_D 5
+#define N_K 6
+#define N_O 7
+
+struct File {
+ int index;
+ char captain[20]; /* 0 */
+ short points; /* 20 */
+ char loadL; /* 22 */
+ char loadR; /* 24 */
+ char readyL; /* 26 */
+ char readyR; /* 28 */
+ struct BP OBP[NBP]; /* 30 */
+ struct BP DBP[NBP]; /* 48 */
+ char struck; /* 66 */
+ struct ship *captured; /* 68 */
+ short pcrew; /* 70 */
+ char movebuf[10]; /* 72 */
+ char drift; /* 82 */
+ short nfoul;
+ short ngrap;
+ struct snag foul[NSHIP]; /* 84 */
+ struct snag grap[NSHIP]; /* 124 */
+ char RH; /* 224 */
+ char RG; /* 226 */
+ char RR; /* 228 */
+ char FS; /* 230 */
+ char explode; /* 232 */
+ char sink; /* 234 */
+ char dir;
+ short col;
+ short row;
+ char loadwith;
+ char stern;
+};
+
+struct ship {
+ char *shipname; /* 0 */
+ struct shipspecs *specs; /* 2 */
+ char nationality; /* 4 */
+ short shiprow; /* 6 */
+ short shipcol; /* 8 */
+ char shipdir; /* 10 */
+ struct File *file; /* 12 */
+};
+
+struct scenario {
+ char winddir; /* 0 */
+ char windspeed; /* 2 */
+ char windchange; /* 4 */
+ char vessels; /* 12 */
+ char *name; /* 14 */
+ struct ship ship[NSHIP]; /* 16 */
+};
+struct scenario scene[];
+int nscene;
+
+struct shipspecs {
+ char bs;
+ char fs;
+ char ta;
+ short guns;
+ char class;
+ char hull;
+ char qual;
+ char crew1;
+ char crew2;
+ char crew3;
+ char gunL;
+ char gunR;
+ char carL;
+ char carR;
+ char rig1;
+ char rig2;
+ char rig3;
+ char rig4;
+ short pts;
+};
+struct shipspecs specs[];
+
+struct scenario *cc; /* the current scenario */
+struct ship *ls; /* &cc->ship[cc->vessels] */
+
+#define SHIP(s) (&cc->ship[s])
+#define foreachship(sp) for ((sp) = cc->ship; (sp) < ls; (sp)++)
+
+struct windeffects {
+ char A, B, C, D;
+};
+struct windeffects WET[7][6];
+
+struct Tables {
+ char H, G, C, R;
+};
+struct Tables RigTable[11][6];
+struct Tables HullTable[11][6];
+
+char AMMO[9][4];
+char HDT[9][10];
+char HDTrake[9][10];
+char QUAL[9][5];
+char MT[9][3];
+
+char *countryname[];
+char *classname[];
+char *directionname[];
+char *qualname[];
+char loadname[];
+
+char rangeofshot[];
+
+char dr[], dc[];
+
+int winddir;
+int windspeed;
+int turn;
+int game;
+int alive;
+int people;
+char hasdriver;
+
+char *info();
+char *quality();
+double arctan();
+char *saywhat();
+struct ship *closestenemy();
+
+char *calloc();
+char *rindex();
+char *strcpy();
+char *strcat();
+char *strncpy();
+char *getenv();
+char *gets();
diff --git a/games/sail/game.c b/games/sail/game.c
new file mode 100644
index 0000000..bc8a32a
--- /dev/null
+++ b/games/sail/game.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)game.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+maxturns(ship, af)
+register struct ship *ship;
+char *af;
+{
+ register int turns;
+
+ turns = ship->specs->ta;
+ if (*af = (ship->file->drift > 1 && turns)) {
+ turns--;
+ if (ship->file->FS == 1)
+ turns = 0;
+ }
+ return turns;
+}
+
+maxmove(ship, dir, fs)
+register struct ship *ship;
+int dir, fs;
+{
+ register int riggone = 0, Move, flank = 0;
+
+ Move = ship->specs->bs;
+ if (!ship->specs->rig1)
+ riggone++;
+ if (!ship->specs->rig2)
+ riggone++;
+ if (!ship->specs->rig3)
+ riggone++;
+ if (!ship->specs->rig4)
+ riggone++;
+ if ((ship->file->FS || fs) && fs != -1) {
+ flank = 1;
+ Move = ship->specs->fs;
+ }
+ if (dir == winddir)
+ Move -= 1 + WET[windspeed][ship->specs->class-1].B;
+ else if (dir == winddir + 2 || dir == winddir - 2 || dir == winddir - 6 || dir == winddir + 6)
+ Move -= 1 + WET[windspeed][ship->specs->class-1].C;
+ else if (dir == winddir + 3 || dir == winddir - 3 || dir == winddir - 5 || dir == winddir + 5)
+ Move = (flank ? 2 : 1) - WET[windspeed][ship->specs->class-1].D;
+ else if (dir == winddir + 4 || dir == winddir - 4)
+ Move = 0;
+ else
+ Move -= WET[windspeed][ship->specs->class-1].A;
+ Move -= riggone;
+ Move = Move < 0 ? 0 : Move;
+ return(Move);
+}
diff --git a/games/sail/globals.c b/games/sail/globals.c
new file mode 100644
index 0000000..1a7acbe
--- /dev/null
+++ b/games/sail/globals.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)globals.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+struct scenario scene[] = {
+ /*
+ * int winddir;
+ * int windspeed;
+ * int windchange;
+ * int vessels;
+ * char *name;
+ * struct ship ship[NSHIP];
+ */
+ 5, 3, 5, 2, "Ranger vs. Drake",
+ {
+ { "Ranger", specs+0, N_A, 7, 20, 4, 0 },
+ { "Drake", specs+1, N_B, 7, 31, 5, 0 }
+ },
+ 1, 3, 6, 2, "The Battle of Flamborough Head",
+ {
+ { "Bonhomme Rich", specs+2, N_A, 13, 40, 2, 0 },
+ { "Serapis", specs+3, N_B, 2, 42, 2, 0 }
+ },
+ 5, 5, 5, 10, "Arbuthnot and Des Touches",
+ {
+ { "America", specs+4, N_B, 7, 37, 4, 0 },
+ { "Befford", specs+5, N_B, 5, 35, 4, 0 },
+ { "Adamant", specs+6, N_B, 3, 33, 4, 0 },
+ { "London", specs+7, N_B, 1, 31, 4, 0 },
+ { "Royal Oak", specs+8, N_B, -1, 29, 4, 0 },
+ { "Neptune", specs+9, N_F, 6, 44, 4, 0 },
+ { "Duc Bougogne", specs+10, N_F, 8, 46, 4, 0 },
+ { "Conquerant", specs+48, N_F, 10, 48, 4, 0 },
+ { "Provence", specs+11, N_F, 12, 50, 4, 0 },
+ { "Romulus", specs+12, N_F, 20, 58, 4, 0 }
+ },
+ 1, 3, 5, 10, "Suffren and Hughes",
+ {
+ { "Monmouth", specs+52, N_B, 9, 45, 2, 0 },
+ { "Hero", specs+5, N_B, 13, 49, 2, 0 },
+ { "Isis", specs+6, N_B, 12, 48, 2, 0 },
+ { "Superb", specs+50, N_B, 10, 46, 2, 0 },
+ { "Burford", specs+48, N_B, 11, 47, 2, 0 },
+ { "Flamband", specs+13, N_F, 7, 59, 4, 0 },
+ { "Annibal", specs+9, N_F, 4, 56, 4, 0 },
+ { "Severe", specs+11, N_F, 2, 54, 4, 0 },
+ { "Brilliant", specs+49, N_F, -1, 51, 4, 0 },
+ { "Sphinx", specs+51, N_F, -5, 47, 4, 0 }
+ },
+ 1, 3, 4, 2, "Nymphe vs. Cleopatre",
+ {
+ { "Nymphe", specs+14, N_B, 13, 30, 2, 0 },
+ { "Cleopatre", specs+15, N_F, 3, 41, 2, 0 }
+ },
+ 1, 3, 5, 2, "Mars vs. Hercule",
+ {
+ { "Mars", specs+16, N_B, 13, 30, 2, 0 },
+ { "Hercule", specs+17, N_F, 3, 41, 2, 0 }
+ },
+ 5, 3, 5, 2, "Ambuscade vs. Baionnaise",
+ {
+ { "Ambuscade", specs+18, N_B, 13, 30, 2, 0 },
+ { "Baionnaise", specs+19, N_F, 3, 41, 2, 0 }
+ },
+ 1, 5, 6, 2, "Constellation vs. Insurgent",
+ {
+ { "Constellation", specs+20, N_A, 9, 50, 8, 0 },
+ { "Insurgent", specs+22, N_F, 4, 24, 2, 0 }
+ },
+ 1, 3, 5, 2, "Constellation vs. Vengeance",
+ {
+ { "Constellation", specs+20, N_A, 12, 40, 2, 0 },
+ { "Vengeance", specs+21, N_F, 1, 43, 2, 0 }
+ },
+ 1, 3, 6, 10, "The Battle of Lissa",
+ {
+ { "Amphion", specs+23, N_B, 8, 50, 4, 0 },
+ { "Active", specs+24, N_B, 6, 48, 4, 0 },
+ { "Volage", specs+25, N_B, 4, 46, 4, 0 },
+ { "Cerberus", specs+26, N_B, 2, 44, 4, 0 },
+ { "Favorite", specs+27, N_F, 9, 34, 2, 0 },
+ { "Flore", specs+21, N_F, 13, 39, 2, 0 },
+ { "Danae", specs+64, N_F, 15, 37, 2, 0 },
+ { "Bellona", specs+28, N_F, 17, 35, 2, 0 },
+ { "Corona", specs+29, N_F, 12, 31, 2, 0 },
+ { "Carolina", specs+30, N_F, 15, 28, 2, 0 }
+ },
+ 2, 5, 6, 2, "Constitution vs. Guerriere",
+ {
+ { "Constitution", specs+31, N_A, 7, 35, 1, 0 },
+ { "Guerriere", specs+32, N_B, 7, 47, 4, 0 }
+ },
+ 1, 3, 5, 2, "United States vs. Macedonian",
+ {
+ { "United States", specs+33, N_A, 1, 52, 6, 0 },
+ { "Macedonian", specs+34, N_B, 14, 40, 1, 0 }
+ },
+ 1, 3, 6, 2, "Constitution vs. Java",
+ {
+ { "Constitution", specs+31, N_A, 1, 40, 2, 0 },
+ { "Java", specs+35, N_B, 11, 40, 2, 0 }
+ },
+ 1, 3, 5, 2, "Chesapeake vs. Shannon",
+ {
+ { "Chesapeake", specs+36, N_A, 13, 40, 2, 0 },
+ { "Shannon", specs+37, N_B, 1, 42, 2, 0 }
+ },
+ 1, 1, 6, 5, "The Battle of Lake Erie",
+ {
+ { "Lawrence", specs+38, N_A, 4, 55, 8, 0 },
+ { "Niagara", specs+42, N_A, 7, 61, 8, 0 },
+ { "Lady Prevost", specs+39, N_B, 4, 25, 2, 0 },
+ { "Detroit", specs+40, N_B, 7, 22, 2, 0 },
+ { "Q. Charlotte", specs+41, N_B, 10, 19, 2, 0 }
+ },
+ 1, 1, 5, 2, "Wasp vs. Reindeer",
+ {
+ { "Wasp", specs+42, N_A, 3, 41, 2, 0 },
+ { "Reindeer", specs+43, N_B, 10, 48, 2, 0 }
+ },
+ 1, 2, 5, 3, "Constitution vs. Cyane and Levant",
+ {
+ { "Constitution", specs+31, N_A, 10, 45, 2, 0 },
+ { "Cyane", specs+44, N_B, 3, 37, 2, 0 },
+ { "Levant", specs+45, N_B, 5, 35, 2, 0 }
+ },
+ 5, 5, 5, 3, "Pellew vs. Droits de L'Homme",
+ {
+ { "Indefatigable", specs+46, N_B, 12, 45, 6, 0 },
+ { "Amazon", specs+47, N_B, 9, 48, 6, 0 },
+ { "Droits L'Hom", specs+48, N_F, 3, 28, 5, 0 }
+ },
+ 2, 2, 3, 10, "Algeciras",
+ {
+ { "Caesar", specs+49, N_B, 7, 70, 6, 0 },
+ { "Pompee", specs+50, N_B, 5, 72, 6, 0 },
+ { "Spencer", specs+5, N_B, 3, 74, 6, 0 },
+ { "Hannibal", specs+7, N_B, 1, 76, 6, 0 },
+ { "Real-Carlos", specs+53, N_S, 9, 20, 3, 0 },
+ { "San Fernando", specs+54, N_S, 11, 16, 3, 0 },
+ { "Argonauta", specs+55, N_S, 10, 14, 4, 0 },
+ { "San Augustine", specs+56, N_S, 6, 22, 4, 0 },
+ { "Indomptable", specs+51, N_F, 7, 23, 5, 0 },
+ { "Desaix", specs+52, N_F, 7, 27, 7, 0 }
+ },
+ 5, 3, 6, 7, "Lake Champlain",
+ {
+ { "Saratoga", specs+60, N_A, 8, 10, 1, 0 },
+ { "Eagle", specs+61, N_A, 9, 13, 2, 0 },
+ { "Ticonderoga", specs+62, N_A, 12, 17, 3, 0 },
+ { "Preble", specs+63, N_A, 14, 20, 2, 0 },
+ { "Confiance", specs+57, N_B, 4, 70, 6, 0 },
+ { "Linnet", specs+58, N_B, 7, 68, 6, 0 },
+ { "Chubb", specs+59, N_B, 10, 65, 6, 0 }
+ },
+ 5, 3, 6, 4, "Last Voyage of the USS President",
+ {
+ { "President", specs+67, N_A, 12, 42, 5, 0 },
+ { "Endymion", specs+64, N_B, 5, 42, 5, 0 },
+ { "Pomone", specs+65, N_B, 7, 82, 6, 0 },
+ { "Tenedos", specs+66, N_B, 7, -1, 4, 0 }
+ },
+ 7, 5, 5, 2, "Hornblower and the Natividad",
+ {
+ { "Lydia", specs+68, N_B, 12, 40, 2, 0 },
+ { "Natividad", specs+69, N_S, 2, 40, 4, 0 }
+ },
+ 1, 3, 6, 2, "Curse of the Flying Dutchman",
+ {
+ { "Piece of Cake", specs+19, N_S, 7, 40, 2, 0 },
+ { "Flying Dutchy", specs+71, N_F, 7, 41, 1, 0 }
+ },
+ 1, 4, 1, 4, "The South Pacific",
+ {
+ { "USS Scurvy", specs+70, N_A, 7, 40, 1, 0 },
+ { "HMS Tahiti", specs+71, N_B, 12, 60, 1, 0 },
+ { "Australian", specs+18, N_S, 5, 20, 8, 0 },
+ { "Bikini Atoll", specs+63, N_F, 2, 60, 4, 0 }
+ },
+ 7, 3, 6, 5, "Hornblower and the battle of Rosas bay",
+ {
+ { "Sutherland", specs+5, N_B, 13, 30, 2, 0 },
+ { "Turenne", specs+10, N_F, 9, 35, 6, 0 },
+ { "Nightmare", specs+9, N_F, 7, 37, 6, 0 },
+ { "Paris", specs+53, N_F, 3, 45, 4, 0 },
+ { "Napolean", specs+56, N_F, 1, 40, 6, 0 }
+ },
+ 6, 4, 7, 5, "Cape Horn",
+ {
+ { "Concord", specs+51, N_A, 3, 20, 4, 0 },
+ { "Berkeley", specs+7, N_A, 5, 50, 5, 0 },
+ { "Thames", specs+71, N_B, 10, 40, 1, 0 },
+ { "Madrid", specs+53, N_S, 13, 60, 8, 0 },
+ { "Musket", specs+10, N_F, 10, 60, 7, 0 }
+ },
+ 8, 3, 7, 3, "New Orleans",
+ {
+ { "Alligator", specs+71, N_A, 13, 5, 1, 0 },
+ { "Firefly", specs+50, N_B, 10, 20, 8, 0 },
+ { "Cypress", specs+46, N_B, 5, 10, 6, 0 }
+ },
+ 5, 3, 7, 3, "Botany Bay",
+ {
+ { "Shark", specs+11, N_B, 6, 15, 4, 0 },
+ { "Coral Snake", specs+31, N_F, 3, 30, 6, 0 },
+ { "Sea Lion", specs+33, N_F, 13, 50, 8, 0 }
+ },
+ 4, 3, 6, 4, "Voyage to the Bottom of the Sea",
+ {
+ { "Seaview", specs+71, N_A, 6, 3, 3, 0 },
+ { "Flying Sub", specs+64, N_A, 8, 3, 3, 0 },
+ { "Mermaid", specs+70, N_B, 2, 5, 5, 0 },
+ { "Giant Squid", specs+53, N_S, 10, 30, 8, 0 }
+ },
+ 7, 3, 6, 3, "Frigate Action",
+ {
+ { "Killdeer", specs+21, N_A, 7, 20, 8, 0 },
+ { "Sandpiper", specs+27, N_B, 5, 40, 8, 0 },
+ { "Curlew", specs+34, N_S, 10, 60, 8, 0 }
+ },
+ 7, 2, 5, 6, "The Battle of Midway",
+ {
+ { "Enterprise", specs+49, N_A, 10, 70, 8, 0 },
+ { "Yorktown", specs+51, N_A, 3, 70, 7, 0 },
+ { "Hornet", specs+52, N_A, 6, 70, 7, 0 },
+ { "Akagi", specs+53, N_J, 6, 10, 4, 0 },
+ { "Kaga", specs+54, N_J, 4, 12, 4, 0 },
+ { "Soryu", specs+55, N_J, 2, 14, 4, 0 }
+ },
+ 1, 3, 4, 8, "Star Trek",
+ {
+ { "Enterprise", specs+76, N_D,-10, 60, 7, 0 },
+ { "Yorktown", specs+77, N_D, 0, 70, 7, 0 },
+ { "Reliant", specs+78, N_D, 10, 70, 7, 0 },
+ { "Galileo", specs+79, N_D, 20, 60, 7, 0 },
+ { "Kobayashi Maru", specs+80, N_K, 0,120, 7, 0 },
+ { "Klingon II", specs+81, N_K, 10,120, 7, 0 },
+ { "Red Orion", specs+82, N_O, 0, 0, 3, 0 },
+ { "Blue Orion", specs+83, N_O, 10, 0, 3, 0 }
+ }
+};
+int nscene = sizeof scene / sizeof (struct scenario);
+
+struct shipspecs specs[] = {
+/* bs fs ta guns hull crew1 crew3 gunR carR rig2 rig4 pts */
+/* class qual crew2 gunL carL rig1 rig3 */
+/*00*/ 4, 7, 3, 19, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*01*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 0, 0, 4, 4, 3, 3, 3, 3, 6,
+/*02*/ 3, 5, 2, 42, 4, 7, 4, 2, 2, 2, 2, 2, 0, 0, 5, 5, 5, -1, 11,
+/*03*/ 4, 6, 3, 44, 3, 7, 4, 2, 2, 2, 3, 3, 0, 0, 5, 5, 5, 5, 12,
+/*04*/ 3, 5, 2, 64, 2, 17, 4, 8, 6, 6, 12, 12, 2, 2, 7, 7, 7, -1, 20,
+/*05*/ 3, 5, 2, 74, 2, 20, 4, 8, 8, 8, 16, 16, 2, 2, 7, 7, 7, -1, 26,
+/*06*/ 3, 5, 2, 50, 2, 12, 4, 6, 4, 4, 8, 8, 2, 2, 6, 6, 6, -1, 17,
+/*07*/ 3, 5, 1, 98, 1, 23, 4, 10, 10, 10, 18, 18, 2, 2, 8, 8, 8, -1, 28,
+/*08*/ 3, 5, 2, 74, 2, 20, 4, 8, 8, 8, 16, 16, 2, 2, 7, 7, 7, -1, 26,
+/*09*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 0, 0, 7, 7, 7, -1, 24,
+/*10*/ 3, 5, 1, 80, 1, 23, 3, 12, 12, 10, 22, 22, 0, 0, 7, 7, 7, -1, 27,
+/*11*/ 3, 5, 2, 64, 2, 18, 3, 8, 8, 6, 12, 12, 0, 0, 7, 7, 7, -1, 18,
+/*12*/ 3, 5, 2, 44, 2, 11, 3, 4, 4, 4, 6, 6, 2, 2, 5, 5, 5, -1, 10,
+/*13*/ 3, 5, 2, 50, 2, 14, 3, 6, 6, 4, 8, 8, 0, 0, 6, 6, 6, -1, 14,
+/*14*/ 4, 6, 3, 36, 3, 11, 4, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 11,
+/*15*/ 4, 6, 3, 36, 3, 11, 3, 4, 4, 4, 4, 4, 2, 2, 5, 5, 5, 5, 10,
+/*16*/ 3, 5, 2, 74, 2, 21, 4, 10, 8, 8, 18, 18, 2, 2, 7, 7, 7, -1, 26,
+/*17*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 2, 2, 7, 7, 7, -1, 23,
+/*18*/ 4, 6, 3, 32, 3, 8, 3, 4, 2, 2, 4, 4, 2, 2, 5, 5, 5, 5, 9,
+/*19*/ 4, 6, 3, 24, 4, 6, 3, 4, 4, 4, 2, 2, 0, 0, 4, 4, 4, 4, 9,
+/*20*/ 4, 7, 3, 38, 4, 14, 5, 6, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5, 17,
+/*21*/ 4, 6, 3, 40, 3, 15, 3, 8, 6, 6, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*22*/ 4, 7, 3, 36, 4, 11, 3, 6, 6, 4, 4, 4, 2, 2, 5, 5, 5, 5, 11,
+/*23*/ 4, 6, 3, 32, 3, 11, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*24*/ 4, 6, 3, 38, 3, 14, 5, 4, 4, 4, 6, 6, 4, 4, 5, 5, 5, 5, 18,
+/*25*/ 4, 6, 3, 22, 3, 6, 5, 2, 2, 2, 0, 0, 8, 8, 4, 4, 4, 4, 11,
+/*26*/ 4, 6, 3, 32, 3, 11, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*27*/ 4, 6, 3, 40, 3, 14, 3, 6, 6, 4, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*28*/ 4, 6, 3, 32, 3, 11, 2, 4, 4, 4, 4, 4, 0, 0, 5, 5, 5, 5, 9,
+/*29*/ 4, 6, 3, 40, 3, 14, 2, 6, 6, 4, 6, 6, 4, 4, 5, 5, 5, 5, 12,
+/*30*/ 4, 6, 3, 32, 3, 8, 2, 4, 4, 1, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*31*/ 4, 7, 3, 44, 4, 18, 5, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 6, 24,
+/*32*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 2, 6, 6, 4, 4, 5, 5, 5, 5, 15,
+/*33*/ 4, 5, 3, 44, 3, 18, 5, 8, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 24,
+/*34*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 4, 6, 6, 4, 4, 5, 5, 5, 5, 16,
+/*35*/ 4, 7, 3, 38, 4, 14, 4, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 19,
+/*36*/ 4, 6, 3, 38, 3, 14, 3, 6, 6, 4, 6, 6, 6, 6, 5, 5, 5, 5, 14,
+/*37*/ 4, 6, 3, 38, 3, 14, 5, 6, 4, 4, 6, 6, 6, 6, 5, 5, 5, 5, 17,
+/*38*/ 4, 7, 3, 20, 5, 6, 4, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*39*/ 4, 7, 3, 13, 6, 3, 4, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 5,
+/*40*/ 4, 7, 3, 19, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 4, 4, 4, 4, 7,
+/*41*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 2, 2, 0, 0, 3, 3, 3, 3, 6,
+/*42*/ 4, 7, 3, 20, 5, 6, 5, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 12,
+/*43*/ 4, 7, 3, 18, 5, 5, 5, 2, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*44*/ 4, 7, 3, 24, 5, 6, 4, 4, 2, 2, 0, 0,10,10, 4, 4, 4, 4, 11,
+/*45*/ 4, 7, 3, 20, 5, 6, 4, 2, 2, 2, 0, 0, 8, 8, 4, 4, 4, 4, 10,
+/*46*/ 4, 6, 3, 44, 3, 11, 5, 4, 4, 4, 4, 4, 2, 2, 5, 5, 5, 5, 14,
+/*47*/ 4, 6, 3, 36, 3, 12, 4, 4, 4, 4, 6, 6, 2, 2, 5, 5, 5, 5, 14,
+/*48*/ 3, 5, 2, 74, 2, 21, 3, 10, 8, 8, 20, 20, 2, 2, 4, 4, 7, -1, 24,
+/*49*/ 3, 5, 2, 80, 2, 24, 4, 10, 8, 8, 20, 20, 2, 2, 8, 8, 8, -1, 31,
+/*50*/ 3, 5, 2, 74, 2, 21, 4, 8, 8, 6, 16, 16, 4, 4, 7, 7, 7, -1, 27,
+/*51*/ 3, 5, 2, 80, 2, 24, 3, 12, 12, 10, 22, 22, 2, 2, 7, 7, 7, -1, 27,
+/*52*/ 3, 5, 2, 74, 2, 21, 3, 10, 10, 8, 20, 20, 2, 2, 7, 7, 7, -1, 24,
+/*53*/ 3, 5, 1, 112, 1, 27, 2, 12, 12, 12, 24, 24, 0, 0, 9, 9, 9, -1, 27,
+/*54*/ 3, 5, 1, 96, 1, 24, 2, 12, 12, 10, 20, 20, 0, 0, 8, 8, 8, -1, 24,
+/*55*/ 3, 5, 2, 80, 2, 23, 2, 10, 10, 8, 20, 20, 0, 0, 7, 7, 7, -1, 23,
+/*56*/ 3, 5, 2, 74, 2, 21, 2, 10, 8, 8, 16, 16, 4, 4, 7, 7, 7, -1, 20,
+/*57*/ 4, 6, 3, 37, 3, 12, 4, 4, 4, 2, 6, 6, 4, 4, 5, 5, 5, 5, 14,
+/*58*/ 4, 7, 3, 16, 5, 5, 5, 2, 2, 2, 0, 0, 4, 4, 4, 4, 4, 4, 10,
+/*59*/ 4, 7, 3, 11, 6, 3, 4, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 5,
+/*60*/ 4, 7, 3, 26, 5, 6, 4, 4, 2, 2, 2, 2, 6, 6, 4, 4, 4, 4, 12,
+/*61*/ 4, 7, 3, 20, 5, 6, 4, 4, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 11,
+/*62*/ 4, 7, 3, 17, 5, 5, 4, 2, 2, 2, 0, 0, 6, 6, 4, 4, 4, 4, 9,
+/*63*/ 4, 7, 3, 7, 6, 3, 4, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 4,
+/*64*/ 4, 6, 3, 40, 3, 15, 4, 4, 4, 4, 8, 8, 6, 6, 5, 5, 5, 5, 17,
+/*65*/ 4, 6, 3, 44, 3, 15, 4, 8, 8, 6, 10, 10, 2, 2, 6, 6, 6, 6, 20,
+/*66*/ 4, 6, 3, 38, 3, 14, 4, 4, 4, 4, 6, 6, 6, 6, 5, 5, 5, 5, 15,
+/*67*/ 4, 5, 3, 44, 3, 18, 5, 8, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 24,
+/*68*/ 4, 6, 3, 36, 3, 9, 5, 4, 4, 2, 4, 4, 2, 2, 5, 5, 5, 5, 13,
+/*69*/ 3, 5, 2, 50, 2, 14, 2, 6, 6, 6, 8, 8, 0, 0, 6, 6, 6, -1, 14,
+/*70*/ 3, 5, 1, 136, 1, 30, 1, 8, 14, 14, 28, 28, 0, 0, 9, 9, 9, -1, 27,
+/*71*/ 3, 5, 1, 120, 1, 27, 5, 16, 14, 14, 28, 28, 2, 2, 9, 9, 9, -1, 43,
+/*72*/ 3, 5, 1, 120, 2, 21, 5, 15, 17, 15, 25, 25, 7, 7, 9, 9, 9, -1, 36,
+/*73*/ 3, 5, 1, 90, 3, 18, 4, 13, 15, 13, 20, 20, 6, 6, 5, 5, 5, 5, 28,
+/*74*/ 4, 7, 3, 6, 6, 3, 4, 2, 2, 2, 20, 20, 6, 6, 2, 2, 3, 3, 5,
+/*75*/ 3, 5, 1, 110, 2, 20, 4, 14, 15, 11, 26, 26, 8, 8, 7, 8, 9, -1, 34,
+/*76*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*77*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*78*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*79*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*80*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*81*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*82*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/*83*/ 4, 7, 3, 450, 1, 99, 5, 50, 40, 40, 50, 50,25,25, 9, 9, 9, -1, 75,
+/* bs fs ta guns hull crew1 crew3 gunR carR rig2 rig4 pts */
+/* class qual crew2 gunL carL rig1 rig3 */
+};
+
+struct windeffects WET[7][6] = {
+ { {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9}, {9,9,9,9} },
+ { {3,2,2,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {2,1,0,0}, {2,1,0,0} },
+ { {1,1,1,0}, {1,1,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} },
+ { {0,0,0,0}, {1,0,0,0}, {1,1,0,0}, {1,1,0,0}, {2,2,1,0}, {2,2,1,0} },
+ { {1,0,0,0}, {1,1,0,0}, {1,1,1,0}, {1,1,1,0}, {3,2,2,0}, {3,2,2,0} },
+ { {2,1,1,0}, {3,2,1,0}, {3,2,1,0}, {3,2,1,0}, {3,3,2,0}, {3,3,2,0} }
+};
+
+struct Tables RigTable[11][6] = {
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,1}, {0,0,1,0}, {1,0,0,1}, {0,1,1,1} },
+ { {0,0,0,0}, {0,0,0,1}, {0,0,1,1}, {0,1,0,1}, {0,1,0,1}, {1,0,1,2} },
+ { {0,0,0,0}, {0,0,1,1}, {0,1,0,1}, {0,0,0,2}, {0,1,0,2}, {1,0,1,2} },
+ { {0,1,0,1}, {1,0,0,1}, {0,1,1,2}, {0,1,0,2}, {0,0,1,3}, {1,0,1,4} },
+ { {0,0,1,1}, {0,1,0,2}, {1,0,0,3}, {0,1,1,3}, {1,0,0,4}, {1,1,1,4} },
+ { {0,0,1,2}, {0,1,1,2}, {1,1,0,3}, {0,1,0,4}, {1,0,0,4}, {1,0,1,5} },
+ { {0,0,1,2}, {0,1,0,3}, {1,1,0,3}, {1,0,2,4}, {0,2,1,5}, {2,1,0,5} },
+ { {0,2,1,3}, {1,0,0,3}, {2,1,0,4}, {0,1,1,4}, {0,1,0,5}, {1,0,2,6} },
+ { {1,1,0,4}, {1,0,1,4}, {2,0,0,5}, {0,2,1,5}, {0,1,2,6}, {0,2,0,7} },
+ { {1,0,1,5}, {0,2,0,6}, {1,2,0,6}, {1,1,1,6}, {2,0,2,6}, {1,1,2,7} }
+};
+struct Tables HullTable[11][6] = {
+ { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,0,0,0}, {0,1,0,0} },
+ { {0,0,0,0}, {0,0,0,0}, {0,1,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1} },
+ { {0,1,0,0}, {1,0,0,0}, {1,1,0,0}, {1,0,1,0}, {1,0,1,1}, {2,1,0,0} },
+ { {0,1,1,0}, {1,0,0,0}, {1,1,1,0}, {2,0,0,1}, {2,0,1,0}, {2,2,0,0} },
+ { {0,1,1,0}, {1,0,0,1}, {2,1,0,1}, {2,2,1,0}, {3,0,1,0}, {3,1,0,0} },
+ { {1,1,1,0}, {2,0,2,1}, {2,1,1,0}, {2,2,0,0}, {3,1,0,1}, {3,1,1,0} },
+ { {1,2,2,0}, {2,0,2,1}, {2,1,0,1}, {2,2,0,0}, {3,1,1,0}, {4,2,1,0} },
+ { {2,1,1,0}, {2,0,1,1}, {3,2,2,0}, {3,2,0,0}, {4,2,1,0}, {4,2,1,1} },
+ { {2,1,2,0}, {3,1,1,1}, {3,2,2,0}, {4,2,1,0}, {4,1,0,2}, {4,2,2,0} },
+ { {2,3,1,0}, {3,2,2,0}, {3,2,2,1}, {4,2,2,0}, {4,1,0,3}, {5,1,2,0} },
+ { {2,2,4,0}, {3,3,1,1}, {4,2,1,1}, {5,1,0,2}, {5,1,2,1}, {6,2,2,0} },
+};
+
+char AMMO[9][4] = {
+ { -1, 1, 0, 1 },
+ { -1, 1, 0, 1 },
+ { -1, 1, 0, 1 },
+ { -2, 1, 0, 2 },
+ { -2, 2, 0, 2 },
+ { -2, 2, 0, 2 },
+ { -3, 2, 0, 2 },
+ { -3, 2, 0, 3 },
+ { -3, 2, 0, 3 }
+};
+
+char HDT[9][10] = {
+ { 1, 0,-1,-2,-3,-3,-4,-4,-4,-4 },
+ { 1, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 4, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 4, 4, 3, 2, 1, 1, 0, 0, 0, 0 },
+ { 5, 4, 3, 2, 1, 1, 0, 0, 0, 0 }
+};
+
+char HDTrake[9][10] = {
+ { 2, 1, 0,-1,-2,-2,-3,-3,-3,-3 },
+ { 2, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 3, 2, 1, 0,-1,-1,-2,-2,-2,-2 },
+ { 4, 3, 2, 1, 0, 0,-1,-1,-1,-1 },
+ { 5, 4, 3, 2, 1, 1, 0, 0, 0, 0 },
+ { 6, 5, 4, 3, 2, 2, 1, 1, 1, 1 },
+ { 7, 6, 5, 4, 3, 3, 2, 2, 2, 2 },
+ { 8, 7, 6, 5, 4, 4, 3, 3, 3, 3 },
+ { 9, 8, 7, 6, 5, 5, 4, 4, 4, 4 }
+};
+
+char QUAL[9][5] = {
+ { -1, 0, 0, 1, 1 },
+ { -1, 0, 0, 1, 1 },
+ { -1, 0, 0, 1, 2 },
+ { -1, 0, 0, 1, 2 },
+ { -1, 0, 0, 2, 2 },
+ { -1,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 2 },
+ { -2,-1, 0, 2, 3 }
+};
+
+char MT[9][3] = {
+ { 1, 0, 0 },
+ { 1, 1, 0 },
+ { 2, 1, 0 },
+ { 2, 1, 1 },
+ { 2, 2, 1 },
+ { 3, 2, 1 },
+ { 3, 2, 2 },
+ { 4, 3, 2 },
+ { 4, 4, 2 }
+};
+
+char rangeofshot[] = {
+ 0,
+ 1, /* grape */
+ 3, /* chain */
+ 10, /* round */
+ 1 /* double */
+};
+
+char *countryname[] = {
+ "American", "British", "Spanish", "French", "Japanese",
+ "Federation", "Klingon", "Orion"
+};
+
+char *classname[] = {
+ "Drift wood",
+ "Ship of the Line",
+ "Ship of the Line",
+ "Frigate",
+ "Corvette",
+ "Sloop",
+ "Brig"
+};
+
+char *directionname[] = {
+ "dead ahead",
+ "off the starboard bow",
+ "off the starboard beam",
+ "off the starboard quarter",
+ "dead astern",
+ "off the port quarter",
+ "off the port beam",
+ "off the port bow",
+ "dead ahead"
+};
+
+char *qualname[] = { "dead", "mutinous", "green", "mundane", "crack", "elite" };
+
+char loadname[] = { '-', 'G', 'C', 'R', 'D', 'E' };
+
+char dr[] = { 0, 1, 1, 0, -1, -1, -1, 0, 1 };
+char dc[] = { 0, 0, -1, -1, -1, 0, 1, 1, 1 };
diff --git a/games/sail/lo_main.c b/games/sail/lo_main.c
new file mode 100644
index 0000000..0194211
--- /dev/null
+++ b/games/sail/lo_main.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lo_main.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+/*
+ * Print out the top ten SAILors
+ *
+ * -l force a long listing (print out real usernames)
+ */
+#include <sys/types.h>
+#include <pwd.h>
+#include "externs.h"
+#include "pathnames.h"
+
+char *title[] = {
+ "Admiral", "Commodore", "Captain", "Captain",
+ "Captain", "Captain", "Captain", "Commander",
+ "Commander", "Lieutenant"
+};
+
+lo_main()
+{
+ FILE *fp;
+ char sbuf[32];
+ int n = 0, people;
+ struct passwd *pass;
+ struct logs log;
+ struct ship *ship;
+
+ if ((fp = fopen(_PATH_LOGFILE, "r")) == 0) {
+ perror(_PATH_LOGFILE);
+ exit(1);
+ }
+ switch (fread((char *)&people, sizeof people, 1, fp)) {
+ case 0:
+ printf("Nobody has sailed yet.\n");
+ exit(0);
+ case 1:
+ break;
+ default:
+ perror(_PATH_LOGFILE);
+ exit(1);
+ }
+ while (fread((char *)&log, sizeof log, 1, fp) == 1 &&
+ log.l_name[0] != '\0') {
+ if (longfmt && (pass = getpwuid(log.l_uid)) != NULL)
+ (void) sprintf(sbuf, "%10.10s (%s)",
+ log.l_name, pass->pw_name);
+ else
+ (void) sprintf(sbuf, "%20.20s", log.l_name);
+ ship = &scene[log.l_gamenum].ship[log.l_shipnum];
+ printf("%-10s %21s of the %15s %3d points, %5.2f equiv\n",
+ title[n++], sbuf, ship->shipname, log.l_netpoints,
+ (float) log.l_netpoints / ship->specs->pts);
+ }
+ printf("\n%d people have played.\n", people);
+ return 0;
+}
diff --git a/games/sail/machdep.h b/games/sail/machdep.h
new file mode 100644
index 0000000..148da5d
--- /dev/null
+++ b/games/sail/machdep.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)machdep.h 8.1 (Berkeley) 5/31/93
+ */
+
+#define TIMEOUT 300 /* Sync() timeout in seconds */
+
+/* for 4.2bsd machines */
+#define blockalarm() ((void) sigblock(1 << SIGALRM-1))
+#define unblockalarm() ((void) sigsetmask(sigblock(0) & ~(1 << SIGALRM-1)))
+
+/* for 2.9bsd machines (onyx)
+typedef int void;
+#define blockalarm() ((void) sighold(SIGALRM))
+#define unblockalarm() ((void) sigrelse(SIGALRM))
+*/
diff --git a/games/sail/main.c b/games/sail/main.c
new file mode 100644
index 0000000..4c59f26
--- /dev/null
+++ b/games/sail/main.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+/*ARGSUSED*/
+main(argc, argv)
+ int argc;
+ register char **argv;
+{
+ register char *p;
+ int i;
+
+ (void) srand(getpid());
+ issetuid = getuid() != geteuid();
+ if (p = rindex(*argv, '/'))
+ p++;
+ else
+ p = *argv;
+ if (strcmp(p, "driver") == 0 || strcmp(p, "saildriver") == 0)
+ mode = MODE_DRIVER;
+ else if (strcmp(p, "sail.log") == 0)
+ mode = MODE_LOGGER;
+ else
+ mode = MODE_PLAYER;
+ while ((p = *++argv) && *p == '-')
+ switch (p[1]) {
+ case 'd':
+ mode = MODE_DRIVER;
+ break;
+ case 's':
+ mode = MODE_LOGGER;
+ break;
+ case 'D':
+ debug++;
+ break;
+ case 'x':
+ randomize;
+ break;
+ case 'l':
+ longfmt++;
+ break;
+ case 'b':
+ nobells++;
+ break;
+ default:
+ fprintf(stderr, "SAIL: Unknown flag %s.\n", p);
+ exit(1);
+ }
+ if (*argv)
+ game = atoi(*argv);
+ else
+ game = -1;
+ if (i = setjmp(restart))
+ mode = i;
+ switch (mode) {
+ case MODE_PLAYER:
+ return pl_main();
+ case MODE_DRIVER:
+ return dr_main();
+ case MODE_LOGGER:
+ return lo_main();
+ default:
+ fprintf(stderr, "SAIL: Unknown mode %d.\n", mode);
+ abort();
+ }
+ /*NOTREACHED*/
+}
diff --git a/games/sail/misc.c b/games/sail/misc.c
new file mode 100644
index 0000000..29e7899
--- /dev/null
+++ b/games/sail/misc.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+#include "pathnames.h"
+
+#define distance(x,y) (abs(x) >= abs(y) ? abs(x) + abs(y)/2 : abs(y) + abs(x)/2)
+
+/* XXX */
+range(from, to)
+struct ship *from, *to;
+{
+ register bow1r, bow1c, bow2r, bow2c;
+ int stern1r, stern1c, stern2c, stern2r;
+ register int bb, bs, sb, ss, result;
+
+ if (!to->file->dir)
+ return -1;
+ stern1r = bow1r = from->file->row;
+ stern1c = bow1c = from->file->col;
+ stern2r = bow2r = to->file->row;
+ stern2c = bow2c = to->file->col;
+ result = bb = distance(bow2r - bow1r, bow2c - bow1c);
+ if (bb < 5) {
+ stern2r += dr[to->file->dir];
+ stern2c += dc[to->file->dir];
+ stern1r += dr[from->file->dir];
+ stern1c += dc[from->file->dir];
+ bs = distance((bow2r - stern1r), (bow2c - stern1c));
+ sb = distance((bow1r - stern2r), (bow1c - stern2c));
+ ss = distance((stern2r - stern1r) ,(stern2c - stern1c));
+ result = min(bb, min(bs, min(sb, ss)));
+ }
+ return result;
+}
+
+struct ship *
+closestenemy(from, side, anyship)
+register struct ship *from;
+char side, anyship;
+{
+ register struct ship *sp;
+ register char a;
+ int olddist = 30000, dist;
+ struct ship *closest = 0;
+
+ a = capship(from)->nationality;
+ foreachship(sp) {
+ if (sp == from)
+ continue;
+ if (sp->file->dir == 0)
+ continue;
+ if (a == capship(sp)->nationality && !anyship)
+ continue;
+ if (side && gunsbear(from, sp) != side)
+ continue;
+ dist = range(from, sp);
+ if (dist < olddist) {
+ closest = sp;
+ olddist = dist;
+ }
+ }
+ return closest;
+}
+
+angle(dr, dc)
+register dr, dc;
+{
+ register i;
+
+ if (dc >= 0 && dr > 0)
+ i = 0;
+ else if (dr <= 0 && dc > 0)
+ i = 2;
+ else if (dc <= 0 && dr < 0)
+ i = 4;
+ else
+ i = 6;
+ dr = abs(dr);
+ dc = abs(dc);
+ if ((i == 0 || i == 4) && dc * 2.4 > dr) {
+ i++;
+ if (dc > dr * 2.4)
+ i++;
+ } else if ((i == 2 || i == 6) && dr * 2.4 > dc) {
+ i++;
+ if (dr > dc * 2.4)
+ i++;
+ }
+ return i % 8 + 1;
+}
+
+gunsbear(from, to) /* checks for target bow or stern */
+register struct ship *from, *to;
+{
+ int Dr, Dc, i;
+ register ang;
+
+ Dr = from->file->row - to->file->row;
+ Dc = to->file->col - from->file->col;
+ for (i = 2; i; i--) {
+ if ((ang = angle(Dr, Dc) - from->file->dir + 1) < 1)
+ ang += 8;
+ if (ang >= 2 && ang <= 4)
+ return 'r';
+ if (ang >= 6 && ang <= 7)
+ return 'l';
+ Dr += dr[to->file->dir];
+ Dc += dc[to->file->dir];
+ }
+ return 0;
+}
+
+portside(from, on, quick)
+register struct ship *from, *on;
+int quick; /* returns true if fromship is */
+{ /* shooting at onship's starboard side */
+ register ang;
+ register Dr, Dc;
+
+ Dr = from->file->row - on->file->row;
+ Dc = on->file->col - from->file->col;
+ if (quick == -1) {
+ Dr += dr[on->file->dir];
+ Dc += dc[on->file->dir];
+ }
+ ang = angle(Dr, Dc);
+ if (quick != 0)
+ return ang;
+ ang = (ang + 4 - on->file->dir - 1) % 8 + 1;
+ return ang < 5;
+}
+
+colours(sp)
+register struct ship *sp;
+{
+ register char flag;
+
+ if (sp->file->struck)
+ flag = '!';
+ if (sp->file->explode)
+ flag = '#';
+ if (sp->file->sink)
+ flag = '~';
+ if (sp->file->struck)
+ return flag;
+ flag = *countryname[capship(sp)->nationality];
+ return sp->file->FS ? flag : tolower(flag);
+}
+
+#include <sys/file.h>
+log(s)
+register struct ship *s;
+{
+ FILE *fp;
+ int persons;
+ int n;
+ struct logs log[NLOG];
+ float net;
+ register struct logs *lp;
+
+ if ((fp = fopen(_PATH_LOGFILE, "r+")) == NULL)
+ return;
+#ifdef LOCK_EX
+ if (flock(fileno(fp), LOCK_EX) < 0)
+ return;
+#endif
+ net = (float)s->file->points / s->specs->pts;
+ persons = getw(fp);
+ n = fread((char *)log, sizeof(struct logs), NLOG, fp);
+ for (lp = &log[n]; lp < &log[NLOG]; lp++)
+ lp->l_name[0] = lp->l_uid = lp->l_shipnum
+ = lp->l_gamenum = lp->l_netpoints = 0;
+ rewind(fp);
+ if (persons < 0)
+ (void) putw(1, fp);
+ else
+ (void) putw(persons + 1, fp);
+ for (lp = log; lp < &log[NLOG]; lp++)
+ if (net > (float)lp->l_netpoints
+ / scene[lp->l_gamenum].ship[lp->l_shipnum].specs->pts) {
+ (void) fwrite((char *)log,
+ sizeof (struct logs), lp - log, fp);
+ (void) strcpy(log[NLOG-1].l_name, s->file->captain);
+ log[NLOG-1].l_uid = getuid();
+ log[NLOG-1].l_shipnum = s->file->index;
+ log[NLOG-1].l_gamenum = game;
+ log[NLOG-1].l_netpoints = s->file->points;
+ (void) fwrite((char *)&log[NLOG-1],
+ sizeof (struct logs), 1, fp);
+ (void) fwrite((char *)lp,
+ sizeof (struct logs), &log[NLOG-1] - lp, fp);
+ break;
+ }
+#ifdef LOCK_EX
+ (void) flock(fileno(fp), LOCK_UN);
+#endif
+ (void) fclose(fp);
+}
diff --git a/games/sail/parties.c b/games/sail/parties.c
new file mode 100644
index 0000000..c6151e38
--- /dev/null
+++ b/games/sail/parties.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)parties.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+
+meleeing(from, to)
+struct ship *from;
+register struct ship *to;
+{
+ register struct BP *p = from->file->OBP;
+ register struct BP *q = p + NBP;
+
+ for (; p < q; p++)
+ if (p->turnsent && p->toship == to)
+ return 1;
+ return 0;
+}
+
+boarding(from, isdefense)
+register struct ship *from;
+char isdefense;
+{
+ register struct BP *p = isdefense ? from->file->DBP : from->file->OBP;
+ register struct BP *q = p + NBP;
+
+ for (; p < q; p++)
+ if (p->turnsent)
+ return 1;
+ return 0;
+}
+
+unboard(ship, to, isdefense)
+register struct ship *ship, *to;
+register char isdefense;
+{
+ register struct BP *p = isdefense ? ship->file->DBP : ship->file->OBP;
+ register n;
+
+ for (n = 0; n < NBP; p++, n++)
+ if (p->turnsent && (p->toship == to || isdefense || ship == to))
+ Write(isdefense ? W_DBP : W_OBP, ship, 0, n, 0, 0, 0);
+}
diff --git a/games/sail/pathnames.h b/games/sail/pathnames.h
new file mode 100644
index 0000000..03a1dc7
--- /dev/null
+++ b/games/sail/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 5/31/93
+ */
+
+#define _PATH_LOGFILE "/var/games/saillog"
diff --git a/games/sail/pl_1.c b/games/sail/pl_1.c
new file mode 100644
index 0000000..4687b1f
--- /dev/null
+++ b/games/sail/pl_1.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_1.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "player.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+
+/*
+ * 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);
+}
+
+void
+choke()
+{
+ leave(LEAVE_QUIT);
+}
+
+void
+child()
+{
+ union wait status;
+ int pid;
+
+ (void) signal(SIGCHLD, SIG_IGN);
+ do {
+ pid = wait3((int *)&status, WNOHANG, (struct rusage *)0);
+ if (pid < 0 || pid > 0 && !WIFSTOPPED(status))
+ hasdriver = 0;
+ } while (pid > 0);
+ (void) signal(SIGCHLD, child);
+}
diff --git a/games/sail/pl_2.c b/games/sail/pl_2.c
new file mode 100644
index 0000000..ad2c477
--- /dev/null
+++ b/games/sail/pl_2.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_2.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#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;
+ }
+ }
+}
diff --git a/games/sail/pl_3.c b/games/sail/pl_3.c
new file mode 100644
index 0000000..3aee8b9
--- /dev/null
+++ b/games/sail/pl_3.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_3.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#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);
+ }
+ }
+}
diff --git a/games/sail/pl_4.c b/games/sail/pl_4.c
new file mode 100644
index 0000000..0553146
--- /dev/null
+++ b/games/sail/pl_4.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_4.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#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]);
+ }
+}
diff --git a/games/sail/pl_5.c b/games/sail/pl_5.c
new file mode 100644
index 0000000..7be6e79
--- /dev/null
+++ b/games/sail/pl_5.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_5.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#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);
+ }
+}
diff --git a/games/sail/pl_6.c b/games/sail/pl_6.c
new file mode 100644
index 0000000..4daaa59
--- /dev/null
+++ b/games/sail/pl_6.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_6.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#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;
+ }
+}
diff --git a/games/sail/pl_7.c b/games/sail/pl_7.c
new file mode 100644
index 0000000..6a20737
--- /dev/null
+++ b/games/sail/pl_7.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_7.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include <sys/ttydefaults.h>
+#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);
+ 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();
+ }
+}
+
+void
+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) {
+ (void)sprintf(buf, p, ship->shipname, colours(ship),
+ sterncolour(ship));
+ p = buf;
+ }
+ 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;
+}
diff --git a/games/sail/pl_main.c b/games/sail/pl_main.c
new file mode 100644
index 0000000..7b1f457
--- /dev/null
+++ b/games/sail/pl_main.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pl_main.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "player.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+
+void choke(), child();
+
+/*ARGSUSED*/
+pl_main()
+{
+
+ if (!SCREENTEST()) {
+ printf("Can't sail on this terminal.\n");
+ exit(1);
+ }
+ initialize();
+ Signal("Aye aye, Sir", (struct ship *)0);
+ play();
+ return 0; /* for lint, play() never returns */
+}
+
+initialize()
+{
+ 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 (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) {
+ if (sp->file == NULL &&
+ (sp->file = (struct File *)calloc(1, sizeof (struct File))) == NULL) {
+ (void) puts("OUT OF MEMORY");
+ exit(1);
+ }
+ 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)
+ switch (fork()) {
+ case 0:
+ longjmp(restart, MODE_DRIVER);
+ /*NOTREACHED*/
+ 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();
+}
diff --git a/games/sail/player.h b/games/sail/player.h
new file mode 100644
index 0000000..8051b72
--- /dev/null
+++ b/games/sail/player.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)player.h 8.1 (Berkeley) 5/31/93
+ */
+
+#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
diff --git a/games/sail/sail.6 b/games/sail/sail.6
new file mode 100644
index 0000000..e1cf4cb
--- /dev/null
+++ b/games/sail/sail.6
@@ -0,0 +1,896 @@
+.\" Copyright (c) 1988, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sail.6 8.2 (Berkeley) 12/30/93
+.\"
+.TH SAIL 6 "December 30, 1993"
+.UC 4
+.SH NAME
+sail \- multi-user wooden ships and iron men
+.SH SYNOPSIS
+.B sail
+[
+.B \-s
+[
+.B \-l
+] ] [
+.B \-x
+] [
+.B \-b
+] [
+.B num
+]
+.br
+.fi
+.SH DESCRIPTION
+.I Sail
+is a computer version of Avalon Hill's game of fighting sail
+originally developed by S. Craig Taylor.
+.PP
+Players of
+.I Sail
+take command of an old fashioned Man of War and fight other
+players or the computer. They may re-enact one of the many
+historical sea battles recorded in the game, or they can choose
+a fictional battle.
+.PP
+As a sea captain in the
+.I Sail
+Navy, the player has complete control over the workings of his ship.
+He must order every maneuver, change the set of his sails, and judge the
+right moment to let loose the terrible destruction of his broadsides.
+In addition to fighting the enemy, he must harness the powers of the wind
+and sea to make them work for him. The outcome of many battles during the
+age of sail was decided by the ability of one captain to hold the `weather
+gage.'
+.PP
+The flags are:
+.TP
+.B \-s
+Print the names and ships of the top ten sailors.
+.TP
+.B \-l
+Show the login name. Only effective with \fB-s\fP.
+.TP
+.B \-x
+Play the first available ship instead of prompting for a choice.
+.TP
+.B \-b
+No bells.
+.SH IMPLEMENTATION
+.I Sail
+is really two programs in one. Each player starts up a process which
+runs his own ship. In addition, a
+.I driver
+process is forked (by the first player) to run the computer ships
+and take care of global bookkeeping.
+.PP
+Because the
+.I driver
+must calculate moves for each ship it controls, the
+more ships the computer is playing, the slower the game will appear.
+.PP
+If a player joins a game in progress, he will synchronize
+with the other players (a rather slow process for everyone), and
+then he may play along with the rest.
+.PP
+To implement a multi-user game in Version 7 UNIX, which was the operating
+system
+.I Sail
+was first written under, the communicating processes must use a common
+temporary file as a place to read and write messages. In addition, a
+locking mechanism must be provided to ensure exclusive access to the
+shared file. For example,
+.I Sail
+uses a temporary file named /tmp/#sailsink.21 for scenario 21, and
+corresponding file names for the other scenarios. To provide exclusive
+access to the temporary file,
+.I Sail
+uses a technique stolen from an old game called "pubcaves" by Jeff Cohen.
+Processes do a busy wait in the loop
+.br
+.sp
+.ce 2
+ for (n = 0; link(sync_file, sync_lock) < 0 && n < 30; n++)
+ sleep(2);
+.br
+.sp
+until they are able to create a link to a file named "/tmp/#saillock.??".
+The "??" correspond to the scenario number of the game. Since UNIX
+guarantees that a link will point to only one file, the process that succeeds
+in linking will have exclusive access to the temporary file.
+.PP
+Whether or not this really works is open to speculation. When ucbmiro
+was rebooted after a crash, the file system check program found 3 links
+between the
+.I Sail
+temporary file and its link file.
+.SH CONSEQUENCES OF SEPARATE PLAYER AND DRIVER PROCESSES
+When players do something of global interest, such as moving or firing,
+the driver must coordinate the action with the other ships in the game.
+For example, if a player wants to move in a certain direction, he writes a
+message into the temporary file requesting the driver to move his ship.
+Each ``turn,'' the driver reads all the messages sent from the players and
+decides what happened. It then writes back into the temporary file new
+values of variables, etc.
+.PP
+The most noticeable effect this communication has on the game is the
+delay in moving. Suppose a player types a move for his ship and hits
+return. What happens then? The player process saves up messages to
+be written to the temporary file in a buffer. Every 7 seconds or so, the
+player process gets exclusive access to the temporary file and writes
+out its buffer to the file. The driver, running asynchronously, must
+read in the movement command, process it, and write out the results. This
+takes two exclusive accesses to the temporary file. Finally, when the player
+process gets around to doing another 7 second update, the results of the
+move are displayed on the screen. Hence, every movement requires four
+exclusive accesses to the temporary file (anywhere from 7 to 21 seconds
+depending upon asynchrony) before the player sees the results of his moves.
+.PP
+In practice, the delays are not as annoying as they would appear. There
+is room for "pipelining" in the movement. After the player writes out
+a first movement message, a second movement command can then be issued.
+The first message will be in the temporary file waiting for the driver, and
+the second will be in the file buffer waiting to be written to the file.
+Thus, by always typing moves a turn ahead of the time, the player can
+sail around quite quickly.
+.PP
+If the player types several movement commands between two 7 second updates,
+only the last movement command typed will be seen by the driver. Movement
+commands within the same update "overwrite" each other, in a sense.
+.SH THE HISTORY OF SAIL
+I wrote the first version of
+.I Sail
+on a PDP 11/70 in the fall of 1980. Needless to say, the code was horrendous,
+not portable in any sense of the word, and didn't work. The program was not
+very modular and had fseeks() and fwrites() every few lines. After a
+tremendous rewrite from the top down, I got the first working version up by
+1981. There were several annoying bugs concerning firing broadsides and
+finding angles.
+.I Sail
+uses no floating point, by the way, so the direction routines are rather
+tricky.
+Ed Wang rewrote my angle() routine in 1981 to be more correct (although
+it still doesn't work perfectly), and he added code to let a player select
+which ship he wanted at the start of the game (instead of the first one
+available).
+.PP
+Captain Happy (Craig Leres) is responsible for making
+.I Sail
+portable for the first time. This was no easy task, by the way. Constants
+like 2 and 10 were very frequent in the code. I also became famous for
+using "Riggle Memorial Structures" in
+.I Sail.
+Many of my structure references are so long that they run off the line
+printer page. Here is an example, if you promise not to laugh.
+.br
+.sp
+.ce
+specs[scene[flog.fgamenum].ship[flog.fshipnum].shipnum].pts
+.br
+.sp
+.PP
+.I Sail
+received its fourth and most thorough rewrite in the summer and fall
+of 1983. Ed Wang rewrote and modularized the code (a monumental feat)
+almost from scratch. Although he introduced many new bugs, the final
+result was very much cleaner and (?) faster. He added window movement
+commands and find ship commands.
+.SH HISTORICAL INFO
+Old Square Riggers were very maneuverable ships capable of intricate
+sailing. Their only disadvantage was an inability to sail very
+close to the wind. The design of a wooden ship allowed only for the
+guns to bear to the left and right sides. A few guns of small
+aspect (usually 6 or 9 pounders) could point forward, but their
+effect was small compared to a 68 gun broadside of 24 or 32 pounders.
+The guns bear approximately like so:
+.nf
+
+ \\
+ b----------------
+ ---0
+ \\
+ \\
+ \\ up to a range of ten (for round shot)
+ \\
+ \\
+ \\
+
+.fi
+An interesting phenomenon occurred when a broadside was fired
+down the length of an enemy ship. The shot tended to bounce along
+the deck and did several times more damage. This phenomenon was called
+a rake. Because the bows of a ship are very strong and present a smaller
+target than the stern, a stern rake (firing from the stern to the bow) causes
+more damage than a bow rake.
+.nf
+
+ b
+ 00 ---- Stern rake!
+ a
+
+.fi
+Most ships were equipped with carronades, which were very large, close
+range cannons. American ships from the revolution until the War of 1812
+were almost entirely armed with carronades.
+.PP
+The period of history covered in
+.I Sail
+is approximately from the 1770's until the end of Napoleonic France in 1815.
+There are many excellent books about the age of sail. My favorite author
+is Captain Frederick Marryat. More contemporary authors include C.S. Forester
+and Alexander Kent.
+.PP
+Fighting ships came in several sizes classed by armament. The mainstays of
+any fleet were its "Ships of the Line", or "Line of Battle Ships". They
+were so named because these ships fought together in great lines. They were
+close enough for mutual support, yet every ship could fire both its broadsides.
+We get the modern words "ocean liner," or "liner," and "battleship" from
+"ship of the line." The most common size was the the 74 gun two decked
+ship of the line. The two gun decks usually mounted 18 and 24 pounder guns.
+.PP
+The pride of the fleet were the first rates. These were huge three decked
+ships of the line mounting 80 to 136 guns. The guns in the three tiers
+were usually 18, 24, and 32 pounders in that order from top to bottom.
+.PP
+Various other ships came next. They were almost all "razees," or ships
+of the line with one deck sawed off. They mounted 40-64 guns and were
+a poor cross between a frigate and a line of battle ship. They neither
+had the speed of the former nor the firepower of the latter.
+.PP
+Next came the "eyes of the fleet." Frigates came in many sizes mounting
+anywhere from 32 to 44 guns. They were very handy vessels. They could
+outsail anything bigger and outshoot anything smaller. Frigates didn't
+fight in lines of battle as the much bigger 74's did. Instead, they
+harassed the enemy's rear or captured crippled ships. They were much
+more useful in missions away from the fleet, such as cutting out expeditions
+or boat actions. They could hit hard and get away fast.
+.PP
+Lastly, there were the corvettes, sloops, and brigs. These were smaller
+ships mounting typically fewer than 20 guns. A corvette was only slightly
+smaller than a frigate, so one might have up to 30 guns. Sloops were used
+for carrying dispatches or passengers. Brigs were something you built for
+land-locked lakes.
+.SH SAIL PARTICULARS
+Ships in
+.I Sail
+are represented by two characters. One character represents the bow of
+the ship, and the other represents the stern. Ships have nationalities
+and numbers. The first ship of a nationality is number 0, the second
+number 1, etc. Therefore, the first British ship in a game would be
+printed as "b0". The second Brit would be "b1", and the fifth Don
+would be "s4".
+.PP
+Ships can set normal sails, called Battle Sails, or bend on extra canvas
+called Full Sails. A ship under full sail is a beautiful sight indeed,
+and it can move much faster than a ship under Battle Sails. The only
+trouble is, with full sails set, there is so much tension on sail and
+rigging that a well aimed round shot can burst a sail into ribbons where
+it would only cause a little hole in a loose sail. For this reason,
+rigging damage is doubled on a ship with full sails set. Don't let
+that discourage you from using full sails. I like to keep them up
+right into the heat of battle. A ship
+with full sails set has a capital letter for its nationality. E.g.,
+a Frog, "f0", with full sails set would be printed as "F0".
+.PP
+When a ship is battered into a listing hulk, the last man aboard "strikes
+the colors." This ceremony is the ship's formal surrender. The nationality
+character
+of a surrendered ship is printed as "!". E.g., the Frog of our last example
+would soon be "!0".
+.PP
+A ship has a random chance of catching fire or sinking when it reaches the
+stage of listing hulk. A sinking ship has a "~" printed for its nationality,
+and a ship on fire and about to explode has a "#" printed.
+.PP
+Captured ships become the nationality of the prize crew. Therefore, if
+an American ship captures a British ship, the British ship will have an
+"a" printed for its nationality. In addition, the ship number is changed
+to "&","'", "(", ,")", "*", or "+" depending upon the original number,
+be it 0,1,2,3,4, or 5. E.g., the "b0" captured by an American becomes the
+"a&". The "s4" captured by a Frog becomes the "f*".
+.PP
+The ultimate example is, of course, an exploding Brit captured by an
+American: "#&".
+.SH MOVEMENT
+Movement is the most confusing part of
+.I Sail
+to many. Ships can head in 8 directions:
+.nf
+
+ 0 0 0
+ b b b0 b b b 0b b
+ 0 0 0
+
+.fi
+The stern of a ship moves when it turns. The bow remains stationary.
+Ships can always turn, regardless of the wind (unless they are becalmed).
+All ships drift when they lose headway. If a ship doesn't move forward
+at all for two turns, it will begin to drift. If a ship has begun to
+drift, then it must move forward before it turns, if it plans to do
+more than make a right or left turn, which is always possible.
+.PP
+Movement commands to
+.I Sail
+are a string of forward moves and turns. An example is "l3". It will
+turn a ship left and then move it ahead 3 spaces. In the drawing above,
+the "b0" made 7 successive left turns. When
+.I Sail
+prompts you for a move, it prints three characters of import. E.g.,
+.nf
+ move (7, 4):
+.fi
+The first number is the maximum number of moves you can make,
+including turns. The second number is the maximum number of turns
+you can make. Between the numbers is sometimes printed a quote "'".
+If the quote is present, it means that your ship has been drifting, and
+you must move ahead to regain headway before you turn (see note above).
+Some of the possible moves for the example above are as follows:
+.nf
+
+ move (7, 4): 7
+ move (7, 4): 1
+ move (7, 4): d /* drift, or do nothing */
+ move (7, 4): 6r
+ move (7, 4): 5r1
+ move (7, 4): 4r1r
+ move (7, 4): l1r1r2
+ move (7, 4): 1r1r1r1
+
+.fi
+Because square riggers performed so poorly sailing into the wind, if at
+any point in a movement command you turn into the wind, the movement stops
+there. E.g.,
+.nf
+
+ move (7, 4): l1l4
+ Movement Error;
+ Helm: l1l
+
+.fi
+Moreover, whenever you make a turn, your movement allowance drops to
+min(what's left, what you would have at the new attitude). In short,
+if you turn closer to the wind, you most likely won't be able to sail the
+full allowance printed in the "move" prompt.
+.PP
+Old sailing captains had to keep an eye constantly on the wind. Captains
+in
+.I Sail
+are no different. A ship's ability to move depends on its attitude to the
+wind. The best angle possible is to have the wind off your quarter, that is,
+just off the stern. The direction rose on the side of the screen gives the
+possible movements for your ship at all positions to the wind. Battle
+sail speeds are given first, and full sail speeds are given in parenthesis.
+.nf
+
+ 0 1(2)
+ \\|/
+ -^-3(6)
+ /|\\
+ | 4(7)
+ 3(6)
+
+.fi
+Pretend the bow of your ship (the "^") is pointing upward and the wind is
+blowing from the bottom to the top of the page. The
+numbers at the bottom "3(6)" will be your speed under battle or full
+sails in such a situation. If the wind is off your quarter, then you
+can move "4(7)". If the wind is off your beam, "3(6)". If the wind is
+off your bow, then you can only move "1(2)". Facing into the wind, you
+can't move at all. Ships facing into the wind were said to be "in irons".
+.SH WINDSPEED AND DIRECTION
+The windspeed and direction is displayed as a little weather vane on the
+side of the screen. The number in the middle of the vane indicates the wind
+speed, and the + to - indicates the wind direction. The wind blows from
+the + sign (high pressure) to the - sign (low pressure). E.g.,
+.nf
+
+ |
+ 3
+ +
+
+.fi
+.PP
+The wind speeds are 0 = becalmed, 1 = light breeze, 2 = moderate breeze,
+3 = fresh breeze, 4 = strong breeze, 5 = gale, 6 = full gale, 7 = hurricane.
+If a hurricane shows up, all ships are destroyed.
+.SH GRAPPLING AND FOULING
+If two ships collide, they run the risk of becoming tangled together. This
+is called "fouling." Fouled ships are stuck together, and neither can move.
+They can unfoul each other if they want to. Boarding parties can only be
+sent across to ships when the antagonists are either fouled or grappled.
+.PP
+Ships can grapple each other by throwing grapnels into the rigging of
+the other.
+.PP
+The number of fouls and grapples you have are displayed on the upper
+right of the screen.
+.SH BOARDING
+Boarding was a very costly venture in terms of human life. Boarding parties
+may be formed in
+.I Sail
+to either board an enemy ship or to defend your own ship against attack.
+Men organized as Defensive Boarding Parties fight twice as hard to save
+their ship as men left unorganized.
+.PP
+The boarding strength of a crew depends upon its quality and upon the
+number of men sent.
+.SH CREW QUALITY
+The British seaman was world renowned for his sailing abilities. American
+sailors, however, were actually the best seamen in the world. Because the
+American Navy offered twice the wages of the Royal Navy, British seamen
+who liked the sea defected to America by the thousands.
+.PP
+In
+.I Sail,
+crew quality is quantized into 5 energy levels. "Elite" crews can outshoot
+and outfight all other sailors. "Crack" crews are next. "Mundane" crews
+are average, and "Green" and "Mutinous" crews are below average. A good
+rule of thumb is that "Crack" or "Elite" crews get one extra hit
+per broadside compared to "Mundane" crews. Don't expect too much from
+"Green" crews.
+.SH BROADSIDES
+Your two broadsides may be loaded with four kinds of shot: grape, chain,
+round, and double. You have guns and carronades in both the port and starboard
+batteries. Carronades only have a range of two, so you have to get in
+close to be able to fire them. You have the choice of firing at the hull
+or rigging of another ship. If the range of the ship is greater than 6,
+then you may only shoot at the rigging.
+.PP
+The types of shot and their advantages are:
+.SH ROUND
+Range of 10. Good for hull or rigging hits.
+.SH DOUBLE
+Range of 1. Extra good for hull or rigging hits.
+Double takes two turns to load.
+.SH CHAIN
+Range of 3. Excellent for tearing down rigging.
+Cannot damage hull or guns, though.
+.SH GRAPE
+Range of 1. Sometimes devastating against enemy crews.
+.PP
+On the side of the screen is displayed some vital information about your
+ship:
+.nf
+
+ Load D! R!
+ Hull 9
+ Crew 4 4 2
+ Guns 4 4
+ Carr 2 2
+ Rigg 5 5 5 5
+
+.fi
+"Load" shows what your port (left) and starboard (right) broadsides are
+loaded with. A "!" after the type of shot indicates that it is an initial
+broadside. Initial broadside were loaded with care before battle and before
+the decks ran red with blood. As a consequence, initial broadsides are a
+little more effective than broadsides loaded later. A "*" after the type of
+shot indicates that the gun
+crews are still loading it, and you cannot fire yet. "Hull" shows how much
+hull you have left. "Crew" shows your three sections of crew. As your
+crew dies off, your ability to fire decreases. "Guns" and "Carr" show
+your port and starboard guns. As you lose guns, your ability to fire
+decreases. "Rigg" shows how much rigging you have on your 3 or 4 masts.
+As rigging is shot away, you lose mobility.
+.SH EFFECTIVENESS OF FIRE
+It is very dramatic when a ship fires its thunderous broadsides, but the
+mere opportunity to fire them does not guarantee any hits. Many factors
+influence the destructive force of a broadside. First of all, and the chief
+factor, is distance. It is harder to hit a ship at range ten than it is
+to hit one sloshing alongside. Next is raking. Raking fire, as
+mentioned before,
+can sometimes dismast a ship at range ten. Next, crew size and quality affects
+the damage done by a broadside. The number of guns firing also bears on the
+point,
+so to speak. Lastly, weather affects the accuracy of a broadside. If the
+seas are high (5 or 6), then the lower gunports of ships of the line can't
+even be opened to run out the guns. This gives frigates and other flush
+decked vessels an advantage in a storm. The scenario
+.I Pellew vs. The Droits de L'Homme
+takes advantage of this peculiar circumstance.
+.SH REPAIRS
+Repairs may be made to your Hull, Guns, and Rigging at the slow rate of
+two points per three turns. The message "Repairs Completed" will be
+printed if no more repairs can be made.
+.SH PECULIARITIES OF COMPUTER SHIPS
+Computer ships in
+.I Sail
+follow all the rules above with a few exceptions. Computer ships never
+repair damage. If they did, the players could never beat them. They
+play well enough as it is. As a consolation, the computer ships can fire double
+shot every turn. That fluke is a good reason to keep your distance. The
+.I
+Driver
+figures out the moves of the computer ships. It computes them with a typical
+A.I. distance function and a depth first search to find the maximum "score."
+It seems to work fairly well, although I'll be the first to admit it isn't
+perfect.
+.SH HOW TO PLAY
+Commands are given to
+.I Sail
+by typing a single character. You will then be prompted for further
+input. A brief summary of the commands follows.
+.br
+.SH COMMAND SUMMARY
+.nf
+
+ 'f' Fire broadsides if they bear
+ 'l' Reload
+ 'L' Unload broadsides (to change ammo)
+ 'm' Move
+ 'i' Print the closest ship
+ 'I' Print all ships
+ 'F' Find a particular ship or ships (e.g. "a?" for all Americans)
+ 's' Send a message around the fleet
+ 'b' Attempt to board an enemy ship
+ 'B' Recall boarding parties
+ 'c' Change set of sail
+ 'r' Repair
+ 'u' Attempt to unfoul
+ 'g' Grapple/ungrapple
+ 'v' Print version number of game
+ '^L' Redraw screen
+ 'Q' Quit
+
+ 'C' Center your ship in the window
+ 'U' Move window up
+ 'D','N' Move window down
+ 'H' Move window left
+ 'J' Move window right
+ 'S' Toggle window to follow your ship or stay where it is
+
+.fi
+.bg
+.SH SCENARIOS
+Here is a summary of the scenarios in
+.I Sail:
+
+.br
+.SH Ranger vs. Drake:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) Ranger 19 gun Sloop (crack crew) (7 pts)
+(b) Drake 17 gun Sloop (crack crew) (6 pts)
+.SH The Battle of Flamborough Head:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+.fi
+This is John Paul Jones' first famous battle. Aboard the Bonhomme
+Richard, he was able to overcome the Serapis's greater firepower
+by quickly boarding her.
+.nf
+
+(a) Bonhomme Rich 42 gun Corvette (crack crew) (11 pts)
+(b) Serapis 44 gun Frigate (crack crew) (12 pts)
+.SH Arbuthnot and Des Touches:
+.nf
+Wind from the N, blowing a gale.
+
+(b) America 64 gun Ship of the Line (crack crew) (20 pts)
+(b) Befford 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Adamant 50 gun Ship of the Line (crack crew) (17 pts)
+(b) London 98 gun 3 Decker SOL (crack crew) (28 pts)
+(b) Royal Oak 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Neptune 74 gun Ship of the Line (average crew) (24 pts)
+(f) Duc de Bourgogne 80 gun 3 Decker SOL (average crew) (27 pts)
+(f) Conquerant 74 gun Ship of the Line (average crew) (24 pts)
+(f) Provence 64 gun Ship of the Line (average crew) (18 pts)
+(f) Romulus 44 gun Ship of the Line (average crew) (10 pts)
+.SH Suffren and Hughes:
+.nf
+
+Wind from the S, blowing a fresh breeze.
+
+(b) Monmouth 74 gun Ship of the Line (average crew) (24 pts)
+(b) Hero 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Isis 50 gun Ship of the Line (crack crew) (17 pts)
+(b) Superb 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Burford 74 gun Ship of the Line (average crew) (24 pts)
+(f) Flamband 50 gun Ship of the Line (average crew) (14 pts)
+(f) Annibal 74 gun Ship of the Line (average crew) (24 pts)
+(f) Severe 64 gun Ship of the Line (average crew) (18 pts)
+(f) Brilliant 80 gun Ship of the Line (crack crew) (31 pts)
+(f) Sphinx 80 gun Ship of the Line (average crew) (27 pts)
+.SH Nymphe vs. Cleopatre:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(b) Nymphe 36 gun Frigate (crack crew) (11 pts)
+(f) Cleopatre 36 gun Frigate (average crew) (10 pts)
+.SH Mars vs. Hercule:
+Wind from the S, blowing a fresh breeze.
+.nf
+(b) Mars 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Hercule 74 gun Ship of the Line (average crew) (23 pts)
+.SH Ambuscade vs. Baionnaise:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(b) Ambuscade 32 gun Frigate (average crew) (9 pts)
+(f) Baionnaise 24 gun Corvette (average crew) (9 pts)
+.SH Constellation vs. Insurgent:
+.nf
+Wind from the S, blowing a gale.
+
+(a) Constellation 38 gun Corvette (elite crew) (17 pts)
+(f) Insurgent 36 gun Corvette (average crew) (11 pts)
+.SH Constellation vs. Vengeance:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Constellation 38 gun Corvette (elite crew) (17 pts)
+(f) Vengeance 40 gun Frigate (average crew) (15 pts)
+.SH The Battle of Lissa:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(b) Amphion 32 gun Frigate (elite crew) (13 pts)
+(b) Active 38 gun Frigate (elite crew) (18 pts)
+(b) Volage 22 gun Frigate (elite crew) (11 pts)
+(b) Cerberus 32 gun Frigate (elite crew) (13 pts)
+(f) Favorite 40 gun Frigate (average crew) (15 pts)
+(f) Flore 40 gun Frigate (average crew) (15 pts)
+(f) Danae 40 gun Frigate (crack crew) (17 pts)
+(f) Bellona 32 gun Frigate (green crew) (9 pts)
+(f) Corona 40 gun Frigate (green crew) (12 pts)
+(f) Carolina 32 gun Frigate (green crew) (7 pts)
+.SH Constitution vs. Guerriere:
+.nf
+Wind from the SW, blowing a gale.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Guerriere 38 gun Frigate (crack crew) (15 pts)
+.SH United States vs. Macedonian:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) United States 44 gun Frigate (elite crew) (24 pts)
+(b) Macedonian 38 gun Frigate (crack crew) (16 pts)
+.SH Constitution vs. Java:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Java 38 gun Corvette (crack crew) (19 pts)
+.SH Chesapeake vs. Shannon:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Chesapeake 38 gun Frigate (average crew) (14 pts)
+(b) Shannon 38 gun Frigate (elite crew) (17 pts)
+.SH The Battle of Lake Erie:
+.nf
+Wind from the S, blowing a light breeze.
+
+(a) Lawrence 20 gun Sloop (crack crew) (9 pts)
+(a) Niagara 20 gun Sloop (elite crew) (12 pts)
+(b) Lady Prevost 13 gun Brig (crack crew) (5 pts)
+(b) Detroit 19 gun Sloop (crack crew) (7 pts)
+(b) Q. Charlotte 17 gun Sloop (crack crew) (6 pts)
+.SH Wasp vs. Reindeer:
+.nf
+Wind from the S, blowing a light breeze.
+
+(a) Wasp 20 gun Sloop (elite crew) (12 pts)
+(b) Reindeer 18 gun Sloop (elite crew) (9 pts)
+.SH Constitution vs. Cyane and Levant:
+.br
+Wind from the S, blowing a moderate breeze.
+
+(a) Constitution 44 gun Corvette (elite crew) (24 pts)
+(b) Cyane 24 gun Sloop (crack crew) (11 pts)
+(b) Levant 20 gun Sloop (crack crew) (10 pts)
+.br
+.SH Pellew vs. Droits de L'Homme:
+.nf
+Wind from the N, blowing a gale.
+
+(b) Indefatigable 44 gun Frigate (elite crew) (14 pts)
+(b) Amazon 36 gun Frigate (crack crew) (14 pts)
+(f) Droits L'Hom 74 gun Ship of the Line (average crew) (24 pts)
+.SH Algeciras:
+.nf
+Wind from the SW, blowing a moderate breeze.
+
+(b) Caesar 80 gun Ship of the Line (crack crew) (31 pts)
+(b) Pompee 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Spencer 74 gun Ship of the Line (crack crew) (26 pts)
+(b) Hannibal 98 gun 3 Decker SOL (crack crew) (28 pts)
+(s) Real-Carlos 112 gun 3 Decker SOL (green crew) (27 pts)
+(s) San Fernando 96 gun 3 Decker SOL (green crew) (24 pts)
+(s) Argonauta 80 gun Ship of the Line (green crew) (23 pts)
+(s) San Augustine 74 gun Ship of the Line (green crew) (20 pts)
+(f) Indomptable 80 gun Ship of the Line (average crew) (27 pts)
+(f) Desaix 74 gun Ship of the Line (average crew) (24 pts)
+.SH Lake Champlain:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) Saratoga 26 gun Sloop (crack crew) (12 pts)
+(a) Eagle 20 gun Sloop (crack crew) (11 pts)
+(a) Ticonderoga 17 gun Sloop (crack crew) (9 pts)
+(a) Preble 7 gun Brig (crack crew) (4 pts)
+(b) Confiance 37 gun Frigate (crack crew) (14 pts)
+(b) Linnet 16 gun Sloop (elite crew) (10 pts)
+(b) Chubb 11 gun Brig (crack crew) (5 pts)
+.SH Last Voyage of the USS President:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(a) President 44 gun Frigate (elite crew) (24 pts)
+(b) Endymion 40 gun Frigate (crack crew) (17 pts)
+(b) Pomone 44 gun Frigate (crack crew) (20 pts)
+(b) Tenedos 38 gun Frigate (crack crew) (15 pts)
+.SH Hornblower and the Natividad:
+.nf
+Wind from the E, blowing a gale.
+
+.fi
+A scenario for you Horny fans. Remember, he sank the Natividad
+against heavy odds and winds. Hint: don't try to board the Natividad,
+her crew is much bigger, albeit green.
+.nf
+
+(b) Lydia 36 gun Frigate (elite crew) (13 pts)
+(s) Natividad 50 gun Ship of the Line (green crew) (14 pts)
+.SH Curse of the Flying Dutchman:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+Just for fun, take the Piece of cake.
+
+(s) Piece of Cake 24 gun Corvette (average crew) (9 pts)
+(f) Flying Dutchy 120 gun 3 Decker SOL (elite crew) (43 pts)
+.SH The South Pacific:
+.nf
+Wind from the S, blowing a strong breeze.
+
+(a) USS Scurvy 136 gun 3 Decker SOL (mutinous crew) (27 pts)
+(b) HMS Tahiti 120 gun 3 Decker SOL (elite crew) (43 pts)
+(s) Australian 32 gun Frigate (average crew) (9 pts)
+(f) Bikini Atoll 7 gun Brig (crack crew) (4 pts)
+.SH Hornblower and the battle of Rosas bay:
+.nf
+Wind from the E, blowing a fresh breeze.
+
+The only battle Hornblower ever lost. He was able to dismast one
+ship and stern rake the others though. See if you can do as well.
+.nf
+
+(b) Sutherland 74 gun Ship of the Line (crack crew) (26 pts)
+(f) Turenne 80 gun 3 Decker SOL (average crew) (27 pts)
+(f) Nightmare 74 gun Ship of the Line (average crew) (24 pts)
+(f) Paris 112 gun 3 Decker SOL (green crew) (27 pts)
+(f) Napoleon 74 gun Ship of the Line (green crew) (20 pts)
+.SH Cape Horn:
+.nf
+Wind from the NE, blowing a strong breeze.
+
+(a) Concord 80 gun Ship of the Line (average crew) (27 pts)
+(a) Berkeley 98 gun 3 Decker SOL (crack crew) (28 pts)
+(b) Thames 120 gun 3 Decker SOL (elite crew) (43 pts)
+(s) Madrid 112 gun 3 Decker SOL (green crew) (27 pts)
+(f) Musket 80 gun 3 Decker SOL (average crew) (27 pts)
+.SH New Orleans:
+.nf
+Wind from the SE, blowing a fresh breeze.
+
+Watch that little Cypress go!
+
+(a) Alligator 120 gun 3 Decker SOL (elite crew) (43 pts)
+(b) Firefly 74 gun Ship of the Line (crack crew) (27 pts)
+(b) Cypress 44 gun Frigate (elite crew) (14 pts)
+.SH Botany Bay:
+.nf
+Wind from the N, blowing a fresh breeze.
+
+(b) Shark 64 gun Ship of the Line (average crew) (18 pts)
+(f) Coral Snake 44 gun Corvette (elite crew) (24 pts)
+(f) Sea Lion 44 gun Frigate (elite crew) (24 pts)
+.SH Voyage to the Bottom of the Sea:
+.nf
+Wind from the NW, blowing a fresh breeze.
+
+This one is dedicated to Richard Basehart and David Hedison.
+
+(a) Seaview 120 gun 3 Decker SOL (elite crew) (43 pts)
+(a) Flying Sub 40 gun Frigate (crack crew) (17 pts)
+(b) Mermaid 136 gun 3 Decker SOL (mutinous crew) (27 pts)
+(s) Giant Squid 112 gun 3 Decker SOL (green crew) (27 pts)
+.SH Frigate Action:
+.nf
+Wind from the E, blowing a fresh breeze.
+
+(a) Killdeer 40 gun Frigate (average crew) (15 pts)
+(b) Sandpiper 40 gun Frigate (average crew) (15 pts)
+(s) Curlew 38 gun Frigate (crack crew) (16 pts)
+.SH The Battle of Midway:
+.nf
+Wind from the E, blowing a moderate breeze.
+
+(a) Enterprise 80 gun Ship of the Line (crack crew) (31 pts)
+(a) Yorktown 80 gun Ship of the Line (average crew) (27 pts)
+(a) Hornet 74 gun Ship of the Line (average crew) (24 pts)
+(j) Akagi 112 gun 3 Decker SOL (green crew) (27 pts)
+(j) Kaga 96 gun 3 Decker SOL (green crew) (24 pts)
+(j) Soryu 80 gun Ship of the Line (green crew) (23 pts)
+
+.SH Star Trek:
+.nf
+Wind from the S, blowing a fresh breeze.
+
+(a) Enterprise 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Yorktown 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Reliant 450 gun Ship of the Line (elite crew) (75 pts)
+(a) Galileo 450 gun Ship of the Line (elite crew) (75 pts)
+(k) Kobayashi Maru 450 gun Ship of the Line (elite crew) (75 pts)
+(k) Klingon II 450 gun Ship of the Line (elite crew) (75 pts)
+(o) Red Orion 450 gun Ship of the Line (elite crew) (75 pts)
+(o) Blue Orion 450 gun Ship of the Line (elite crew) (75 pts)
+
+.SH CONCLUSION
+
+.I Sail
+has been a group effort.
+
+.SH AUTHOR
+Dave Riggle
+.SH CO-AUTHOR
+Ed Wang
+.SH REFITTING
+Craig Leres
+.SH CONSULTANTS
+.nf
+Chris Guthrie
+Captain Happy
+Horatio Nelson
+ and many valiant others...
+.fi
+.SH "REFERENCES"
+.nf
+Wooden Ships & Iron Men, by Avalon Hill
+Captain Horatio Hornblower Novels, (13 of them) by C.S. Forester
+Captain Richard Bolitho Novels, (12 of them) by Alexander Kent
+The Complete Works of Captain Frederick Marryat, (about 20) especially
+.in +6n
+Mr. Midshipman Easy
+Peter Simple
+Jacob Faithful
+Japhet in Search of a Father
+Snarleyyow, or The Dog Fiend
+Frank Mildmay, or The Naval Officer
+.in -6n
+.SH BUGS
+Probably a few, and please report them to "riggle@ernie.berkeley.edu" and
+"edward@ucbarpa.berkeley.edu"
diff --git a/games/sail/sync.c b/games/sail/sync.c
new file mode 100644
index 0000000..ca56e23
--- /dev/null
+++ b/games/sail/sync.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sync.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+#include "externs.h"
+#include <sys/file.h>
+#include <sys/errno.h>
+
+#define BUFSIZE 4096
+
+static char sync_buf[BUFSIZE];
+static char *sync_bp = sync_buf;
+static char sync_lock[25];
+static char sync_file[25];
+static long sync_seek;
+static FILE *sync_fp;
+#define SF "/tmp/#sailsink.%d"
+#define LF "/tmp/#saillock.%d"
+
+/*VARARGS3*/
+makesignal(from, fmt, ship, a, b, c)
+ struct ship *from;
+ char *fmt;
+ register struct ship *ship;
+{
+ char message[80];
+
+ if (ship == 0)
+ (void) sprintf(message, fmt, a, b, c);
+ else
+ (void) sprintf(message, fmt,
+ ship->shipname, colours(ship),
+ sterncolour(ship), a, b, c);
+ Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
+}
+
+#include <sys/types.h>
+#include <sys/stat.h>
+sync_exists(game)
+{
+ char buf[sizeof sync_file];
+ struct stat s;
+ time_t t;
+
+ (void) sprintf(buf, SF, game);
+ (void) time(&t);
+ if (stat(buf, &s) < 0)
+ return 0;
+ if (s.st_mtime < t - 60*60*2) { /* 2 hours */
+ (void) unlink(buf);
+ (void) sprintf(buf, LF, game);
+ (void) unlink(buf);
+ return 0;
+ } else
+ return 1;
+}
+
+sync_open()
+{
+ if (sync_fp != NULL)
+ (void) fclose(sync_fp);
+ (void) sprintf(sync_lock, LF, game);
+ (void) sprintf(sync_file, SF, game);
+ if (access(sync_file, 0) < 0) {
+ int omask = umask(issetuid ? 077 : 011);
+ sync_fp = fopen(sync_file, "w+");
+ (void) umask(omask);
+ } else
+ sync_fp = fopen(sync_file, "r+");
+ if (sync_fp == NULL)
+ return -1;
+ sync_seek = 0;
+ return 0;
+}
+
+sync_close(remove)
+ char remove;
+{
+ if (sync_fp != 0)
+ (void) fclose(sync_fp);
+ if (remove)
+ (void) unlink(sync_file);
+}
+
+Write(type, ship, isstr, a, b, c, d)
+ int type;
+ struct ship *ship;
+ char isstr;
+ int a, b, c, d;
+{
+ if (isstr)
+ (void) sprintf(sync_bp, "%d %d %d %s\n",
+ type, ship->file->index, isstr, a);
+ else
+ (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
+ type, ship->file->index, isstr, a, b, c, d);
+ while (*sync_bp++)
+ ;
+ sync_bp--;
+ if (sync_bp >= &sync_buf[sizeof sync_buf])
+ abort();
+ (void) sync_update(type, ship, a, b, c, d);
+}
+
+Sync()
+{
+ sig_t sighup, sigint;
+ register n;
+ int type, shipnum, isstr, a, b, c, d;
+ char buf[80];
+ char erred = 0;
+ extern errno;
+
+ sighup = signal(SIGHUP, SIG_IGN);
+ sigint = signal(SIGINT, SIG_IGN);
+ for (n = TIMEOUT; --n >= 0;) {
+#ifdef LOCK_EX
+ if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
+ break;
+ if (errno != EWOULDBLOCK)
+ return -1;
+#else
+ if (link(sync_file, sync_lock) >= 0)
+ break;
+ if (errno != EEXIST)
+ return -1;
+#endif
+ sleep(1);
+ }
+ if (n <= 0)
+ return -1;
+ (void) fseek(sync_fp, sync_seek, 0);
+ for (;;) {
+ switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
+ case 3:
+ break;
+ case EOF:
+ goto out;
+ default:
+ goto bad;
+ }
+ if (shipnum < 0 || shipnum >= cc->vessels)
+ goto bad;
+ if (isstr != 0 && isstr != 1)
+ goto bad;
+ if (isstr) {
+ register char *p;
+ for (p = buf;;) {
+ switch (*p++ = getc(sync_fp)) {
+ case '\n':
+ p--;
+ case EOF:
+ break;
+ default:
+ if (p >= buf + sizeof buf)
+ p--;
+ continue;
+ }
+ break;
+ }
+ *p = 0;
+ for (p = buf; *p == ' '; p++)
+ ;
+ a = (int)p;
+ b = c = d = 0;
+ } else
+ if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
+ goto bad;
+ if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
+ goto bad;
+ }
+bad:
+ erred++;
+out:
+ if (!erred && sync_bp != sync_buf) {
+ (void) fseek(sync_fp, 0L, 2);
+ (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
+ sync_fp);
+ (void) fflush(sync_fp);
+ sync_bp = sync_buf;
+ }
+ sync_seek = ftell(sync_fp);
+#ifdef LOCK_EX
+ (void) flock(fileno(sync_fp), LOCK_UN);
+#else
+ (void) unlink(sync_lock);
+#endif
+ (void) signal(SIGHUP, sighup);
+ (void) signal(SIGINT, sigint);
+ return erred ? -1 : 0;
+}
+
+sync_update(type, ship, a, b, c, d)
+ int type;
+ register struct ship *ship;
+ int a, b, c, d;
+{
+ switch (type) {
+ case W_DBP: {
+ register struct BP *p = &ship->file->DBP[a];
+ p->turnsent = b;
+ p->toship = SHIP(c);
+ p->mensent = d;
+ break;
+ }
+ case W_OBP: {
+ register struct BP *p = &ship->file->OBP[a];
+ p->turnsent = b;
+ p->toship = SHIP(c);
+ p->mensent = d;
+ break;
+ }
+ case W_FOUL: {
+ register struct snag *p = &ship->file->foul[a];
+ if (SHIP(a)->file->dir == 0)
+ break;
+ if (p->sn_count++ == 0)
+ p->sn_turn = turn;
+ ship->file->nfoul++;
+ break;
+ }
+ case W_GRAP: {
+ register struct snag *p = &ship->file->grap[a];
+ if (SHIP(a)->file->dir == 0)
+ break;
+ if (p->sn_count++ == 0)
+ p->sn_turn = turn;
+ ship->file->ngrap++;
+ break;
+ }
+ case W_UNFOUL: {
+ register struct snag *p = &ship->file->foul[a];
+ if (p->sn_count > 0)
+ if (b) {
+ ship->file->nfoul -= p->sn_count;
+ p->sn_count = 0;
+ } else {
+ ship->file->nfoul--;
+ p->sn_count--;
+ }
+ break;
+ }
+ case W_UNGRAP: {
+ register struct snag *p = &ship->file->grap[a];
+ if (p->sn_count > 0)
+ if (b) {
+ ship->file->ngrap -= p->sn_count;
+ p->sn_count = 0;
+ } else {
+ ship->file->ngrap--;
+ p->sn_count--;
+ }
+ break;
+ }
+ case W_SIGNAL:
+ if (mode == MODE_PLAYER)
+ if (nobells)
+ Signal("%s (%c%c): %s", ship, a);
+ else
+ Signal("\7%s (%c%c): %s", ship, a);
+ break;
+ case W_CREW: {
+ register struct shipspecs *s = ship->specs;
+ s->crew1 = a;
+ s->crew2 = b;
+ s->crew3 = c;
+ break;
+ }
+ case W_CAPTAIN:
+ (void) strncpy(ship->file->captain, (char *)a,
+ sizeof ship->file->captain - 1);
+ ship->file->captain[sizeof ship->file->captain - 1] = 0;
+ break;
+ case W_CAPTURED:
+ if (a < 0)
+ ship->file->captured = 0;
+ else
+ ship->file->captured = SHIP(a);
+ break;
+ case W_CLASS:
+ ship->specs->class = a;
+ break;
+ case W_DRIFT:
+ ship->file->drift = a;
+ break;
+ case W_EXPLODE:
+ if ((ship->file->explode = a) == 2)
+ ship->file->dir = 0;
+ break;
+ case W_FS:
+ ship->file->FS = a;
+ break;
+ case W_GUNL: {
+ register struct shipspecs *s = ship->specs;
+ s->gunL = a;
+ s->carL = b;
+ break;
+ }
+ case W_GUNR: {
+ register struct shipspecs *s = ship->specs;
+ s->gunR = a;
+ s->carR = b;
+ break;
+ }
+ case W_HULL:
+ ship->specs->hull = a;
+ break;
+ case W_MOVE:
+ (void) strncpy(ship->file->movebuf, (char *)a,
+ sizeof ship->file->movebuf - 1);
+ ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
+ break;
+ case W_PCREW:
+ ship->file->pcrew = a;
+ break;
+ case W_POINTS:
+ ship->file->points = a;
+ break;
+ case W_QUAL:
+ ship->specs->qual = a;
+ break;
+ case W_RIGG: {
+ register struct shipspecs *s = ship->specs;
+ s->rig1 = a;
+ s->rig2 = b;
+ s->rig3 = c;
+ s->rig4 = d;
+ break;
+ }
+ case W_RIG1:
+ ship->specs->rig1 = a;
+ break;
+ case W_RIG2:
+ ship->specs->rig2 = a;
+ break;
+ case W_RIG3:
+ ship->specs->rig3 = a;
+ break;
+ case W_RIG4:
+ ship->specs->rig4 = a;
+ break;
+ case W_COL:
+ ship->file->col = a;
+ break;
+ case W_DIR:
+ ship->file->dir = a;
+ break;
+ case W_ROW:
+ ship->file->row = a;
+ break;
+ case W_SINK:
+ if ((ship->file->sink = a) == 2)
+ ship->file->dir = 0;
+ break;
+ case W_STRUCK:
+ ship->file->struck = a;
+ break;
+ case W_TA:
+ ship->specs->ta = a;
+ break;
+ case W_ALIVE:
+ alive = 1;
+ break;
+ case W_TURN:
+ turn = a;
+ break;
+ case W_WIND:
+ winddir = a;
+ windspeed = b;
+ break;
+ case W_BEGIN:
+ (void) strcpy(ship->file->captain, "begin");
+ people++;
+ break;
+ case W_END:
+ *ship->file->captain = 0;
+ ship->file->points = 0;
+ people--;
+ break;
+ case W_DDEAD:
+ hasdriver = 0;
+ break;
+ default:
+ fprintf(stderr, "sync_update: unknown type %d\r\n", type);
+ return -1;
+ }
+ return 0;
+}
diff --git a/games/sail/version.c b/games/sail/version.c
new file mode 100644
index 0000000..94f8aab
--- /dev/null
+++ b/games/sail/version.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)version.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+char version[] = "Wooden Ships and Iron Men, Version 8.1 (93/05/31)";
OpenPOWER on IntegriCloud