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