File: | src/games/sail/dr_3.c |
Warning: | line 245, column 7 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: dr_3.c,v 1.7 2016/01/08 20:26:33 mestre Exp $ */ | |||
2 | /* $NetBSD: dr_3.c,v 1.3 1995/04/22 10:36:49 cgd Exp $ */ | |||
3 | ||||
4 | /* | |||
5 | * Copyright (c) 1983, 1993 | |||
6 | * The Regents of the University of California. All rights reserved. | |||
7 | * | |||
8 | * Redistribution and use in source and binary forms, with or without | |||
9 | * modification, are permitted provided that the following conditions | |||
10 | * are met: | |||
11 | * 1. Redistributions of source code must retain the above copyright | |||
12 | * notice, this list of conditions and the following disclaimer. | |||
13 | * 2. Redistributions in binary form must reproduce the above copyright | |||
14 | * notice, this list of conditions and the following disclaimer in the | |||
15 | * documentation and/or other materials provided with the distribution. | |||
16 | * 3. Neither the name of the University nor the names of its contributors | |||
17 | * may be used to endorse or promote products derived from this software | |||
18 | * without specific prior written permission. | |||
19 | * | |||
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
30 | * SUCH DAMAGE. | |||
31 | */ | |||
32 | ||||
33 | #include <stdlib.h> | |||
34 | #include <string.h> | |||
35 | ||||
36 | #include "driver.h" | |||
37 | #include "extern.h" | |||
38 | #include "player.h" | |||
39 | ||||
40 | /* move all comp ships */ | |||
41 | void | |||
42 | moveall(void) | |||
43 | { | |||
44 | struct ship *sp, *sq; /* r11, r10 */ | |||
45 | int n; /* r9 */ | |||
46 | int k, l; /* r8, r7 */ | |||
47 | int row[NSHIP10], col[NSHIP10], dir[NSHIP10], drift[NSHIP10]; | |||
48 | char moved[NSHIP10]; | |||
49 | ||||
50 | /* | |||
51 | * first try to create moves for OUR ships | |||
52 | */ | |||
53 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
| ||||
54 | struct ship *closest; | |||
55 | int ma, ta; | |||
56 | char af; | |||
57 | ||||
58 | if (sp->file->captain[0] || sp->file->dir == 0) | |||
59 | continue; | |||
60 | if (!sp->file->struck && windspeed && !snagged(sp)(((sp)->file->ngrap) + ((sp)->file->nfoul)) | |||
61 | && sp->specs->crew3) { | |||
62 | ta = maxturns(sp, &af); | |||
63 | ma = maxmove(sp, sp->file->dir, 0); | |||
64 | closest = closestenemy(sp, 0, 0); | |||
65 | if (closest == 0) | |||
66 | *sp->file->movebuf = '\0'; | |||
67 | else | |||
68 | closeon(sp, closest, sp->file->movebuf, | |||
69 | sizeof sp->file->movebuf, | |||
70 | ta, ma, af); | |||
71 | } else | |||
72 | *sp->file->movebuf = '\0'; | |||
73 | } | |||
74 | /* | |||
75 | * Then execute the moves for ALL ships (dead ones too), | |||
76 | * checking for collisions and snags at each step. | |||
77 | * The old positions are saved in row[], col[], dir[]. | |||
78 | * At the end, we compare and write out the changes. | |||
79 | */ | |||
80 | n = 0; | |||
81 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
82 | if (snagged(sp)(((sp)->file->ngrap) + ((sp)->file->nfoul))) | |||
83 | (void) strlcpy(sp->file->movebuf, "d", | |||
84 | sizeof sp->file->movebuf); | |||
85 | else | |||
86 | if (*sp->file->movebuf != 'd') | |||
87 | (void) strlcat(sp->file->movebuf, "d", | |||
88 | sizeof sp->file->movebuf); | |||
89 | row[n] = sp->file->row; | |||
90 | col[n] = sp->file->col; | |||
91 | dir[n] = sp->file->dir; | |||
92 | drift[n] = sp->file->drift; | |||
93 | moved[n] = 0; | |||
94 | n++; | |||
95 | } | |||
96 | /* | |||
97 | * Now resolve collisions. | |||
98 | * This is the tough part. | |||
99 | */ | |||
100 | for (k = 0; stillmoving(k); k++) { | |||
101 | /* | |||
102 | * Step once. | |||
103 | * And propagate the nulls at the end of sp->file->movebuf. | |||
104 | */ | |||
105 | n = 0; | |||
106 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
107 | if (!sp->file->movebuf[k]) | |||
108 | sp->file->movebuf[k+1] = '\0'; | |||
109 | else if (sp->file->dir) | |||
110 | step(sp->file->movebuf[k], sp, &moved[n]); | |||
111 | n++; | |||
112 | } | |||
113 | /* | |||
114 | * The real stuff. | |||
115 | */ | |||
116 | n = 0; | |||
117 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
118 | if (sp->file->dir == 0 || is_isolated(sp)) | |||
119 | goto cont1; | |||
120 | l = 0; | |||
121 | foreachship(sq)for ((sq) = cc->ship; (sq) < ls; (sq)++) { | |||
122 | char snap = 0; | |||
123 | ||||
124 | if (sp == sq) | |||
125 | goto cont2; | |||
126 | if (sq->file->dir == 0) | |||
127 | goto cont2; | |||
128 | if (!push(sp, sq)) | |||
129 | goto cont2; | |||
130 | if (snagged2(sp, sq)(((sp)->file->grap[(sq)->file->index].sn_count) + ((sp)->file->foul[(sq)->file->index].sn_count)) && range(sp, sq) > 1) | |||
131 | snap++; | |||
132 | if (!range(sp, sq) && !fouled2(sp, sq)((sp)->file->foul[(sq)->file->index].sn_count)) { | |||
133 | makesignal(sp, "collision with $$", sq); | |||
134 | if (die()(arc4random_uniform(6) + 1) < 4) { | |||
135 | makesignal(sp, "fouled with $$", | |||
136 | sq); | |||
137 | Write(W_FOUL9, sp, l, 0, 0, 0); | |||
138 | Write(W_FOUL9, sq, n, 0, 0, 0); | |||
139 | } | |||
140 | snap++; | |||
141 | } | |||
142 | if (snap) { | |||
143 | sp->file->movebuf[k + 1] = 0; | |||
144 | sq->file->movebuf[k + 1] = 0; | |||
145 | sq->file->row = sp->file->row - 1; | |||
146 | if (sp->file->dir == 1 | |||
147 | || sp->file->dir == 5) | |||
148 | sq->file->col = | |||
149 | sp->file->col - 1; | |||
150 | else | |||
151 | sq->file->col = sp->file->col; | |||
152 | sq->file->dir = sp->file->dir; | |||
153 | } | |||
154 | cont2: | |||
155 | l++; | |||
156 | } | |||
157 | cont1: | |||
158 | n++; | |||
159 | } | |||
160 | } | |||
161 | /* | |||
162 | * Clear old moves. And write out new pos. | |||
163 | */ | |||
164 | n = 0; | |||
165 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
166 | if (sp->file->dir != 0) { | |||
167 | *sp->file->movebuf = 0; | |||
168 | if (row[n] != sp->file->row) | |||
169 | Write(W_ROW23, sp, sp->file->row, 0, 0, 0); | |||
170 | if (col[n] != sp->file->col) | |||
171 | Write(W_COL21, sp, sp->file->col, 0, 0, 0); | |||
172 | if (dir[n] != sp->file->dir) | |||
173 | Write(W_DIR22, sp, sp->file->dir, 0, 0, 0); | |||
174 | if (drift[n] != sp->file->drift) | |||
175 | Write(W_DRIFT6, sp, sp->file->drift, 0, 0, 0); | |||
176 | } | |||
177 | n++; | |||
178 | } | |||
179 | } | |||
180 | ||||
181 | int | |||
182 | stillmoving(int k) | |||
183 | { | |||
184 | struct ship *sp; | |||
185 | ||||
186 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) | |||
187 | if (sp->file->movebuf[k]) | |||
188 | return 1; | |||
189 | return 0; | |||
190 | } | |||
191 | ||||
192 | int | |||
193 | is_isolated(struct ship *ship) | |||
194 | { | |||
195 | struct ship *sp; | |||
196 | ||||
197 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
198 | if (ship != sp && range(ship, sp) <= 10) | |||
199 | return 0; | |||
200 | } | |||
201 | return 1; | |||
202 | } | |||
203 | ||||
204 | int | |||
205 | push(struct ship *from, struct ship *to) | |||
206 | { | |||
207 | int bs, sb; | |||
208 | ||||
209 | sb = to->specs->guns; | |||
210 | bs = from->specs->guns; | |||
211 | if (sb > bs) | |||
212 | return 1; | |||
213 | if (sb < bs) | |||
214 | return 0; | |||
215 | return from < to; | |||
216 | } | |||
217 | ||||
218 | void | |||
219 | step(int com, struct ship *sp, char *moved) | |||
220 | { | |||
221 | int dist; | |||
222 | ||||
223 | switch (com) { | |||
224 | case 'r': | |||
225 | if (++sp->file->dir == 9) | |||
226 | sp->file->dir = 1; | |||
227 | break; | |||
228 | case 'l': | |||
229 | if (--sp->file->dir == 0) | |||
230 | sp->file->dir = 8; | |||
231 | break; | |||
232 | case '0': case '1': case '2': case '3': | |||
233 | case '4': case '5': case '6': case '7': | |||
234 | if (sp->file->dir % 2 == 0) | |||
235 | dist = dtab[com - '0']; | |||
236 | else | |||
237 | dist = com - '0'; | |||
238 | sp->file->row -= dr[sp->file->dir] * dist; | |||
239 | sp->file->col -= dc[sp->file->dir] * dist; | |||
240 | *moved = 1; | |||
241 | break; | |||
242 | case 'b': | |||
243 | break; | |||
244 | case 'd': | |||
245 | if (!*moved) { | |||
| ||||
246 | if (windspeed != 0 && ++sp->file->drift > 2 && | |||
247 | ((sp->specs->class >= 3 && !snagged(sp)(((sp)->file->ngrap) + ((sp)->file->nfoul))) | |||
248 | || (turn & 1) == 0)) { | |||
249 | sp->file->row -= dr[winddir]; | |||
250 | sp->file->col -= dc[winddir]; | |||
251 | } | |||
252 | } else | |||
253 | sp->file->drift = 0; | |||
254 | break; | |||
255 | } | |||
256 | } | |||
257 | ||||
258 | void | |||
259 | sendbp(struct ship *from, struct ship *to, int sections, int isdefense) | |||
260 | { | |||
261 | int n; | |||
262 | struct BP *bp; | |||
263 | ||||
264 | bp = isdefense ? from->file->DBP : from->file->OBP; | |||
265 | for (n = 0; n < NBP3 && bp[n].turnsent; n++) | |||
266 | ; | |||
267 | if (n < NBP3 && sections) { | |||
268 | Write(isdefense ? W_DBP5 : W_OBP14, from, | |||
269 | n, turn, to->file->index, sections); | |||
270 | if (isdefense) | |||
271 | makemsg(from, "repelling boarders"); | |||
272 | else | |||
273 | makesignal(from, "boarding the $$", to); | |||
274 | } | |||
275 | } | |||
276 | ||||
277 | int | |||
278 | is_toughmelee(struct ship *ship, struct ship *to, int isdefense, int count) | |||
279 | { | |||
280 | struct BP *bp; | |||
281 | int obp = 0; | |||
282 | int n, OBP = 0, DBP = 0, dbp = 0; | |||
283 | int qual; | |||
284 | ||||
285 | qual = ship->specs->qual; | |||
286 | bp = isdefense ? ship->file->DBP : ship->file->OBP; | |||
287 | for (n = 0; n < NBP3; n++, bp++) { | |||
288 | if (bp->turnsent && (to == bp->toship || isdefense)) { | |||
289 | obp += bp->mensent / 100 | |||
290 | ? ship->specs->crew1 * qual : 0; | |||
291 | obp += (bp->mensent % 100)/10 | |||
292 | ? ship->specs->crew2 * qual : 0; | |||
293 | obp += bp->mensent % 10 | |||
294 | ? ship->specs->crew3 * qual : 0; | |||
295 | } | |||
296 | } | |||
297 | if (count || isdefense) | |||
298 | return obp; | |||
299 | OBP = is_toughmelee(to, ship, 0, count + 1); | |||
300 | dbp = is_toughmelee(ship, to, 1, count + 1); | |||
301 | DBP = is_toughmelee(to, ship, 1, count + 1); | |||
302 | if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) | |||
303 | return 1; | |||
304 | else | |||
305 | return 0; | |||
306 | } | |||
307 | ||||
308 | void | |||
309 | reload(void) | |||
310 | { | |||
311 | struct ship *sp; | |||
312 | ||||
313 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
314 | sp->file->loadwith = 0; | |||
315 | } | |||
316 | } | |||
317 | ||||
318 | void | |||
319 | checksails(void) | |||
320 | { | |||
321 | struct ship *sp; | |||
322 | int rig, full; | |||
323 | struct ship *close; | |||
324 | ||||
325 | foreachship(sp)for ((sp) = cc->ship; (sp) < ls; (sp)++) { | |||
326 | if (sp->file->captain[0] != 0) | |||
327 | continue; | |||
328 | rig = sp->specs->rig1; | |||
329 | if (windspeed == 6 || (windspeed == 5 && sp->specs->class > 4)) | |||
330 | rig = 0; | |||
331 | if (rig && sp->specs->crew3) { | |||
332 | close = closestenemy(sp, 0, 0); | |||
333 | if (close != 0) { | |||
334 | if (range(sp, close) > 9) | |||
335 | full = 1; | |||
336 | else | |||
337 | full = 0; | |||
338 | } else | |||
339 | full = 0; | |||
340 | } else | |||
341 | full = 0; | |||
342 | if ((sp->file->FS != 0) != full) | |||
343 | Write(W_FS31, sp, full, 0, 0, 0); | |||
344 | } | |||
345 | } |