1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32: #include <sys/cdefs.h>
33: #ifndef lint
34: #if 0
35: static char sccsid[] = "@(#)phaser.c 8.1 (Berkeley) 5/31/93";
36: #else
37: __RCSID("$NetBSD: phaser.c,v 1.9 2003/08/07 09:37:53 agc Exp $");
38: #endif
39: #endif
40:
41: #include <stdio.h>
42: #include <math.h>
43: #include "trek.h"
44: #include "getpar.h"
45:
46:
47:
48: # define ALPHA 3.0
49: # define BETA 3.0
50: # define GAMMA 0.30
51: # define EPSILON 150.0
52: # define OMEGA 10.596
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79: struct cvntab Matab[] =
80: {
81: { "m", "anual", (cmdfun) 1, 0 },
82: { "a", "utomatic", (cmdfun) 0, 0 },
83: { NULL, NULL, NULL, 0 }
84: };
85:
86: struct banks
87: {
88: int units;
89: double angle;
90: double spread;
91: };
92:
93:
94:
95:
96: void
97: phaser(v)
98: int v __attribute__((__unused__));
99: {
100: int i;
101: int j;
102: struct kling *k;
103: double dx, dy;
104: double anglefactor, distfactor;
105: struct banks *b;
106: int manual, flag, extra = 0;
107: int hit;
108: double tot;
109: int n;
110: int hitreqd[NBANKS];
111: struct banks bank[NBANKS];
112: const struct cvntab *ptr;
113:
114: if (Ship.cond == DOCKED) {
115: printf("Phasers cannot fire through starbase shields\n");
116: return;
117: }
118: if (damaged(PHASER)) {
119: out(PHASER);
120: return;
121: }
122: if (Ship.shldup) {
123: printf("Sulu: Captain, we cannot fire through shields.\n");
124: return;
125: }
126: if (Ship.cloaked)
127: {
128: printf("Sulu: Captain, surely you must realize that we cannot fire\n");
129: printf(" phasers with the cloaking device up.\n");
130: return;
131: }
132:
133:
134: manual = 0;
135: if (testnl())
136: {
137: if (damaged(COMPUTER))
138: {
139: printf("%s", Device[COMPUTER].name);
140: manual++;
141: }
142: else
143: if (damaged(SRSCAN))
144: {
145: printf("%s", Device[SRSCAN].name);
146: manual++;
147: }
148: if (manual)
149: printf(" damaged, manual mode selected\n");
150: }
151:
152: if (!manual)
153: {
154: ptr = getcodpar("Manual or automatic", Matab);
155: manual = (long) ptr->value;
156: }
157: if (!manual && damaged(COMPUTER))
158: {
159: printf("Computer damaged, manual selected\n");
160: skiptonl(0);
161: manual++;
162: }
163:
164:
165: flag = 1;
166: for (i = 0; i < NBANKS; i++)
167: bank[i].units = 0;
168: if (manual)
169: {
170:
171: while (flag)
172: {
173: printf("%d units available\n", Ship.energy);
174: extra = 0;
175: flag = 0;
176: for (i = 0; i < NBANKS; i++)
177: {
178: b = &bank[i];
179: printf("\nBank %d:\n", i);
180: hit = getintpar("units");
181: if (hit < 0)
182: return;
183: if (hit == 0)
184: break;
185: extra += hit;
186: if (extra > Ship.energy)
187: {
188: printf("available energy exceeded. ");
189: skiptonl(0);
190: flag++;
191: break;
192: }
193: b->units = hit;
194: hit = getintpar("course");
195: if (hit < 0 || hit > 360)
196: return;
197: b->angle = hit * 0.0174532925;
198: b->spread = getfltpar("spread");
199: if (b->spread < 0 || b->spread > 1)
200: return;
201: }
202: Ship.energy -= extra;
203: }
204: extra = 0;
205: }
206: else
207: {
208:
209: if (Etc.nkling <= 0) {
210: printf("Sulu: But there are no Klingons in this quadrant\n");
211: return;
212: }
213: printf("Phasers locked on target. ");
214: while (flag)
215: {
216: printf("%d units available\n", Ship.energy);
217: hit = getintpar("Units to fire");
218: if (hit <= 0)
219: return;
220: if (hit > Ship.energy)
221: {
222: printf("available energy exceeded. ");
223: skiptonl(0);
224: continue;
225: }
226: flag = 0;
227: Ship.energy -= hit;
228: extra = hit;
229: n = Etc.nkling;
230: if (n > NBANKS)
231: n = NBANKS;
232: tot = n * (n + 1) / 2;
233: for (i = 0; i < n; i++)
234: {
235: k = &Etc.klingon[i];
236: b = &bank[i];
237: distfactor = k->dist;
238: anglefactor = ALPHA * BETA * OMEGA / (distfactor * distfactor + EPSILON);
239: anglefactor *= GAMMA;
240: distfactor = k->power;
241: distfactor /= anglefactor;
242: hitreqd[i] = distfactor + 0.5;
243: dx = Ship.sectx - k->x;
244: dy = k->y - Ship.secty;
245: b->angle = atan2(dy, dx);
246: b->spread = 0.0;
247: b->units = ((n - i) / tot) * extra;
248: # ifdef xTRACE
249: if (Trace)
250: {
251: printf("b%d hr%d u%d df%.2f af%.2f\n",
252: i, hitreqd[i], b->units,
253: distfactor, anglefactor);
254: }
255: # endif
256: extra -= b->units;
257: hit = b->units - hitreqd[i];
258: if (hit > 0)
259: {
260: extra += hit;
261: b->units -= hit;
262: }
263: }
264:
265:
266: if (extra > 0)
267: {
268: for (i = 0; i < n; i++)
269: {
270: b = &bank[i];
271: hit = hitreqd[i] - b->units;
272: if (hit <= 0)
273: continue;
274: if (hit >= extra)
275: {
276: b->units += extra;
277: extra = 0;
278: break;
279: }
280: b->units = hitreqd[i];
281: extra -= hit;
282: }
283: if (extra > 0)
284: printf("%d units overkill\n", extra);
285: }
286: }
287: }
288:
289: # ifdef xTRACE
290: if (Trace)
291: {
292: for (i = 0; i < NBANKS; i++)
293: {
294: b = &bank[i];
295: printf("b%d u%d", i, b->units);
296: if (b->units > 0)
297: printf(" a%.2f s%.2f\n", b->angle, b->spread);
298: else
299: printf("\n");
300: }
301: }
302: # endif
303:
304:
305: Move.free = 0;
306: for (i = 0; i < NBANKS; i++)
307: {
308: b = &bank[i];
309: if (b->units <= 0)
310: {
311: continue;
312: }
313: printf("\nPhaser bank %d fires:\n", i);
314: n = Etc.nkling;
315: k = Etc.klingon;
316: for (j = 0; j < n; j++)
317: {
318: if (b->units <= 0)
319: break;
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349: distfactor = BETA + franf();
350: distfactor *= ALPHA + b->spread;
351: distfactor *= OMEGA;
352: anglefactor = k->dist;
353: distfactor /= anglefactor * anglefactor + EPSILON;
354: distfactor *= b->units;
355: dx = Ship.sectx - k->x;
356: dy = k->y - Ship.secty;
357: anglefactor = atan2(dy, dx) - b->angle;
358: anglefactor = cos((anglefactor * b->spread) + GAMMA);
359: if (anglefactor < 0.0)
360: {
361: k++;
362: continue;
363: }
364: hit = anglefactor * distfactor + 0.5;
365: k->power -= hit;
366: printf("%d unit hit on Klingon", hit);
367: if (!damaged(SRSCAN))
368: printf(" at %d,%d", k->x, k->y);
369: printf("\n");
370: b->units -= hit;
371: if (k->power <= 0)
372: {
373: killk(k->x, k->y);
374: continue;
375: }
376: k++;
377: }
378: }
379:
380:
381: for (i = 0; i < NBANKS; i++)
382: extra += bank[i].units;
383: if (extra > 0)
384: printf("\n%d units expended on empty space\n", extra);
385: }