xref: /csrg-svn/games/sail/dr_2.c (revision 14010)
111590Sleres #ifndef lint
2*14010Sedward static	char *sccsid = "@(#)dr_2.c	1.2 83/07/20";
311590Sleres #endif
411590Sleres 
5*14010Sedward #include "driver.h"
611590Sleres 
7*14010Sedward #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
8*14010Sedward 
911590Sleres thinkofgrapples()
1011590Sleres {
11*14010Sedward 	register struct ship *sp, *sq;
12*14010Sedward 	char friendly;
1311590Sleres 
14*14010Sedward 	foreachship(sp) {
15*14010Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
16*14010Sedward 			continue;
17*14010Sedward 		foreachship(sq) {
18*14010Sedward 			friendly = sp->nationality == capship(sq)->nationality;
19*14010Sedward 			if (!friendly) {
20*14010Sedward 				if (sp->file->struck || sp->file->captured != 0)
21*14010Sedward 					continue;
22*14010Sedward 				if (range(sp, sq) != 1)
23*14010Sedward 					continue;
24*14010Sedward 				if (grappled2(sp, sq))
25*14010Sedward 					if (toughmelee(sp, sq, 0, 0))
26*14010Sedward 						ungrap(sp, sq);
27*14010Sedward 					else
28*14010Sedward 						grap(sp, sq);
29*14010Sedward 				else if (couldwin(sp, sq)) {
30*14010Sedward 					grap(sp, sq);
31*14010Sedward 					sp->file->loadwith = L_GRAPE;
3211590Sleres 				}
33*14010Sedward 			} else
34*14010Sedward 				ungrap(sp, sq);
3511590Sleres 		}
3611590Sleres 	}
3711590Sleres }
3811590Sleres 
3911590Sleres checkup()
4011590Sleres {
41*14010Sedward 	register int k;
42*14010Sedward 	register struct ship *sp, *sq;
43*14010Sedward 	register char explode, sink;
4411590Sleres 
4511590Sleres 	readpos();
46*14010Sedward 	foreachship(sp) {
47*14010Sedward 		explode = sp->file->explode;
48*14010Sedward 		sink = sp->file->sink;
49*14010Sedward 		if (die() < 5)
50*14010Sedward 			continue;
51*14010Sedward 		if (explode != 1 && sink != 1)
52*14010Sedward 			continue;
53*14010Sedward 		Write(sink ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0);
54*14010Sedward 		sp->file->dir = 0;	/* hopefully enough to kill ship */
55*14010Sedward 		/* Write(n, 0, 10, 0); XXX */
56*14010Sedward 		Write(W_CLASS, sp, 0, 0, 0, 0, 0);
57*14010Sedward 		if (fouled(sp) || grappled(sp)) {
58*14010Sedward 			for (k = 0; k < NSHIP; k++) {
59*14010Sedward 				if (sp->file->fouls[k].turnfoul)
60*14010Sedward 					cleanfoul(sp,
61*14010Sedward 						sp->file->fouls[k].toship, k);
6211590Sleres 			}
63*14010Sedward 			for (k = 0; k < NSHIP; k++) {
64*14010Sedward 				if (sp->file->grapples[k].turnfoul)
65*14010Sedward 					cleangrapple(sp,
66*14010Sedward 						sp->file->grapples[k].toship,
67*14010Sedward 						k);
6811590Sleres 			}
69*14010Sedward 		}
70*14010Sedward 		if (sink != 1) {
71*14010Sedward 			makesignal(sp, "exploding!", (struct ship *)0);
72*14010Sedward 			foreachship(sq) {
73*14010Sedward 				if (sp != sq && sq->file->dir && range(sp, sq) < 4)
74*14010Sedward 					table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6);
7511590Sleres 			}
76*14010Sedward 		} else
77*14010Sedward 			makesignal(sp, "sinking!", (struct ship *)0);
7811590Sleres 	}
7911590Sleres }
8011590Sleres 
8111590Sleres prizecheck()
8211590Sleres {
83*14010Sedward 	register struct ship *sp;
84*14010Sedward 	register int prisoners, points;
8511590Sleres 
86*14010Sedward 	foreachship(sp) {
87*14010Sedward 		if (sp->file->captured == 0)
88*14010Sedward 			continue;
89*14010Sedward 		if (sp->file->struck || sp->file->dir == 0)
90*14010Sedward 			continue;
91*14010Sedward 		prisoners = sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3;
92*14010Sedward 		if (prisoners > sp->file->pcrew * 6) {
93*14010Sedward 			Write(W_CAPTURED, sp, 0, -1, 0, 0, 0);
94*14010Sedward 			Write(W_SIGNAL, sp, 1,
95*14010Sedward 				(int)"prize crew overthrown", 0, 0, 0);
96*14010Sedward 			points = sp->file->captured->file->points
97*14010Sedward 				- 2 * sp->specs->pts;
98*14010Sedward 			Write(W_POINTS, sp->file->captured, 0, points, 0, 0, 0);
9911590Sleres 		}
10011590Sleres 	}
10111590Sleres }
10211590Sleres 
103*14010Sedward strend(str)
10411590Sleres char *str;
10511590Sleres {
106*14010Sedward 	register char *p;
10711590Sleres 
108*14010Sedward 	for (p = str; *p; p++)
109*14010Sedward 		;
110*14010Sedward 	return p == str ? 0 : p[-1];
11111590Sleres }
11211590Sleres 
113*14010Sedward closeon(from, to, command, ta, ma, af)
114*14010Sedward register struct ship *from, *to;
115*14010Sedward char command[];
116*14010Sedward int ma, ta, af;
11711590Sleres {
11811590Sleres 	int high;
11911590Sleres 	char temp[10];
12011590Sleres 
12111590Sleres 	temp[0] = command[0] = '\0';
12211590Sleres 	high = -30000;
123*14010Sedward 	try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0);
12411590Sleres }
12511590Sleres 
126*14010Sedward int dtab[] = {0,1,1,2,3,4,4,5};		/* diagonal distances in x==y */
12711590Sleres 
128*14010Sedward score(movement, ship, to, onlytemp)
129*14010Sedward char movement[];
130*14010Sedward register struct ship *ship, *to;
131*14010Sedward char onlytemp;
13211590Sleres {
133*14010Sedward 	int drift, row, col, dir, total, ran;
134*14010Sedward 	register struct File *fp = ship->file;
13511590Sleres 
136*14010Sedward 	if ((dir = fp->dir) == 0)
137*14010Sedward 		return 0;
138*14010Sedward 	row = fp->row;
139*14010Sedward 	col = fp->col;
140*14010Sedward 	drift = fp->drift;
141*14010Sedward 	move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
142*14010Sedward 	if (!*movement)
143*14010Sedward 		(void) strcpy(movement, "d");
144*14010Sedward 
145*14010Sedward 	ran = range(ship, to);
146*14010Sedward 	total = -50 * ran;
147*14010Sedward 	if (ran < 4 && gunsbear(ship, to))
148*14010Sedward 		total += 60;
149*14010Sedward 	if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
150*14010Sedward 		total = -30000;
151*14010Sedward 
152*14010Sedward 	if (!onlytemp) {
153*14010Sedward 		fp->row = row;
154*14010Sedward 		fp->col = col;
155*14010Sedward 		fp->dir = dir;
156*14010Sedward 	}
157*14010Sedward 	return total;
158*14010Sedward }
159*14010Sedward 
160*14010Sedward moveship(ship, movement)
161*14010Sedward struct ship *ship;
162*14010Sedward char *movement;
163*14010Sedward {
164*14010Sedward 	int drift;
165*14010Sedward 	register struct File *fp = ship->file;
166*14010Sedward 
167*14010Sedward 	if (fp->dir == 0)
168*14010Sedward 		return;
169*14010Sedward 	drift = fp->drift;
170*14010Sedward 	move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
171*14010Sedward 	if (drift > 2 || *movement == 0)
172*14010Sedward 		(void) strcat(movement, "d");
173*14010Sedward 	if (drift != fp->drift)
174*14010Sedward 		Write(W_DRIFT, ship, 0, drift, 0, 0, 0);
175*14010Sedward 	if (fp->row != ship->shiprow)
176*14010Sedward 		Write(W_SHIPROW, ship, 0, fp->row, 0, 0, 0);
177*14010Sedward 	if (fp->col != ship->shipcol)
178*14010Sedward 		Write(W_SHIPCOL, ship, 0, fp->col, 0, 0, 0);
179*14010Sedward 	if (fp->dir != ship->shipdir)
180*14010Sedward 		Write(W_SHIPDIR, ship, 0, fp->dir, 0, 0, 0);
181*14010Sedward }
182*14010Sedward 
183*14010Sedward move(p, ship, dir, row, col, drift)
184*14010Sedward register char *p;
185*14010Sedward register struct ship *ship;
186*14010Sedward register int *dir, *row, *col, *drift;
187*14010Sedward {
188*14010Sedward 	int dist;
189*14010Sedward 	char moved = 0;
190*14010Sedward 
191*14010Sedward 	for (; *p; p++) {
192*14010Sedward 		switch (*p) {
193*14010Sedward 		case 'r':
194*14010Sedward 			if (++*dir == 9)
195*14010Sedward 				*dir = 1;
196*14010Sedward 			break;
197*14010Sedward 		case 'l':
198*14010Sedward 			if (--*dir == 0)
199*14010Sedward 				*dir = 8;
200*14010Sedward 			break;
201*14010Sedward 		case '1': case '2': case '3': case '4':
202*14010Sedward 		case '5': case '6': case '7':
203*14010Sedward 			moved++;
204*14010Sedward 			if (*dir % 2 == 0)
205*14010Sedward 				dist = dtab[*p - '0'];
206*14010Sedward 			else
207*14010Sedward 				dist = *p - '0';
208*14010Sedward 			*row -= dr[*dir] * dist;
209*14010Sedward 			*col -= dc[*dir] * dist;
210*14010Sedward 			break;
211*14010Sedward 		}
212*14010Sedward 	}
213*14010Sedward 	if (!windspeed)
214*14010Sedward 		*drift = 1;
215*14010Sedward 	if (!moved) {
216*14010Sedward 		if (++*drift > 2) {
217*14010Sedward 			if (ship->specs->class >= 3 && !snagged(ship)
218*14010Sedward 			    || turn % 2 == 0) {
219*14010Sedward 				*row -= dr[winddir];
220*14010Sedward 				*col -= dc[winddir];
22111590Sleres 			}
22211590Sleres 		}
223*14010Sedward 	} else
224*14010Sedward 		drift = 0;
22511590Sleres }
22611590Sleres 
227*14010Sedward try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme)
228*14010Sedward register struct ship *f, *t;
229*14010Sedward int ma, ta, af, *high, rakeme;
230*14010Sedward char command[], temp[];
23111590Sleres {
23211590Sleres 	register int new, n;
23311590Sleres 	char st[4];
234*14010Sedward #define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
23511590Sleres 
23611590Sleres 	if ((n = strend(temp)) < '1' || n > '9')
237*14010Sedward 		for (n = 1; vma - n >= 0; n++) {
238*14010Sedward 			(void) sprintf(st, "%d", n);
239*14010Sedward 			(void) strcat(temp, st);
240*14010Sedward 			new = score(temp, f, t, rakeme);
241*14010Sedward 			if (new > *high && (!rakeme || rakeyou)) {
24211590Sleres 				*high = new;
243*14010Sedward 				(void) strcpy(command, temp);
24411590Sleres 			}
245*14010Sedward 			try(command, temp, ma-n, ta, af, vma-n,
246*14010Sedward 				dir, f, t, high, rakeme);
24711590Sleres 			rmend(temp);
24811590Sleres 		}
249*14010Sedward 	if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) {
250*14010Sedward 		(void) strcat(temp, "r");
251*14010Sedward 		new = score(temp, f, t, rakeme);
252*14010Sedward 		if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) {
25311590Sleres 			*high = new;
254*14010Sedward 			(void) strcpy(command, temp);
25511590Sleres 		}
256*14010Sedward 		try(command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1),f,t,high,rakeme);
25711590Sleres 		rmend(temp);
25811590Sleres 	}
259*14010Sedward 	if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){
260*14010Sedward 		(void) strcat(temp, "l");
261*14010Sedward 		new = score(temp, f, t, rakeme);
262*14010Sedward 		if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
26311590Sleres 			*high = new;
264*14010Sedward 			(void) strcpy(command, temp);
26511590Sleres 		}
266*14010Sedward 		try(command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), f, t, high, rakeme);
26711590Sleres 		rmend(temp);
26811590Sleres 	}
26911590Sleres }
270