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