xref: /original-bsd/games/sail/dr_2.c (revision 4b2c5e10)
1 #ifndef lint
2 static	char *sccsid = "@(#)dr_2.c	1.2 83/07/20";
3 #endif
4 
5 #include "driver.h"
6 
7 #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
8 
9 thinkofgrapples()
10 {
11 	register struct ship *sp, *sq;
12 	char friendly;
13 
14 	foreachship(sp) {
15 		if (sp->file->captain[0] || sp->file->dir == 0)
16 			continue;
17 		foreachship(sq) {
18 			friendly = sp->nationality == capship(sq)->nationality;
19 			if (!friendly) {
20 				if (sp->file->struck || sp->file->captured != 0)
21 					continue;
22 				if (range(sp, sq) != 1)
23 					continue;
24 				if (grappled2(sp, sq))
25 					if (toughmelee(sp, sq, 0, 0))
26 						ungrap(sp, sq);
27 					else
28 						grap(sp, sq);
29 				else if (couldwin(sp, sq)) {
30 					grap(sp, sq);
31 					sp->file->loadwith = L_GRAPE;
32 				}
33 			} else
34 				ungrap(sp, sq);
35 		}
36 	}
37 }
38 
39 checkup()
40 {
41 	register int k;
42 	register struct ship *sp, *sq;
43 	register char explode, sink;
44 
45 	readpos();
46 	foreachship(sp) {
47 		explode = sp->file->explode;
48 		sink = sp->file->sink;
49 		if (die() < 5)
50 			continue;
51 		if (explode != 1 && sink != 1)
52 			continue;
53 		Write(sink ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0);
54 		sp->file->dir = 0;	/* hopefully enough to kill ship */
55 		/* Write(n, 0, 10, 0); XXX */
56 		Write(W_CLASS, sp, 0, 0, 0, 0, 0);
57 		if (fouled(sp) || grappled(sp)) {
58 			for (k = 0; k < NSHIP; k++) {
59 				if (sp->file->fouls[k].turnfoul)
60 					cleanfoul(sp,
61 						sp->file->fouls[k].toship, k);
62 			}
63 			for (k = 0; k < NSHIP; k++) {
64 				if (sp->file->grapples[k].turnfoul)
65 					cleangrapple(sp,
66 						sp->file->grapples[k].toship,
67 						k);
68 			}
69 		}
70 		if (sink != 1) {
71 			makesignal(sp, "exploding!", (struct ship *)0);
72 			foreachship(sq) {
73 				if (sp != sq && sq->file->dir && range(sp, sq) < 4)
74 					table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6);
75 			}
76 		} else
77 			makesignal(sp, "sinking!", (struct ship *)0);
78 	}
79 }
80 
81 prizecheck()
82 {
83 	register struct ship *sp;
84 	register int prisoners, points;
85 
86 	foreachship(sp) {
87 		if (sp->file->captured == 0)
88 			continue;
89 		if (sp->file->struck || sp->file->dir == 0)
90 			continue;
91 		prisoners = sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3;
92 		if (prisoners > sp->file->pcrew * 6) {
93 			Write(W_CAPTURED, sp, 0, -1, 0, 0, 0);
94 			Write(W_SIGNAL, sp, 1,
95 				(int)"prize crew overthrown", 0, 0, 0);
96 			points = sp->file->captured->file->points
97 				- 2 * sp->specs->pts;
98 			Write(W_POINTS, sp->file->captured, 0, points, 0, 0, 0);
99 		}
100 	}
101 }
102 
103 strend(str)
104 char *str;
105 {
106 	register char *p;
107 
108 	for (p = str; *p; p++)
109 		;
110 	return p == str ? 0 : p[-1];
111 }
112 
113 closeon(from, to, command, ta, ma, af)
114 register struct ship *from, *to;
115 char command[];
116 int ma, ta, af;
117 {
118 	int high;
119 	char temp[10];
120 
121 	temp[0] = command[0] = '\0';
122 	high = -30000;
123 	try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0);
124 }
125 
126 int dtab[] = {0,1,1,2,3,4,4,5};		/* diagonal distances in x==y */
127 
128 score(movement, ship, to, onlytemp)
129 char movement[];
130 register struct ship *ship, *to;
131 char onlytemp;
132 {
133 	int drift, row, col, dir, total, ran;
134 	register struct File *fp = ship->file;
135 
136 	if ((dir = fp->dir) == 0)
137 		return 0;
138 	row = fp->row;
139 	col = fp->col;
140 	drift = fp->drift;
141 	move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
142 	if (!*movement)
143 		(void) strcpy(movement, "d");
144 
145 	ran = range(ship, to);
146 	total = -50 * ran;
147 	if (ran < 4 && gunsbear(ship, to))
148 		total += 60;
149 	if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
150 		total = -30000;
151 
152 	if (!onlytemp) {
153 		fp->row = row;
154 		fp->col = col;
155 		fp->dir = dir;
156 	}
157 	return total;
158 }
159 
160 moveship(ship, movement)
161 struct ship *ship;
162 char *movement;
163 {
164 	int drift;
165 	register struct File *fp = ship->file;
166 
167 	if (fp->dir == 0)
168 		return;
169 	drift = fp->drift;
170 	move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
171 	if (drift > 2 || *movement == 0)
172 		(void) strcat(movement, "d");
173 	if (drift != fp->drift)
174 		Write(W_DRIFT, ship, 0, drift, 0, 0, 0);
175 	if (fp->row != ship->shiprow)
176 		Write(W_SHIPROW, ship, 0, fp->row, 0, 0, 0);
177 	if (fp->col != ship->shipcol)
178 		Write(W_SHIPCOL, ship, 0, fp->col, 0, 0, 0);
179 	if (fp->dir != ship->shipdir)
180 		Write(W_SHIPDIR, ship, 0, fp->dir, 0, 0, 0);
181 }
182 
183 move(p, ship, dir, row, col, drift)
184 register char *p;
185 register struct ship *ship;
186 register int *dir, *row, *col, *drift;
187 {
188 	int dist;
189 	char moved = 0;
190 
191 	for (; *p; p++) {
192 		switch (*p) {
193 		case 'r':
194 			if (++*dir == 9)
195 				*dir = 1;
196 			break;
197 		case 'l':
198 			if (--*dir == 0)
199 				*dir = 8;
200 			break;
201 		case '1': case '2': case '3': case '4':
202 		case '5': case '6': case '7':
203 			moved++;
204 			if (*dir % 2 == 0)
205 				dist = dtab[*p - '0'];
206 			else
207 				dist = *p - '0';
208 			*row -= dr[*dir] * dist;
209 			*col -= dc[*dir] * dist;
210 			break;
211 		}
212 	}
213 	if (!windspeed)
214 		*drift = 1;
215 	if (!moved) {
216 		if (++*drift > 2) {
217 			if (ship->specs->class >= 3 && !snagged(ship)
218 			    || turn % 2 == 0) {
219 				*row -= dr[winddir];
220 				*col -= dc[winddir];
221 			}
222 		}
223 	} else
224 		drift = 0;
225 }
226 
227 try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme)
228 register struct ship *f, *t;
229 int ma, ta, af, *high, rakeme;
230 char command[], temp[];
231 {
232 	register int new, n;
233 	char st[4];
234 #define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
235 
236 	if ((n = strend(temp)) < '1' || n > '9')
237 		for (n = 1; vma - n >= 0; n++) {
238 			(void) sprintf(st, "%d", n);
239 			(void) strcat(temp, st);
240 			new = score(temp, f, t, rakeme);
241 			if (new > *high && (!rakeme || rakeyou)) {
242 				*high = new;
243 				(void) strcpy(command, temp);
244 			}
245 			try(command, temp, ma-n, ta, af, vma-n,
246 				dir, f, t, high, rakeme);
247 			rmend(temp);
248 		}
249 	if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) {
250 		(void) strcat(temp, "r");
251 		new = score(temp, f, t, rakeme);
252 		if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) {
253 			*high = new;
254 			(void) strcpy(command, temp);
255 		}
256 		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);
257 		rmend(temp);
258 	}
259 	if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){
260 		(void) strcat(temp, "l");
261 		new = score(temp, f, t, rakeme);
262 		if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
263 			*high = new;
264 			(void) strcpy(command, temp);
265 		}
266 		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);
267 		rmend(temp);
268 	}
269 }
270