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