Commit | Line | Data |
---|---|---|
b5f0675e | 1 | /* |
1e008c14 | 2 | * Copyright (c) 1983 Regents of the University of California. |
c0ca48ec KB |
3 | * All rights reserved. |
4 | * | |
b2e7427f | 5 | * %sccs.include.redist.c% |
b5f0675e EW |
6 | */ |
7 | ||
b860dc81 | 8 | #ifndef lint |
b2e7427f | 9 | static char sccsid[] = "@(#)dr_3.c 5.4 (Berkeley) %G%"; |
c0ca48ec | 10 | #endif /* not lint */ |
b860dc81 | 11 | |
b3a57661 | 12 | #include "driver.h" |
b860dc81 CL |
13 | |
14 | moveall() /* move all comp ships */ | |
15 | { | |
b3a57661 EW |
16 | register struct ship *sp, *sq; /* r11, r10 */ |
17 | register int n; /* r9 */ | |
6ca45914 | 18 | register int k, l; /* r8, r7 */ |
28c0fb82 EW |
19 | int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; |
20 | char moved[NSHIP]; | |
b860dc81 | 21 | |
b3a57661 EW |
22 | /* |
23 | * first try to create moves for OUR ships | |
24 | */ | |
25 | foreachship(sp) { | |
28c0fb82 EW |
26 | struct ship *closest; |
27 | int ma, ta; | |
28 | char af; | |
29 | ||
6c17b19a | 30 | if (sp->file->captain[0] || sp->file->dir == 0) |
b3a57661 EW |
31 | continue; |
32 | if (!sp->file->struck && windspeed && !snagged(sp) | |
33 | && sp->specs->crew3) { | |
6c17b19a | 34 | ta = maxturns(sp, &af); |
b3a57661 EW |
35 | ma = maxmove(sp, sp->file->dir, 0); |
36 | closest = closestenemy(sp, 0, 0); | |
37 | if (closest == 0) | |
6ca45914 | 38 | *sp->file->movebuf = '\0'; |
b860dc81 | 39 | else |
6ca45914 | 40 | closeon(sp, closest, sp->file->movebuf, |
b3a57661 EW |
41 | ta, ma, af); |
42 | } else | |
6ca45914 | 43 | *sp->file->movebuf = '\0'; |
b860dc81 | 44 | } |
b3a57661 EW |
45 | /* |
46 | * Then execute the moves for ALL ships (dead ones too), | |
28c0fb82 EW |
47 | * checking for collisions and snags at each step. |
48 | * The old positions are saved in row[], col[], dir[]. | |
49 | * At the end, we compare and write out the changes. | |
b3a57661 EW |
50 | */ |
51 | n = 0; | |
52 | foreachship(sp) { | |
53 | if (snagged(sp)) | |
6ca45914 | 54 | (void) strcpy(sp->file->movebuf, "d"); |
b3a57661 | 55 | else |
6ca45914 EW |
56 | if (*sp->file->movebuf != 'd') |
57 | (void) strcat(sp->file->movebuf, "d"); | |
b3a57661 EW |
58 | row[n] = sp->file->row; |
59 | col[n] = sp->file->col; | |
60 | dir[n] = sp->file->dir; | |
28c0fb82 EW |
61 | drift[n] = sp->file->drift; |
62 | moved[n] = 0; | |
b3a57661 | 63 | n++; |
b860dc81 | 64 | } |
b3a57661 EW |
65 | /* |
66 | * Now resolve collisions. | |
67 | * This is the tough part. | |
68 | */ | |
28c0fb82 | 69 | for (k = 0; stillmoving(k); k++) { |
b3a57661 EW |
70 | /* |
71 | * Step once. | |
6ca45914 | 72 | * And propagate the nulls at the end of sp->file->movebuf. |
b3a57661 EW |
73 | */ |
74 | n = 0; | |
75 | foreachship(sp) { | |
6ca45914 EW |
76 | if (!sp->file->movebuf[k]) |
77 | sp->file->movebuf[k+1] = '\0'; | |
28c0fb82 | 78 | else if (sp->file->dir) |
6ca45914 | 79 | step(sp->file->movebuf[k], sp, &moved[n]); |
b3a57661 | 80 | n++; |
b860dc81 | 81 | } |
b3a57661 EW |
82 | /* |
83 | * The real stuff. | |
84 | */ | |
85 | n = 0; | |
86 | foreachship(sp) { | |
28c0fb82 | 87 | if (sp->file->dir == 0 || isolated(sp)) |
759267e0 | 88 | goto cont1; |
b3a57661 EW |
89 | l = 0; |
90 | foreachship(sq) { | |
28c0fb82 EW |
91 | char snap = 0; |
92 | ||
759267e0 EW |
93 | if (sp == sq) |
94 | goto cont2; | |
28c0fb82 | 95 | if (sq->file->dir == 0) |
759267e0 | 96 | goto cont2; |
28c0fb82 EW |
97 | if (!push(sp, sq)) |
98 | goto cont2; | |
99 | if (snagged2(sp, sq) && range(sp, sq) > 1) | |
100 | snap++; | |
101 | if (!range(sp, sq) && !fouled2(sp, sq)) { | |
b3a57661 EW |
102 | makesignal(sp, |
103 | "collision with %s (%c%c)", sq); | |
104 | if (die() < 4) { | |
105 | makesignal(sp, | |
106 | "fouled with %s (%c%c)", | |
107 | sq); | |
6ca45914 EW |
108 | Write(W_FOUL, sp, 0, l, 0, 0, 0); |
109 | Write(W_FOUL, sq, 0, n, 0, 0, 0); | |
b860dc81 | 110 | } |
28c0fb82 EW |
111 | snap++; |
112 | } | |
113 | if (snap) { | |
6ca45914 EW |
114 | sp->file->movebuf[k + 1] = 0; |
115 | sq->file->movebuf[k + 1] = 0; | |
28c0fb82 | 116 | sq->file->row = sp->file->row - 1; |
b3a57661 EW |
117 | if (sp->file->dir == 1 |
118 | || sp->file->dir == 5) | |
28c0fb82 EW |
119 | sq->file->col = |
120 | sp->file->col - 1; | |
b3a57661 | 121 | else |
28c0fb82 EW |
122 | sq->file->col = sp->file->col; |
123 | sq->file->dir = sp->file->dir; | |
b860dc81 | 124 | } |
759267e0 | 125 | cont2: |
b3a57661 | 126 | l++; |
b860dc81 | 127 | } |
759267e0 | 128 | cont1: |
b3a57661 | 129 | n++; |
b860dc81 CL |
130 | } |
131 | } | |
b3a57661 | 132 | /* |
28c0fb82 | 133 | * Clear old moves. And write out new pos. |
b3a57661 | 134 | */ |
28c0fb82 EW |
135 | n = 0; |
136 | foreachship(sp) { | |
137 | if (sp->file->dir != 0) { | |
6ca45914 | 138 | *sp->file->movebuf = 0; |
28c0fb82 | 139 | if (row[n] != sp->file->row) |
6ca45914 | 140 | Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0); |
28c0fb82 | 141 | if (col[n] != sp->file->col) |
6ca45914 | 142 | Write(W_COL, sp, 0, sp->file->col, 0, 0, 0); |
28c0fb82 | 143 | if (dir[n] != sp->file->dir) |
6ca45914 | 144 | Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0); |
28c0fb82 EW |
145 | if (drift[n] != sp->file->drift) |
146 | Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0); | |
147 | } | |
148 | n++; | |
149 | } | |
b860dc81 CL |
150 | } |
151 | ||
28c0fb82 | 152 | stillmoving(k) |
b860dc81 CL |
153 | register int k; |
154 | { | |
b3a57661 | 155 | register struct ship *sp; |
b860dc81 | 156 | |
28c0fb82 | 157 | foreachship(sp) |
6ca45914 | 158 | if (sp->file->movebuf[k]) |
b3a57661 | 159 | return 1; |
b3a57661 | 160 | return 0; |
b860dc81 CL |
161 | } |
162 | ||
163 | isolated(ship) | |
b3a57661 | 164 | register struct ship *ship; |
b860dc81 | 165 | { |
b3a57661 | 166 | register struct ship *sp; |
b860dc81 | 167 | |
b3a57661 EW |
168 | foreachship(sp) { |
169 | if (ship != sp && range(ship, sp) <= 10) | |
170 | return 0; | |
171 | } | |
172 | return 1; | |
b860dc81 CL |
173 | } |
174 | ||
175 | push(from, to) | |
b3a57661 | 176 | register struct ship *from, *to; |
b860dc81 | 177 | { |
b860dc81 CL |
178 | register int bs, sb; |
179 | ||
28c0fb82 EW |
180 | sb = to->specs->guns; |
181 | bs = from->specs->guns; | |
b3a57661 EW |
182 | if (sb > bs) |
183 | return 1; | |
b860dc81 | 184 | if (sb < bs) |
b3a57661 EW |
185 | return 0; |
186 | return from < to; | |
b860dc81 CL |
187 | } |
188 | ||
28c0fb82 | 189 | step(com, sp, moved) |
b860dc81 | 190 | char com; |
28c0fb82 EW |
191 | register struct ship *sp; |
192 | char *moved; | |
b860dc81 | 193 | { |
b860dc81 CL |
194 | register int dist; |
195 | ||
b3a57661 EW |
196 | switch (com) { |
197 | case 'r': | |
28c0fb82 EW |
198 | if (++sp->file->dir == 9) |
199 | sp->file->dir = 1; | |
b3a57661 EW |
200 | break; |
201 | case 'l': | |
28c0fb82 EW |
202 | if (--sp->file->dir == 0) |
203 | sp->file->dir = 8; | |
b3a57661 | 204 | break; |
daf95c1e EW |
205 | case '0': case '1': case '2': case '3': |
206 | case '4': case '5': case '6': case '7': | |
28c0fb82 | 207 | if (sp->file->dir % 2 == 0) |
b3a57661 EW |
208 | dist = dtab[com - '0']; |
209 | else | |
210 | dist = com - '0'; | |
28c0fb82 EW |
211 | sp->file->row -= dr[sp->file->dir] * dist; |
212 | sp->file->col -= dc[sp->file->dir] * dist; | |
213 | *moved = 1; | |
b3a57661 EW |
214 | break; |
215 | case 'b': | |
216 | break; | |
217 | case 'd': | |
28c0fb82 | 218 | if (!*moved) { |
9d517234 | 219 | if (windspeed != 0 && ++sp->file->drift > 2 && |
28c0fb82 EW |
220 | (sp->specs->class >= 3 && !snagged(sp) |
221 | || (turn & 1) == 0)) { | |
222 | sp->file->row -= dr[winddir]; | |
223 | sp->file->col -= dc[winddir]; | |
224 | } | |
225 | } else | |
226 | sp->file->drift = 0; | |
b3a57661 | 227 | break; |
b860dc81 CL |
228 | } |
229 | } | |
230 | ||
b3a57661 EW |
231 | sendbp(from, to, sections, isdefense) |
232 | register struct ship *from, *to; | |
233 | int sections; | |
234 | char isdefense; | |
b860dc81 CL |
235 | { |
236 | int n; | |
b3a57661 | 237 | register struct BP *bp; |
b860dc81 | 238 | |
b3a57661 | 239 | bp = isdefense ? from->file->DBP : from->file->OBP; |
daf95c1e | 240 | for (n = 0; n < NBP && bp[n].turnsent; n++) |
b3a57661 | 241 | ; |
daf95c1e | 242 | if (n < NBP && sections) { |
b3a57661 | 243 | Write(isdefense ? W_DBP : W_OBP, from, 0, |
daf95c1e | 244 | n, turn, to->file->index, sections); |
b3a57661 EW |
245 | if (isdefense) |
246 | makesignal(from, "repelling boarders", | |
247 | (struct ship *)0); | |
b860dc81 | 248 | else |
b3a57661 | 249 | makesignal(from, "boarding the %s (%c%c)", to); |
b860dc81 CL |
250 | } |
251 | } | |
252 | ||
b3a57661 EW |
253 | toughmelee(ship, to, isdefense, count) |
254 | register struct ship *ship, *to; | |
255 | int isdefense, count; | |
b860dc81 | 256 | { |
b3a57661 EW |
257 | register struct BP *bp; |
258 | register obp = 0; | |
259 | int n, OBP = 0, DBP = 0, dbp = 0; | |
b860dc81 | 260 | int qual; |
b860dc81 | 261 | |
b3a57661 EW |
262 | qual = ship->specs->qual; |
263 | bp = isdefense ? ship->file->DBP : ship->file->OBP; | |
264 | for (n = 0; n < NBP; n++, bp++) { | |
265 | if (bp->turnsent && (to == bp->toship || isdefense)) { | |
266 | obp += bp->mensent / 100 | |
267 | ? ship->specs->crew1 * qual : 0; | |
268 | obp += (bp->mensent % 100)/10 | |
269 | ? ship->specs->crew2 * qual : 0; | |
270 | obp += bp->mensent % 10 | |
271 | ? ship->specs->crew3 * qual : 0; | |
b860dc81 CL |
272 | } |
273 | } | |
b3a57661 EW |
274 | if (count || isdefense) |
275 | return obp; | |
276 | OBP = toughmelee(to, ship, 0, count + 1); | |
277 | dbp = toughmelee(ship, to, 1, count + 1); | |
278 | DBP = toughmelee(to, ship, 1, count + 1); | |
b860dc81 | 279 | if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) |
b3a57661 | 280 | return 1; |
b860dc81 | 281 | else |
b3a57661 | 282 | return 0; |
b860dc81 CL |
283 | } |
284 | ||
285 | reload() | |
286 | { | |
b3a57661 | 287 | register struct ship *sp; |
b860dc81 | 288 | |
b3a57661 EW |
289 | foreachship(sp) { |
290 | sp->file->loadwith = 0; | |
291 | } | |
b860dc81 CL |
292 | } |
293 | ||
294 | checksails() | |
295 | { | |
b3a57661 EW |
296 | register struct ship *sp; |
297 | register int rig, full; | |
298 | struct ship *close; | |
b860dc81 | 299 | |
b3a57661 EW |
300 | foreachship(sp) { |
301 | if (sp->file->captain[0] != 0) | |
302 | continue; | |
303 | rig = sp->specs->rig1; | |
304 | if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4) | |
b860dc81 | 305 | rig = 0; |
b3a57661 EW |
306 | if (rig && sp->specs->crew3) { |
307 | close = closestenemy(sp, 0, 0); | |
308 | if (close != 0) { | |
309 | if (range(sp, close) > 9) | |
310 | full = 1; | |
311 | else | |
b860dc81 | 312 | full = 0; |
b3a57661 | 313 | } else |
b860dc81 | 314 | full = 0; |
b3a57661 EW |
315 | } else |
316 | full = 0; | |
317 | if ((sp->file->FS != 0) != full) | |
318 | Write(W_FS, sp, 0, full, 0, 0, 0); | |
b860dc81 CL |
319 | } |
320 | } |