Subversion Repositories Kolibri OS

Rev

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
}