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