1 /* $NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)assorted.c 8.2 (Berkeley) 4/28/95"; 36 #else 37 __RCSID("$NetBSD: assorted.c,v 1.19 2011/08/16 11:26:16 christos Exp $"); 38 #endif 39 #endif /* not lint */ 40 41 #include <stdlib.h> 42 #include <err.h> 43 #include "extern.h" 44 45 static void strike(struct ship *, struct ship *); 46 47 void 48 table(struct ship *from, struct ship *on, 49 int rig, int shot, int hittable, int roll) 50 { 51 int hhits = 0, chits = 0, ghits = 0, rhits = 0; 52 int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; 53 int guns, car, pc, hull; 54 int crew[3]; 55 int n; 56 int rigg[4]; 57 const char *message; 58 const struct Tables *tp; 59 60 pc = on->file->pcrew; 61 hull = on->specs->hull; 62 crew[0] = on->specs->crew1; 63 crew[1] = on->specs->crew2; 64 crew[2] = on->specs->crew3; 65 rigg[0] = on->specs->rig1; 66 rigg[1] = on->specs->rig2; 67 rigg[2] = on->specs->rig3; 68 rigg[3] = on->specs->rig4; 69 if (shot == L_GRAPE) { 70 Chit = chits = hittable; 71 } else { 72 tp = &(rig ? RigTable : HullTable)[hittable][roll-1]; 73 Chit = chits = tp->C; 74 Rhit = rhits = tp->R; 75 Hhit = hhits = tp->H; 76 Ghit = ghits = tp->G; 77 if (on->file->FS) 78 rhits *= 2; 79 if (shot == L_CHAIN) { 80 Ghit = ghits = 0; 81 Hhit = hhits = 0; 82 } 83 } 84 if (on->file->captured != 0) { 85 pc -= (chits + 1) / 2; 86 chits /= 2; 87 } 88 for (n = 0; n < 3; n++) { 89 if (chits > crew[n]) { 90 chits -= crew[n]; 91 crew[n] = 0; 92 } else { 93 crew[n] -= chits; 94 chits = 0; 95 } 96 } 97 for (n = 0; n < 3; n++) { 98 if (rhits > rigg[n]) { 99 rhits -= rigg[n]; 100 rigg[n] = 0; 101 } else { 102 rigg[n] -= rhits; 103 rhits = 0; 104 } 105 } 106 if (rigg[3] != -1 && rhits > rigg[3]) { 107 rhits -= rigg[3]; 108 rigg[3] = 0; 109 } else if (rigg[3] != -1) { 110 rigg[3] -= rhits; 111 } 112 if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1)) 113 makemsg(on, "dismasted!"); 114 if (portside(from, on, 0)) { 115 guns = on->specs->gunR; 116 car = on->specs->carR; 117 } else { 118 guns = on->specs->gunL; 119 car = on->specs->carL; 120 } 121 if (ghits > car) { 122 ghits -= car; 123 car = 0; 124 } else { 125 car -= ghits; 126 ghits = 0; 127 } 128 if (ghits > guns) { 129 ghits -= guns; 130 guns = 0; 131 } else { 132 guns -= ghits; 133 ghits = 0; 134 } 135 hull -= ghits; 136 if (Ghit) { 137 if (portside(from, on, 0)) { 138 send_gunr(on, guns, car); 139 } else { 140 send_gunl(on, guns, car); 141 } 142 } 143 hull -= hhits; 144 hull = hull < 0 ? 0 : hull; 145 if (on->file->captured != 0 && Chit) 146 send_pcrew(on, pc); 147 if (Hhit) 148 send_hull(on, hull); 149 if (Chit) 150 send_crew(on, crew[0], crew[1], crew[2]); 151 if (Rhit) 152 send_rigg(on, rigg[0], rigg[1], rigg[2], rigg[3]); 153 switch (shot) { 154 case L_ROUND: 155 message = "firing round"; 156 break; 157 case L_GRAPE: 158 message = "firing grape"; 159 break; 160 case L_CHAIN: 161 message = "firing chain"; 162 break; 163 case L_DOUBLE: 164 message = "firing double"; 165 break; 166 case L_EXPLODE: 167 message = "exploding"; 168 break; 169 default: 170 errx(1, "Unknown shot type %d", shot); 171 172 } 173 makesignal(from, "%s shot on $$", on, message); 174 if (roll == 6 && rig) { 175 switch(Rhit) { 176 case 0: 177 message = "fore topsail sheets parted"; 178 break; 179 case 1: 180 message = "mizzen shrouds parted"; 181 break; 182 case 2: 183 message = "main topsail yard shot away"; 184 break; 185 case 4: 186 message = "fore topmast and foremast shrouds shot away"; 187 break; 188 case 5: 189 message = "mizzen mast and yard shot through"; 190 break; 191 case 6: 192 message = "foremast and spritsail yard shattered"; 193 break; 194 case 7: 195 message = "main topmast and mizzen mast shattered"; 196 break; 197 default: 198 errx(1, "Bad Rhit = %d", Rhit); 199 } 200 makemsg(on, "%s", message); 201 } else if (roll == 6) { 202 switch (Hhit) { 203 case 0: 204 message = "anchor cables severed"; 205 break; 206 case 1: 207 message = "two anchor stocks shot away"; 208 break; 209 case 2: 210 message = "quarterdeck bulwarks damaged"; 211 break; 212 case 3: 213 message = "three gun ports shot away"; 214 break; 215 case 4: 216 message = "four guns dismounted"; 217 break; 218 case 5: 219 message = "rudder cables shot through"; 220 send_ta(on, 0); 221 break; 222 case 6: 223 message = "shot holes below the water line"; 224 break; 225 default: 226 errx(1, "Bad Hhit = %d", Hhit); 227 } 228 makemsg(on, "%s", message); 229 } 230 /* 231 if (Chit > 1 && on->file->readyL & R_INITIAL && 232 on->file->readyR & R_INITIAL) { 233 on->specs->qual--; 234 if (on->specs->qual <= 0) { 235 makemsg(on, "crew mutinying!"); 236 on->specs->qual = 5; 237 Write(W_CAPTURED, on, on->file->index, 0, 0, 0); 238 } else { 239 makemsg(on, "crew demoralized"); 240 } 241 Write(W_QUAL, on, on->specs->qual, 0, 0, 0); 242 } 243 */ 244 if (!hull) 245 strike(on, from); 246 } 247 248 void 249 Cleansnag(struct ship *from, struct ship *to, int all, int flag) 250 { 251 if (flag & 1) { 252 send_ungrap(from, to->file->index, all); 253 send_ungrap(to, from->file->index, all); 254 } 255 if (flag & 2) { 256 send_unfoul(from, to->file->index, all); 257 send_unfoul(to, from->file->index, all); 258 } 259 if (!snagged2(from, to)) { 260 if (!snagged(from)) { 261 unboard(from, from, 1); /* defense */ 262 unboard(from, from, 0); /* defense */ 263 } else 264 unboard(from, to, 0); /* offense */ 265 if (!snagged(to)) { 266 unboard(to, to, 1); /* defense */ 267 unboard(to, to, 0); /* defense */ 268 } else 269 unboard(to, from, 0); /* offense */ 270 } 271 } 272 273 static void 274 strike(struct ship *ship, struct ship *from) 275 { 276 int points; 277 278 if (ship->file->struck) 279 return; 280 send_struck(ship, 1); 281 points = ship->specs->pts + from->file->points; 282 send_points(from, points); 283 unboard(ship, ship, 0); /* all offense */ 284 unboard(ship, ship, 1); /* all defense */ 285 switch (dieroll()) { 286 case 3: 287 case 4: /* ship may sink */ 288 send_sink(ship, 1); 289 break; 290 case 5: 291 case 6: /* ship may explode */ 292 send_explode(ship, 1); 293 break; 294 } 295 send_signal(ship, "striking her colours!"); 296 } 297