ckdist(1): Sync with FreeBSD.
[dragonfly.git] / games / sail / pl_3.c
blobe4d60b8224022190e3e09c50831a1ddc78e98281
1 /*-
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#)pl_3.c 8.1 (Berkeley) 5/31/93
30 * $FreeBSD: src/games/sail/pl_3.c,v 1.6 1999/11/30 03:49:37 billf Exp $
33 #include "player.h"
35 void
36 acceptcombat(void)
38 int men = 0;
39 int target, temp;
40 int n, r;
41 int idx, rakehim, sternrake;
42 int hhits = 0, ghits = 0, rhits = 0, chits = 0;
43 int crew[3];
44 int load;
45 int guns, car, ready, shootat, hit;
46 int roll;
47 struct ship *closest;
49 crew[0] = mc->crew1;
50 crew[1] = mc->crew2;
51 crew[2] = mc->crew3;
52 for (n = 0; n < 3; n++) {
53 if (mf->OBP[n].turnsent)
54 men += mf->OBP[n].mensent;
56 for (n = 0; n < 3; n++) {
57 if (mf->DBP[n].turnsent)
58 men += mf->DBP[n].mensent;
60 if (men) {
61 crew[0] = men/100 ? 0 : crew[0] != 0;
62 crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
63 crew[2] = men%10 ? 0 : crew[2] != 0;
65 for (r = 0; r < 2; r++) {
66 if (r) {
67 ready = mf->readyR;
68 load = mf->loadR;
69 guns = mc->gunR;
70 car = mc->carR;
71 } else {
72 ready = mf->readyL;
73 load = mf->loadL;
74 guns = mc->gunL;
75 car = mc->carL;
77 if ((!guns && !car) || load == L_EMPTY ||
78 (ready & R_LOADED) == 0)
79 goto cant;
80 if (mf->struck || !crew[2])
81 goto cant;
82 closest = closestenemy(ms, (r ? 'r' : 'l'), 1);
83 if (closest == NULL)
84 goto cant;
85 if (closest->file->struck)
86 goto cant;
87 target = range(ms, closest);
88 if (target > rangeofshot[load] || (!guns && target >= 3))
89 goto cant;
90 Signal("%s (%c%c) within range of %s broadside.",
91 closest, r ? "right" : "left");
92 if (load > L_CHAIN && target < 6) {
93 switch (sgetch("Aim for hull or rigging? ",
94 NULL, 1)) {
95 case 'r':
96 shootat = RIGGING;
97 break;
98 case 'h':
99 shootat = HULL;
100 break;
101 default:
102 shootat = -1;
103 Signal("'Avast there! Hold your fire.'",
104 NULL);
106 } else {
107 if (sgetch("Fire? ", NULL, 1) == 'n') {
108 shootat = -1;
109 Signal("Belay that! Hold your fire.",
110 NULL);
111 } else
112 shootat = RIGGING;
114 if (shootat == -1)
115 continue;
116 fired = 1;
117 rakehim = gunsbear(ms, closest) && !gunsbear(closest, ms);
118 temp = portside(closest, ms, 1) - closest->file->dir + 1;
119 if (temp < 1)
120 temp += 8;
121 else if (temp > 8)
122 temp -= 8;
123 sternrake = temp > 4 && temp < 6;
124 if (rakehim) {
125 if (!sternrake)
126 Signal("Raking the %s!", closest);
127 else
128 Signal("Stern Rake! %s splintering!", closest);
130 idx = guns;
131 if (target < 3)
132 idx += car;
133 idx = (idx - 1)/3;
134 idx = idx > 8 ? 8 : idx;
135 if (!rakehim)
136 hit = HDT[idx][target-1];
137 else
138 hit = HDTrake[idx][target-1];
139 if (rakehim && sternrake)
140 hit++;
141 hit += QUAL[idx][mc->qual-1];
142 for (n = 0; n < 3 && mf->captured == 0; n++)
143 if (!crew[n]) {
144 if (idx <= 5)
145 hit--;
146 else
147 hit -= 2;
149 if (ready & R_INITIAL) {
150 if (idx <= 3)
151 hit++;
152 else
153 hit += 2;
155 if (mf->captured != 0) {
156 if (idx <= 1)
157 hit--;
158 else
159 hit -= 2;
161 hit += AMMO[idx][load - 1];
162 if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5)
163 hit--;
164 if (windspeed == 6 && temp == 4)
165 hit -= 2;
166 if (windspeed == 6 && temp <= 3)
167 hit--;
168 if (hit >= 0) {
169 roll = die();
170 if (load == L_GRAPE)
171 chits = hit;
172 else {
173 struct Tables *t;
174 if (hit > 10)
175 hit = 10;
176 t = &(shootat == RIGGING ? RigTable : HullTable)
177 [hit][roll-1];
178 chits = t->C;
179 rhits = t->R;
180 hhits = t->H;
181 ghits = t->G;
182 if (closest->file->FS)
183 rhits *= 2;
184 if (load == L_CHAIN) {
185 ghits = 0;
186 hhits = 0;
189 table(shootat, load, hit, closest, ms, roll);
191 Signal("Damage inflicted on the %s:",
192 NULL, closest->shipname);
193 Signal("\t%d HULL, %d GUNS, %d CREW, %d RIGGING",
194 NULL, hhits, ghits, chits, rhits);
195 if (!r) {
196 mf->loadL = L_EMPTY;
197 mf->readyL = R_EMPTY;
198 } else {
199 mf->loadR = L_EMPTY;
200 mf->readyR = R_EMPTY;
202 continue;
203 cant:
204 Signal("Unable to fire %s broadside",
205 NULL, r ? "right" : "left");
207 blockalarm();
208 draw_stat();
209 unblockalarm();
212 void
213 grapungrap(void)
215 struct ship *sp;
216 int i;
218 foreachship(sp) {
219 if (sp == ms || sp->file->dir == 0)
220 continue;
221 if (range(ms, sp) > 1 && !grappled2(ms, sp))
222 continue;
223 switch (sgetch("Attempt to grapple or ungrapple %s (%c%c): ",
224 sp, 1)) {
225 case 'g':
226 if (die() < 3
227 || ms->nationality == capship(sp)->nationality) {
228 Write(W_GRAP, ms, sp->file->index, 0, 0, 0);
229 Write(W_GRAP, sp, player, 0, 0, 0);
230 Signal("Attempt succeeds!", NULL);
231 makesignal(ms, "grappled with %s (%c%c)", sp);
232 } else
233 Signal("Attempt fails.", NULL);
234 break;
235 case 'u':
236 for (i = grappled2(ms, sp); --i >= 0;) {
237 if (ms->nationality
238 == capship(sp)->nationality
239 || die() < 3) {
240 cleangrapple(ms, sp, 0);
241 Signal("Attempt succeeds!",
242 NULL);
243 makesignal(ms,
244 "ungrappling with %s (%c%c)",
245 sp);
246 } else
247 Signal("Attempt fails.",
248 NULL);
250 break;
255 void
256 unfoulplayer(void)
258 struct ship *to;
259 int i;
261 foreachship(to) {
262 if (fouled2(ms, to) == 0)
263 continue;
264 if (sgetch("Attempt to unfoul with the %s (%c%c)? ", to, 1) != 'y')
265 continue;
266 for (i = fouled2(ms, to); --i >= 0;) {
267 if (die() <= 2) {
268 cleanfoul(ms, to, 0);
269 Signal("Attempt succeeds!", NULL);
270 makesignal(ms, "Unfouling %s (%c%c)", to);
271 } else
272 Signal("Attempt fails.", NULL);