xref: /csrg-svn/games/sail/dr_1.c (revision 15395)
111589Sleres #ifndef lint
2*15395Sedward static	char *sccsid = "@(#)dr_1.c	2.4 83/11/08";
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];
2415202Sedward 	ls = &cc->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");
3515202Sedward 			exit(0);
3615202Sedward 		}
3715202Sedward 		sp->file->loadL = L_ROUND;
3815202Sedward 		sp->file->loadR = L_ROUND;
3915202Sedward 		sp->file->readyR = R_LOADED|R_INITIAL;
4015202Sedward 		sp->file->readyL = R_LOADED|R_INITIAL;
4115202Sedward 		sp->file->stern = nat[sp->nationality]++;
4215202Sedward 		sp->file->dir = sp->shipdir;
4315202Sedward 		sp->file->row = sp->shiprow;
4415202Sedward 		sp->file->col = sp->shipcol;
4515202Sedward 	}
4615202Sedward 	windspeed = cc->windspeed;
4715202Sedward 	winddir = cc->winddir;
4815202Sedward 	for (;;) {
4915353Sedward 		sleep(7);
5015202Sedward 		Sync();
5115202Sedward 		next();
5215202Sedward 		unfoul();
5315202Sedward 		checkup();
5415202Sedward 		prizecheck();
5515202Sedward 		moveall();
5615202Sedward 		thinkofgrapples();
5715202Sedward 		boardcomp();
5815202Sedward 		compcombat();
5915202Sedward 		resolve();
6015202Sedward 		reload();
6115202Sedward 		checksails();
6215202Sedward 		Sync();
6315202Sedward 	}
6415202Sedward }
6515202Sedward 
6611589Sleres unfoul()
6711589Sleres {
6814007Sedward 	register int k;
6914007Sedward 	register struct ship *sp;
7014007Sedward 	struct ship *to;
7114007Sedward 	register int nat;
7211589Sleres 
7314007Sedward 	foreachship(sp) {
7414007Sedward 		if (sp->file->captain[0])
7514007Sedward 			continue;
7614007Sedward 		nat = capship(sp)->nationality;
7714007Sedward 		for (k = 0; k < NSHIP; k++) {
7814007Sedward 			if (sp->file->fouls[k].turnfoul == 0)
7914007Sedward 				continue;
8014007Sedward 			to = sp->file->fouls[k].toship;
8114007Sedward 			if (nat != capship(to)->nationality)
8214007Sedward 				continue;
8314007Sedward 			if (!toughmelee(sp, to, 0, 0))
8414007Sedward 				continue;
8514007Sedward 			if (die() <= 2)
8614007Sedward 				cleanfoul(sp, to, k);
8711589Sleres 		}
8811589Sleres 	}
8911589Sleres }
9011589Sleres 
9111589Sleres boardcomp()
9211589Sleres {
9312619Sroot 	int crew[3];
9414007Sedward 	register struct ship *sp, *sq;
9511589Sleres 
9614007Sedward 	foreachship(sp) {
9714007Sedward 		if (*sp->file->captain)
9814007Sedward 			continue;
9914007Sedward 		if (!fouled(sp) && !grappled(sp))
10014007Sedward 			continue;
10114007Sedward 		if (sp->file->dir == 0)
10214007Sedward 			continue;
10314007Sedward 		if (sp->file->struck || sp->file->captured != 0)
10414007Sedward 			continue;
10514007Sedward 		crew[0] = sp->specs->crew1 != 0;
10614007Sedward 		crew[1] = sp->specs->crew2 != 0;
10714007Sedward 		crew[2] = sp->specs->crew3 != 0;
10814007Sedward 		foreachship(sq) {
10914007Sedward 			if (!Xsnagged2(sp, sq))
11014007Sedward 				continue;
11114007Sedward 			if (meleeing(sp, sq))
11214007Sedward 				continue;
11314007Sedward 			if (!sq->file->dir
11414007Sedward 				|| sp->nationality == capship(sq)->nationality)
11514007Sedward 				continue;
11614007Sedward 			switch (sp->specs->class - sq->specs->class) {
11714007Sedward 			case -3: case -4: case -5:
11814007Sedward 				if (crew[0]) {
11914007Sedward 					/* OBP */
12014007Sedward 					sendbp(sp, sq, crew[0]*100, 0);
12114007Sedward 					crew[0] = 0;
12214007Sedward 				} else if (crew[1]){
12314007Sedward 					/* OBP */
12414007Sedward 					sendbp(sp, sq, crew[1]*10, 0);
12514007Sedward 					crew[1] = 0;
12611589Sleres 				}
12714007Sedward 				break;
12814007Sedward 			case -2:
12914007Sedward 				if (crew[0] || crew[1]) {
13014007Sedward 					/* OBP */
13114007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
13214007Sedward 						0);
13314007Sedward 					crew[0] = crew[1] = 0;
13414007Sedward 				}
13514007Sedward 				break;
13614007Sedward 			case -1: case 0: case 1:
13714007Sedward 				if (crew[0]) {
13814007Sedward 					/* OBP */
13914007Sedward 					sendbp(sp, sq, crew[0]*100+crew[1]*10,
14014007Sedward 						0);
14114007Sedward 					crew[0] = crew[1] = 0;
14214007Sedward 				}
14314007Sedward 				break;
14414007Sedward 			case 2: case 3: case 4: case 5:
14514007Sedward 				/* OBP */
14614007Sedward 				sendbp(sp, sq, crew[0]*100+crew[1]*10+crew[2],
14714007Sedward 					0);
14814007Sedward 				crew[0] = crew[1] = crew[2] = 0;
14914007Sedward 				break;
15011589Sleres 			}
15114007Sedward 		}
15211589Sleres 	}
15311589Sleres }
15411589Sleres 
15511589Sleres fightitout(from, to, key)
15614007Sedward struct ship *from, *to;
15714007Sedward int key;
15811589Sleres {
15914007Sedward 	struct ship *fromcap, *tocap;
16014007Sedward 	int crewfrom[3], crewto[3], menfrom, mento;
16111589Sleres 	int pcto, pcfrom, fromstrength, strengthto, frominjured, toinjured;
16214007Sedward 	int topoints;
16314007Sedward 	int index, totalfrom = 0, totalto = 0;
16414007Sedward 	int count;
16511589Sleres 	char message[60];
16611589Sleres 
16714007Sedward 	menfrom = mensent(from, to, crewfrom, &fromcap, &pcfrom, key);
16814007Sedward 	mento = mensent(to, from, crewto, &tocap, &pcto, 0);
16914007Sedward 	if (fromcap == 0)
17011589Sleres 		fromcap = from;
17114007Sedward 	if (tocap == 0)
17211589Sleres 		tocap = to;
17315330Sedward 	if (key) {
17415330Sedward 		if (!menfrom) {		 /* if crew surprised */
17515330Sedward 			if (fromcap == from)
17615330Sedward 				menfrom = from->specs->crew1
17715330Sedward 					+ from->specs->crew2
17815330Sedward 					+ from->specs->crew3;
17915330Sedward 			else
18015330Sedward 				menfrom = from->file->pcrew;
18115330Sedward 		} else {
18215330Sedward 			menfrom *= 2;	/* DBP's fight at an advantage */
18315330Sedward 		}
18415330Sedward 	}
18514007Sedward 	fromstrength = menfrom * fromcap->specs->qual;
18614007Sedward 	strengthto = mento * tocap->specs->qual;
18714007Sedward 	for (count = 0;
18814007Sedward 	     (fromstrength < strengthto * 3 && strengthto < fromstrength * 3
18914007Sedward 	      || fromstrength == -1) && count < 4;
19014007Sedward 	     count++) {
19111589Sleres 		index = fromstrength/10;
19211589Sleres 		if (index > 8)
19311589Sleres 			index = 8;
19411589Sleres 		toinjured = MT[index][2 - die() / 3];
19511589Sleres 		totalto += toinjured;
19611589Sleres 		index = strengthto/10;
19711589Sleres 		if (index > 8)
19811589Sleres 			index = 8;
19911589Sleres 		frominjured = MT[index][2 - die() / 3];
20011589Sleres 		totalfrom += frominjured;
20111589Sleres 		menfrom -= frominjured;
20211589Sleres 		mento -= toinjured;
20314007Sedward 		fromstrength = menfrom * fromcap->specs->qual;
20414007Sedward 		strengthto = mento * tocap->specs->qual;
20511589Sleres 	}
20614007Sedward 	if (fromstrength >= strengthto * 3 || count == 4) {
20711589Sleres 		unboard(to, from, 0);
20811589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
20911589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
21014007Sedward 		makesignal(from, "boarders from %s repelled", to);
21114007Sedward 		(void) sprintf(message, "killed in melee: %d.  %s: %d",
21214007Sedward 			totalto, from->shipname, totalfrom);
21314007Sedward 		Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
21411589Sleres 		if (key)
21514007Sedward 			return 1;
21614007Sedward 	} else if (strengthto >= fromstrength * 3) {
21711589Sleres 		unboard(from, to, 0);
21811589Sleres 		subtract(from, totalfrom, crewfrom, fromcap, pcfrom);
21911589Sleres 		subtract(to, totalto, crewto, tocap, pcto);
22014007Sedward 		if (key) {
22111589Sleres 			if (fromcap != from)
22214007Sedward 				Write(W_POINTS, fromcap, 0,
22314007Sedward 					fromcap->file->points -
22414007Sedward 						from->file->struck
22514007Sedward 						? from->specs->pts
22614007Sedward 						: 2 * from->specs->pts,
22714007Sedward 					0, 0, 0);
22811589Sleres 
22911589Sleres /* ptr1 points to the shipspec for the ship that was just unboarded.
23011589Sleres    I guess that what is going on here is that the pointer is multiplied
23111589Sleres    or something. */
23211589Sleres 
23314007Sedward 			Write(W_CAPTURED, from, 0, to-SHIP(0), 0, 0, 0);
23414007Sedward 			topoints = 2 * from->specs->pts + to->file->points;
23514007Sedward 			if (from->file->struck)
23614007Sedward 				topoints -= from->specs->pts;
23714007Sedward 			Write(W_POINTS, to, 0, topoints, 0, 0, 0);
23811589Sleres 			mento = crewto[0] ? crewto[0] : crewto[1];
23914007Sedward 			if (mento) {
24011589Sleres 				subtract(to, mento, crewto, tocap, pcto);
24114007Sedward 				subtract(from, - mento, crewfrom, to, 0);
24211589Sleres 			}
24314007Sedward 			(void) sprintf(message, "captured by the %s!",
24414007Sedward 				to->shipname);
24514007Sedward 			Write(W_SIGNAL, from, 1, (int) message, 0, 0, 0);
24614007Sedward 			(void) sprintf(message, "killed in melee: %d.  %s: %d",
24714007Sedward 				totalto, from->shipname, totalfrom);
24814007Sedward 			Write(W_SIGNAL, to, 1, (int) message, 0, 0, 0);
24911589Sleres 			mento = 0;
25014007Sedward 			return 0;
25111589Sleres 		}
25211589Sleres 	}
25314007Sedward 	return 0;
25414007Sedward }
25511589Sleres 
25611589Sleres resolve()
25711589Sleres {
25814007Sedward 	int thwart;
25914007Sedward 	register struct ship *sp, *sq;
26011589Sleres 
26114007Sedward 	foreachship(sp) {
26214007Sedward 		if (sp->file->dir == 0)
26314007Sedward 			continue;
26415330Sedward 		for (sq = sp + 1; sq < ls; sq++)
26514007Sedward 			if (sq->file->dir && meleeing(sp, sq) && meleeing(sq, sp))
26614007Sedward 				(void) fightitout(sp, sq, 0);
267*15395Sedward 		thwart = 2;
26814007Sedward 		foreachship(sq) {
26914007Sedward 			if (sq->file->dir && meleeing(sq, sp))
27014007Sedward 				thwart = fightitout(sp, sq, 1);
27114007Sedward 			if (!thwart)
27214007Sedward 				break;
27311589Sleres 		}
274*15395Sedward 		if (!thwart) {
275*15395Sedward 			foreachship(sq) {
276*15395Sedward 				if (sq->file->dir && meleeing(sq, sp))
277*15395Sedward 					unboard(sq, sp, 0);
278*15395Sedward 				unboard(sp, sq, 0);
279*15395Sedward 			}
28014007Sedward 			unboard(sp, sp, 1);
281*15395Sedward 		} else if (thwart == 2)
282*15395Sedward 			unboard(sp, sp, 1);
28311589Sleres 	}
28411589Sleres }
28511589Sleres 
28611589Sleres compcombat()
28711589Sleres {
28814007Sedward 	register n;
28914007Sedward 	register struct ship *sp;
29014007Sedward 	struct ship *closest;
29111589Sleres 	int crew[3], men = 0, target, temp;
29215311Sedward 	int r, guns, ready, load, car;
29315311Sedward 	int index, rakehim, sternrake;
29414007Sedward 	int shootat, hit;
29511589Sleres 
29614007Sedward 	foreachship(sp) {
29714007Sedward 		if (sp->file->captain[0] || sp->file->dir == 0)
29814007Sedward 			continue;
29914007Sedward 		crew[0] = sp->specs->crew1;
30014007Sedward 		crew[1] = sp->specs->crew2;
30114007Sedward 		crew[2] = sp->specs->crew3;
30214007Sedward 		for (n = 0; n < 3; n++) {
30314007Sedward 			if (sp->file->OBP[n].turnsent)
30414007Sedward 				men += sp->file->OBP[n].mensent;
30514007Sedward 		}
30614007Sedward 		for (n = 0; n < 3; n++) {
30714007Sedward 			if (sp->file->DBP[n].turnsent)
30814007Sedward 				men += sp->file->DBP[n].mensent;
30914007Sedward 		}
31014007Sedward 		if (men){
31114007Sedward 			crew[0] = men/100 ? 0 : crew[0] != 0;
31214007Sedward 			crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
31314007Sedward 			crew[2] = men%10 ? 0 : crew[2] != 0;
31414007Sedward 		}
31514007Sedward 		for (r = 0; r < 2; r++) {
31614007Sedward 			if (!crew[2])
31714007Sedward 				continue;
31814007Sedward 			if (sp->file->struck)
31914007Sedward 				continue;
32014007Sedward 			if (r) {
32114007Sedward 				ready = sp->file->readyR;
32214007Sedward 				guns = sp->specs->gunR;
32314007Sedward 				car = sp->specs->carR;
32414007Sedward 			} else {
32514007Sedward 				ready = sp->file->readyL;
32614007Sedward 				guns = sp->specs->gunL;
32714007Sedward 				car = sp->specs->carL;
32811589Sleres 			}
32914007Sedward 			if (!guns && !car)
33014007Sedward 				continue;
33114007Sedward 			if ((ready & R_LOADED) == 0)
33214007Sedward 				continue;
33314007Sedward 			closest = closestenemy(sp, r ? 'r' : 'l', 0);
33414007Sedward 			if (closest == 0)
33514007Sedward 				continue;
33614007Sedward 			if (range(closest, sp) > range(sp, closestenemy(sp, r ? 'r' : 'l', 1)))
33714007Sedward 				continue;
33814007Sedward 			if (closest->file->struck)
33914007Sedward 				continue;
34014007Sedward 			target = range(sp, closest);
34114007Sedward 			if (target > 10)
34214007Sedward 				continue;
34314007Sedward 			if (!guns && target >= 3)
34414007Sedward 				continue;
34514007Sedward 			load = L_ROUND;
34614007Sedward 			if (target == 1 && sp->file->loadwith == L_GRAPE)
34714007Sedward 				load = L_GRAPE;
34814007Sedward 			if (target <= 3 && closest->file->FS)
34914007Sedward 				load = L_CHAIN;
35014007Sedward 			if (target == 1 && load != L_GRAPE)
35114007Sedward 				load = L_DOUBLE;
35214007Sedward 			if (load > L_CHAIN && target < 6)
35314007Sedward 				shootat = HULL;
35414007Sedward 			else
35514007Sedward 				shootat = RIGGING;
35614007Sedward 			rakehim = gunsbear(sp, closest)
35714007Sedward 				&& !gunsbear(closest, sp);
35814007Sedward 			temp = portside(closest, sp, 1)
35914007Sedward 				- closest->file->dir + 1;
36014007Sedward 			if (temp < 1)
36114007Sedward 				temp += 8;
36214007Sedward 			if (temp > 8)
36314007Sedward 				temp -= 8;
36414007Sedward 			sternrake = temp > 4 && temp < 6;
36514007Sedward 			index = guns;
36614007Sedward 			if (target < 3)
36714007Sedward 				index += car;
36814007Sedward 			index = (index - 1) / 3;
36914007Sedward 			index = index > 8 ? 8 : index;
37014007Sedward 			if (!rakehim)
37114007Sedward 				hit = HDT[index][target-1];
37214007Sedward 			else
37314007Sedward 				hit = HDTrake[index][target-1];
37414007Sedward 			if (rakehim && sternrake)
37514007Sedward 				hit++;
37614007Sedward 			hit += QUAL[index][capship(sp)->specs->qual - 1];
37714007Sedward 			for (n = 0; n < 3 && sp->file->captured == 0; n++)
37814007Sedward 				if (!crew[n])
37914007Sedward 					if (index <= 5)
38014007Sedward 						hit--;
38114007Sedward 					else
38214007Sedward 						hit -= 2;
38315311Sedward 			if (ready & R_INITIAL) {
38415311Sedward 				if (!r)
38515311Sedward 					sp->file->readyL &= ~R_INITIAL;
38615311Sedward 				else
38715311Sedward 					sp->file->readyR &= ~R_INITIAL;
38814007Sedward 				if (index <= 3)
38914007Sedward 					hit++;
39011589Sleres 				else
39114007Sedward 					hit += 2;
39215311Sedward 			}
39314007Sedward 			if (sp->file->captured != 0)
39414007Sedward 				if (index <= 1)
39514007Sedward 					hit--;
39614007Sedward 				else
39714007Sedward 					hit -= 2;
39814007Sedward 			hit += AMMO[index][load - 1];
39914007Sedward 			temp = sp->specs->class;
40014007Sedward 			if ((temp >= 5 || temp == 1) && windspeed == 5)
40114007Sedward 				hit--;
40214007Sedward 			if (windspeed == 6 && temp == 4)
40314007Sedward 				hit -= 2;
40414007Sedward 			if (windspeed == 6 && temp <= 3)
40514007Sedward 				hit--;
40614007Sedward 			if (hit >= 0) {
40714007Sedward 				if (load != L_GRAPE)
40814007Sedward 					hit = hit > 10 ? 10 : hit;
40914007Sedward 				table(shootat, load, hit, closest, sp, die());
41011589Sleres 			}
41111589Sleres 		}
41211589Sleres 	}
41311589Sleres }
41411589Sleres 
41511589Sleres next()
41611589Sleres {
41714007Sedward 	if (++turn % 55 == 0)
41815202Sedward 		if (alive)
41915202Sedward 			alive = 0;
42014007Sedward 		else
42115202Sedward 			people = 0;
42215202Sedward 	if (people <= 0 || windspeed == 7) {
42315202Sedward 		sync_close(1);
42411589Sleres 		exit(0);
42511589Sleres 	}
42614007Sedward 	Write(W_TURN, SHIP(0), 0, turn, 0, 0, 0);
42714007Sedward 	if (turn % 7 == 0) {
42814007Sedward 		if (die() >= cc->windchange || !windspeed) {
42914007Sedward 			switch (die()) {
43014007Sedward 			case 1:
43114007Sedward 				winddir = 1;
43214007Sedward 				break;
43314007Sedward 			case 2:
43414007Sedward 				break;
43514007Sedward 			case 3:
43614007Sedward 				winddir++;
43714007Sedward 				break;
43814007Sedward 			case 4:
43914007Sedward 				winddir--;
44014007Sedward 				break;
44114007Sedward 			case 5:
44214007Sedward 				winddir += 2;
44314007Sedward 				break;
44414007Sedward 			case 6:
44514007Sedward 				winddir -= 2;
44614007Sedward 				break;
44714007Sedward 			}
44814007Sedward 			if (winddir > 8)
44914007Sedward 				winddir -= 8;
45014007Sedward 			if (winddir < 1)
45114007Sedward 				winddir += 8;
45214007Sedward 			if (windspeed)
45314007Sedward 				switch (die()) {
45411589Sleres 				case 1:
45511589Sleres 				case 2:
45614007Sedward 					windspeed--;
45711589Sleres 					break;
45811589Sleres 				case 5:
45911589Sleres 				case 6:
46014007Sedward 					windspeed++;
46111589Sleres 					break;
46211589Sleres 				}
46311589Sleres 			else
46411589Sleres 				windspeed++;
46514007Sedward 			Write(W_WIND, SHIP(0), 0, winddir, windspeed, 0, 0);
46614007Sedward 		}
46711589Sleres 	}
46811589Sleres }
46915237Sedward 
47015237Sedward /*VARARGS2*/
47115237Sedward Signal(fmt, ship, a, b, c)
47215237Sedward char *fmt;
47315237Sedward struct ship *ship;
47415237Sedward {
47515237Sedward }
476