1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)torped.c 5.2 (Berkeley) 05/05/88"; 15 #endif /* not lint */ 16 17 # include <stdio.h> 18 # include "trek.h" 19 20 /* 21 ** PHOTON TORPEDO CONTROL 22 ** 23 ** Either one or three photon torpedoes are fired. If three 24 ** are fired, it is called a "burst" and you also specify 25 ** a spread angle. 26 ** 27 ** Torpedoes are never 100% accurate. There is always a random 28 ** cludge factor in their course which is increased if you have 29 ** your shields up. Hence, you will find that they are more 30 ** accurate at close range. However, they have the advantage that 31 ** at long range they don't lose any of their power as phasers 32 ** do, i.e., a hit is a hit is a hit, by any other name. 33 ** 34 ** When the course spreads too much, you get a misfire, and the 35 ** course is randomized even more. You also have the chance that 36 ** the misfire damages your torpedo tubes. 37 */ 38 39 40 torped() 41 { 42 register int ix, iy; 43 double x, y, dx, dy; 44 double angle; 45 int course, course2; 46 register int k; 47 double bigger; 48 double sectsize; 49 int burst; 50 int n; 51 52 if (Ship.cloaked) 53 { 54 return (printf("Federation regulations do not permit attack while cloaked.\n")); 55 } 56 if (check_out(TORPED)) 57 return; 58 if (Ship.torped <= 0) 59 { 60 return (printf("All photon torpedos expended\n")); 61 } 62 63 /* get the course */ 64 course = getintpar("Torpedo course"); 65 if (course < 0 || course > 360) 66 return; 67 burst = -1; 68 69 /* need at least three torpedoes for a burst */ 70 if (Ship.torped < 3) 71 { 72 printf("No-burst mode selected\n"); 73 burst = 0; 74 } 75 else 76 { 77 /* see if the user wants one */ 78 if (!testnl()) 79 { 80 k = ungetc(cgetc(0), stdin); 81 if (k >= '0' && k <= '9') 82 burst = 1; 83 } 84 } 85 if (burst < 0) 86 { 87 burst = getynpar("Do you want a burst"); 88 } 89 if (burst) 90 { 91 burst = getintpar("burst angle"); 92 if (burst <= 0) 93 return; 94 if (burst > 15) 95 return (printf("Maximum burst angle is 15 degrees\n")); 96 } 97 sectsize = NSECTS; 98 n = -1; 99 if (burst) 100 { 101 n = 1; 102 course -= burst; 103 } 104 for (; n && n <= 3; n++) 105 { 106 /* select a nice random course */ 107 course2 = course + randcourse(n); 108 angle = course2 * 0.0174532925; /* convert to radians */ 109 dx = -cos(angle); 110 dy = sin(angle); 111 bigger = fabs(dx); 112 x = fabs(dy); 113 if (x > bigger) 114 bigger = x; 115 dx /= bigger; 116 dy /= bigger; 117 x = Ship.sectx + 0.5; 118 y = Ship.secty + 0.5; 119 if (Ship.cond != DOCKED) 120 Ship.torped -= 1; 121 printf("Torpedo track"); 122 if (n > 0) 123 printf(", torpedo number %d", n); 124 printf(":\n%6.1f\t%4.1f\n", x, y); 125 while (1) 126 { 127 ix = x += dx; 128 iy = y += dy; 129 if (x < 0.0 || x >= sectsize || y < 0.0 || y >= sectsize) 130 { 131 printf("Torpedo missed\n"); 132 break; 133 } 134 printf("%6.1f\t%4.1f\n", x, y); 135 switch (Sect[ix][iy]) 136 { 137 case EMPTY: 138 continue; 139 140 case HOLE: 141 printf("Torpedo disappears into a black hole\n"); 142 break; 143 144 case KLINGON: 145 for (k = 0; k < Etc.nkling; k++) 146 { 147 if (Etc.klingon[k].x != ix || Etc.klingon[k].y != iy) 148 continue; 149 Etc.klingon[k].power -= 500 + ranf(501); 150 if (Etc.klingon[k].power > 0) 151 { 152 printf("*** Hit on Klingon at %d,%d: extensive damages\n", 153 ix, iy); 154 break; 155 } 156 killk(ix, iy); 157 break; 158 } 159 break; 160 161 case STAR: 162 nova(ix, iy); 163 break; 164 165 case INHABIT: 166 kills(ix, iy, -1); 167 break; 168 169 case BASE: 170 killb(Ship.quadx, Ship.quady); 171 Game.killb += 1; 172 break; 173 default: 174 printf("Unknown object %c at %d,%d destroyed\n", 175 Sect[ix][iy], ix, iy); 176 Sect[ix][iy] = EMPTY; 177 break; 178 } 179 break; 180 } 181 if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0) 182 break; 183 course += burst; 184 } 185 Move.free = 0; 186 } 187 188 189 /* 190 ** RANDOMIZE COURSE 191 ** 192 ** This routine randomizes the course for torpedo number 'n'. 193 ** Other things handled by this routine are misfires, damages 194 ** to the tubes, etc. 195 */ 196 197 randcourse(n) 198 int n; 199 { 200 double r; 201 register int d; 202 203 d = ((franf() + franf()) - 1.0) * 20; 204 if (abs(d) > 12) 205 { 206 printf("Photon tubes misfire"); 207 if (n < 0) 208 printf("\n"); 209 else 210 printf(" on torpedo %d\n", n); 211 if (ranf(2)) 212 { 213 damage(TORPED, 0.2 * abs(d) * (franf() + 1.0)); 214 } 215 d *= 1.0 + 2.0 * franf(); 216 } 217 if (Ship.shldup || Ship.cond == DOCKED) 218 { 219 r = Ship.shield; 220 r = 1.0 + r / Param.shield; 221 if (Ship.cond == DOCKED) 222 r = 2.0; 223 d *= r; 224 } 225 return (d); 226 } 227