Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7142 | siemargl | 1 | #include "sst.h" |
2 | |||
3 | static void getcd(int, int); |
||
4 | |||
5 | void lmove(void) { |
||
6 | double angle, deltax, deltay, bigger, x, y, |
||
7 | finald, finalx, finaly, stopegy; |
||
8 | int oldquadx, oldquady; |
||
9 | int trbeam = 0, n, l, ix, iy, kink, kinks, iquad; |
||
10 | |||
11 | if (inorbit) { |
||
12 | prout("SULU- \"Leaving standard orbit.\""); |
||
13 | inorbit = 0; |
||
14 | } |
||
15 | |||
16 | angle = ((15.0 - direc) * 0.5235988); |
||
17 | deltax = -sin(angle); |
||
18 | deltay = cos(angle); |
||
19 | if (fabs(deltax) > fabs(deltay)) |
||
20 | bigger = fabs(deltax); |
||
21 | else |
||
22 | bigger = fabs(deltay); |
||
23 | |||
24 | deltay /= bigger; |
||
25 | deltax /= bigger; |
||
26 | |||
27 | #ifdef CLOAKING |
||
28 | if (iscloaked && d.date+Time >= future[FTBEAM]) |
||
29 | { /* We can't be tracto beamed if cloaked, so move the event into the future */ |
||
30 | future[FTBEAM] = d.date + Time + |
||
31 | expran(1.5*intime/d.remcom); |
||
32 | } |
||
33 | #endif |
||
34 | |||
35 | /* If tractor beam is to occur, don't move full distance */ |
||
36 | if (d.date+Time >= future[FTBEAM]) { |
||
37 | trbeam = 1; |
||
38 | condit = IHRED; |
||
39 | dist = dist*(future[FTBEAM]-d.date)/Time + 0.1; |
||
40 | Time = future[FTBEAM] - d.date + 1e-5; |
||
41 | } |
||
42 | /* Move within the quadrant */ |
||
43 | quad[sectx][secty] = IHDOT; |
||
44 | x = sectx; |
||
45 | y = secty; |
||
46 | n = 10.0*dist*bigger+0.5; |
||
47 | |||
48 | if (n > 0) { |
||
49 | for (l = 1; l <= n; l++) { |
||
50 | ix = (x += deltax) + 0.5; |
||
51 | iy = (y += deltay) + 0.5; |
||
52 | if (ix < 1 || ix > 10 || iy < 1 || iy > 10) { |
||
53 | /* Leaving quadrant -- allow final enemy attack */ |
||
54 | /* Don't do it if being pushed by Nova */ |
||
55 | if (nenhere != 0 && iattak != 2 |
||
56 | #ifdef CLOAKING |
||
57 | && !iscloaked |
||
58 | #endif |
||
59 | ) { |
||
60 | newcnd(); |
||
61 | for (l = 1; l <= nenhere; l++) { |
||
62 | finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) + |
||
63 | (iy-ky[l])*(double)(iy-ky[l])); |
||
64 | kavgd[l] = 0.5 * (finald+kdist[l]); |
||
65 | } |
||
66 | if (d.galaxy[quadx][quady] != 1000) attack(0); |
||
67 | if (alldone) return; |
||
68 | } |
||
69 | /* compute final position -- new quadrant and sector */ |
||
70 | x = 10*(quadx-1)+sectx; |
||
71 | y = 10*(quady-1)+secty; |
||
72 | ix = x+10.0*dist*bigger*deltax+0.5; |
||
73 | iy = y+10.0*dist*bigger*deltay+0.5; |
||
74 | /* check for edge of galaxy */ |
||
75 | kinks = FALSE; |
||
76 | do { |
||
77 | kink = 0; |
||
78 | if (ix <= 0) { |
||
79 | ix = -ix + 1; |
||
80 | kink = 1; |
||
81 | } |
||
82 | if (iy <= 0) { |
||
83 | iy = -iy + 1; |
||
84 | kink = 1; |
||
85 | } |
||
86 | if (ix > 80) { |
||
87 | ix = 161 - ix; |
||
88 | kink = 1; |
||
89 | } |
||
90 | if (iy > 80) { |
||
91 | iy = 161 - iy; |
||
92 | kink = 1; |
||
93 | } |
||
94 | if (kink) kinks = TRUE; |
||
95 | } while (kink); |
||
96 | |||
97 | if (kinks) { |
||
98 | nkinks += 1; |
||
99 | if (nkinks == 3) { |
||
100 | /* Three strikes -- you're out! */ |
||
101 | finish(FNEG3); |
||
102 | return; |
||
103 | } |
||
104 | prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n" |
||
105 | "AT THE EDGE OF THE GALAXY. THE THIRD TIME YOU TRY THIS,\n" |
||
106 | "YOU WILL BE DESTROYED.\n"); |
||
107 | } |
||
108 | /* Compute final position in new quadrant */ |
||
109 | if (trbeam) return; /* Don't bother if we are to be beamed */ |
||
110 | oldquadx = quadx; |
||
111 | oldquady = quady; |
||
112 | quadx = (ix+9)/10; |
||
113 | quady = (iy+9)/10; |
||
114 | sectx = ix - 10*(quadx-1); |
||
115 | secty = iy - 10*(quady-1); |
||
116 | if (quadx != oldquadx || quady != oldquady) { |
||
117 | proutn("\nEntering"); |
||
118 | cramlc(1, quadx, quady); |
||
119 | } else { |
||
120 | prout("(Negative energy barrier disturbs quadrant.)"); |
||
121 | } |
||
122 | skip(1); |
||
123 | quad[sectx][secty] = ship; |
||
124 | newqad(0); |
||
125 | return; |
||
126 | } |
||
127 | iquad = quad[ix][iy]; |
||
128 | if (iquad != IHDOT) { |
||
129 | /* object encountered in flight path */ |
||
130 | stopegy = 50.0*dist/Time; |
||
131 | dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) + |
||
132 | (secty-iy)*(double)(secty-iy)); |
||
133 | switch (iquad) { |
||
134 | case IHT: /* Ram a Tholean */ |
||
135 | case IHK: /* Ram enemy ship */ |
||
136 | case IHC: |
||
137 | case IHS: |
||
138 | case IHR: |
||
139 | sectx = ix; |
||
140 | secty = iy; |
||
141 | ram(0, iquad, sectx, secty); |
||
142 | finalx = sectx; |
||
143 | finaly = secty; |
||
144 | break; |
||
145 | case IHBLANK: |
||
146 | skip(1); |
||
147 | prouts("***RED ALERT! RED ALERT!"); |
||
148 | skip(1); |
||
149 | proutn("***"); |
||
150 | crmshp(); |
||
151 | proutn(" pulled into black hole at"); |
||
152 | cramlc(2, ix, iy); |
||
153 | skip(1); |
||
154 | finish(FHOLE); |
||
155 | return; |
||
156 | default: |
||
157 | /* something else */ |
||
158 | skip(1); |
||
159 | crmshp(); |
||
160 | if (iquad == IHWEB) |
||
161 | proutn(" encounters Tholian web at"); |
||
162 | else |
||
163 | proutn(" blocked by object at"); |
||
164 | cramlc(2, ix,iy); |
||
165 | prout(";"); |
||
166 | proutn("Emergency stop required "); |
||
167 | cramf(stopegy, 0, 2); |
||
168 | prout(" units of energy."); |
||
169 | energy -= stopegy; |
||
170 | finalx = x-deltax+0.5; |
||
171 | sectx = finalx; |
||
172 | finaly = y-deltay+0.5; |
||
173 | secty = finaly; |
||
174 | if (energy <= 0) { |
||
175 | finish(FNRG); |
||
176 | return; |
||
177 | } |
||
178 | break; |
||
179 | } |
||
180 | goto label100; /* sorry! */ /* ACTUALLY BREAK SHOULD WORK HERE */ |
||
181 | } |
||
182 | } |
||
183 | dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) + |
||
184 | (secty-iy)*(double)(secty-iy)); |
||
185 | sectx = ix; |
||
186 | secty = iy; |
||
187 | } |
||
188 | finalx = sectx; /* THESE STATEMENTS DO NOTHING USEFUL */ |
||
189 | finaly = secty; |
||
190 | label100: |
||
191 | /* No quadrant change -- compute new avg enemy distances */ |
||
192 | quad[sectx][secty] = ship; |
||
193 | if (nenhere) { |
||
194 | for (l = 1; l <= nenhere; l++) { |
||
195 | finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) + |
||
196 | (iy-ky[l])*(double)(iy-ky[l])); |
||
197 | kavgd[l] = 0.5 * (finald+kdist[l]); |
||
198 | kdist[l] = finald; |
||
199 | } |
||
200 | sortkl(); |
||
201 | if (d.galaxy[quadx][quady] != 1000 && iattak == 0) |
||
202 | attack(0); |
||
203 | for (l = 1 ; l <= nenhere; l++) kavgd[l] = kdist[l]; |
||
204 | } |
||
205 | newcnd(); |
||
206 | iattak = 0; |
||
207 | return; |
||
208 | } |
||
209 | |||
210 | void dock(void) { |
||
211 | chew(); |
||
212 | if (condit == IHDOCKED) { |
||
213 | prout("Already docked."); |
||
214 | return; |
||
215 | } |
||
216 | if (inorbit) { |
||
217 | prout("You must first leave standard orbit."); |
||
218 | return; |
||
219 | } |
||
220 | if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) { |
||
221 | crmshp(); |
||
222 | prout(" not adjacent to base."); |
||
223 | return; |
||
224 | } |
||
225 | #ifdef CLOAKING |
||
226 | if (iscloaked) { |
||
227 | prout("You cannot dock while cloaked."); |
||
228 | return; |
||
229 | } |
||
230 | #endif |
||
231 | condit = IHDOCKED; |
||
232 | prout("Docked."); |
||
233 | if (energy < inenrg) energy = inenrg; |
||
234 | shield = inshld; |
||
235 | torps = intorps; |
||
236 | lsupres = inlsr; |
||
237 | #ifdef CAPTURE |
||
238 | if (brigcapacity-brigfree > 0) |
||
239 | { |
||
240 | printf("%d captured Klingons transferred to base.\n", brigcapacity-brigfree); |
||
241 | kcaptured += brigcapacity-brigfree; |
||
242 | brigfree = brigcapacity; |
||
243 | } |
||
244 | #endif |
||
245 | if (stdamtim != 1e30 && |
||
246 | (future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) { |
||
247 | /* get attack report from base */ |
||
248 | prout("Lt. Uhura- \"Captain, an important message from the starbase:\""); |
||
249 | attakreport(); |
||
250 | iseenit = 1; |
||
251 | } |
||
252 | } |
||
253 | |||
254 | static void getcd(int isprobe, int akey) { |
||
255 | /* This program originally required input in terms of a (clock) |
||
256 | direction and distance. Somewhere in history, it was changed to |
||
257 | cartesian coordinates. So we need to convert. I think |
||
258 | "manual" input should still be done this way -- it's a real |
||
259 | pain if the computer isn't working! Manual mode is still confusing |
||
260 | because it involves giving x and y motions, yet the coordinates |
||
261 | are always displayed y - x, where +y is downward! */ |
||
262 | |||
263 | |||
264 | int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key; |
||
265 | double xi, xj, xk, xl; |
||
266 | double deltax, deltay; |
||
267 | int automatic = -1; |
||
268 | |||
269 | /* Get course direction and distance. If user types bad values, return |
||
270 | with DIREC = -1.0. */ |
||
271 | |||
272 | direc = -1.0; |
||
273 | |||
274 | if (landed == 1 && !isprobe) { |
||
275 | prout("Dummy! You can't leave standard orbit until you"); |
||
276 | proutn("are back aboard the "); |
||
277 | crmshp(); |
||
278 | prout("."); |
||
279 | chew(); |
||
280 | return; |
||
281 | } |
||
282 | while (automatic == -1) { |
||
283 | if (damage[DCOMPTR]) { |
||
284 | if (isprobe) |
||
285 | prout("Computer damaged; manual navigation only"); |
||
286 | else |
||
287 | prout("Computer damaged; manual movement only"); |
||
288 | chew(); |
||
289 | automatic = 0; |
||
290 | key = IHEOL; |
||
291 | break; |
||
292 | } |
||
293 | if (isprobe && akey != -1) { |
||
294 | /* For probe launch, use pre-scaned value first time */ |
||
295 | key = akey; |
||
296 | akey = -1; |
||
297 | } |
||
298 | else |
||
299 | key = scan(); |
||
300 | |||
301 | if (key == IHEOL) { |
||
302 | proutn("Manual or automatic- "); |
||
303 | iprompt = 1; |
||
304 | chew(); |
||
305 | } |
||
306 | else if (key == IHALPHA) { |
||
307 | if (isit("manual")) { |
||
308 | automatic =0; |
||
309 | key = scan(); |
||
310 | break; |
||
311 | } |
||
312 | else if (isit("automatic")) { |
||
313 | automatic = 1; |
||
314 | key = scan(); |
||
315 | break; |
||
316 | } |
||
317 | else { |
||
318 | huh(); |
||
319 | chew(); |
||
320 | return; |
||
321 | } |
||
322 | } |
||
323 | else { /* numeric */ |
||
324 | if (isprobe) |
||
325 | prout("(Manual navigation assumed.)"); |
||
326 | else |
||
327 | prout("(Manual movement assumed.)"); |
||
328 | automatic = 0; |
||
329 | break; |
||
330 | } |
||
331 | } |
||
332 | |||
333 | if (automatic) { |
||
334 | while (key == IHEOL) { |
||
335 | if (isprobe) |
||
336 | proutn("Target quadrant or quadrant§or- "); |
||
337 | else |
||
338 | proutn("Destination sector or quadrant§or- "); |
||
339 | chew(); |
||
340 | iprompt = 1; |
||
341 | key = scan(); |
||
342 | } |
||
343 | |||
344 | if (key != IHREAL) { |
||
345 | huh(); |
||
346 | return; |
||
347 | } |
||
348 | xi = aaitem; |
||
349 | key = scan(); |
||
350 | if (key != IHREAL){ |
||
351 | huh(); |
||
352 | return; |
||
353 | } |
||
354 | xj = aaitem; |
||
355 | key = scan(); |
||
356 | if (key == IHREAL) { |
||
357 | /* both quadrant and sector specified */ |
||
358 | xk = aaitem; |
||
359 | key = scan(); |
||
360 | if (key != IHREAL) { |
||
361 | huh(); |
||
362 | return; |
||
363 | } |
||
364 | xl = aaitem; |
||
365 | |||
366 | irowq = xi + 0.5; |
||
367 | icolq = xj + 0.5; |
||
368 | irows = xk + 0.5; |
||
369 | icols = xl + 0.5; |
||
370 | } |
||
371 | else { |
||
372 | if (isprobe) { |
||
373 | /* only quadrant specified -- go to center of dest quad */ |
||
374 | irowq = xi + 0.5; |
||
375 | icolq = xj + 0.5; |
||
376 | irows = icols = 5; |
||
377 | } |
||
378 | else { |
||
379 | irows = xi + 0.5; |
||
380 | icols = xj + 0.5; |
||
381 | } |
||
382 | itemp = 1; |
||
383 | } |
||
384 | if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 || |
||
385 | irows<1 || irows > 10 || icols<1 || icols > 10) { |
||
386 | huh(); |
||
387 | return; |
||
388 | } |
||
389 | skip(1); |
||
390 | if (!isprobe) { |
||
391 | if (itemp) { |
||
392 | if (iprompt) { |
||
393 | proutn("Helmsman Sulu- \"Course locked in for"); |
||
394 | cramlc(2, irows, icols); |
||
395 | prout(".\""); |
||
396 | } |
||
397 | } |
||
398 | else prout("Ensign Chekov- \"Course laid in, Captain.\""); |
||
399 | } |
||
400 | deltax = icolq - quady + 0.1*(icols-secty); |
||
401 | deltay = quadx - irowq + 0.1*(sectx-irows); |
||
402 | } |
||
403 | else { /* manual */ |
||
404 | while (key == IHEOL) { |
||
405 | proutn("X and Y displacements- "); |
||
406 | chew(); |
||
407 | iprompt = 1; |
||
408 | key = scan(); |
||
409 | } |
||
410 | itemp = 2; |
||
411 | if (key != IHREAL) { |
||
412 | huh(); |
||
413 | return; |
||
414 | } |
||
415 | deltax = aaitem; |
||
416 | key = scan(); |
||
417 | if (key == IHEOL) { |
||
418 | deltay = 0.0; |
||
419 | } else if (key != IHREAL) { |
||
420 | huh(); |
||
421 | return; |
||
422 | } else { |
||
423 | deltay = aaitem; |
||
424 | } |
||
425 | |||
426 | if (coordfixed) { |
||
427 | double temp = deltax; |
||
428 | deltax = deltay; |
||
429 | deltay = -temp; |
||
430 | } |
||
431 | } |
||
432 | /* Check for zero movement */ |
||
433 | if (deltax == 0 && deltay == 0) { |
||
434 | chew(); |
||
435 | return; |
||
436 | } |
||
437 | if (itemp == 2 && !isprobe) { |
||
438 | skip(1); |
||
439 | prout("Helmsman Sulu- \"Aye, Sir.\""); |
||
440 | } |
||
441 | dist = sqrt(deltax*deltax + deltay*deltay); |
||
442 | direc = atan2(deltax, deltay)*1.90985932; |
||
443 | if (direc < 0.0) direc += 12.0; |
||
444 | chew(); |
||
445 | return; |
||
446 | |||
447 | } |
||
448 | |||
449 | |||
450 | |||
451 | void impuls(void) { |
||
452 | double power; |
||
453 | |||
454 | ididit = 0; |
||
455 | if (damage[DIMPULS]) { |
||
456 | chew(); |
||
457 | skip(1); |
||
458 | prout("Engineer Scott- \"The impulse engines are damaged, Sir.\""); |
||
459 | return; |
||
460 | } |
||
461 | |||
462 | if (energy > 30.0) { |
||
463 | getcd(FALSE, 0); |
||
464 | if (direc == -1.0) return; |
||
465 | power = 20.0 + 100.0*dist; |
||
466 | } |
||
467 | else |
||
468 | power = 30.0; |
||
469 | |||
470 | if (power >= energy) { |
||
471 | /* Insufficient power for trip */ |
||
472 | skip(1); |
||
473 | prout("First Officer Spock- \"Captain, the impulse engines"); |
||
474 | prout("require 20.0 units to engage, plus 100.0 units per"); |
||
475 | if (energy > 30) { |
||
476 | proutn("quadrant. We can go, therefore, a maximum of "); |
||
477 | cramf(0.01 * (energy-20.0)-0.05, 0, 1); |
||
478 | prout(" quadrants.\""); |
||
479 | } |
||
480 | else { |
||
481 | prout("quadrant. They are, therefore, useless.\""); |
||
482 | } |
||
483 | chew(); |
||
484 | return; |
||
485 | } |
||
486 | /* Make sure enough time is left for the trip */ |
||
487 | Time = dist/0.095; |
||
488 | if (Time >= d.remtime) { |
||
489 | prout("First Officer Spock- \"Captain, our speed under impulse"); |
||
490 | prout("power is only 0.95 sectors per stardate. Are you sure"); |
||
491 | prout("we dare spend the time?\""); |
||
492 | if (ja() == 0) { Time = 0.0; return;} |
||
493 | } |
||
494 | /* Activate impulse engines and pay the cost */ |
||
495 | lmove(); |
||
496 | ididit = 1; |
||
497 | if (alldone) return; |
||
498 | power = 20.0 + 100.0*dist; |
||
499 | energy -= power; |
||
500 | // Time = dist/0.095; Don't recalculate because lmove may have |
||
501 | // adjusted it for tractor beaming |
||
502 | if (energy <= 0) finish(FNRG); |
||
503 | return; |
||
504 | } |
||
505 | |||
506 | |||
507 | void warp(int i) { |
||
508 | int blooey=0, twarp=0, iwarp; |
||
509 | double power; |
||
510 | |||
511 | if (i!=2) { /* Not WARPX entry */ |
||
512 | ididit = 0; |
||
513 | #ifdef CLOAKING |
||
514 | if (iscloaked) { |
||
515 | chew(); |
||
516 | skip(1); |
||
517 | prout("Engineer Scott- \"The warp engines can better not be used while cloaked, Sir.\""); |
||
518 | return; |
||
519 | } |
||
520 | #endif |
||
521 | if (damage[DWARPEN] > 10.0) { |
||
522 | chew(); |
||
523 | skip(1); |
||
524 | prout("Engineer Scott- \"The warp engines are damaged, Sir.\""); // Was "Impulse" 10/2013 |
||
525 | return; |
||
526 | } |
||
527 | if (damage[DWARPEN] > 0.0 && warpfac > 4.0) { |
||
528 | chew(); |
||
529 | skip(1); |
||
530 | prout("Engineer Scott- \"Sorry, Captain. Until this damage"); |
||
531 | prout(" is repaired, I can only give you warp 4.\""); |
||
532 | return; |
||
533 | } |
||
534 | |||
535 | /* Read in course and distance */ |
||
536 | getcd(FALSE, 0); |
||
537 | if (direc == -1.0) return; |
||
538 | |||
539 | /* Make sure starship has enough energy for the trip */ |
||
540 | power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1); |
||
541 | |||
542 | |||
543 | if (power >= energy) { |
||
544 | /* Insufficient power for trip */ |
||
545 | ididit = 0; |
||
546 | skip(1); |
||
547 | prout("Engineering to bridge--"); |
||
548 | if (shldup==0 || 0.5*power > energy) { |
||
549 | iwarp = pow((energy/(dist+0.05)), 0.333333333); |
||
550 | if (iwarp <= 0) { |
||
551 | prout("We can't do it, Captain. We haven't the energy."); |
||
552 | } |
||
553 | else { |
||
554 | proutn("We haven't the energy, but we could do it at warp "); |
||
555 | crami(iwarp, 1); |
||
556 | if (shldup) |
||
557 | prout(",\nif you'll lower the shields."); |
||
558 | else |
||
559 | prout("."); |
||
560 | } |
||
561 | } |
||
562 | else |
||
563 | prout("We haven't the energy to go that far with the shields up."); |
||
564 | return; |
||
565 | } |
||
566 | |||
567 | /* Make sure enough time is left for the trip */ |
||
568 | Time = 10.0*dist/wfacsq; |
||
569 | if (Time >= 0.8*d.remtime) { |
||
570 | skip(1); |
||
571 | prout("First Officer Spock- \"Captain, I compute that such"); |
||
572 | proutn(" a trip would require approximately "); |
||
573 | cramf(100.0*Time/d.remtime, 0, 2); |
||
574 | prout(" percent of our"); |
||
575 | prout(" remaining time. Are you sure this is wise?\""); |
||
576 | if (ja() == 0) { Time = 0.0; return;} |
||
577 | } |
||
578 | } |
||
579 | /* Entry WARPX */ |
||
580 | if (warpfac > 6.0) { |
||
581 | /* Decide if engine damage will occur */ |
||
582 | double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666; |
||
583 | if (prob > Rand()) { |
||
584 | blooey = 1; |
||
585 | dist = Rand()*dist; |
||
586 | } |
||
587 | /* Decide if time warp will occur */ |
||
588 | if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1; |
||
589 | #ifdef DEBUG |
||
590 | if (idebug &&warpfac==10 && twarp==0) { |
||
591 | blooey=0; |
||
592 | proutn("Force time warp? "); |
||
593 | if (ja()==1) twarp=1; |
||
594 | } |
||
595 | #endif |
||
596 | if (blooey || twarp) { |
||
597 | /* If time warp or engine damage, check path */ |
||
598 | /* If it is obstructed, don't do warp or damage */ |
||
599 | double angle = ((15.0-direc)*0.5235998); |
||
600 | double deltax = -sin(angle); |
||
601 | double deltay = cos(angle); |
||
602 | double bigger, x, y; |
||
603 | int n, l, ix, iy; |
||
604 | if (fabs(deltax) > fabs(deltay)) |
||
605 | bigger = fabs(deltax); |
||
606 | else |
||
607 | bigger = fabs(deltay); |
||
608 | |||
609 | deltax /= bigger; |
||
610 | deltay /= bigger; |
||
611 | n = 10.0 * dist * bigger +0.5; |
||
612 | x = sectx; |
||
613 | y = secty; |
||
614 | for (l = 1; l <= n; l++) { |
||
615 | x += deltax; |
||
616 | ix = x + 0.5; |
||
617 | if (ix < 1 || ix > 10) break; |
||
618 | y += deltay; |
||
619 | iy = y +0.5; |
||
620 | if (iy < 1 || iy > 10) break; |
||
621 | if (quad[ix][iy] != IHDOT) { |
||
622 | blooey = 0; |
||
623 | twarp = 0; |
||
624 | } |
||
625 | } |
||
626 | } |
||
627 | } |
||
628 | |||
629 | |||
630 | /* Activate Warp Engines and pay the cost */ |
||
631 | lmove(); |
||
632 | if (alldone) return; |
||
633 | energy -= dist*warpfac*warpfac*warpfac*(shldup+1); |
||
634 | if (energy <= 0) finish(FNRG); |
||
635 | Time = 10.0*dist/wfacsq; |
||
636 | if (twarp) timwrp(); |
||
637 | if (blooey) { |
||
638 | damage[DWARPEN] = damfac*(3.0*Rand()+1.0); |
||
639 | skip(1); |
||
640 | prout("Engineering to bridge--"); |
||
641 | prout(" Scott here. The warp engines are damaged."); |
||
642 | prout(" We'll have to reduce speed to warp 4."); |
||
643 | } |
||
644 | ididit = 1; |
||
645 | return; |
||
646 | } |
||
647 | |||
648 | |||
649 | |||
650 | void setwrp(void) { |
||
651 | int key; |
||
652 | double oldfac; |
||
653 | |||
654 | while ((key=scan()) == IHEOL) { |
||
655 | chew(); |
||
656 | proutn("Warp factor-"); |
||
657 | } |
||
658 | chew(); |
||
659 | if (key != IHREAL) { |
||
660 | huh(); |
||
661 | return; |
||
662 | } |
||
663 | if (damage[DWARPEN] > 10.0) { |
||
664 | prout("Warp engines inoperative."); |
||
665 | return; |
||
666 | } |
||
667 | if (damage[DWARPEN] > 0.0 && aaitem > 4.0) { |
||
668 | prout("Engineer Scott- \"I'm doing my best, Captain,\n" |
||
669 | " but right now we can only go warp 4.\""); |
||
670 | return; |
||
671 | } |
||
672 | if (aaitem > 10.0) { |
||
673 | prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\""); |
||
674 | return; |
||
675 | } |
||
676 | if (aaitem < 1.0) { |
||
677 | prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\""); |
||
678 | return; |
||
679 | } |
||
680 | oldfac = warpfac; |
||
681 | warpfac = aaitem; |
||
682 | wfacsq=warpfac*warpfac; |
||
683 | if (warpfac <= oldfac || warpfac <= 6.0) { |
||
684 | proutn("Helmsman Sulu- \"Warp factor "); |
||
685 | cramf(warpfac, 0, 1); |
||
686 | prout(", Captain.\""); |
||
687 | return; |
||
688 | } |
||
689 | if (warpfac < 8.00) { |
||
690 | prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\""); |
||
691 | return; |
||
692 | } |
||
693 | if (warpfac == 10.0) { |
||
694 | prout("Engineer Scott- \"Aye, Captain, we'll try it.\""); |
||
695 | return; |
||
696 | } |
||
697 | prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\""); |
||
698 | return; |
||
699 | } |
||
700 | |||
701 | void atover(int igrab) { |
||
702 | double power, distreq; |
||
703 | |||
704 | chew(); |
||
705 | /* is captain on planet? */ |
||
706 | if (landed==1) { |
||
707 | if (damage[DTRANSP]) { |
||
708 | finish(FPNOVA); |
||
709 | return; |
||
710 | } |
||
711 | prout("Scotty rushes to the transporter controls."); |
||
712 | if (shldup) { |
||
713 | prout("But with the shields up it's hopeless."); |
||
714 | finish(FPNOVA); |
||
715 | } |
||
716 | prouts("His desperate attempt to rescue you . . ."); |
||
717 | if (Rand() <= 0.5) { |
||
718 | prout("fails."); |
||
719 | finish(FPNOVA); |
||
720 | return; |
||
721 | } |
||
722 | prout("SUCCEEDS!"); |
||
723 | if (imine) { |
||
724 | imine = 0; |
||
725 | proutn("The crystals mined were "); |
||
726 | if (Rand() <= 0.25) { |
||
727 | prout("lost."); |
||
728 | } |
||
729 | else { |
||
730 | prout("saved."); |
||
731 | icrystl = 1; |
||
732 | } |
||
733 | } |
||
734 | } |
||
735 | if (igrab) return; |
||
736 | |||
737 | /* Check to see if captain in shuttle craft */ |
||
738 | if (icraft) finish(FSTRACTOR); |
||
739 | if (alldone) return; |
||
740 | |||
741 | /* Inform captain of attempt to reach safety */ |
||
742 | skip(1); |
||
743 | do { |
||
744 | if (justin) { |
||
745 | prouts("***RED ALERT! RED ALERT!"); |
||
746 | skip(1); |
||
747 | proutn("The "); |
||
748 | crmshp(); |
||
749 | prout(" has stopped in a quadrant containing"); |
||
750 | prouts(" a supernova."); |
||
751 | skip(2); |
||
752 | } |
||
753 | proutn("***Emergency automatic override attempts to hurl "); |
||
754 | crmshp(); |
||
755 | skip(1); |
||
756 | prout("safely out of quadrant."); |
||
757 | starch[quadx][quady] = damage[DRADIO] > 0.0 ? d.galaxy[quadx][quady]+1000:1; |
||
758 | |||
759 | /* Try to use warp engines */ |
||
760 | if (damage[DWARPEN]) { |
||
761 | skip(1); |
||
762 | prout("Warp engines damaged."); |
||
763 | finish(FSNOVAED); |
||
764 | return; |
||
765 | } |
||
766 | warpfac = 6.0+2.0*Rand(); |
||
767 | wfacsq = warpfac * warpfac; |
||
768 | proutn("Warp factor set to "); |
||
769 | cramf(warpfac, 1, 1); |
||
770 | skip(1); |
||
771 | power = 0.75*energy; |
||
772 | dist = power/(warpfac*warpfac*warpfac*(shldup+1)); |
||
773 | distreq = 1.4142+Rand(); |
||
774 | if (distreq < dist) dist = distreq; |
||
775 | Time = 10.0*dist/wfacsq; |
||
776 | direc = 12.0*Rand(); /* How dumb! */ |
||
777 | justin = 0; |
||
778 | inorbit = 0; |
||
779 | warp(2); |
||
780 | if (justin == 0) { |
||
781 | /* This is bad news, we didn't leave quadrant. */ |
||
782 | if (alldone) return; |
||
783 | skip(1); |
||
784 | prout("Insufficient energy to leave quadrant."); |
||
785 | finish(FSNOVAED); |
||
786 | return; |
||
787 | } |
||
788 | /* Repeat if another snova */ |
||
789 | } while (d.galaxy[quadx][quady] == 1000); |
||
790 | if (d.remkl==0) finish(FWON); /* Snova killed remaining enemy. */ |
||
791 | } |
||
792 | |||
793 | void timwrp() { |
||
794 | int l, ll, gotit; |
||
795 | prout("***TIME WARP ENTERED."); |
||
796 | if (d.snap && Rand() < 0.5) { |
||
797 | /* Go back in time */ |
||
798 | proutn("You are traveling backwards in time "); |
||
799 | cramf(d.date-snapsht.date, 0, 2); |
||
800 | prout(" stardates."); |
||
801 | d = snapsht; |
||
802 | d.snap = 0; |
||
803 | if (d.remcom) { |
||
804 | future[FTBEAM] = d.date + expran(intime/d.remcom); |
||
805 | future[FBATTAK] = d.date + expran(0.3*intime); |
||
806 | } |
||
807 | future[FSNOVA] = d.date + expran(0.5*intime); |
||
808 | future[FSNAP] = d.date +expran(0.25*d.remtime); /* next snapshot will |
||
809 | be sooner */ |
||
810 | if (d.nscrem) future[FSCMOVE] = 0.2777; |
||
811 | isatb = 0; |
||
812 | future[FCDBAS] = future[FSCDBAS] = 1e30; |
||
813 | batx = baty = 0; |
||
814 | |||
815 | /* Make sure Galileo is consistant -- Snapshot may have been taken |
||
816 | when on planet, which would give us two Galileos! */ |
||
817 | gotit = 0; |
||
818 | for (l = 1; l <= inplan; l++) { |
||
819 | if (d.plnets[l].known == 2) { |
||
820 | gotit = 1; |
||
821 | if (iscraft==1 && ship==IHE) { |
||
822 | prout("Checkov- \"Security reports the Galileo has disappeared, Sir!"); |
||
823 | iscraft = 0; |
||
824 | } |
||
825 | } |
||
826 | } |
||
827 | /* Likewise, if in the original time the Galileo was abandoned, but |
||
828 | was on ship earlier, it would have vanished -- lets restore it */ |
||
829 | if (iscraft==0 && gotit==0 && damage[DSHUTTL] >= 0.0) { |
||
830 | prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\""); |
||
831 | iscraft = 1; |
||
832 | } |
||
833 | |||
834 | /* Revert star chart to earlier era, if it was known then*/ |
||
835 | if (damage[DRADIO]==0.0 || stdamtim > d.date) { |
||
836 | for (l = 1; l <= 8; l++) |
||
837 | for (ll = 1; ll <= 8; ll++) |
||
838 | if (starch[l][ll] > 1) |
||
839 | starch[l][ll]=damage[DRADIO]>0.0 ? d.galaxy[l][ll]+1000 :1; |
||
840 | prout("Spock has reconstructed a correct star chart from memory"); |
||
841 | if (damage[DRADIO] > 0.0) stdamtim = d.date; |
||
842 | } |
||
843 | } |
||
844 | else { |
||
845 | /* Go forward in time */ |
||
846 | Time = -0.5*intime*log(Rand()); |
||
847 | proutn("You are traveling forward in time "); |
||
848 | cramf(Time, 1, 2); |
||
849 | prout(" stardates."); |
||
850 | /* cheat to make sure no tractor beams occur during time warp */ |
||
851 | future[FTBEAM] += Time; |
||
852 | damage[DRADIO] += Time; |
||
853 | } |
||
854 | newqad(0); |
||
855 | } |
||
856 | |||
857 | void probe(void) { |
||
858 | double angle, bigger; |
||
859 | int key; |
||
860 | /* New code to launch a deep space probe */ |
||
861 | if (nprobes == 0) { |
||
862 | chew(); |
||
863 | skip(1); |
||
864 | if (ship == IHE) |
||
865 | prout("Engineer Scott- \"We have no more deep space probes, Sir.\""); |
||
866 | else |
||
867 | prout("Ye Faerie Queene has no deep space probes."); |
||
868 | return; |
||
869 | } |
||
870 | if (damage[DDSP] != 0.0) { |
||
871 | chew(); |
||
872 | skip(1); |
||
873 | prout("Engineer Scott- \"The probe launcher is damaged, Sir.\""); |
||
874 | return; |
||
875 | } |
||
876 | if (future[FDSPROB] != 1e30) { |
||
877 | chew(); |
||
878 | skip(1); |
||
879 | if (REPORTS) { |
||
880 | prout("Uhura- \"The previous probe is still reporting data, Sir.\""); |
||
881 | } else { |
||
882 | prout("Spock- \"Records show the previous probe has not yet"); |
||
883 | prout(" reached its destination.\""); |
||
884 | } |
||
885 | return; |
||
886 | } |
||
887 | key = scan(); |
||
888 | |||
889 | if (key == IHEOL) { |
||
890 | /* slow mode, so let Kirk know how many probes there are left */ |
||
891 | crami(nprobes,1); |
||
892 | prout(nprobes==1 ? " probe left." : " probes left."); |
||
893 | proutn("Are you sure you want to fire a probe? "); |
||
894 | if (ja()==0) return; |
||
895 | } |
||
896 | |||
897 | isarmed = FALSE; |
||
898 | if (key == IHALPHA && strcmp(citem,"armed") == 0) { |
||
899 | isarmed = TRUE; |
||
900 | key = scan(); |
||
901 | } |
||
902 | else if (key == IHEOL) { |
||
903 | proutn("Arm NOVAMAX warhead?"); |
||
904 | isarmed = ja(); |
||
905 | } |
||
906 | getcd(TRUE, key); |
||
907 | if (direc == -1.0) return; |
||
908 | nprobes--; |
||
909 | angle = ((15.0 - direc) * 0.5235988); |
||
910 | probeinx = -sin(angle); |
||
911 | probeiny = cos(angle); |
||
912 | if (fabs(probeinx) > fabs(probeiny)) |
||
913 | bigger = fabs(probeinx); |
||
914 | else |
||
915 | bigger = fabs(probeiny); |
||
916 | |||
917 | probeiny /= bigger; |
||
918 | probeinx /= bigger; |
||
919 | proben = 10.0*dist*bigger +0.5; |
||
920 | probex = quadx*10 + sectx - 1; // We will use better packing than original |
||
921 | probey = quady*10 + secty - 1; |
||
922 | probecx = quadx; |
||
923 | probecy = quady; |
||
924 | future[FDSPROB] = d.date + 0.01; // Time to move one sector |
||
925 | prout("Ensign Chekov- \"The deep space probe is launched, Captain.\""); |
||
926 | return; |
||
927 | } |
||
928 | |||
929 | void help(void) { |
||
930 | /* There's more than one way to move in this game! */ |
||
931 | double ddist, xdist, probf; |
||
932 | int line, l, ix, iy; |
||
933 | |||
934 | chew(); |
||
935 | /* Test for conditions which prevent calling for help */ |
||
936 | if (condit == IHDOCKED) { |
||
937 | prout("Lt. Uhura- \"But Captain, we're already docked.\""); |
||
938 | return; |
||
939 | } |
||
940 | if (damage[DRADIO] != 0) { |
||
941 | prout("Subspace radio damaged."); |
||
942 | return; |
||
943 | } |
||
944 | if (d.rembase==0) { |
||
945 | prout("Lt. Uhura- \"Captain, I'm not getting any response from Starbase.\""); |
||
946 | return; |
||
947 | } |
||
948 | if (landed == 1) { |
||
949 | proutn("You must be aboard the "); |
||
950 | crmshp(); |
||
951 | prout("."); |
||
952 | return; |
||
953 | } |
||
954 | /* OK -- call for help from nearest starbase */ |
||
955 | nhelp++; |
||
956 | if (basex!=0) { |
||
957 | /* There's one in this quadrant */ |
||
958 | ddist = sqrt(square(basex-sectx)+square(basey-secty)); |
||
959 | } |
||
960 | else { |
||
961 | ddist = 1e30; |
||
962 | for (l = 1; l <= d.rembase; l++) { |
||
963 | xdist=10.0*sqrt(square(d.baseqx[l]-quadx)+square(d.baseqy[l]-quady)); |
||
964 | if (xdist < ddist) { |
||
965 | ddist = xdist; |
||
966 | line = l; |
||
967 | } |
||
968 | } |
||
969 | /* Since starbase not in quadrant, set up new quadrant */ |
||
970 | quadx = d.baseqx[line]; |
||
971 | quady = d.baseqy[line]; |
||
972 | newqad(1); |
||
973 | } |
||
974 | /* dematerialize starship */ |
||
975 | quad[sectx][secty]=IHDOT; |
||
976 | proutn("Starbase in"); |
||
977 | cramlc(1, quadx, quady); |
||
978 | proutn(" responds--"); |
||
979 | crmshp(); |
||
980 | prout(" dematerializes."); |
||
981 | /* Give starbase three chances to rematerialize starship */ |
||
982 | probf = pow((1.0 - pow(0.98,ddist)), 0.33333333); |
||
983 | for (l = 1; l <= 3; l++) { |
||
984 | switch (l) { |
||
985 | case 1: proutn("1st"); break; |
||
986 | case 2: proutn("2nd"); break; |
||
987 | case 3: proutn("3rd"); break; |
||
988 | } |
||
989 | proutn(" attempt to re-materialize "); |
||
990 | crmshp(); |
||
991 | prouts(" . . . . . "); |
||
992 | if (Rand() > probf) break; |
||
993 | prout("fails."); |
||
994 | } |
||
995 | if (l > 3) { |
||
996 | finish(FMATERIALIZE); |
||
997 | return; |
||
998 | } |
||
999 | /* Rematerialization attempt should succeed if can get adj to base */ |
||
1000 | for (l = 1; l <= 5; l++) { |
||
1001 | ix = basex+3.0*Rand()-1; |
||
1002 | iy = basey+3.0*Rand()-1; |
||
1003 | if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && quad[ix][iy]==IHDOT) { |
||
1004 | /* found one -- finish up */ |
||
1005 | prout("succeeds."); |
||
1006 | sectx=ix; |
||
1007 | secty=iy; |
||
1008 | quad[ix][iy]=ship; |
||
1009 | dock(); |
||
1010 | skip(1); |
||
1011 | prout("Lt. Uhura- \"Captain, we made it!\""); |
||
1012 | return; |
||
1013 | } |
||
1014 | } |
||
1015 | finish(FMATERIALIZE); |
||
1016 | return; |
||
1017 | }=10>=10>=>=>>=>=>=>=>>>=>=>>=>=>>=>>>=>=>=>>1>1>1>1>>>=>=>=>=>=>=>>>=> |