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