xref: /csrg-svn/games/sail/dr_3.c (revision 60846)
118697Sedward /*
2*60846Sbostic  * Copyright (c) 1983, 1993
3*60846Sbostic  *	The Regents of the University of California.  All rights reserved.
433695Sbostic  *
542603Sbostic  * %sccs.include.redist.c%
618697Sedward  */
718697Sedward 
811591Sleres #ifndef lint
9*60846Sbostic static char sccsid[] = "@(#)dr_3.c	8.1 (Berkeley) 05/31/93";
1033695Sbostic #endif /* not lint */
1111591Sleres 
1214011Sedward #include "driver.h"
1311591Sleres 
moveall()1411591Sleres moveall()		/* move all comp ships */
1511591Sleres {
1614011Sedward 	register struct ship *sp, *sq;		/* r11, r10 */
1714011Sedward 	register int n;				/* r9 */
1815722Sedward 	register int k, l;			/* r8, r7 */
1915708Sedward 	int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
2015708Sedward 	char moved[NSHIP];
2111591Sleres 
2214011Sedward 	/*
2314011Sedward 	 * first try to create moves for OUR ships
2414011Sedward 	 */
2514011Sedward 	foreachship(sp) {
2615708Sedward 		struct ship *closest;
2715708Sedward 		int ma, ta;
2815708Sedward 		char af;
2915708Sedward 
3015203Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
3114011Sedward 			continue;
3214011Sedward 		if (!sp->file->struck && windspeed && !snagged(sp)
3314011Sedward 		    && sp->specs->crew3) {
3415203Sedward 			ta = maxturns(sp, &af);
3514011Sedward 			ma = maxmove(sp, sp->file->dir, 0);
3614011Sedward 			closest = closestenemy(sp, 0, 0);
3714011Sedward 			if (closest == 0)
3815722Sedward 				*sp->file->movebuf = '\0';
3911591Sleres 			else
4015722Sedward 				closeon(sp, closest, sp->file->movebuf,
4114011Sedward 					ta, ma, af);
4214011Sedward 		} else
4315722Sedward 			*sp->file->movebuf = '\0';
4411591Sleres 	}
4514011Sedward 	/*
4614011Sedward 	 * Then execute the moves for ALL ships (dead ones too),
4715708Sedward 	 * checking for collisions and snags at each step.
4815708Sedward 	 * The old positions are saved in row[], col[], dir[].
4915708Sedward 	 * At the end, we compare and write out the changes.
5014011Sedward 	 */
5114011Sedward 	n = 0;
5214011Sedward 	foreachship(sp) {
5314011Sedward 		if (snagged(sp))
5415722Sedward 			(void) strcpy(sp->file->movebuf, "d");
5514011Sedward 		else
5615722Sedward 			if (*sp->file->movebuf != 'd')
5715722Sedward 				(void) strcat(sp->file->movebuf, "d");
5814011Sedward 		row[n] = sp->file->row;
5914011Sedward 		col[n] = sp->file->col;
6014011Sedward 		dir[n] = sp->file->dir;
6115708Sedward 		drift[n] = sp->file->drift;
6215708Sedward 		moved[n] = 0;
6314011Sedward 		n++;
6411591Sleres 	}
6514011Sedward 	/*
6614011Sedward 	 * Now resolve collisions.
6714011Sedward 	 * This is the tough part.
6814011Sedward 	 */
6915708Sedward 	for (k = 0; stillmoving(k); k++) {
7014011Sedward 		/*
7114011Sedward 		 * Step once.
7215722Sedward 		 * And propagate the nulls at the end of sp->file->movebuf.
7314011Sedward 		 */
7414011Sedward 		n = 0;
7514011Sedward 		foreachship(sp) {
7615722Sedward 			if (!sp->file->movebuf[k])
7715722Sedward 				sp->file->movebuf[k+1] = '\0';
7815708Sedward 			else if (sp->file->dir)
7915722Sedward 				step(sp->file->movebuf[k], sp, &moved[n]);
8014011Sedward 			n++;
8111591Sleres 		}
8214011Sedward 		/*
8314011Sedward 		 * The real stuff.
8414011Sedward 		 */
8514011Sedward 		n = 0;
8614011Sedward 		foreachship(sp) {
8715708Sedward 			if (sp->file->dir == 0 || isolated(sp))
8815238Sedward 				goto cont1;
8914011Sedward 			l = 0;
9014011Sedward 			foreachship(sq) {
9115708Sedward 				char snap = 0;
9215708Sedward 
9315238Sedward 				if (sp == sq)
9415238Sedward 					goto cont2;
9515708Sedward 				if (sq->file->dir == 0)
9615238Sedward 					goto cont2;
9715708Sedward 				if (!push(sp, sq))
9815708Sedward 					goto cont2;
9915708Sedward 				if (snagged2(sp, sq) && range(sp, sq) > 1)
10015708Sedward 					snap++;
10115708Sedward 				if (!range(sp, sq) && !fouled2(sp, sq)) {
10214011Sedward 					makesignal(sp,
10314011Sedward 						"collision with %s (%c%c)", sq);
10414011Sedward 					if (die() < 4) {
10514011Sedward 						makesignal(sp,
10614011Sedward 							"fouled with %s (%c%c)",
10714011Sedward 							sq);
10815722Sedward 						Write(W_FOUL, sp, 0, l, 0, 0, 0);
10915722Sedward 						Write(W_FOUL, sq, 0, n, 0, 0, 0);
11011591Sleres 					}
11115708Sedward 					snap++;
11215708Sedward 				}
11315708Sedward 				if (snap) {
11415722Sedward 					sp->file->movebuf[k + 1] = 0;
11515722Sedward 					sq->file->movebuf[k + 1] = 0;
11615708Sedward 					sq->file->row = sp->file->row - 1;
11714011Sedward 					if (sp->file->dir == 1
11814011Sedward 					    || sp->file->dir == 5)
11915708Sedward 						sq->file->col =
12015708Sedward 							sp->file->col - 1;
12114011Sedward 					else
12215708Sedward 						sq->file->col = sp->file->col;
12315708Sedward 					sq->file->dir = sp->file->dir;
12411591Sleres 				}
12515238Sedward 			cont2:
12614011Sedward 				l++;
12711591Sleres 			}
12815238Sedward 		cont1:
12914011Sedward 			n++;
13011591Sleres 		}
13111591Sleres 	}
13214011Sedward 	/*
13315708Sedward 	 * Clear old moves.  And write out new pos.
13414011Sedward 	 */
13515708Sedward 	n = 0;
13615708Sedward 	foreachship(sp) {
13715708Sedward 		if (sp->file->dir != 0) {
13815722Sedward 			*sp->file->movebuf = 0;
13915708Sedward 			if (row[n] != sp->file->row)
14015722Sedward 				Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
14115708Sedward 			if (col[n] != sp->file->col)
14215722Sedward 				Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
14315708Sedward 			if (dir[n] != sp->file->dir)
14415722Sedward 				Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
14515708Sedward 			if (drift[n] != sp->file->drift)
14615708Sedward 				Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
14715708Sedward 		}
14815708Sedward 		n++;
14915708Sedward 	}
15011591Sleres }
15111591Sleres 
stillmoving(k)15215708Sedward stillmoving(k)
15311591Sleres register int k;
15411591Sleres {
15514011Sedward 	register struct ship *sp;
15611591Sleres 
15715708Sedward 	foreachship(sp)
15815722Sedward 		if (sp->file->movebuf[k])
15914011Sedward 			return 1;
16014011Sedward 	return 0;
16111591Sleres }
16211591Sleres 
isolated(ship)16311591Sleres isolated(ship)
16414011Sedward register struct ship *ship;
16511591Sleres {
16614011Sedward 	register struct ship *sp;
16711591Sleres 
16814011Sedward 	foreachship(sp) {
16914011Sedward 		if (ship != sp && range(ship, sp) <= 10)
17014011Sedward 			return 0;
17114011Sedward 	}
17214011Sedward 	return 1;
17311591Sleres }
17411591Sleres 
push(from,to)17511591Sleres push(from, to)
17614011Sedward register struct ship *from, *to;
17711591Sleres {
17811591Sleres 	register int bs, sb;
17911591Sleres 
18015708Sedward 	sb = to->specs->guns;
18115708Sedward 	bs = from->specs->guns;
18214011Sedward 	if (sb > bs)
18314011Sedward 		return 1;
18411591Sleres 	if (sb < bs)
18514011Sedward 		return 0;
18614011Sedward 	return from < to;
18711591Sleres }
18811591Sleres 
step(com,sp,moved)18915708Sedward step(com, sp, moved)
19011591Sleres char com;
19115708Sedward register struct ship *sp;
19215708Sedward char *moved;
19311591Sleres {
19411591Sleres 	register int dist;
19511591Sleres 
19614011Sedward 	switch (com) {
19714011Sedward 	case 'r':
19815708Sedward 		if (++sp->file->dir == 9)
19915708Sedward 			sp->file->dir = 1;
20014011Sedward 		break;
20114011Sedward 	case 'l':
20215708Sedward 		if (--sp->file->dir == 0)
20315708Sedward 			sp->file->dir = 8;
20414011Sedward 		break;
20515879Sedward 		case '0': case '1': case '2': case '3':
20615879Sedward 		case '4': case '5': case '6': case '7':
20715708Sedward 		if (sp->file->dir % 2 == 0)
20814011Sedward 			dist = dtab[com - '0'];
20914011Sedward 		else
21014011Sedward 			dist = com - '0';
21115708Sedward 		sp->file->row -= dr[sp->file->dir] * dist;
21215708Sedward 		sp->file->col -= dc[sp->file->dir] * dist;
21315708Sedward 		*moved = 1;
21414011Sedward 		break;
21514011Sedward 	case 'b':
21614011Sedward 		break;
21714011Sedward 	case 'd':
21815708Sedward 		if (!*moved) {
21916426Sedward 			if (windspeed != 0 && ++sp->file->drift > 2 &&
22015708Sedward 			    (sp->specs->class >= 3 && !snagged(sp)
22115708Sedward 			     || (turn & 1) == 0)) {
22215708Sedward 				sp->file->row -= dr[winddir];
22315708Sedward 				sp->file->col -= dc[winddir];
22415708Sedward 			}
22515708Sedward 		} else
22615708Sedward 			sp->file->drift = 0;
22714011Sedward 		break;
22811591Sleres 	}
22911591Sleres }
23011591Sleres 
sendbp(from,to,sections,isdefense)23114011Sedward sendbp(from, to, sections, isdefense)
23214011Sedward register struct ship *from, *to;
23314011Sedward int sections;
23414011Sedward char isdefense;
23511591Sleres {
23611591Sleres 	int n;
23714011Sedward 	register struct BP *bp;
23811591Sleres 
23914011Sedward 	bp = isdefense ? from->file->DBP : from->file->OBP;
24015879Sedward 	for (n = 0; n < NBP && bp[n].turnsent; n++)
24114011Sedward 		;
24215879Sedward 	if (n < NBP && sections) {
24314011Sedward 		Write(isdefense ? W_DBP : W_OBP, from, 0,
24415879Sedward 			n, turn, to->file->index, sections);
24514011Sedward 		if (isdefense)
24614011Sedward 			makesignal(from, "repelling boarders",
24714011Sedward 				(struct ship *)0);
24811591Sleres 		else
24914011Sedward 			makesignal(from, "boarding the %s (%c%c)", to);
25011591Sleres 	}
25111591Sleres }
25211591Sleres 
toughmelee(ship,to,isdefense,count)25314011Sedward toughmelee(ship, to, isdefense, count)
25414011Sedward register struct ship *ship, *to;
25514011Sedward int isdefense, count;
25611591Sleres {
25714011Sedward 	register struct BP *bp;
25814011Sedward 	register obp = 0;
25914011Sedward 	int n, OBP = 0, DBP = 0, dbp = 0;
26011591Sleres 	int qual;
26111591Sleres 
26214011Sedward 	qual = ship->specs->qual;
26314011Sedward 	bp = isdefense ? ship->file->DBP : ship->file->OBP;
26414011Sedward 	for (n = 0; n < NBP; n++, bp++) {
26514011Sedward 		if (bp->turnsent && (to == bp->toship || isdefense)) {
26614011Sedward 			obp += bp->mensent / 100
26714011Sedward 				? ship->specs->crew1 * qual : 0;
26814011Sedward 			obp += (bp->mensent % 100)/10
26914011Sedward 				? ship->specs->crew2 * qual : 0;
27014011Sedward 			obp += bp->mensent % 10
27114011Sedward 				? ship->specs->crew3 * qual : 0;
27211591Sleres 		}
27311591Sleres 	}
27414011Sedward 	if (count || isdefense)
27514011Sedward 		return obp;
27614011Sedward 	OBP = toughmelee(to, ship, 0, count + 1);
27714011Sedward 	dbp = toughmelee(ship, to, 1, count + 1);
27814011Sedward 	DBP = toughmelee(to, ship, 1, count + 1);
27911591Sleres 	if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
28014011Sedward 		return 1;
28111591Sleres 	else
28214011Sedward 		return 0;
28311591Sleres }
28411591Sleres 
reload()28511591Sleres reload()
28611591Sleres {
28714011Sedward 	register struct ship *sp;
28811591Sleres 
28914011Sedward 	foreachship(sp) {
29014011Sedward 		sp->file->loadwith = 0;
29114011Sedward 	}
29211591Sleres }
29311591Sleres 
checksails()29411591Sleres checksails()
29511591Sleres {
29614011Sedward 	register struct ship *sp;
29714011Sedward 	register int rig, full;
29814011Sedward 	struct ship *close;
29911591Sleres 
30014011Sedward 	foreachship(sp) {
30114011Sedward 		if (sp->file->captain[0] != 0)
30214011Sedward 			continue;
30314011Sedward 		rig = sp->specs->rig1;
30414011Sedward 		if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
30511591Sleres 			rig = 0;
30614011Sedward 		if (rig && sp->specs->crew3) {
30714011Sedward 			close = closestenemy(sp, 0, 0);
30814011Sedward 			if (close != 0) {
30914011Sedward 				if (range(sp, close) > 9)
31014011Sedward 					full = 1;
31114011Sedward 				else
31211591Sleres 					full = 0;
31314011Sedward 			} else
31411591Sleres 				full = 0;
31514011Sedward 		} else
31614011Sedward 			full = 0;
31714011Sedward 		if ((sp->file->FS != 0) != full)
31814011Sedward 			Write(W_FS, sp, 0, full, 0, 0, 0);
31911591Sleres 	}
32011591Sleres }
321