BSD 4_2 release
[unix-history] / usr / src / games / sail / driver1.c
CommitLineData
0f4556f1
C
1#ifndef lint
2static 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
10unfoul()
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
39boardcomp()
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
102fightitout(from, to, key)
103int 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
165Write(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
197resolve()
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
232compcombat()
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
352next()
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
427main(argc, argv)
428int argc;
429char **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}