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