(no message)
[unix-history] / usr / src / games / sail / dr_1.c
CommitLineData
41506c08 1#ifndef lint
b3a57661 2static char *sccsid = "@(#)dr_1.c 1.4 83/07/20";
41506c08 3#endif
7fc06086 4
b3a57661 5#include "driver.h"
41506c08
CL
6
7unfoul()
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
32boardcomp()
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 96fightitout(from, to, key)
b3a57661
EW
97struct ship *from, *to;
98int 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
194resolve()
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
223compcombat()
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
351next()
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
411main(argc, argv)
412int argc;
413char **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}