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