Commit | Line | Data |
---|---|---|
41506c08 | 1 | #ifndef lint |
b3a57661 | 2 | static char *sccsid = "@(#)dr_1.c 1.4 83/07/20"; |
41506c08 | 3 | #endif |
7fc06086 | 4 | |
b3a57661 | 5 | #include "driver.h" |
41506c08 CL |
6 | |
7 | unfoul() | |
8 | { | |
b3a57661 EW |
9 | register int k; |
10 | register struct ship *sp; | |
11 | struct ship *to; | |
12 | register int nat; | |
41506c08 | 13 | |
b3a57661 EW |
14 | foreachship(sp) { |
15 | if (sp->file->captain[0]) | |
16 | continue; | |
17 | nat = capship(sp)->nationality; | |
18 | for (k = 0; k < NSHIP; k++) { | |
19 | if (sp->file->fouls[k].turnfoul == 0) | |
20 | continue; | |
21 | to = sp->file->fouls[k].toship; | |
22 | if (nat != capship(to)->nationality) | |
23 | continue; | |
24 | if (!toughmelee(sp, to, 0, 0)) | |
25 | continue; | |
26 | if (die() <= 2) | |
27 | cleanfoul(sp, to, k); | |
41506c08 CL |
28 | } |
29 | } | |
30 | } | |
31 | ||
41506c08 CL |
32 | boardcomp() |
33 | { | |
7fc06086 | 34 | int crew[3]; |
b3a57661 | 35 | register struct ship *sp, *sq; |
41506c08 | 36 | |
b3a57661 EW |
37 | foreachship(sp) { |
38 | if (*sp->file->captain) | |
39 | continue; | |
40 | if (!fouled(sp) && !grappled(sp)) | |
41 | continue; | |
42 | if (sp->file->dir == 0) | |
43 | continue; | |
44 | if (sp->file->struck || sp->file->captured != 0) | |
45 | continue; | |
46 | crew[0] = sp->specs->crew1 != 0; | |
47 | crew[1] = sp->specs->crew2 != 0; | |
48 | crew[2] = sp->specs->crew3 != 0; | |
49 | foreachship(sq) { | |
50 | if (!Xsnagged2(sp, sq)) | |
51 | continue; | |
52 | if (meleeing(sp, sq)) | |
53 | continue; | |
54 | if (!sq->file->dir | |
55 | || sp->nationality == capship(sq)->nationality) | |
56 | continue; | |
57 | switch (sp->specs->class - sq->specs->class) { | |
58 | case -3: case -4: case -5: | |
59 | if (crew[0]) { | |
60 | /* OBP */ | |
61 | sendbp(sp, sq, crew[0]*100, 0); | |
62 | crew[0] = 0; | |
63 | } else if (crew[1]){ | |
64 | /* OBP */ | |
65 | sendbp(sp, sq, crew[1]*10, 0); | |
66 | crew[1] = 0; | |
67 | } | |
68 | break; | |
69 | case -2: | |
70 | if (crew[0] || crew[1]) { | |
71 | /* OBP */ | |
72 | sendbp(sp, sq, crew[0]*100+crew[1]*10, | |
73 | 0); | |
74 | crew[0] = crew[1] = 0; | |
75 | } | |
76 | break; | |
77 | case -1: case 0: case 1: | |
78 | if (crew[0]) { | |
79 | /* OBP */ | |
80 | sendbp(sp, sq, crew[0]*100+crew[1]*10, | |
81 | 0); | |
82 | crew[0] = crew[1] = 0; | |
41506c08 | 83 | } |
b3a57661 EW |
84 | break; |
85 | case 2: case 3: case 4: case 5: | |
86 | /* OBP */ | |
87 | sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2], | |
88 | 0); | |
89 | crew[0] = crew[1] = crew[2] = 0; | |
90 | break; | |
41506c08 | 91 | } |
b3a57661 | 92 | } |
41506c08 CL |
93 | } |
94 | } | |
95 | ||
41506c08 | 96 | fightitout(from, to, key) |
b3a57661 EW |
97 | struct ship *from, *to; |
98 | int key; | |
41506c08 | 99 | { |
b3a57661 EW |
100 | struct ship *fromcap, *tocap; |
101 | int crewfrom[3], crewto[3], menfrom, mento; | |
41506c08 | 102 | int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured; |
b3a57661 EW |
103 | int topoints; |
104 | int index, totalfrom = 0, totalto = 0; | |
105 | int count; | |
41506c08 CL |
106 | char message[60]; |
107 | ||
b3a57661 EW |
108 | menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key); |
109 | mento = mensent(to, from, crewto, &tocap, &pcto, 0); | |
110 | if (fromcap == 0) | |
41506c08 | 111 | fromcap = from; |
b3a57661 | 112 | if (tocap == 0) |
41506c08 | 113 | tocap = to; |
b3a57661 EW |
114 | fromstrength = menfrom * fromcap->specs->qual; |
115 | strengthto = mento * tocap->specs->qual; | |
116 | if (key && !menfrom) { | |
41506c08 | 117 | if (fromcap == from) |
b3a57661 EW |
118 | menfrom = from->specs->crew1 |
119 | + from->specs->crew2 + from->specs->crew3; | |
41506c08 | 120 | else |
b3a57661 | 121 | menfrom = from->file->pcrew; |
41506c08 CL |
122 | fromstrength = -1; |
123 | strengthto *= 2; | |
124 | } | |
b3a57661 EW |
125 | for (count = 0; |
126 | (fromstrength < strengthto * 3 && strengthto < fromstrength * 3 | |
127 | || fromstrength == -1) && count < 4; | |
128 | count++) { | |
41506c08 CL |
129 | index = fromstrength/10; |
130 | if (index > 8) | |
131 | index = 8; | |
132 | toinjured = MT[index][2 - die() / 3]; | |
133 | totalto += toinjured; | |
134 | index = strengthto/10; | |
135 | if (index > 8) | |
136 | index = 8; | |
137 | frominjured = MT[index][2 - die() / 3]; | |
138 | totalfrom += frominjured; | |
139 | menfrom -= frominjured; | |
140 | mento -= toinjured; | |
b3a57661 EW |
141 | fromstrength = menfrom * fromcap->specs->qual; |
142 | strengthto = mento * tocap->specs->qual; | |
41506c08 | 143 | } |
b3a57661 | 144 | if (fromstrength >= strengthto * 3 || count == 4) { |
41506c08 CL |
145 | unboard(to, from, 0); |
146 | subtract(from, totalfrom, crewfrom, fromcap, pcfrom); | |
147 | subtract(to, totalto, crewto, tocap, pcto); | |
b3a57661 EW |
148 | makesignal(from, "boarders from %s repelled", to); |
149 | (void) sprintf(message, "killed in melee: %d. %s: %d", | |
150 | totalto, from->shipname, totalfrom); | |
151 | Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); | |
41506c08 | 152 | if (key) |
b3a57661 EW |
153 | return 1; |
154 | } else if (strengthto >= fromstrength * 3) { | |
41506c08 CL |
155 | unboard(from, to, 0); |
156 | subtract(from, totalfrom, crewfrom, fromcap, pcfrom); | |
157 | subtract(to, totalto, crewto, tocap, pcto); | |
b3a57661 | 158 | if (key) { |
41506c08 | 159 | if (fromcap != from) |
b3a57661 EW |
160 | Write(W_POINTS, fromcap, 0, |
161 | fromcap->file->points - | |
162 | from->file->struck | |
163 | ? from->specs->pts | |
164 | : 2 * from->specs->pts, | |
165 | 0, 0, 0); | |
41506c08 CL |
166 | |
167 | /* ptr1 points to the shipspec for the ship that was just unboarded. | |
168 | I guess that what is going on here is that the pointer is multiplied | |
169 | or something. */ | |
170 | ||
b3a57661 EW |
171 | Write(W_CAPTURED, from, 0, to-SHIP(0), 0, 0, 0); |
172 | topoints = 2 * from->specs->pts + to->file->points; | |
173 | if (from->file->struck) | |
174 | topoints -= from->specs->pts; | |
175 | Write(W_POINTS, to, 0, topoints, 0, 0, 0); | |
41506c08 | 176 | mento = crewto[0] ? crewto[0] : crewto[1]; |
b3a57661 | 177 | if (mento) { |
41506c08 | 178 | subtract(to, mento, crewto, tocap, pcto); |
b3a57661 | 179 | subtract(from, - mento, crewfrom, to, 0); |
41506c08 | 180 | } |
b3a57661 EW |
181 | (void) sprintf(message, "captured by the %s!", |
182 | to->shipname); | |
183 | Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0); | |
184 | (void) sprintf(message, "killed in melee: %d. %s: %d", | |
185 | totalto, from->shipname, totalfrom); | |
186 | Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0); | |
41506c08 | 187 | mento = 0; |
b3a57661 | 188 | return 0; |
41506c08 CL |
189 | } |
190 | } | |
b3a57661 EW |
191 | return 0; |
192 | } | |
41506c08 CL |
193 | |
194 | resolve() | |
195 | { | |
b3a57661 EW |
196 | int thwart; |
197 | register struct ship *sp, *sq; | |
41506c08 | 198 | |
b3a57661 | 199 | foreachship(sp) { |
41506c08 | 200 | thwart = 2; |
b3a57661 EW |
201 | if (sp->file->dir == 0) |
202 | continue; | |
203 | foreachship(sq) | |
204 | if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp)) | |
205 | (void) fightitout(sp, sq, 0); | |
206 | foreachship(sq) { | |
207 | if (sq->file->dir && meleeing(sq, sp)) | |
208 | thwart = fightitout(sp, sq, 1); | |
209 | if (!thwart) | |
210 | break; | |
211 | } | |
212 | foreachship(sq) { | |
213 | if (sq->file->dir && meleeing(sq, sp)) | |
214 | unboard(sq, sp, 0); | |
215 | unboard(sp, sq, 0); | |
41506c08 | 216 | } |
b3a57661 EW |
217 | unboard(sp, sp, 1); |
218 | if (thwart == 2) | |
219 | unboard(sp, sp, 1); | |
41506c08 CL |
220 | } |
221 | } | |
222 | ||
41506c08 CL |
223 | compcombat() |
224 | { | |
b3a57661 EW |
225 | register n; |
226 | register struct ship *sp; | |
227 | struct ship *closest; | |
41506c08 | 228 | int crew[3], men = 0, target, temp; |
b3a57661 EW |
229 | int r, guns, load, car; |
230 | int ready, index, rakehim, sternrake; | |
231 | int shootat, hit; | |
41506c08 | 232 | |
b3a57661 EW |
233 | foreachship(sp) { |
234 | if (sp->file->captain[0] || sp->file->dir == 0) | |
235 | continue; | |
236 | crew[0] = sp->specs->crew1; | |
237 | crew[1] = sp->specs->crew2; | |
238 | crew[2] = sp->specs->crew3; | |
239 | for (n = 0; n < 3; n++) { | |
240 | if (sp->file->OBP[n].turnsent) | |
241 | men += sp->file->OBP[n].mensent; | |
242 | } | |
243 | for (n = 0; n < 3; n++) { | |
244 | if (sp->file->DBP[n].turnsent) | |
245 | men += sp->file->DBP[n].mensent; | |
246 | } | |
247 | if (men){ | |
248 | crew[0] = men/100 ? 0 : crew[0] != 0; | |
249 | crew[1] = (men%100)/10 ? 0 : crew[1] != 0; | |
250 | crew[2] = men%10 ? 0 : crew[2] != 0; | |
251 | } | |
252 | for (r = 0; r < 2; r++) { | |
253 | if (!crew[2]) | |
254 | continue; | |
255 | if (sp->file->struck) | |
256 | continue; | |
257 | if (r) { | |
258 | ready = sp->file->readyR; | |
259 | guns = sp->specs->gunR; | |
260 | car = sp->specs->carR; | |
261 | } else { | |
262 | ready = sp->file->readyL; | |
263 | guns = sp->specs->gunL; | |
264 | car = sp->specs->carL; | |
41506c08 | 265 | } |
b3a57661 EW |
266 | if (!guns && !car) |
267 | continue; | |
268 | if ((ready & R_LOADED) == 0) | |
269 | continue; | |
270 | closest = closestenemy(sp, r ? 'r' : 'l', 0); | |
271 | if (closest == 0) | |
272 | continue; | |
273 | if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1))) | |
274 | continue; | |
275 | if (closest->file->struck) | |
276 | continue; | |
277 | target = range(sp, closest); | |
278 | if (target > 10) | |
279 | continue; | |
280 | if (!guns && target >= 3) | |
281 | continue; | |
282 | load = L_ROUND; | |
283 | if (target == 1 && sp->file->loadwith == L_GRAPE) | |
284 | load = L_GRAPE; | |
285 | if (target <= 3 && closest->file->FS) | |
286 | load = L_CHAIN; | |
287 | if (target == 1 && load != L_GRAPE) | |
288 | load = L_DOUBLE; | |
289 | if (load > L_CHAIN && target < 6) | |
290 | shootat = HULL; | |
291 | else | |
292 | shootat = RIGGING; | |
293 | rakehim = gunsbear(sp, closest) | |
294 | && !gunsbear(closest, sp); | |
295 | temp = portside(closest, sp, 1) | |
296 | - closest->file->dir + 1; | |
297 | if (temp < 1) | |
298 | temp += 8; | |
299 | if (temp > 8) | |
300 | temp -= 8; | |
301 | sternrake = temp > 4 && temp < 6; | |
302 | index = guns; | |
303 | if (target < 3) | |
304 | index += car; | |
305 | index = (index - 1) / 3; | |
306 | index = index > 8 ? 8 : index; | |
307 | if (!rakehim) | |
308 | hit = HDT[index][target-1]; | |
309 | else | |
310 | hit = HDTrake[index][target-1]; | |
311 | if (rakehim && sternrake) | |
312 | hit++; | |
313 | hit += QUAL[index][capship(sp)->specs->qual - 1]; | |
314 | for (n = 0; n < 3 && sp->file->captured == 0; n++) | |
315 | if (!crew[n]) | |
316 | if (index <= 5) | |
317 | hit--; | |
318 | else | |
319 | hit -= 2; | |
320 | if (ready & R_INITIAL) | |
321 | if (index <= 3) | |
322 | hit++; | |
41506c08 | 323 | else |
b3a57661 EW |
324 | hit += 2; |
325 | if (sp->file->captured != 0) | |
326 | if (index <= 1) | |
327 | hit--; | |
328 | else | |
329 | hit -= 2; | |
330 | hit += AMMO[index][load - 1]; | |
331 | temp = sp->specs->class; | |
332 | if ((temp >= 5 || temp == 1) && windspeed == 5) | |
333 | hit--; | |
334 | if (windspeed == 6 && temp == 4) | |
335 | hit -= 2; | |
336 | if (windspeed == 6 && temp <= 3) | |
337 | hit--; | |
338 | if (hit >= 0) { | |
339 | if (load != L_GRAPE) | |
340 | hit = hit > 10 ? 10 : hit; | |
341 | table(shootat, load, hit, closest, sp, die()); | |
41506c08 | 342 | } |
b3a57661 EW |
343 | if (!r) |
344 | sp->file->readyL = R_EMPTY; | |
345 | else | |
346 | sp->file->readyR = R_EMPTY; | |
41506c08 CL |
347 | } |
348 | } | |
349 | } | |
350 | ||
351 | next() | |
352 | { | |
b3a57661 EW |
353 | if (++turn % 55 == 0) |
354 | if (cc->time) | |
355 | cc->time = 0; | |
41506c08 | 356 | else |
b3a57661 EW |
357 | cc->people = 0; /* die if no one */ |
358 | if (cc->people <= 0 || windspeed == 7) { | |
359 | char string[25]; | |
360 | ||
361 | (void) fclose(syncfile); | |
362 | (void) sprintf(string, "/tmp/.%d", game); | |
41506c08 CL |
363 | if (unlink(string) == -1) |
364 | perror(string); | |
365 | exit(0); | |
366 | } | |
b3a57661 EW |
367 | Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0); |
368 | if (turn % 7 == 0) { | |
369 | if (die() >= cc->windchange || !windspeed) { | |
370 | switch (die()) { | |
371 | case 1: | |
372 | winddir = 1; | |
373 | break; | |
374 | case 2: | |
375 | break; | |
376 | case 3: | |
377 | winddir++; | |
378 | break; | |
379 | case 4: | |
380 | winddir--; | |
381 | break; | |
382 | case 5: | |
383 | winddir += 2; | |
384 | break; | |
385 | case 6: | |
386 | winddir -= 2; | |
387 | break; | |
41506c08 CL |
388 | } |
389 | if (winddir > 8) | |
390 | winddir -= 8; | |
391 | if (winddir < 1) | |
392 | winddir += 8; | |
41506c08 | 393 | if (windspeed) |
b3a57661 EW |
394 | switch (die()) { |
395 | case 1: | |
396 | case 2: | |
397 | windspeed--; | |
398 | break; | |
399 | case 5: | |
400 | case 6: | |
401 | windspeed++; | |
402 | break; | |
41506c08 CL |
403 | } |
404 | else | |
405 | windspeed++; | |
b3a57661 EW |
406 | Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0); |
407 | } | |
41506c08 CL |
408 | } |
409 | } | |
410 | ||
411 | main(argc, argv) | |
412 | int argc; | |
413 | char **argv; | |
414 | { | |
b3a57661 | 415 | register int n; |
41506c08 | 416 | char file[25]; |
b3a57661 EW |
417 | register struct ship *sp; |
418 | int nat[NNATION]; | |
41506c08 | 419 | |
b3a57661 EW |
420 | if (argc != 2) |
421 | exit(1); | |
422 | (void) signal(SIGINT, SIG_IGN); | |
423 | (void) signal(SIGQUIT, SIG_IGN); | |
424 | (void) srand(getpid()); | |
41506c08 | 425 | /* ;;; add code here to check the game number. */ |
b3a57661 | 426 | (void) sprintf(file, "/tmp/.%s", argv[1]); |
a0b548f9 | 427 | for (n = 0; access(file, 0) < 0 && n < 20; n++) |
41506c08 CL |
428 | sleep(5); |
429 | syncfile = fopen(file, "r+"); | |
a0b548f9 BJ |
430 | if (syncfile == NULL) { |
431 | perror(file); | |
432 | exit(1); | |
433 | } | |
b3a57661 EW |
434 | game = atoi(argv[1]); |
435 | cc = &scene[game]; | |
436 | ls = &cc->ship[cc->vessels]; | |
437 | for (n = 0; n < NNATION; n++) | |
438 | nat[n] = 0; | |
439 | foreachship(sp) { | |
440 | sp->file = (struct File *) calloc(1, sizeof (struct File)); | |
441 | if (sp == NULL) { | |
442 | (void) printf("driver: OUT OF MEMORY\n"); | |
41506c08 CL |
443 | exit(0); |
444 | } | |
b3a57661 EW |
445 | sp->file->loadL = L_ROUND; |
446 | sp->file->loadR = L_ROUND; | |
447 | sp->file->readyR = R_LOADED|R_INITIAL; | |
448 | sp->file->readyL = R_LOADED|R_INITIAL; | |
449 | sp->file->stern = nat[sp->nationality]++; | |
41506c08 | 450 | } |
b3a57661 EW |
451 | for (;;) { |
452 | Sync(); | |
453 | windspeed = cc->windspeed; | |
454 | winddir = cc->winddir; | |
455 | turn = cc->turn; | |
41506c08 CL |
456 | next(); |
457 | unfoul(); | |
458 | checkup(); | |
459 | prizecheck(); | |
460 | moveall(); | |
461 | readpos(); | |
462 | thinkofgrapples(); | |
463 | boardcomp(); | |
464 | compcombat(); | |
465 | readpos(); | |
466 | resolve(); | |
467 | reload(); | |
468 | checksails(); | |
b3a57661 | 469 | Sync(); |
41506c08 | 470 | sleep(7); |
41506c08 CL |
471 | } |
472 | } |