1 #ifndef lint 2 static char *sccsid = "@(#)pl_2.c 1.2 83/05/20"; 3 #endif 4 5 #include "player.h" 6 7 #define turnfirst(buf) (*buf == 'r' || *buf == 'l') 8 9 lost() 10 { 11 if (scene[game].ship[player].file -> struck) 12 leave(0); 13 if (scene[game].ship[player].file -> captured > -1) 14 leave(1); 15 if (windspeed == 7) 16 leave(3); 17 if(scene[game].ship[player].file -> FS && (!specs[scene[game].ship[player].shipnum].rig1 || windspeed == 6)) 18 Write(FILES + player, 0, 230, 0); 19 } 20 21 22 acceptmove(ma, ta, af) 23 int ma, ta, af; 24 { 25 register int n; 26 int moved = 0; 27 int full, vma, dir, ch; 28 char buf[60], last = '\0'; 29 30 if (scroll >= 22) scroll = 18; 31 move(scroll++, 0); 32 clearline(); 33 printw("move (%d,%c%d): ", ma, (af ? '\'' : ' '), ta); 34 refresh(); 35 n = 0; 36 while((ch = getch()) != '\n'){ 37 if (ch != EOF){ 38 buf[n++] = ch; 39 addch(ch); 40 refresh(); 41 } 42 if(ch == '' && n > 1) 43 n -= 2; 44 } 45 buf[n] = '\0'; 46 buf[9] = '\0'; 47 dir = pos[player].dir; 48 vma = ma; 49 for (n = 0; buf[n]; n++) 50 if (!(buf[n] == 'r' || buf[n] == '\n' || buf[n] == 'l' || (buf[n] == '0' && !n) || isdigit(buf[n]) || buf[n] == 'b' || (buf[n] == 'd' && !n))){ 51 if (isspace(buf[n])){ 52 strcpy(buf+n, buf+n+1); 53 n--; 54 } else { 55 Signal("Syntax error.",0,0); 56 buf[n--] = '\0'; 57 } 58 } 59 else 60 switch(buf[n]){ 61 case 'l': 62 dir -= 2; 63 case 'r': 64 dir++; 65 if (!dir) dir = 8; 66 if (dir == 9) dir = 1; 67 if (last == 't'){ 68 Signal("Error; ship can't turn that fast.", 0, 0); 69 buf[n--] = '\0'; 70 } 71 last = 't'; 72 ma--; 73 ta--; 74 vma = min(ma, maxmove(player, dir, 0)); 75 if (ta < 0 && moved || vma < 0 && moved) 76 buf[n--] = '\0'; 77 break; 78 79 case 'b': 80 ma--; 81 vma--; 82 last = 'b'; 83 if (ta < 0 && moved || vma < 0 && moved) 84 buf[n--] = '\0'; 85 break; 86 87 case '0': 88 case 'd': 89 buf[n--] = '\0'; 90 break; 91 92 case '\n': 93 buf[n] = '\0'; 94 break; 95 96 case '1': 97 case '2': 98 case '3': 99 case '4': 100 case '5': 101 case '6': 102 case '7': 103 if (last == '0'){ 104 Signal("Error; value out of range.", 0, 0); 105 buf[n--] = '\0'; 106 } 107 last = '0'; 108 moved = 1; 109 ma -= buf[n] - '0'; 110 vma -= buf[n] - '0'; 111 if (ta < 0 && moved || vma < 0 && moved) 112 buf[n--] = '\0'; 113 break; 114 115 } /* end switch and else and for */ 116 if (ta < 0 && moved || vma < 0 && moved || af && turnfirst(buf) && moved){ 117 Signal("Movement error.", 0, 0); 118 if (ta < 0 && moved){ 119 if (scene[game].ship[player].file -> FS == 1){ 120 Write(FILES + player, 0, 230, 0); 121 Signal("No hands to set full sails.", 0, 0); 122 } 123 } 124 else if (ma >= 0) 125 buf[1] = '\0'; 126 } 127 if (af && !moved){ 128 if (scene[game].ship[player].file -> FS == 1){ 129 Write(FILES + player, 0, 230, 0); 130 Signal("No hands to set full sails.", 0, 0); 131 } 132 } 133 strcpy(movebuf, buf); 134 if (!*movebuf) strcpy(movebuf, "d"); 135 Write(FILES + player, 1, 72, movebuf); 136 Signal("Helm: %s.", -1, movebuf); 137 } 138 139 boarding() 140 { 141 register int n; 142 int crew[3]; 143 int captured, men = 0; 144 struct shipspecs *ptr; 145 146 ptr = &specs[scene[game].ship[player].shipnum]; 147 crew[0] = ptr -> crew1; 148 crew[1] = ptr -> crew2; 149 crew[2] = ptr -> crew3; 150 for(n=0; n < 3; n++){ 151 if (scene[game].ship[player].file -> OBP[n].turnsent) 152 men += scene[game].ship[player].file -> OBP[n].turnsent; 153 } 154 for(n=0; n < 3; n++){ 155 if (scene[game].ship[player].file -> DBP[n].turnsent) 156 men += scene[game].ship[player].file -> DBP[n].turnsent; 157 } 158 if (men){ 159 crew[0] = men/100 ? 0 : crew[0] != 0; 160 crew[1] = (men%100)/10 ? 0 : crew[1] != 0; 161 crew[2] = men%10 ? 0 : crew[2] != 0; 162 } else { 163 crew[0] = crew[0] != 0; 164 crew[1] = crew[1] != 0; 165 crew[2] = crew[2] != 0; 166 } 167 for (n=0; n < scene[game].vessels; n++){ 168 if ((captured = scene[game].ship[n].file -> captured) < 0) 169 captured = n; 170 if (n != player && pos[n].dir && range(player, n) <= 1 && scene[game].ship[player].nationality != scene[game].ship[captured].nationality){ 171 if (meleeing(player, n) && crew[2]){ 172 Signal("How many more to board the %s (%c%c)? ",n,0); 173 parties(crew, n, 200); 174 } 175 else if ((foul(player, n) || grapple(player, n)) && crew[2]){ 176 Signal("Crew sections to board the %s (%c%c) (3 max) ?", n, 0); 177 parties(crew, n, 200); 178 } 179 } 180 } 181 if (crew[2]){ 182 Signal("How many sections to repel boarders? ", 0, 0); 183 parties(crew, player, 260); 184 } 185 } 186 187 parties(crew, n, offset) 188 int crew[3], n, offset; 189 { 190 register int k, j, men; 191 struct BP * ptr; 192 int buf; 193 int temp[3]; 194 195 for (k=0; k < 3; k++) 196 temp[k] = crew[k]; 197 while((buf = getch()) == EOF); 198 addch(buf); 199 if (isdigit(buf)){ 200 ptr = offset == 200 ? scene[game].ship[player].file -> OBP : scene[game].ship[player].file -> DBP ; 201 for (j = 0; j < 3 && ptr[j].turnsent; j++); 202 if (!ptr[j].turnsent && buf > '0'){ 203 men = 0; 204 for (k=0; k < 3 && buf > '0'; k++){ 205 men += crew[k]*power(10, 2-k); 206 crew[k] = 0; 207 if (men) buf -= 1; 208 } 209 if (buf > '0') 210 Signal("Sending all crew sections.", 0, 0); 211 Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j, turn); 212 Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j + 2, n); 213 Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j + 4, men); 214 switch(offset){ 215 case 200: 216 wmove(slot, 0, 0); 217 for (k=0; k < 3; k++) 218 if (temp[k] && !crew[k]) 219 waddch(slot, k + '1'); 220 else 221 wmove(slot, 0, 1 + k); 222 wmove(slot, 1, 0); 223 waddstr(slot, "OBP"); 224 makesignal("boarding the %s (%c%c)", n, player); 225 break; 226 case 260: 227 wmove(slot, 2, 0); 228 for (k=0; k < 3; k++) 229 if (temp[k] && !crew[k]) 230 waddch(slot, k + '1'); 231 else 232 wmove(slot, 2, 1 + k); 233 wmove(slot, 3, 0); 234 waddstr(slot, "DBP"); 235 makesignal("repelling boarders", 0, player); 236 break; 237 } 238 wrefresh(slot); 239 } 240 else 241 Signal("Sending no crew sections.", 0, 0); 242 } 243 } 244 245 power(base, exp) 246 int base, exp; 247 { 248 switch(exp){ 249 case 0: 250 return(1); 251 case 1: 252 return(base); 253 case 2: 254 return(base * base); 255 } 256 return(0); 257 } 258 259 repair() 260 { 261 int buf; 262 int *repairs; 263 struct shipspecs *ptr; 264 265 if (!repaired && !loaded && !fired && !changed && !turned()){ 266 ptr = &specs[scene[game].ship[player].shipnum]; 267 Signal("Repair (hull, guns, rigging)? ", 0, 0); 268 while((buf = getch()) == EOF); 269 addch(buf); 270 switch(buf){ 271 case 'h': 272 repairs = &scene[game].ship[player].file -> RH; 273 break; 274 case 'g': 275 repairs = &scene[game].ship[player].file -> RG; 276 break; 277 case 'r': 278 repairs = &scene[game].ship[player].file -> RR; 279 break; 280 default: 281 Signal("Avast heaving!", 0, 0); 282 return; 283 } 284 repaired = 1; 285 *repairs += 1; 286 if (*repairs >= 3){ 287 *repairs = 0; 288 } 289 if (!*repairs){ 290 switch(buf){ 291 case 'h': 292 if (ptr -> hull < ptr -> guns/4) 293 Write(SPECS + player, 0, 10, ptr -> hull + 2); 294 else buf = 0; 295 break; 296 case 'g': 297 if (ptr -> gunL < ptr -> gunR){ 298 if (ptr -> gunL + ptr -> carL < ptr -> guns/5) 299 Write(SPECS + player, 0, 20, ptr -> gunL + 2); 300 else buf = 0; 301 } else 302 if (ptr -> gunR + ptr -> carR < ptr -> guns/5) 303 Write(SPECS + player, 0, 22, ptr -> gunR + 2); 304 else buf = 0; 305 break; 306 case 'r': 307 if (!ptr -> rig4) 308 Write(SPECS + player, 0, 34, ptr -> rig4 + 2); 309 else if (!ptr -> rig3) 310 Write(SPECS + player, 0, 32, 2); 311 else if (!ptr -> rig2) 312 Write(SPECS + player, 0, 30, 2); 313 else if (ptr -> rig1 < 4) 314 Write(SPECS + player, 0, 28, 2); 315 else buf = 0; 316 break; 317 } 318 if (!buf) 319 Signal("Repairs completed.", 0, 0); 320 } 321 } 322 else 323 Signal("No hands free to repair",0,0); 324 } 325 326 turned() 327 { 328 register int n; 329 330 for (n=0; movebuf[n]; n++) 331 if (movebuf[n] == 'r' || movebuf[n] == 'l') 332 return(1); 333 return(0); 334 } 335 336 loadplayer() 337 { 338 int buf; 339 int loadL, loadR, ready, load, *Ready, *Load; 340 341 if (!specs[scene[game].ship[player].shipnum].crew3){ 342 Signal("out of crew",0,0); 343 return(0); 344 } 345 Load = &scene[game].ship[player].file -> loadL; 346 Ready = &scene[game].ship[player].file -> readyL; 347 loadL = *Load; 348 loadR = *(Load + 1); 349 if (!loadL && !loadR){ 350 Signal("Load which broadside (left or right)? ", 0, 0); 351 while((buf = getch()) == EOF); 352 addch(buf); 353 if (buf == 'r') 354 loadL = 1; 355 else 356 loadR = 1; 357 } 358 if ((!loadL && loadR || loadL && !loadR)){ 359 Signal("Reload with (round, double, chain, grape)? ", 0, 0); 360 while((buf = getch()) == EOF); 361 addch(buf); 362 switch(buf){ 363 case 'r': 364 load = ROUND; 365 ready = 1; 366 break; 367 case 'd': 368 load = DOUBLE; 369 ready = 2; 370 break; 371 case 'c': 372 load = CHAIN; 373 ready = 1; 374 break; 375 case 'g': 376 load = GRAPE; 377 ready = 1; 378 break; 379 default: 380 Signal("Broadside not loaded.", 0, 0); 381 return; 382 } 383 if (!loadR){ 384 *(Load + 1) = load; 385 *(Ready + 1) = ready; 386 } 387 else { 388 *Load = load; 389 *Ready = ready; 390 } 391 loaded = 1; 392 } 393 } 394 395 changesail() 396 { 397 int buf; 398 int rig, full; 399 400 rig = specs[scene[game].ship[player].shipnum].rig1; 401 full = scene[game].ship[player].file -> FS; 402 if ((windspeed == 6) || (windspeed == 5 && specs[scene[game].ship[player].shipnum].class > 4)) 403 rig = 0; 404 if (specs[scene[game].ship[player].shipnum].crew3 && rig){ 405 if (!full){ 406 Signal("Increase to Full sails? ", 0, 0); 407 while((buf = getch()) == EOF); 408 addch(buf); 409 if (buf == 'y'){ 410 changed = 1; 411 Write(FILES + player, 0, 230, 1); 412 } 413 } 414 else { 415 Signal("Reduce to Battle sails? ", 0, 0); 416 while((buf = getch()) == EOF); 417 addch(buf); 418 if (buf == 'y'){ 419 Write(FILES + player, 0, 230, 0); 420 changed = 1; 421 } 422 } 423 } 424 else if (!rig) 425 Signal("Sails rent to pieces",0,0); 426 } 427 428 429 signalflags() 430 { 431 register int n; 432 433 for(n=0; n < scene[game].vessels; n++){ 434 if (*scene[game].ship[n].file -> signal){ 435 putchar('\7'); 436 Signal("%s (%c%c): %s",n,scene[game].ship[n].file -> signal); 437 *scene[game].ship[n].file -> signal = '\0'; 438 } 439 } 440 } 441 442 iplotships() /* new turn; also plot-ships */ 443 { 444 repaired = loaded = fired = changed = 0; 445 plotships(); 446 } 447 448 449 plotships() /* uses ken's package */ 450 { 451 register int n; 452 char ch; 453 int sternr,sternc; 454 455 getyx(stdscr, ylast, xlast); 456 screen(); 457 readpos(); 458 werase(view); 459 if (pos[player].row < viewrow + 5) 460 viewrow = pos[player].row - ROWSINVIEW + 5; 461 else if (pos[player].row > viewrow + ROWSINVIEW - 5) 462 viewrow = pos[player].row - 5; 463 if (pos[player].col < viewcol + 10) 464 viewcol = pos[player].col - COLSINVIEW + 10; 465 else if (pos[player].col > viewcol + COLSINVIEW - 10) 466 viewcol = pos[player].col - 10; 467 for (n=0; n < scene[game].vessels; n++) 468 if (pos[n].dir && pos[n].row > viewrow && pos[n].row < viewrow + ROWSINVIEW && pos[n].col > viewcol && pos[n].col < viewcol + COLSINVIEW){ 469 wmove(view, pos[n].row - viewrow, pos[n].col - viewcol); 470 waddch(view, colours(n)); 471 ch = sterncolor(n, &sternr, &sternc); 472 wmove(view, sternr - viewrow, sternc - viewcol); 473 waddch(view, ch); 474 } 475 wrefresh(view); 476 move(ylast, xlast); 477 refresh(); 478 } 479 480 acceptsignal() 481 { 482 int ch; 483 char buf[60]; 484 register int n; 485 486 if(scroll == 23) scroll = 18; 487 Signal("Message? ",0,0); 488 buf[0] = 34; 489 n = 1; 490 while((ch = getch()) != '\n'){ 491 if (ch != EOF){ 492 buf[n++] = ch; 493 addch(ch); 494 refresh(); 495 } 496 if (ch == '' && n > 1) 497 n -= 2; 498 } 499 buf[n] = 34; 500 buf[n+1] = '\0'; 501 buf[59] = '\0'; 502 Write(FILES + player, 1, 164, buf); 503 } 504 505 506 board() 507 { 508 register int n; 509 char *name; 510 int class, junk; 511 512 clear(); 513 werase(view); 514 werase(slot); 515 move(1,0); 516 for (n=0; n < 80; n++) 517 addch('-'); 518 move(17,0); 519 for (n=0; n < 80; n++) 520 addch('-'); 521 for (n=2; n < 17; n++){ 522 mvaddch(n, 0,'|'); 523 mvaddch(n, 79, '|'); 524 } 525 mvaddch(1,0,'+'); 526 mvaddch(17,0,'+'); 527 mvaddch(1,79,'+'); 528 mvaddch(17,79,'+'); 529 wmove(view, 2, 27); 530 waddstr(view, "Wooden Ships & Iron Men"); 531 wmove(view, 4, (77 - lengthof(scene[game].name))/2); 532 waddstr(view, scene[game].name); 533 refresh(); 534 wrefresh(view); 535 switch((class = specs[scene[game].ship[player].shipnum].class)){ 536 case 2: 537 case 1: 538 name = "SOL"; 539 break; 540 case 3: 541 case 4: 542 name = "Frigate"; 543 break; 544 case 5: 545 case 6: 546 name = "Sloop"; 547 break; 548 } 549 move(0,0); 550 printw("Class %d %s (%d guns) '%s' (%c%c)", class, name, specs[scene[game].ship[player].shipnum].guns, scene[game].ship[player].shipname, colours(player), sterncolor(player, &junk, &junk)); 551 } 552 553 clearline() 554 { 555 register int n; 556 557 move(scroll-1, 0); 558 for (n=0; n < 59; n++) 559 addch(' '); 560 move(scroll-1, 0); 561 } 562 563 564 565 Signal(fmt, shipnum, string) 566 int shipnum; 567 char *fmt, *string; 568 { 569 int junk; 570 571 move(scroll++, 0); 572 clearline(); 573 if (scroll > 23) scroll = 18; 574 if (shipnum == -1) 575 printw(fmt, string); 576 else if (*string == '*') 577 printw(fmt, "computer", '0','0', string); 578 else 579 printw(fmt, scene[game].ship[shipnum].shipname, colours(shipnum), sterncolor(shipnum, &junk, &junk), string); 580 refresh(); 581 } 582 583 char *quality(shipnum) 584 int shipnum; 585 { 586 switch(specs[scene[game].ship[shipnum].shipnum].qual){ 587 588 case 5: 589 return("elite"); 590 case 4: 591 return("crack"); 592 case 3: 593 return("mundane"); 594 case 2: 595 return("green"); 596 case 1: 597 return("mutinous"); 598 } 599 } 600 601 char *info(ship, final) 602 int ship; 603 char *final; 604 { 605 sprintf(final, "%d gun \0", specs[scene[game].ship[ship].shipnum].guns); 606 switch(specs[scene[game].ship[ship].shipnum].class){ 607 case 1: 608 case 2: 609 strcat(final, "Ship of the Line"); 610 break; 611 case 3: 612 strcat(final, "Frigate"); 613 break; 614 case 4: 615 strcat(final, "Corvette"); 616 break; 617 case 5: 618 strcat(final, "Sloop"); 619 break; 620 case 6: 621 strcat(final, "Brig"); 622 break; 623 } 624 return(final); 625 } 626 627 screen() 628 { 629 int class; 630 register int n; 631 int dr = 0, dc = 0; 632 struct shipspecs *data; 633 struct File *ptr; 634 635 scene[game].ship[player].file -> readyL--; 636 scene[game].ship[player].file -> readyR--; 637 movebuf[0] = '\0'; 638 sync(); 639 if (turn % 50 == 0) 640 Write(SCENARIO, 0, 10, 1); /* still playing */ 641 windspeed = scene[game].windspeed; 642 winddir = scene[game].winddir; 643 turn = scene[game].turn; 644 move(0, 47); 645 ptr = scene[game].ship[player].file; 646 data = &specs[scene[game].ship[player].shipnum]; 647 if (ptr -> FS == 1) 648 Write(FILES + player, 0, 230, 2); 649 printw("Points:%3d Fouls:%2d Grapples:%2d",ptr -> points, fouled(player), grappled(player)); 650 move(17, 36); 651 printw("Turn %d", turn); 652 move(18, 59); 653 printw("Load %c%c %c%c", symbol(ptr -> loadL), iinitial(ptr -> readyL), symbol(ptr -> loadR), iinitial(ptr -> readyR)); 654 move(19, 59); 655 printw("Hull %2d", data -> hull); 656 move(20, 59); 657 printw("Crew %2d %2d %2d", data -> crew1, data -> crew2, data -> crew3); 658 move(21, 59); 659 printw("Guns %2d %2d", data -> gunL, data -> gunR); 660 move(22, 59); 661 printw("Carr %2d %2d", data -> carR, data -> carL); 662 move(23, 59); 663 printw("Rigg %d %d %d ", data -> rig1, data -> rig2, data -> rig3); 664 if (data -> rig4 < 0) 665 addch('-'); 666 else 667 printw("%d", data -> rig4); 668 move(18, 74); 669 printw("0 %d(%d)", maxmove(player, winddir + 3, -1), maxmove(player, winddir + 3, 1)); 670 move(19, 73); 671 addstr("\\|/"); 672 move(20, 73); 673 printw("-^-%d(%d)", maxmove(player, winddir + 2, -1), maxmove(player, winddir + 2, 1)); 674 move(21, 73); 675 addstr("/|\\"); 676 move(22, 74); 677 printw("| %d(%d)", maxmove(player, winddir + 1, -1), maxmove(player, winddir + 1, 1)); 678 move(23, 73); 679 printw("%d(%d)", maxmove(player, winddir, -1), maxmove(player, winddir, 1)); 680 refresh(); 681 if (!boarders(player, 0)){ 682 wmove(slot, 0, 0); 683 waddstr(slot, " "); 684 wmove(slot, 1, 0); 685 waddstr(slot, " "); 686 } else { 687 wmove(slot, 1, 0); 688 waddstr(slot, "OBP"); 689 } 690 if (!boarders(player, 1)){ 691 wmove(slot, 2, 0); 692 waddstr(slot, " "); 693 wmove(slot, 3, 0); 694 waddstr(slot, " "); 695 } else { 696 wmove(slot, 3, 0); 697 waddstr(slot, "DBP"); 698 } 699 wmove(slot, 12, 0); 700 if (n = scene[game].ship[player].file -> RH) 701 wprintw(slot, "%dRH", n); 702 else 703 waddstr(slot, " "); 704 wmove(slot, 13, 0); 705 if (n = scene[game].ship[player].file -> RG) 706 wprintw(slot, "%dRG", n); 707 else 708 waddstr(slot, " "); 709 wmove(slot, 14, 0); 710 if (n = scene[game].ship[player].file -> RR) 711 wprintw(slot, "%dRR", n); 712 else 713 waddstr(slot, " "); 714 wmove(slot, 7, 1); 715 wprintw(slot,"%d", windspeed); 716 drdc(&dr, &dc, winddir); 717 wmove(slot, 7, 0); waddch(slot, ' '); 718 wmove(slot, 7, 2); waddch(slot, ' '); 719 wmove(slot, 6, 0); waddch(slot, ' '); 720 wmove(slot, 6, 1); waddch(slot, ' '); 721 wmove(slot, 6, 2); waddch(slot, ' '); 722 wmove(slot, 8, 0); waddch(slot, ' '); 723 wmove(slot, 8, 1); waddch(slot, ' '); 724 wmove(slot, 8, 2); waddch(slot, ' '); 725 wmove(slot, (7 - dr), (1 - dc)); 726 switch(winddir){ 727 case 1: 728 case 5: 729 waddch(slot, '|'); 730 break; 731 case 2: 732 case 6: 733 waddch(slot, '/'); 734 break; 735 case 3: 736 case 7: 737 waddch(slot, '-'); 738 break; 739 case 4: 740 case 8: 741 waddch(slot, '\\'); 742 break; 743 } 744 wmove(slot, (7 + dr), (1 + dc)); 745 waddch(slot, '+'); 746 wrefresh(slot); 747 signal(SIGALRM, iplotships); /* new turn and plot-ships */ 748 alarm(7); 749 } 750 751 extern char iinitial(ready) 752 int ready; 753 { 754 if (ready <= -30000) 755 return('!'); 756 if (ready > 0) 757 return('*'); 758 return(' '); 759 } 760 761 char symbol(number) 762 int number; 763 { 764 switch(number){ 765 case GRAPE: 766 return('G'); 767 case ROUND: 768 return('R'); 769 case DOUBLE: 770 return('D'); 771 case CHAIN: 772 return('C'); 773 } 774 return('-'); 775 } 776 777