Commit | Line | Data |
---|---|---|
9758240b KM |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
e9fb6bea KB |
3 | * All rights reserved. |
4 | * | |
b2e7427f | 5 | * %sccs.include.redist.c% |
9758240b KM |
6 | */ |
7 | ||
b4aa093a | 8 | #ifndef lint |
b2e7427f | 9 | static char sccsid[] = "@(#)torped.c 5.4 (Berkeley) %G%"; |
e9fb6bea | 10 | #endif /* not lint */ |
b4aa093a | 11 | |
06d69904 | 12 | # include <stdio.h> |
b4aa093a KM |
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 | { | |
06d69904 | 75 | k = ungetc(cgetc(0), stdin); |
b4aa093a KM |
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; | |
35b95499 | 97 | course -= burst; |
b4aa093a KM |
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; | |
35b95499 KL |
110 | dx /= bigger; |
111 | dy /= bigger; | |
b4aa093a KM |
112 | x = Ship.sectx + 0.5; |
113 | y = Ship.secty + 0.5; | |
114 | if (Ship.cond != DOCKED) | |
35b95499 | 115 | Ship.torped -= 1; |
b4aa093a KM |
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 | { | |
35b95499 KL |
122 | ix = x += dx; |
123 | iy = y += dy; | |
b4aa093a KM |
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; | |
35b95499 | 144 | Etc.klingon[k].power -= 500 + ranf(501); |
b4aa093a KM |
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); | |
35b95499 | 166 | Game.killb += 1; |
b4aa093a KM |
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; | |
35b95499 | 178 | course += burst; |
b4aa093a KM |
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 | } | |
35b95499 | 210 | d *= 1.0 + 2.0 * franf(); |
b4aa093a KM |
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; | |
35b95499 | 218 | d *= r; |
b4aa093a KM |
219 | } |
220 | return (d); | |
221 | } |