1*459966a9Schristos /* $NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $ */
2982615d7Scgd
361f28255Scgd /*
4982615d7Scgd * Copyright (c) 1983, 1993
5982615d7Scgd * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
32bf72b656Schristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
34982615d7Scgd #if 0
35156daa7aStls static char sccsid[] = "@(#)assorted.c 8.2 (Berkeley) 4/28/95";
36982615d7Scgd #else
37*459966a9Schristos __RCSID("$NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $");
38982615d7Scgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd
41bf72b656Schristos #include <stdlib.h>
42bf72b656Schristos #include <err.h>
43aac077fcSjwise #include "extern.h"
4461f28255Scgd
45dfea9f08Sjwise static void strike(struct ship *, struct ship *);
46bf72b656Schristos
47bf72b656Schristos void
table(struct ship * from,struct ship * on,int rig,int shot,int hittable,int roll)48b8c43a1fSdholland table(struct ship *from, struct ship *on,
49b8c43a1fSdholland int rig, int shot, int hittable, int roll)
5061f28255Scgd {
51bf72b656Schristos int hhits = 0, chits = 0, ghits = 0, rhits = 0;
5261f28255Scgd int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0;
5361f28255Scgd int guns, car, pc, hull;
5461f28255Scgd int crew[3];
55bf72b656Schristos int n;
5661f28255Scgd int rigg[4];
57092d3130Sjsm const char *message;
58092d3130Sjsm const struct Tables *tp;
5961f28255Scgd
6061f28255Scgd pc = on->file->pcrew;
6161f28255Scgd hull = on->specs->hull;
6261f28255Scgd crew[0] = on->specs->crew1;
6361f28255Scgd crew[1] = on->specs->crew2;
6461f28255Scgd crew[2] = on->specs->crew3;
6561f28255Scgd rigg[0] = on->specs->rig1;
6661f28255Scgd rigg[1] = on->specs->rig2;
6761f28255Scgd rigg[2] = on->specs->rig3;
6861f28255Scgd rigg[3] = on->specs->rig4;
69b8c43a1fSdholland if (shot == L_GRAPE) {
7061f28255Scgd Chit = chits = hittable;
71b8c43a1fSdholland } else {
7261f28255Scgd tp = &(rig ? RigTable : HullTable)[hittable][roll-1];
7361f28255Scgd Chit = chits = tp->C;
7461f28255Scgd Rhit = rhits = tp->R;
7561f28255Scgd Hhit = hhits = tp->H;
7661f28255Scgd Ghit = ghits = tp->G;
7761f28255Scgd if (on->file->FS)
7861f28255Scgd rhits *= 2;
7961f28255Scgd if (shot == L_CHAIN) {
8061f28255Scgd Ghit = ghits = 0;
8161f28255Scgd Hhit = hhits = 0;
8261f28255Scgd }
8361f28255Scgd }
8461f28255Scgd if (on->file->captured != 0) {
8561f28255Scgd pc -= (chits + 1) / 2;
8661f28255Scgd chits /= 2;
8761f28255Scgd }
88b8c43a1fSdholland for (n = 0; n < 3; n++) {
8961f28255Scgd if (chits > crew[n]) {
9061f28255Scgd chits -= crew[n];
9161f28255Scgd crew[n] = 0;
9261f28255Scgd } else {
9361f28255Scgd crew[n] -= chits;
9461f28255Scgd chits = 0;
9561f28255Scgd }
96b8c43a1fSdholland }
97b8c43a1fSdholland for (n = 0; n < 3; n++) {
9861f28255Scgd if (rhits > rigg[n]) {
9961f28255Scgd rhits -= rigg[n];
10061f28255Scgd rigg[n] = 0;
10161f28255Scgd } else {
10261f28255Scgd rigg[n] -= rhits;
10361f28255Scgd rhits = 0;
10461f28255Scgd }
105b8c43a1fSdholland }
10661f28255Scgd if (rigg[3] != -1 && rhits > rigg[3]) {
10761f28255Scgd rhits -= rigg[3];
10861f28255Scgd rigg[3] = 0;
10961f28255Scgd } else if (rigg[3] != -1) {
11061f28255Scgd rigg[3] -= rhits;
11161f28255Scgd }
11261f28255Scgd if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1))
1135175902cSchristos makemsg(on, "dismasted!");
11461f28255Scgd if (portside(from, on, 0)) {
11561f28255Scgd guns = on->specs->gunR;
11661f28255Scgd car = on->specs->carR;
11761f28255Scgd } else {
11861f28255Scgd guns = on->specs->gunL;
11961f28255Scgd car = on->specs->carL;
12061f28255Scgd }
12161f28255Scgd if (ghits > car) {
12261f28255Scgd ghits -= car;
12361f28255Scgd car = 0;
12461f28255Scgd } else {
12561f28255Scgd car -= ghits;
12661f28255Scgd ghits = 0;
12761f28255Scgd }
12861f28255Scgd if (ghits > guns) {
12961f28255Scgd ghits -= guns;
13061f28255Scgd guns = 0;
13161f28255Scgd } else {
13261f28255Scgd guns -= ghits;
13361f28255Scgd ghits = 0;
13461f28255Scgd }
13561f28255Scgd hull -= ghits;
136e544d2b8Sdholland if (Ghit) {
137e544d2b8Sdholland if (portside(from, on, 0)) {
138e544d2b8Sdholland send_gunr(on, guns, car);
139e544d2b8Sdholland } else {
140e544d2b8Sdholland send_gunl(on, guns, car);
141e544d2b8Sdholland }
142e544d2b8Sdholland }
14361f28255Scgd hull -= hhits;
14461f28255Scgd hull = hull < 0 ? 0 : hull;
14561f28255Scgd if (on->file->captured != 0 && Chit)
146e544d2b8Sdholland send_pcrew(on, pc);
14761f28255Scgd if (Hhit)
148e544d2b8Sdholland send_hull(on, hull);
14961f28255Scgd if (Chit)
150e544d2b8Sdholland send_crew(on, crew[0], crew[1], crew[2]);
15161f28255Scgd if (Rhit)
152e544d2b8Sdholland send_rigg(on, rigg[0], rigg[1], rigg[2], rigg[3]);
15361f28255Scgd switch (shot) {
15461f28255Scgd case L_ROUND:
155*459966a9Schristos message = "firing round";
15661f28255Scgd break;
15761f28255Scgd case L_GRAPE:
158*459966a9Schristos message = "firing grape";
15961f28255Scgd break;
16061f28255Scgd case L_CHAIN:
161*459966a9Schristos message = "firing chain";
16261f28255Scgd break;
16361f28255Scgd case L_DOUBLE:
164*459966a9Schristos message = "firing double";
16561f28255Scgd break;
16661f28255Scgd case L_EXPLODE:
167*459966a9Schristos message = "exploding";
168bf72b656Schristos break;
169bf72b656Schristos default:
170bf72b656Schristos errx(1, "Unknown shot type %d", shot);
171bf72b656Schristos
17261f28255Scgd }
173*459966a9Schristos makesignal(from, "%s shot on $$", on, message);
17461f28255Scgd if (roll == 6 && rig) {
17561f28255Scgd switch(Rhit) {
17661f28255Scgd case 0:
17761f28255Scgd message = "fore topsail sheets parted";
17861f28255Scgd break;
17961f28255Scgd case 1:
18061f28255Scgd message = "mizzen shrouds parted";
18161f28255Scgd break;
18261f28255Scgd case 2:
18361f28255Scgd message = "main topsail yard shot away";
18461f28255Scgd break;
18561f28255Scgd case 4:
18661f28255Scgd message = "fore topmast and foremast shrouds shot away";
18761f28255Scgd break;
18861f28255Scgd case 5:
18961f28255Scgd message = "mizzen mast and yard shot through";
19061f28255Scgd break;
19161f28255Scgd case 6:
19261f28255Scgd message = "foremast and spritsail yard shattered";
19361f28255Scgd break;
19461f28255Scgd case 7:
19561f28255Scgd message = "main topmast and mizzen mast shattered";
19661f28255Scgd break;
197bf72b656Schristos default:
198bf72b656Schristos errx(1, "Bad Rhit = %d", Rhit);
19961f28255Scgd }
2008f09f5ccSjoerg makemsg(on, "%s", message);
20161f28255Scgd } else if (roll == 6) {
20261f28255Scgd switch (Hhit) {
20361f28255Scgd case 0:
20461f28255Scgd message = "anchor cables severed";
20561f28255Scgd break;
20661f28255Scgd case 1:
20761f28255Scgd message = "two anchor stocks shot away";
20861f28255Scgd break;
20961f28255Scgd case 2:
21061f28255Scgd message = "quarterdeck bulwarks damaged";
21161f28255Scgd break;
21261f28255Scgd case 3:
21361f28255Scgd message = "three gun ports shot away";
21461f28255Scgd break;
21561f28255Scgd case 4:
21661f28255Scgd message = "four guns dismounted";
21761f28255Scgd break;
21861f28255Scgd case 5:
21961f28255Scgd message = "rudder cables shot through";
220e544d2b8Sdholland send_ta(on, 0);
22161f28255Scgd break;
22261f28255Scgd case 6:
22361f28255Scgd message = "shot holes below the water line";
22461f28255Scgd break;
225bf72b656Schristos default:
226bf72b656Schristos errx(1, "Bad Hhit = %d", Hhit);
22761f28255Scgd }
2288f09f5ccSjoerg makemsg(on, "%s", message);
22961f28255Scgd }
23061f28255Scgd /*
231b8c43a1fSdholland if (Chit > 1 && on->file->readyL & R_INITIAL &&
232b8c43a1fSdholland on->file->readyR & R_INITIAL) {
23361f28255Scgd on->specs->qual--;
23461f28255Scgd if (on->specs->qual <= 0) {
2355175902cSchristos makemsg(on, "crew mutinying!");
23661f28255Scgd on->specs->qual = 5;
23724f809b0Shubertf Write(W_CAPTURED, on, on->file->index, 0, 0, 0);
238b8c43a1fSdholland } else {
2395175902cSchristos makemsg(on, "crew demoralized");
240b8c43a1fSdholland }
24124f809b0Shubertf Write(W_QUAL, on, on->specs->qual, 0, 0, 0);
24261f28255Scgd }
24361f28255Scgd */
24461f28255Scgd if (!hull)
24561f28255Scgd strike(on, from);
24661f28255Scgd }
24761f28255Scgd
248bf72b656Schristos void
Cleansnag(struct ship * from,struct ship * to,int all,int flag)249dfea9f08Sjwise Cleansnag(struct ship *from, struct ship *to, int all, int flag)
25061f28255Scgd {
25161f28255Scgd if (flag & 1) {
252e544d2b8Sdholland send_ungrap(from, to->file->index, all);
253e544d2b8Sdholland send_ungrap(to, from->file->index, all);
25461f28255Scgd }
25561f28255Scgd if (flag & 2) {
256e544d2b8Sdholland send_unfoul(from, to->file->index, all);
257e544d2b8Sdholland send_unfoul(to, from->file->index, all);
25861f28255Scgd }
25961f28255Scgd if (!snagged2(from, to)) {
26061f28255Scgd if (!snagged(from)) {
26161f28255Scgd unboard(from, from, 1); /* defense */
26261f28255Scgd unboard(from, from, 0); /* defense */
26361f28255Scgd } else
26461f28255Scgd unboard(from, to, 0); /* offense */
26561f28255Scgd if (!snagged(to)) {
26661f28255Scgd unboard(to, to, 1); /* defense */
26761f28255Scgd unboard(to, to, 0); /* defense */
26861f28255Scgd } else
26961f28255Scgd unboard(to, from, 0); /* offense */
27061f28255Scgd }
27161f28255Scgd }
27261f28255Scgd
273bf72b656Schristos static void
strike(struct ship * ship,struct ship * from)274dfea9f08Sjwise strike(struct ship *ship, struct ship *from)
27561f28255Scgd {
27661f28255Scgd int points;
27761f28255Scgd
27861f28255Scgd if (ship->file->struck)
27961f28255Scgd return;
280e544d2b8Sdholland send_struck(ship, 1);
28161f28255Scgd points = ship->specs->pts + from->file->points;
282e544d2b8Sdholland send_points(from, points);
28361f28255Scgd unboard(ship, ship, 0); /* all offense */
28461f28255Scgd unboard(ship, ship, 1); /* all defense */
28548253ebcSjwise switch (dieroll()) {
28661f28255Scgd case 3:
28761f28255Scgd case 4: /* ship may sink */
288e544d2b8Sdholland send_sink(ship, 1);
28961f28255Scgd break;
29061f28255Scgd case 5:
29161f28255Scgd case 6: /* ship may explode */
292e544d2b8Sdholland send_explode(ship, 1);
29361f28255Scgd break;
29461f28255Scgd }
295e544d2b8Sdholland send_signal(ship, "striking her colours!");
29661f28255Scgd }
297