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