Esempio n. 1
0
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);
}
Esempio n. 2
0
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++;
	}
}