#ifndef lint
-static char *sccsid = "@(#)dr_3.c 1.4 83/07/20";
+static char *sccsid = "@(#)dr_3.c 2.6 84/04/28";
#endif
#include "driver.h"
{
register struct ship *sp, *sq; /* r11, r10 */
register int n; /* r9 */
- struct ship *closest;
- register int k, l, m, ma; /* r8, r7, r6, */
- int ta, af;
- int row[NSHIP], col[NSHIP], dir[NSHIP], r1, r2, c1, c2, d1, d2;
- char clast[NSHIP][sizeof SHIP(0)->file->last];
+ register 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) {
- if (sp->file->captain[0] || sp->shipdir == 0)
+ 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 = ta & 0100000;
- ta &= 077777;
+ ta = maxturns(sp, &af);
ma = maxmove(sp, sp->file->dir, 0);
closest = closestenemy(sp, 0, 0);
if (closest == 0)
- *sp->file->last = '\0';
+ *sp->file->movebuf = '\0';
else
- closeon(sp, closest, sp->file->last,
+ closeon(sp, closest, sp->file->movebuf,
ta, ma, af);
} else
- *sp->file->last = '\0';
+ *sp->file->movebuf = '\0';
}
/*
* Then execute the moves for ALL ships (dead ones too),
- * saving old positions in row[], col[], dir[],
- * and the moves in clase[][].
- * The new positions are written out.
+ * 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))
- clast[n][0] = '\0';
+ (void) strcpy(sp->file->movebuf, "d");
else
- (void) strcpy(clast[n], sp->file->last);
+ if (*sp->file->movebuf != 'd')
+ (void) strcat(sp->file->movebuf, "d");
row[n] = sp->file->row;
col[n] = sp->file->col;
dir[n] = sp->file->dir;
- moveship(sp, clast[n]);
+ drift[n] = sp->file->drift;
+ moved[n] = 0;
n++;
}
/*
* Now resolve collisions.
* This is the tough part.
*/
- for (k = 0; stillmoving(clast, k); k++) {
+ for (k = 0; stillmoving(k); k++) {
/*
* Step once.
- * And propagate the nulls at the end of clast[].
+ * And propagate the nulls at the end of sp->file->movebuf.
*/
n = 0;
foreachship(sp) {
- if (dir[n])
- step(clast[n][k], sp, row+n, col+n, dir+n);
- if (!clast[n][k])
- clast[n][k+1] = '\0';
+ 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++;
}
/*
*/
n = 0;
foreachship(sp) {
- if ((d1 = sp->file->dir) == 0 || isolated(sp))
- continue;
- r1 = sp->file->row;
- c1 = sp->file->col;
- sp->file->dir = dir[n];
- sp->file->row = row[n];
- sp->file->col = col[n];
+ if (sp->file->dir == 0 || isolated(sp))
+ goto cont1;
l = 0;
foreachship(sq) {
- if ((d2 = sq->file->dir) == 0 || sp == sq)
- continue;
- r2 = sq->file->row;
- c2 = sq->file->col;
- sq->file->dir = dir[l];
- sq->file->row = row[l];
- sq->file->col = col[l];
- if (grappled2(sp, sq)
- && push(sp, sq) && range(sp, sq) > 1) {
- Write(W_SHIPROW, sq, 0,
- sp->file->row - 1, 0, 0, 0);
- if (sp->file->dir == 1
- || sp->file->dir == 5) /* XXX */
- Write(W_SHIPCOL, sq, 0,
- sp->file->col - 1,
- 0, 0, 0);
- else
- Write(W_SHIPCOL, sq, 0,
- sp->file->col, 0, 0, 0);
- Write(W_SHIPDIR, sq, 0,
- sp->file->dir, 0, 0, 0);
- }
- if (!range(sp, sq) && !fouled2(sp, sq)
- && push(sp, 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 %s (%c%c)", sq);
if (die() < 4) {
makesignal(sp,
"fouled with %s (%c%c)",
sq);
- for (m = 0; m < NSHIP && sp->file->fouls[m].turnfoul; m++)
- ;
- if (m < NSHIP)
- Write(W_FOUL, sp, 0,
- m, turn, l, 0);
- for (m = 0; m < NSHIP && sq->file->fouls[m].turnfoul; m++)
- ;
- if (m < NSHIP)
- Write(W_FOUL, sq, 0,
- m, turn, n, 0);
+ Write(W_FOUL, sp, 0, l, 0, 0, 0);
+ Write(W_FOUL, sq, 0, n, 0, 0, 0);
}
- clast[n][k+1] = '\0';
- sp->file->row = r2;
- sp->file->col = c2;
- sp->file->dir = d2;
- moveship(sp, clast[n]);
- Write(W_SHIPROW, sq, 0,
- sp->file->row-1, 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)
- Write(W_SHIPCOL, sq, 0,
- sp->file->col-1, 0, 0, 0);
+ sq->file->col =
+ sp->file->col - 1;
else
- Write(W_SHIPCOL, sq, 0,
- sp->file->col, 0, 0, 0);
- Write(W_SHIPDIR, sq, 0,
- sp->file->dir, 0, 0, 0);
- Write(W_DRIFT, sq, 0, 0, 0, 0, 0);
- Write(W_DRIFT, sp, 0, 0, 0, 0, 0);
- } else {
- sq->file->row = r2;
- sq->file->col = c2;
- sq->file->dir = d2;
+ sq->file->col = sp->file->col;
+ sq->file->dir = sp->file->dir;
}
+ cont2:
l++;
}
- sp->file->row = r1;
- sp->file->col = c1;
- sp->file->dir = d1;
+ cont1:
n++;
}
}
/*
- * Clear old moves.
+ * Clear old moves. And write out new pos.
*/
- foreachship(sp)
- sp->file->last[0] = 0;
+ n = 0;
+ foreachship(sp) {
+ if (sp->file->dir != 0) {
+ *sp->file->movebuf = 0;
+ if (row[n] != sp->file->row)
+ Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
+ if (col[n] != sp->file->col)
+ Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
+ if (dir[n] != sp->file->dir)
+ Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
+ if (drift[n] != sp->file->drift)
+ Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
+ }
+ n++;
+ }
}
-stillmoving(last, k)
-char last[][sizeof SHIP(0)->file->last]; /* how's that for portability */
+stillmoving(k)
register int k;
{
register struct ship *sp;
- register char (*p)[sizeof *last]; /* and this? */
- p = last;
- foreachship(sp) {
- if ((*p)[k])
+ foreachship(sp)
+ if (sp->file->movebuf[k])
return 1;
- p++;
- }
return 0;
}
return 1;
}
-/* XXX */
push(from, to)
register struct ship *from, *to;
{
- int bow1r, bow1c, bow2r, bow2c, stern1r, stern1c, stern2r, stern2c;
register int bs, sb;
- stern1r = bow1r = from->file->row;
- stern1c = bow1c = from->file->col;
- stern2r = bow2r = to->file->row;
- stern2c = bow2c = to->file->col;
- stern2r += dr[to->file->dir];
- stern2c += dc[to->file->dir];
- bs = bow1r - stern2r + bow1c - stern2c;
- sb = stern1r - bow2r + stern1c - bow2c;
- if (!bs)
- return 1;
- stern1r += dr[from->file->dir];
- stern1c += dc[from->file->dir];
- if(!sb)
- return 0;
- sb = to->specs->class;
- bs = from->specs->class;
+ sb = to->specs->guns;
+ bs = from->specs->guns;
if (sb > bs)
return 1;
if (sb < bs)
return from < to;
}
-step(com, ship, row, col, dir)
-register struct ship *ship;
-register int *row, *col, *dir;
+step(com, sp, moved)
char com;
+register struct ship *sp;
+char *moved;
{
register int dist;
switch (com) {
case 'r':
- if (++*dir == 9)
- *dir = 1;
+ if (++sp->file->dir == 9)
+ sp->file->dir = 1;
break;
case 'l':
- if (--*dir == 0)
- *dir = 8;
+ if (--sp->file->dir == 0)
+ sp->file->dir = 8;
break;
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- if (*dir % 2 == 0)
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ if (sp->file->dir % 2 == 0)
dist = dtab[com - '0'];
else
dist = com - '0';
- *row -= dr[*dir] * dist;
- *col -= dc[*dir] * dist;
+ sp->file->row -= dr[sp->file->dir] * dist;
+ sp->file->col -= dc[sp->file->dir] * dist;
+ *moved = 1;
break;
case 'b':
break;
case 'd':
- if (ship->specs->class >= 3 && !snagged(ship)
- || turn % 2 == 0) {
- *row -= dr[winddir];
- *col -= dc[winddir];
- }
+ if (!*moved) {
+ if (windspeed != 0 && ++sp->file->drift > 2 &&
+ (sp->specs->class >= 3 && !snagged(sp)
+ || (turn & 1) == 0)) {
+ sp->file->row -= dr[winddir];
+ sp->file->col -= dc[winddir];
+ }
+ } else
+ sp->file->drift = 0;
break;
}
}
register struct BP *bp;
bp = isdefense ? from->file->DBP : from->file->OBP;
- for (n = 0; n < 3 && bp[n].turnsent; n++)
+ for (n = 0; n < NBP && bp[n].turnsent; n++)
;
- if (n < 3 && sections) {
+ if (n < NBP && sections) {
Write(isdefense ? W_DBP : W_OBP, from, 0,
- turn, to-SHIP(0), sections, 0);
+ n, turn, to->file->index, sections);
if (isdefense)
makesignal(from, "repelling boarders",
(struct ship *)0);