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