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(&game, sizeof(game), 1, fp);
\r
43 /* I hope that's enough! */
\r
52 game.passwd[0] = '\0';
\r
53 if ((key = scan()) == IHEOL) {
\r
54 proutn("File name: ");
\r
57 if (key != IHALPHA) {
\r
62 if (strchr(citem, '.') == NULL) {
\r
63 strcat(citem, ".trk");
\r
65 if ((fp = fopen(citem, "rb")) == NULL) {
\r
66 proutn("Can't find game file ");
\r
71 fread(&game, sizeof(game), 1, fp);
\r
75 /* I hope that's enough! */
\r
82 if (condit==IHDOCKED) {
\r
84 prout("You cannot abandon Ye Faerie Queene.");
\r
89 /* Must take shuttle craft to exit */
\r
90 if (game.damage[DSHUTTL]==-1) {
\r
91 prout("Ye Faerie Queene has no shuttle craft.");
\r
94 if (game.damage[DSHUTTL]<0) {
\r
95 prout("Shuttle craft now serving Big Mac's.");
\r
98 if (game.damage[DSHUTTL]>0) {
\r
99 prout("Shuttle craft damaged.");
\r
103 prout("You must be aboard the Enterprise.");
\r
107 prout("Shuttle craft not currently available.");
\r
110 /* Print abandon ship messages */
\r
112 prouts("***ABANDON SHIP! ABANDON SHIP!");
\r
114 prouts("***ALL HANDS ABANDON SHIP!");
\r
116 prout("Captain and crew escape in shuttle craft.");
\r
117 prout("Remainder of ship's complement beam down");
\r
118 prout("to nearest habitable planet.");
\r
119 if (game.state.rembase==0) {
\r
120 /* Ops! no place to go... */
\r
124 /* If at least one base left, give 'em the Faerie Queene */
\r
126 icrystl = 0; /* crystals are lost */
\r
127 nprobes = 0; /* No probes */
\r
128 prout("You are captured by Klingons and released to");
\r
129 prout("the Federation in a prisoner-of-war exchange.");
\r
130 nb = Rand()*game.state.rembase+1;
\r
131 /* Set up quadrant and position FQ adjacient to base */
\r
132 if (quadx!=game.state.baseqx[nb] || quady!=game.state.baseqy[nb]) {
\r
133 quadx = game.state.baseqx[nb];
\r
134 quady = game.state.baseqy[nb];
\r
139 /* position next to base by trial and error */
\r
140 game.quad[sectx][secty] = IHDOT;
\r
141 for (l = 1; l <= 10; l++) {
\r
142 sectx = 3.0*Rand() - 1.0 + basex;
\r
143 secty = 3.0*Rand() - 1.0 + basey;
\r
144 if (sectx >= 1 && sectx <= 10 &&
\r
145 secty >= 1 && secty <= 10 &&
\r
146 game.quad[sectx][secty] == IHDOT) break;
\r
148 if (l < 11) break; /* found a spot */
\r
154 /* Get new commission */
\r
155 game.quad[sectx][secty] = ship = IHF;
\r
156 prout("Starfleet puts you in command of another ship,");
\r
157 prout("the Faerie Queene, which is antiquated but,");
\r
158 prout("still useable.");
\r
159 if (icrystl!=0) prout("The dilithium crystals have been moved.");
\r
161 iscraft=0; /* Gallileo disappears */
\r
162 /* Resupply ship */
\r
164 for (l = 1; l <= ndevice; l++) game.damage[l] = 0.0;
\r
165 game.damage[DSHUTTL] = -1;
\r
166 energy = inenrg = 3000.0;
\r
167 shield = inshld = 1250.0;
\r
168 torps = intorps = 6;
\r
177 int i,j, krem, klumper;
\r
179 alldone = gamewon = 0;
\r
183 // Decide how many of everything
\r
184 if (choose()) return; // frozen game
\r
185 // Prepare the Enterprise
\r
187 energy = inenrg = 5000.0;
\r
188 shield = inshld = 2500.0;
\r
189 shldchg = shldup = 0;
\r
192 iran8(&quadx, &quady);
\r
193 iran10(§x, §y);
\r
194 torps = intorps = 10;
\r
195 nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */
\r
197 wfacsq = warpfac * warpfac;
\r
198 for (i=0; i <= ndevice; i++) game.damage[i] = 0.0;
\r
199 // Set up assorted game parameters
\r
201 game.state.date = indate = 100.0*(int)(31.0*Rand()+20.0);
\r
202 game.state.killk = game.state.killc = nkinks = nhelp = resting = casual = game.state.nromkl = 0;
\r
203 isatb = iscate = imine = icrystl = icraft = game.state.nsckill = game.state.nplankl = 0;
\r
208 for (i = 1; i <= 8; i++)
\r
209 for (j = 1; j <= 8; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0;
\r
210 // Initialize times for extraneous events
\r
211 game.future[FSNOVA] = game.state.date + expran(0.5 * intime);
\r
212 game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));
\r
213 game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot
\r
214 game.future[FBATTAK] = game.state.date + expran(0.3*intime);
\r
215 game.future[FCDBAS] = 1e30;
\r
216 game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : 1e30;
\r
217 game.future[FSCDBAS] = 1e30;
\r
218 game.future[FDSPROB] = 1e30;
\r
219 // Starchart is functional
\r
221 // Put stars in the galaxy
\r
223 for (i=1; i<=8; i++)
\r
224 for (j=1; j<=8; j++) {
\r
225 int k = Rand()*9.0 + 1.0;
\r
227 game.state.galaxy[i][j] = k;
\r
229 // Locate star bases in galaxy
\r
230 for (i = 1; i <= inbase; i++) {
\r
233 do iran8(&ix, &iy);
\r
234 while (game.state.galaxy[ix][iy] >= 10);
\r
236 for (j = i-1; j > 0; j--) {
\r
237 /* Improved placement algorithm to spread out bases */
\r
238 double distq = square(ix-game.state.baseqx[j]) + square(iy-game.state.baseqy[j]);
\r
239 if (distq < 6.0*(6-inbase) && Rand() < 0.75) {
\r
242 printf("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);
\r
247 else if (distq < 6.0 * (6-inbase)) {
\r
248 printf("DEBUG: saving base #%d, close to #%d\n", i, j);
\r
252 } while (contflag);
\r
254 game.state.baseqx[i] = ix;
\r
255 game.state.baseqy[i] = iy;
\r
256 game.starch[ix][iy] = -1;
\r
257 game.state.galaxy[ix][iy] += 10;
\r
259 // Position ordinary Klingon Battle Cruisers
\r
260 krem = inkling - incom - game.state.nscrem;
\r
261 klumper = 0.25*skill*(9.0-length)+1.0;
\r
262 if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant
\r
265 int klump = (1.0 - r*r)*klumper;
\r
266 if (klump > krem) klump = krem;
\r
269 do iran8(&ix, &iy);
\r
270 while (game.state.galaxy[ix][iy] + klump >= 1000);
\r
271 game.state.galaxy[ix][iy] += klump;
\r
272 } while (krem > 0);
\r
273 // Position Klingon Commander Ships
\r
277 for (i = 1; i <= incom; i++) {
\r
279 do { /* IF debugging, put commanders by bases, always! */
\r
281 if (idebug && klumper <= inbase) {
\r
282 ix = game.state.baseqx[klumper];
\r
283 iy = game.state.baseqy[klumper];
\r
290 while ((game.state.galaxy[ix][iy] < 99 && Rand() < 0.75)||
\r
291 game.state.galaxy[ix][iy]>899);
\r
292 // check for duplicate
\r
293 for (j = 1; j < i; j++)
\r
294 if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;
\r
296 game.state.galaxy[ix][iy] += 100;
\r
297 game.state.cx[i] = ix;
\r
298 game.state.cy[i] = iy;
\r
300 // Locate planets in galaxy
\r
301 for (i = 1; i <= inplan; i++) {
\r
302 do iran8(&ix, &iy);
\r
303 while (game.state.newstuf[ix][iy] > 0);
\r
304 game.state.newstuf[ix][iy] = 1;
\r
305 game.state.plnets[i].x = ix;
\r
306 game.state.plnets[i].y = iy;
\r
307 game.state.plnets[i].pclass = Rand()*3.0 + 1.0; // Planet class M N or O
\r
308 game.state.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals
\r
309 game.state.plnets[i].known = unknown;
\r
312 for (i = 1; i <= game.state.nromrem; i++) {
\r
314 game.state.newstuf[ix][iy] += 10;
\r
316 // Locate the Super Commander
\r
317 if (game.state.nscrem > 0) {
\r
318 do iran8(&ix, &iy);
\r
319 while (game.state.galaxy[ix][iy] >= 900);
\r
320 game.state.isx = ix;
\r
321 game.state.isy = iy;
\r
322 game.state.galaxy[ix][iy] += 100;
\r
324 // Place thing (in tournament game, thingx == -1, don't want one!)
\r
325 if (Rand() < 0.1 && thingx != -1) {
\r
326 iran8(&thingx, &thingy);
\r
329 thingx = thingy = 0;
\r
334 game.state.snap = 0;
\r
337 printf("It is stardate %d. The Federation is being attacked by\n",
\r
338 (int)game.state.date);
\r
339 printf("a deadly Klingon invasion force. As captain of the United\n"
\r
340 "Starship U.S.S. Enterprise, it is your mission to seek out\n"
\r
341 "and destroy this invasion force of %d battle cruisers.\n",
\r
343 printf("You have an initial allotment of %d stardates to complete\n"
\r
344 "your mission. As you proceed you may be given more time.\n\n"
\r
345 "You will have %d supporting starbases.\n"
\r
346 "Starbase locations- ",
\r
347 (int)intime, inbase);
\r
350 printf("Stardate %d.\n\n"
\r
351 "%d Klingons.\nAn unknown number of Romulans\n",
\r
352 (int)game.state.date, inkling);
\r
353 if (game.state.nscrem) printf("and one (GULP) Super-Commander.\n");
\r
354 printf("%d stardates\n%d starbases in ",(int)intime, inbase);
\r
356 for (i = 1; i <= inbase; i++) {
\r
357 cramlc(0, game.state.baseqx[i], game.state.baseqy[i]);
\r
358 if (i < inbase) proutn(" ");
\r
361 proutn("The Enterprise is currently in");
\r
362 cramlc(1, quadx, quady);
\r
364 cramlc(2, sectx, secty);
\r
366 prout("Good Luck!");
\r
367 if (game.state.nscrem) proutn(" YOU'LL NEED IT.");
\r
370 if (nenhere) shldup=1.0;
\r
371 if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone
\r
380 if (fromcommandline) /* Can start with command line options */
\r
381 fromcommandline = 0;
\r
383 proutn("Would you like a regular, tournament, or frozen game?");
\r
385 if (strlen(citem)==0) continue; // Try again
\r
386 if (isit("tournament")) {
\r
387 while (scan() == IHEOL) {
\r
388 proutn("Type in tournament number-");
\r
392 continue; // We don't want a blank entry
\r
394 tourn = (int)aaitem;
\r
396 srand((unsigned int)(int)aaitem);
\r
399 if (isit("frozen")) {
\r
402 if (*game.passwd==0) continue;
\r
404 Rand(); Rand(); Rand(); Rand();
\r
405 if (!alldone) thawed = 1; // No plaque if not finished
\r
409 if (isit("regular")) {
\r
412 Rand(); Rand(); Rand(); Rand();
\r
415 proutn("What is \"");
\r
420 while (length==0 || skill==0) {
\r
421 if (scan() == IHALPHA) {
\r
422 if (isit("short")) length = 1;
\r
423 else if (isit("medium")) length = 2;
\r
424 else if (isit("long")) length = 4;
\r
425 else if (isit("novice")) skill = 1;
\r
426 else if (isit("fair")) skill = 2;
\r
427 else if (isit("good")) skill = 3;
\r
428 else if (isit("expert")) skill = 4;
\r
429 else if (isit("emeritus")) skill = 5;
\r
431 proutn("What is \"");
\r
438 if (length==0) proutn("Would you like a Short, Medium, or Long game? ");
\r
439 else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player?");
\r
444 strcpy(game.passwd, citem);
\r
446 if (*game.passwd != 0) break;
\r
447 proutn("Please type in a secret password-");
\r
450 if (strcmp(game.passwd, "debug")==0) idebug = 1;
\r
453 // Use parameters to generate initial values of things
\r
454 damfac = 0.5 * skill;
\r
455 game.state.rembase = 3.0*Rand()+2.0;
\r
456 inbase = game.state.rembase;
\r
457 inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();
\r
458 game.state.nromrem = (2.0+Rand())*skill;
\r
459 game.state.nscrem = (skill > 2? 1 : 0);
\r
460 game.state.remtime = 7.0 * length;
\r
461 intime = game.state.remtime;
\r
462 game.state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);
\r
463 inkling = game.state.remkl;
\r
464 incom = skill + 0.0625*inkling*Rand();
\r
465 game.state.remcom= min(10, incom);
\r
466 incom = game.state.remcom;
\r
467 game.state.remres = (inkling+4*incom)*intime;
\r
468 inresor = game.state.remres;
\r
469 if (inkling > 50) {
\r
470 inbase = (game.state.rembase += 1);
\r
475 void dropin(int iquad, int *ix, int *iy) {
\r
477 while (game.quad[*ix][*iy] != IHDOT);
\r
478 game.quad[*ix][*iy] = iquad;
\r
481 void newcnd(void) {
\r
483 if (energy < 1000.0) condit = IHYELLOW;
\r
484 if (game.state.galaxy[quadx][quady] > 99 || game.state.newstuf[quadx][quady] > 9)
\r
489 void newqad(int shutup) {
\r
490 int quadnum = game.state.galaxy[quadx][quady];
\r
491 int newnum = game.state.newstuf[quadx][quady];
\r
492 int i, j, ix, iy, nplan;
\r
499 plnetx = plnety = 0;
\r
511 // Attempt to escape Super-commander, so tbeam back!
\r
516 for (i=1; i <= 10; i++)
\r
517 for (j=1; j <= 10; j++) game.quad[i][j] = IHDOT;
\r
518 // cope with supernova
\r
519 if (quadnum > 999) {
\r
522 klhere = quadnum/100;
\r
523 irhere = newnum/10;
\r
525 nenhere = klhere + irhere;
\r
527 // Position Starship
\r
528 game.quad[sectx][secty] = ship;
\r
530 // Decide if quadrant needs a Tholian
\r
531 if ((skill < 3 && Rand() <= 0.02) || /* Lighten up if skill is low */
\r
532 (skill == 3 && Rand() <= 0.05) ||
\r
533 (skill > 3 && Rand() <= 0.08)
\r
535 || strcmp(game.passwd, "tholianx")==0
\r
539 ithx = Rand() > 0.5 ? 10 : 1;
\r
540 ithy = Rand() > 0.5 ? 10 : 1;
\r
541 } while (game.quad[ithx][ithy] != IHDOT);
\r
542 game.quad[ithx][ithy] = IHT;
\r
544 /* Reserve unocupied corners */
\r
545 if (game.quad[1][1]==IHDOT) game.quad[1][1] = 'X';
\r
546 if (game.quad[1][10]==IHDOT) game.quad[1][10] = 'X';
\r
547 if (game.quad[10][1]==IHDOT) game.quad[10][1] = 'X';
\r
548 if (game.quad[10][10]==IHDOT) game.quad[10][10] = 'X';
\r
551 if (quadnum >= 100) {
\r
552 // Position ordinary Klingons
\r
553 quadnum -= 100*klhere;
\r
554 for (i = 1; i <= klhere; i++) {
\r
555 dropin(IHK, &ix, &iy);
\r
558 game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
559 game.kpower[i] = Rand()*150.0 +300.0 +25.0*skill;
\r
561 // If we need a commander, promote a Klingon
\r
562 for (i = 1; i <= game.state.remcom ; i++)
\r
563 if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;
\r
565 if (i <= game.state.remcom) {
\r
566 game.quad[ix][iy] = IHC;
\r
567 game.kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;
\r
571 // If we need a super-commander, promote a Klingon
\r
572 if (quadx == game.state.isx && quady == game.state.isy) {
\r
573 game.quad[game.kx[1]][game.ky[1]] = IHS;
\r
574 game.kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;
\r
579 // Put in Romulans if needed
\r
580 for (i = klhere+1; i <= nenhere; i++) {
\r
581 dropin(IHR, &ix, &iy);
\r
584 game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
\r
585 game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
\r
588 // If quadrant needs a starbase, put it in
\r
589 if (quadnum >= 10) {
\r
591 dropin(IHB, &basex, &basey);
\r
595 // If quadrant needs a planet, put it in
\r
596 for (i=1; i <= inplan; i++)
\r
597 if (game.state.plnets[i].x == quadx && game.state.plnets[i].y == quady) break;
\r
600 dropin(IHP, &plnetx, &plnety);
\r
603 // Check for condition
\r
605 // And finally the stars
\r
606 for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
\r
609 if (irhere > 0 && klhere == 0 && basex == 0) {
\r
611 if (game.damage[DRADIO] <= 0.0) {
\r
613 prout("LT. Uhura- \"Captain, an urgent message.");
\r
614 prout(" I'll put it on audio.\" CLICK");
\r
616 prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");
\r
617 prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");
\r
622 // Put in THING if needed
\r
623 if (thingx == quadx && thingy == quady) {
\r
624 dropin(IHQUEST, &ix, &iy);
\r
625 thingx = thingy = 0; // Transient
\r
626 if (game.damage[DSRSENS] == 0.0) {
\r
628 prout("MR. SPOCK- \"Captain, this is most unusual.");
\r
629 prout(" Please examine your short-range scan.\"");
\r
634 // Put in a few black holes
\r
635 for (i = 1; i <= 3; i++)
\r
636 if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
\r
638 // Take out X's in corners if Tholian present
\r
640 if (game.quad[1][1]=='X') game.quad[1][1] = IHDOT;
\r
641 if (game.quad[1][10]=='X') game.quad[1][10] = IHDOT;
\r
642 if (game.quad[10][1]=='X') game.quad[10][1] = IHDOT;
\r
643 if (game.quad[10][10]=='X') game.quad[10][10] = IHDOT;
\r
647 void sortkl(void) {
\r
651 // The author liked bubble sort. So we will use it. :-(
\r
653 if (nenhere < 2) return;
\r
657 for (j = 1; j < nenhere; j++)
\r
658 if (game.kdist[j] > game.kdist[j+1]) {
\r
661 game.kdist[j] = game.kdist[j+1];
\r
662 game.kdist[j+1] = t;
\r
664 game.kavgd[j] = game.kavgd[j+1];
\r
665 game.kavgd[j+1] = t;
\r
667 game.kx[j] = game.kx[j+1];
\r
670 game.ky[j] = game.ky[j+1];
\r
672 t = game.kpower[j];
\r
673 game.kpower[j] = game.kpower[j+1];
\r
674 game.kpower[j+1] = t;
\r