1 /* $NetBSD: assorted.c,v 1.6 1997/10/13 21:02:57 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.6 1997/10/13 21:02:57 christos Exp $"); 42 #endif 43 #endif /* not lint */ 44 45 #include "extern.h" 46 #include <stdlib.h> 47 #include <unistd.h> 48 #include <err.h> 49 50 static void strike __P((struct ship *, struct ship *)); 51 52 void 53 table(rig, shot, hittable, on, from, roll) 54 struct ship *on, *from; 55 int rig, shot, hittable, roll; 56 { 57 int hhits = 0, chits = 0, ghits = 0, rhits = 0; 58 int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; 59 int guns, car, pc, hull; 60 int crew[3]; 61 int n; 62 int rigg[4]; 63 char *message; 64 struct Tables *tp; 65 66 pc = on->file->pcrew; 67 hull = on->specs->hull; 68 crew[0] = on->specs->crew1; 69 crew[1] = on->specs->crew2; 70 crew[2] = on->specs->crew3; 71 rigg[0] = on->specs->rig1; 72 rigg[1] = on->specs->rig2; 73 rigg[2] = on->specs->rig3; 74 rigg[3] = on->specs->rig4; 75 if (shot == L_GRAPE) 76 Chit = chits = hittable; 77 else { 78 tp = &(rig ? RigTable : HullTable)[hittable][roll-1]; 79 Chit = chits = tp->C; 80 Rhit = rhits = tp->R; 81 Hhit = hhits = tp->H; 82 Ghit = ghits = tp->G; 83 if (on->file->FS) 84 rhits *= 2; 85 if (shot == L_CHAIN) { 86 Ghit = ghits = 0; 87 Hhit = hhits = 0; 88 } 89 } 90 if (on->file->captured != 0) { 91 pc -= (chits + 1) / 2; 92 chits /= 2; 93 } 94 for (n = 0; n < 3; n++) 95 if (chits > crew[n]) { 96 chits -= crew[n]; 97 crew[n] = 0; 98 } else { 99 crew[n] -= chits; 100 chits = 0; 101 } 102 for (n = 0; n < 3; n++) 103 if (rhits > rigg[n]){ 104 rhits -= rigg[n]; 105 rigg[n] = 0; 106 } else { 107 rigg[n] -= rhits; 108 rhits = 0; 109 } 110 if (rigg[3] != -1 && rhits > rigg[3]) { 111 rhits -= rigg[3]; 112 rigg[3] = 0; 113 } else if (rigg[3] != -1) { 114 rigg[3] -= rhits; 115 } 116 if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1)) 117 makemsg(on, "dismasted!"); 118 if (portside(from, on, 0)) { 119 guns = on->specs->gunR; 120 car = on->specs->carR; 121 } else { 122 guns = on->specs->gunL; 123 car = on->specs->carL; 124 } 125 if (ghits > car) { 126 ghits -= car; 127 car = 0; 128 } else { 129 car -= ghits; 130 ghits = 0; 131 } 132 if (ghits > guns){ 133 ghits -= guns; 134 guns = 0; 135 } else { 136 guns -= ghits; 137 ghits = 0; 138 } 139 hull -= ghits; 140 if (Ghit) 141 Write(portside(from, on, 0) ? W_GUNR : W_GUNL, 142 on, 0, guns, car, 0, 0); 143 hull -= hhits; 144 hull = hull < 0 ? 0 : hull; 145 if (on->file->captured != 0 && Chit) 146 Write(W_PCREW, on, 0, pc, 0, 0, 0); 147 if (Hhit) 148 Write(W_HULL, on, 0, hull, 0, 0, 0); 149 if (Chit) 150 Write(W_CREW, on, 0, crew[0], crew[1], crew[2], 0); 151 if (Rhit) 152 Write(W_RIGG, on, 0, rigg[0], rigg[1], rigg[2], rigg[3]); 153 switch (shot) { 154 case L_ROUND: 155 message = "firing round shot on $$"; 156 break; 157 case L_GRAPE: 158 message = "firing grape shot on $$"; 159 break; 160 case L_CHAIN: 161 message = "firing chain shot on $$"; 162 break; 163 case L_DOUBLE: 164 message = "firing double shot on $$"; 165 break; 166 case L_EXPLODE: 167 message = "exploding shot on $$"; 168 break; 169 default: 170 errx(1, "Unknown shot type %d", shot); 171 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, 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, 0, on->file->index, 0, 0, 0); 237 } else 238 makemsg(on, "crew demoralized"); 239 Write(W_QUAL, on, 0, 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, 0, to->file->index, all, 0, 0); 253 Write(W_UNGRAP, to, 0, from->file->index, all, 0, 0); 254 } 255 if (flag & 2) { 256 Write(W_UNFOUL, from, 0, to->file->index, all, 0, 0); 257 Write(W_UNFOUL, to, 0, 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, 0, 1, 0, 0, 0); 282 points = ship->specs->pts + from->file->points; 283 Write(W_POINTS, from, 0, 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, 0, 1, 0, 0, 0); 290 break; 291 case 5: 292 case 6: /* ship may explode */ 293 Write(W_EXPLODE, ship, 0, 1, 0, 0, 0); 294 break; 295 } 296 Write(W_SIGNAL, ship, 1, (int) "striking her colours!", 0, 0, 0); 297 } 298