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