date and time created 88/10/19 15:51:23 by bostic
[unix-history] / usr / src / games / sail / dr_1.c
CommitLineData
b5f0675e 1/*
1e008c14 2 * Copyright (c) 1983 Regents of the University of California.
c0ca48ec
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
65c7d3b6
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
b5f0675e
EW
16 */
17
41506c08 18#ifndef lint
65c7d3b6 19static char sccsid[] = "@(#)dr_1.c 5.3 (Berkeley) %G%";
c0ca48ec 20#endif /* not lint */
7fc06086 21
b3a57661 22#include "driver.h"
41506c08
CL
23
24unfoul()
25{
b3a57661
EW
26 register struct ship *sp;
27 struct ship *to;
28 register int nat;
6ca45914 29 register i;
41506c08 30
b3a57661
EW
31 foreachship(sp) {
32 if (sp->file->captain[0])
33 continue;
34 nat = capship(sp)->nationality;
6ca45914 35 foreachship(to) {
ba28d9ed
EW
36 if (nat != capship(to)->nationality &&
37 !toughmelee(sp, to, 0, 0))
b3a57661 38 continue;
6ca45914
EW
39 for (i = fouled2(sp, to); --i >= 0;)
40 if (die() <= 2)
41 cleanfoul(sp, to, 0);
41506c08
CL
42 }
43 }
44}
45
41506c08
CL
46boardcomp()
47{
7fc06086 48 int crew[3];
b3a57661 49 register struct ship *sp, *sq;
41506c08 50
b3a57661
EW
51 foreachship(sp) {
52 if (*sp->file->captain)
53 continue;
b3a57661
EW
54 if (sp->file->dir == 0)
55 continue;
56 if (sp->file->struck || sp->file->captured != 0)
57 continue;
6ca45914
EW
58 if (!snagged(sp))
59 continue;
b3a57661
EW
60 crew[0] = sp->specs->crew1 != 0;
61 crew[1] = sp->specs->crew2 != 0;
62 crew[2] = sp->specs->crew3 != 0;
63 foreachship(sq) {
64 if (!Xsnagged2(sp, sq))
65 continue;
66 if (meleeing(sp, sq))
67 continue;
68 if (!sq->file->dir
69 || sp->nationality == capship(sq)->nationality)
70 continue;
71 switch (sp->specs->class - sq->specs->class) {
72 case -3: case -4: case -5:
73 if (crew[0]) {
74 /* OBP */
75 sendbp(sp, sq, crew[0]*100, 0);
76 crew[0] = 0;
77 } else if (crew[1]){
78 /* OBP */
79 sendbp(sp, sq, crew[1]*10, 0);
80 crew[1] = 0;
81 }
82 break;
83 case -2:
84 if (crew[0] || crew[1]) {
85 /* OBP */
86 sendbp(sp, sq, crew[0]*100+crew[1]*10,
87 0);
88 crew[0] = crew[1] = 0;
89 }
90 break;
91 case -1: case 0: case 1:
92 if (crew[0]) {
93 /* OBP */
94 sendbp(sp, sq, crew[0]*100+crew[1]*10,
95 0);
96 crew[0] = crew[1] = 0;
41506c08 97 }
b3a57661
EW
98 break;
99 case 2: case 3: case 4: case 5:
100 /* OBP */
101 sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
102 0);
103 crew[0] = crew[1] = crew[2] = 0;
104 break;
41506c08 105 }
b3a57661 106 }
41506c08
CL
107 }
108}
109
41506c08 110fightitout(from, to, key)
b3a57661
EW
111struct ship *from, *to;
112int key;
41506c08 113{
b3a57661
EW
114 struct ship *fromcap, *tocap;
115 int crewfrom[3], crewto[3], menfrom, mento;
41506c08 116 int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
b3a57661
EW
117 int topoints;
118 int index, totalfrom = 0, totalto = 0;
119 int count;
41506c08
CL
120 char message[60];
121
b3a57661
EW
122 menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
123 mento = mensent(to, from, crewto, &tocap, &pcto, 0);
124 if (fromcap == 0)
41506c08 125 fromcap = from;
b3a57661 126 if (tocap == 0)
41506c08 127 tocap = to;
6ca45914 128 if (key) {
22cfa172
EW
129 if (!menfrom) { /* if crew surprised */
130 if (fromcap == from)
131 menfrom = from->specs->crew1
132 + from->specs->crew2
133 + from->specs->crew3;
134 else
135 menfrom = from->file->pcrew;
136 } else {
137 menfrom *= 2; /* DBP's fight at an advantage */
138 }
139 }
b3a57661
EW
140 fromstrength = menfrom * fromcap->specs->qual;
141 strengthto = mento * tocap->specs->qual;
b3a57661
EW
142 for (count = 0;
143 (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
144 || fromstrength == -1) && count < 4;
145 count++) {
41506c08
CL
146 index = fromstrength/10;
147 if (index > 8)
148 index = 8;
149 toinjured = MT[index][2 - die() / 3];
150 totalto += toinjured;
151 index = strengthto/10;
152 if (index > 8)
153 index = 8;
154 frominjured = MT[index][2 - die() / 3];
155 totalfrom += frominjured;
156 menfrom -= frominjured;
157 mento -= toinjured;
b3a57661
EW
158 fromstrength = menfrom * fromcap->specs->qual;
159 strengthto = mento * tocap->specs->qual;
41506c08 160 }
b3a57661 161 if (fromstrength >= strengthto * 3 || count == 4) {
41506c08
CL
162 unboard(to, from, 0);
163 subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
164 subtract(to, totalto, crewto, tocap, pcto);
b3a57661
EW
165 makesignal(from, "boarders from %s repelled", to);
166 (void) sprintf(message, "killed in melee: %d. %s: %d",
167 totalto, from->shipname, totalfrom);
168 Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
41506c08 169 if (key)
b3a57661
EW
170 return 1;
171 } else if (strengthto >= fromstrength * 3) {
41506c08
CL
172 unboard(from, to, 0);
173 subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
174 subtract(to, totalto, crewto, tocap, pcto);
b3a57661 175 if (key) {
41506c08 176 if (fromcap != from)
b3a57661
EW
177 Write(W_POINTS, fromcap, 0,
178 fromcap->file->points -
179 from->file->struck
180 ? from->specs->pts
181 : 2 * from->specs->pts,
182 0, 0, 0);
41506c08
CL
183
184/* ptr1 points to the shipspec for the ship that was just unboarded.
185 I guess that what is going on here is that the pointer is multiplied
186 or something. */
187
6ca45914 188 Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
b3a57661
EW
189 topoints = 2 * from->specs->pts + to->file->points;
190 if (from->file->struck)
191 topoints -= from->specs->pts;
192 Write(W_POINTS, to, 0, topoints, 0, 0, 0);
41506c08 193 mento = crewto[0] ? crewto[0] : crewto[1];
b3a57661 194 if (mento) {
41506c08 195 subtract(to, mento, crewto, tocap, pcto);
b3a57661 196 subtract(from, - mento, crewfrom, to, 0);
41506c08 197 }
b3a57661
EW
198 (void) sprintf(message, "captured by the %s!",
199 to->shipname);
200 Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
201 (void) sprintf(message, "killed in melee: %d. %s: %d",
202 totalto, from->shipname, totalfrom);
203 Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
41506c08 204 mento = 0;
b3a57661 205 return 0;
41506c08
CL
206 }
207 }
b3a57661
EW
208 return 0;
209}
41506c08
CL
210
211resolve()
212{
b3a57661
EW
213 int thwart;
214 register struct ship *sp, *sq;
41506c08 215
b3a57661 216 foreachship(sp) {
b3a57661
EW
217 if (sp->file->dir == 0)
218 continue;
22cfa172 219 for (sq = sp + 1; sq < ls; sq++)
b3a57661
EW
220 if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
221 (void) fightitout(sp, sq, 0);
265d8c6a 222 thwart = 2;
b3a57661
EW
223 foreachship(sq) {
224 if (sq->file->dir && meleeing(sq, sp))
225 thwart = fightitout(sp, sq, 1);
226 if (!thwart)
227 break;
228 }
265d8c6a
EW
229 if (!thwart) {
230 foreachship(sq) {
231 if (sq->file->dir && meleeing(sq, sp))
232 unboard(sq, sp, 0);
233 unboard(sp, sq, 0);
234 }
235 unboard(sp, sp, 1);
236 } else if (thwart == 2)
b3a57661 237 unboard(sp, sp, 1);
41506c08
CL
238 }
239}
240
41506c08
CL
241compcombat()
242{
b3a57661
EW
243 register n;
244 register struct ship *sp;
245 struct ship *closest;
41506c08 246 int crew[3], men = 0, target, temp;
3ee7f12c
EW
247 int r, guns, ready, load, car;
248 int index, rakehim, sternrake;
b3a57661 249 int shootat, hit;
41506c08 250
b3a57661
EW
251 foreachship(sp) {
252 if (sp->file->captain[0] || sp->file->dir == 0)
253 continue;
254 crew[0] = sp->specs->crew1;
255 crew[1] = sp->specs->crew2;
256 crew[2] = sp->specs->crew3;
257 for (n = 0; n < 3; n++) {
258 if (sp->file->OBP[n].turnsent)
259 men += sp->file->OBP[n].mensent;
260 }
261 for (n = 0; n < 3; n++) {
262 if (sp->file->DBP[n].turnsent)
263 men += sp->file->DBP[n].mensent;
264 }
265 if (men){
266 crew[0] = men/100 ? 0 : crew[0] != 0;
267 crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
268 crew[2] = men%10 ? 0 : crew[2] != 0;
269 }
270 for (r = 0; r < 2; r++) {
271 if (!crew[2])
272 continue;
273 if (sp->file->struck)
274 continue;
275 if (r) {
276 ready = sp->file->readyR;
277 guns = sp->specs->gunR;
278 car = sp->specs->carR;
279 } else {
280 ready = sp->file->readyL;
281 guns = sp->specs->gunL;
282 car = sp->specs->carL;
41506c08 283 }
b3a57661
EW
284 if (!guns && !car)
285 continue;
286 if ((ready & R_LOADED) == 0)
287 continue;
288 closest = closestenemy(sp, r ? 'r' : 'l', 0);
289 if (closest == 0)
290 continue;
291 if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
292 continue;
293 if (closest->file->struck)
294 continue;
295 target = range(sp, closest);
296 if (target > 10)
297 continue;
298 if (!guns && target >= 3)
299 continue;
300 load = L_ROUND;
301 if (target == 1 && sp->file->loadwith == L_GRAPE)
302 load = L_GRAPE;
303 if (target <= 3 && closest->file->FS)
304 load = L_CHAIN;
305 if (target == 1 && load != L_GRAPE)
306 load = L_DOUBLE;
307 if (load > L_CHAIN && target < 6)
308 shootat = HULL;
309 else
310 shootat = RIGGING;
311 rakehim = gunsbear(sp, closest)
312 && !gunsbear(closest, sp);
313 temp = portside(closest, sp, 1)
314 - closest->file->dir + 1;
315 if (temp < 1)
316 temp += 8;
317 if (temp > 8)
318 temp -= 8;
319 sternrake = temp > 4 && temp < 6;
320 index = guns;
321 if (target < 3)
322 index += car;
323 index = (index - 1) / 3;
324 index = index > 8 ? 8 : index;
325 if (!rakehim)
326 hit = HDT[index][target-1];
327 else
328 hit = HDTrake[index][target-1];
329 if (rakehim && sternrake)
330 hit++;
331 hit += QUAL[index][capship(sp)->specs->qual - 1];
332 for (n = 0; n < 3 && sp->file->captured == 0; n++)
333 if (!crew[n])
334 if (index <= 5)
335 hit--;
336 else
337 hit -= 2;
3ee7f12c
EW
338 if (ready & R_INITIAL) {
339 if (!r)
340 sp->file->readyL &= ~R_INITIAL;
341 else
342 sp->file->readyR &= ~R_INITIAL;
b3a57661
EW
343 if (index <= 3)
344 hit++;
41506c08 345 else
b3a57661 346 hit += 2;
3ee7f12c 347 }
b3a57661
EW
348 if (sp->file->captured != 0)
349 if (index <= 1)
350 hit--;
351 else
352 hit -= 2;
353 hit += AMMO[index][load - 1];
354 temp = sp->specs->class;
355 if ((temp >= 5 || temp == 1) && windspeed == 5)
356 hit--;
357 if (windspeed == 6 && temp == 4)
358 hit -= 2;
359 if (windspeed == 6 && temp <= 3)
360 hit--;
361 if (hit >= 0) {
362 if (load != L_GRAPE)
363 hit = hit > 10 ? 10 : hit;
364 table(shootat, load, hit, closest, sp, die());
41506c08
CL
365 }
366 }
367 }
368}
369
370next()
371{
b3a57661 372 if (++turn % 55 == 0)
6c17b19a
EW
373 if (alive)
374 alive = 0;
41506c08 375 else
6c17b19a
EW
376 people = 0;
377 if (people <= 0 || windspeed == 7) {
9329b33f
EW
378 register struct ship *s;
379 struct ship *bestship;
380 float net, best = 0.0;
381 foreachship(s) {
382 if (*s->file->captain)
383 continue;
384 net = (float)s->file->points / s->specs->pts;
385 if (net > best) {
386 best = net;
387 bestship = s;
388 }
389 }
390 if (best > 0.0) {
391 char *p = getenv("WOTD");
392 if (p == 0)
393 p = "Driver";
1f7f69b9
EW
394 if (islower(*p))
395 *p = toupper(*p);
7f1cb789 396 (void) strncpy(bestship->file->captain, p,
aaa1c87f
EW
397 sizeof bestship->file->captain);
398 bestship->file->captain
399 [sizeof bestship->file->captain - 1] = 0;
9329b33f
EW
400 log(bestship);
401 }
a3a7a20d 402 return -1;
41506c08 403 }
b3a57661 404 Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
a3a7a20d
EW
405 if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) {
406 switch (die()) {
407 case 1:
408 winddir = 1;
409 break;
410 case 2:
411 break;
412 case 3:
413 winddir++;
414 break;
415 case 4:
416 winddir--;
417 break;
418 case 5:
419 winddir += 2;
420 break;
421 case 6:
422 winddir -= 2;
423 break;
424 }
425 if (winddir > 8)
426 winddir -= 8;
427 if (winddir < 1)
428 winddir += 8;
429 if (windspeed)
b3a57661
EW
430 switch (die()) {
431 case 1:
b3a57661 432 case 2:
a3a7a20d 433 windspeed--;
b3a57661
EW
434 break;
435 case 5:
b3a57661 436 case 6:
a3a7a20d 437 windspeed++;
b3a57661 438 break;
41506c08 439 }
a3a7a20d
EW
440 else
441 windspeed++;
442 Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
41506c08 443 }
a3a7a20d 444 return 0;
41506c08 445}