1 /* $NetBSD: torped.c,v 1.14 2009/05/24 23:20:22 dholland Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 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. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)torped.c 8.1 (Berkeley) 5/31/93"; 36 #else 37 __RCSID("$NetBSD: torped.c,v 1.14 2009/05/24 23:20:22 dholland Exp $"); 38 #endif 39 #endif /* not lint */ 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <math.h> 44 #include "trek.h" 45 #include "getpar.h" 46 47 /* 48 ** PHOTON TORPEDO CONTROL 49 ** 50 ** Either one or three photon torpedoes are fired. If three 51 ** are fired, it is called a "burst" and you also specify 52 ** a spread angle. 53 ** 54 ** Torpedoes are never 100% accurate. There is always a random 55 ** cludge factor in their course which is increased if you have 56 ** your shields up. Hence, you will find that they are more 57 ** accurate at close range. However, they have the advantage that 58 ** at long range they don't lose any of their power as phasers 59 ** do, i.e., a hit is a hit is a hit, by any other name. 60 ** 61 ** When the course spreads too much, you get a misfire, and the 62 ** course is randomized even more. You also have the chance that 63 ** the misfire damages your torpedo tubes. 64 */ 65 66 static int randcourse(int); 67 68 /*ARGSUSED*/ 69 void 70 torped(int v __unused) 71 { 72 int ix, iy; 73 double x, y, dx, dy; 74 double angle; 75 int course, course2; 76 int k; 77 double bigger; 78 double sectsize; 79 int burst; 80 int n; 81 82 if (Ship.cloaked) { 83 printf("Federation regulations do not permit attack while " 84 "cloaked.\n"); 85 return; 86 } 87 if (check_out(TORPED)) 88 return; 89 if (Ship.torped <= 0) { 90 printf("All photon torpedos expended\n"); 91 return; 92 } 93 94 /* get the course */ 95 course = getintpar("Torpedo course"); 96 if (course < 0 || course > 360) 97 return; 98 burst = -1; 99 100 /* need at least three torpedoes for a burst */ 101 if (Ship.torped < 3) { 102 printf("No-burst mode selected\n"); 103 burst = 0; 104 } else { 105 /* see if the user wants one */ 106 if (!testnl()) { 107 k = ungetc(getchar(), stdin); 108 if (k >= '0' && k <= '9') 109 burst = 1; 110 } 111 } 112 if (burst < 0) { 113 burst = getynpar("Do you want a burst"); 114 } 115 if (burst) { 116 burst = getintpar("burst angle"); 117 if (burst <= 0) 118 return; 119 if (burst > 15) { 120 printf("Maximum burst angle is 15 degrees\n"); 121 return; 122 } 123 } 124 sectsize = NSECTS; 125 n = -1; 126 if (burst) { 127 n = 1; 128 course -= burst; 129 } 130 for (; n && n <= 3; n++) { 131 /* select a nice random course */ 132 course2 = course + randcourse(n); 133 /* convert to radians */ 134 angle = course2 * 0.0174532925; 135 dx = -cos(angle); 136 dy = sin(angle); 137 bigger = fabs(dx); 138 x = fabs(dy); 139 if (x > bigger) 140 bigger = x; 141 dx /= bigger; 142 dy /= bigger; 143 x = Ship.sectx + 0.5; 144 y = Ship.secty + 0.5; 145 if (Ship.cond != DOCKED) 146 Ship.torped -= 1; 147 printf("Torpedo track"); 148 if (n > 0) 149 printf(", torpedo number %d", n); 150 printf(":\n%6.1f\t%4.1f\n", x, y); 151 while (1) { 152 ix = x += dx; 153 iy = y += dy; 154 if (x < 0.0 || x >= sectsize || 155 y < 0.0 || y >= sectsize) { 156 printf("Torpedo missed\n"); 157 break; 158 } 159 printf("%6.1f\t%4.1f\n", x, y); 160 switch (Sect[ix][iy]) { 161 case EMPTY: 162 continue; 163 164 case HOLE: 165 printf("Torpedo disappears into a black " 166 "hole\n"); 167 break; 168 169 case KLINGON: 170 for (k = 0; k < Etc.nkling; k++) { 171 if (Etc.klingon[k].x != ix || 172 Etc.klingon[k].y != iy) 173 continue; 174 Etc.klingon[k].power -= 500 + ranf(501); 175 if (Etc.klingon[k].power > 0) { 176 printf("*** Hit on Klingon at " 177 "%d,%d: extensive " 178 "damages\n", 179 ix, iy); 180 break; 181 } 182 killk(ix, iy); 183 break; 184 } 185 break; 186 187 case STAR: 188 nova(ix, iy); 189 break; 190 191 case INHABIT: 192 kills(ix, iy, -1); 193 break; 194 195 case BASE: 196 killb(Ship.quadx, Ship.quady); 197 Game.killb += 1; 198 break; 199 200 default: 201 printf("Unknown object %c at %d,%d destroyed\n", 202 Sect[ix][iy], ix, iy); 203 Sect[ix][iy] = EMPTY; 204 break; 205 } 206 break; 207 } 208 if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0) 209 break; 210 course += burst; 211 } 212 Move.free = 0; 213 } 214 215 216 /* 217 ** RANDOMIZE COURSE 218 ** 219 ** This routine randomizes the course for torpedo number 'n'. 220 ** Other things handled by this routine are misfires, damages 221 ** to the tubes, etc. 222 */ 223 224 static int 225 randcourse(int n) 226 { 227 double r; 228 int d; 229 230 d = ((franf() + franf()) - 1.0) * 20; 231 if (abs(d) > 12) { 232 printf("Photon tubes misfire"); 233 if (n < 0) 234 printf("\n"); 235 else 236 printf(" on torpedo %d\n", n); 237 if (ranf(2)) { 238 damage(TORPED, 0.2 * abs(d) * (franf() + 1.0)); 239 } 240 d *= 1.0 + 2.0 * franf(); 241 } 242 if (Ship.shldup || Ship.cond == DOCKED) { 243 r = Ship.shield; 244 r = 1.0 + r / Param.shield; 245 if (Ship.cond == DOCKED) 246 r = 2.0; 247 d *= r; 248 } 249 return (d); 250 } 251