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