1 /* $OpenBSD: assorted.c,v 1.2 1999/01/18 06:20:51 pjanzen Exp $ */ 2 /* $NetBSD: assorted.c,v 1.3 1995/04/22 10:36:45 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)assorted.c 8.2 (Berkeley) 4/28/95"; 40 #else 41 static char rcsid[] = "$OpenBSD: assorted.c,v 1.2 1999/01/18 06:20:51 pjanzen Exp $"; 42 #endif 43 #endif /* not lint */ 44 45 #include "extern.h" 46 #include <sys/cdefs.h> 47 #include <stdlib.h> 48 #include <unistd.h> 49 #include <err.h> 50 51 static void strike __P((struct ship *, struct ship *)); 52 53 void 54 table(rig, shot, hittable, on, from, roll) 55 struct ship *on, *from; 56 int rig, shot, hittable, roll; 57 { 58 int hhits = 0, chits = 0, ghits = 0, rhits = 0; 59 int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; 60 int guns, car, pc, hull; 61 int crew[3]; 62 int n; 63 int rigg[4]; 64 const char *message; 65 const struct Tables *tp; 66 67 pc = on->file->pcrew; 68 hull = on->specs->hull; 69 crew[0] = on->specs->crew1; 70 crew[1] = on->specs->crew2; 71 crew[2] = on->specs->crew3; 72 rigg[0] = on->specs->rig1; 73 rigg[1] = on->specs->rig2; 74 rigg[2] = on->specs->rig3; 75 rigg[3] = on->specs->rig4; 76 if (shot == L_GRAPE) 77 Chit = chits = hittable; 78 else { 79 tp = &(rig ? RigTable : HullTable)[hittable][roll-1]; 80 Chit = chits = tp->C; 81 Rhit = rhits = tp->R; 82 Hhit = hhits = tp->H; 83 Ghit = ghits = tp->G; 84 if (on->file->FS) 85 rhits *= 2; 86 if (shot == L_CHAIN) { 87 Ghit = ghits = 0; 88 Hhit = hhits = 0; 89 } 90 } 91 if (on->file->captured != 0) { 92 pc -= (chits + 1) / 2; 93 chits /= 2; 94 } 95 for (n = 0; n < 3; n++) 96 if (chits > crew[n]) { 97 chits -= crew[n]; 98 crew[n] = 0; 99 } else { 100 crew[n] -= chits; 101 chits = 0; 102 } 103 for (n = 0; n < 3; n++) 104 if (rhits > rigg[n]){ 105 rhits -= rigg[n]; 106 rigg[n] = 0; 107 } else { 108 rigg[n] -= rhits; 109 rhits = 0; 110 } 111 if (rigg[3] != -1 && rhits > rigg[3]) { 112 rhits -= rigg[3]; 113 rigg[3] = 0; 114 } else if (rigg[3] != -1) { 115 rigg[3] -= rhits; 116 } 117 if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1)) 118 makemsg(on, "dismasted!"); 119 if (portside(from, on, 0)) { 120 guns = on->specs->gunR; 121 car = on->specs->carR; 122 } else { 123 guns = on->specs->gunL; 124 car = on->specs->carL; 125 } 126 if (ghits > car) { 127 ghits -= car; 128 car = 0; 129 } else { 130 car -= ghits; 131 ghits = 0; 132 } 133 if (ghits > guns){ 134 ghits -= guns; 135 guns = 0; 136 } else { 137 guns -= ghits; 138 ghits = 0; 139 } 140 hull -= ghits; 141 if (Ghit) 142 Write(portside(from, on, 0) ? W_GUNR : W_GUNL, 143 on, guns, car, 0, 0); 144 hull -= hhits; 145 hull = hull < 0 ? 0 : hull; 146 if (on->file->captured != 0 && Chit) 147 Write(W_PCREW, on, pc, 0, 0, 0); 148 if (Hhit) 149 Write(W_HULL, on, hull, 0, 0, 0); 150 if (Chit) 151 Write(W_CREW, on, crew[0], crew[1], crew[2], 0); 152 if (Rhit) 153 Write(W_RIGG, on, rigg[0], rigg[1], rigg[2], rigg[3]); 154 switch (shot) { 155 case L_ROUND: 156 message = "firing round shot on $$"; 157 break; 158 case L_GRAPE: 159 message = "firing grape shot on $$"; 160 break; 161 case L_CHAIN: 162 message = "firing chain shot on $$"; 163 break; 164 case L_DOUBLE: 165 message = "firing double shot on $$"; 166 break; 167 case L_EXPLODE: 168 message = "exploding shot on $$"; 169 break; 170 default: 171 errx(1, "Unknown shot type %d", shot); 172 } 173 makesignal(from, message, on); 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, 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 Write(W_TA, on, 0, 0, 0, 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, message); 229 } 230 /* 231 if (Chit > 1 && on->file->readyL&R_INITIAL && on->file->readyR&R_INITIAL) { 232 on->specs->qual--; 233 if (on->specs->qual <= 0) { 234 makemsg(on, "crew mutinying!"); 235 on->specs->qual = 5; 236 Write(W_CAPTURED, on, on->file->index, 0, 0, 0); 237 } else 238 makemsg(on, "crew demoralized"); 239 Write(W_QUAL, on, on->specs->qual, 0, 0, 0); 240 } 241 */ 242 if (!hull) 243 strike(on, from); 244 } 245 246 void 247 Cleansnag(from, to, all, flag) 248 struct ship *from, *to; 249 char all, flag; 250 { 251 if (flag & 1) { 252 Write(W_UNGRAP, from, to->file->index, all, 0, 0); 253 Write(W_UNGRAP, to, from->file->index, all, 0, 0); 254 } 255 if (flag & 2) { 256 Write(W_UNFOUL, from, to->file->index, all, 0, 0); 257 Write(W_UNFOUL, to, from->file->index, all, 0, 0); 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(ship, from) 275 struct ship *ship, *from; 276 { 277 int points; 278 279 if (ship->file->struck) 280 return; 281 Write(W_STRUCK, ship, 1, 0, 0, 0); 282 points = ship->specs->pts + from->file->points; 283 Write(W_POINTS, from, points, 0, 0, 0); 284 unboard(ship, ship, 0); /* all offense */ 285 unboard(ship, ship, 1); /* all defense */ 286 switch (die()) { 287 case 3: 288 case 4: /* ship may sink */ 289 Write(W_SINK, ship, 1, 0, 0, 0); 290 break; 291 case 5: 292 case 6: /* ship may explode */ 293 Write(W_EXPLODE, ship, 1, 0, 0, 0); 294 break; 295 } 296 Writestr(W_SIGNAL, ship, "striking her colours!"); 297 } 298