xref: /csrg-svn/games/sail/dr_1.c (revision 16082)
111589Sleres #ifndef lint
2*16082Sedward static	char *sccsid = "@(#)dr_1.c	2.8 84/02/23";
311589Sleres #endif
412619Sroot 
514007Sedward #include "driver.h"
611589Sleres 
715202Sedward main(argc, argv)
815202Sedward int argc;
915202Sedward char **argv;
1015202Sedward {
1115202Sedward 	register int n;
1215202Sedward 	register struct ship *sp;
1315202Sedward 	int nat[NNATION];
1415202Sedward 
1515202Sedward 	if (argc != 2)
1615202Sedward 		exit(1);
1715202Sedward 	(void) signal(SIGINT, SIG_IGN);
1815202Sedward 	(void) signal(SIGQUIT, SIG_IGN);
1915369Sedward 	(void) signal(SIGTSTP, SIG_IGN);
2015202Sedward 	(void) srand(getpid());
2115202Sedward 	/* ;;; add code here to check the game number. */
2215202Sedward 	game = atoi(argv[1]);
2315202Sedward 	cc = &scene[game];
2415899Sedward 	ls = SHIP(cc->vessels);
2515202Sedward 	if (sync_open() < 0) {
2615202Sedward 		perror("driver: syncfile");
2715202Sedward 		exit(1);
2815202Sedward 	}
2915202Sedward 	for (n = 0; n < NNATION; n++)
3015202Sedward 		nat[n] = 0;
3115202Sedward 	foreachship(sp) {
3215202Sedward 		sp->file = (struct File *) calloc(1, sizeof (struct File));
3315202Sedward 		if (sp == NULL) {
3415202Sedward 			(void) printf("driver: OUT OF MEMORY\n");
35*16082Sedward 			exit(1);
3615202Sedward 		}
3715721Sedward 		sp->file->index = sp - SHIP(0);
3815202Sedward 		sp->file->loadL = L_ROUND;
3915202Sedward 		sp->file->loadR = L_ROUND;
4015202Sedward 		sp->file->readyR = R_LOADED|R_INITIAL;
4115202Sedward 		sp->file->readyL = R_LOADED|R_INITIAL;
4215202Sedward 		sp->file->stern = nat[sp->nationality]++;
4315202Sedward 		sp->file->dir = sp->shipdir;
4415202Sedward 		sp->file->row = sp->shiprow;
4515202Sedward 		sp->file->col = sp->shipcol;
4615202Sedward 	}
4715202Sedward 	windspeed = cc->windspeed;
4815202Sedward 	winddir = cc->winddir;
4915202Sedward 	for (;;) {
5015353Sedward 		sleep(7);
51*16082Sedward 		if (Sync() < 0) {
52*16082Sedward 			sync_close(1);
53*16082Sedward 			exit(1);
54*16082Sedward 		}
5515202Sedward 		next();
5615202Sedward 		unfoul();
5715202Sedward 		checkup();
5815202Sedward 		prizecheck();
5915202Sedward 		moveall();
6015202Sedward 		thinkofgrapples();
6115202Sedward 		boardcomp();
6215202Sedward 		compcombat();
6315202Sedward 		resolve();
6415202Sedward 		reload();
6515202Sedward 		checksails();
66*16082Sedward 		if (Sync() < 0) {
67*16082Sedward 			sync_close(1);
68*16082Sedward 			exit(1);
69*16082Sedward 		}
7015202Sedward 	}
7115202Sedward }
7215202Sedward 
7311589Sleres unfoul()
7411589Sleres {
7514007Sedward 	register struct ship *sp;
7614007Sedward 	struct ship *to;
7714007Sedward 	register int nat;
7815721Sedward 	register i;
7911589Sleres 
8014007Sedward 	foreachship(sp) {
8114007Sedward 		if (sp->file->captain[0])
8214007Sedward 			continue;
8314007Sedward 		nat = capship(sp)->nationality;
8415721Sedward 		foreachship(to) {
8515721Sedward 			if (nat != capship(to)->nationality
8615721Sedward 			    && !toughmelee(sp, to, 0, 0))
8714007Sedward 				continue;
8815721Sedward 			for (i = fouled2(sp, to); --i >= 0;)
8915721Sedward 				if (die() <= 2)
9015721Sedward 					cleanfoul(sp, to, 0);
9111589Sleres 		}
9211589Sleres 	}
9311589Sleres }
9411589Sleres 
9511589Sleres boardcomp()
9611589Sleres {
9712619Sroot 	int crew[3];
9814007Sedward 	register struct ship *sp, *sq;
9911589Sleres 
10014007Sedward 	foreachship(sp) {
10114007Sedward 		if (*sp->file->captain)
10214007Sedward 			continue;
10314007Sedward 		if (sp->file->dir == 0)
10414007Sedward 			continue;
10514007Sedward 		if (sp->file->struck || sp->file->captured != 0)
10614007Sedward 			continue;
10715721Sedward 		if (!snagged(sp))
10815721Sedward 			continue;
10914007Sedward 		crew[0] = sp->specs->crew1 != 0;
11014007Sedward 		crew[1] = sp->specs->crew2 != 0;
11114007Sedward 		crew[2] = sp->specs->crew3 != 0;
11214007Sedward 		foreachship(sq) {
11314007Sedward 			if (!Xsnagged2(sp, sq))
11414007Sedward 				continue;
11514007Sedward 			if (meleeing(sp, sq))
11614007Sedward 				continue;
11714007Sedward 			if (!sq->file->dir
11814007Sedward 				|| sp->nationality == capship(sq)->nationality)
11914007Sedward 				continue;
12014007Sedward 			switch (sp->specs->class - sq->specs->class) {
12114007Sedward 			case -3: case -4: case -5:
12214007Sedward 				if (crew[0]) {
12314007Sedward 					/* OBP */
12414007Sedward 					sendbp(sp, sq, crew[0]*100, 0);
12514007Sedward 					crew[0] = 0;
12614007Sedward 				} else if (crew[1]){
12714007Sedward 					/* OBP */
12814007Sedward 					sendbp(sp, sq, crew[1]*10, 0);
12914007Sedward 					crew[1] = 0;
13011589Sleres 				}
13114007Sedward 				break;
13214007Sedward 			case -2:
13314007Sedward 				if (crew[0] || crew[1]) {
13414007Sedward 					/* OBP */
13514007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
13614007Sedward 						0);
13714007Sedward 					crew[0] = crew[1] = 0;
13814007Sedward 				}
13914007Sedward 				break;
14014007Sedward 			case -1: case 0: case 1:
14114007Sedward 				if (crew[0]) {
14214007Sedward 					/* OBP */
14314007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
14414007Sedward 						0);
14514007Sedward 					crew[0] = crew[1] = 0;
14614007Sedward 				}
14714007Sedward 				break;
14814007Sedward 			case 2: case 3: case 4: case 5:
14914007Sedward 				/* OBP */
15014007Sedward 				sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
15114007Sedward 					0);
15214007Sedward 				crew[0] = crew[1] = crew[2] = 0;
15314007Sedward 				break;
15411589Sleres 			}
15514007Sedward 		}
15611589Sleres 	}
15711589Sleres }
15811589Sleres 
15911589Sleres fightitout(from, to, key)
16014007Sedward struct ship *from, *to;
16114007Sedward int key;
16211589Sleres {
16314007Sedward 	struct ship *fromcap, *tocap;
16414007Sedward 	int crewfrom[3], crewto[3], menfrom, mento;
16511589Sleres 	int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
16614007Sedward 	int topoints;
16714007Sedward 	int index, totalfrom = 0, totalto = 0;
16814007Sedward 	int count;
16911589Sleres 	char message[60];
17011589Sleres 
17114007Sedward 	menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
17214007Sedward 	mento = mensent(to, from, crewto, &tocap, &pcto, 0);
17314007Sedward 	if (fromcap == 0)
17411589Sleres 		fromcap = from;
17514007Sedward 	if (tocap == 0)
17611589Sleres 		tocap = to;
17715721Sedward 	if (key) {
17815330Sedward 		if (!menfrom) {		 /* if crew surprised */
17915330Sedward 			if (fromcap == from)
18015330Sedward 				menfrom = from->specs->crew1
18115330Sedward 					+ from->specs->crew2
18215330Sedward 					+ from->specs->crew3;
18315330Sedward 			else
18415330Sedward 				menfrom = from->file->pcrew;
18515330Sedward 		} else {
18615330Sedward 			menfrom *= 2;	/* DBP's fight at an advantage */
18715330Sedward 		}
18815330Sedward 	}
18914007Sedward 	fromstrength = menfrom * fromcap->specs->qual;
19014007Sedward 	strengthto = mento * tocap->specs->qual;
19114007Sedward 	for (count = 0;
19214007Sedward 	     (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
19314007Sedward 	      || fromstrength == -1) && count < 4;
19414007Sedward 	     count++) {
19511589Sleres 		index = fromstrength/10;
19611589Sleres 		if (index > 8)
19711589Sleres 			index = 8;
19811589Sleres 		toinjured = MT[index][2 - die() / 3];
19911589Sleres 		totalto += toinjured;
20011589Sleres 		index = strengthto/10;
20111589Sleres 		if (index > 8)
20211589Sleres 			index = 8;
20311589Sleres 		frominjured = MT[index][2 - die() / 3];
20411589Sleres 		totalfrom += frominjured;
20511589Sleres 		menfrom -= frominjured;
20611589Sleres 		mento -= toinjured;
20714007Sedward 		fromstrength = menfrom * fromcap->specs->qual;
20814007Sedward 		strengthto = mento * tocap->specs->qual;
20911589Sleres 	}
21014007Sedward 	if (fromstrength >= strengthto * 3 || count == 4) {
21111589Sleres 		unboard(to, from, 0);
21211589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
21311589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
21414007Sedward 		makesignal(from, "boarders from %s repelled", to);
21514007Sedward 		(void) sprintf(message, "killed in melee: %d.  %s: %d",
21614007Sedward 			totalto, from->shipname, totalfrom);
21714007Sedward 		Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
21811589Sleres 		if (key)
21914007Sedward 			return 1;
22014007Sedward 	} else if (strengthto >= fromstrength * 3) {
22111589Sleres 		unboard(from, to, 0);
22211589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
22311589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
22414007Sedward 		if (key) {
22511589Sleres 			if (fromcap != from)
22614007Sedward 				Write(W_POINTS, fromcap, 0,
22714007Sedward 					fromcap->file->points -
22814007Sedward 						from->file->struck
22914007Sedward 						? from->specs->pts
23014007Sedward 						: 2 * from->specs->pts,
23114007Sedward 					0, 0, 0);
23211589Sleres 
23311589Sleres /* ptr1 points to the shipspec for the ship that was just unboarded.
23411589Sleres    I guess that what is going on here is that the pointer is multiplied
23511589Sleres    or something. */
23611589Sleres 
23715721Sedward 			Write(W_CAPTURED, from, 0, to->file->index, 0, 0, 0);
23814007Sedward 			topoints = 2 * from->specs->pts + to->file->points;
23914007Sedward 			if (from->file->struck)
24014007Sedward 				topoints -= from->specs->pts;
24114007Sedward 			Write(W_POINTS, to, 0, topoints, 0, 0, 0);
24211589Sleres 			mento = crewto[0] ? crewto[0] : crewto[1];
24314007Sedward 			if (mento) {
24411589Sleres 				subtract(to, mento, crewto, tocap, pcto);
24514007Sedward 				subtract(from, - mento, crewfrom, to, 0);
24611589Sleres 			}
24714007Sedward 			(void) sprintf(message, "captured by the %s!",
24814007Sedward 				to->shipname);
24914007Sedward 			Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
25014007Sedward 			(void) sprintf(message, "killed in melee: %d.  %s: %d",
25114007Sedward 				totalto, from->shipname, totalfrom);
25214007Sedward 			Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
25311589Sleres 			mento = 0;
25414007Sedward 			return 0;
25511589Sleres 		}
25611589Sleres 	}
25714007Sedward 	return 0;
25814007Sedward }
25911589Sleres 
26011589Sleres resolve()
26111589Sleres {
26214007Sedward 	int thwart;
26314007Sedward 	register struct ship *sp, *sq;
26411589Sleres 
26514007Sedward 	foreachship(sp) {
26614007Sedward 		if (sp->file->dir == 0)
26714007Sedward 			continue;
26815330Sedward 		for (sq = sp + 1; sq < ls; sq++)
26914007Sedward 			if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
27014007Sedward 				(void) fightitout(sp, sq, 0);
27115395Sedward 		thwart = 2;
27214007Sedward 		foreachship(sq) {
27314007Sedward 			if (sq->file->dir && meleeing(sq, sp))
27414007Sedward 				thwart = fightitout(sp, sq, 1);
27514007Sedward 			if (!thwart)
27614007Sedward 				break;
27711589Sleres 		}
27815395Sedward 		if (!thwart) {
27915395Sedward 			foreachship(sq) {
28015395Sedward 				if (sq->file->dir && meleeing(sq, sp))
28115395Sedward 					unboard(sq, sp, 0);
28215395Sedward 				unboard(sp, sq, 0);
28315395Sedward 			}
28414007Sedward 			unboard(sp, sp, 1);
28515395Sedward 		} else if (thwart == 2)
28615395Sedward 			unboard(sp, sp, 1);
28711589Sleres 	}
28811589Sleres }
28911589Sleres 
29011589Sleres compcombat()
29111589Sleres {
29214007Sedward 	register n;
29314007Sedward 	register struct ship *sp;
29414007Sedward 	struct ship *closest;
29511589Sleres 	int crew[3], men = 0, target, temp;
29615311Sedward 	int r, guns, ready, load, car;
29715311Sedward 	int index, rakehim, sternrake;
29814007Sedward 	int shootat, hit;
29911589Sleres 
30014007Sedward 	foreachship(sp) {
30114007Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
30214007Sedward 			continue;
30314007Sedward 		crew[0] = sp->specs->crew1;
30414007Sedward 		crew[1] = sp->specs->crew2;
30514007Sedward 		crew[2] = sp->specs->crew3;
30614007Sedward 		for (n = 0; n < 3; n++) {
30714007Sedward 			if (sp->file->OBP[n].turnsent)
30814007Sedward 				men += sp->file->OBP[n].mensent;
30914007Sedward 		}
31014007Sedward 		for (n = 0; n < 3; n++) {
31114007Sedward 			if (sp->file->DBP[n].turnsent)
31214007Sedward 				men += sp->file->DBP[n].mensent;
31314007Sedward 		}
31414007Sedward 		if (men){
31514007Sedward 			crew[0] = men/100 ? 0 : crew[0] != 0;
31614007Sedward 			crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
31714007Sedward 			crew[2] = men%10 ? 0 : crew[2] != 0;
31814007Sedward 		}
31914007Sedward 		for (r = 0; r < 2; r++) {
32014007Sedward 			if (!crew[2])
32114007Sedward 				continue;
32214007Sedward 			if (sp->file->struck)
32314007Sedward 				continue;
32414007Sedward 			if (r) {
32514007Sedward 				ready = sp->file->readyR;
32614007Sedward 				guns = sp->specs->gunR;
32714007Sedward 				car = sp->specs->carR;
32814007Sedward 			} else {
32914007Sedward 				ready = sp->file->readyL;
33014007Sedward 				guns = sp->specs->gunL;
33114007Sedward 				car = sp->specs->carL;
33211589Sleres 			}
33314007Sedward 			if (!guns && !car)
33414007Sedward 				continue;
33514007Sedward 			if ((ready & R_LOADED) == 0)
33614007Sedward 				continue;
33714007Sedward 			closest = closestenemy(sp, r ? 'r' : 'l', 0);
33814007Sedward 			if (closest == 0)
33914007Sedward 				continue;
34014007Sedward 			if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
34114007Sedward 				continue;
34214007Sedward 			if (closest->file->struck)
34314007Sedward 				continue;
34414007Sedward 			target = range(sp, closest);
34514007Sedward 			if (target > 10)
34614007Sedward 				continue;
34714007Sedward 			if (!guns && target >= 3)
34814007Sedward 				continue;
34914007Sedward 			load = L_ROUND;
35014007Sedward 			if (target == 1 && sp->file->loadwith == L_GRAPE)
35114007Sedward 				load = L_GRAPE;
35214007Sedward 			if (target <= 3 && closest->file->FS)
35314007Sedward 				load = L_CHAIN;
35414007Sedward 			if (target == 1 && load != L_GRAPE)
35514007Sedward 				load = L_DOUBLE;
35614007Sedward 			if (load > L_CHAIN && target < 6)
35714007Sedward 				shootat = HULL;
35814007Sedward 			else
35914007Sedward 				shootat = RIGGING;
36014007Sedward 			rakehim = gunsbear(sp, closest)
36114007Sedward 				&& !gunsbear(closest, sp);
36214007Sedward 			temp = portside(closest, sp, 1)
36314007Sedward 				- closest->file->dir + 1;
36414007Sedward 			if (temp < 1)
36514007Sedward 				temp += 8;
36614007Sedward 			if (temp > 8)
36714007Sedward 				temp -= 8;
36814007Sedward 			sternrake = temp > 4 && temp < 6;
36914007Sedward 			index = guns;
37014007Sedward 			if (target < 3)
37114007Sedward 				index += car;
37214007Sedward 			index = (index - 1) / 3;
37314007Sedward 			index = index > 8 ? 8 : index;
37414007Sedward 			if (!rakehim)
37514007Sedward 				hit = HDT[index][target-1];
37614007Sedward 			else
37714007Sedward 				hit = HDTrake[index][target-1];
37814007Sedward 			if (rakehim && sternrake)
37914007Sedward 				hit++;
38014007Sedward 			hit += QUAL[index][capship(sp)->specs->qual - 1];
38114007Sedward 			for (n = 0; n < 3 && sp->file->captured == 0; n++)
38214007Sedward 				if (!crew[n])
38314007Sedward 					if (index <= 5)
38414007Sedward 						hit--;
38514007Sedward 					else
38614007Sedward 						hit -= 2;
38715311Sedward 			if (ready & R_INITIAL) {
38815311Sedward 				if (!r)
38915311Sedward 					sp->file->readyL &= ~R_INITIAL;
39015311Sedward 				else
39115311Sedward 					sp->file->readyR &= ~R_INITIAL;
39214007Sedward 				if (index <= 3)
39314007Sedward 					hit++;
39411589Sleres 				else
39514007Sedward 					hit += 2;
39615311Sedward 			}
39714007Sedward 			if (sp->file->captured != 0)
39814007Sedward 				if (index <= 1)
39914007Sedward 					hit--;
40014007Sedward 				else
40114007Sedward 					hit -= 2;
40214007Sedward 			hit += AMMO[index][load - 1];
40314007Sedward 			temp = sp->specs->class;
40414007Sedward 			if ((temp >= 5 || temp == 1) && windspeed == 5)
40514007Sedward 				hit--;
40614007Sedward 			if (windspeed == 6 && temp == 4)
40714007Sedward 				hit -= 2;
40814007Sedward 			if (windspeed == 6 && temp <= 3)
40914007Sedward 				hit--;
41014007Sedward 			if (hit >= 0) {
41114007Sedward 				if (load != L_GRAPE)
41214007Sedward 					hit = hit > 10 ? 10 : hit;
41314007Sedward 				table(shootat, load, hit, closest, sp, die());
41411589Sleres 			}
41511589Sleres 		}
41611589Sleres 	}
41711589Sleres }
41811589Sleres 
41911589Sleres next()
42011589Sleres {
42114007Sedward 	if (++turn % 55 == 0)
42215202Sedward 		if (alive)
42315202Sedward 			alive = 0;
42414007Sedward 		else
42515202Sedward 			people = 0;
42615202Sedward 	if (people <= 0 || windspeed == 7) {
427*16082Sedward 		register struct ship *s;
428*16082Sedward 		struct ship *bestship;
429*16082Sedward 		float net, best = 0.0;
430*16082Sedward 		foreachship(s) {
431*16082Sedward 			if (*s->file->captain)
432*16082Sedward 				continue;
433*16082Sedward 			net = (float)s->file->points / s->specs->pts;
434*16082Sedward 			if (net > best) {
435*16082Sedward 				best = net;
436*16082Sedward 				bestship = s;
437*16082Sedward 			}
438*16082Sedward 		}
439*16082Sedward 		if (best > 0.0) {
440*16082Sedward 			char *p = getenv("WOTD");
441*16082Sedward 			if (p == 0)
442*16082Sedward 				p = "Driver";
443*16082Sedward 			strcpy(bestship->file->captain, p);
444*16082Sedward 			log(bestship);
445*16082Sedward 		}
44615202Sedward 		sync_close(1);
44711589Sleres 		exit(0);
44811589Sleres 	}
44914007Sedward 	Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
45014007Sedward 	if (turn % 7 == 0) {
45114007Sedward 		if (die() >= cc->windchange || !windspeed) {
45214007Sedward 			switch (die()) {
45314007Sedward 			case 1:
45414007Sedward 				winddir = 1;
45514007Sedward 				break;
45614007Sedward 			case 2:
45714007Sedward 				break;
45814007Sedward 			case 3:
45914007Sedward 				winddir++;
46014007Sedward 				break;
46114007Sedward 			case 4:
46214007Sedward 				winddir--;
46314007Sedward 				break;
46414007Sedward 			case 5:
46514007Sedward 				winddir += 2;
46614007Sedward 				break;
46714007Sedward 			case 6:
46814007Sedward 				winddir -= 2;
46914007Sedward 				break;
47014007Sedward 			}
47114007Sedward 			if (winddir > 8)
47214007Sedward 				winddir -= 8;
47314007Sedward 			if (winddir < 1)
47414007Sedward 				winddir += 8;
47514007Sedward 			if (windspeed)
47614007Sedward 				switch (die()) {
47711589Sleres 				case 1:
47811589Sleres 				case 2:
47914007Sedward 					windspeed--;
48011589Sleres 					break;
48111589Sleres 				case 5:
48211589Sleres 				case 6:
48314007Sedward 					windspeed++;
48411589Sleres 					break;
48511589Sleres 				}
48611589Sleres 			else
48711589Sleres 				windspeed++;
48814007Sedward 			Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
48914007Sedward 		}
49011589Sleres 	}
49111589Sleres }
49215237Sedward 
49315721Sedward /*ARGSUSED*/
49415237Sedward /*VARARGS2*/
49515237Sedward Signal(fmt, ship, a, b, c)
49615237Sedward char *fmt;
49715237Sedward struct ship *ship;
49815237Sedward {
49915237Sedward }
500