xref: /csrg-svn/games/sail/dr_1.c (revision 60846)
118696Sedward /*
2*60846Sbostic  * Copyright (c) 1983, 1993
3*60846Sbostic  *	The Regents of the University of California.  All rights reserved.
433695Sbostic  *
542601Sbostic  * %sccs.include.redist.c%
618696Sedward  */
718696Sedward 
811589Sleres #ifndef lint
9*60846Sbostic static char sccsid[] = "@(#)dr_1.c	8.1 (Berkeley) 05/31/93";
1033695Sbostic #endif /* not lint */
1112619Sroot 
1214007Sedward #include "driver.h"
1311589Sleres 
unfoul()1411589Sleres unfoul()
1511589Sleres {
1614007Sedward 	register struct ship *sp;
1714007Sedward 	struct ship *to;
1814007Sedward 	register int nat;
1915721Sedward 	register i;
2011589Sleres 
2114007Sedward 	foreachship(sp) {
2214007Sedward 		if (sp->file->captain[0])
2314007Sedward 			continue;
2414007Sedward 		nat = capship(sp)->nationality;
2515721Sedward 		foreachship(to) {
2618251Sedward 			if (nat != capship(to)->nationality &&
2718251Sedward 			    !toughmelee(sp, to, 0, 0))
2814007Sedward 				continue;
2915721Sedward 			for (i = fouled2(sp, to); --i >= 0;)
3015721Sedward 				if (die() <= 2)
3115721Sedward 					cleanfoul(sp, to, 0);
3211589Sleres 		}
3311589Sleres 	}
3411589Sleres }
3511589Sleres 
boardcomp()3611589Sleres boardcomp()
3711589Sleres {
3812619Sroot 	int crew[3];
3914007Sedward 	register struct ship *sp, *sq;
4011589Sleres 
4114007Sedward 	foreachship(sp) {
4214007Sedward 		if (*sp->file->captain)
4314007Sedward 			continue;
4414007Sedward 		if (sp->file->dir == 0)
4514007Sedward 			continue;
4614007Sedward 		if (sp->file->struck || sp->file->captured != 0)
4714007Sedward 			continue;
4815721Sedward 		if (!snagged(sp))
4915721Sedward 			continue;
5014007Sedward 		crew[0] = sp->specs->crew1 != 0;
5114007Sedward 		crew[1] = sp->specs->crew2 != 0;
5214007Sedward 		crew[2] = sp->specs->crew3 != 0;
5314007Sedward 		foreachship(sq) {
5414007Sedward 			if (!Xsnagged2(sp, sq))
5514007Sedward 				continue;
5614007Sedward 			if (meleeing(sp, sq))
5714007Sedward 				continue;
5814007Sedward 			if (!sq->file->dir
5914007Sedward 				|| sp->nationality == capship(sq)->nationality)
6014007Sedward 				continue;
6114007Sedward 			switch (sp->specs->class - sq->specs->class) {
6214007Sedward 			case -3: case -4: case -5:
6314007Sedward 				if (crew[0]) {
6414007Sedward 					/* OBP */
6514007Sedward 					sendbp(sp, sq, crew[0]*100, 0);
6614007Sedward 					crew[0] = 0;
6714007Sedward 				} else if (crew[1]){
6814007Sedward 					/* OBP */
6914007Sedward 					sendbp(sp, sq, crew[1]*10, 0);
7014007Sedward 					crew[1] = 0;
7111589Sleres 				}
7214007Sedward 				break;
7314007Sedward 			case -2:
7414007Sedward 				if (crew[0] || crew[1]) {
7514007Sedward 					/* OBP */
7614007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
7714007Sedward 						0);
7814007Sedward 					crew[0] = crew[1] = 0;
7914007Sedward 				}
8014007Sedward 				break;
8114007Sedward 			case -1: case 0: case 1:
8214007Sedward 				if (crew[0]) {
8314007Sedward 					/* OBP */
8414007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
8514007Sedward 						0);
8614007Sedward 					crew[0] = crew[1] = 0;
8714007Sedward 				}
8814007Sedward 				break;
8914007Sedward 			case 2: case 3: case 4: case 5:
9014007Sedward 				/* OBP */
9114007Sedward 				sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
9214007Sedward 					0);
9314007Sedward 				crew[0] = crew[1] = crew[2] = 0;
9414007Sedward 				break;
9511589Sleres 			}
9614007Sedward 		}
9711589Sleres 	}
9811589Sleres }
9911589Sleres 
10011589Sleres fightitout(from, to, key)
10114007Sedward struct ship *from, *to;
10214007Sedward int key;
10311589Sleres {
10414007Sedward 	struct ship *fromcap, *tocap;
10514007Sedward 	int crewfrom[3], crewto[3], menfrom, mento;
10611589Sleres 	int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
10714007Sedward 	int topoints;
10814007Sedward 	int index, totalfrom = 0, totalto = 0;
10914007Sedward 	int count;
11011589Sleres 	char message[60];
11111589Sleres 
11214007Sedward 	menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
11314007Sedward 	mento = mensent(to, from, crewto, &tocap, &pcto, 0);
11414007Sedward 	if (fromcap == 0)
11511589Sleres 		fromcap = from;
11614007Sedward 	if (tocap == 0)
11711589Sleres 		tocap = to;
11815721Sedward 	if (key) {
11915330Sedward 		if (!menfrom) {		 /* if crew surprised */
12015330Sedward 			if (fromcap == from)
12115330Sedward 				menfrom = from->specs->crew1
12215330Sedward 					+ from->specs->crew2
12315330Sedward 					+ from->specs->crew3;
12415330Sedward 			else
12515330Sedward 				menfrom = from->file->pcrew;
12615330Sedward 		} else {
12715330Sedward 			menfrom *= 2;	/* DBP's fight at an advantage */
12815330Sedward 		}
12915330Sedward 	}
13014007Sedward 	fromstrength = menfrom * fromcap->specs->qual;
13114007Sedward 	strengthto = mento * tocap->specs->qual;
13214007Sedward 	for (count = 0;
13314007Sedward 	     (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
13414007Sedward 	      || fromstrength == -1) && count < 4;
13514007Sedward 	     count++) {
13611589Sleres 		index = fromstrength/10;
13711589Sleres 		if (index > 8)
13811589Sleres 			index = 8;
13911589Sleres 		toinjured = MT[index][2 - die() / 3];
14011589Sleres 		totalto += toinjured;
14111589Sleres 		index = strengthto/10;
14211589Sleres 		if (index > 8)
14311589Sleres 			index = 8;
14411589Sleres 		frominjured = MT[index][2 - die() / 3];
14511589Sleres 		totalfrom += frominjured;
14611589Sleres 		menfrom -= frominjured;
14711589Sleres 		mento -= toinjured;
14814007Sedward 		fromstrength = menfrom * fromcap->specs->qual;
14914007Sedward 		strengthto = mento * tocap->specs->qual;
15011589Sleres 	}
15114007Sedward 	if (fromstrength >= strengthto * 3 || count == 4) {
15211589Sleres 		unboard(to, from, 0);
15311589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
15411589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
15514007Sedward 		makesignal(from, "boarders from %s repelled", to);
15614007Sedward 		(void) sprintf(message, "killed in melee: %d.  %s: %d",
15714007Sedward 			totalto, from->shipname, totalfrom);
15814007Sedward 		Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
15911589Sleres 		if (key)
16014007Sedward 			return 1;
16114007Sedward 	} else if (strengthto >= fromstrength * 3) {
16211589Sleres 		unboard(from, to, 0);
16311589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
16411589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
16514007Sedward 		if (key) {
16611589Sleres 			if (fromcap != from)
16714007Sedward 				Write(W_POINTS, fromcap, 0,
16814007Sedward 					fromcap->file->points -
16914007Sedward 						from->file->struck
17014007Sedward 						? from->specs->pts
17114007Sedward 						: 2 * from->specs->pts,
17214007Sedward 					0, 0, 0);
17311589Sleres 
17411589Sleres /* ptr1 points to the shipspec for the ship that was just unboarded.
17511589Sleres    I guess that what is going on here is that the pointer is multiplied
17611589Sleres    or something. */
17711589Sleres 
17815721Sedward 			Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
17914007Sedward 			topoints = 2 * from->specs->pts + to->file->points;
18014007Sedward 			if (from->file->struck)
18114007Sedward 				topoints -= from->specs->pts;
18214007Sedward 			Write(W_POINTS, to, 0, topoints, 0, 0, 0);
18311589Sleres 			mento = crewto[0] ? crewto[0] : crewto[1];
18414007Sedward 			if (mento) {
18511589Sleres 				subtract(to, mento, crewto, tocap, pcto);
18614007Sedward 				subtract(from, - mento, crewfrom, to, 0);
18711589Sleres 			}
18814007Sedward 			(void) sprintf(message, "captured by the %s!",
18914007Sedward 				to->shipname);
19014007Sedward 			Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
19114007Sedward 			(void) sprintf(message, "killed in melee: %d.  %s: %d",
19214007Sedward 				totalto, from->shipname, totalfrom);
19314007Sedward 			Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
19411589Sleres 			mento = 0;
19514007Sedward 			return 0;
19611589Sleres 		}
19711589Sleres 	}
19814007Sedward 	return 0;
19914007Sedward }
20011589Sleres 
resolve()20111589Sleres resolve()
20211589Sleres {
20314007Sedward 	int thwart;
20414007Sedward 	register struct ship *sp, *sq;
20511589Sleres 
20614007Sedward 	foreachship(sp) {
20714007Sedward 		if (sp->file->dir == 0)
20814007Sedward 			continue;
20915330Sedward 		for (sq = sp + 1; sq < ls; sq++)
21014007Sedward 			if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
21114007Sedward 				(void) fightitout(sp, sq, 0);
21215395Sedward 		thwart = 2;
21314007Sedward 		foreachship(sq) {
21414007Sedward 			if (sq->file->dir && meleeing(sq, sp))
21514007Sedward 				thwart = fightitout(sp, sq, 1);
21614007Sedward 			if (!thwart)
21714007Sedward 				break;
21811589Sleres 		}
21915395Sedward 		if (!thwart) {
22015395Sedward 			foreachship(sq) {
22115395Sedward 				if (sq->file->dir && meleeing(sq, sp))
22215395Sedward 					unboard(sq, sp, 0);
22315395Sedward 				unboard(sp, sq, 0);
22415395Sedward 			}
22514007Sedward 			unboard(sp, sp, 1);
22615395Sedward 		} else if (thwart == 2)
22715395Sedward 			unboard(sp, sp, 1);
22811589Sleres 	}
22911589Sleres }
23011589Sleres 
compcombat()23111589Sleres compcombat()
23211589Sleres {
23314007Sedward 	register n;
23414007Sedward 	register struct ship *sp;
23514007Sedward 	struct ship *closest;
23611589Sleres 	int crew[3], men = 0, target, temp;
23715311Sedward 	int r, guns, ready, load, car;
23815311Sedward 	int index, rakehim, sternrake;
23914007Sedward 	int shootat, hit;
24011589Sleres 
24114007Sedward 	foreachship(sp) {
24214007Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
24314007Sedward 			continue;
24414007Sedward 		crew[0] = sp->specs->crew1;
24514007Sedward 		crew[1] = sp->specs->crew2;
24614007Sedward 		crew[2] = sp->specs->crew3;
24714007Sedward 		for (n = 0; n < 3; n++) {
24814007Sedward 			if (sp->file->OBP[n].turnsent)
24914007Sedward 				men += sp->file->OBP[n].mensent;
25014007Sedward 		}
25114007Sedward 		for (n = 0; n < 3; n++) {
25214007Sedward 			if (sp->file->DBP[n].turnsent)
25314007Sedward 				men += sp->file->DBP[n].mensent;
25414007Sedward 		}
25514007Sedward 		if (men){
25614007Sedward 			crew[0] = men/100 ? 0 : crew[0] != 0;
25714007Sedward 			crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
25814007Sedward 			crew[2] = men%10 ? 0 : crew[2] != 0;
25914007Sedward 		}
26014007Sedward 		for (r = 0; r < 2; r++) {
26114007Sedward 			if (!crew[2])
26214007Sedward 				continue;
26314007Sedward 			if (sp->file->struck)
26414007Sedward 				continue;
26514007Sedward 			if (r) {
26614007Sedward 				ready = sp->file->readyR;
26714007Sedward 				guns = sp->specs->gunR;
26814007Sedward 				car = sp->specs->carR;
26914007Sedward 			} else {
27014007Sedward 				ready = sp->file->readyL;
27114007Sedward 				guns = sp->specs->gunL;
27214007Sedward 				car = sp->specs->carL;
27311589Sleres 			}
27414007Sedward 			if (!guns && !car)
27514007Sedward 				continue;
27614007Sedward 			if ((ready & R_LOADED) == 0)
27714007Sedward 				continue;
27814007Sedward 			closest = closestenemy(sp, r ? 'r' : 'l', 0);
27914007Sedward 			if (closest == 0)
28014007Sedward 				continue;
28114007Sedward 			if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
28214007Sedward 				continue;
28314007Sedward 			if (closest->file->struck)
28414007Sedward 				continue;
28514007Sedward 			target = range(sp, closest);
28614007Sedward 			if (target > 10)
28714007Sedward 				continue;
28814007Sedward 			if (!guns && target >= 3)
28914007Sedward 				continue;
29014007Sedward 			load = L_ROUND;
29114007Sedward 			if (target == 1 && sp->file->loadwith == L_GRAPE)
29214007Sedward 				load = L_GRAPE;
29314007Sedward 			if (target <= 3 && closest->file->FS)
29414007Sedward 				load = L_CHAIN;
29514007Sedward 			if (target == 1 && load != L_GRAPE)
29614007Sedward 				load = L_DOUBLE;
29714007Sedward 			if (load > L_CHAIN && target < 6)
29814007Sedward 				shootat = HULL;
29914007Sedward 			else
30014007Sedward 				shootat = RIGGING;
30114007Sedward 			rakehim = gunsbear(sp, closest)
30214007Sedward 				&& !gunsbear(closest, sp);
30314007Sedward 			temp = portside(closest, sp, 1)
30414007Sedward 				- closest->file->dir + 1;
30514007Sedward 			if (temp < 1)
30614007Sedward 				temp += 8;
30714007Sedward 			if (temp > 8)
30814007Sedward 				temp -= 8;
30914007Sedward 			sternrake = temp > 4 && temp < 6;
31014007Sedward 			index = guns;
31114007Sedward 			if (target < 3)
31214007Sedward 				index += car;
31314007Sedward 			index = (index - 1) / 3;
31414007Sedward 			index = index > 8 ? 8 : index;
31514007Sedward 			if (!rakehim)
31614007Sedward 				hit = HDT[index][target-1];
31714007Sedward 			else
31814007Sedward 				hit = HDTrake[index][target-1];
31914007Sedward 			if (rakehim && sternrake)
32014007Sedward 				hit++;
32114007Sedward 			hit += QUAL[index][capship(sp)->specs->qual - 1];
32214007Sedward 			for (n = 0; n < 3 && sp->file->captured == 0; n++)
32314007Sedward 				if (!crew[n])
32414007Sedward 					if (index <= 5)
32514007Sedward 						hit--;
32614007Sedward 					else
32714007Sedward 						hit -= 2;
32815311Sedward 			if (ready & R_INITIAL) {
32915311Sedward 				if (!r)
33015311Sedward 					sp->file->readyL &= ~R_INITIAL;
33115311Sedward 				else
33215311Sedward 					sp->file->readyR &= ~R_INITIAL;
33314007Sedward 				if (index <= 3)
33414007Sedward 					hit++;
33511589Sleres 				else
33614007Sedward 					hit += 2;
33715311Sedward 			}
33814007Sedward 			if (sp->file->captured != 0)
33914007Sedward 				if (index <= 1)
34014007Sedward 					hit--;
34114007Sedward 				else
34214007Sedward 					hit -= 2;
34314007Sedward 			hit += AMMO[index][load - 1];
34414007Sedward 			temp = sp->specs->class;
34514007Sedward 			if ((temp >= 5 || temp == 1) && windspeed == 5)
34614007Sedward 				hit--;
34714007Sedward 			if (windspeed == 6 && temp == 4)
34814007Sedward 				hit -= 2;
34914007Sedward 			if (windspeed == 6 && temp <= 3)
35014007Sedward 				hit--;
35114007Sedward 			if (hit >= 0) {
35214007Sedward 				if (load != L_GRAPE)
35314007Sedward 					hit = hit > 10 ? 10 : hit;
35414007Sedward 				table(shootat, load, hit, closest, sp, die());
35511589Sleres 			}
35611589Sleres 		}
35711589Sleres 	}
35811589Sleres }
35911589Sleres 
next()36011589Sleres next()
36111589Sleres {
36214007Sedward 	if (++turn % 55 == 0)
36315202Sedward 		if (alive)
36415202Sedward 			alive = 0;
36514007Sedward 		else
36615202Sedward 			people = 0;
36715202Sedward 	if (people <= 0 || windspeed == 7) {
36816082Sedward 		register struct ship *s;
36916082Sedward 		struct ship *bestship;
37016082Sedward 		float net, best = 0.0;
37116082Sedward 		foreachship(s) {
37216082Sedward 			if (*s->file->captain)
37316082Sedward 				continue;
37416082Sedward 			net = (float)s->file->points / s->specs->pts;
37516082Sedward 			if (net > best) {
37616082Sedward 				best = net;
37716082Sedward 				bestship = s;
37816082Sedward 			}
37916082Sedward 		}
38016082Sedward 		if (best > 0.0) {
38116082Sedward 			char *p = getenv("WOTD");
38216082Sedward 			if (p == 0)
38316082Sedward 				p = "Driver";
38416102Sedward 			if (islower(*p))
38516102Sedward 				*p = toupper(*p);
38618767Sedward 			(void) strncpy(bestship->file->captain, p,
38716129Sedward 				sizeof bestship->file->captain);
38816129Sedward 			bestship->file->captain
38916129Sedward 				[sizeof bestship->file->captain - 1] = 0;
39016082Sedward 			log(bestship);
39116082Sedward 		}
39218772Sedward 		return -1;
39311589Sleres 	}
39414007Sedward 	Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
39518772Sedward 	if (turn % 7 == 0 && (die() >= cc->windchange || !windspeed)) {
39618772Sedward 		switch (die()) {
39718772Sedward 		case 1:
39818772Sedward 			winddir = 1;
39918772Sedward 			break;
40018772Sedward 		case 2:
40118772Sedward 			break;
40218772Sedward 		case 3:
40318772Sedward 			winddir++;
40418772Sedward 			break;
40518772Sedward 		case 4:
40618772Sedward 			winddir--;
40718772Sedward 			break;
40818772Sedward 		case 5:
40918772Sedward 			winddir += 2;
41018772Sedward 			break;
41118772Sedward 		case 6:
41218772Sedward 			winddir -= 2;
41318772Sedward 			break;
41418772Sedward 		}
41518772Sedward 		if (winddir > 8)
41618772Sedward 			winddir -= 8;
41718772Sedward 		if (winddir < 1)
41818772Sedward 			winddir += 8;
41918772Sedward 		if (windspeed)
42014007Sedward 			switch (die()) {
42114007Sedward 			case 1:
42214007Sedward 			case 2:
42318772Sedward 				windspeed--;
42414007Sedward 				break;
42514007Sedward 			case 5:
42614007Sedward 			case 6:
42718772Sedward 				windspeed++;
42814007Sedward 				break;
42914007Sedward 			}
43018772Sedward 		else
43118772Sedward 			windspeed++;
43218772Sedward 		Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
43311589Sleres 	}
43418772Sedward 	return 0;
43511589Sleres }
436