xref: /csrg-svn/games/sail/dr_3.c (revision 15722)
111591Sleres #ifndef lint
2*15722Sedward static	char *sccsid = "@(#)dr_3.c	2.4 83/12/17";
311591Sleres #endif
411591Sleres 
514011Sedward #include "driver.h"
611591Sleres 
711591Sleres moveall()		/* move all comp ships */
811591Sleres {
914011Sedward 	register struct ship *sp, *sq;		/* r11, r10 */
1014011Sedward 	register int n;				/* r9 */
11*15722Sedward 	register int k, l;			/* r8, r7 */
1215708Sedward 	int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
1315708Sedward 	char moved[NSHIP];
1411591Sleres 
1514011Sedward 	/*
1614011Sedward 	 * first try to create moves for OUR ships
1714011Sedward 	 */
1814011Sedward 	foreachship(sp) {
1915708Sedward 		struct ship *closest;
2015708Sedward 		int ma, ta;
2115708Sedward 		char af;
2215708Sedward 
2315203Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
2414011Sedward 			continue;
2514011Sedward 		if (!sp->file->struck && windspeed && !snagged(sp)
2614011Sedward 		    && sp->specs->crew3) {
2715203Sedward 			ta = maxturns(sp, &af);
2814011Sedward 			ma = maxmove(sp, sp->file->dir, 0);
2914011Sedward 			closest = closestenemy(sp, 0, 0);
3014011Sedward 			if (closest == 0)
31*15722Sedward 				*sp->file->movebuf = '\0';
3211591Sleres 			else
33*15722Sedward 				closeon(sp, closest, sp->file->movebuf,
3414011Sedward 					ta, ma, af);
3514011Sedward 		} else
36*15722Sedward 			*sp->file->movebuf = '\0';
3711591Sleres 	}
3814011Sedward 	/*
3914011Sedward 	 * Then execute the moves for ALL ships (dead ones too),
4015708Sedward 	 * checking for collisions and snags at each step.
4115708Sedward 	 * The old positions are saved in row[], col[], dir[].
4215708Sedward 	 * At the end, we compare and write out the changes.
4314011Sedward 	 */
4414011Sedward 	n = 0;
4514011Sedward 	foreachship(sp) {
4614011Sedward 		if (snagged(sp))
47*15722Sedward 			(void) strcpy(sp->file->movebuf, "d");
4814011Sedward 		else
49*15722Sedward 			if (*sp->file->movebuf != 'd')
50*15722Sedward 				(void) strcat(sp->file->movebuf, "d");
5114011Sedward 		row[n] = sp->file->row;
5214011Sedward 		col[n] = sp->file->col;
5314011Sedward 		dir[n] = sp->file->dir;
5415708Sedward 		drift[n] = sp->file->drift;
5515708Sedward 		moved[n] = 0;
5614011Sedward 		n++;
5711591Sleres 	}
5814011Sedward 	/*
5914011Sedward 	 * Now resolve collisions.
6014011Sedward 	 * This is the tough part.
6114011Sedward 	 */
6215708Sedward 	for (k = 0; stillmoving(k); k++) {
6314011Sedward 		/*
6414011Sedward 		 * Step once.
65*15722Sedward 		 * And propagate the nulls at the end of sp->file->movebuf.
6614011Sedward 		 */
6714011Sedward 		n = 0;
6814011Sedward 		foreachship(sp) {
69*15722Sedward 			if (!sp->file->movebuf[k])
70*15722Sedward 				sp->file->movebuf[k+1] = '\0';
7115708Sedward 			else if (sp->file->dir)
72*15722Sedward 				step(sp->file->movebuf[k], sp, &moved[n]);
7314011Sedward 			n++;
7411591Sleres 		}
7514011Sedward 		/*
7614011Sedward 		 * The real stuff.
7714011Sedward 		 */
7814011Sedward 		n = 0;
7914011Sedward 		foreachship(sp) {
8015708Sedward 			if (sp->file->dir == 0 || isolated(sp))
8115238Sedward 				goto cont1;
8214011Sedward 			l = 0;
8314011Sedward 			foreachship(sq) {
8415708Sedward 				char snap = 0;
8515708Sedward 
8615238Sedward 				if (sp == sq)
8715238Sedward 					goto cont2;
8815708Sedward 				if (sq->file->dir == 0)
8915238Sedward 					goto cont2;
9015708Sedward 				if (!push(sp, sq))
9115708Sedward 					goto cont2;
9215708Sedward 				if (snagged2(sp, sq) && range(sp, sq) > 1)
9315708Sedward 					snap++;
9415708Sedward 				if (!range(sp, sq) && !fouled2(sp, sq)) {
9514011Sedward 					makesignal(sp,
9614011Sedward 						"collision with %s (%c%c)", sq);
9714011Sedward 					if (die() < 4) {
9814011Sedward 						makesignal(sp,
9914011Sedward 							"fouled with %s (%c%c)",
10014011Sedward 							sq);
101*15722Sedward 						Write(W_FOUL, sp, 0, l, 0, 0, 0);
102*15722Sedward 						Write(W_FOUL, sq, 0, n, 0, 0, 0);
10311591Sleres 					}
10415708Sedward 					snap++;
10515708Sedward 				}
10615708Sedward 				if (snap) {
107*15722Sedward 					sp->file->movebuf[k + 1] = 0;
108*15722Sedward 					sq->file->movebuf[k + 1] = 0;
10915708Sedward 					sq->file->row = sp->file->row - 1;
11014011Sedward 					if (sp->file->dir == 1
11114011Sedward 					    || sp->file->dir == 5)
11215708Sedward 						sq->file->col =
11315708Sedward 							sp->file->col - 1;
11414011Sedward 					else
11515708Sedward 						sq->file->col = sp->file->col;
11615708Sedward 					sq->file->dir = sp->file->dir;
11711591Sleres 				}
11815238Sedward 			cont2:
11914011Sedward 				l++;
12011591Sleres 			}
12115238Sedward 		cont1:
12214011Sedward 			n++;
12311591Sleres 		}
12411591Sleres 	}
12514011Sedward 	/*
12615708Sedward 	 * Clear old moves.  And write out new pos.
12714011Sedward 	 */
12815708Sedward 	n = 0;
12915708Sedward 	foreachship(sp) {
13015708Sedward 		if (sp->file->dir != 0) {
131*15722Sedward 			*sp->file->movebuf = 0;
13215708Sedward 			if (row[n] != sp->file->row)
133*15722Sedward 				Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
13415708Sedward 			if (col[n] != sp->file->col)
135*15722Sedward 				Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
13615708Sedward 			if (dir[n] != sp->file->dir)
137*15722Sedward 				Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
13815708Sedward 			if (drift[n] != sp->file->drift)
13915708Sedward 				Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
14015708Sedward 		}
14115708Sedward 		n++;
14215708Sedward 	}
14311591Sleres }
14411591Sleres 
14515708Sedward stillmoving(k)
14611591Sleres register int k;
14711591Sleres {
14814011Sedward 	register struct ship *sp;
14911591Sleres 
15015708Sedward 	foreachship(sp)
151*15722Sedward 		if (sp->file->movebuf[k])
15214011Sedward 			return 1;
15314011Sedward 	return 0;
15411591Sleres }
15511591Sleres 
15611591Sleres isolated(ship)
15714011Sedward register struct ship *ship;
15811591Sleres {
15914011Sedward 	register struct ship *sp;
16011591Sleres 
16114011Sedward 	foreachship(sp) {
16214011Sedward 		if (ship != sp && range(ship, sp) <= 10)
16314011Sedward 			return 0;
16414011Sedward 	}
16514011Sedward 	return 1;
16611591Sleres }
16711591Sleres 
16811591Sleres push(from, to)
16914011Sedward register struct ship *from, *to;
17011591Sleres {
17111591Sleres 	register int bs, sb;
17211591Sleres 
17315708Sedward 	sb = to->specs->guns;
17415708Sedward 	bs = from->specs->guns;
17514011Sedward 	if (sb > bs)
17614011Sedward 		return 1;
17711591Sleres 	if (sb < bs)
17814011Sedward 		return 0;
17914011Sedward 	return from < to;
18011591Sleres }
18111591Sleres 
18215708Sedward step(com, sp, moved)
18311591Sleres char com;
18415708Sedward register struct ship *sp;
18515708Sedward char *moved;
18611591Sleres {
18711591Sleres 	register int dist;
18811591Sleres 
18914011Sedward 	switch (com) {
19014011Sedward 	case 'r':
19115708Sedward 		if (++sp->file->dir == 9)
19215708Sedward 			sp->file->dir = 1;
19314011Sedward 		break;
19414011Sedward 	case 'l':
19515708Sedward 		if (--sp->file->dir == 0)
19615708Sedward 			sp->file->dir = 8;
19714011Sedward 		break;
19814011Sedward 	case '0': case '1': case '2': case '3':
19914011Sedward 	case '4': case '5': case '6': case '7':
20015708Sedward 		if (sp->file->dir % 2 == 0)
20114011Sedward 			dist = dtab[com - '0'];
20214011Sedward 		else
20314011Sedward 			dist = com - '0';
20415708Sedward 		sp->file->row -= dr[sp->file->dir] * dist;
20515708Sedward 		sp->file->col -= dc[sp->file->dir] * dist;
20615708Sedward 		*moved = 1;
20714011Sedward 		break;
20814011Sedward 	case 'b':
20914011Sedward 		break;
21014011Sedward 	case 'd':
21115708Sedward 		if (!*moved) {
21215708Sedward 			if (++sp->file->drift > 2 &&
21315708Sedward 			    (sp->specs->class >= 3 && !snagged(sp)
21415708Sedward 			     || (turn & 1) == 0)) {
21515708Sedward 				sp->file->row -= dr[winddir];
21615708Sedward 				sp->file->col -= dc[winddir];
21715708Sedward 			}
21815708Sedward 		} else
21915708Sedward 			sp->file->drift = 0;
22014011Sedward 		break;
22111591Sleres 	}
22211591Sleres }
22311591Sleres 
22414011Sedward sendbp(from, to, sections, isdefense)
22514011Sedward register struct ship *from, *to;
22614011Sedward int sections;
22714011Sedward char isdefense;
22811591Sleres {
22911591Sleres 	int n;
23014011Sedward 	register struct BP *bp;
23111591Sleres 
23214011Sedward 	bp = isdefense ? from->file->DBP : from->file->OBP;
23314011Sedward 	for (n = 0; n < 3 && bp[n].turnsent; n++)
23414011Sedward 		;
23514011Sedward 	if (n < 3 && sections) {
23614011Sedward 		Write(isdefense ? W_DBP : W_OBP, from, 0,
237*15722Sedward 			turn, to->file->index, sections, 0);
23814011Sedward 		if (isdefense)
23914011Sedward 			makesignal(from, "repelling boarders",
24014011Sedward 				(struct ship *)0);
24111591Sleres 		else
24214011Sedward 			makesignal(from, "boarding the %s (%c%c)", to);
24311591Sleres 	}
24411591Sleres }
24511591Sleres 
24614011Sedward toughmelee(ship, to, isdefense, count)
24714011Sedward register struct ship *ship, *to;
24814011Sedward int isdefense, count;
24911591Sleres {
25014011Sedward 	register struct BP *bp;
25114011Sedward 	register obp = 0;
25214011Sedward 	int n, OBP = 0, DBP = 0, dbp = 0;
25311591Sleres 	int qual;
25411591Sleres 
25514011Sedward 	qual = ship->specs->qual;
25614011Sedward 	bp = isdefense ? ship->file->DBP : ship->file->OBP;
25714011Sedward 	for (n = 0; n < NBP; n++, bp++) {
25814011Sedward 		if (bp->turnsent && (to == bp->toship || isdefense)) {
25914011Sedward 			obp += bp->mensent / 100
26014011Sedward 				? ship->specs->crew1 * qual : 0;
26114011Sedward 			obp += (bp->mensent % 100)/10
26214011Sedward 				? ship->specs->crew2 * qual : 0;
26314011Sedward 			obp += bp->mensent % 10
26414011Sedward 				? ship->specs->crew3 * qual : 0;
26511591Sleres 		}
26611591Sleres 	}
26714011Sedward 	if (count || isdefense)
26814011Sedward 		return obp;
26914011Sedward 	OBP = toughmelee(to, ship, 0, count + 1);
27014011Sedward 	dbp = toughmelee(ship, to, 1, count + 1);
27114011Sedward 	DBP = toughmelee(to, ship, 1, count + 1);
27211591Sleres 	if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
27314011Sedward 		return 1;
27411591Sleres 	else
27514011Sedward 		return 0;
27611591Sleres }
27711591Sleres 
27811591Sleres reload()
27911591Sleres {
28014011Sedward 	register struct ship *sp;
28111591Sleres 
28214011Sedward 	foreachship(sp) {
28314011Sedward 		sp->file->loadwith = 0;
28414011Sedward 	}
28511591Sleres }
28611591Sleres 
28711591Sleres checksails()
28811591Sleres {
28914011Sedward 	register struct ship *sp;
29014011Sedward 	register int rig, full;
29114011Sedward 	struct ship *close;
29211591Sleres 
29314011Sedward 	foreachship(sp) {
29414011Sedward 		if (sp->file->captain[0] != 0)
29514011Sedward 			continue;
29614011Sedward 		rig = sp->specs->rig1;
29714011Sedward 		if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
29811591Sleres 			rig = 0;
29914011Sedward 		if (rig && sp->specs->crew3) {
30014011Sedward 			close = closestenemy(sp, 0, 0);
30114011Sedward 			if (close != 0) {
30214011Sedward 				if (range(sp, close) > 9)
30314011Sedward 					full = 1;
30414011Sedward 				else
30511591Sleres 					full = 0;
30614011Sedward 			} else
30711591Sleres 				full = 0;
30814011Sedward 		} else
30914011Sedward 			full = 0;
31014011Sedward 		if ((sp->file->FS != 0) != full)
31114011Sedward 			Write(W_FS, sp, 0, full, 0, 0, 0);
31211591Sleres 	}
31311591Sleres }
314