1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: #include <sys/cdefs.h>
33: #ifndef lint
34: #if 0
35: static char sccsid[] = "@(#)pl_3.c 8.1 (Berkeley) 5/31/93";
36: #else
37: __RCSID("$NetBSD: pl_3.c,v 1.17 2003/08/07 09:37:43 agc Exp $");
38: #endif
39: #endif
40:
41: #include <signal.h>
42: #include <stdlib.h>
43: #include "extern.h"
44: #include "player.h"
45:
46: void
47: acceptcombat(void)
48: {
49: int men = 0;
50: int target, temp;
51: int n, r;
52: int index, rakehim, sternrake;
53: int hhits = 0, ghits = 0, rhits = 0, chits = 0;
54: int crew[3];
55: int load;
56: int guns, car, ready, shootat, hit;
57: int roll;
58: struct ship *closest;
59:
60: crew[0] = mc->crew1;
61: crew[1] = mc->crew2;
62: crew[2] = mc->crew3;
63: for (n = 0; n < 3; n++) {
64: if (mf->OBP[n].turnsent)
65: men += mf->OBP[n].mensent;
66: }
67: for (n = 0; n < 3; n++) {
68: if (mf->DBP[n].turnsent)
69: men += mf->DBP[n].mensent;
70: }
71: if (men) {
72: crew[0] = men/100 ? 0 : crew[0] != 0;
73: crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
74: crew[2] = men%10 ? 0 : crew[2] != 0;
75: }
76: for (r = 0; r < 2; r++) {
77: if (r) {
78: ready = mf->readyR;
79: load = mf->loadR;
80: guns = mc->gunR;
81: car = mc->carR;
82: } else {
83: ready = mf->readyL;
84: load = mf->loadL;
85: guns = mc->gunL;
86: car = mc->carL;
87: }
88: if ((!guns && !car) || load == L_EMPTY || (ready & R_LOADED) == 0)
89: goto cant;
90: if (mf->struck || !crew[2])
91: goto cant;
92: closest = closestenemy(ms, (r ? 'r' : 'l'), 1);
93: if (closest == 0)
94: goto cant;
95: if (closest->file->struck)
96: goto cant;
97: target = range(ms, closest);
98: if (target > rangeofshot[load] || (!guns && target >= 3))
99: goto cant;
100: Signal("$$ within range of %s broadside.",
101: closest, r ? "right" : "left");
102: if (load > L_CHAIN && target < 6) {
103: switch (sgetch("Aim for hull or rigging? ",
104: (struct ship *)0, 1)) {
105: case 'r':
106: shootat = RIGGING;
107: break;
108: case 'h':
109: shootat = HULL;
110: break;
111: default:
112: shootat = -1;
113: Msg("'Avast there! Hold your fire.'");
114: }
115: } else {
116: if (sgetch("Fire? ", (struct ship *)0, 1) == 'n') {
117: shootat = -1;
118: Msg("Belay that! Hold your fire.");
119: } else
120: shootat = RIGGING;
121: }
122: if (shootat == -1)
123: continue;
124: fired = 1;
125: rakehim = gunsbear(ms, closest) && !gunsbear(closest, ms);
126: temp = portside(closest, ms, 1) - closest->file->dir + 1;
127: if (temp < 1)
128: temp += 8;
129: else if (temp > 8)
130: temp -= 8;
131: sternrake = temp > 4 && temp < 6;
132: if (rakehim) {
133: if (!sternrake)
134: Msg("Raking the %s!", closest->shipname);
135: else
136: Msg("Stern Rake! %s splintering!",
137: closest->shipname);
138: }
139: index = guns;
140: if (target < 3)
141: index += car;
142: index = (index - 1)/3;
143: index = index > 8 ? 8 : index;
144: if (!rakehim)
145: hit = HDT[index][target-1];
146: else
147: hit = HDTrake[index][target-1];
148: if (rakehim && sternrake)
149: hit++;
150: hit += QUAL[index][mc->qual-1];
151: for (n = 0; n < 3 && mf->captured == 0; n++)
152: if (!crew[n]) {
153: if (index <= 5)
154: hit--;
155: else
156: hit -= 2;
157: }
158: if (ready & R_INITIAL) {
159: if (index <= 3)
160: hit++;
161: else
162: hit += 2;
163: }
164: if (mf->captured != 0) {
165: if (index <= 1)
166: hit--;
167: else
168: hit -= 2;
169: }
170: hit += AMMO[index][load - 1];
171: if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5)
172: hit--;
173: if (windspeed == 6 && temp == 4)
174: hit -= 2;
175: if (windspeed == 6 && temp <= 3)
176: hit--;
177: if (hit >= 0) {
178: roll = dieroll();
179: if (load == L_GRAPE)
180: chits = hit;
181: else {
182: const struct Tables *t;
183: if (hit > 10)
184: hit = 10;
185: t = &(shootat == RIGGING ? RigTable : HullTable)
186: [hit][roll-1];
187: chits = t->C;
188: rhits = t->R;
189: hhits = t->H;
190: ghits = t->G;
191: if (closest->file->FS)
192: rhits *= 2;
193: if (load == L_CHAIN) {
194: ghits = 0;
195: hhits = 0;
196: }
197: }
198: table(ms, closest, shootat, load, hit, roll);
199: }
200: Msg("Damage inflicted on the %s:", closest->shipname);
201: Msg("\t%d HULL, %d GUNS, %d CREW, %d RIGGING",
202: hhits, ghits, chits, rhits);
203: if (!r) {
204: mf->loadL = L_EMPTY;
205: mf->readyL = R_EMPTY;
206: } else {
207: mf->loadR = L_EMPTY;
208: mf->readyR = R_EMPTY;
209: }
210: continue;
211: cant:
212: Msg("Unable to fire %s broadside", r ? "right" : "left");
213: }
214: blockalarm();
215: draw_stat();
216: unblockalarm();
217: }
218:
219: void
220: grapungrap(void)
221: {
222: struct ship *sp;
223: int i;
224:
225: foreachship(sp) {
226: if (sp == ms || sp->file->dir == 0)
227: continue;
228: if (range(ms, sp) > 1 && !grappled2(ms, sp))
229: continue;
230: switch (sgetch("Attempt to grapple or ungrapple $$: ",
231: sp, 1)) {
232: case 'g':
233: if (dieroll() < 3
234: || ms->nationality == capship(sp)->nationality) {
235: Write(W_GRAP, ms, sp->file->index, 0, 0, 0);
236: Write(W_GRAP, sp, player, 0, 0, 0);
237: Msg("Attempt succeeds!");
238: makesignal(ms, "grappled with $$", sp);
239: } else
240: Msg("Attempt fails.");
241: break;
242: case 'u':
243: for (i = grappled2(ms, sp); --i >= 0;) {
244: if (ms->nationality
245: == capship(sp)->nationality
246: || dieroll() < 3) {
247: cleangrapple(ms, sp, 0);
248: Msg("Attempt succeeds!");
249: makesignal(ms, "ungrappling with $$",
250: sp);
251: } else
252: Msg("Attempt fails.");
253: }
254: break;
255: }
256: }
257: }
258:
259: void
260: unfoulplayer(void)
261: {
262: struct ship *to;
263: int i;
264:
265: foreachship(to) {
266: if (fouled2(ms, to) == 0)
267: continue;
268: if (sgetch("Attempt to unfoul with the $$? ", to, 1) != 'y')
269: continue;
270: for (i = fouled2(ms, to); --i >= 0;) {
271: if (dieroll() <= 2) {
272: cleanfoul(ms, to, 0);
273: Msg("Attempt succeeds!");
274: makesignal(ms, "Unfouling $$", to);
275: } else
276: Msg("Attempt fails.");
277: }
278: }
279: }