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