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