+#ifndef lint
+static char *sccsid = "@(#)pl_2.c 1.1 83/03/17";
+#endif
+#include "player.h"
+
+#define turnfirst(buf) (*buf == 'r' || *buf == 'l')
+
+lost()
+{
+ if (scene[game].ship[player].file -> struck)
+ leave(0);
+ if (scene[game].ship[player].file -> captured > -1)
+ leave(1);
+ if (windspeed == 7)
+ leave(3);
+ if(scene[game].ship[player].file -> FS && (!specs[scene[game].ship[player].shipnum].rig1 || windspeed == 6))
+ Write(FILES + player, 0, 230, 0);
+}
+
+
+acceptmove(ma, ta, af)
+int ma, ta, af;
+{
+ register int n;
+ int moved = 0;
+ int full, vma, dir, ch;
+ char buf[60], last = '\0';
+
+ if (scroll >= 22) scroll = 18;
+ move(scroll++, 0);
+ clearline();
+ printw("move (%d,%c%d): ", ma, (af ? '\'' : ' '), ta);
+ refresh();
+ n = 0;
+ while((ch = getch()) != '\n'){
+ if (ch != EOF){
+ buf[n++] = ch;
+ addch(ch);
+ refresh();
+ }
+ if(ch == '\b' && n > 1)
+ n -= 2;
+ }
+ buf[n] = '\0';
+ buf[9] = '\0';
+ dir = pos[player].dir;
+ vma = ma;
+ for (n = 0; buf[n]; n++)
+ if (!(buf[n] == 'r' || buf[n] == '\n' || buf[n] == 'l' || (buf[n] == '0' && !n) || isdigit(buf[n]) || buf[n] == 'b' || (buf[n] == 'd' && !n))){
+ if (isspace(buf[n])){
+ strcpy(buf+n, buf+n+1);
+ n--;
+ } else {
+ Signal("Syntax error.",0,0);
+ buf[n--] = '\0';
+ }
+ }
+ else
+ switch(buf[n]){
+ case 'l':
+ dir -= 2;
+ case 'r':
+ dir++;
+ if (!dir) dir = 8;
+ if (dir == 9) dir = 1;
+ if (last == 't'){
+ Signal("Error; ship can't turn that fast.", 0, 0);
+ buf[n--] = '\0';
+ }
+ last = 't';
+ ma--;
+ ta--;
+ vma = min(ma, maxmove(player, dir, 0));
+ if (ta < 0 && moved || vma < 0 && moved)
+ buf[n--] = '\0';
+ break;
+
+ case 'b':
+ ma--;
+ vma--;
+ last = 'b';
+ if (ta < 0 && moved || vma < 0 && moved)
+ buf[n--] = '\0';
+ break;
+
+ case '0':
+ case 'd':
+ buf[n--] = '\0';
+ break;
+
+ case '\n':
+ buf[n] = '\0';
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ if (last == '0'){
+ Signal("Error; value out of range.", 0, 0);
+ buf[n--] = '\0';
+ }
+ last = '0';
+ moved = 1;
+ ma -= buf[n] - '0';
+ vma -= buf[n] - '0';
+ if (ta < 0 && moved || vma < 0 && moved)
+ buf[n--] = '\0';
+ break;
+
+ } /* end switch and else and for */
+ if (ta < 0 && moved || vma < 0 && moved || af && turnfirst(buf) && moved){
+ Signal("Movement error.", 0, 0);
+ if (ta < 0 && moved){
+ if (scene[game].ship[player].file -> FS == 1){
+ Write(FILES + player, 0, 230, 0);
+ Signal("No hands to set full sails.", 0, 0);
+ }
+ }
+ else if (ma >= 0)
+ buf[1] = '\0';
+ }
+ if (af && !moved){
+ if (scene[game].ship[player].file -> FS == 1){
+ Write(FILES + player, 0, 230, 0);
+ Signal("No hands to set full sails.", 0, 0);
+ }
+ }
+ strcpy(movebuf, buf);
+ if (!*movebuf) strcpy(movebuf, "d");
+ Write(FILES + player, 1, 72, movebuf);
+ Signal("Helm: %s.", -1, movebuf);
+}
+
+boarding()
+{
+ register int n, crew[3];
+ int captured, men = 0;
+ struct shipspecs *ptr;
+
+ ptr = &specs[scene[game].ship[player].shipnum];
+ crew[0] = ptr -> crew1;
+ crew[1] = ptr -> crew2;
+ crew[2] = ptr -> crew3;
+ for(n=0; n < 3; n++){
+ if (scene[game].ship[player].file -> OBP[n].turnsent)
+ men += scene[game].ship[player].file -> OBP[n].turnsent;
+ }
+ for(n=0; n < 3; n++){
+ if (scene[game].ship[player].file -> DBP[n].turnsent)
+ men += scene[game].ship[player].file -> DBP[n].turnsent;
+ }
+ 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;
+ }
+ for (n=0; n < scene[game].vessels; n++){
+ if ((captured = scene[game].ship[n].file -> captured) < 0)
+ captured = n;
+ if (n != player && pos[n].dir && range(player, n) <= 1 && scene[game].ship[player].nationality != scene[game].ship[captured].nationality){
+ if (meleeing(player, n) && crew[2]){
+ Signal("How many more to board the %s (%c%c)? ",n,0);
+ parties(crew, n, 200);
+ }
+ else if ((foul(player, n) || grapple(player, n)) && crew[2]){
+ Signal("Crew sections to board the %s (%c%c) (3 max) ?", n, 0);
+ parties(crew, n, 200);
+ }
+ }
+ }
+ if (crew[2]){
+ Signal("How many sections to repel boarders? ", 0, 0);
+ parties(crew, player, 260);
+ }
+}
+
+parties(crew, n, offset)
+int crew[3], n, offset;
+{
+ register int k, j, men;
+ struct BP * ptr;
+ int buf;
+ int temp[3];
+
+ for (k=0; k < 3; k++)
+ temp[k] = crew[k];
+ while((buf = getch()) == EOF);
+ addch(buf);
+ if (isdigit(buf)){
+ ptr = offset == 200 ? scene[game].ship[player].file -> OBP : scene[game].ship[player].file -> DBP ;
+ for (j = 0; j < 3 && ptr[j].turnsent; j++);
+ if (!ptr[j].turnsent && buf > '0'){
+ men = 0;
+ for (k=0; k < 3 && buf > '0'; k++){
+ men += crew[k]*power(10, 2-k);
+ crew[k] = 0;
+ if (men) buf -= 1;
+ }
+ if (buf > '0')
+ Signal("Sending all crew sections.", 0, 0);
+ Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j, turn);
+ Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j + 2, n);
+ Write(FILES + player, 0, 30 + (offset > 200)*18 + 6*j + 4, men);
+ switch(offset){
+ case 200:
+ wmove(slot, 0, 0);
+ for (k=0; k < 3; k++)
+ if (temp[k] && !crew[k])
+ waddch(slot, k + '1');
+ else
+ wmove(slot, 0, 1 + k);
+ wmove(slot, 1, 0);
+ waddstr(slot, "OBP");
+ makesignal("boarding the %s (%c%c)", n, player);
+ break;
+ case 260:
+ wmove(slot, 2, 0);
+ for (k=0; k < 3; k++)
+ if (temp[k] && !crew[k])
+ waddch(slot, k + '1');
+ else
+ wmove(slot, 2, 1 + k);
+ wmove(slot, 3, 0);
+ waddstr(slot, "DBP");
+ makesignal("repelling boarders", 0, player);
+ break;
+ }
+ wrefresh(slot);
+ }
+ else
+ Signal("Sending no crew sections.", 0, 0);
+ }
+}
+
+power(base, exp)
+int base, exp;
+{
+ switch(exp){
+ case 0:
+ return(1);
+ case 1:
+ return(base);
+ case 2:
+ return(base * base);
+ }
+ return(0);
+}
+
+repair()
+{
+ int buf;
+ int *repairs;
+ struct shipspecs *ptr;
+
+ if (!repaired && !loaded && !fired && !changed && !turned()){
+ ptr = &specs[scene[game].ship[player].shipnum];
+ Signal("Repair (hull, guns, rigging)? ", 0, 0);
+ while((buf = getch()) == EOF);
+ addch(buf);
+ switch(buf){
+ case 'h':
+ repairs = &scene[game].ship[player].file -> RH;
+ break;
+ case 'g':
+ repairs = &scene[game].ship[player].file -> RG;
+ break;
+ case 'r':
+ repairs = &scene[game].ship[player].file -> RR;
+ break;
+ default:
+ Signal("Avast heaving!", 0, 0);
+ return;
+ }
+ repaired = 1;
+ *repairs += 1;
+ if (*repairs >= 3){
+ *repairs = 0;
+ }
+ if (!*repairs){
+ switch(buf){
+ case 'h':
+ if (ptr -> hull < ptr -> guns/4)
+ Write(SPECS + player, 0, 10, ptr -> hull + 2);
+ else buf = 0;
+ break;
+ case 'g':
+ if (ptr -> gunL < ptr -> gunR){
+ if (ptr -> gunL + ptr -> carL < ptr -> guns/5)
+ Write(SPECS + player, 0, 20, ptr -> gunL + 2);
+ else buf = 0;
+ } else
+ if (ptr -> gunR + ptr -> carR < ptr -> guns/5)
+ Write(SPECS + player, 0, 22, ptr -> gunR + 2);
+ else buf = 0;
+ break;
+ case 'r':
+ if (!ptr -> rig4)
+ Write(SPECS + player, 0, 34, ptr -> rig4 + 2);
+ else if (!ptr -> rig3)
+ Write(SPECS + player, 0, 32, 2);
+ else if (!ptr -> rig2)
+ Write(SPECS + player, 0, 30, 2);
+ else if (ptr -> rig1 < 4)
+ Write(SPECS + player, 0, 28, 2);
+ else buf = 0;
+ break;
+ }
+ if (!buf)
+ Signal("Repairs completed.", 0, 0);
+ }
+ }
+ else
+ Signal("No hands free to repair",0,0);
+}
+
+turned()
+{
+ register int n;
+
+ for (n=0; movebuf[n]; n++)
+ if (movebuf[n] == 'r' || movebuf[n] == 'l')
+ return(1);
+ return(0);
+}
+
+loadplayer()
+{
+ int buf;
+ int loadL, loadR, ready, load, *Ready, *Load;
+
+ if (!specs[scene[game].ship[player].shipnum].crew3){
+ Signal("out of crew",0,0);
+ return(0);
+ }
+ Load = &scene[game].ship[player].file -> loadL;
+ Ready = &scene[game].ship[player].file -> readyL;
+ loadL = *Load;
+ loadR = *(Load + 1);
+ if (!loadL && !loadR){
+ Signal("Load which broadside (left or right)? ", 0, 0);
+ while((buf = getch()) == EOF);
+ addch(buf);
+ if (buf == 'r')
+ loadL = 1;
+ else
+ loadR = 1;
+ }
+ if ((!loadL && loadR || loadL && !loadR)){
+ Signal("Reload with (round, double, chain, grape)? ", 0, 0);
+ while((buf = getch()) == EOF);
+ addch(buf);
+ switch(buf){
+ case 'r':
+ load = ROUND;
+ ready = 1;
+ break;
+ case 'd':
+ load = DOUBLE;
+ ready = 2;
+ break;
+ case 'c':
+ load = CHAIN;
+ ready = 1;
+ break;
+ case 'g':
+ load = GRAPE;
+ ready = 1;
+ break;
+ default:
+ Signal("Broadside not loaded.", 0, 0);
+ return;
+ }
+ if (!loadR){
+ *(Load + 1) = load;
+ *(Ready + 1) = ready;
+ }
+ else {
+ *Load = load;
+ *Ready = ready;
+ }
+ loaded = 1;
+ }
+}
+
+changesail()
+{
+ int buf;
+ int rig, full;
+
+ rig = specs[scene[game].ship[player].shipnum].rig1;
+ full = scene[game].ship[player].file -> FS;
+ if ((windspeed == 6) || (windspeed == 5 && specs[scene[game].ship[player].shipnum].class > 4))
+ rig = 0;
+ if (specs[scene[game].ship[player].shipnum].crew3 && rig){
+ if (!full){
+ Signal("Increase to Full sails? ", 0, 0);
+ while((buf = getch()) == EOF);
+ addch(buf);
+ if (buf == 'y'){
+ changed = 1;
+ Write(FILES + player, 0, 230, 1);
+ }
+ }
+ else {
+ Signal("Reduce to Battle sails? ", 0, 0);
+ while((buf = getch()) == EOF);
+ addch(buf);
+ if (buf == 'y'){
+ Write(FILES + player, 0, 230, 0);
+ changed = 1;
+ }
+ }
+ }
+ else if (!rig)
+ Signal("Sails rent to pieces",0,0);
+}
+
+
+signalflags()
+{
+ register int n;
+
+ for(n=0; n < scene[game].vessels; n++){
+ if (*scene[game].ship[n].file -> signal){
+ putchar('\7');
+ Signal("%s (%c%c): %s",n,scene[game].ship[n].file -> signal);
+ *scene[game].ship[n].file -> signal = '\0';
+ }
+ }
+}
+
+iplotships() /* new turn; also plot-ships */
+{
+ repaired = loaded = fired = changed = 0;
+ plotships();
+}
+
+
+plotships() /* uses ken's package */
+{
+ register int n;
+ char ch;
+ int sternr,sternc;
+
+ getyx(stdscr, ylast, xlast);
+ screen();
+ readpos();
+ werase(view);
+ if (pos[player].row < viewrow + 5)
+ viewrow = pos[player].row - ROWSINVIEW + 5;
+ else if (pos[player].row > viewrow + ROWSINVIEW - 5)
+ viewrow = pos[player].row - 5;
+ if (pos[player].col < viewcol + 10)
+ viewcol = pos[player].col - COLSINVIEW + 10;
+ else if (pos[player].col > viewcol + COLSINVIEW - 10)
+ viewcol = pos[player].col - 10;
+ for (n=0; n < scene[game].vessels; n++)
+ if (pos[n].dir && pos[n].row > viewrow && pos[n].row < viewrow + ROWSINVIEW && pos[n].col > viewcol && pos[n].col < viewcol + COLSINVIEW){
+ wmove(view, pos[n].row - viewrow, pos[n].col - viewcol);
+ waddch(view, colours(n));
+ ch = sterncolor(n, &sternr, &sternc);
+ wmove(view, sternr - viewrow, sternc - viewcol);
+ waddch(view, ch);
+ }
+ wrefresh(view);
+ move(ylast, xlast);
+ refresh();
+}
+
+acceptsignal()
+{
+ int ch;
+ char buf[60];
+ register int n;
+
+ if(scroll == 23) scroll = 18;
+ Signal("Message? ",0,0);
+ buf[0] = 34;
+ n = 1;
+ while((ch = getch()) != '\n'){
+ if (ch != EOF){
+ buf[n++] = ch;
+ addch(ch);
+ refresh();
+ }
+ if (ch == '\b' && n > 1)
+ n -= 2;
+ }
+ buf[n] = 34;
+ buf[n+1] = '\0';
+ buf[59] = '\0';
+ Write(FILES + player, 1, 164, buf);
+}
+
+
+board()
+{
+ register int n;
+ char *name;
+ int class, junk;
+
+ clear();
+ werase(view);
+ werase(slot);
+ move(1,0);
+ for (n=0; n < 80; n++)
+ addch('-');
+ move(17,0);
+ for (n=0; n < 80; n++)
+ addch('-');
+ for (n=2; n < 17; n++){
+ mvaddch(n, 0,'|');
+ mvaddch(n, 79, '|');
+ }
+ mvaddch(1,0,'+');
+ mvaddch(17,0,'+');
+ mvaddch(1,79,'+');
+ mvaddch(17,79,'+');
+ wmove(view, 2, 27);
+ waddstr(view, "Wooden Ships & Iron Men");
+ wmove(view, 4, (77 - lengthof(scene[game].name))/2);
+ waddstr(view, scene[game].name);
+ refresh();
+ wrefresh(view);
+ switch((class = specs[scene[game].ship[player].shipnum].class)){
+ case 2:
+ case 1:
+ name = "SOL";
+ break;
+ case 3:
+ case 4:
+ name = "Frigate";
+ break;
+ case 5:
+ case 6:
+ name = "Sloop";
+ break;
+ }
+ move(0,0);
+ 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));
+}
+
+clearline()
+{
+ register int n;
+
+ move(scroll-1, 0);
+ for (n=0; n < 59; n++)
+ addch(' ');
+ move(scroll-1, 0);
+}
+
+
+
+Signal(fmt, shipnum, string)
+int shipnum;
+char *fmt, *string;
+{
+ int junk;
+
+ move(scroll++, 0);
+ clearline();
+ if (scroll > 23) scroll = 18;
+ if (shipnum == -1)
+ printw(fmt, string);
+ else if (*string == '*')
+ printw(fmt, "computer", '0','0', string);
+ else
+ printw(fmt, scene[game].ship[shipnum].shipname, colours(shipnum), sterncolor(shipnum, &junk, &junk), string);
+ refresh();
+}
+
+char *quality(shipnum)
+int shipnum;
+{
+ switch(specs[scene[game].ship[shipnum].shipnum].qual){
+
+ case 5:
+ return("elite");
+ case 4:
+ return("crack");
+ case 3:
+ return("mundane");
+ case 2:
+ return("green");
+ case 1:
+ return("mutinous");
+ }
+}
+
+char *info(ship, final)
+int ship;
+char *final;
+{
+ sprintf(final, "%d gun \0", specs[scene[game].ship[ship].shipnum].guns);
+ switch(specs[scene[game].ship[ship].shipnum].class){
+ case 1:
+ case 2:
+ strcat(final, "Ship of the Line");
+ break;
+ case 3:
+ strcat(final, "Frigate");
+ break;
+ case 4:
+ strcat(final, "Corvette");
+ break;
+ case 5:
+ strcat(final, "Sloop");
+ break;
+ case 6:
+ strcat(final, "Brig");
+ break;
+ }
+ return(final);
+}
+
+screen()
+{
+ int class;
+ register int n;
+ int dr = 0, dc = 0;
+ struct shipspecs *data;
+ struct File *ptr;
+
+ scene[game].ship[player].file -> readyL--;
+ scene[game].ship[player].file -> readyR--;
+ movebuf[0] = '\0';
+ sync();
+ if (turn % 50 == 0)
+ Write(SCENARIO, 0, 10, 1); /* still playing */
+ windspeed = scene[game].windspeed;
+ winddir = scene[game].winddir;
+ turn = scene[game].turn;
+ move(0, 47);
+ ptr = scene[game].ship[player].file;
+ data = &specs[scene[game].ship[player].shipnum];
+ if (ptr -> FS == 1)
+ Write(FILES + player, 0, 230, 2);
+ printw("Points:%3d Fouls:%2d Grapples:%2d",ptr -> points, fouled(player), grappled(player));
+ move(17, 36);
+ printw("Turn %d", turn);
+ move(18, 59);
+ printw("Load %c%c %c%c", symbol(ptr -> loadL), iinitial(ptr -> readyL), symbol(ptr -> loadR), iinitial(ptr -> readyR));
+ move(19, 59);
+ printw("Hull %2d", data -> hull);
+ move(20, 59);
+ printw("Crew %2d %2d %2d", data -> crew1, data -> crew2, data -> crew3);
+ move(21, 59);
+ printw("Guns %2d %2d", data -> gunL, data -> gunR);
+ move(22, 59);
+ printw("Carr %2d %2d", data -> carR, data -> carL);
+ move(23, 59);
+ printw("Rigg %d %d %d ", data -> rig1, data -> rig2, data -> rig3);
+ if (data -> rig4 < 0)
+ addch('-');
+ else
+ printw("%d", data -> rig4);
+ move(18, 74);
+ printw("0 %d(%d)", maxmove(player, winddir + 3, -1), maxmove(player, winddir + 3, 1));
+ move(19, 73);
+ addstr("\\|/");
+ move(20, 73);
+ printw("-^-%d(%d)", maxmove(player, winddir + 2, -1), maxmove(player, winddir + 2, 1));
+ move(21, 73);
+ addstr("/|\\");
+ move(22, 74);
+ printw("| %d(%d)", maxmove(player, winddir + 1, -1), maxmove(player, winddir + 1, 1));
+ move(23, 73);
+ printw("%d(%d)", maxmove(player, winddir, -1), maxmove(player, winddir, 1));
+ refresh();
+ if (!boarders(player, 0)){
+ wmove(slot, 0, 0);
+ waddstr(slot, " ");
+ wmove(slot, 1, 0);
+ waddstr(slot, " ");
+ } else {
+ wmove(slot, 1, 0);
+ waddstr(slot, "OBP");
+ }
+ if (!boarders(player, 1)){
+ wmove(slot, 2, 0);
+ waddstr(slot, " ");
+ wmove(slot, 3, 0);
+ waddstr(slot, " ");
+ } else {
+ wmove(slot, 3, 0);
+ waddstr(slot, "DBP");
+ }
+ wmove(slot, 12, 0);
+ if (n = scene[game].ship[player].file -> RH)
+ wprintw(slot, "%dRH", n);
+ else
+ waddstr(slot, " ");
+ wmove(slot, 13, 0);
+ if (n = scene[game].ship[player].file -> RG)
+ wprintw(slot, "%dRG", n);
+ else
+ waddstr(slot, " ");
+ wmove(slot, 14, 0);
+ if (n = scene[game].ship[player].file -> RR)
+ wprintw(slot, "%dRR", n);
+ else
+ waddstr(slot, " ");
+ wmove(slot, 7, 1);
+ wprintw(slot,"%d", windspeed);
+ drdc(&dr, &dc, winddir);
+ wmove(slot, 7, 0); waddch(slot, ' ');
+ wmove(slot, 7, 2); waddch(slot, ' ');
+ wmove(slot, 6, 0); waddch(slot, ' ');
+ wmove(slot, 6, 1); waddch(slot, ' ');
+ wmove(slot, 6, 2); waddch(slot, ' ');
+ wmove(slot, 8, 0); waddch(slot, ' ');
+ wmove(slot, 8, 1); waddch(slot, ' ');
+ wmove(slot, 8, 2); waddch(slot, ' ');
+ wmove(slot, (7 - dr), (1 - dc));
+ switch(winddir){
+ case 1:
+ case 5:
+ waddch(slot, '|');
+ break;
+ case 2:
+ case 6:
+ waddch(slot, '/');
+ break;
+ case 3:
+ case 7:
+ waddch(slot, '-');
+ break;
+ case 4:
+ case 8:
+ waddch(slot, '\\');
+ break;
+ }
+ wmove(slot, (7 + dr), (1 + dc));
+ waddch(slot, '+');
+ wrefresh(slot);
+ signal(SIGALRM, iplotships); /* new turn and plot-ships */
+ alarm(7);
+}
+
+extern char iinitial(ready)
+int ready;
+{
+ if (ready <= -30000)
+ return('!');
+ if (ready > 0)
+ return('*');
+ return(' ');
+}
+
+char symbol(number)
+int number;
+{
+ switch(number){
+ case GRAPE:
+ return('G');
+ case ROUND:
+ return('R');
+ case DOUBLE:
+ return('D');
+ case CHAIN:
+ return('C');
+ }
+ return('-');
+}
+