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