Assembler doesn't like ta to be a register in main()
[unix-history] / usr / src / games / sail / pl_1.c
CommitLineData
c77f0542 1#ifndef lint
ac83b1e0 2static char *sccsid = "@(#)pl_1.c 1.4 83/05/19";
c77f0542
CL
3#endif
4#include "player.h"
5#include <sys/types.h>
6#include <sys/stat.h>
7
8WINDOW *view,*slot;
9/* int devestate; */
10
11acceptcombat()
12{
13 int crew[3], men = 0, rangeofshot, target, temp;
14 int n, r, guns[2], load[2], car[2], roll[2];
15 int ready[2], index, rakehim, sternrake;
16 int shootat[2], /*power,*/ hit[2], closest[2], ship;
17 int hhits = 0, ghits = 0, rhits = 0, chits = 0;
18 int buf;
19 struct shipspecs *ptr;
20 struct File *ptr1;
21
22 ptr = &specs[scene[game].ship[player].shipnum];
23 ptr1 = scene[game].ship[player].file;
24 crew[0] = ptr -> crew1;
25 crew[1] = ptr -> crew2;
26 crew[2] = ptr -> crew3;
27 ready[0] = ptr1 -> readyL;
28 ready[1] = ptr1 -> readyR;
29 load[0] = ptr1 -> loadL;
30 load[1] = ptr1 -> loadR;
31 guns[0] = ptr -> gunL;
32 guns[1] = ptr -> gunR;
33 car[0] = ptr -> carL;
34 car[1] = ptr -> carR;
35 for (n = 0; n < 3; n++){
36 if (ptr1 -> OBP[n].turnsent)
37 men += ptr1 -> OBP[n].mensent;
38 }
39 for (n = 0; n < 3; n++){
40 if (ptr1 -> DBP[n].turnsent)
41 men += ptr1 -> DBP[n].mensent;
42 }
43 if (men) {
44 crew[0] = men/100 ? 0 : crew[0] != 0;
45 crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
46 crew[2] = men%10 ? 0 : crew[2] != 0;
47 }
48 for (r = 0; r < 2; r++) {
49 if ((guns[r] || car[r]) && crew[2] && load[r] &&
50 ready[r] <= 0 && !ptr1 -> struck &&
51 ((closest[r] = closestenemy(player, (r ? 'r' : 'l'), 1)) != 30000)) {
52 switch(load[r]) {
53 case GRAPE:
54 rangeofshot = 1;
55 break;
56 case CHAIN:
57 rangeofshot = 3;
58 break;
59 case DOUBLE:
60 rangeofshot = 1;
61 break;
62 case ROUND:
63 rangeofshot = 10;
64 break;
65 }
66/* if (power)
67 rangeofshot = 20; */
68 if ((target = range(player, closest[r])) <= rangeofshot &&
69 !scene[game].ship[closest[r]].file -> struck &&
70 (guns[r] || (car[r] && target < 3))) {
71 Signal("%s (%c%c) within range of %s broadside.", closest[r], (r?"right":"left"));
72 if (load[r] > CHAIN && target < 6) {
73 Signal("Aim for hull or rigging? ", -1, 0);
74 while ((buf = getch()) == EOF);
75 addch(buf);
76 if(buf == 'r')
77 shootat[r] = RIGGING;
78 else if (buf == 'h')
79 shootat[r] = HULL;
80 else {
81 shootat[r] = -1;
82 Signal("'Avast there! Hold your fire.'", -1, 0);
83 }
84 } else {
85 shootat[r] = RIGGING;
86 Signal("Fire? ", -1, 0);
87 while((buf = getch()) == EOF);
88 addch(buf);
89 if (buf == 'n') {
90 shootat[r] = -1;
91 Signal("Belay that! Hold your fire.", -1, 0);
92 }
93 }
94 if (shootat[r] != -1) {
95 fired = 1;
96 rakehim = gunsbear(player, closest[r]) && !gunsbear(closest[r], player);
97 temp = portside(closest[r], player, 1) - pos[closest[r]].dir + 1;
98 if (temp < 1)
99 temp += 8;
100 if (temp > 8)
101 temp -= 8;
102 sternrake = temp > 4 && temp < 6;
103/* if (power) {
104 sternrake = 1;
105 rakehim = 1;
106 } */
107 if (rakehim && !sternrake)
108 Signal("Raking the %s!", closest[r], 0);
109 else if (rakehim && sternrake)
110 Signal("Stern Rake! %s splintering!", closest[r], 0);
111 index = guns[r];
112 if (target < 3)
113 index += car[r];
114 index = (index - 1)/3;
115 index = index > 8 ? 8 : index;
116 if (!rakehim)
117 hit[r] = HDT[index][target-1];
118 else
119 hit[r] = HDTrake[index][target-1];
120 if (rakehim && sternrake)
121 hit[r]++;
122 hit[r] += QUAL[index][ptr -> qual-1];
123 for (n=0; n < 3 && ptr1 -> captured < 0; n++)
124 if (!crew[n])
125 if (index <= 5)
126 hit[r]--;
127 else
128 hit[r] -= 2;
129 if (ready[r] <= -30000)
130 if (index <= 3)
131 hit[r]++;
132 else
133 hit[r] += 2;
134 if (ptr1 -> captured > -1)
135 if (index <= 1)
136 hit[r]--;
137 else
138 hit[r] -= 2;
139 hit[r] += AMMO[index][load[r] - 1];
140 if (((temp = ptr -> class) >= 5 || temp == 1) && windspeed == 5)
141 hit[r]--;
142 if (windspeed == 6 && temp == 4)
143 hit[r] -= 2;
144 if (windspeed == 6 && temp <= 3)
145 hit[r]--;
146 if (hit[r] >= 0) {
147 roll[r] = die();
148 if (load[r] == GRAPE)
149 chits = hit[r];
150 else {
151 hit[r] = hit[r] > 10 ? 10 : hit[r];
152 chits = shootat[r] ? RigTable[hit[r]][roll[r]-1].C : HullTable[hit[r]][roll[r]-1].C;
153 rhits = shootat[r] ? RigTable[hit[r]][roll[r]-1].R : HullTable[hit[r]][roll[r]-1].R;
154/* if (devestate && power) {
155 hhits = 10;
156 devestate = 0;
157 }
158 else */
159 hhits = shootat[r] ? RigTable[hit[r]][roll[r]-1].H : HullTable[hit[r]][roll[r]-1].H;
160 ghits = shootat[r] ? RigTable[hit[r]][roll[r]-1].G : HullTable[hit[r]][roll[r]-1].G;
161 if (scene[game].ship[closest[r]].file -> FS)
162 rhits *= 2;
163 if (load[r] == CHAIN) {
164 ghits = 0;
165 hhits = 0;
166 }
167 }
168/* if (power)
169 table(shootat[r], load[r], 10, closest[r], player, 6);
170 else */
171 table(shootat[r], load[r], hit[r], closest[r], player, roll[r]);
172 }
173 scroll = 18;
174 move(scroll++, 0);
175 clearline();
176 printw("Damage inflicted on the %s:", scene[game].ship[closest[r]].shipname);
177 move(scroll++, 0);
178 clearline();
179 printw("\t%d HULL, %d GUNS, %d CREW, %d RIGGING", hhits, ghits, chits, rhits);
180 load[r] = 0;
181 if (!r) {
182 ptr1 -> loadL = 0;
183 ptr1 -> readyL = 0;
184 } else {
185 ptr1 -> loadR = 0;
186 ptr1 -> readyR = 0;
187 }
188 }
189 } else {
190 load[r] = 0;
191 Signal("Unable to fire %s broadside", -1, (r?"right":"left"));
192 }
193 } else
194 Signal("Unable to fire %s broadside", -1, (r?"right":"left"));
195 }
196}
197
198leave(conditions)
199int conditions;
200{
201 FILE *fp;
202 int people;
203 float net;
204 char * capn;
205 char message[60];
206 register int n;
207 struct logs log[10], temp;
208
209 signal(SIGHUP, SIG_IGN);
210 signal(SIGINT, SIG_IGN);
211 signal(SIGQUIT, SIG_IGN);
212 signal(SIGALRM, SIG_IGN);
213
214 if (conditions != -1) {
215 capn = scene[game].ship[player].file -> captain;
216 sprintf(message,"Captain %s relinquishing.",capn);
217 Write(FILES + player, 1, 164, message);
218
219 if (fp = fopen(LOGFILE, "r+")) {
220 net = (float) (scene[game].ship[player].file -> points) / specs[scene[game].ship[player].shipnum].pts;
221 people = getw(fp);
222 n = fread(log, sizeof(struct logs), 10, fp);
223 for (; n < 10; n++)
224 log[n].fname[0] = log[n].uid = log[n].fshipnum = log[n].fgamenum = log[n].netpoints = 0;
225 rewind(fp);
226 if(people < 0)
227 putw(1, fp);
228 else
229 putw(people+1, fp);
230 for (n=0; n < 10; n++)
231 if (net > (float) log[n].netpoints / specs[scene[log[n].fgamenum].ship[log[n].fshipnum].shipnum].pts) {
232 fwrite(log, sizeof(struct logs), n, fp);
233 strcpy(temp.fname, capn);
234 temp.uid = getuid();
235 temp.fshipnum = player;
236 temp.fgamenum = game;
237 temp.netpoints = scene[game].ship[player].file -> points;
238 fwrite(&temp, sizeof(struct logs), 1, fp);
239 fwrite(log + n, sizeof(struct logs), 9 - n, fp);
240 break;
241 }
242 fclose(fp);
243 }
244 Write(FILES + player, 1, 0, " ");
245 Write(SCENARIO, 0, 8, scene[game].people - 1);
246 screen();
247 fclose(syncfile);
248 Signal("It looks like you've had it!", -1, 0);
249 if (conditions == 1)
250 Signal("Your ship was captured.", -1, 0);
251 if (conditions == 2)
252 Signal("No more enemies.", -1, 0);
253 if (conditions == 3)
254 Signal("Hurricane! All ships destroyed.", -1, 0);
255 move(0, LINES-1);
256 scroll = LINES;
257 clearline();
258 refresh();
259 }
260 nocrmode();
261 echo();
262 endwin();
263 exit(0);
264}
265
266choke()
267{
268 leave(0);
269}
270
271grapungrap()
272{
273 register int n, k, l, number, captured;
274 int buf;
275
276 for (n=0; n < scene[game].vessels ; n++) {
277 if (n != player && (range(player, n) <= 1 || grapple(player, n))) {
278 if ((captured = scene[game].ship[n].file -> captured) < 0)
279 captured = n;
280 Signal("Attempt to grapple or ungrapple %s (%c%c): ", n, 0);
281 while((buf = getch()) == EOF);
282 addch(buf);
283 if (buf == 'g') {
284 number = die() < 3;
285 if (!number && scene[game].ship[player].nationality == scene[game].ship[captured].nationality)
286 number = 1;
287 if (number) {
288 for (l=0; l < 10 && scene[game].ship[player].file -> grapples[l].turnfoul; l++);
289 if (!scene[game].ship[player].file -> grapples[l].turnfoul) {
290 Write(FILES + player, 0, 124 + l*4, turn);
291 Write(FILES + player, 0, 124 + l*4 + 2, n);
292 }
293 for (l=0; l < 10 && scene[game].ship[n].file -> grapples[l].turnfoul; l++);
294 if (!scene[game].ship[n].file -> grapples[l].turnfoul) {
295 Write(FILES + n, 0, 124 + l*4, turn);
296 Write(FILES + n, 0, 124 + l*4 + 2, player);
297 }
298 }
299 if (number) {
300 Signal("Attempt succeeds!", 0, 0);
301 makesignal("grappled with %s (%c%c)", n, player);
302 } else
303 Signal("Attempt fails.", 0, 0);
304 }
305 if (buf == 'u'){ for (k=0; k < 10; k++) {
306 if (scene[game].ship[player].file -> grapples[k].turnfoul && n == scene[game].ship[player].file -> grapples[k].toship) {
307 if (die() < 3 || scene[game].ship[player].nationality == scene[game].ship[captured].nationality) {
308 cleangrapple(player, n, k);
309 Signal("Attempt succeeds!", 0, 0);
310 makesignal("ungrappling with %s (%c%c)", n, player);
311 } else
312 Signal("Attempt fails.", 0, 0);
313 }
314 }
315 }
316 }
317 }
318}
319
320unfoulplayer()
321{
322 register int n, toship;
323 int buf;
324
325 for (n=0; n < 10; n++) {
326 if (scene[game].ship[player].file -> fouls[n].turnfoul) {
327 Signal("Attempt to unfoul with the %s (%c%c)? ", (toship = scene[game].ship[player].file -> fouls[n].toship), 0);
328 while((buf = getch()) == EOF);
329 addch(buf);
330 if (buf == 'y' && die() < 3) {
331 cleanfoul(player, toship, n);
332 Signal("Attempt succeeds!", 0, 0);
333 makesignal("unfouling %s (%c%c)", toship, player);
334 } else if (buf == 'y')
335 Signal("Attempt fails.", 0, 0);
336 }
337 }
338}
339
340initialize(nodriver, randomize)
341char randomize, nodriver;
342{
343 char comm[80], num[5], file[25], capn;
344 char message[60];
345 int load = ROUND, ready = -30000;
346 int people = 0;
a2294d92 347 int pid, omask;
c77f0542
CL
348 register int n;
349 register int k;
350 struct stat Stat;
351 char *nameptr;
352
353 srand(pid = getpid());
c77f0542
CL
354 initscr();
355 view = newwin(ROWSINVIEW, COLSINVIEW, 2, 1);
356 slot = newwin(ROWSINVIEW, 3, 2, 1+COLSINVIEW);
357
358 if (game < 0) {
359 puts("Choose a scenario:\n");
360 puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
361 for (n=0; n < NUMOFSCENES; n++) {
362 sprintf(file, "/tmp/.%d", n);
363 printf("\t%d):\t%d", n, scene[n].vessels);
364 if (stat(file, &Stat) >= 0)
365 printf("\tYES");
366 else
367 printf("\tno");
368 printf("\t%s\n", scene[n].name);
369 }
370reprint:
371 printf("\nScenario number? ");
372 scanf("%d", &game);
373 while (getchar() != '\n');
374 }
375 if (game < 0 || game >= NUMOFSCENES) {
376 puts("Very funny.");
377 endwin();
378 exit(1);
379 }
380 sprintf(file, "/tmp/.%d", game);
a2294d92
CL
381 if (stat(file, &Stat) < 0 ) {
382#ifdef SETUID
383 omask = umask(077);
384#else
385 omask = umask(011);
386#endif
c77f0542 387 syncfile = fopen(file, "w+");
a2294d92
CL
388 umask(omask);
389 } else {
c77f0542
CL
390 syncfile = fopen(file, "r+");
391 people = 1;
392 }
393 lastsync = 0;
394 for (n=0; n < scene[game].vessels; n++) {
395 nation[scene[game].ship[n].nationality + 1] = n + 1;
396 if ((scene[game].ship[n].file = (struct File *) calloc(1, sizeof(struct File))) == NULL) {
397 puts("OUT OF MEMORY");
398 endwin();
399 exit(0);
400 }
401 scene[game].ship[n].file -> captured = -1;
402 }
403 if (!nation[2])
404 nation[2] = nation[1];
405 if (!nation[3])
406 nation[3] = nation[2];
407 if (people > 0) {
408 puts("Synchronizing with the other players...");
409 fflush(stdout);
410 sync();
411 capn = 1;
412 for (n=0; n < scene[game].vessels && capn; n++) {
413 capn = scene[game].ship[n].file -> captain[0];
414 if (scene[game].ship[n].file -> struck || scene[game].ship[n].file -> captured > -1)
415 capn = 1;
416 }
417 if (!capn)
418 player = n-1;
419 else {
420 puts("All ships taken in that scenario.");
421 for (n=0; n < scene[game].vessels; n++)
422 free(scene[game].ship[n].file);
423 people = 0;
424 for (n=0; n < 5; n++)
425 nation[n] = 0;
426 goto reprint;
427 }
428 } else
429 player = 0;
430 while (randomize) {
431 static char *color[] =
432 { "(American)", "(British)", "(Spanish)", "(French)" };
433
434 puts(scene[game].name);
435 putchar('\n');
436 for (n=0; n < scene[game].vessels; n++) {
437 printf(" %2d: %-10s %-15s (%-2d pts) ", n,
438 color[scene[game].ship[n].nationality],
439 scene[game].ship[n].shipname,
440 specs[scene[game].ship[n].shipnum].pts);
441 if(scene[game].ship[n].file -> captain[0])
442 puts(scene[game].ship[n].file -> captain);
443 else if (scene[game].ship[n].file -> struck)
444 puts("(struck)");
445 else if(scene[game].ship[n].file -> captured > -1)
446 puts("(captured)");
447 else
448 puts("(available)");
449 }
450 putchar('\n');
451 printf("Which ship do you want (0-%d)? ",scene[game].vessels-1);
452 if (scanf("%d",&player) != 1 || player < 0 || player >= scene[game].vessels) {
453 while (getchar() != '\n');
454 puts("Say what?");
455 } else {
456 while (getchar() != '\n');
457 sync();
458 if (scene[game].ship[player].file -> captain[0] || scene[game].ship[player].file -> struck || scene[game].ship[player].file -> captured > -1)
459 puts("Sorry, that ship is taken.");
460 else
461 break;
462 }
463 }
464 signal(2, choke);
465 signal(1, choke);
466 Write(FILES + player, 1, 0, "begin"); /* he now exits */
467 if(people)
468 Write(SCENARIO, 0, 8, scene[game].people + 1);
469 sync();
470 printf("Your ship is the %s, a %s (%s crew).\n", scene[game].ship[player].shipname, info(player, message), quality(player));
471 if ((nameptr = (char *) getenv("NAME")) && *nameptr)
472 strcpy(comm,nameptr);
473 else {
474 fputs("Your name, Captain? ", stdout);
475 gets(comm);
476 if (!*comm) strcpy(comm, "no name");
477 }
478 comm[19] = '\0';
479 for (k=0; k < 2; k++) {
480 printf("\nInitial broadside %s (grape, chain, round, double): ", (k ? "right" : "left"));
481 scanf("%s", file);
482 switch(*file) {
483 case 'g':
484 load = GRAPE;
485 break;
486 case 'c':
487 load = CHAIN;
488 break;
489 case 'r':
490 load = ROUND;
491 break;
492 case 'd':
493 load = DOUBLE;
494 break;
495 }
496 if (k) {
497 scene[game].ship[player].file -> loadR = load;
498 scene[game].ship[player].file -> readyR = ready;
499 } else {
500 scene[game].ship[player].file -> loadL = load;
501 scene[game].ship[player].file -> readyL = ready;
502 }
503 }
504 Write(FILES + player, 1, 0, comm);
505 if (!people && !nodriver) {
506 sprintf(num, "%d", game);
507 if (!fork()) {
508 execl(DRIVER, DRIVERNAME, num, 0);
509 perror(DRIVER);
510 kill(pid,9);
511 exit(1);
512 }
513 }
514 board();
515 sprintf(message, "Captain %s assuming command",comm);
516 Write(FILES + player, 1, 164, message);
517 windspeed = scene[game].windspeed;
518 winddir = scene[game].winddir;
519 turn = scene[game].turn;
520 iplotships(); /* new turn */
521}
522
523/*
524 * Returns the NUMBER of the closest ship
525 */
526closestenemy(fromship, side, anyship)
527int fromship;
528char side, anyship;
529{
530 register int n, olddist = 30000, ident, captured;
531 register int dist, eclosest = 30000;
532
533 if ((ident = scene[game].ship[fromship].file -> captured) < 0)
534 ident = fromship;
535 for (n=0; n < scene[game].vessels; n++) {
536 if ((captured = scene[game].ship[n].file -> captured) < 0)
537 captured = n;
538 if (n != fromship && pos[n].dir && (scene[game].ship[ident].nationality != scene[game].ship[captured].nationality || anyship)) {
539 if (!side || gunsbear(fromship, n) == side) {
540 dist = range(fromship, n);
541 if (dist < olddist){
542 eclosest = n;
543 olddist = dist;
544 }
545 }
546 }
547 }
548 if (!side && olddist == 30000)
549 leave(2);
550 return(eclosest);
551}
552
553finalexit()
554{
555 endwin();
556 nocrmode();
557 echo();
558 exit(1);
559}
560
561main(argc, argv)
562int argc;
563char ** argv;
564{
e454b583
CL
565 register int crew, aheadfirst, ma, n;
566 int ta;
c77f0542
CL
567 char message[60], ch;
568 int uid;
569 char nodrive = 0, randomize = 0, *badstring();
570
571 signal(SIGINT, finalexit);
572 signal(SIGQUIT, finalexit);
573 signal(SIGHUP, finalexit);
574
575 if (timetoplay() != 0 && gooduid(uid) != 0)
576 {
577 printf("Sorry Captain, but since you are not an Admiral and this is\n");
578 printf("a weekday between %s, you are not permitted to\n",badstring());
579 printf("sail. Come back again some time when the harbor is open.\n");
580 exit(1);
581 }
582
583 while (*++argv && **argv == '-')
584 switch (*++*argv)
585 {
586 case 'd':
587 nodrive = 1;
588 break;
589 case 'x':
590 randomize = 1;
591 break;
592 default:
593 printf("Unknown flag '%s'\n",*argv);
594 break;
595 }
596 if (*argv)
597 game = atoi(*argv);
598 else
599 game = -1;
600 initialize(nodrive, randomize);
601 noecho();
602 crmode();
603 Signal("Aye aye, Sir", 0, 0);
604 for(;;)
605 {
606 move(scroll++,0);
607 clearline();
608 addch('~');
609 move(--scroll,0);
610 refresh();
611 ch = getch();
612 switch(ch)
613 {
614 case 'm':
615 crew = specs[scene[game].ship[player].shipnum].crew3;
616 /* for (n=0; n < 3; n++)
617 {
618 if (ptr -> OBP[n].turnsent && ptr -> OBP[n].mensent % 10)
619 crew = 0;
620 }
621 for (n=0; n < 3; n++)
622 {
623 if (ptr -> DBP[n].turnsent && ptr -> DBP[n].mensent % 10)
624 crew = 0;
625 } */
626 if (crew && !grappled(player) && !fouled(player) && windspeed)
627 {
628 ta = maxturns(player);
629 aheadfirst = ta & 0100000;
630 ma = maxmove(player, pos[player].dir, 0);
631 ta &= 077777;
632 acceptmove(ma, ta, aheadfirst);
633 }
634 else
635 Signal("Unable to move", 0, 0);
636 break;
637 case 's':
638 acceptsignal();
639 break;
640 case 'g':
641 grapungrap();
642 break;
643 case 'u':
644 unfoulplayer();
645 break;
2f14594b
CL
646 case 'v':
647 version();
648 break;
c77f0542
CL
649 case 'b':
650 boarding();
651 break;
652/* case '[':
653 devestate = 1;
654 acceptcombat();
655 break; */
656 case 'f':
657 acceptcombat();
658 break;
659 case 'l':
660 loadplayer();
661 break;
662 case 'c':
663 changesail();
664 break;
665 case 'r':
666 repair();
667 break;
668 case 'B':
669 Signal("'Hands to stations!'", 0, 0);
670 unboard(player, player, 1); /* cancel DBP's */
671 unboard(player, player, 0); /* cancel offense */
672 break;
673 case '\f':
674 signal(SIGALRM, SIG_IGN);
675 viewrow = pos[player].row - ROWSINVIEW / 2;
676 viewcol = pos[player].col - COLSINVIEW / 2;
677 board();
678 plotships(); /* don't create new turn */
679 break;
680 case 'L':
681 scene[game].ship[player].file -> loadL = 0;
682 scene[game].ship[player].file -> loadR = 0;
683 scene[game].ship[player].file -> readyL = 0;
684 scene[game].ship[player].file -> readyR = 0;
685 Signal("Broadsides unloaded", 0, 0);
686 break;
687 case 'q':
688 Signal("Type 'Q' to quit", 0, 0);
689 break;
690 case 'Q':
691 leave(0);
692 break;
693 case 'I':
694 for (n = 0; n < scene[game].vessels; n++)
695 eyeball(player, n);
696 break;
697 case 'i':
698 n = closestenemy(player, 0, 1);
699 eyeball(player, n);
700 break;
701 }
702 signalflags();
703 lost();
704 }
705 }
706
707char *saywhat(n)
708int n;
709{
710 if(scene[game].ship[n].file -> captain[0])
711 return(scene[game].ship[n].file -> captain);
712 else if (scene[game].ship[n].file -> struck)
713 return("(struck)");
714 else if(scene[game].ship[n].file -> captured > -1)
715 return("(captured)");
716 else
717 return("(computer)");
718}
719
720eyeball(player, n)
721int player, n;
722{
723 char message[80];
724 register i;
725
726 if (scene[game].ship[n].shipdir){
727 sprintf(message, "%d, %s", range(player, n), saywhat(n));
728 Signal("Sail ho! (range %s)", -1, message);
729 switch(scene[game].ship[n].nationality)
730 {
731 case 0:
732 strcpy(message, "American ");
733 break;
734 case 1:
735 strcpy(message, "British ");
736 break;
737 case 2:
738 strcpy(message, "Spanish ");
739 break;
740 case 3:
741 strcpy(message, "French ");
742 break;
743 default:
744 strcpy(message, "Gremlin ");
745 break;
746 }
747 switch(specs[scene[game].ship[n].shipnum].class)
748 {
749 case 1:
750 case 2:
751 strcat(message, "Ship of the Line ");
752 break;
753 case 3:
754 case 4:
755 strcat(message, "Frigate ");
756 break;
757 case 5:
758 case 6:
759 strcat(message, "Sloop ");
760 break;
761 }
762 switch(portside(player, n, 1) - pos[player].dir)
763 {
764 case -7:
765 case 1:
766 strcat(message, "off the starboard bow.");
767 break;
768 case -6:
769 case 2:
770 strcat(message, "off the starboard beam.");
771 break;
772 case -5:
773 case 3:
774 strcat(message, "off the starboard quarter.");
775 break;
776 case -4:
777 case 4:
778 strcat(message, "dead astern.");
779 break;
780 case -3:
781 case 5:
782 strcat(message, "off the port quarter.");
783 break;
784 case -2:
785 case 6:
786 strcat(message, "off the port beam.");
787 break;
788 case -1:
789 case 7:
790 strcat(message, "off the port bow.");
791 break;
792 case 0:
793 strcat(message, "dead ahead.");
794 break;
795 }
796 Signal(message, 0, 0);
797 }
798}