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