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