1 /*- 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)assorted.c 8.1 (Berkeley) 5/31/93 30 * $FreeBSD: src/games/sail/assorted.c,v 1.5 1999/11/30 03:49:31 billf Exp $ 31 * $DragonFly: src/games/sail/assorted.c,v 1.3 2006/09/03 17:33:13 pavalos Exp $ 32 */ 33 34 #include "externs.h" 35 36 static void strike(struct ship *, struct ship *); 37 38 void 39 table(int rig, int shot, int hittable, 40 struct ship *on, struct ship *from, int roll) 41 { 42 int hhits = 0, chits = 0, ghits = 0, rhits = 0; 43 int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0; 44 int guns, car, pc, hull; 45 int crew[3]; 46 int n; 47 int rigg[4]; 48 const char *message = NULL; 49 struct Tables *tp; 50 51 pc = on->file->pcrew; 52 hull = on->specs->hull; 53 crew[0] = on->specs->crew1; 54 crew[1] = on->specs->crew2; 55 crew[2] = on->specs->crew3; 56 rigg[0] = on->specs->rig1; 57 rigg[1] = on->specs->rig2; 58 rigg[2] = on->specs->rig3; 59 rigg[3] = on->specs->rig4; 60 if (shot == L_GRAPE) { 61 Chit = chits = hittable; 62 } else { 63 tp = &(rig ? RigTable : HullTable)[hittable][roll-1]; 64 Chit = chits = tp->C; 65 Rhit = rhits = tp->R; 66 Hhit = hhits = tp->H; 67 Ghit = ghits = tp->G; 68 if (on->file->FS) 69 rhits *= 2; 70 if (shot == L_CHAIN) { 71 Ghit = ghits = 0; 72 Hhit = hhits = 0; 73 } 74 } 75 if (on->file->captured != 0) { 76 pc -= (chits + 1) / 2; 77 chits /= 2; 78 } 79 for (n = 0; n < 3; n++) { 80 if (chits > crew[n]) { 81 chits -= crew[n]; 82 crew[n] = 0; 83 } else { 84 crew[n] -= chits; 85 chits = 0; 86 } 87 } 88 for (n = 0; n < 3; n++) { 89 if (rhits > rigg[n]) { 90 rhits -= rigg[n]; 91 rigg[n] = 0; 92 } else { 93 rigg[n] -= rhits; 94 rhits = 0; 95 } 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 makesignal(on, "dismasted!", NULL); 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 %s (%c%c)"; 143 break; 144 case L_GRAPE: 145 message = "firing grape shot on %s (%c%c)"; 146 break; 147 case L_CHAIN: 148 message = "firing chain shot on %s (%c%c)"; 149 break; 150 case L_DOUBLE: 151 message = "firing double shot on %s (%c%c)"; 152 break; 153 case L_EXPLODE: 154 message = "exploding shot on %s (%c%c)"; 155 } 156 makesignal(from, message, on); 157 if (roll == 6 && rig) { 158 switch(Rhit) { 159 case 0: 160 message = "fore topsail sheets parted"; 161 break; 162 case 1: 163 message = "mizzen shrouds parted"; 164 break; 165 case 2: 166 message = "main topsail yard shot away"; 167 break; 168 case 4: 169 message = "fore topmast and foremast shrouds shot away"; 170 break; 171 case 5: 172 message = "mizzen mast and yard shot through"; 173 break; 174 case 6: 175 message = "foremast and spritsail yard shattered"; 176 break; 177 case 7: 178 message = "main topmast and mizzen mast shattered"; 179 break; 180 } 181 makesignal(on, message, NULL); 182 } else if (roll == 6) { 183 switch (Hhit) { 184 case 0: 185 message = "anchor cables severed"; 186 break; 187 case 1: 188 message = "two anchor stocks shot away"; 189 break; 190 case 2: 191 message = "quarterdeck bulwarks damaged"; 192 break; 193 case 3: 194 message = "three gun ports shot away"; 195 break; 196 case 4: 197 message = "four guns dismounted"; 198 break; 199 case 5: 200 message = "rudder cables shot through"; 201 Write(W_TA, on, 0, 0, 0, 0); 202 break; 203 case 6: 204 message = "shot holes below the water line"; 205 break; 206 } 207 makesignal(on, message, NULL); 208 } 209 if (!hull) 210 strike(on, from); 211 } 212 213 void 214 Cleansnag(struct ship *from, struct ship *to, char all, char flag) 215 { 216 if (flag & 1) { 217 Write(W_UNGRAP, from, to->file->index, all, 0, 0); 218 Write(W_UNGRAP, to, from->file->index, all, 0, 0); 219 } 220 if (flag & 2) { 221 Write(W_UNFOUL, from, to->file->index, all, 0, 0); 222 Write(W_UNFOUL, to, from->file->index, all, 0, 0); 223 } 224 if (!snagged2(from, to)) { 225 if (!snagged(from)) { 226 unboard(from, from, 1); /* defense */ 227 unboard(from, from, 0); /* defense */ 228 } else 229 unboard(from, to, 0); /* offense */ 230 if (!snagged(to)) { 231 unboard(to, to, 1); /* defense */ 232 unboard(to, to, 0); /* defense */ 233 } else 234 unboard(to, from, 0); /* offense */ 235 } 236 } 237 238 static void 239 strike(struct ship *ship, struct ship *from) 240 { 241 int points; 242 243 if (ship->file->struck) 244 return; 245 Write(W_STRUCK, ship, 1, 0, 0, 0); 246 points = ship->specs->pts + from->file->points; 247 Write(W_POINTS, from, points, 0, 0, 0); 248 unboard(ship, ship, 0); /* all offense */ 249 unboard(ship, ship, 1); /* all defense */ 250 switch (die()) { 251 case 3: 252 case 4: /* ship may sink */ 253 Write(W_SINK, ship, 1, 0, 0, 0); 254 break; 255 case 5: 256 case 6: /* ship may explode */ 257 Write(W_EXPLODE, ship, 1, 0, 0, 0); 258 break; 259 } 260 Writestr(W_SIGNAL, ship, "striking her colours!"); 261 } 262