void checkup() { struct ship *sp, *sq; 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) { makemsg(sp, "exploding!"); 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 Cleansnag(struct ship *from, struct ship *to, char all, char flag) { if (flag & 1) { Write(W_UNGRAP, from, to->file->index, all, 0, 0); Write(W_UNGRAP, to, from->file->index, all, 0, 0); } if (flag & 2) { Write(W_UNFOUL, from, to->file->index, all, 0, 0); Write(W_UNFOUL, to, from->file->index, all, 0, 0); } if (!snagged2(from, to)) { if (!snagged(from)) { unboard(from, from, 1); /* defense */ unboard(from, from, 0); /* defense */ } else unboard(from, to, 0); /* offense */ if (!snagged(to)) { unboard(to, to, 1); /* defense */ unboard(to, to, 0); /* defense */ } else unboard(to, from, 0); /* offense */ } }
void acceptmove(void) { int ta; int ma; char af; int moved = 0; int vma, dir; char prompt[60]; char buf[60], last = '\0'; char *p; if (!mc->crew3 || snagged(ms) || !windspeed) { Msg("Unable to move"); return; } ta = maxturns(ms, &af); ma = maxmove(ms, mf->dir, 0); sprintf(prompt, "move (%d,%c%d): ", ma, af ? '\'' : ' ', ta); sgetstr(prompt, buf, sizeof buf); dir = mf->dir; vma = ma; for (p = buf; *p; p++) switch (*p) { case 'l': dir -= 2; case 'r': if (++dir == 0) dir = 8; else if (dir == 9) dir = 1; if (last == 't') { Msg("Ship can't turn that fast."); *p-- = '\0'; } last = 't'; ma--; ta--; vma = min(ma, maxmove(ms, dir, 0)); if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; case 'b': ma--; vma--; last = 'b'; if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; case '0': case 'd': *p-- = '\0'; break; case '\n': *p-- = '\0'; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (last == '0') { Msg("Can't move that fast."); *p-- = '\0'; } last = '0'; moved = 1; ma -= *p - '0'; vma -= *p - '0'; if ((ta < 0 && moved) || (vma < 0 && moved)) *p-- = '\0'; break; default: if (!isspace((unsigned char) *p)) { Msg("Input error."); *p-- = '\0'; } } if ((ta < 0 && moved) || (vma < 0 && moved) || (af && turnfirst(buf) && moved)) { Msg("Movement error."); if (ta < 0 && moved) { if (mf->FS == 1) { Write(W_FS, ms, 0, 0, 0, 0); Msg("No hands to set full sails."); } } else if (ma >= 0) buf[1] = '\0'; } if (af && !moved) { if (mf->FS == 1) { Write(W_FS, ms, 0, 0, 0, 0); Msg("No hands to set full sails."); } } if (*buf) strcpy(movebuf, buf); else strcpy(movebuf, "d"); Writestr(W_MOVE, ms, movebuf); Msg("Helm: %s.", movebuf); }
boardcomp() { int crew[3]; register struct ship *sp, *sq; foreachship(sp) { if (*sp->file->captain) continue; if (sp->file->dir == 0) continue; if (sp->file->struck || sp->file->captured != 0) continue; if (!snagged(sp)) continue; crew[0] = sp->specs->crew1 != 0; crew[1] = sp->specs->crew2 != 0; crew[2] = sp->specs->crew3 != 0; foreachship(sq) { if (!Xsnagged2(sp, sq)) continue; if (meleeing(sp, sq)) continue; if (!sq->file->dir || sp->nationality == capship(sq)->nationality) continue; switch (sp->specs->class - sq->specs->class) { case -3: case -4: case -5: if (crew[0]) { /* OBP */ sendbp(sp, sq, crew[0]*100, 0); crew[0] = 0; } else if (crew[1]){ /* OBP */ sendbp(sp, sq, crew[1]*10, 0); crew[1] = 0; } break; case -2: if (crew[0] || crew[1]) { /* OBP */ sendbp(sp, sq, crew[0]*100+crew[1]*10, 0); crew[0] = crew[1] = 0; } break; case -1: case 0: case 1: if (crew[0]) { /* OBP */ sendbp(sp, sq, crew[0]*100+crew[1]*10, 0); crew[0] = crew[1] = 0; } break; case 2: case 3: case 4: case 5: /* OBP */ sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2], 0); crew[0] = crew[1] = crew[2] = 0; break; } } } }
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++; } }