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