xref: /original-bsd/games/sail/assorted.c (revision 0842ddeb)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)assorted.c	8.2 (Berkeley) 04/28/95";
10 #endif /* not lint */
11 
12 #include "extern.h"
13 
14 table(rig, shot, hittable, on, from, roll)
15 struct ship *on, *from;
16 int rig, shot, hittable, roll;
17 {
18 	register int hhits = 0, chits = 0, ghits = 0, rhits = 0;
19 	int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0;
20 	int guns, car, pc, hull;
21 	int crew[3];
22 	register int n;
23 	int rigg[4];
24 	char *message;
25 	struct Tables *tp;
26 
27 	pc = on->file->pcrew;
28 	hull = on->specs->hull;
29 	crew[0] = on->specs->crew1;
30 	crew[1] = on->specs->crew2;
31 	crew[2] = on->specs->crew3;
32 	rigg[0] = on->specs->rig1;
33 	rigg[1] = on->specs->rig2;
34 	rigg[2] = on->specs->rig3;
35 	rigg[3] = on->specs->rig4;
36 	if (shot == L_GRAPE)
37 		Chit = chits = hittable;
38 	else {
39 		tp = &(rig ? RigTable : HullTable)[hittable][roll-1];
40 		Chit = chits = tp->C;
41 		Rhit = rhits = tp->R;
42 		Hhit = hhits = tp->H;
43 		Ghit = ghits = tp->G;
44 		if (on->file->FS)
45 			rhits *= 2;
46 		if (shot == L_CHAIN) {
47 			Ghit = ghits = 0;
48 			Hhit = hhits = 0;
49 		}
50 	}
51 	if (on->file->captured != 0) {
52 		pc -= (chits + 1) / 2;
53 		chits /= 2;
54 	}
55 	for (n = 0; n < 3; n++)
56 		if (chits > crew[n]) {
57 			chits -= crew[n];
58 			crew[n] = 0;
59 		} else {
60 			crew[n] -= chits;
61 			chits = 0;
62 		}
63 	for (n = 0; n < 3; n++)
64 		if (rhits > rigg[n]){
65 			rhits -= rigg[n];
66 			rigg[n] = 0;
67 		} else {
68 			rigg[n] -= rhits;
69 			rhits = 0;
70 		}
71 	if (rigg[3] != -1 && rhits > rigg[3]) {
72 		rhits -= rigg[3];
73 		rigg[3] = 0;
74 	} else if (rigg[3] != -1) {
75 		rigg[3] -= rhits;
76 	}
77 	if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1))
78 		makesignal(on, "dismasted!", (struct ship *)0);
79 	if (portside(from, on, 0)) {
80 		guns = on->specs->gunR;
81 		car = on->specs->carR;
82 	} else {
83 		guns = on->specs->gunL;
84 		car = on->specs->carL;
85 	}
86 	if (ghits > car) {
87 		ghits -= car;
88 		car = 0;
89 	} else {
90 		car -= ghits;
91 		ghits = 0;
92 	}
93 	if (ghits > guns){
94 		ghits -= guns;
95 		guns = 0;
96 	} else {
97 		guns -= ghits;
98 		ghits = 0;
99 	}
100 	hull -= ghits;
101 	if (Ghit)
102 		Write(portside(from, on, 0) ? W_GUNR : W_GUNL,
103 			on, 0, guns, car, 0, 0);
104 	hull -= hhits;
105 	hull = hull < 0 ? 0 : hull;
106 	if (on->file->captured != 0 && Chit)
107 		Write(W_PCREW, on, 0, pc, 0, 0, 0);
108 	if (Hhit)
109 		Write(W_HULL, on, 0, hull, 0, 0, 0);
110 	if (Chit)
111 		Write(W_CREW, on, 0, crew[0], crew[1], crew[2], 0);
112 	if (Rhit)
113 		Write(W_RIGG, on, 0, rigg[0], rigg[1], rigg[2], rigg[3]);
114 	switch (shot) {
115 	case L_ROUND:
116 		message = "firing round shot on %s (%c%c)";
117 		break;
118 	case L_GRAPE:
119 		message = "firing grape shot on %s (%c%c)";
120 		break;
121 	case L_CHAIN:
122 		message = "firing chain shot on %s (%c%c)";
123 		break;
124 	case L_DOUBLE:
125 		message = "firing double shot on %s (%c%c)";
126 		break;
127 	case L_EXPLODE:
128 		message = "exploding shot on %s (%c%c)";
129 	}
130 	makesignal(from, message, on);
131 	if (roll == 6 && rig) {
132 		switch(Rhit) {
133 		case 0:
134 			message = "fore topsail sheets parted";
135 			break;
136 		case 1:
137 			message = "mizzen shrouds parted";
138 			break;
139 		case 2:
140 			message = "main topsail yard shot away";
141 			break;
142 		case 4:
143 			message = "fore topmast and foremast shrouds shot away";
144 			break;
145 		case 5:
146 			message = "mizzen mast and yard shot through";
147 			break;
148 		case 6:
149 			message = "foremast and spritsail yard shattered";
150 			break;
151 		case 7:
152 			message = "main topmast and mizzen mast shattered";
153 			break;
154 		}
155 		makesignal(on, message, (struct ship *)0);
156 	} else if (roll == 6) {
157 		switch (Hhit) {
158 		case 0:
159 			message = "anchor cables severed";
160 			break;
161 		case 1:
162 			message = "two anchor stocks shot away";
163 			break;
164 		case 2:
165 			message = "quarterdeck bulwarks damaged";
166 			break;
167 		case 3:
168 			message = "three gun ports shot away";
169 			break;
170 		case 4:
171 			message = "four guns dismounted";
172 			break;
173 		case 5:
174 			message = "rudder cables shot through";
175 			Write(W_TA, on, 0, 0, 0, 0, 0);
176 			break;
177 		case 6:
178 			message = "shot holes below the water line";
179 			break;
180 		}
181 		makesignal(on, message, (struct ship *)0);
182 	}
183 	/*
184 	if (Chit > 1 && on->file->readyL&R_INITIAL && on->file->readyR&R_INITIAL) {
185 		on->specs->qual--;
186 		if (on->specs->qual <= 0) {
187 			makesignal(on, "crew mutinying!", (struct ship *)0);
188 			on->specs->qual = 5;
189 			Write(W_CAPTURED, on, 0, on->file->index, 0, 0, 0);
190 		} else
191 			makesignal(on, "crew demoralized", (struct ship *)0);
192 		Write(W_QUAL, on, 0, on->specs->qual, 0, 0, 0);
193 	}
194 	*/
195 	if (!hull)
196 		strike(on, from);
197 }
198 
199 Cleansnag(from, to, all, flag)
200 register struct ship *from, *to;
201 char all, flag;
202 {
203 	if (flag & 1) {
204 		Write(W_UNGRAP, from, 0, to->file->index, all, 0, 0);
205 		Write(W_UNGRAP, to, 0, from->file->index, all, 0, 0);
206 	}
207 	if (flag & 2) {
208 		Write(W_UNFOUL, from, 0, to->file->index, all, 0, 0);
209 		Write(W_UNFOUL, to, 0, from->file->index, all, 0, 0);
210 	}
211 	if (!snagged2(from, to)) {
212 		if (!snagged(from)) {
213 			unboard(from, from, 1);		/* defense */
214 			unboard(from, from, 0);		/* defense */
215 		} else
216 			unboard(from, to, 0);		/* offense */
217 		if (!snagged(to)) {
218 			unboard(to, to, 1);		/* defense */
219 			unboard(to, to, 0);		/* defense */
220 		} else
221 			unboard(to, from, 0);		/* offense */
222 	}
223 }
224 
225 strike(ship, from)
226 register struct ship *ship, *from;
227 {
228 	int points;
229 
230 	if (ship->file->struck)
231 		return;
232 	Write(W_STRUCK, ship, 0, 1, 0, 0, 0);
233 	points = ship->specs->pts + from->file->points;
234 	Write(W_POINTS, from, 0, points, 0, 0, 0);
235 	unboard(ship, ship, 0);		/* all offense */
236 	unboard(ship, ship, 1);		/* all defense */
237 	switch (die()) {
238 	case 3:
239 	case 4:		/* ship may sink */
240 		Write(W_SINK, ship, 0, 1, 0, 0, 0);
241 		break;
242 	case 5:
243 	case 6:		/* ship may explode */
244 		Write(W_EXPLODE, ship, 0, 1, 0, 0, 0);
245 		break;
246 	}
247 	Write(W_SIGNAL, ship, 1, (int) "striking her colours!", 0, 0, 0);
248 }
249