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