static void parties(int crew[3], struct ship *to, char isdefense, char buf) { int k, j, men; struct BP *ptr; int temp[3]; for (k = 0; k < 3; k++) temp[k] = crew[k]; if (isdigit(buf)) { ptr = isdefense ? to->file->DBP : to->file->OBP; for (j = 0; j < NBP && ptr[j].turnsent; j++) ; if (!ptr[j].turnsent && buf > '0') { men = 0; for (k = 0; k < 3 && buf > '0'; k++) { men += crew[k] * (k == 0 ? 100 : (k == 1 ? 10 : 1)); crew[k] = 0; if (men) buf--; } if (buf > '0') Signal("Sending all crew sections.", NULL); Write(isdefense ? W_DBP : W_OBP, ms, j, turn, to->file->index, men); if (isdefense) { wmove(slot_w, 2, 0); for (k=0; k < NBP; k++) if (temp[k] && !crew[k]) waddch(slot_w, k + '1'); else wmove(slot_w, 2, 1 + k); mvwaddstr(slot_w, 3, 0, "DBP"); makesignal(ms, "repelling boarders", NULL); } else { wmove(slot_w, 0, 0); for (k=0; k < NBP; k++) if (temp[k] && !crew[k]) waddch(slot_w, k + '1'); else wmove(slot_w, 0, 1 + k); mvwaddstr(slot_w, 1, 0, "OBP"); makesignal(ms, "boarding the %s (%c%c)", to); } blockalarm(); wrefresh(slot_w); unblockalarm(); } else Signal("Sending no crew sections.", NULL); } }
checkup() { register struct ship *sp, *sq; register char explode, sink; foreachship(sp) { if (sp->file->dir == 0) continue; explode = sp->file->explode; sink = sp->file->sink; if (explode != 1 && sink != 1) continue; if (die() < 5) continue; Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0); Write(W_DIR, sp, 0, 0, 0, 0, 0); if (snagged(sp)) foreachship(sq) cleansnag(sp, sq, 1); if (sink != 1) { makesignal(sp, "exploding!", (struct ship *)0); foreachship(sq) { if (sp != sq && sq->file->dir && range(sp, sq) < 4) table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6); } } else
void grap(struct ship *from, struct ship *to) { if (capship(from)->nationality != capship(to)->nationality && die() > 2) return; Write(W_GRAP, from, to->file->index, 0, 0, 0); Write(W_GRAP, to, from->file->index, 0, 0, 0); makesignal(from, "grappled with $$", to); }
checkup() { register int k, n, explode, sink; readpos(); for (n=0; n < scene[game].vessels; n++){ explode = scene[game].ship[n].file -> explode; sink = scene[game].ship[n].file -> sink; if (die() >= 5 && (explode == 1 || sink == 1)){ explode = 2; if (sink != 1) Write(FILES + n, 0, 232, explode); else Write(FILES + n, 0, 234, explode); pos[n].dir = 0; /* hopefully enough to kill ship */ Write(n, 0, 10, 0); if (fouled(n) || grappled(n)){ for (k=0; k < 10; k++){ if (scene[game].ship[n].file -> fouls[k].turnfoul) cleanfoul(n,scene[game].ship[n].file -> fouls[k].toship,k); } for (k=0; k < 10; k++){ if (scene[game].ship[n].file -> grapples[k].turnfoul) cleangrapple(n,scene[game].ship[n].file -> grapples[k].toship,k); } } if (sink != 1){ makesignal("exploding!", 0, n); for (k=0; k < scene[game].vessels; k++) if (k != n && pos[k].dir && range(n,k) < 4) table(RIGGING, EXPLODE, specs[scene[game].ship[n].shipnum].guns/13, k, n, 6); } else { makesignal("sinking!", 0, n); } } } }
void ungrap(struct ship *from, struct ship *to) { int k; char friend; if ((k = grappled2(from, to)) == 0) return; friend = capship(from)->nationality == capship(to)->nationality; while (--k >= 0) { if (friend || die() < 3) { cleangrapple(from, to, 0); makesignal(from, "ungrappling $$", to); } } }
/* * If we get here before a ship is chosen, then ms == 0 and * we don't want to update the score file, or do any Write's either. * We can assume the sync file is already created and may need * to be removed. * Of course, we don't do any more Sync()'s if we got here * because of a Sync() failure. */ void leave(int conditions) { signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGALRM, SIG_IGN); signal(SIGCHLD, SIG_IGN); if (done_curses) { Signal("It looks like you've had it!", NULL); switch (conditions) { case LEAVE_QUIT: break; case LEAVE_CAPTURED: Signal("Your ship was captured.", NULL); break; case LEAVE_HURRICAN: Signal("Hurricane! All ships destroyed.", NULL); break; case LEAVE_DRIVER: Signal("The driver died.", NULL); break; case LEAVE_SYNC: Signal("Synchronization error.", NULL); break; default: Signal("A funny thing happened (%d).", NULL, conditions); } } else { switch (conditions) { case LEAVE_QUIT: break; case LEAVE_DRIVER: printf("The driver died.\n"); break; case LEAVE_FORK: perror("fork"); break; case LEAVE_SYNC: printf("Synchronization error\n."); break; default: printf("A funny thing happened (%d).\n", conditions); } } if (ms != 0) { write_log(ms); if (conditions != LEAVE_SYNC) { makesignal(ms, "Captain %s relinquishing.", NULL, mf->captain); Write(W_END, ms, 0, 0, 0, 0); Sync(); } } sync_close(!hasdriver); cleanupscreen(); exit(0); }
void table(int rig, int shot, int hittable, struct ship *on, struct ship *from, int roll) { int hhits = 0, chits = 0, ghits = 0, rhits = 0; int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; int guns, car, pc, hull; int crew[3]; int n; int rigg[4]; const char *message = NULL; struct Tables *tp; pc = on->file->pcrew; hull = on->specs->hull; crew[0] = on->specs->crew1; crew[1] = on->specs->crew2; crew[2] = on->specs->crew3; rigg[0] = on->specs->rig1; rigg[1] = on->specs->rig2; rigg[2] = on->specs->rig3; rigg[3] = on->specs->rig4; if (shot == L_GRAPE) { Chit = chits = hittable; } else { tp = &(rig ? RigTable : HullTable)[hittable][roll-1]; Chit = chits = tp->C; Rhit = rhits = tp->R; Hhit = hhits = tp->H; Ghit = ghits = tp->G; if (on->file->FS) rhits *= 2; if (shot == L_CHAIN) { Ghit = ghits = 0; Hhit = hhits = 0; } } if (on->file->captured != 0) { pc -= (chits + 1) / 2; chits /= 2; } for (n = 0; n < 3; n++) { if (chits > crew[n]) { chits -= crew[n]; crew[n] = 0; } else { crew[n] -= chits; chits = 0; } } for (n = 0; n < 3; n++) { if (rhits > rigg[n]) { rhits -= rigg[n]; rigg[n] = 0; } else { rigg[n] -= rhits; rhits = 0; } } if (rigg[3] != -1 && rhits > rigg[3]) { rhits -= rigg[3]; rigg[3] = 0; } else if (rigg[3] != -1) { rigg[3] -= rhits; } if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1)) makesignal(on, "dismasted!", NULL); if (portside(from, on, 0)) { guns = on->specs->gunR; car = on->specs->carR; } else { guns = on->specs->gunL; car = on->specs->carL; } if (ghits > car) { ghits -= car; car = 0; } else { car -= ghits; ghits = 0; } if (ghits > guns) { ghits -= guns; guns = 0; } else { guns -= ghits; ghits = 0; } hull -= ghits; if (Ghit) Write(portside(from, on, 0) ? W_GUNR : W_GUNL, on, guns, car, 0, 0); hull -= hhits; hull = hull < 0 ? 0 : hull; if (on->file->captured != 0 && Chit) Write(W_PCREW, on, pc, 0, 0, 0); if (Hhit) Write(W_HULL, on, hull, 0, 0, 0); if (Chit) Write(W_CREW, on, crew[0], crew[1], crew[2], 0); if (Rhit) Write(W_RIGG, on, rigg[0], rigg[1], rigg[2], rigg[3]); switch (shot) { case L_ROUND: message = "firing round shot on %s (%c%c)"; break; case L_GRAPE: message = "firing grape shot on %s (%c%c)"; break; case L_CHAIN: message = "firing chain shot on %s (%c%c)"; break; case L_DOUBLE: message = "firing double shot on %s (%c%c)"; break; case L_EXPLODE: message = "exploding shot on %s (%c%c)"; } makesignal(from, message, on); if (roll == 6 && rig) { switch(Rhit) { case 0: message = "fore topsail sheets parted"; break; case 1: message = "mizzen shrouds parted"; break; case 2: message = "main topsail yard shot away"; break; case 4: message = "fore topmast and foremast shrouds shot away"; break; case 5: message = "mizzen mast and yard shot through"; break; case 6: message = "foremast and spritsail yard shattered"; break; case 7: message = "main topmast and mizzen mast shattered"; break; } makesignal(on, message, NULL); } else if (roll == 6) { switch (Hhit) { case 0: message = "anchor cables severed"; break; case 1: message = "two anchor stocks shot away"; break; case 2: message = "quarterdeck bulwarks damaged"; break; case 3: message = "three gun ports shot away"; break; case 4: message = "four guns dismounted"; break; case 5: message = "rudder cables shot through"; Write(W_TA, on, 0, 0, 0, 0); break; case 6: message = "shot holes below the water line"; break; } makesignal(on, message, NULL); } if (!hull) strike(on, from); }
void moveall() /* move all comp ships */ { struct ship *sp, *sq; /* r11, r10 */ int n; /* r9 */ int k, l; /* r8, r7 */ int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; char moved[NSHIP]; /* * first try to create moves for OUR ships */ foreachship(sp) { struct ship *closest; int ma, ta; char af; if (sp->file->captain[0] || sp->file->dir == 0) continue; if (!sp->file->struck && windspeed && !snagged(sp) && sp->specs->crew3) { ta = maxturns(sp, &af); ma = maxmove(sp, sp->file->dir, 0); closest = closestenemy(sp, 0, 0); if (closest == 0) *sp->file->movebuf = '\0'; else closeon(sp, closest, sp->file->movebuf, sizeof sp->file->movebuf, ta, ma, af); } else *sp->file->movebuf = '\0'; } /* * Then execute the moves for ALL ships (dead ones too), * checking for collisions and snags at each step. * The old positions are saved in row[], col[], dir[]. * At the end, we compare and write out the changes. */ n = 0; foreachship(sp) { if (snagged(sp)) (void) strlcpy(sp->file->movebuf, "d", sizeof sp->file->movebuf); else if (*sp->file->movebuf != 'd') (void) strlcat(sp->file->movebuf, "d", sizeof sp->file->movebuf); row[n] = sp->file->row; col[n] = sp->file->col; dir[n] = sp->file->dir; drift[n] = sp->file->drift; moved[n] = 0; n++; } /* * Now resolve collisions. * This is the tough part. */ for (k = 0; stillmoving(k); k++) { /* * Step once. * And propagate the nulls at the end of sp->file->movebuf. */ n = 0; foreachship(sp) { if (!sp->file->movebuf[k]) sp->file->movebuf[k+1] = '\0'; else if (sp->file->dir) step(sp->file->movebuf[k], sp, &moved[n]); n++; } /* * The real stuff. */ n = 0; foreachship(sp) { if (sp->file->dir == 0 || is_isolated(sp)) goto cont1; l = 0; foreachship(sq) { char snap = 0; if (sp == sq) goto cont2; if (sq->file->dir == 0) goto cont2; if (!push(sp, sq)) goto cont2; if (snagged2(sp, sq) && range(sp, sq) > 1) snap++; if (!range(sp, sq) && !fouled2(sp, sq)) { makesignal(sp, "collision with $$", sq); if (die() < 4) { makesignal(sp, "fouled with $$", sq); Write(W_FOUL, sp, l, 0, 0, 0); Write(W_FOUL, sq, n, 0, 0, 0); } snap++; } if (snap) { sp->file->movebuf[k + 1] = 0; sq->file->movebuf[k + 1] = 0; sq->file->row = sp->file->row - 1; if (sp->file->dir == 1 || sp->file->dir == 5) sq->file->col = sp->file->col - 1; else sq->file->col = sp->file->col; sq->file->dir = sp->file->dir; } cont2: l++; } cont1: n++; } } /* * Clear old moves. And write out new pos. */ n = 0; foreachship(sp) { if (sp->file->dir != 0) { *sp->file->movebuf = 0; if (row[n] != sp->file->row) Write(W_ROW, sp, sp->file->row, 0, 0, 0); if (col[n] != sp->file->col) Write(W_COL, sp, sp->file->col, 0, 0, 0); if (dir[n] != sp->file->dir) Write(W_DIR, sp, sp->file->dir, 0, 0, 0); if (drift[n] != sp->file->drift) Write(W_DRIFT, sp, sp->file->drift, 0, 0, 0); } n++; } }