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(&state, sizeof(state), 1, fp);
\r
40 fwrite(&snapsht, sizeof(snapsht), 1, fp);
\r
41 fwrite(kx, sizeof(kx), 1, fp);
\r
42 fwrite(ky, sizeof(ky), 1, fp);
\r
43 fwrite(starch, sizeof(starch), 1, fp);
\r
44 fwrite(kpower, sizeof(kpower), 1, fp);
\r
45 fwrite(kdist, sizeof(kdist), 1, fp);
\r
46 fwrite(kavgd, sizeof(kavgd), 1, fp);
\r
47 fwrite(damage, sizeof(damage), 1, fp);
\r
48 fwrite(future, sizeof(future), 1, fp);
\r
49 fwrite(&frozen, sizeof(frozen), 1, fp);
\r
50 fwrite(passwd, sizeof(passwd), 1, fp);
\r
54 /* I hope that's enough! */
\r
64 if ((key = scan()) == IHEOL) {
\r
65 proutn("File name: ");
\r
68 if (key != IHALPHA) {
\r
73 if (strchr(citem, '.') == NULL) {
\r
74 strcat(citem, ".trk");
\r
76 if ((fp = fopen(citem, "rb")) == NULL) {
\r
77 proutn("Can't find game file ");
\r
82 fread(&state, sizeof(state), 1, fp);
\r
83 fread(&snapsht, sizeof(snapsht), 1, fp);
\r
84 fread(kx, sizeof(kx), 1, fp);
\r
85 fread(ky, sizeof(ky), 1, fp);
\r
86 fread(starch, sizeof(starch), 1, fp);
\r
87 fread(kpower, sizeof(kpower), 1, fp);
\r
88 fread(kdist, sizeof(kdist), 1, fp);
\r
89 fread(kavgd, sizeof(kavgd), 1, fp);
\r
90 fread(damage, sizeof(damage), 1, fp);
\r
91 fread(future, sizeof(future), 1, fp);
\r
92 fread(&frozen, sizeof(frozen), 1, fp);
\r
93 fread(passwd, sizeof(passwd), 1, fp);
\r
97 /* I hope that's enough! */
\r
100 void abandn(void) {
\r
104 if (condit==IHDOCKED) {
\r
106 prout("You cannot abandon Ye Faerie Queene.");
\r
111 /* Must take shuttle craft to exit */
\r
112 if (damage[DSHUTTL]==-1) {
\r
113 prout("Ye Faerie Queene has no shuttle craft.");
\r
116 if (damage[DSHUTTL]<0) {
\r
117 prout("Shuttle craft now serving Big Mac's.");
\r
120 if (damage[DSHUTTL]>0) {
\r
121 prout("Shuttle craft damaged.");
\r
125 prout("You must be aboard the Enterprise.");
\r
129 prout("Shuttle craft not currently available.");
\r
132 /* Print abandon ship messages */
\r
134 prouts("***ABANDON SHIP! ABANDON SHIP!");
\r
136 prouts("***ALL HANDS ABANDON SHIP!");
\r
138 prout("Captain and crew escape in shuttle craft.");
\r
139 prout("Remainder of ship's complement beam down");
\r
140 prout("to nearest habitable planet.");
\r
141 if (state.rembase==0) {
\r
142 /* Ops! no place to go... */
\r
146 /* If at least one base left, give 'em the Faerie Queene */
\r
148 icrystl = 0; /* crystals are lost */
\r
149 nprobes = 0; /* No probes */
\r
150 prout("You are captured by Klingons and released to");
\r
151 prout("the Federation in a prisoner-of-war exchange.");
\r
152 nb = Rand()*state.rembase+1;
\r
153 /* Set up quadrant and position FQ adjacient to base */
\r
154 if (quadx!=state.baseqx[nb] || quady!=state.baseqy[nb]) {
\r
155 quadx = state.baseqx[nb];
\r
156 quady = state.baseqy[nb];
\r
161 /* position next to base by trial and error */
\r
162 frozen.quad[sectx][secty] = IHDOT;
\r
163 for (l = 1; l <= 10; l++) {
\r
164 sectx = 3.0*Rand() - 1.0 + basex;
\r
165 secty = 3.0*Rand() - 1.0 + basey;
\r
166 if (sectx >= 1 && sectx <= 10 &&
\r
167 secty >= 1 && secty <= 10 &&
\r
168 frozen.quad[sectx][secty] == IHDOT) break;
\r
170 if (l < 11) break; /* found a spot */
\r
176 /* Get new commission */
\r
177 frozen.quad[sectx][secty] = ship = IHF;
\r
178 prout("Starfleet puts you in command of another ship,");
\r
179 prout("the Faerie Queene, which is antiquated but,");
\r
180 prout("still useable.");
\r
181 if (icrystl!=0) prout("The dilithium crystals have been moved.");
\r
183 iscraft=0; /* Gallileo disappears */
\r
184 /* Resupply ship */
\r
186 for (l = 1; l <= ndevice; l++) damage[l] = 0.0;
\r
187 damage[DSHUTTL] = -1;
\r
188 energy = inenrg = 3000.0;
\r
189 shield = inshld = 1250.0;
\r
190 torps = intorps = 6;
\r
199 int i,j, krem, klumper;
\r
201 alldone = gamewon = 0;
\r
205 // Decide how many of everything
\r
206 if (choose()) return; // frozen game
\r
207 // Prepare the Enterprise
\r
209 energy = inenrg = 5000.0;
\r
210 shield = inshld = 2500.0;
\r
211 shldchg = shldup = 0;
\r
214 iran8(&quadx, &quady);
\r
215 iran10(§x, §y);
\r
216 torps = intorps = 10;
\r
217 nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */
\r
219 wfacsq = warpfac * warpfac;
\r
220 for (i=0; i <= ndevice; i++) damage[i] = 0.0;
\r
221 // Set up assorted game parameters
\r
223 state.date = indate = 100.0*(int)(31.0*Rand()+20.0);
\r
224 state.killk = state.killc = nkinks = nhelp = resting = casual = state.nromkl = 0;
\r
225 isatb = iscate = imine = icrystl = icraft = state.nsckill = state.nplankl = 0;
\r
230 for (i = 1; i <= 8; i++)
\r
231 for (j = 1; j <= 8; j++) state.newstuf[i][j] = starch[i][j] = 0;
\r
232 // Initialize times for extraneous events
\r
233 future[FSNOVA] = state.date + expran(0.5 * intime);
\r
234 future[FTBEAM] = state.date + expran(1.5 * (intime / state.remcom));
\r
235 future[FSNAP] = state.date + 1.0 + Rand(); // Force an early snapshot
\r
236 future[FBATTAK] = state.date + expran(0.3*intime);
\r
237 future[FCDBAS] = 1e30;
\r
238 future[FSCMOVE] = state.nscrem ? state.date+0.2777 : 1e30;
\r
239 future[FSCDBAS] = 1e30;
\r
240 future[FDSPROB] = 1e30;
\r
241 // Starchart is functional
\r
243 // Put stars in the galaxy
\r
245 for (i=1; i<=8; i++)
\r
246 for (j=1; j<=8; j++) {
\r
247 int k = Rand()*9.0 + 1.0;
\r
249 state.galaxy[i][j] = k;
\r
251 // Locate star bases in galaxy
\r
252 for (i = 1; i <= inbase; i++) {
\r
255 do iran8(&ix, &iy);
\r
256 while (state.galaxy[ix][iy] >= 10);
\r
258 for (j = i-1; j > 0; j--) {
\r
259 /* Improved placement algorithm to spread out bases */
\r
260 double distq = square(ix-state.baseqx[j]) + square(iy-state.baseqy[j]);
\r
261 if (distq < 6.0*(6-inbase) && Rand() < 0.75) {
\r
264 printf("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);
\r
269 else if (distq < 6.0 * (6-inbase)) {
\r
270 printf("DEBUG: saving base #%d, close to #%d\n", i, j);
\r
274 } while (contflag);
\r
276 state.baseqx[i] = ix;
\r
277 state.baseqy[i] = iy;
\r
278 starch[ix][iy] = -1;
\r
279 state.galaxy[ix][iy] += 10;
\r
281 // Position ordinary Klingon Battle Cruisers
\r
282 krem = inkling - incom - state.nscrem;
\r
283 klumper = 0.25*skill*(9.0-length)+1.0;
\r
284 if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant
\r
287 int klump = (1.0 - r*r)*klumper;
\r
288 if (klump > krem) klump = krem;
\r
291 do iran8(&ix, &iy);
\r
292 while (state.galaxy[ix][iy] + klump >= 1000);
\r
293 state.galaxy[ix][iy] += klump;
\r
294 } while (krem > 0);
\r
295 // Position Klingon Commander Ships
\r
299 for (i = 1; i <= incom; i++) {
\r
301 do { /* IF debugging, put commanders by bases, always! */
\r
303 if (idebug && klumper <= inbase) {
\r
304 ix = state.baseqx[klumper];
\r
305 iy = state.baseqy[klumper];
\r
312 while ((state.galaxy[ix][iy] < 99 && Rand() < 0.75)||
\r
313 state.galaxy[ix][iy]>899);
\r
314 // check for duplicate
\r
315 for (j = 1; j < i; j++)
\r
316 if (state.cx[j]==ix && state.cy[j]==iy) break;
\r
318 state.galaxy[ix][iy] += 100;
\r
322 // Locate planets in galaxy
\r
323 for (i = 1; i <= inplan; i++) {
\r
324 do iran8(&ix, &iy);
\r
325 while (state.newstuf[ix][iy] > 0);
\r
326 state.newstuf[ix][iy] = 1;
\r
327 state.plnets[i].x = ix;
\r
328 state.plnets[i].y = iy;
\r
329 state.plnets[i].pclass = Rand()*3.0 + 1.0; // Planet class M N or O
\r
330 state.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals
\r
331 state.plnets[i].known = 0;
\r
334 for (i = 1; i <= state.nromrem; i++) {
\r
336 state.newstuf[ix][iy] += 10;
\r
338 // Locate the Super Commander
\r
339 if (state.nscrem > 0) {
\r
340 do iran8(&ix, &iy);
\r
341 while (state.galaxy[ix][iy] >= 900);
\r
344 state.galaxy[ix][iy] += 100;
\r
346 // Place thing (in tournament game, thingx == -1, don't want one!)
\r
347 if (Rand() < 0.1 && thingx != -1) {
\r
348 iran8(&thingx, &thingy);
\r
351 thingx = thingy = 0;
\r
359 printf("It is stardate %d. The Federation is being attacked by\n",
\r
361 printf("a deadly Klingon invasion force. As captain of the United\n"
\r
362 "Starship U.S.S. Enterprise, it is your mission to seek out\n"
\r
363 "and destroy this invasion force of %d battle cruisers.\n",
\r
365 printf("You have an initial allotment of %d stardates to complete\n"
\r
366 "your mission. As you proceed you may be given more time.\n\n"
\r
367 "You will have %d supporting starbases.\n"
\r
368 "Starbase locations- ",
\r
369 (int)intime, inbase);
\r
372 printf("Stardate %d.\n\n"
\r
373 "%d Klingons.\nAn unknown number of Romulans\n",
\r
374 (int)state.date, inkling);
\r
375 if (state.nscrem) printf("and one (GULP) Super-Commander.\n");
\r
376 printf("%d stardates\n%d starbases in ",(int)intime, inbase);
\r
378 for (i = 1; i <= inbase; i++) {
\r
379 cramlc(0, state.baseqx[i], state.baseqy[i]);
\r
380 if (i < inbase) proutn(" ");
\r
383 proutn("The Enterprise is currently in");
\r
384 cramlc(1, quadx, quady);
\r
386 cramlc(2, sectx, secty);
\r
388 prout("Good Luck!");
\r
389 if (state.nscrem) proutn(" YOU'LL NEED IT.");
\r
392 if (nenhere) shldup=1.0;
\r
393 if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone
\r
402 if (fromcommandline) /* Can start with command line options */
\r
403 fromcommandline = 0;
\r
405 proutn("Would you like a regular, tournament, or frozen game?");
\r
407 if (strlen(citem)==0) continue; // Try again
\r
408 if (isit("tournament")) {
\r
409 while (scan() == IHEOL) {
\r
410 proutn("Type in tournament number-");
\r
414 continue; // We don't want a blank entry
\r
416 tourn = (int)aaitem;
\r
418 srand((unsigned int)(int)aaitem);
\r
421 if (isit("frozen")) {
\r
424 if (*passwd==0) continue;
\r
426 Rand(); Rand(); Rand(); Rand();
\r
427 if (!alldone) thawed = 1; // No plaque if not finished
\r
431 if (isit("regular")) {
\r
434 Rand(); Rand(); Rand(); Rand();
\r
437 proutn("What is \"");
\r
442 while (length==0 || skill==0) {
\r
443 if (scan() == IHALPHA) {
\r
444 if (isit("short")) length = 1;
\r
445 else if (isit("medium")) length = 2;
\r
446 else if (isit("long")) length = 4;
\r
447 else if (isit("novice")) skill = 1;
\r
448 else if (isit("fair")) skill = 2;
\r
449 else if (isit("good")) skill = 3;
\r
450 else if (isit("expert")) skill = 4;
\r
451 else if (isit("emeritus")) skill = 5;
\r
453 proutn("What is \"");
\r
460 if (length==0) proutn("Would you like a Short, Medium, or Long game? ");
\r
461 else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player?");
\r
466 strcpy(passwd, citem);
\r
468 if (*passwd != 0) break;
\r
469 proutn("Please type in a secret password-");
\r
472 if (strcmp(passwd, "debug")==0) idebug = 1;
\r
475 // Use parameters to generate initial values of things
\r
476 damfac = 0.5 * skill;
\r
477 state.rembase = 3.0*Rand()+2.0;
\r
478 inbase = state.rembase;
\r
479 inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();
\r
480 state.nromrem = (2.0+Rand())*skill;
\r
481 state.nscrem = (skill > 2? 1 : 0);
\r
482 state.remtime = 7.0 * length;
\r
483 intime = state.remtime;
\r
484 state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);
\r
485 inkling = state.remkl;
\r
486 incom = skill + 0.0625*inkling*Rand();
\r
487 state.remcom= min(10, incom);
\r
488 incom = state.remcom;
\r
489 state.remres = (inkling+4*incom)*intime;
\r
490 inresor = state.remres;
\r
491 if (inkling > 50) {
\r
492 inbase = (state.rembase += 1);
\r
497 void dropin(int iquad, int *ix, int *iy) {
\r
499 while (frozen.quad[*ix][*iy] != IHDOT);
\r
500 frozen.quad[*ix][*iy] = iquad;
\r
503 void newcnd(void) {
\r
505 if (energy < 1000.0) condit = IHYELLOW;
\r
506 if (state.galaxy[quadx][quady] > 99 || state.newstuf[quadx][quady] > 9)
\r
511 void newqad(int shutup) {
\r
512 int quadnum = state.galaxy[quadx][quady];
\r
513 int newnum = state.newstuf[quadx][quady];
\r
514 int i, j, ix, iy, nplan;
\r
521 plnetx = plnety = 0;
\r
533 // Attempt to escape Super-commander, so tbeam back!
\r
538 for (i=1; i <= 10; i++)
\r
539 for (j=1; j <= 10; j++) frozen.quad[i][j] = IHDOT;
\r
540 // cope with supernova
\r
541 if (quadnum > 999) {
\r
544 klhere = quadnum/100;
\r
545 irhere = newnum/10;
\r
547 nenhere = klhere + irhere;
\r
549 // Position Starship
\r
550 frozen.quad[sectx][secty] = ship;
\r
552 // Decide if quadrant needs a Tholian
\r
553 if ((skill < 3 && Rand() <= 0.02) || /* Lighten up if skill is low */
\r
554 (skill == 3 && Rand() <= 0.05) ||
\r
555 (skill > 3 && Rand() <= 0.08)
\r
557 || strcmp(passwd, "tholianx")==0
\r
561 ithx = Rand() > 0.5 ? 10 : 1;
\r
562 ithy = Rand() > 0.5 ? 10 : 1;
\r
563 } while (frozen.quad[ithx][ithy] != IHDOT);
\r
564 frozen.quad[ithx][ithy] = IHT;
\r
566 /* Reserve unocupied corners */
\r
567 if (frozen.quad[1][1]==IHDOT) frozen.quad[1][1] = 'X';
\r
568 if (frozen.quad[1][10]==IHDOT) frozen.quad[1][10] = 'X';
\r
569 if (frozen.quad[10][1]==IHDOT) frozen.quad[10][1] = 'X';
\r
570 if (frozen.quad[10][10]==IHDOT) frozen.quad[10][10] = 'X';
\r
573 if (quadnum >= 100) {
\r
574 // Position ordinary Klingons
\r
575 quadnum -= 100*klhere;
\r
576 for (i = 1; i <= klhere; i++) {
\r
577 dropin(IHK, &ix, &iy);
\r
580 kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
581 kpower[i] = Rand()*150.0 +300.0 +25.0*skill;
\r
583 // If we need a commander, promote a Klingon
\r
584 for (i = 1; i <= state.remcom ; i++)
\r
585 if (state.cx[i]==quadx && state.cy[i]==quady) break;
\r
587 if (i <= state.remcom) {
\r
588 frozen.quad[ix][iy] = IHC;
\r
589 kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;
\r
593 // If we need a super-commander, promote a Klingon
\r
594 if (quadx == state.isx && quady == state.isy) {
\r
595 frozen.quad[kx[1]][ky[1]] = IHS;
\r
596 kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;
\r
601 // Put in Romulans if needed
\r
602 for (i = klhere+1; i <= nenhere; i++) {
\r
603 dropin(IHR, &ix, &iy);
\r
606 kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
607 kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
\r
610 // If quadrant needs a starbase, put it in
\r
611 if (quadnum >= 10) {
\r
613 dropin(IHB, &basex, &basey);
\r
617 // If quadrant needs a planet, put it in
\r
618 for (i=1; i <= inplan; i++)
\r
619 if (state.plnets[i].x == quadx && state.plnets[i].y == quady) break;
\r
622 dropin(IHP, &plnetx, &plnety);
\r
625 // Check for condition
\r
627 // And finally the stars
\r
628 for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
\r
631 if (irhere > 0 && klhere == 0 && basex == 0) {
\r
633 if (damage[DRADIO] <= 0.0) {
\r
635 prout("LT. Uhura- \"Captain, an urgent message.");
\r
636 prout(" I'll put it on audio.\" CLICK");
\r
638 prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");
\r
639 prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");
\r
644 // Put in THING if needed
\r
645 if (thingx == quadx && thingy == quady) {
\r
646 dropin(IHQUEST, &ix, &iy);
\r
647 thingx = thingy = 0; // Transient
\r
648 if (damage[DSRSENS] == 0.0) {
\r
650 prout("MR. SPOCK- \"Captain, this is most unusual.");
\r
651 prout(" Please examine your short-range scan.\"");
\r
656 // Put in a few black holes
\r
657 for (i = 1; i <= 3; i++)
\r
658 if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
\r
660 // Take out X's in corners if Tholian present
\r
662 if (frozen.quad[1][1]=='X') frozen.quad[1][1] = IHDOT;
\r
663 if (frozen.quad[1][10]=='X') frozen.quad[1][10] = IHDOT;
\r
664 if (frozen.quad[10][1]=='X') frozen.quad[10][1] = IHDOT;
\r
665 if (frozen.quad[10][10]=='X') frozen.quad[10][10] = IHDOT;
\r
669 void sortkl(void) {
\r
673 // The author liked bubble sort. So we will use it. :-(
\r
675 if (nenhere < 2) return;
\r
679 for (j = 1; j < nenhere; j++)
\r
680 if (kdist[j] > kdist[j+1]) {
\r
683 kdist[j] = kdist[j+1];
\r
686 kavgd[j] = kavgd[j+1];
\r
695 kpower[j] = kpower[j+1];
\r