(no message)
[unix-history] / usr / src / games / sail / pl_1.c
CommitLineData
c77f0542 1#ifndef lint
b3a57661 2static char *sccsid = "@(#)pl_1.c 1.9 83/07/20";
c77f0542 3#endif
7fc06086 4
c77f0542
CL
5#include "player.h"
6#include <sys/types.h>
b3a57661 7#include <wait.h>
c77f0542 8
b3a57661 9int choke(), child();
c77f0542 10
b3a57661
EW
11/*ARGSUSED*/
12main(argc, argv)
13int argc;
14char **argv;
c77f0542 15{
b3a57661
EW
16 register struct ship *sp;
17 int aheadfirst, ma;
18 int ta;
19 char nodrive = 0, randomize = 0, debug = 0;
20 char *badstring();
21 extern char _sobuf[];
c77f0542 22
b3a57661 23 setbuf(stdout, _sobuf);
7fc06086 24
b3a57661
EW
25 while (*++argv && **argv == '-')
26 switch (*++*argv) {
27 case 'd':
28 nodrive = 1;
29 break;
30 case 'D':
31 debug++;
32 break;
33 case 'x':
34 randomize = 1;
35 break;
36 default:
37 printf("Unknown flag '%s'\n",*argv);
38 break;
7fc06086 39 }
b3a57661
EW
40 if (*argv)
41 game = atoi(*argv);
42 else
43 game = -1;
44 initialize(nodrive, randomize, debug);
45 Signal("Aye aye, Sir", (struct ship *)0);
46 for (;;) {
47 prompt();
48 switch (sgetch(0)) {
49 case 'm':
50 if (mc->crew3 && !snagged(ms)
51 && windspeed != 0) {
52 ta = maxturns(ms);
53 aheadfirst = ta & 0100000;
54 ma = maxmove(ms, mf->dir, 0);
55 ta &= 077777;
56 acceptmove(ma, ta, aheadfirst);
57 } else
58 Signal("Unable to move", (struct ship *)0);
59 break;
60 case 's':
61 acceptsignal();
62 break;
63 case 'g':
64 grapungrap();
65 break;
66 case 'u':
67 unfoulplayer();
68 break;
69 case 'v':
70 Signal("%s", (struct ship *)0, version);
71 break;
72 case 'b':
73 doboarding();
74 break;
75 case 'f':
76 acceptcombat();
77 break;
78 case 'l':
79 loadplayer();
80 break;
81 case 'c':
82 changesail();
83 break;
84 case 'r':
85 repair();
86 break;
87 case 'B':
88 Signal("'Hands to stations!'", (struct ship *)0);
89 unboard(ms, ms, 1); /* cancel DBP's */
90 unboard(ms, ms, 0); /* cancel offense */
91 break;
92 case '\f':
93 centerview();
94 board();
7fc06086 95 screen();
b3a57661
EW
96 break;
97 case 'L':
98 mf->loadL = L_EMPTY;
99 mf->loadR = L_EMPTY;
100 mf->readyL = R_EMPTY;
101 mf->readyR = R_EMPTY;
102 Signal("Broadsides unloaded", (struct ship *)0);
103 break;
104 case 'q':
105 Signal("Type 'Q' to quit", (struct ship *)0);
106 break;
107 case 'Q':
108 leave(LEAVE_QUIT);
109 break;
110 case 'I':
111 foreachship(sp)
112 eyeball(sp);
113 break;
114 case 'i':
115 eyeball(closestenemy(ms, 0, 1));
116 break;
117 case 'C':
118 centerview();
119 draw_view();
120 break;
121 case 'U':
122 upview();
123 draw_view();
124 break;
125 case 'D':
126 case 'N':
127 downview();
128 draw_view();
129 break;
130 case 'H':
131 leftview();
132 draw_view();
133 break;
134 case 'J':
135 rightview();
136 draw_view();
137 break;
138 case 'F':
139 lookout();
140 break;
141 case 'S':
142 dont_adjust = !dont_adjust;
143 break;
7fc06086 144 }
b3a57661
EW
145 signalflags();
146 lost();
c77f0542 147 }
c77f0542
CL
148}
149
bba7bfeb
BJ
150initialize(nodriver, randomize, debug)
151char randomize, nodriver, debug;
c77f0542 152{
b3a57661
EW
153 register struct File *fp;
154 register struct ship *sp;
155 char captain[80], file[25];
7fc06086 156 char message[60];
b3a57661 157 int load;
7fc06086 158 int people = 0;
7fc06086 159 register int n;
7fc06086 160 char *nameptr;
b3a57661 161 int nat[NNATION];
c77f0542 162
b3a57661 163 (void) srand(getpid());
c77f0542 164
7fc06086 165 if (game < 0) {
b3a57661
EW
166 (void) puts("Choose a scenario:\n");
167 (void) puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
168 for (n = 0; n < NSCENE; n++) {
7fc06086 169 printf("\t%d):\t%d", n, scene[n].vessels);
b3a57661 170 (void) sprintf(file, "/tmp/.%d", n);
7fc06086
BJ
171 if (access(file, 0) >= 0)
172 printf("\tYES");
173 else
174 printf("\tno");
175 printf("\t%s\n", scene[n].name);
176 }
c77f0542 177reprint:
7fc06086 178 printf("\nScenario number? ");
b3a57661
EW
179 (void) fflush(stdout);
180 (void) scanf("%d", &game);
181 while (getchar() != '\n')
182 ;
7fc06086 183 }
b3a57661
EW
184 if (game < 0 || game >= NSCENE) {
185 (void) puts("Very funny.");
7fc06086
BJ
186 exit(1);
187 }
b3a57661
EW
188 cc = &scene[game];
189 ls = cc->ship + cc->vessels;
190
191 (void) sprintf(file, "/tmp/.%d", game);
7fc06086
BJ
192 if (access(file, 0) < 0) {
193 int omask;
a2294d92 194#ifdef SETUID
7fc06086 195 omask = umask(077);
a2294d92 196#else
7fc06086 197 omask = umask(011);
a2294d92 198#endif
7fc06086 199 syncfile = fopen(file, "w+");
b3a57661 200 (void) umask(omask);
7fc06086
BJ
201 } else {
202 syncfile = fopen(file, "r+");
203 people = 1;
c77f0542 204 }
7fc06086 205 lastsync = 0;
b3a57661
EW
206
207 for (n = 0; n < NNATION; n++)
208 nat[n] = 0;
209 foreachship(sp) {
210 sp->file = (struct File *) calloc(1, sizeof (struct File));
211 if (sp->file == NULL) {
212 (void) puts("OUT OF MEMORY");
7fc06086
BJ
213 exit(0);
214 }
b3a57661 215 sp->file->stern = nat[sp->nationality]++;
c77f0542 216 }
7fc06086 217 if (people > 0) {
b3a57661
EW
218 (void) puts("Synchronizing with the other players...");
219 (void) fflush(stdout);
220 Sync();
221 foreachship(sp) {
222 if (sp->file->captain[0]
223 || sp->file->struck || sp->file->captured != 0)
224 break;
7fc06086 225 }
b3a57661
EW
226 if (sp >= ls) {
227 (void) puts("All ships taken in that scenario.");
228 foreachship(sp)
229 free((char *)sp->file);
7fc06086 230 people = 0;
b3a57661 231 (void) fclose(syncfile);
7fc06086
BJ
232 goto reprint;
233 }
b3a57661 234 player = sp - cc->ship;
7fc06086
BJ
235 } else
236 player = 0;
b3a57661 237
7fc06086 238 while (randomize) {
b3a57661
EW
239 printf("%s\n\n", cc->name);
240 foreachship(sp) {
241 printf(" %2d: %-10s %-15s (%-2d pts) %s\n",
242 sp - SHIP(0),
243 countryname[sp->nationality],
244 sp->shipname,
245 sp->specs->pts,
246 saywhat(sp, 1));
7fc06086 247 }
b3a57661
EW
248 printf("\nWhich ship do you want (0-%d)? ", cc->vessels-1);
249 (void) fflush(stdout);
250 if (scanf("%d", &player) != 1 || player < 0
251 || player >= cc->vessels) {
252 while (getchar() != '\n')
253 ;
254 (void) puts("Say what?");
7fc06086 255 } else {
b3a57661
EW
256 while (getchar() != '\n')
257 ;
258 Sync();
259 fp = SHIP(player)->file;
260 if (fp->captain[0] || fp->struck || fp->captured != 0)
261 (void) puts("Sorry, that ship is taken.");
7fc06086
BJ
262 else
263 break;
264 }
c77f0542 265 }
7fc06086 266
b3a57661
EW
267 ms = SHIP(player);
268 mf = ms->file;
269 mc = ms->specs;
7fc06086 270
b3a57661
EW
271 (void) signal(SIGHUP, choke);
272 (void) signal(SIGINT, choke);
273 (void) signal(SIGQUIT, choke);
274 (void) signal(SIGCHLD, child);
275
276 Write(W_CAPTAIN, ms, 1, (int) "begin", 0, 0, 0);
7fc06086 277 if (people)
b3a57661
EW
278 Write(W_PEOPLE, SHIP(0), 0, cc->people + 1, 0, 0, 0);
279 Sync();
280 printf("Your ship is the %s, a %d gun %s (%s crew).\n",
281 ms->shipname, mc->guns, classname[mc->class],
282 qualname[mc->qual]);
283 if ((nameptr = (char *) getenv("SAILNAME")) && *nameptr)
284 (void) strncpy(captain, nameptr, sizeof captain);
7fc06086 285 else {
b3a57661
EW
286 (void) printf("Your name, Captain? ");
287 (void) fflush(stdout);
288 (void) gets(captain);
289 if (!*captain)
290 (void) strcpy(captain, "no name");
c77f0542 291 }
b3a57661
EW
292 captain[sizeof captain - 1] = '\0';
293 for (n = 0; n < 2; n++) {
294 printf("\nInitial broadside %s (grape, chain, round, double): ",
295 n ? "right" : "left");
296 (void) fflush(stdout);
297 (void) scanf("%s", file);
298 switch (*file) {
7fc06086 299 case 'g':
b3a57661 300 load = L_GRAPE;
7fc06086
BJ
301 break;
302 case 'c':
b3a57661 303 load = L_CHAIN;
7fc06086
BJ
304 break;
305 case 'r':
b3a57661 306 load = L_ROUND;
7fc06086
BJ
307 break;
308 case 'd':
b3a57661 309 load = L_DOUBLE;
7fc06086 310 break;
b3a57661
EW
311 default:
312 load = L_ROUND;
7fc06086 313 }
b3a57661
EW
314 if (n) {
315 mf->loadR = load;
316 mf->readyR = R_LOADED|R_INITIAL;
7fc06086 317 } else {
b3a57661
EW
318 mf->loadL = load;
319 mf->readyL = R_LOADED|R_INITIAL;
7fc06086 320 }
c77f0542 321 }
b3a57661 322 Write(W_CAPTAIN, ms, 1, (int)captain, 0, 0, 0);
7fc06086
BJ
323 if (!people && !nodriver) {
324 char num[10];
b3a57661 325 (void) sprintf(num, "%d", game);
7fc06086 326 if (!fork()) {
bba7bfeb
BJ
327 if (debug)
328 execl(DEBUGDRIVER, DRIVERNAME, num, 0);
329 else
330 execl(DRIVER, DRIVERNAME, num, 0);
7fc06086 331 perror(DRIVER);
7fc06086
BJ
332 exit(1);
333 }
c77f0542 334 }
7fc06086 335
b3a57661 336 initscreen();
7fc06086
BJ
337
338 board();
b3a57661
EW
339 (void) sprintf(message, "Captain %s assuming command", captain);
340 Write(W_SIGNAL, ms, 1, (int)message, 0, 0, 0);
7fc06086 341
b3a57661 342 newturn();
c77f0542
CL
343}
344
b3a57661
EW
345leave(conditions)
346int conditions;
c77f0542 347{
b3a57661
EW
348 FILE *fp;
349 int people;
350 float net;
351 char * capn;
352 char message[60];
353 register int n;
354 struct logs log[10], temp;
c77f0542 355
b3a57661
EW
356 (void) signal(SIGHUP, SIG_IGN);
357 (void) signal(SIGINT, SIG_IGN);
358 (void) signal(SIGQUIT, SIG_IGN);
359 (void) signal(SIGALRM, SIG_IGN);
360 (void) signal(SIGCHLD, SIG_IGN);
c77f0542 361
b3a57661
EW
362 if (conditions != -1) {
363 capn = mf->captain;
364 (void) sprintf(message,"Captain %s relinquishing.",capn);
365 Write(W_SIGNAL, ms, 1, (int)message, 0, 0, 0);
c77f0542 366
b3a57661
EW
367 if (fp = fopen(LOGFILE, "r+")) {
368 net = (float)mf->points / mc->pts;
369 people = getw(fp);
370 n = fread((char *)log, sizeof(struct logs), 10, fp);
371 for (; n < 10; n++)
372 log[n].l_name[0]
373 = log[n].l_uid
374 = log[n].l_shipnum
375 = log[n].l_gamenum
376 = log[n].l_netpoints = 0;
377 rewind(fp);
378 if (people < 0)
379 (void) putw(1, fp);
380 else
381 (void) putw(people + 1, fp);
382 for (n = 0; n < 10; n++)
383 if (net > (float) log[n].l_netpoints / scene[log[n].l_gamenum].ship[log[n].l_shipnum].specs->pts) {
384 (void) fwrite((char *)log,
385 sizeof (struct logs), n, fp);
386 (void) strcpy(temp.l_name, capn);
387 temp.l_uid = getuid();
388 temp.l_shipnum = player;
389 temp.l_gamenum = game;
390 temp.l_netpoints = mf->points;
391 (void) fwrite((char *)&temp,
392 sizeof temp, 1, fp);
393 (void) fwrite((char *)&log[n],
394 sizeof (struct logs), 9-n, fp);
395 break;
396 }
397 (void) fclose(fp);
7fc06086 398 }
b3a57661
EW
399 Write(W_CAPTAIN, ms, 1, (int)" ", 0, 0, 0);
400 Write(W_PEOPLE, SHIP(0), 0, cc->people - 1, 0, 0, 0);
401 if (done_curses) {
402 screen();
403 Signal("It looks like you've had it!",
404 (struct ship *)0);
405 switch (conditions) {
406 case LEAVE_QUIT:
407 break;
408 case LEAVE_CAPTURED:
409 Signal("Your ship was captured.",
410 (struct ship *)0);
411 break;
412 case LEAVE_HURRICAN:
413 Signal("Hurricane! All ships destroyed.",
414 (struct ship *)0);
415 break;
416 case LEAVE_DRIVER:
417 Signal("The driver died.", (struct ship *)0);
418 break;
419 default:
420 Signal("A funny thing happened (%d).",
421 (struct ship *)0, conditions);
422 }
423 } else {
424 if (conditions == LEAVE_DRIVER)
425 printf("The driver died.\n");
426 else
427 printf("leave: unknown code %d\n", conditions);
7fc06086 428 }
b3a57661
EW
429 (void) fclose(syncfile);
430 }
431 if (done_curses) {
432 lastline();
433 nocrmode();
434 echo();
435 endwin();
c77f0542 436 }
b3a57661 437 exit(0);
7fc06086 438}
c77f0542 439
b3a57661 440choke()
c77f0542 441{
b3a57661 442 leave(LEAVE_QUIT);
c77f0542
CL
443}
444
b3a57661 445child()
c77f0542 446{
b3a57661
EW
447 union wait status;
448 int pid;
c77f0542 449
b3a57661
EW
450 (void) signal(SIGCHLD, SIG_IGN);
451 do {
452 pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
453 if (pid < 0 || pid > 0 && !WIFSTOPPED(status))
454 leave(LEAVE_DRIVER);
455 } while (pid != 0);
456 (void) signal(SIGCHLD, child);
c77f0542 457}