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); }
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++; } }