6 prout("-SUPER- STAR TREK");
\r
8 prout("Latest update-21 Sept 78");
\r
12 void freeze(int boss) {
\r
17 strcpy(citem, "emsave.trk");
\r
20 if ((key = scan()) == IHEOL) {
\r
21 proutn("File name: ");
\r
24 if (key != IHALPHA) {
\r
29 if (strchr(citem, '.') == NULL) {
\r
30 strcat(citem, ".trk");
\r
33 if ((fp = fopen(citem, "wb")) == NULL) {
\r
34 proutn("Can't freeze game as file ");
\r
39 fwrite(&d, sizeof(d), 1, fp);
\r
40 fwrite(&snapsht, sizeof(snapsht), 1, fp);
\r
41 fwrite(quad, sizeof(quad), 1, fp);
\r
42 fwrite(kx, sizeof(kx), 1, fp);
\r
43 fwrite(ky, sizeof(ky), 1, fp);
\r
44 fwrite(starch, sizeof(starch), 1, fp);
\r
45 fwrite(kpower, sizeof(kpower), 1, fp);
\r
46 fwrite(kdist, sizeof(kdist), 1, fp);
\r
47 fwrite(kavgd, sizeof(kavgd), 1, fp);
\r
48 fwrite(damage, sizeof(damage), 1, fp);
\r
49 fwrite(future, sizeof(future), 1, fp);
\r
50 fwrite(&game, sizeof(game), 1, fp);
\r
51 fwrite(passwd, sizeof(passwd), 1, fp);
\r
55 /* I hope that's enough! */
\r
65 if ((key = scan()) == IHEOL) {
\r
66 proutn("File name: ");
\r
69 if (key != IHALPHA) {
\r
74 if (strchr(citem, '.') == NULL) {
\r
75 strcat(citem, ".trk");
\r
77 if ((fp = fopen(citem, "rb")) == NULL) {
\r
78 proutn("Can't find game file ");
\r
83 fread(&d, sizeof(d), 1, fp);
\r
84 fread(&snapsht, sizeof(snapsht), 1, fp);
\r
85 fread(quad, sizeof(quad), 1, fp);
\r
86 fread(kx, sizeof(kx), 1, fp);
\r
87 fread(ky, sizeof(ky), 1, fp);
\r
88 fread(starch, sizeof(starch), 1, fp);
\r
89 fread(kpower, sizeof(kpower), 1, fp);
\r
90 fread(kdist, sizeof(kdist), 1, fp);
\r
91 fread(kavgd, sizeof(kavgd), 1, fp);
\r
92 fread(damage, sizeof(damage), 1, fp);
\r
93 fread(future, sizeof(future), 1, fp);
\r
94 fread(&game, sizeof(game), 1, fp);
\r
95 fread(passwd, sizeof(passwd), 1, fp);
\r
99 /* I hope that's enough! */
\r
102 void abandn(void) {
\r
106 if (condit==IHDOCKED) {
\r
108 prout("You cannot abandon Ye Faerie Queene.");
\r
113 /* Must take shuttle craft to exit */
\r
114 if (damage[DSHUTTL]==-1) {
\r
115 prout("Ye Faerie Queene has no shuttle craft.");
\r
118 if (damage[DSHUTTL]<0) {
\r
119 prout("Shuttle craft now serving Big Mac's.");
\r
122 if (damage[DSHUTTL]>0) {
\r
123 prout("Shuttle craft damaged.");
\r
127 prout("You must be aboard the Enterprise.");
\r
131 prout("Shuttle craft not currently available.");
\r
134 /* Print abandon ship messages */
\r
136 prouts("***ABANDON SHIP! ABANDON SHIP!");
\r
138 prouts("***ALL HANDS ABANDON SHIP!");
\r
140 prout("Captain and crew escape in shuttle craft.");
\r
141 prout("Remainder of ship's complement beam down");
\r
142 prout("to nearest habitable planet.");
\r
143 if (d.rembase==0) {
\r
144 /* Ops! no place to go... */
\r
148 /* If at least one base left, give 'em the Faerie Queene */
\r
150 icrystl = 0; /* crystals are lost */
\r
151 nprobes = 0; /* No probes */
\r
152 prout("You are captured by Klingons and released to");
\r
153 prout("the Federation in a prisoner-of-war exchange.");
\r
154 nb = Rand()*d.rembase+1;
\r
155 /* Set up quadrant and position FQ adjacient to base */
\r
156 if (quadx!=d.baseqx[nb] || quady!=d.baseqy[nb]) {
\r
157 quadx = d.baseqx[nb];
\r
158 quady = d.baseqy[nb];
\r
163 /* position next to base by trial and error */
\r
164 quad[sectx][secty] = IHDOT;
\r
165 for (l = 1; l <= 10; l++) {
\r
166 sectx = 3.0*Rand() - 1.0 + basex;
\r
167 secty = 3.0*Rand() - 1.0 + basey;
\r
168 if (sectx >= 1 && sectx <= 10 &&
\r
169 secty >= 1 && secty <= 10 &&
\r
170 quad[sectx][secty] == IHDOT) break;
\r
172 if (l < 11) break; /* found a spot */
\r
178 /* Get new commission */
\r
179 quad[sectx][secty] = ship = IHF;
\r
180 prout("Starfleet puts you in command of another ship,");
\r
181 prout("the Faerie Queene, which is antiquated but,");
\r
182 prout("still useable.");
\r
183 if (icrystl!=0) prout("The dilithium crystals have been moved.");
\r
185 iscraft=0; /* Gallileo disappears */
\r
186 /* Resupply ship */
\r
188 for (l = 1; l <= ndevice; l++) damage[l] = 0.0;
\r
189 damage[DSHUTTL] = -1;
\r
190 energy = inenrg = 3000.0;
\r
191 shield = inshld = 1250.0;
\r
192 torps = intorps = 6;
\r
201 int i,j, krem, klumper;
\r
203 alldone = gamewon = 0;
\r
207 // Decide how many of everything
\r
208 if (choose()) return; // frozen game
\r
209 // Prepare the Enterprise
\r
211 energy = inenrg = 5000.0;
\r
212 shield = inshld = 2500.0;
\r
213 shldchg = shldup = 0;
\r
216 iran8(&quadx, &quady);
\r
217 iran10(§x, §y);
\r
218 torps = intorps = 10;
\r
219 nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */
\r
221 wfacsq = warpfac * warpfac;
\r
222 for (i=0; i <= ndevice; i++) damage[i] = 0.0;
\r
223 // Set up assorted game parameters
\r
225 d.date = indate = 100.0*(int)(31.0*Rand()+20.0);
\r
226 d.killk = d.killc = nkinks = nhelp = resting = casual = d.nromkl = 0;
\r
227 isatb = iscate = imine = icrystl = icraft = d.nsckill = d.nplankl = 0;
\r
232 for (i = 1; i <= 8; i++)
\r
233 for (j = 1; j <= 8; j++) d.newstuf[i][j] = starch[i][j] = 0;
\r
234 // Initialize times for extraneous events
\r
235 future[FSNOVA] = d.date + expran(0.5 * intime);
\r
236 future[FTBEAM] = d.date + expran(1.5 * (intime / d.remcom));
\r
237 future[FSNAP] = d.date + 1.0 + Rand(); // Force an early snapshot
\r
238 future[FBATTAK] = d.date + expran(0.3*intime);
\r
239 future[FCDBAS] = 1e30;
\r
240 future[FSCMOVE] = d.nscrem ? d.date+0.2777 : 1e30;
\r
241 future[FSCDBAS] = 1e30;
\r
242 future[FDSPROB] = 1e30;
\r
243 // Starchart is functional
\r
245 // Put stars in the galaxy
\r
247 for (i=1; i<=8; i++)
\r
248 for (j=1; j<=8; j++) {
\r
249 int k = Rand()*9.0 + 1.0;
\r
251 d.galaxy[i][j] = k;
\r
253 // Locate star bases in galaxy
\r
254 for (i = 1; i <= inbase; i++) {
\r
257 do iran8(&ix, &iy);
\r
258 while (d.galaxy[ix][iy] >= 10);
\r
260 for (j = i-1; j > 0; j--) {
\r
261 /* Improved placement algorithm to spread out bases */
\r
262 double distq = square(ix-d.baseqx[j]) + square(iy-d.baseqy[j]);
\r
263 if (distq < 6.0*(6-inbase) && Rand() < 0.75) {
\r
266 printf("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);
\r
271 else if (distq < 6.0 * (6-inbase)) {
\r
272 printf("DEBUG: saving base #%d, close to #%d\n", i, j);
\r
276 } while (contflag);
\r
280 starch[ix][iy] = -1;
\r
281 d.galaxy[ix][iy] += 10;
\r
283 // Position ordinary Klingon Battle Cruisers
\r
284 krem = inkling - incom - d.nscrem;
\r
285 klumper = 0.25*skill*(9.0-length)+1.0;
\r
286 if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant
\r
289 int klump = (1.0 - r*r)*klumper;
\r
290 if (klump > krem) klump = krem;
\r
293 do iran8(&ix, &iy);
\r
294 while (d.galaxy[ix][iy] + klump >= 1000);
\r
295 d.galaxy[ix][iy] += klump;
\r
296 } while (krem > 0);
\r
297 // Position Klingon Commander Ships
\r
301 for (i = 1; i <= incom; i++) {
\r
303 do { /* IF debugging, put commanders by bases, always! */
\r
305 if (idebug && klumper <= inbase) {
\r
306 ix = d.baseqx[klumper];
\r
307 iy = d.baseqy[klumper];
\r
314 while ((d.galaxy[ix][iy] < 99 && Rand() < 0.75)||
\r
315 d.galaxy[ix][iy]>899);
\r
316 // check for duplicate
\r
317 for (j = 1; j < i; j++)
\r
318 if (d.cx[j]==ix && d.cy[j]==iy) break;
\r
320 d.galaxy[ix][iy] += 100;
\r
324 // Locate planets in galaxy
\r
325 for (i = 1; i <= inplan; i++) {
\r
326 do iran8(&ix, &iy);
\r
327 while (d.newstuf[ix][iy] > 0);
\r
328 d.newstuf[ix][iy] = 1;
\r
329 d.plnets[i].x = ix;
\r
330 d.plnets[i].y = iy;
\r
331 d.plnets[i].pclass = Rand()*3.0 + 1.0; // Planet class M N or O
\r
332 d.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals
\r
333 d.plnets[i].known = 0;
\r
336 for (i = 1; i <= d.nromrem; i++) {
\r
338 d.newstuf[ix][iy] += 10;
\r
340 // Locate the Super Commander
\r
341 if (d.nscrem > 0) {
\r
342 do iran8(&ix, &iy);
\r
343 while (d.galaxy[ix][iy] >= 900);
\r
346 d.galaxy[ix][iy] += 100;
\r
348 // Place thing (in tournament game, thingx == -1, don't want one!)
\r
349 if (Rand() < 0.1 && thingx != -1) {
\r
350 iran8(&thingx, &thingy);
\r
353 thingx = thingy = 0;
\r
361 printf("It is stardate %d. The Federation is being attacked by\n",
\r
363 printf("a deadly Klingon invasion force. As captain of the United\n"
\r
364 "Starship U.S.S. Enterprise, it is your mission to seek out\n"
\r
365 "and destroy this invasion force of %d battle cruisers.\n",
\r
367 printf("You have an initial allotment of %d stardates to complete\n"
\r
368 "your mission. As you proceed you may be given more time.\n\n"
\r
369 "You will have %d supporting starbases.\n"
\r
370 "Starbase locations- ",
\r
371 (int)intime, inbase);
\r
374 printf("Stardate %d.\n\n"
\r
375 "%d Klingons.\nAn unknown number of Romulans\n",
\r
376 (int)d.date, inkling);
\r
377 if (d.nscrem) printf("and one (GULP) Super-Commander.\n");
\r
378 printf("%d stardates\n%d starbases in ",(int)intime, inbase);
\r
380 for (i = 1; i <= inbase; i++) {
\r
381 cramlc(0, d.baseqx[i], d.baseqy[i]);
\r
382 if (i < inbase) proutn(" ");
\r
385 proutn("The Enterprise is currently in");
\r
386 cramlc(1, quadx, quady);
\r
388 cramlc(2, sectx, secty);
\r
390 prout("Good Luck!");
\r
391 if (d.nscrem) proutn(" YOU'LL NEED IT.");
\r
394 if (nenhere) shldup=1.0;
\r
395 if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone
\r
404 if (fromcommandline) /* Can start with command line options */
\r
405 fromcommandline = 0;
\r
407 proutn("Would you like a regular, tournament, or frozen game?");
\r
409 if (strlen(citem)==0) continue; // Try again
\r
410 if (isit("tournament")) {
\r
411 while (scan() == IHEOL) {
\r
412 proutn("Type in tournament number-");
\r
416 continue; // We don't want a blank entry
\r
418 tourn = (int)aaitem;
\r
420 srand((unsigned int)(int)aaitem);
\r
423 if (isit("frozen")) {
\r
426 if (*passwd==0) continue;
\r
428 Rand(); Rand(); Rand(); Rand();
\r
429 if (!alldone) thawed = 1; // No plaque if not finished
\r
433 if (isit("regular")) {
\r
436 Rand(); Rand(); Rand(); Rand();
\r
439 proutn("What is \"");
\r
444 while (length==0 || skill==0) {
\r
445 if (scan() == IHALPHA) {
\r
446 if (isit("short")) length = 1;
\r
447 else if (isit("medium")) length = 2;
\r
448 else if (isit("long")) length = 4;
\r
449 else if (isit("novice")) skill = 1;
\r
450 else if (isit("fair")) skill = 2;
\r
451 else if (isit("good")) skill = 3;
\r
452 else if (isit("expert")) skill = 4;
\r
453 else if (isit("emeritus")) skill = 5;
\r
455 proutn("What is \"");
\r
462 if (length==0) proutn("Would you like a Short, Medium, or Long game? ");
\r
463 else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player?");
\r
468 strcpy(passwd, citem);
\r
470 if (*passwd != 0) break;
\r
471 proutn("Please type in a secret password-");
\r
474 if (strcmp(passwd, "debug")==0) idebug = 1;
\r
477 // Use parameters to generate initial values of things
\r
478 damfac = 0.5 * skill;
\r
479 d.rembase = 3.0*Rand()+2.0;
\r
480 inbase = d.rembase;
\r
481 inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();
\r
482 d.nromrem = (2.0+Rand())*skill;
\r
483 d.nscrem = (skill > 2? 1 : 0);
\r
484 d.remtime = 7.0 * length;
\r
485 intime = d.remtime;
\r
486 d.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);
\r
488 incom = skill + 0.0625*inkling*Rand();
\r
489 d.remcom= min(10, incom);
\r
491 d.remres = (inkling+4*incom)*intime;
\r
492 inresor = d.remres;
\r
493 if (inkling > 50) {
\r
494 inbase = (d.rembase += 1);
\r
499 void dropin(int iquad, int *ix, int *iy) {
\r
501 while (quad[*ix][*iy] != IHDOT);
\r
502 quad[*ix][*iy] = iquad;
\r
505 void newcnd(void) {
\r
507 if (energy < 1000.0) condit = IHYELLOW;
\r
508 if (d.galaxy[quadx][quady] > 99 || d.newstuf[quadx][quady] > 9)
\r
513 void newqad(int shutup) {
\r
514 int quadnum = d.galaxy[quadx][quady];
\r
515 int newnum = d.newstuf[quadx][quady];
\r
516 int i, j, ix, iy, nplan;
\r
523 plnetx = plnety = 0;
\r
535 // Attempt to escape Super-commander, so tbeam back!
\r
540 for (i=1; i <= 10; i++)
\r
541 for (j=1; j <= 10; j++) quad[i][j] = IHDOT;
\r
542 // cope with supernova
\r
543 if (quadnum > 999) {
\r
546 klhere = quadnum/100;
\r
547 irhere = newnum/10;
\r
549 nenhere = klhere + irhere;
\r
551 // Position Starship
\r
552 quad[sectx][secty] = ship;
\r
554 // Decide if quadrant needs a Tholian
\r
555 if ((skill < 3 && Rand() <= 0.02) || /* Lighten up if skill is low */
\r
556 (skill == 3 && Rand() <= 0.05) ||
\r
557 (skill > 3 && Rand() <= 0.08)
\r
559 || strcmp(passwd, "tholianx")==0
\r
563 ithx = Rand() > 0.5 ? 10 : 1;
\r
564 ithy = Rand() > 0.5 ? 10 : 1;
\r
565 } while (quad[ithx][ithy] != IHDOT);
\r
566 quad[ithx][ithy] = IHT;
\r
568 /* Reserve unocupied corners */
\r
569 if (quad[1][1]==IHDOT) quad[1][1] = 'X';
\r
570 if (quad[1][10]==IHDOT) quad[1][10] = 'X';
\r
571 if (quad[10][1]==IHDOT) quad[10][1] = 'X';
\r
572 if (quad[10][10]==IHDOT) quad[10][10] = 'X';
\r
575 if (quadnum >= 100) {
\r
576 // Position ordinary Klingons
\r
577 quadnum -= 100*klhere;
\r
578 for (i = 1; i <= klhere; i++) {
\r
579 dropin(IHK, &ix, &iy);
\r
582 kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
583 kpower[i] = Rand()*150.0 +300.0 +25.0*skill;
\r
585 // If we need a commander, promote a Klingon
\r
586 for (i = 1; i <= d.remcom ; i++)
\r
587 if (d.cx[i]==quadx && d.cy[i]==quady) break;
\r
589 if (i <= d.remcom) {
\r
590 quad[ix][iy] = IHC;
\r
591 kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;
\r
595 // If we need a super-commander, promote a Klingon
\r
596 if (quadx == d.isx && quady == d.isy) {
\r
597 quad[kx[1]][ky[1]] = IHS;
\r
598 kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;
\r
603 // Put in Romulans if needed
\r
604 for (i = klhere+1; i <= nenhere; i++) {
\r
605 dropin(IHR, &ix, &iy);
\r
608 kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
609 kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
\r
612 // If quadrant needs a starbase, put it in
\r
613 if (quadnum >= 10) {
\r
615 dropin(IHB, &basex, &basey);
\r
619 // If quadrant needs a planet, put it in
\r
620 for (i=1; i <= inplan; i++)
\r
621 if (d.plnets[i].x == quadx && d.plnets[i].y == quady) break;
\r
624 dropin(IHP, &plnetx, &plnety);
\r
627 // Check for condition
\r
629 // And finally the stars
\r
630 for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
\r
633 if (irhere > 0 && klhere == 0 && basex == 0) {
\r
635 if (damage[DRADIO] <= 0.0) {
\r
637 prout("LT. Uhura- \"Captain, an urgent message.");
\r
638 prout(" I'll put it on audio.\" CLICK");
\r
640 prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");
\r
641 prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");
\r
646 // Put in THING if needed
\r
647 if (thingx == quadx && thingy == quady) {
\r
648 dropin(IHQUEST, &ix, &iy);
\r
649 thingx = thingy = 0; // Transient
\r
650 if (damage[DSRSENS] == 0.0) {
\r
652 prout("MR. SPOCK- \"Captain, this is most unusual.");
\r
653 prout(" Please examine your short-range scan.\"");
\r
658 // Put in a few black holes
\r
659 for (i = 1; i <= 3; i++)
\r
660 if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
\r
662 // Take out X's in corners if Tholian present
\r
664 if (quad[1][1]=='X') quad[1][1] = IHDOT;
\r
665 if (quad[1][10]=='X') quad[1][10] = IHDOT;
\r
666 if (quad[10][1]=='X') quad[10][1] = IHDOT;
\r
667 if (quad[10][10]=='X') quad[10][10] = IHDOT;
\r
671 void sortkl(void) {
\r
675 // The author liked bubble sort. So we will use it. :-(
\r
677 if (nenhere < 2) return;
\r
681 for (j = 1; j < nenhere; j++)
\r
682 if (kdist[j] > kdist[j+1]) {
\r
685 kdist[j] = kdist[j+1];
\r
688 kavgd[j] = kavgd[j+1];
\r
697 kpower[j] = kpower[j+1];
\r