Initial commit of Tom Almy's version plus sst.doc.
authorEric S. Raymond <esr@thyrsus.com>
Sun, 31 Oct 2004 14:49:26 +0000 (14:49 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Sun, 31 Oct 2004 14:49:26 +0000 (14:49 +0000)
16 files changed:
MAKEFILE.DOS [new file with mode: 0644]
MAKEFILE.OS2 [new file with mode: 0644]
ai.c [new file with mode: 0644]
battle.c [new file with mode: 0644]
events.c [new file with mode: 0644]
finish.c [new file with mode: 0644]
linux.c [new file with mode: 0644]
makefile [new file with mode: 0644]
moving.c [new file with mode: 0644]
os2.c [new file with mode: 0644]
planets.c [new file with mode: 0644]
reports.c [new file with mode: 0644]
setup.c [new file with mode: 0644]
sst.c [new file with mode: 0644]
sst.doc [new file with mode: 0644]
sst.h [new file with mode: 0644]

diff --git a/MAKEFILE.DOS b/MAKEFILE.DOS
new file mode 100644 (file)
index 0000000..e7e4821
--- /dev/null
@@ -0,0 +1,14 @@
+MODEL=m\r
+CFLAGS=-f87 -2 -m$(MODEL)\r
+\r
+.c.obj:; bcc $(CFLAGS) -c $*.c\r
+\r
+OBJS= sst.obj setup.obj reports.obj finish.obj moving.obj\\r
+ battle.obj events.obj ai.obj planets.obj\r
+\r
+sst.exe:       $(OBJS) sst.lnk\r
+       bcc @sst.lnk\r
+\r
+\r
+sst.lnk:       makefile\r
+       >sst.lnk $(CFLAGS) -M $(OBJS) noeh$(MODEL).lib
\ No newline at end of file
diff --git a/MAKEFILE.OS2 b/MAKEFILE.OS2
new file mode 100644 (file)
index 0000000..59f7dbb
--- /dev/null
@@ -0,0 +1,17 @@
+CFLAGS=     -O\r
+\r
+.SUFFIXES: .o .c .s .exe\r
+\r
+.c.o:\r
+       $(CC) $(CFLAGS) -c $<\r
+\r
+OFILES=     sst.o finish.o reports.o setup.o os2.o moving.o battle.o events.o ai.o planets.o\r
+\r
+HFILES=     sst.h\r
+\r
+sstos2.exe:  $(OFILES)\r
+       gcc  -o sstos2.exe $(OFILES)\r
+\r
+        \r
+$(OFILES):  $(HFILES)\r
+\r
diff --git a/ai.c b/ai.c
new file mode 100644 (file)
index 0000000..de54e7b
--- /dev/null
+++ b/ai.c
@@ -0,0 +1,610 @@
+#include "sst.h"\r
+\r
+static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {\r
+       int iqx, iqy, l;\r
+\r
+       iqx = quadx+(lookx+9)/10 - 1;\r
+       iqy = quady+(looky+9)/10 - 1;\r
+       if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
+               d.galaxy[iqx][iqy] > 899)\r
+               return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */\r
+       if (ienm == IHR) return 0; /* Romulans cannot escape! */\r
+       if (irun == 0) {\r
+               /* avoid intruding on another commander's territory */\r
+               if (ienm == IHC) {\r
+                       for (l = 1; l <= d.remcom; l++)\r
+                               if (d.cx[l]==iqx && d.cy[l]==iqy) return 0;\r
+                       /* refuse to leave if currently attacking starbase */\r
+                       if (batx==quadx && baty==quady) return 0;\r
+               }\r
+               /* don't leave if over 1000 units of energy */\r
+               if (kpower[loccom] > 1000.) return 0;\r
+       }\r
+       /* print escape message and move out of quadrant.\r
+          We know this if either short or long range sensors are working */\r
+       if (damage[DSRSENS] == 0.0 || damage[DLRSENS] == 0.0 ||\r
+               condit == IHDOCKED) {\r
+               proutn("***");\r
+               cramen(ienm);\r
+               proutn(" escapes to");\r
+               cramlc(1, iqx, iqy);\r
+               prout(" (and regains strength).");\r
+       }\r
+       /* handle local matters related to escape */\r
+       kx[loccom] = kx[nenhere];\r
+       ky[loccom] = ky[nenhere];\r
+       kavgd[loccom] = kavgd[nenhere];\r
+       kpower[loccom] = kpower[nenhere];\r
+       kdist[loccom] = kdist[nenhere];\r
+       klhere--;\r
+       nenhere--;\r
+       if (condit != IHDOCKED) newcnd();\r
+       /* Handle global matters related to escape */\r
+       d.galaxy[quadx][quady] -= 100;\r
+       d.galaxy[iqx][iqy] += 100;\r
+       if (ienm==IHS) {\r
+               ishere=0;\r
+               iscate=0;\r
+               ientesc=0;\r
+               isatb=0;\r
+               future[FSCMOVE]=0.2777+d.date;\r
+               future[FSCDBAS]=1e30;\r
+               d.isx=iqx;\r
+               d.isy=iqy;\r
+       }\r
+       else {\r
+               for (l=1; l<=d.remcom; l++) {\r
+                       if (d.cx[l]==quadx && d.cy[l]==quady) {\r
+                               d.cx[l]=iqx;\r
+                               d.cy[l]=iqy;\r
+                               break;\r
+                       }\r
+               }\r
+               comhere = 0;\r
+       }\r
+       return 1; /* success */\r
+}\r
+\r
+\r
+static void movebaddy(int comx, int comy, int loccom, int ienm) {\r
+       int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;\r
+       int irun = 0;\r
+       int krawlx, krawly;\r
+       int success;\r
+       int attempts;\r
+       /* This should probably be just comhere + ishere */\r
+       int nbaddys = skill > 3 ?\r
+                                 (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):\r
+                                 (comhere + ishere);\r
+       double dist1, forces;\r
+\r
+       dist1 = kdist[loccom];\r
+       mdist = dist1 + 0.5; /* Nearest integer distance */\r
+\r
+       /* If SC, check with spy to see if should hi-tail it */\r
+       if (ienm==IHS &&\r
+               (kpower[loccom] <= 500.0 || (condit==IHDOCKED && damage[DPHOTON]==0))) {\r
+               irun = 1;\r
+               motion = -10;\r
+       }\r
+       else {\r
+               /* decide whether to advance, retreat, or hold position */\r
+/* Algorithm:\r
+   * Enterprise has "force" based on condition of phaser and photon torpedoes.\r
+     If both are operating full strength, force is 1000. If both are damaged,\r
+        force is -1000. Having shields down subtracts an additional 1000.\r
+\r
+   * Enemy has forces equal to the energy of the attacker plus\r
+     100*(K+R) + 500*(C+S) - 400 for novice through good levels OR\r
+        346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.\r
+\r
+        Attacker Initial energy levels (nominal):\r
+                 Klingon   Romulan   Commander   Super-Commander\r
+        Novice    400        700        1200        \r
+        Fair      425        750        1250\r
+        Good      450        800        1300        1750\r
+        Expert    475        850        1350        1875\r
+        Emeritus  500        900        1400        2000\r
+     VARIANCE   75        200         200         200\r
+\r
+        Enemy vessels only move prior to their attack. In Novice - Good games\r
+        only commanders move. In Expert games, all enemy vessels move if there\r
+        is a commander present. In Emeritus games all enemy vessels move.\r
+\r
+  *  If Enterprise is not docked, an agressive action is taken if enemy\r
+     forces are 1000 greater than Enterprise.\r
+\r
+        Agressive action on average cuts the distance between the ship and\r
+        the enemy to 1/4 the original.\r
+\r
+  *  At lower energy advantage, movement units are proportional to the\r
+     advantage with a 650 advantage being to hold ground, 800 to move forward\r
+        1, 950 for two, 150 for back 4, etc. Variance of 100.\r
+\r
+        If docked, is reduced by roughly 1.75*skill, generally forcing a\r
+        retreat, especially at high skill levels.\r
+\r
+  *  Motion is limited to skill level, except for SC hi-tailing it out.\r
+  */\r
+\r
+               forces = kpower[loccom]+100.0*nenhere+400*(nbaddys-1);\r
+               if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */\r
+               if (damage[DPHASER] == 0.0 || damage[DPHOTON] == 0.0) {\r
+                       if (damage[DPHASER] != 0) /* phasers damaged */\r
+                               forces += 300.0;\r
+                       else\r
+                               forces -= 0.2*(energy - 2500.0);\r
+                       if (damage[DPHOTON] != 0) /* photon torpedoes damaged */\r
+                               forces += 300.0;\r
+                       else\r
+                               forces -= 50.0*torps;\r
+               }\r
+               else {\r
+                       /* phasers and photon tubes both out! */\r
+                       forces += 1000.0;\r
+               }\r
+               motion = 0;\r
+               if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */\r
+                       motion = ((forces+200.0*Rand())/150.0) - 5.0;\r
+               else {\r
+                       if (forces > 1000.0) /* Very strong -- move in for kill */\r
+                               motion = (1.0-square(Rand()))*dist1 + 1.0;\r
+                       if (condit==IHDOCKED) /* protected by base -- back off ! */\r
+                               motion -= skill*(2.0-square(Rand()));\r
+               }\r
+#ifdef DEBUG\r
+               if (idebug) {\r
+                       proutn("MOTION = ");\r
+                       cramf(motion, 1, 2);\r
+            proutn("  FORCES = ");\r
+                       cramf(forces, 1, 2);\r
+                       skip(1);\r
+               }\r
+#endif\r
+               /* don't move if no motion */\r
+               if (motion==0) return;\r
+               /* Limit motion according to skill */\r
+               if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;\r
+       }\r
+       /* calcuate preferred number of steps */\r
+       nsteps = motion < 0 ? -motion : motion;\r
+       if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */\r
+       if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */\r
+       if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */\r
+#ifdef DEBUG\r
+       if (idebug) {\r
+               proutn("NSTEPS = ");\r
+               crami(nsteps, 1);\r
+               skip(1);\r
+       }\r
+#endif\r
+       /* Compute preferred values of delta X and Y */\r
+       mx = sectx - comx;\r
+       my = secty - comy;\r
+       if (2.0 * abs(mx) < abs(my)) mx = 0;\r
+       if (2.0 * abs(my) < abs(sectx-comx)) my = 0;\r
+       if (mx != 0) mx = mx*motion < 0 ? -1 : 1;\r
+       if (my != 0) my = my*motion < 0 ? -1 : 1;\r
+       nextx = comx;\r
+       nexty = comy;\r
+       quad[comx][comy] = IHDOT;\r
+       /* main move loop */\r
+       for (ll = 1; ll <= nsteps; ll++) {\r
+#ifdef DEBUG\r
+               if (idebug) {\r
+                       crami(ll,2);\r
+                       skip(1);\r
+               }\r
+#endif\r
+               /* Check if preferred position available */\r
+               lookx = nextx + mx;\r
+               looky = nexty + my;\r
+               krawlx = mx < 0 ? 1 : -1;\r
+               krawly = my < 0 ? 1 : -1;\r
+               success = 0;\r
+               attempts = 0; /* Settle mysterious hang problem */\r
+               while (attempts++ < 20 && !success) {\r
+                       if (lookx < 1 || lookx > 10) {\r
+                               if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
+                                       return;\r
+                               if (krawlx == mx || my == 0) break;\r
+                               lookx = nextx + krawlx;\r
+                               krawlx = -krawlx;\r
+                       }\r
+                       else if (looky < 1 || looky > 10) {\r
+                               if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
+                                       return;\r
+                               if (krawly == my || mx == 0) break;\r
+                               looky = nexty + krawly;\r
+                               krawly = -krawly;\r
+                       }\r
+                       else if (quad[lookx][looky] != IHDOT) {\r
+                               /* See if we should ram ship */\r
+                               if (quad[lookx][looky] == ship &&\r
+                                       (ienm == IHC || ienm == IHS)) {\r
+                                       ram(1, ienm, comx, comy);\r
+                                       return;\r
+                               }\r
+                               if (krawlx != mx && my != 0) {\r
+                                       lookx = nextx + krawlx;\r
+                                       krawlx = -krawlx;\r
+                               }\r
+                               else if (krawly != my && mx != 0) {\r
+                                       looky = nexty + krawly;\r
+                                       krawly = -krawly;\r
+                               }\r
+                               else break; /* we have failed */\r
+                       }\r
+                       else success = 1;\r
+               }\r
+               if (success) {\r
+                       nextx = lookx;\r
+                       nexty = looky;\r
+#ifdef DEBUG\r
+                       if (idebug) {\r
+                               cramlc(0, nextx, nexty);\r
+                               skip(1);\r
+                       }\r
+#endif\r
+               }\r
+               else break; /* done early */\r
+       }\r
+       /* Put commander in place within same quadrant */\r
+       quad[nextx][nexty] = ienm;\r
+       if (nextx != comx || nexty != comy) {\r
+               /* it moved */\r
+               kx[loccom] = nextx;\r
+               ky[loccom] = nexty;\r
+               kdist[loccom] = kavgd[loccom] =\r
+                                       sqrt(square(sectx-nextx)+square(secty-nexty));\r
+               if (damage[DSRSENS] == 0 || condit == IHDOCKED) {\r
+                       proutn("***");\r
+                       cramen(ienm);\r
+                       if (kdist[loccom] < dist1) proutn(" advances to");\r
+                       else proutn(" retreats to");\r
+                       cramlc(2, nextx, nexty);\r
+                       skip(1);\r
+               }\r
+       }\r
+}\r
+\r
+void movcom(void) {\r
+       int ix, iy, i;\r
+\r
+#ifdef DEBUG\r
+       if (idebug) prout("MOVCOM");\r
+#endif\r
+\r
+       /* Figure out which Klingon is the commander (or Supercommander)\r
+          and do move */\r
+       if (comhere) for (i = 1; i <= nenhere; i++) {\r
+               ix = kx[i];\r
+               iy = ky[i];\r
+               if (quad[ix][iy] == IHC) {\r
+                       movebaddy(ix, iy, i, IHC);\r
+                       break;\r
+               }\r
+       }\r
+       if (ishere) for (i = 1; i <= nenhere; i++) {\r
+               ix = kx[i];\r
+               iy = ky[i];\r
+               if (quad[ix][iy] == IHS) {\r
+                       movebaddy(ix, iy, i, IHS);\r
+                       break;\r
+               }\r
+       }\r
+       /* if skill level is high, move other Klingons and Romulans too!\r
+          Move these last so they can base their actions on what the\r
+       commander(s) do. */\r
+       if (skill > 3) for (i = 1; i <= nenhere; i++) {\r
+               ix = kx[i];\r
+               iy = ky[i];\r
+               if (quad[ix][iy] == IHK || quad[ix][iy] == IHR)\r
+                       movebaddy(ix, iy, i, quad[ix][iy]);\r
+       }\r
+\r
+       sortkl();\r
+}\r
+\r
+static int checkdest(int iqx, int iqy, int flag, int *ipage) {\r
+       int i, j;\r
+\r
+       if ((iqx==quadx && iqy==quady) ||\r
+               iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
+               d.galaxy[iqx][iqy] > 899) return 1;\r
+       if (flag) {\r
+               /* Avoid quadrants with bases if we want to avoid Enterprise */\r
+               for (i = 1; i <= d.rembase; i++)\r
+                       if (d.baseqx[i]==iqx && d.baseqy[i]==iqy) return 1;\r
+       }\r
+\r
+       /* do the move */\r
+       d.galaxy[d.isx][d.isy] -= 100;\r
+       d.isx = iqx;\r
+       d.isy = iqy;\r
+       d.galaxy[d.isx][d.isy] += 100;\r
+       if (iscate) {\r
+               /* SC has scooted, Remove him from current quadrant */\r
+               iscate=0;\r
+               isatb=0;\r
+               ishere=0;\r
+               ientesc=0;\r
+               future[FSCDBAS]=1e30;\r
+               for (i = 1; i <= nenhere; i++) \r
+                       if (quad[kx[i]][ky[i]] == IHS) break;\r
+               quad[kx[i]][ky[i]] = IHDOT;\r
+               kx[i] = kx[nenhere];\r
+               ky[i] = ky[nenhere];\r
+               kdist[i] = kdist[nenhere];\r
+               kavgd[i] = kavgd[nenhere];\r
+               kpower[i] = kpower[nenhere];\r
+               klhere--;\r
+               nenhere--;\r
+               if (condit!=IHDOCKED) newcnd();\r
+               sortkl();\r
+       }\r
+       /* check for a helpful planet */\r
+       for (i = 1; i <= inplan; i++) {\r
+               if (d.plnets[i].x==d.isx && d.plnets[i].y==d.isy &&\r
+                       d.plnets[i].crystals == 1) {\r
+                       /* destroy the planet */\r
+                       d.plnets[i] = nulplanet;\r
+                       d.newstuf[d.isx][d.isy] -= 1;\r
+                       if (damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
+                               if (*ipage==0) pause(1);\r
+                               *ipage = 1;\r
+                               prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
+                               proutn("   a planet in");\r
+                               cramlc(1, d.isx, d.isy);\r
+                               prout(" has been destroyed");\r
+                               prout("   by the Super-commander.\"");\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       return 0; /* looks good! */\r
+}\r
+                       \r
+               \r
+       \r
+\r
+\r
+void scom(int *ipage) {\r
+       int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;\r
+       int iqx, iqy;\r
+       int basetbl[6];\r
+       double bdist[6];\r
+       int flag;\r
+#ifdef DEBUG\r
+       if (idebug) prout("SCOM");\r
+#endif\r
+\r
+       /* Decide on being active or passive */\r
+       flag = ((d.killc+d.killk)/(d.date+0.01-indate) < 0.1*skill*(skill+1.0) ||\r
+                       (d.date-indate) < 3.0);\r
+       if (iscate==0 && flag) {\r
+               /* compute move away from Enterprise */\r
+               ideltax = d.isx-quadx;\r
+               ideltay = d.isy-quady;\r
+               if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {\r
+                       /* circulate in space */\r
+                       ideltax = d.isy-quady;\r
+                       ideltay = quadx-d.isx;\r
+               }\r
+       }\r
+       else {\r
+               /* compute distances to starbases */\r
+               if (d.rembase <= 0) {\r
+                       /* nothing left to do */\r
+                       future[FSCMOVE] = 1e30;\r
+                       return;\r
+               }\r
+               sx = d.isx;\r
+               sy = d.isy;\r
+               for (i = 1; i <= d.rembase; i++) {\r
+                       basetbl[i] = i;\r
+                       ibqx = d.baseqx[i];\r
+                       ibqy = d.baseqy[i];\r
+                       bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));\r
+               }\r
+               if (d.rembase > 1) {\r
+                       /* sort into nearest first order */\r
+                       int iswitch;\r
+                       do {\r
+                               iswitch = 0;\r
+                               for (i=1; i < d.rembase-1; i++) {\r
+                                       if (bdist[i] > bdist[i+1]) {\r
+                                               int ti = basetbl[i];\r
+                                               double t = bdist[i];\r
+                                               bdist[i] = bdist[i+1];\r
+                                               bdist[i+1] = t;\r
+                                               basetbl[i] = basetbl[i+1];\r
+                                               basetbl[i+1] =ti;\r
+                                               iswitch = 1;\r
+                                       }\r
+                               }\r
+                       } while (iswitch);\r
+               }\r
+               /* look for nearest base without a commander, no Enterprise, and\r
+                  without too many Klingons, and not already under attack. */\r
+               ifindit = iwhichb = 0;\r
+\r
+               for (i2 = 1; i2 <= d.rembase; i2++) {\r
+                       i = basetbl[i2];        /* bug in original had it not finding nearest*/\r
+                       ibqx = d.baseqx[i];\r
+                       ibqy = d.baseqy[i];\r
+                       if ((ibqx == quadx && ibqy == quady) ||\r
+                               (ibqx == batx && ibqy == baty) ||\r
+                               d.galaxy[ibqx][ibqy] > 899) continue;\r
+                       /* if there is a commander, an no other base is appropriate,\r
+                          we will take the one with the commander */\r
+                       for (j = 1; j <= d.remcom; j++) {\r
+                               if (ibqx==d.cx[j] && ibqy==d.cy[j] && ifindit!= 2) {\r
+                                               ifindit = 2;\r
+                                               iwhichb = i;\r
+                                               break;\r
+                               }\r
+                       }\r
+                       if (j > d.remcom) { /* no commander -- use this one */\r
+                               ifindit = 1;\r
+                               iwhichb = i;\r
+                               break;\r
+                       }\r
+               }\r
+               if (ifindit==0) return; /* Nothing suitable -- wait until next time*/\r
+               ibqx = d.baseqx[iwhichb];\r
+               ibqy = d.baseqy[iwhichb];\r
+               /* decide how to move toward base */\r
+               ideltax = ibqx - d.isx;\r
+               ideltay = ibqy - d.isy;\r
+       }\r
+       /* Maximum movement is 1 quadrant in either or both axis */\r
+       if (ideltax > 1) ideltax = 1;\r
+       if (ideltax < -1) ideltax = -1;\r
+       if (ideltay > 1) ideltay = 1;\r
+       if (ideltay < -1) ideltay = -1;\r
+\r
+       /* try moving in both x and y directions */\r
+       iqx = d.isx + ideltax;\r
+       iqy = d.isy + ideltax;\r
+       if (checkdest(iqx, iqy, flag, ipage)) {\r
+               /* failed -- try some other maneuvers */\r
+               if (ideltax==0 || ideltay==0) {\r
+                       /* attempt angle move */\r
+                       if (ideltax != 0) {\r
+                               iqy = d.isy + 1;\r
+                               if (checkdest(iqx, iqy, flag, ipage)) {\r
+                                       iqy = d.isy - 1;\r
+                                       checkdest(iqx, iqy, flag, ipage);\r
+                               }\r
+                       }\r
+                       else {\r
+                               iqx = d.isx + 1;\r
+                               if (checkdest(iqx, iqy, flag, ipage)) {\r
+                                       iqx = d.isx - 1;\r
+                                       checkdest(iqx, iqy, flag, ipage);\r
+                               }\r
+                       }\r
+               }\r
+               else {\r
+                       /* try moving just in x or y */\r
+                       iqy = d.isy;\r
+                       if (checkdest(iqx, iqy, flag, ipage)) {\r
+                               iqy = d.isy + ideltay;\r
+                               iqx = d.isx;\r
+                               checkdest(iqx, iqy, flag, ipage);\r
+                       }\r
+               }\r
+       }\r
+       /* check for a base */\r
+       if (d.rembase == 0) {\r
+               future[FSCMOVE] = 1e30;\r
+       }\r
+       else for (i=1; i<=d.rembase; i++) {\r
+               ibqx = d.baseqx[i];\r
+               ibqy = d.baseqy[i];\r
+               if (ibqx==d.isx && ibqy == d.isy && d.isx != batx && d.isy != baty) {\r
+                       /* attack the base */\r
+                       if (flag) return; /* no, don't attack base! */\r
+                       iseenit = 0;\r
+                       isatb=1;\r
+                       future[FSCDBAS] = d.date + 1.0 +2.0*Rand();\r
+                       if (batx != 0) future[FSCDBAS] += future[FCDBAS]-d.date;\r
+                       if (damage[DRADIO] > 0 && condit != IHDOCKED)\r
+                               return; /* no warning */\r
+                       iseenit = 1;\r
+                       if (*ipage == 0)  pause(1);\r
+                       *ipage=1;\r
+                       proutn("Lt. Uhura-  \"Captain, the starbase in");\r
+                       cramlc(1, d.isx, d.isy);\r
+                       skip(1);\r
+                       prout("   reports that it is under attack from the Klingon Super-commander.");\r
+                       proutn("   It can survive until stardate ");\r
+                       cramf(future[FSCDBAS], 0, 1);\r
+                       prout(" .\"");\r
+                       if (resting==0) return;\r
+                       prout("Mr. Spock-  \"Captain, shall we cancel the rest period?\"");\r
+                       if (ja()==0) return;\r
+                       resting = 0;\r
+                       Time = 0.0; /* actually finished */\r
+                       return;\r
+               }\r
+       }\r
+       /* Check for intelligence report */\r
+       if (\r
+#ifdef DEBUG\r
+               idebug==0 &&\r
+#endif\r
+               (Rand() > 0.2 ||\r
+                (damage[DRADIO] > 0.0 && condit != IHDOCKED) ||\r
+                starch[d.isx][d.isy] > 0))\r
+               return;\r
+       if (*ipage==0) pause(1);\r
+       *ipage = 1;\r
+       prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
+       proutn("   the Super-commander is in");\r
+       cramlc(1, d.isx, d.isy);\r
+       prout(".\"");\r
+       return;\r
+}\r
+\r
+void movetho(void) {\r
+       int idx, idy, im, i, dum, my;\r
+       /* Move the Tholean */\r
+       if (ithere==0 || justin == 1) return;\r
+\r
+       if (ithx == 1 && ithy == 1) {\r
+               idx = 1; idy = 10;\r
+       }\r
+       else if (ithx == 1 && ithy == 10) {\r
+               idx = 10; idy = 10;\r
+       }\r
+       else if (ithx == 10 && ithy == 10) {\r
+               idx = 10; idy = 1;\r
+       }\r
+       else if (ithx == 10 && ithy == 1) {\r
+               idx = 1; idy = 1;\r
+       }\r
+       else {\r
+               /* something is wrong! */\r
+               ithere = 0;\r
+               return;\r
+       }\r
+\r
+       /* Do nothing if we are blocked */\r
+       if (quad[idx][idy]!= IHDOT && quad[idx][idy]!= IHWEB) return;\r
+       quad[ithx][ithy] = IHWEB;\r
+\r
+       if (ithx != idx) {\r
+               /* move in x axis */\r
+               im = fabs((double)idx - ithx)/((double)idx - ithx);\r
+               while (ithx != idx) {\r
+                       ithx += im;\r
+                       if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
+               }\r
+       }\r
+       else if (ithy != idy) {\r
+               /* move in y axis */\r
+               im = fabs((double)idy - ithy)/((double)idy - ithy);\r
+               while (ithy != idy) {\r
+                       ithy += im;\r
+                       if (quad[ithx][ithy]==IHDOT) quad[ithx][ithy] = IHWEB;\r
+               }\r
+       }\r
+       quad[ithx][ithy] = IHT;\r
+\r
+       /* check to see if all holes plugged */\r
+       for (i = 1; i < 11; i++) {\r
+               if (quad[1][i]!=IHWEB && quad[1][i]!=IHT) return;\r
+               if (quad[10][i]!=IHWEB && quad[10][i]!=IHT) return;\r
+               if (quad[i][1]!=IHWEB && quad[i][1]!=IHT) return;\r
+               if (quad[i][10]!=IHWEB && quad[i][10]!=IHT) return;\r
+       }\r
+       /* All plugged up -- Tholian splits */\r
+       quad[ithx][ithy]=IHWEB;\r
+       dropin(IHBLANK, &dum, &my);\r
+       crmena(1,IHT, 2, ithx, ithy);\r
+       prout(" completes web.");\r
+       ithere = ithx = ithy = 0;\r
+       return;\r
+}\r
diff --git a/battle.c b/battle.c
new file mode 100644 (file)
index 0000000..e9cc2f6
--- /dev/null
+++ b/battle.c
@@ -0,0 +1,1214 @@
+#include "sst.h"\r
+\r
+void sheild(int i) {\r
+       int key;\r
+       enum {NONE, SHUP, SHDN, NRG} action = NONE;\r
+\r
+       ididit = 0;\r
+\r
+       if (i == 2) action = SHUP;\r
+       else {\r
+               key = scan();\r
+               if (key == IHALPHA) {\r
+                       if (isit("transfer"))\r
+                               action = NRG;\r
+                       else {\r
+                               chew();\r
+                               if (damage[DSHIELD]) {\r
+                                       prout("Shields damaged and down.");\r
+                                       return;\r
+                               }\r
+                               if (isit("up"))\r
+                                       action = SHUP;\r
+                               else if (isit("down"))\r
+                                       action = SHDN;\r
+                       }\r
+               }\r
+               if (action==NONE) {\r
+                       proutn("Do you wish to change shield energy? ");\r
+                       if (ja()) {\r
+                               proutn("Energy to transfer to shields- ");\r
+                               action = NRG;\r
+                       }\r
+                       else if (damage[DSHIELD]) {\r
+                               prout("Shields damaged and down.");\r
+                               return;\r
+                       }\r
+                       else if (shldup) {\r
+                               proutn("Shields are up. Do you want them down? ");\r
+                               if (ja()) action = SHDN;\r
+                               else {\r
+                                       chew();\r
+                                       return;\r
+                               }\r
+                       }\r
+                       else {\r
+                               proutn("Shields are down. Do you want them up? ");\r
+                               if (ja()) action = SHUP;\r
+                               else {\r
+                                       chew();\r
+                                       return;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       switch (action) {\r
+               case SHUP: /* raise shields */\r
+                       if (shldup) {\r
+                               prout("Shields already up.");\r
+                               return;\r
+                       }\r
+                       shldup = 1;\r
+                       shldchg = 1;\r
+                       if (condit != IHDOCKED) energy -= 50.0;\r
+                       prout("Shields raised.");\r
+                       if (energy <= 0) {\r
+                               skip(1);\r
+                               prout("Shields raising uses up last of energy.");\r
+                               finish(FNRG);\r
+                               return;\r
+                       }\r
+                       ididit=1;\r
+                       return;\r
+               case SHDN:\r
+                       if (shldup==0) {\r
+                               prout("Shields already down.");\r
+                               return;\r
+                       }\r
+                       shldup=0;\r
+                       shldchg=1;\r
+                       prout("Shields lowered.");\r
+                       ididit=1;\r
+                       return;\r
+               case NRG:\r
+                       while (scan() != IHREAL) {\r
+                               chew();\r
+                               proutn("Energy to transfer to shields- ");\r
+                       }\r
+                       chew();\r
+                       if (aaitem==0) return;\r
+                       if (aaitem > energy) {\r
+                               prout("Insufficient ship energy.");\r
+                               return;\r
+                       }\r
+                       ididit = 1;\r
+                       if (shield+aaitem >= inshld) {\r
+                               prout("Shield energy maximized.");\r
+                               if (shield+aaitem > inshld) {\r
+                                       prout("Excess energy requested returned to ship energy");\r
+                               }\r
+                               energy -= inshld-shield;\r
+                               shield = inshld;\r
+                               return;\r
+                       }\r
+                       if (aaitem < 0.0 && energy-aaitem > inenrg) {\r
+                               /* Prevent shield drain loophole */\r
+                               skip(1);\r
+                               prout("Engineering to bridge--");\r
+                               prout("  Scott here. Power circuit problem, Captain.");\r
+                               prout("  I can't drain the shields.");\r
+                               ididit = 0;\r
+                               return;\r
+                       }\r
+                       if (shield+aaitem < 0) {\r
+                               prout("All shield energy transferred to ship.");\r
+                               energy += shield;\r
+                               shield = 0.0;\r
+                               return;\r
+                       }\r
+                       proutn("Scotty- \"");\r
+                       if (aaitem > 0)\r
+                               prout("Transferring energy to shields.\"");\r
+                       else\r
+                               prout("Draining energy from shields.\"");\r
+                       shield += aaitem;\r
+                       energy -= aaitem;\r
+                       return;\r
+       }\r
+}\r
+\r
+void ram(int ibumpd, int ienm, int ix, int iy) {\r
+       double type = 1.0, extradm;\r
+       int icas, l;\r
+       \r
+       prouts("***RED ALERT!  RED ALERT!");\r
+       skip(1);\r
+       prout("***COLLISION IMMINENT.");\r
+       skip(2);\r
+       proutn("***");\r
+       crmshp();\r
+       switch (ienm) {\r
+               case IHR: type = 1.5; break;\r
+               case IHC: type = 2.0; break;\r
+               case IHS: type = 2.5; break;\r
+               case IHT: type = 0.5; break;\r
+       }\r
+       proutn(ibumpd ? " rammed by " : " rams ");\r
+       crmena(0, ienm, 2, ix, iy);\r
+       if (ibumpd) proutn(" (original position)");\r
+       skip(1);\r
+       deadkl(ix, iy, ienm, sectx, secty);\r
+       proutn("***");\r
+       crmshp();\r
+       prout(" heavily damaged.");\r
+       icas = 10.0+20.0*Rand();\r
+       proutn("***Sickbay reports ");\r
+       crami(icas, 1);\r
+       prout(" casualties.");\r
+       casual += icas;\r
+       for (l=1; l <= ndevice; l++) {\r
+               if (l == DDRAY) continue; // Don't damage deathray \r
+               if (damage[l] < 0) continue;\r
+               extradm = (10.0*type*Rand()+1.0)*damfac;\r
+               damage[l] += Time + extradm; /* Damage for at least time of travel! */\r
+       }\r
+       shldup = 0;\r
+       if (d.remkl) {\r
+               pause(2);\r
+               dreprt();\r
+       }\r
+       else finish(FWON);\r
+       return;\r
+}\r
+\r
+void torpedo(double course, double r, int inx, int iny, double *hit) {\r
+       int l, iquad, ix, iy,  jx, jy, shoved=0, ll;\r
+       double ac=course + 0.25*r;\r
+       double angle = (15.0-ac)*0.5235988;\r
+       double bullseye = (15.0 - course)*0.5235988;\r
+       double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;\r
+       double ang, temp, xx, yy, kp, h1;\r
+\r
+       bigger = fabs(deltax);\r
+       if (fabs(deltay) > bigger) bigger = fabs(deltay);\r
+       deltax /= bigger;\r
+       deltay /= bigger;\r
+\r
+       /* Loop to move a single torpedo */\r
+       for (l=1; l <= 15; l++) {\r
+               x += deltax;\r
+               ix = x + 0.5;\r
+               if (ix < 1 || ix > 10) break;\r
+               y += deltay;\r
+               iy = y + 0.5;\r
+               if (iy < 1 || iy > 10) break;\r
+               if (l==4 || l==9) skip(1);\r
+               cramf(x, 0, 1);\r
+               proutn(" - ");\r
+               cramf(y, 0, 1);\r
+               proutn("   ");\r
+               iquad=quad[ix][iy];\r
+               if (iquad==IHDOT) continue;\r
+               /* hit something */\r
+               skip(1);\r
+               switch(iquad) {\r
+                       case IHE: /* Hit our ship */\r
+                       case IHF:\r
+                               skip(1);\r
+                               proutn("Torpedo hits ");\r
+                               crmshp();\r
+                               prout(".");\r
+                               *hit = 700.0 + 100.0*Rand() -\r
+                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+                                          fabs(sin(bullseye-angle));\r
+                               *hit = fabs(*hit);\r
+                               newcnd(); /* undock */\r
+                               /* We may be displaced. */\r
+                               if (landed==1) return; /* Cheat if on a planet */\r
+                               ang = angle + 2.5*(Rand()-0.5);\r
+                               temp = fabs(sin(ang));\r
+                               if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
+                               xx = -sin(ang)/temp;\r
+                               yy = cos(ang)/temp;\r
+                               jx=ix+xx+0.5;\r
+                               jy=iy+yy+0.5;\r
+                               if (jx<1 || jx>10 || jy<1 ||jy > 10) return;\r
+                               if (quad[jx][jy]==IHBLANK) {\r
+                                       finish(FHOLE);\r
+                                       return;\r
+                               }\r
+                               if (quad[jx][jy]!=IHDOT) {\r
+                                       /* can't move into object */\r
+                                       return;\r
+                               }\r
+                               sectx = jx;\r
+                               secty = jy;\r
+                               crmshp();\r
+                               shoved = 1;\r
+                               break;\r
+                                         \r
+                       case IHC: /* Hit a commander */\r
+                       case IHS:\r
+                               if (Rand() <= 0.05) {\r
+                                       crmena(1, iquad, 2, ix, iy);\r
+                                       prout(" uses anti-photon device;");\r
+                                       prout("   torpedo neutralized.");\r
+                                       return;\r
+                               }\r
+                       case IHR: /* Hit a regular enemy */\r
+                       case IHK:\r
+                               /* find the enemy */\r
+                               for (ll=1; ll <= nenhere; ll++)\r
+                                       if (ix==kx[ll] && iy==ky[ll]) break;\r
+                               kp = fabs(kpower[ll]);\r
+                               h1 = 700.0 + 100.0*Rand() -\r
+                                        1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+                                        fabs(sin(bullseye-angle));\r
+                               h1 = fabs(h1);\r
+                               if (kp < h1) h1 = kp;\r
+                               kpower[ll] -= (kpower[ll]<0 ? -h1 : h1);\r
+                               if (kpower[ll] == 0) {\r
+                                       deadkl(ix, iy, iquad, ix, iy);\r
+                                       return;\r
+                               }\r
+                               crmena(1, iquad, 2, ix, iy);\r
+                               /* If enemy damaged but not destroyed, try to displace */\r
+                               ang = angle + 2.5*(Rand()-0.5);\r
+                               temp = fabs(sin(ang));\r
+                               if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
+                               xx = -sin(ang)/temp;\r
+                               yy = cos(ang)/temp;\r
+                               jx=ix+xx+0.5;\r
+                               jy=iy+yy+0.5;\r
+                               if (jx<1 || jx>10 || jy<1 ||jy > 10) {\r
+                                       prout(" damaged but not destroyed.");\r
+                                       return;\r
+                               }\r
+                               if (quad[jx][jy]==IHBLANK) {\r
+                                       prout(" buffeted into black hole.");\r
+                                       deadkl(ix, iy, iquad, jx, jy);\r
+                                       return;\r
+                               }\r
+                               if (quad[jx][jy]!=IHDOT) {\r
+                                       /* can't move into object */\r
+                                       prout(" damaged but not destroyed.");\r
+                                       return;\r
+                               }\r
+                               prout(" damaged--");\r
+                               kx[ll] = jx;\r
+                               ky[ll] = jy;\r
+                               shoved = 1;\r
+                               break;\r
+                       case IHB: /* Hit a base */\r
+                               prout("***STARBASE DESTROYED..");\r
+                               if (starch[quadx][quady] < 0) starch[quadx][quady] = 0;\r
+                               for (ll=1; ll<=d.rembase; ll++) {\r
+                                       if (d.baseqx[ll]==quadx && d.baseqy[ll]==quady) {\r
+                                               d.baseqx[ll]=d.baseqx[d.rembase];\r
+                                               d.baseqy[ll]=d.baseqy[d.rembase];\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               quad[ix][iy]=IHDOT;\r
+                               d.rembase--;\r
+                               basex=basey=0;\r
+                               d.galaxy[quadx][quady] -= 10;\r
+                               d.basekl++;\r
+                               newcnd();\r
+                               return;\r
+                       case IHP: /* Hit a planet */\r
+                               crmena(1, iquad, 2, ix, iy);\r
+                               prout(" destroyed.");\r
+                               d.nplankl++;\r
+                               d.newstuf[quadx][quady] -= 1;\r
+                               d.plnets[iplnet] = nulplanet;\r
+                               iplnet = 0;\r
+                               plnetx = plnety = 0;\r
+                               quad[ix][iy] = IHDOT;\r
+                               if (landed==1) {\r
+                                       /* captain parishes on planet */\r
+                                       finish(FDPLANET);\r
+                               }\r
+                               return;\r
+                       case IHSTAR: /* Hit a star */\r
+                               if (Rand() > 0.10) {\r
+                                       nova(ix, iy);\r
+                                       return;\r
+                               }\r
+                               crmena(1, IHSTAR, 2, ix, iy);\r
+                               prout(" unaffected by photon blast.");\r
+                               return;\r
+                       case IHQUEST: /* Hit a thingy */\r
+                               skip(1);\r
+                               prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");\r
+                               skip(1);\r
+                               prouts("    HACK!     HACK!    HACK!        *CHOKE!*  ");\r
+                               skip(1);\r
+                               proutn("Mr. Spock-");\r
+                               prouts("  \"Facinating!\"");\r
+                               skip(1);\r
+                               quad[ix][iy] = IHDOT;\r
+                               return;\r
+                       case IHBLANK: /* Black hole */\r
+                               skip(1);\r
+                               crmena(1, IHBLANK, 2, ix, iy);\r
+                               prout(" swallows torpedo.");\r
+                               return;\r
+                       case IHWEB: /* hit the web */\r
+                               skip(1);\r
+                               prout("***Torpedo absorbed by Tholian web.");\r
+                               return;\r
+                       case IHT:  /* Hit a Tholian */\r
+                               skip(1);\r
+                               crmena(1, IHT, 2, ix, iy);\r
+                               h1 = 700.0 + 100.0*Rand() -\r
+                                        1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
+                                        fabs(sin(bullseye-angle));\r
+                               h1 = fabs(h1);\r
+                               if (h1 >= 600) {\r
+                                       prout(" destroyed.");\r
+                                       quad[ix][iy] = IHDOT;\r
+                                       ithere = 0;\r
+                                       ithx = ithy = 0;\r
+                                       return;\r
+                               }\r
+                               if (Rand() > 0.05) {\r
+                                       prout(" survives photon blast.");\r
+                                       return;\r
+                               }\r
+                               prout(" disappears.");\r
+                               quad[ix][iy] = IHWEB;\r
+                               ithere = ithx = ithy = 0;\r
+                               {\r
+                                       int dum, my;\r
+                                       dropin(IHBLANK, &dum, &my);\r
+                               }\r
+                               return;\r
+                                       \r
+                       default: /* Problem! */\r
+                               skip(1);\r
+                               proutn("Don't know how to handle collision with ");\r
+                               crmena(1, iquad, 2, ix, iy);\r
+                               skip(1);\r
+                               return;\r
+               }\r
+               break;\r
+       }\r
+       if (shoved) {\r
+               quad[jx][jy]=iquad;\r
+               quad[ix][iy]=IHDOT;\r
+               proutn(" displaced by blast to");\r
+               cramlc(2, jx, jy);\r
+               skip(1);\r
+               for (ll=1; ll<=nenhere; ll++)\r
+                       kdist[ll] = kavgd[ll] = sqrt(square(sectx-kx[ll])+square(secty-ky[ll]));\r
+               sortkl();\r
+               return;\r
+       }\r
+       skip(1);\r
+       prout("Torpedo missed.");\r
+       return;\r
+}\r
+\r
+static void fry(double hit) {\r
+       double ncrit, extradm;\r
+       int ktr=1, l, ll, j, cdam[6], crptr;\r
+\r
+       /* a critical hit occured */\r
+       if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;\r
+\r
+       ncrit = 1.0 + hit/(500.0+100.0*Rand());\r
+       proutn("***CRITICAL HIT--");\r
+       /* Select devices and cause damage */\r
+       for (l = 1; l <= ncrit; l++) {\r
+               do {\r
+                       j = ndevice*Rand()+1.0;\r
+                       /* Cheat to prevent shuttle damage unless on ship */\r
+               } while (damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||\r
+                                j == DDRAY);\r
+               cdam[l] = j;\r
+               extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));\r
+               damage[j] += extradm;\r
+               if (l > 1) {\r
+                       for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;\r
+                       if (ll<=l) continue;\r
+                       ktr += 1;\r
+                       if (ktr==3) skip(1);\r
+                       proutn(" and ");\r
+               }\r
+               proutn(device[j]);\r
+       }\r
+       prout(" damaged.");\r
+       if (damage[DSHIELD] && shldup) {\r
+               prout("***Shields knocked down.");\r
+               shldup=0;\r
+       }\r
+}\r
+\r
+void attack(int k) {\r
+       /* k == 0 forces use of phasers in an attack */\r
+       int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;\r
+       int atackd = 0, attempt = 0;\r
+       double hit;\r
+       double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;\r
+\r
+       iattak = 1;\r
+       if (alldone) return;\r
+#ifdef DEBUG\r
+       if (idebug) prout("ATTACK!");\r
+#endif\r
+\r
+       if (ithere) movetho();\r
+\r
+       if (neutz) { /* The one chance not to be attacked */\r
+               neutz = 0;\r
+               return;\r
+       }\r
+       if (((comhere || ishere) && (justin == 0)) || skill == 5) movcom();\r
+       if (nenhere==0) return;\r
+       pfac = 1.0/inshld;\r
+       if (shldchg == 1) chgfac = 0.25+0.5*Rand();\r
+       skip(1);\r
+       if (skill <= 2) i = 2;\r
+       for (l=1; l <= nenhere; l++) {\r
+               if (kpower[l] < 0) continue;    /* too weak to attack */\r
+               /* compute hit strength and diminsh shield power */\r
+               r = Rand();\r
+               /* Increase chance of photon torpedos if docked or enemy energy low */\r
+               if (condit == IHDOCKED) r *= 0.25;\r
+               if (kpower[l] < 500) r *= 0.25; \r
+               jx = kx[l];\r
+               jy = ky[l];\r
+               iquad = quad[jx][jy];\r
+               itflag = (iquad == IHK && r > 0.0005) || k == 0 ||\r
+                       (iquad==IHC && r > 0.015) ||\r
+                       (iquad==IHR && r > 0.3) ||\r
+                       (iquad==IHS && r > 0.07);\r
+               if (itflag) {\r
+                       /* Enemy uses phasers */\r
+                       if (condit == IHDOCKED) continue; /* Don't waste the effort! */\r
+                       attempt = 1; /* Attempt to attack */\r
+                       dustfac = 0.8+0.05*Rand();\r
+                       hit = kpower[l]*pow(dustfac,kavgd[l]);\r
+                       kpower[l] *= 0.75;\r
+               }\r
+               else { /* Enemy used photon torpedo */\r
+                       double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);\r
+                       hit = 0;\r
+                       proutn("***TORPEDO INCOMING");\r
+                       if (damage[DSRSENS] <= 0.0) {\r
+                               proutn(" From ");\r
+                               crmena(0, iquad, i, jx, jy);\r
+                       }\r
+                       attempt = 1;\r
+                       prout("--");\r
+                       r = (Rand()+Rand())*0.5 -0.5;\r
+                       r += 0.002*kpower[l]*r;\r
+                       torpedo(course, r, jx, jy, &hit);\r
+                       if (d.remkl==0) finish(FWON); /* Klingons did themselves in! */\r
+                       if (d.galaxy[quadx][quady] == 1000 ||\r
+                               alldone) return; /* Supernova or finished */\r
+                       if (hit == 0) continue;\r
+               }\r
+               if (shldup != 0 || shldchg != 0) {\r
+                       /* shields will take hits */\r
+                       double absorb, hitsh, propor = pfac*shield;\r
+                       if(propor < 0.1) propor = 0.1;\r
+                       hitsh = propor*chgfac*hit+1.0;\r
+                       atackd=1;\r
+                       absorb = 0.8*hitsh;\r
+                       if (absorb > shield) absorb = shield;\r
+                       shield -= absorb;\r
+                       hit -= hitsh;\r
+                       if (propor > 0.1 && hit < 0.005*energy) continue;\r
+               }\r
+               /* It's a hit -- print out hit size */\r
+               atackd = 1; /* We weren't going to check casualties, etc. if\r
+                              shields were down for some strange reason. This\r
+                                          doesn't make any sense, so I've fixed it */\r
+               ihurt = 1;\r
+               cramf(hit, 0, 2);\r
+               proutn(" unit hit");\r
+               if ((damage[DSRSENS] > 0 && itflag) || skill <= 2) {\r
+                       proutn(" on the ");\r
+                       crmshp();\r
+               }\r
+               if (damage[DSRSENS] <= 0.0 && itflag) {\r
+                       proutn(" from ");\r
+                       crmena(0, iquad, i, jx, jy);\r
+               }\r
+               skip(1);\r
+               /* Decide if hit is critical */\r
+               if (hit > hitmax) hitmax = hit;\r
+               hittot += hit;\r
+               fry(hit);\r
+               printf("Hit %g energy %g\n", hit, energy);\r
+               energy -= hit;\r
+       }\r
+       if (energy <= 0) {\r
+               /* Returning home upon your shield, not with it... */\r
+               finish(FBATTLE);\r
+               return;\r
+       }\r
+       if (attempt == 0 && condit == IHDOCKED)\r
+               prout("***Enemies decide against attacking your ship.");\r
+       if (atackd == 0) return;\r
+       percent = 100.0*pfac*shield+0.5;\r
+       if (ihurt==0) {\r
+               /* Shields fully protect ship */\r
+               proutn("Enemy attack reduces shield strength to ");\r
+       }\r
+       else {\r
+               /* Print message if starship suffered hit(s) */\r
+               skip(1);\r
+               proutn("Energy left ");\r
+               cramf(energy, 0, 2);\r
+               proutn("    shields ");\r
+               if (shldup) proutn("up, ");\r
+               else if (damage[DSHIELD] == 0) proutn("down, ");\r
+               else proutn("damaged, ");\r
+       }\r
+       crami(percent, 1);\r
+       proutn("%   torpedoes left ");\r
+       crami(torps, 1);\r
+       skip(1);\r
+       /* Check if anyone was hurt */\r
+       if (hitmax >= 200 || hittot >= 500) {\r
+               int icas= hittot*Rand()*0.015;\r
+               if (icas >= 2) {\r
+                       skip(1);\r
+                       proutn("Mc Coy-  \"Sickbay to bridge.  We suffered ");\r
+                       crami(icas, 1);\r
+                       prout(" casualties");\r
+                       prout("   in that last attack.\"");\r
+                       casual += icas;\r
+               }\r
+       }\r
+       /* After attack, reset average distance to enemies */\r
+       for (l = 1; l <= nenhere; l++)\r
+               kavgd[l] = kdist[l];\r
+       sortkl();\r
+       return;\r
+}\r
+               \r
+void deadkl(int ix, int iy, int type, int ixx, int iyy) {\r
+       /* Added ixx and iyy allow enemy to "move" before dying */\r
+\r
+       int i,j;\r
+       \r
+       crmena(1, type, 2, ixx, iyy);\r
+       /* Decide what kind of enemy it is and update approriately */\r
+       if (type == IHR) {\r
+               /* chalk up a Romulan */\r
+               d.newstuf[quadx][quady] -= 10;\r
+               irhere--;\r
+               d.nromkl++;\r
+               d.nromrem--;\r
+       }\r
+       else if (type == IHT) {\r
+               /* Killed a Tholean */\r
+               ithere = 0;\r
+       }\r
+       else {\r
+               /* Some type of a Klingon */\r
+               d.galaxy[quadx][quady] -= 100;\r
+               klhere--;\r
+               d.remkl--;\r
+               switch (type) {\r
+                       case IHC:\r
+                               comhere = 0;\r
+                               for (i=1; i<=d.remcom; i++)\r
+                                       if (d.cx[i]==quadx && d.cy[i]==quady) break;\r
+                               d.cx[i] = d.cx[d.remcom];\r
+                               d.cy[i] = d.cy[d.remcom];\r
+                               d.cx[d.remcom] = 0;\r
+                               d.cy[d.remcom] = 0;\r
+                               d.remcom--;\r
+                               future[FTBEAM] = 1e30;\r
+                               if (d.remcom != 0)\r
+                                       future[FTBEAM] = d.date + expran(1.0*incom/d.remcom);\r
+                               d.killc++;\r
+                               break;\r
+                       case IHK:\r
+                               d.killk++;\r
+                               break;\r
+                       case IHS:\r
+                               d.nscrem = ishere = d.isx = d.isy = isatb = iscate = 0;\r
+                               d.nsckill = 1;\r
+                               future[FSCMOVE] = future[FSCDBAS] = 1e30;\r
+                               break;\r
+               }\r
+       }\r
+\r
+       /* For each kind of enemy, finish message to player */\r
+       prout(" destroyed.");\r
+       quad[ix][iy] = IHDOT;\r
+       if (d.remkl==0) return;\r
+\r
+       d.remtime = d.remres/(d.remkl + 4*d.remcom);\r
+\r
+       if (type == IHT) return;\r
+\r
+       /* Remove enemy ship from arrays describing local conditions */\r
+\r
+       for (i=1; i<=nenhere; i++)\r
+               if (kx[i]==ix && ky[i]==iy) break;\r
+       nenhere--;\r
+       if (i <= nenhere)  {\r
+               for (j=i; j<=nenhere; j++) {\r
+                       kx[j] = kx[j+1];\r
+                       ky[j] = ky[j+1];\r
+                       kpower[j] = kpower[j+1];\r
+                       kavgd[j] = kdist[j] = kdist[j+1];\r
+               }\r
+       }\r
+       kx[nenhere+1] = 0;\r
+       ky[nenhere+1] = 0;\r
+       kdist[nenhere+1] = 0;\r
+       kavgd[nenhere+1] = 0;\r
+       kpower[nenhere+1] = 0;\r
+       return;\r
+}\r
+\r
+static int targetcheck(double x, double y, double *course) {\r
+       double deltx, delty;\r
+       /* Return TRUE if target is invalid */\r
+       if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {\r
+               huh();\r
+               return 1;\r
+       }\r
+       deltx = 0.1*(y - secty);\r
+       delty = 0.1*(sectx - x);\r
+       if (deltx==0 && delty== 0) {\r
+               skip(1);\r
+               prout("Spock-  \"Bridge to sickbay.  Dr. McCoy,");\r
+               prout("  I recommend an immediate review of");\r
+               prout("  the Captain's psychological profile.");\r
+               chew();\r
+               return 1;\r
+       }\r
+       *course = 1.90985932*atan2(deltx, delty);\r
+       return 0;\r
+}\r
+\r
+void photon(void) {\r
+       double targ[4][3], course[4];\r
+       double r, dummy;\r
+       int key, n, i, osuabor;\r
+\r
+       ididit = 0;\r
+\r
+       if (damage[DPHOTON]) {\r
+               prout("Photon tubes damaged.");\r
+               chew();\r
+               return;\r
+       }\r
+       if (torps == 0) {\r
+               prout("No torpedoes left.");\r
+               chew();\r
+               return;\r
+       }\r
+       key = scan();\r
+       for (;;) {\r
+               if (key == IHALPHA) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               else if (key == IHEOL) {\r
+                       crami(torps,1);\r
+                       prout(" torpedoes left.");\r
+                       proutn("Number of torpedoes to fire- ");\r
+                       key = scan();\r
+               }\r
+               else /* key == IHREAL */ {\r
+                       n = aaitem + 0.5;\r
+                       if (n <= 0) { /* abort command */\r
+                               chew();\r
+                               return;\r
+                       }\r
+                       if (n > 3) {\r
+                               chew();\r
+                               prout("Maximum of 3 torpedoes per burst.");\r
+                               key = IHEOL;\r
+                       }\r
+                       if (n <= torps) break;\r
+                       chew();\r
+                       key = IHEOL;\r
+               }\r
+       }\r
+       for (i = 1; i <= n; i++) {\r
+               key = scan();\r
+               if (i==1 && key == IHEOL) {\r
+                       break;  /* we will try prompting */\r
+               }\r
+               if (i==2 && key == IHEOL) {\r
+                       /* direct all torpedoes at one target */\r
+                       while (i <= n) {\r
+                               targ[i][1] = targ[1][1];\r
+                               targ[i][2] = targ[1][2];\r
+                               course[i] = course[1];\r
+                               i++;\r
+                       }\r
+                       break;\r
+               }\r
+               if (key != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               targ[i][1] = aaitem;\r
+               key = scan();\r
+               if (key != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               targ[i][2] = aaitem;\r
+               if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
+       }\r
+       chew();\r
+       if (i == 1 && key == IHEOL) {\r
+               /* prompt for each one */\r
+               for (i = 1; i <= n; i++) {\r
+                       proutn("Target sector for torpedo number");\r
+                       crami(i, 2);\r
+                       proutn("- ");\r
+                       key = scan();\r
+                       if (key != IHREAL) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+                       targ[i][1] = aaitem;\r
+                       key = scan();\r
+                       if (key != IHREAL) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+                       targ[i][2] = aaitem;\r
+                       chew();\r
+                       if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
+               }\r
+       }\r
+       ididit = 1;\r
+       /* Loop for moving <n> torpedoes */\r
+       osuabor = 0;\r
+       for (i = 1; i <= n && !osuabor; i++) {\r
+               if (condit != IHDOCKED) torps--;\r
+               r = (Rand()+Rand())*0.5 -0.5;\r
+               if (fabs(r) >= 0.47) {\r
+                       /* misfire! */\r
+                       r = (Rand()+1.2) * r;\r
+                       if (n>1) {\r
+                               prouts("***TORPEDO NUMBER");\r
+                               crami(i, 2);\r
+                               prouts(" MISFIRES.");\r
+                       }\r
+                       else prouts("***TORPEDO MISFIRES.");\r
+                       skip(1);\r
+                       if (i < n)\r
+                               prout("  Remainder of burst aborted.");\r
+                       osuabor=1;\r
+                       if (Rand() <= 0.2) {\r
+                               prout("***Photon tubes damaged by misfire.");\r
+                               damage[DPHOTON] = damfac*(1.0+2.0*Rand());\r
+                               break;\r
+                       }\r
+               }\r
+               if (shldup != 0 || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;\r
+               if (n != 1) {\r
+                       skip(1);\r
+                       proutn("Track for torpedo number");\r
+                       crami(i, 2);\r
+                       proutn("-   ");\r
+               }\r
+               else {\r
+                       skip(1);\r
+                       proutn("Torpedo track- ");\r
+               }\r
+               torpedo(course[i], r, sectx, secty, &dummy);\r
+               if (alldone || d.galaxy[quadx][quady]==1000) return;\r
+       }\r
+       if (d.remkl==0) finish(FWON);\r
+}\r
+\r
+       \r
+\r
+static void overheat(double rpow) {\r
+       if (rpow > 1500) {\r
+               double chekbrn = (rpow-1500.)*0.00038;\r
+               if (Rand() <= chekbrn) {\r
+                       prout("Weapons officer Sulu-  \"Phasers overheated, sir.\"");\r
+                       damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);\r
+               }\r
+       }\r
+}\r
+\r
+static int checkshctrl(double rpow) {\r
+       double hit;\r
+       int icas;\r
+       \r
+       skip(1);\r
+       if (Rand() < .998) {\r
+               prout("Shields lowered.");\r
+               return 0;\r
+       }\r
+       /* Something bad has happened */\r
+       prouts("***RED ALERT!  RED ALERT!");\r
+       skip(2);\r
+       hit = rpow*shield/inshld;\r
+       energy -= rpow+hit*0.8;\r
+       shield -= hit*0.2;\r
+       if (energy <= 0.0) {\r
+               prouts("Sulu-  \"Captain! Shield malf***********************\"");\r
+               skip(1);\r
+               stars();\r
+               finish(FPHASER);\r
+               return 1;\r
+       }\r
+       prouts("Sulu-  \"Captain! Shield malfunction! Phaser fire contained!\"");\r
+       skip(2);\r
+       prout("Lt. Uhura-  \"Sir, all decks reporting damage.\"");\r
+       icas = hit*Rand()*0.012;\r
+       skip(1);\r
+       fry(0.8*hit);\r
+       if (icas) {\r
+               skip(1);\r
+               prout("McCoy to bridge- \"Severe radiation burns, Jim.");\r
+               proutn("  ");\r
+               crami(icas, 1);\r
+               prout(" casualties so far.\"");\r
+               casual -= icas;\r
+       }\r
+       skip(1);\r
+       prout("Phaser energy dispersed by shields.");\r
+       prout("Enemy unaffected.");\r
+       overheat(rpow);\r
+       return 1;\r
+}\r
+       \r
+\r
+void phasers(void) {\r
+       double hits[21], rpow, extra, powrem, over, temp;\r
+       int kz = 0, k=1, i; /* Cheating inhibitor */\r
+       int ifast=0, no=0, ipoop=1, msgflag = 1;\r
+       enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;\r
+       int key;\r
+\r
+       skip(1);\r
+       /* SR sensors and Computer */\r
+       if (damage[DSRSENS]+damage[DCOMPTR] > 0) ipoop = 0;\r
+       if (condit == IHDOCKED) {\r
+               prout("Phasers can't be fired through base shields.");\r
+               chew();\r
+               return;\r
+       }\r
+       if (damage[DPHASER] != 0) {\r
+               prout("Phaser control damaged.");\r
+               chew();\r
+               return;\r
+       }\r
+       if (shldup) {\r
+               if (damage[DSHCTRL]) {\r
+                       prout("High speed shield control damaged.");\r
+                       chew();\r
+                       return;\r
+               }\r
+               if (energy <= 200.0) {\r
+                       prout("Insufficient energy to activate high-speed shield control.");\r
+                       chew();\r
+                       return;\r
+               }\r
+               prout("Weapons Officer Sulu-  \"High-speed shield control enabled, sir.\"");\r
+               ifast = 1;\r
+               \r
+       }\r
+       ididit = 1;\r
+       /* Original code so convoluted, I re-did it all */\r
+       while (automode==NOTSET) {\r
+               key=scan();\r
+               if (key == IHALPHA) {\r
+                       if (isit("manual")) {\r
+                               if (nenhere==0) {\r
+                                       prout("There is no enemy present to select.");\r
+                                       chew();\r
+                                       key = IHEOL;\r
+                                       automode=AUTOMATIC;\r
+                               }\r
+                               else {\r
+                                       automode = MANUAL;\r
+                                       key = scan();\r
+                               }\r
+                       }\r
+                       else if (isit("automatic")) {\r
+                               if ((!ipoop) && nenhere != 0) {\r
+                                       automode = FORCEMAN;\r
+                               }\r
+                               else {\r
+                                       if (nenhere==0)\r
+                                               prout("Energy will be expended into space.");\r
+                                       automode = AUTOMATIC;\r
+                                       key = scan();\r
+                               }\r
+                       }\r
+                       else if (isit("no")) {\r
+                               no = 1;\r
+                       }\r
+                       else {\r
+                               huh();\r
+                               ididit = 0;\r
+                               return;\r
+                       }\r
+               }\r
+               else if (key == IHREAL) {\r
+                       if (nenhere==0) {\r
+                               prout("Energy will be expended into space.");\r
+                               automode = AUTOMATIC;\r
+                       }\r
+                       else if (!ipoop)\r
+                               automode = FORCEMAN;\r
+                       else\r
+                               automode = AUTOMATIC;\r
+               }\r
+               else {\r
+                       /* IHEOL */\r
+                       if (nenhere==0) {\r
+                               prout("Energy will be expended into space.");\r
+                               automode = AUTOMATIC;\r
+                       }\r
+                       else if (!ipoop)\r
+                               automode = FORCEMAN;\r
+                       else \r
+                       proutn("Manual or automatic? ");\r
+               }\r
+       }\r
+                               \r
+       switch (automode) {\r
+               case AUTOMATIC:\r
+                       if (key == IHALPHA && isit("no")) {\r
+                               no = 1;\r
+                               key = scan();\r
+                       }\r
+                       if (key != IHREAL && nenhere != 0) {\r
+                               proutn("Phasers locked on target. Energy available =");\r
+                               cramf(ifast?energy-200.0:energy,1,2);\r
+                               skip(1);\r
+                       }\r
+                       do {\r
+                               while (key != IHREAL) {\r
+                                       chew();\r
+                                       proutn("Units to fire=");\r
+                                       key = scan();\r
+                               }\r
+                               rpow = aaitem;\r
+                               if (rpow >= (ifast?energy-200:energy)) {\r
+                                       proutn("Energy available= ");\r
+                                       cramf(ifast?energy-200:energy, 1,2);\r
+                                       skip(1);\r
+                                       key = IHEOL;\r
+                               }\r
+                       } while (rpow >= (ifast?energy-200:energy));\r
+                       if (rpow<=0) {\r
+                               /* chicken out */\r
+                               ididit = 0;\r
+                               chew();\r
+                               return;\r
+                       }\r
+                       if ((key=scan()) == IHALPHA && isit("no")) {\r
+                               no = 1;\r
+                       }\r
+                       if (ifast) {\r
+                               energy -= 200; /* Go and do it! */\r
+                               if (checkshctrl(rpow)) return;\r
+                       }\r
+                       chew();\r
+                       energy -= rpow;\r
+                       extra = rpow;\r
+                       if (nenhere) {\r
+                               extra = 0.0;\r
+                               powrem = rpow;\r
+                               for (i = 1; i <= nenhere; i++) {\r
+                                       hits[i] = 0.0;\r
+                                       if (powrem <= 0) continue;\r
+                                       hits[i] = fabs(kpower[i])/(phasefac*pow(0.90,kdist[i]));\r
+                                       over = (0.01 + 0.05*Rand())*hits[i];\r
+                                       temp = powrem;\r
+                                       powrem -= hits[i] + over;\r
+                                       if (powrem <= 0 && temp < hits[i]) hits[i] = temp;\r
+                                       if (powrem <= 0) over = 0.0;\r
+                                       extra += over;\r
+                               }\r
+                               if (powrem > 0.0) extra += powrem;\r
+                               hittem(hits);\r
+                       }\r
+                       if (extra > 0 && alldone == 0) {\r
+                               if (ithere) {\r
+                                       proutn("*** Tholian web absorbs ");\r
+                                       if (nenhere>0) proutn("excess ");\r
+                                       prout("phaser energy.");\r
+                               }\r
+                               else {\r
+                                       cramf(extra, 0, 2);\r
+                                       prout(" expended on empty space.");\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+               case FORCEMAN:\r
+                       chew();\r
+                       key = IHEOL;\r
+                       if (damage[DCOMPTR]!=0)\r
+                               prout("Battle comuter damaged, manual file only.");\r
+                       else {\r
+                               skip(1);\r
+                               prouts("---WORKING---");\r
+                               skip(1);\r
+                               prout("Short-range-sensors-damaged");\r
+                               prout("Insufficient-data-for-automatic-phaser-fire");\r
+                               prout("Manual-fire-must-be-used");\r
+                               skip(1);\r
+                       }\r
+               case MANUAL:\r
+                       rpow = 0.0;\r
+                       for (k = 1; k <= nenhere;) {\r
+                               int ii = kx[k], jj = ky[k];\r
+                               int ienm = quad[ii][jj];\r
+                               if (msgflag) {\r
+                                       proutn("Energy available= ");\r
+                                       cramf(energy-.006-(ifast?200:0), 0, 2);\r
+                                       skip(1);\r
+                                       msgflag = 0;\r
+                                       rpow = 0.0;\r
+                               }\r
+                               if (damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&\r
+                                       (ienm == IHC || ienm == IHS)) {\r
+                                       cramen(ienm);\r
+                                       prout(" can't be located without short range scan.");\r
+                                       chew();\r
+                                       key = IHEOL;\r
+                                       hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */\r
+                                       k++;\r
+                                       continue;\r
+                               }\r
+                               if (key == IHEOL) {\r
+                                       chew();\r
+                                       if (ipoop && k > kz) {\r
+                                               int irec=(fabs(kpower[k])/(phasefac*pow(0.9,kdist[k])))*\r
+                                                                (1.01+0.05*Rand()) + 1.0;\r
+                                               kz = k;\r
+                                               proutn("(");\r
+                                               crami(irec, 1);\r
+                                               proutn(")  ");\r
+                                       }\r
+                                       proutn("units to fire at ");\r
+                                       crmena(0, ienm, 2, ii, jj);\r
+                                       proutn("-  ");\r
+                                       key = scan();\r
+                               }\r
+                               if (key == IHALPHA && isit("no")) {\r
+                                       no = 1;\r
+                                       key = scan();\r
+                                       continue;\r
+                                       }\r
+                               if (key == IHALPHA) {\r
+                                       huh();\r
+                                       ididit = 0;\r
+                                       return;\r
+                               }\r
+                               if (key == IHEOL) {\r
+                                       if (k==1) { /* Let me say I'm baffled by this */\r
+                                               msgflag = 1;\r
+                                       }\r
+                                       continue;\r
+                               }\r
+                               if (aaitem < 0) {\r
+                                       /* abort out */\r
+                                       ididit = 0;\r
+                                       chew();\r
+                                       return;\r
+                               }\r
+                               hits[k] = aaitem;\r
+                               rpow += aaitem;\r
+                               /* If total requested is too much, inform and start over */\r
+                               \r
+                               if (rpow >= (ifast?energy-200:energy)) {\r
+                                       prout("Available energy exceeded -- try again.");\r
+                                       chew();\r
+                                       key = IHEOL;\r
+                                       k = 1;\r
+                                       msgflag = 1;\r
+                                       continue;\r
+                               }\r
+                               key = scan(); /* scan for next value */\r
+                               k++;\r
+                       }\r
+                       if (rpow == 0.0) {\r
+                               /* zero energy -- abort */\r
+                               ididit = 0;\r
+                               chew();\r
+                               return;\r
+                       }\r
+                       if (key == IHALPHA & isit("no")) {\r
+                               no = 1;\r
+                       }\r
+                       energy -= rpow;\r
+                       chew();\r
+                       if (ifast) {\r
+                               energy -= 200.0;\r
+                               if (checkshctrl(rpow)) return;\r
+                       }\r
+                       hittem(hits);\r
+                       ididit=1;\r
+       }\r
+       /* Say shield raised or malfunction, if necessary */\r
+       if (alldone) return;\r
+       if (ifast) {\r
+               skip(1);\r
+               if (no == 0) {\r
+                       if (Rand() >= 0.99) {\r
+                               prout("Sulu-  \"Sir, the high-speed shield control has malfunctioned . . .");\r
+                               prouts("         CLICK   CLICK   POP  . . .");\r
+                               prout(" No  response, sir!");\r
+                               shldup = 0;\r
+                       }\r
+                       else\r
+                               prout("Shields raised.");\r
+               }\r
+               else\r
+                       shldup = 0;\r
+       }\r
+       overheat(rpow);\r
+}\r
+\r
+void hittem(double *hits) {\r
+       double kp, kpow, wham, hit, dustfac, kpini;\r
+       int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;\r
+\r
+       skip(1);\r
+\r
+       for (; k <= nenhr2; k++, kk++) {\r
+               if ((wham = hits[k])==0) continue;\r
+               dustfac = 0.9 + 0.01*Rand();\r
+               hit = wham*pow(dustfac,kdist[kk]);\r
+               kpini = kpower[kk];\r
+               kp = fabs(kpini);\r
+               if (phasefac*hit < kp) kp = phasefac*hit;\r
+               kpower[kk] -= (kpower[kk] < 0 ? -kp: kp);\r
+               kpow = kpower[kk];\r
+               ii = kx[kk];\r
+               jj = ky[kk];\r
+               if (hit > 0.005) {\r
+                       cramf(hit, 0, 2);\r
+                       proutn(" unit hit on ");\r
+               }\r
+               else\r
+                       proutn("Very small hit on ");\r
+               ienm = quad[ii][jj];\r
+               crmena(0,ienm,2,ii,jj);\r
+               skip(1);\r
+               if (kpow == 0) {\r
+                       deadkl(ii, jj, ienm, ii, jj);\r
+                       if (d.remkl==0) finish(FWON);\r
+                       if (alldone) return;\r
+                       kk--; /* don't do the increment */\r
+               }\r
+               else /* decide whether or not to emasculate klingon */\r
+                       if (kpow > 0 && Rand() >= 0.9 &&\r
+                               kpow <= ((0.4 + 0.4*Rand())*kpini)) {\r
+                               proutn("***Mr. Spock-  \"Captain, the vessel at");\r
+                               cramlc(2,ii,jj);\r
+                               skip(1);\r
+                               prout("   has just lost its firepower.\"");\r
+                               kpower[kk] = -kpow;\r
+                       }\r
+       }\r
+       return;\r
+}\r
+\r
diff --git a/events.c b/events.c
new file mode 100644 (file)
index 0000000..192b1cb
--- /dev/null
+++ b/events.c
@@ -0,0 +1,767 @@
+#include "sst.h"\r
+#include <math.h>\r
+\r
+void events(void) {\r
+\r
+       int ictbeam=0, ipage=0, istract=0, line, i, j, k, l, ixhold, iyhold;\r
+       double fintim = d.date + Time, datemin, xtime, repair, yank;\r
+       \r
+\r
+#ifdef DEBUG\r
+       if (idebug) prout("EVENTS");\r
+#endif\r
+\r
+       if (stdamtim == 1e30 && damage[DRADIO] != 0.0) {\r
+               /* chart will no longer be updated because radio is dead */\r
+               stdamtim = d.date;\r
+               for (i=1; i <= 8 ; i++)\r
+                       for (j=1; j <= 8; j++)\r
+                               if (starch[i][j] == 1) starch[i][j] = d.galaxy[i][j]+1000;\r
+       }\r
+\r
+       for (;;) {\r
+               /* Select earliest extraneous event, line==0 if no events */\r
+               line = FSPY;\r
+               if (alldone) return;\r
+               datemin = fintim;\r
+               for (l=1; l<=NEVENTS; l++)\r
+                       if (future[l] <= datemin) {\r
+                               line = l;\r
+                               datemin = future[l];\r
+                       }\r
+               xtime = datemin-d.date;\r
+               d.date = datemin;\r
+               /* Decrement Federation resources and recompute remaining time */\r
+               d.remres -= (d.remkl+4*d.remcom)*xtime;\r
+               d.remtime = d.remres/(d.remkl+4*d.remcom);\r
+               if (d.remtime <=0) {\r
+                       finish(FDEPLETE);\r
+                       return;\r
+               }\r
+               /* Is life support adequate? */\r
+               if (damage[DLIFSUP] && condit != IHDOCKED) {\r
+                       if (lsupres < xtime && damage[DLIFSUP] > lsupres) {\r
+                               finish(FLIFESUP);\r
+                               return;\r
+                       }\r
+                       lsupres -= xtime;\r
+                       if (damage[DLIFSUP] <= xtime) lsupres = inlsr;\r
+               }\r
+               /* Fix devices */\r
+               repair = xtime;\r
+               if (condit == IHDOCKED) repair /= docfac;\r
+               /* Don't fix Deathray here */\r
+               for (l=1; l<=ndevice; l++)\r
+                       if (damage[l] > 0.0 && l != DDRAY)\r
+                               damage[l] -= (damage[l]-repair > 0.0 ? repair : damage[l]);\r
+               /* If radio repaired, update star chart and attack reports */\r
+               if (stdamtim != 1e30 && damage[DRADIO] == 0.0) {\r
+                       stdamtim = 1e30;\r
+                       prout("Lt. Uhura- \"Captain, the sub-space radio is working and");\r
+                       prout("   surveillance reports are coming in.");\r
+                       skip(1);\r
+                       for (i=1; i <= 8 ; i++)\r
+                               for (j=1; j <= 8; j++)\r
+                                       if (starch[i][j] > 999) starch[i][j] = 1;\r
+                       if (iseenit==0) {\r
+                               attakreport();\r
+                               iseenit = 1;\r
+                       }\r
+                       skip(1);\r
+                       prout("   The star chart is now up to date.\"");\r
+                       skip(1);\r
+               }\r
+               /* Cause extraneous event LINE to occur */\r
+               Time -= xtime;\r
+               switch (line) {\r
+                       case FSNOVA: /* Supernova */\r
+                               if (ipage==0) pause(1);\r
+                               ipage=1;\r
+                               snova(0,0);\r
+                               future[FSNOVA] = d.date + expran(0.5*intime);\r
+                               if (d.galaxy[quadx][quady] == 1000) return;\r
+                               break;\r
+                       case FSPY: /* Check with spy to see if S.C. should tractor beam */\r
+                               if (d.nscrem == 0 ||\r
+                                       ictbeam+istract > 0 ||\r
+                                       condit==IHDOCKED || isatb==1 || iscate==1) return;\r
+                               if (ientesc ||\r
+                                       (energy < 2000 && torps < 4 && shield < 1250) ||\r
+                                       (damage[DPHASER]>0 && (damage[DPHOTON]>0 || torps < 4)) ||\r
+                                       (damage[DSHIELD] > 0 &&\r
+                                        (energy < 2500 || damage[DPHASER] > 0) &&\r
+                                        (torps < 5 || damage[DPHOTON] > 0))) {\r
+                                       /* Tractor-beam her! */\r
+                                       istract=1;\r
+                                       yank = square(d.isx-quadx) + square(d.isy-quady);\r
+                                       /*********TBEAM CODE***********/\r
+                               }\r
+                               else return;\r
+                       case FTBEAM: /* Tractor beam */\r
+                               if (line==FTBEAM) {\r
+                                       if (d.remcom == 0) {\r
+                                               future[FTBEAM] = 1e30;\r
+                                               break;\r
+                                       }\r
+                                       i = Rand()*d.remcom+1.0;\r
+                                       yank = square(d.cx[i]-quadx) + square(d.cy[i]-quady);\r
+                                       if (istract || condit == IHDOCKED || yank == 0) {\r
+                                               /* Drats! Have to reschedule */\r
+                                               future[FTBEAM] = d.date + Time +\r
+                                                                                expran(1.5*intime/d.remcom);\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               /* tractor beaming cases merge here */\r
+                               yank = sqrt(yank);\r
+                               if (ipage==0) pause(1);\r
+                               ipage=1;\r
+                               Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */\r
+                               ictbeam = 1;\r
+                               skip(1);\r
+                               proutn("***");\r
+                               crmshp();\r
+                               prout(" caught in long range tractor beam--");\r
+                               /* If Kirk & Co. screwing around on planet, handle */\r
+                               atover(1); /* atover(1) is Grab */\r
+                               if (alldone) return;\r
+                               if (icraft == 1) { /* Caught in Galileo? */\r
+                                       finish(FSTRACTOR);\r
+                                       return;\r
+                               }\r
+                               /* Check to see if shuttle is aboard */\r
+                               if (iscraft==0) {\r
+                                       skip(1);\r
+                                       if (Rand() >0.5) {\r
+                                               prout("Galileo, left on the planet surface, is captured");\r
+                                               prout("by aliens and made into a flying McDonald's.");\r
+                                               damage[DSHUTTL] = -10;\r
+                                               iscraft = -1;\r
+                                       }\r
+                                       else {\r
+                                               prout("Galileo, left on the planet surface, is well hidden.");\r
+                                       }\r
+                               }\r
+                               if (line==0) {\r
+                                       quadx = d.isx;\r
+                                       quady = d.isy;\r
+                               }\r
+                               else {\r
+                                       quadx = d.cx[i];\r
+                                       quady = d.cy[i];\r
+                               }\r
+                               iran10(&sectx, &secty);\r
+                               crmshp();\r
+                               proutn(" is pulled to");\r
+                               cramlc(1, quadx, quady);\r
+                               proutn(", ");\r
+                               cramlc(2, sectx, secty);\r
+                               skip(1);\r
+                               if (resting) {\r
+                                       prout("(Remainder of rest/repair period cancelled.)");\r
+                                       resting = 0;\r
+                               }\r
+                               if (shldup==0) {\r
+                                       if (damage[DSHIELD]==0 && shield > 0) {\r
+                                               sheild(2); /* Shldsup */\r
+                                               shldchg=0;\r
+                                       }\r
+                                       else prout("(Shields not currently useable.)");\r
+                               }\r
+                               newqad(0);\r
+                               /* Adjust finish time to time of tractor beaming */\r
+                               fintim = d.date+Time;\r
+                               if (d.remcom <= 0) future[FTBEAM] = 1e30;\r
+                               else future[FTBEAM] = d.date+Time+expran(1.5*intime/d.remcom);\r
+                               break;\r
+                       case FSNAP: /* Snapshot of the universe (for time warp) */\r
+                               snapsht = d;\r
+                               d.snap = 1;\r
+                               future[FSNAP] = d.date + expran(0.5 * intime);\r
+                               break;\r
+                       case FBATTAK: /* Commander attacks starbase */\r
+                               if (d.remcom==0 || d.rembase==0) {\r
+                                       /* no can do */\r
+                                       future[FBATTAK] = future[FCDBAS] = 1e30;\r
+                                       break;\r
+                               }\r
+                               i = 0;\r
+                               for (j=1; j<=d.rembase; j++) {\r
+                                       for (k=1; k<=d.remcom; k++)\r
+                                               if (d.baseqx[j]==d.cx[k] && d.baseqy[j]==d.cy[k] &&\r
+                                                       (d.baseqx[j]!=quadx || d.baseqy[j]!=quady) &&\r
+                                                       (d.baseqx[j]!=d.isx || d.baseqy[j]!=d.isy)) {\r
+                                                       i = 1;\r
+                                                       break;\r
+                                               }\r
+                                       if (i == 1) break;\r
+                               }\r
+                               if (j>d.rembase) {\r
+                                       /* no match found -- try later */\r
+                                       future[FBATTAK] = d.date + expran(0.3*intime);\r
+                                       future[FCDBAS] = 1e30;\r
+                                       break;\r
+                               }\r
+                               /* commander + starbase combination found -- launch attack */\r
+                               batx = d.baseqx[j];\r
+                               baty = d.baseqy[j];\r
+                               future[FCDBAS] = d.date+1.0+3.0*Rand();\r
+                               if (isatb) /* extra time if SC already attacking */\r
+                                       future[FCDBAS] += future[FSCDBAS]-d.date;\r
+                               future[FBATTAK] = future[FCDBAS] +expran(0.3*intime);\r
+                               iseenit = 0;\r
+                               if (damage[DRADIO] != 0.0 &&\r
+                                       condit != IHDOCKED) break; /* No warning :-( */\r
+                               iseenit = 1;\r
+                               if (ipage==0) pause(1);\r
+                               ipage = 1;\r
+                               skip(1);\r
+                               proutn("Lt. Uhura-  \"Captain, the starbase in");\r
+                               cramlc(1, batx, baty);\r
+                               skip(1);\r
+                               prout("   reports that it is under atttack and that it can");\r
+                               proutn("   hold out only until stardate ");\r
+                               cramf(future[FCDBAS],1,1);\r
+                               prout(".\"");\r
+                               if (resting) {\r
+                                       skip(1);\r
+                                       proutn("Mr. Spock-  \"Captain, shall we cancel the rest period?\"");\r
+                                       if (ja()) {\r
+                                               resting = 0;\r
+                                               Time = 0.0;\r
+                                               return;\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case FSCDBAS: /* Supercommander destroys base */\r
+                               future[FSCDBAS] = 1e30;\r
+                               isatb = 2;\r
+                               if (d.galaxy[d.isx][d.isy]%100 < 10) break; /* WAS RETURN! */\r
+                               ixhold = batx;\r
+                               iyhold = baty;\r
+                               batx = d.isx;\r
+                               baty = d.isy;\r
+                       case FCDBAS: /* Commander succeeds in destroying base */\r
+                               if (line==FCDBAS) {\r
+                                       future[FCDBAS] = 1e30;\r
+                                       /* find the lucky pair */\r
+                                       for (i = 1; i <= d.remcom; i++)\r
+                                               if (d.cx[i]==batx && d.cy[i]==baty) break;\r
+                                       if (i > d.remcom || d.rembase == 0 ||\r
+                                               d.galaxy[batx][baty] % 100 < 10) {\r
+                                               /* No action to take after all */\r
+                                               batx = baty = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               /* Code merges here for any commander destroying base */\r
+                               /* Not perfect, but will have to do */\r
+                               if (starch[batx][baty] == -1) starch[batx][baty] = 0;\r
+                               /* Handle case where base is in same quadrant as starship */\r
+                               if (batx==quadx && baty==quady) {\r
+                                       if (starch[batx][baty] > 999) starch[batx][baty] -= 10;\r
+                                       quad[basex][basey]= IHDOT;\r
+                                       basex=basey=0;\r
+                                       newcnd();\r
+                                       skip(1);\r
+                                       prout("Spock-  \"Captain, I believe the starbase has been destroyed.\"");\r
+                               }\r
+                               else if (d.rembase != 1 &&\r
+                                                (damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {\r
+                                       /* Get word via subspace radio */\r
+                                       if (ipage==0) pause(1);\r
+                                       ipage = 1;\r
+                                       skip(1);\r
+                                       prout("Lt. Uhura-  \"Captain, Starfleet Command reports that");\r
+                                       proutn("   the starbase in");\r
+                                       cramlc(1, batx, baty);\r
+                                       prout(" has been destroyed by");\r
+                                       if (isatb==2) prout("the Klingon Super-Commander");\r
+                                       else prout("a Klingon Commander");\r
+                               }\r
+                               /* Remove Starbase from galaxy */\r
+                               d.galaxy[batx][baty] -= 10;\r
+                               for (i=1; i <= d.rembase; i++)\r
+                                       if (d.baseqx[i]==batx && d.baseqy[i]==baty) {\r
+                                               d.baseqx[i]=d.baseqx[d.rembase];\r
+                                               d.baseqy[i]=d.baseqy[d.rembase];\r
+                                       }\r
+                               d.rembase--;\r
+                               if (isatb == 2) {\r
+                                       /* reinstate a commander's base attack */\r
+                                       batx = ixhold;\r
+                                       baty = iyhold;\r
+                                       isatb = 0;\r
+                               }\r
+                               else {\r
+                                       batx = baty = 0;\r
+                               }\r
+                               break;\r
+                       case FSCMOVE: /* Supercommander moves */\r
+                               future[FSCMOVE] = d.date+0.2777;\r
+                               if (ientesc+istract==0 &&\r
+                                       isatb!=1 &&\r
+                                       (iscate!=1 || justin==1)) scom(&ipage);\r
+                               break;\r
+                       case FDSPROB: /* Move deep space probe */\r
+                               future[FDSPROB] = d.date + 0.01;\r
+                               probex += probeinx;\r
+                               probey += probeiny;\r
+                               i = (int)(probex/10 +0.05);\r
+                               j = (int)(probey/10 + 0.05);\r
+                               if (probecx != i || probecy != j) {\r
+                                       probecx = i;\r
+                                       probecy = j;\r
+                                       if (i < 1 || i > 8 || j < 1 || j > 8 ||\r
+                                               d.galaxy[probecx][probecy] == 1000) {\r
+                                               // Left galaxy or ran into supernova\r
+                                               if (damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
+                                                       if (ipage==0) pause(1);\r
+                                                       ipage = 1;\r
+                                                       skip(1);\r
+                                                       proutn("Lt. Uhura-  \"The deep space probe ");\r
+                                                       if (i < 1 ||i > 8 || j < 1 || j > 8)\r
+                                                               proutn("has left the galaxy");\r
+                                                       else\r
+                                                               proutn("is no longer transmitting");\r
+                                                       prout(".\"");\r
+                                               }\r
+                                               future[FDSPROB] = 1e30;\r
+                                               break;\r
+                                       }\r
+                                       if (damage[DRADIO]==0.0   || condit == IHDOCKED) {\r
+                                               if (ipage==0) pause(1);\r
+                                               ipage = 1;\r
+                                               skip(1);\r
+                                               proutn("Lt. Uhura-  \"The deep space probe is now in ");\r
+                                               cramlc(1, probecx, probecy);\r
+                                               prout(".\"");\r
+                                       }\r
+                               }\r
+                               /* Update star chart if Radio is working or have access to\r
+                                  radio. */\r
+                               if (damage[DRADIO] == 0.0 || condit == IHDOCKED)\r
+                                       starch[probecx][probecy] = damage[DRADIO] > 0.0 ?\r
+                                                                                  d.galaxy[probecx][probecy]+1000 : 1;\r
+                               proben--; // One less to travel\r
+                               if (proben == 0 && isarmed &&\r
+                                       d.galaxy[probecx][probecy] % 10 > 0) {\r
+                                       /* lets blow the sucker! */\r
+                                       snova(1,0);\r
+                                       future[FDSPROB] = 1e30;\r
+                                       if (d.galaxy[quadx][quady] == 1000) return;\r
+                               }\r
+                               break;\r
+               }\r
+       }\r
+}\r
+\r
+                               \r
+void wait(void) {\r
+       int key;\r
+       double temp, delay, origTime;\r
+\r
+       ididit = 0;\r
+       for (;;) {\r
+               key = scan();\r
+               if (key  != IHEOL) break;\r
+               proutn("How long? ");\r
+       }\r
+       chew();\r
+       if (key != IHREAL) {\r
+               huh();\r
+               return;\r
+       }\r
+       origTime = delay = aaitem;\r
+       if (delay <= 0.0) return;\r
+       if (delay >= d.remtime || nenhere != 0) {\r
+               prout("Are you sure? ");\r
+               if (ja() == 0) return;\r
+       }\r
+\r
+       /* Alternate resting periods (events) with attacks */\r
+\r
+       resting = 1;\r
+       do {\r
+               if (delay <= 0) resting = 0;\r
+               if (resting == 0) {\r
+                       cramf(d.remtime, 0, 2);\r
+                       prout(" stardates left.");\r
+                       return;\r
+               }\r
+               temp = Time = delay;\r
+\r
+               if (nenhere) {\r
+                       double rtime = 1.0 + Rand();\r
+                       if (rtime < temp) temp = rtime;\r
+                       Time = temp;\r
+               }\r
+               if (Time < delay) attack(0);\r
+               if (nenhere==0) movetho();\r
+               if (alldone) return;\r
+               events();\r
+               ididit = 1;\r
+               if (alldone) return;\r
+               delay -= temp;\r
+               /* Repair Deathray if long rest at starbase */\r
+               if (origTime-delay >= 9.99 && condit == IHDOCKED)\r
+                       damage[DDRAY] = 0.0;\r
+       } while (d.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas\r
+\r
+       resting = 0;\r
+       Time = 0;\r
+}\r
+\r
+void nova(int ix, int iy) {\r
+       static double course[] =\r
+               {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};\r
+       int bot, top, top2, burst, hits[11][3], kount, icx, icy, mm, nn, j;\r
+       int iquad, iquad1, i, ll, newcx, newcy, ii, jj;\r
+       if (Rand() < 0.05) {\r
+               /* Wow! We've supernova'ed */\r
+               snova(ix, iy);\r
+               return;\r
+       }\r
+\r
+       /* handle initial nova */\r
+       quad[ix][iy] = IHDOT;\r
+       crmena(1, IHSTAR, 2, ix, iy);\r
+       prout(" novas.");\r
+       d.galaxy[quadx][quady] -= 1;\r
+       d.starkl++;\r
+       \r
+       /* Set up stack to recursively trigger adjacent stars */\r
+       bot = top = top2 = 1;\r
+       kount = 0;\r
+       icx = icy = 0;\r
+       hits[1][1] = ix;\r
+       hits[1][2] = iy;\r
+       while (1) {\r
+               for (mm = bot; mm <= top; mm++) \r
+               for (nn = 1; nn <= 3; nn++)  /* nn,j represents coordinates around current */\r
+                       for (j = 1; j <= 3; j++) {\r
+                               if (j==2 && nn== 2) continue;\r
+                               ii = hits[mm][1]+nn-2;\r
+                               jj = hits[mm][2]+j-2;\r
+                               if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;\r
+                               iquad = quad[ii][jj];\r
+                               switch (iquad) {\r
+//                                     case IHDOT:     /* Empty space ends reaction\r
+//                                     case IHQUEST:\r
+//                                     case IHBLANK:\r
+//                                     case IHT:\r
+//                                     case IHWEB:\r
+                                       default:\r
+                                               break;\r
+                                       case IHSTAR: /* Affect another star */\r
+                                               if (Rand() < 0.05) {\r
+                                                       /* This star supernovas */\r
+                                                       snova(ii,jj);\r
+                                                       return;\r
+                                               }\r
+                                               top2++;\r
+                                               hits[top2][1]=ii;\r
+                                               hits[top2][2]=jj;\r
+                                               d.galaxy[quadx][quady] -= 1;\r
+                                               d.starkl++;\r
+                                               crmena(1, IHSTAR, 2, ii, jj);\r
+                                               prout(" novas.");\r
+                                               quad[ii][jj] = IHDOT;\r
+                                               break;\r
+                                       case IHP: /* Destroy planet */\r
+                                               d.newstuf[quadx][quady] -= 1;\r
+                                               d.nplankl++;\r
+                                               crmena(1, IHP, 2, ii, jj);\r
+                                               prout(" destroyed.");\r
+                                               d.plnets[iplnet] = nulplanet;\r
+                                               iplnet = plnetx = plnety = 0;\r
+                                               if (landed == 1) {\r
+                                                       finish(FPNOVA);\r
+                                                       return;\r
+                                               }\r
+                                               quad[ii][jj] = IHDOT;\r
+                                               break;\r
+                                       case IHB: /* Destroy base */\r
+                                               d.galaxy[quadx][quady] -= 10;\r
+                                               for (i = 1; i <= d.rembase; i++)\r
+                                                       if (d.baseqx[i]==quadx && d.baseqy[i]==quady) break;\r
+                                               d.baseqx[i] = d.baseqx[d.rembase];\r
+                                               d.baseqy[i] = d.baseqy[d.rembase];\r
+                                               d.rembase--;\r
+                                               basex = basey = 0;\r
+                                               d.basekl++;\r
+                                               newcnd();\r
+                                               crmena(1, IHB, 2, ii, jj);\r
+                                               prout(" destroyed.");\r
+                                               quad[ii][jj] = IHDOT;\r
+                                               break;\r
+                                       case IHE: /* Buffet ship */\r
+                                       case IHF:\r
+                                               prout("***Starship buffeted by nova.");\r
+                                               if (shldup) {\r
+                                                       if (shield >= 2000.0) shield -= 2000.0;\r
+                                                       else {\r
+                                                               double diff = 2000.0 - shield;\r
+                                                               energy -= diff;\r
+                                                               shield = 0.0;\r
+                                                               shldup = 0;\r
+                                                               prout("***Shields knocked out.");\r
+                                                               damage[DSHIELD] += 0.005*damfac*Rand()*diff;\r
+                                                       }\r
+                                               }\r
+                                               else energy -= 2000.0;\r
+                                               if (energy <= 0) {\r
+                                                       finish(FNOVA);\r
+                                                       return;\r
+                                               }\r
+                                               /* add in course nova contributes to kicking starship*/\r
+                                               icx += sectx-hits[mm][1];\r
+                                               icy += secty-hits[mm][2];\r
+                                               kount++;\r
+                                               break;\r
+                                       case IHK: /* kill klingon */\r
+                                               deadkl(ii,jj,iquad, ii, jj);\r
+                                               break;\r
+                                       case IHC: /* Damage/destroy big enemies */\r
+                                       case IHS:\r
+                                       case IHR:\r
+                                               for (ll = 1; ll <= nenhere; ll++)\r
+                                                       if (kx[ll]==ii && ky[ll]==jj) break;\r
+                                               kpower[ll] -= 800.0; /* If firepower is lost, die */\r
+                                               if (kpower[ll] <= 0.0) {\r
+                                                       deadkl(ii, jj, iquad, ii, jj);\r
+                                                       break;\r
+                                               }\r
+                                               newcx = ii + ii - hits[mm][1];\r
+                                               newcy = jj + jj - hits[mm][2];\r
+                                               crmena(1, iquad, 2, ii, jj);\r
+                                               proutn(" damaged");\r
+                                               if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {\r
+                                                       /* can't leave quadrant */\r
+                                                       skip(1);\r
+                                                       break;\r
+                                               }\r
+                                               iquad1 = quad[newcx][newcy];\r
+                                               if (iquad1 == IHBLANK) {\r
+                                                       proutn(", blasted into ");\r
+                                                       crmena(0, IHBLANK, 2, newcx, newcy);\r
+                                                       skip(1);\r
+                                                       deadkl(ii, jj, iquad, newcx, newcy);\r
+                                                       break;\r
+                                               }\r
+                                               if (iquad1 != IHDOT) {\r
+                                                       /* can't move into something else */\r
+                                                       skip(1);\r
+                                                       break;\r
+                                               }\r
+                                               proutn(", buffeted to");\r
+                                               cramlc(2, newcx, newcy);\r
+                                               quad[ii][jj] = IHDOT;\r
+                                               quad[newcx][newcy] = iquad;\r
+                                               kx[ll] = newcx;\r
+                                               ky[ll] = newcy;\r
+                                               kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));\r
+                                               kdist[ll] = kavgd[ll];\r
+                                               skip(1);\r
+                                               break;\r
+                               }\r
+                       }\r
+               if (top == top2) break;\r
+               bot = top + 1;\r
+               top = top2;\r
+       }\r
+       if (kount==0) return;\r
+\r
+       /* Starship affected by nova -- kick it away. */\r
+       dist = kount*0.1;\r
+       if (icx) icx = (icx < 0 ? -1 : 1);\r
+       if (icy) icy = (icy < 0 ? -1 : 1);\r
+       direc = course[3*(icx+1)+icy+2];\r
+       if (direc == 0.0) dist = 0.0;\r
+       if (dist == 0.0) return;\r
+       Time = 10.0*dist/16.0;\r
+       skip(1);\r
+       prout("Force of nova displaces starship.");\r
+       iattak=2;       /* Eliminates recursion problem */\r
+       move();\r
+       Time = 10.0*dist/16.0;\r
+       return;\r
+}\r
+       \r
+       \r
+void snova(int insx, int insy) {\r
+       int comdead, nqx, nqy, nsx, nsy, num, kldead, iscdead;\r
+       int nrmdead, npdead;\r
+       int insipient=0;\r
+\r
+       nsx = insy;\r
+       nsy = insy;\r
+\r
+       if (insy== 0) {\r
+               if (insx == 1) {\r
+                       /* NOVAMAX being used */\r
+                       nqx = probecx;\r
+                       nqy = probecy;\r
+               }\r
+               else {\r
+                       int stars = 0;\r
+                       /* Scheduled supernova -- select star */\r
+                       /* logic changed here so that we won't favor quadrants in top\r
+                       left of universe */\r
+                       for (nqx = 1; nqx<=8; nqx++) {\r
+                               for (nqy = 1; nqy<=8; nqy++) {\r
+                                       stars += d.galaxy[nqx][nqy] % 10;\r
+                               }\r
+                       }\r
+                       if (stars == 0) return; /* nothing to supernova exists */\r
+                       num = Rand()*stars + 1;\r
+                       for (nqx = 1; nqx<=8; nqx++) {\r
+                               for (nqy = 1; nqy<=8; nqy++) {\r
+                                       num -= d.galaxy[nqx][nqy] % 10;\r
+                                       if (num <= 0) break;\r
+                               }\r
+                               if (num <=0) break;\r
+                       }\r
+#ifdef DEBUG\r
+                       if (idebug) {\r
+                               proutn("Super nova here?");\r
+                               if (ja()==1) {\r
+                                       nqx = quadx;\r
+                                       nqy = quady;\r
+                               }\r
+                       }\r
+#endif\r
+               }\r
+\r
+               if (nqx != quady || nqy != quady || justin != 0) {\r
+                       /* it isn't here, or we just entered (treat as inroute) */\r
+                       if (damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
+                               skip(1);\r
+                               proutn("Message from Starfleet Command       Stardate ");\r
+                               cramf(d.date, 0, 1);\r
+                               skip(1);\r
+                               proutn("     Supernova in");\r
+                               cramlc(1, nqx, nqy);\r
+                               prout("; caution advised.");\r
+                       }\r
+               }\r
+               else {\r
+                       /* we are in the quadrant! */\r
+                       insipient = 1;\r
+                       num = Rand()* (d.galaxy[nqx][nqy]%10) + 1;\r
+                       for (nsx=1; nsx < 10; nsx++) {\r
+                               for (nsy=1; nsy < 10; nsy++) {\r
+                                       if (quad[nsx][nsy]==IHSTAR) {\r
+                                               num--;\r
+                                               if (num==0) break;\r
+                                       }\r
+                               }\r
+                               if (num==0) break;\r
+                       }\r
+               }\r
+       }\r
+       else {\r
+               insipient = 1;\r
+       }\r
+\r
+       if (insipient) {\r
+               skip(1);\r
+               prouts("***RED ALERT!  RED ALERT!");\r
+               skip(1);\r
+               proutn("***Incipient supernova detected at");\r
+               cramlc(2, nsx, nsy);\r
+               skip(1);\r
+               nqx = quadx;\r
+               nqy = quady;\r
+               if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {\r
+                       proutn("Emergency override attempts t");\r
+                       prouts("***************");\r
+                       skip(1);\r
+                       stars();\r
+                       alldone=1;\r
+               }\r
+       }\r
+       /* destroy any Klingons in supernovaed quadrant */\r
+       num=d.galaxy[nqx][nqy];\r
+       kldead = num/100;\r
+       comdead = iscdead = 0;\r
+       if (nqx==d.isx && nqy == d.isy) {\r
+               /* did in the Supercommander! */\r
+               d.nscrem = d.isx = d.isy = isatb = iscate = 0;\r
+               iscdead = 1;\r
+               future[FSCMOVE] = future[FSCDBAS] = 1e30;\r
+       }\r
+       d.remkl -= kldead;\r
+       if (d.remcom) {\r
+               int maxloop = d.remcom, l;\r
+               for (l = 1; l <= maxloop; l++) {\r
+                       if (d.cx[l] == nqx && d.cy[l] == nqy) {\r
+                               d.cx[l] = d.cx[d.remcom];\r
+                               d.cy[l] = d.cy[d.remcom];\r
+                               d.cx[d.remcom] = d.cy[d.remcom] = 0;\r
+                               d.remcom--;\r
+                               kldead--;\r
+                               comdead++;\r
+                               if (d.remcom==0) future[FTBEAM] = 1e30;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       /* destroy Romulans and planets in supernovaed quadrant */\r
+       num = d.newstuf[nqx][nqy];\r
+       d.newstuf[nqx][nqy] = 0;\r
+       nrmdead = num/10;\r
+       d.nromrem -= nrmdead;\r
+       npdead = num - nrmdead*10;\r
+       if (npdead) {\r
+               int l;\r
+               for (l = 1; l <= inplan; l++)\r
+                       if (d.plnets[l].x == nqx && d.plnets[l].y == nqy) {\r
+                               d.plnets[l] = nulplanet;\r
+                       }\r
+       }\r
+       /* Destroy any base in supernovaed quadrant */\r
+       if (d.rembase) {\r
+               int maxloop = d.rembase, l;\r
+               for (l = 1; l <= maxloop; l++)\r
+                       if (d.baseqx[l]==nqx && d.baseqy[l]==nqy) {\r
+                               d.baseqx[l] = d.baseqx[d.rembase];\r
+                               d.baseqy[l] = d.baseqy[d.rembase];\r
+                               d.baseqx[d.rembase] = d.baseqy[d.rembase] = 0;\r
+                               d.rembase--;\r
+                               break;\r
+                       }\r
+       }\r
+       /* If starship caused supernova, tally up destruction */\r
+       if (insx) {\r
+               num = d.galaxy[nqx][nqy] % 100;\r
+               d.starkl += num % 10;\r
+               d.basekl += num/10;\r
+               d.killk += kldead;\r
+               d.killc += comdead;\r
+               d.nromkl += nrmdead;\r
+               d.nplankl += npdead;\r
+               d.nsckill += iscdead;\r
+       }\r
+       /* mark supernova in galaxy and in star chart */\r
+       if ((quadx == nqx && quady == nqy) ||\r
+               damage[DRADIO] == 0 ||\r
+               condit == IHDOCKED)\r
+               starch[nqx][nqy] = 1;\r
+       d.galaxy[nqx][nqy] = 1000;\r
+       /* If supernova destroys last klingons give special message */\r
+       if (d.remkl==0 && (nqx != quadx || nqy != quady)) {\r
+               skip(2);\r
+               if (insx == 0) prout("Lucky you!");\r
+               proutn("A supernova in");\r
+               cramlc(1, nqx, nqy);\r
+               prout(" has just destroyed the last Klingons.");\r
+               finish(FWON);\r
+               return;\r
+       }\r
+       /* if some Klingons remain, continue or die in supernova */\r
+       if (alldone) finish(FSNOVAED);\r
+       return;\r
+}\r
+               \r
+                               \r
diff --git a/finish.c b/finish.c
new file mode 100644 (file)
index 0000000..1d58840
--- /dev/null
+++ b/finish.c
@@ -0,0 +1,447 @@
+#include "sst.h"\r
+#include <string.h>\r
+#include <time.h>\r
+\r
+void dstrct() {\r
+       /* Finish with a BANG! */\r
+       chew();\r
+       if (damage[DCOMPTR] != 0.0) {\r
+               prout("Computer damaged; cannot execute destruct sequence.");\r
+               return;\r
+       }\r
+       skip(1);\r
+       prouts("---WORKING---"); skip(1);\r
+       prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED");\r
+       prouts("   10"); skip(1);\r
+       prouts("       9"); skip(1);\r
+       prouts("          8"); skip(1);\r
+       prouts("             7"); skip(1);\r
+       prouts("                6"); skip(1);\r
+       prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");\r
+       prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");\r
+       prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");\r
+       scan();\r
+       chew();\r
+       if (strcmp(passwd, citem) != 0) {\r
+               prouts("PASSWORD-REJECTED;"); skip(1);\r
+               prout("CONTINUITY-EFFECTED");\r
+               skip(1);\r
+               return;\r
+       }\r
+       prouts("PASSWORD-ACCEPTED"); skip(1);\r
+       prouts("                   5"); skip(1);\r
+       prouts("                      4"); skip(1);\r
+       prouts("                         3"); skip(1);\r
+       prouts("                            2"); skip(1);\r
+       prouts("                              1"); skip(1);\r
+       if (Rand() < 0.15) {\r
+               prouts("GOODBYE-CRUEL-WORLD");\r
+               skip(1);\r
+       }\r
+       skip(2);\r
+       kaboom();\r
+}\r
+\r
+void kaboom(void) {\r
+       stars();\r
+       if (ship==IHE) prouts("***");\r
+       prouts("********* Entropy of ");\r
+       crmshp();\r
+       prouts(" maximized *********");\r
+       skip(1);\r
+       stars();\r
+       skip(1);\r
+       if (nenhere != 0) {\r
+               double whammo = 25.0 * energy;\r
+               int l=1;\r
+               while (l <= nenhere) {\r
+                       if (kpower[l]*kdist[l] <= whammo) \r
+                               deadkl(kx[l],ky[l], quad[kx[l]][ky[l]], kx[l], ky[l]);\r
+                       l++;\r
+               }\r
+       }\r
+       finish(FDILITHIUM);\r
+}\r
+                               \r
+\r
+void finish(FINTYPE ifin) {\r
+       int igotit = 0;\r
+       alldone = 1;\r
+       skip(3);\r
+       printf("It is stardate %.1f .\n\n", d.date);\r
+       switch (ifin) {\r
+               case FWON: // Game has been won\r
+                       if (d.nromrem != 0)\r
+                               printf("The remaining %d Romulans surrender to Starfleet Command.\n",\r
+                                          d.nromrem);\r
+                       \r
+                       prout("You have smashed the Klingon invasion fleet and saved");\r
+                       prout("the Federation.");\r
+                       gamewon=1;\r
+                       if (alive) {\r
+                               double badpt;\r
+                               badpt = 5.*d.starkl + casual + 10.*d.nplankl +\r
+                                               45.*nhelp+100.*d.basekl;\r
+                               if (ship == IHF) badpt += 100.0;\r
+                               else if (ship == 0) badpt += 200.0;\r
+                               if (badpt < 100.0) badpt = 0.0; // Close enough!\r
+                               if (d.date-indate < 5.0 ||\r
+                                       // killsPerDate >= RateMax\r
+                                       (d.killk+d.killc+d.nsckill)/(d.date-indate) >=\r
+                                       0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {\r
+                                       skip(1);\r
+                                       prout("In fact, you have done so well that Starfleet Command");\r
+                                       switch (skill) {\r
+                                               case 1:\r
+                                                       prout("promotes you one step in rank from \"Novice\" to \"Fair\".");\r
+                                                       break;\r
+                                               case 2:\r
+                                                       prout("promotes you one step in rank from \"Fair\" to \"Good\".");\r
+                                                       break;\r
+                                               case 3:\r
+                                                       prout("promotes you one step in rank from \"Good\" to \"Expert\".");\r
+                                                       break;\r
+                                               case 4:\r
+                                                       prout("promotes you to Commodore Emeritus.");\r
+                                                       skip(1);\r
+                                                       prout("Now that you think you're really good, try playing");\r
+                                                       prout("the \"Emeritus\" game. It will splatter your ego.");\r
+                                                       break;\r
+                                               case 5:\r
+                                                       skip(1);\r
+                                                       prout("Computer-  ERROR-ERROR-ERROR-ERROR");\r
+                                                       skip(1);\r
+                                                       prout("  YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");\r
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");\r
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");\r
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");\r
+                                                       prout("  THIS-PROGRAM-MUST?- MUST ? - SUR? ? -?  VI");\r
+                                                       skip(1);\r
+                                                       prout("Now you can retire and write your own Star Trek game!");\r
+                                                       skip(1);\r
+                                                       break;\r
+                                       }\r
+                                       if (skill > 3) {\r
+                                               if (thawed\r
+#ifdef DEBUG\r
+                                                       && !idebug\r
+#endif\r
+                                                       )\r
+                                                       prout("You cannot get a citation, so...");\r
+                                               else {\r
+                                                       prout("Do you want your Commodore Emeritus Citation printed?");\r
+                                                       proutn("(You need a 132 column printer.)");\r
+                                                       chew();\r
+                                                       if (ja()) {\r
+                                                               igotit = 1;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               // Only grant long life if alive (original didn't!)\r
+                               skip(1);\r
+                               prout("LIVE LONG AND PROSPER.");\r
+                       }\r
+                       score();\r
+                       if (igotit != 0) plaque();\r
+                       return;\r
+               case FDEPLETE: // Federation Resources Depleted\r
+                       prout("Your time has run out and the Federation has been");\r
+                       prout("conquered.  Your starship is now Klingon property,");\r
+                       prout("and you are put on trial as a war criminal.  On the");\r
+                       proutn("basis of your record, you are ");\r
+                       if (d.remkl*3.0 > inkling) {\r
+                               prout("aquitted.");\r
+                               skip(1);\r
+                               prout("LIVE LONG AND PROSPER.");\r
+                       }\r
+                       else {\r
+                               prout("found guilty and");\r
+                               prout("sentenced to death by slow torture.");\r
+                               alive = 0;\r
+                       }\r
+                       score();\r
+                       return;\r
+               case FLIFESUP:\r
+                       prout("Your life support reserves have run out, and");\r
+                       prout("you die of thirst, starvation, and asphyxiation.");\r
+                       prout("Your starship is a derelict in space.");\r
+                       break;\r
+               case FNRG:\r
+                       prout("Your energy supply is exhausted.");\r
+                       skip(1);\r
+                       prout("Your starship is a derelict in space.");\r
+                       break;\r
+               case FBATTLE:\r
+                       proutn("The ");\r
+                       crmshp();\r
+                       prout("has been destroyed in battle.");\r
+                       skip(1);\r
+                       prout("Dulce et decorum est pro patria mori.");\r
+                       break;\r
+               case FNEG3:\r
+                       prout("You have made three attempts to cross the negative energy");\r
+                       prout("barrier which surrounds the galaxy.");\r
+                       skip(1);\r
+                       prout("Your navigation is abominable.");\r
+                       score();\r
+                       return;\r
+               case FNOVA:\r
+                       prout("Your starship has been destroyed by a nova.");\r
+                       prout("That was a great shot.");\r
+                       skip(1);\r
+                       break;\r
+               case FSNOVAED:\r
+                       proutn("The ");\r
+                       crmshp();\r
+                       prout(" has been fried by a supernova.");\r
+                       prout("...Not even cinders remain...");\r
+                       break;\r
+               case FABANDN:\r
+                       prout("You have been captured by the Klingons. If you still");\r
+                       prout("had a starbase to be returned to, you would have been");\r
+                       prout("repatriated and given another chance. Since you have");\r
+                       prout("no starbases, you will be mercilessly tortured to death.");\r
+                       break;\r
+               case FDILITHIUM:\r
+                       prout("Your starship is now an expanding cloud of subatomic particles");\r
+                       break;\r
+               case FMATERIALIZE:\r
+                       prout("Starbase was unable to re-materialize your starship.");\r
+                       prout("Sic transit gloria muntdi");\r
+                       break;\r
+               case FPHASER:\r
+                       proutn("The ");\r
+                       crmshp();\r
+                       prout(" has been cremated by its own phasers.");\r
+                       break;\r
+               case FLOST:\r
+                       prout("You and your landing party have been");\r
+                       prout("converted to energy, disipating through space.");\r
+                       break;\r
+               case FMINING:\r
+                       prout("You are left with your landing party on");\r
+                       prout("a wild jungle planet inhabited by primitive cannibals.");\r
+                       skip(1);\r
+                       prout("They are very fond of \"Captain Kirk\" soup.");\r
+                       skip(1);\r
+                       proutn("Without your leadership, the ");\r
+                       crmshp();\r
+                       prout(" is destroyed.");\r
+                       break;\r
+               case FDPLANET:\r
+                       prout("You and your mining party perish.");\r
+                       skip(1);\r
+                       prout("That was a great shot.");\r
+                       skip(1);\r
+                       break;\r
+               case FSSC:\r
+                       prout("The Galileo is instantly annihilated by the supernova.");\r
+                       // no break;\r
+               case FPNOVA:\r
+                       prout("You and your mining party are atomized.");\r
+                       skip(1);\r
+                       proutn("Mr. Spock takes command of the ");\r
+                       crmshp();\r
+                       prout(" and");\r
+                       prout("joins the Romulans, reigning terror on the Federation.");\r
+                       break;\r
+               case FSTRACTOR:\r
+                       prout("The shuttle craft Galileo is also caught,");\r
+                       prout("and breaks up under the strain.");\r
+                       skip(1);\r
+                       prout("Your debris is scattered for millions of miles.");\r
+                       proutn("Without your leadership, the ");\r
+                       crmshp();\r
+                       prout(" is destroyed.");\r
+                       break;\r
+               case FDRAY:\r
+                       prout("The mutants attack and kill Spock.");\r
+                       prout("Your ship is captured by Klingons, and");\r
+                       prout("your crew is put on display in a Klingon zoo.");\r
+                       break;\r
+               case FTRIBBLE:\r
+                       prout("Tribbles consume all remaining water,");\r
+                       prout("food, and oxygen on your ship.");\r
+                       skip(1);\r
+                       prout("You die of thirst, starvation, and asphyxiation.");\r
+                       prout("Your starship is a derelict in space.");\r
+                       break;\r
+               case FHOLE:\r
+                       prout("Your ship is drawn to the center of the black hole.");\r
+                       prout("You are crushed into extremely dense matter.");\r
+                       break;\r
+       }\r
+       if (ship==IHF) ship= 0;\r
+       else if (ship == IHE) ship = IHF;\r
+       alive = 0;\r
+       if (d.remkl != 0) {\r
+               double goodies = d.remres/inresor;\r
+               double baddies = (d.remkl + 2.0*d.remcom)/(inkling+2.0*incom);\r
+               if (goodies/baddies >= 1.0+0.5*Rand()) {\r
+                       prout("As a result of your actions, a treaty with the Klingon");\r
+                       prout("Empire has been signed. The terms of the treaty are");\r
+                       if (goodies/baddies >= 3.0+Rand()) {\r
+                               prout("favorable to the Federation.");\r
+                               skip(1);\r
+                               prout("Congratulations!");\r
+                       }\r
+                       else\r
+                               prout("highly unfavorable to the Federation.");\r
+               }\r
+               else\r
+                       prout("The Federation will be destroyed.");\r
+       }\r
+       else {\r
+               prout("Since you took the last Klingon with you, you are a");\r
+               prout("martyr and a hero. Someday maybe they'll erect a");\r
+               prout("statue in your memory. Rest in peace, and try not");\r
+               prout("to think about pigeons.");\r
+               gamewon = 1;\r
+       }\r
+       score();\r
+}\r
+\r
+void score(void) {\r
+       double timused = d.date - indate;\r
+       int ithperd, iwon, klship;\r
+\r
+       pause(0);\r
+\r
+       iskill = skill;\r
+       if ((timused == 0 || d.remkl != 0) && timused < 5.0) timused = 5.0;\r
+       perdate = (d.killc + d.killk + d.nsckill)/timused;\r
+       ithperd = 500*perdate + 0.5;\r
+       iwon = 0;\r
+       if (gamewon) iwon = 100*skill;\r
+       if (ship == IHE) klship = 0;\r
+       else if (ship == IHF) klship = 1;\r
+       else klship = 2;\r
+       if (gamewon == 0) d.nromrem = 0; // None captured if no win\r
+       iscore = 10*d.killk + 50*d.killc + ithperd + iwon\r
+                        - 100*d.basekl - 100*klship - 45*nhelp -5*d.starkl - casual\r
+                        + 20*d.nromkl + 200*d.nsckill - 10*d.nplankl + d.nromrem;\r
+       if (alive == 0) iscore -= 200;\r
+       skip(2);\r
+       prout("Your score --");\r
+       if (d.nromkl)\r
+               printf("%6d Romulans destroyed                 %5d\n",\r
+                          d.nromkl,20*d.nromkl);\r
+       if (d.nromrem)\r
+               printf("%6d Romulans captured                  %5d\n",\r
+                          d.nromrem, d.nromrem);\r
+       if (d.killk)\r
+               printf("%6d ordinary Klingons destroyed        %5d\n",\r
+                          d.killk, 10*d.killk);\r
+       if (d.killc)\r
+               printf("%6d Klingon commanders destroyed       %5d\n",\r
+                          d.killc, 50*d.killc);\r
+       if (d.nsckill)\r
+               printf("%6d Super-Commander destroyed          %5d\n",\r
+                          d.nsckill, 200*d.nsckill);\r
+       if (ithperd)\r
+               printf("%6.2f Klingons per stardate              %5d\n",\r
+                          perdate, ithperd);\r
+       if (d.starkl)\r
+               printf("%6d stars destroyed by your action     %5d\n",\r
+                          d.starkl, -5*d.starkl);\r
+       if (d.nplankl)\r
+               printf("%6d planets destroyed by your action   %5d\n",\r
+                          d.nplankl, -10*d.nplankl);\r
+       if (d.basekl)\r
+               printf("%6d bases destroyed by your action     %5d\n",\r
+                          d.basekl, -100*d.basekl);\r
+       if (nhelp)\r
+               printf("%6d calls for help from starbase       %5d\n",\r
+                          nhelp, -45*nhelp);\r
+       if (casual)\r
+               printf("%6d casualties incurred                %5d\n",\r
+                          casual, -casual);\r
+       if (klship)\r
+               printf("%6d ship(s) lost or destroyed          %5d\n",\r
+                          klship, -100*klship);\r
+       if (alive==0)\r
+               prout("Penalty for getting yourself killed        -200");\r
+       if (gamewon) {\r
+               skip(1);\r
+               proutn("Bonus for winning ");\r
+               switch (skill) {\r
+                       case 1: proutn("Novice game  "); break;\r
+                       case 2: proutn("Fair game    "); break;\r
+                       case 3: proutn("Good game    "); break;\r
+                       case 4: proutn("Expert game  "); break;\r
+                       case 5: proutn("Emeritus game"); break;\r
+               }\r
+               printf("           %5d\n", iwon);\r
+       }\r
+       skip(2);\r
+       printf("TOTAL SCORE                               %5d\n", iscore);\r
+}\r
+\r
+void plaque(void) {\r
+       FILE *fp=NULL;\r
+       time_t t;\r
+       char *timestring;\r
+       int nskip;\r
+       char winner[128];\r
+\r
+       skip(2);\r
+       \r
+       while (fp == NULL) {\r
+               printf("File or device name for your plaque:");\r
+               fgets(winner, 128, stdin);\r
+               winner[strlen(winner)-1] = '\0';\r
+               fp = fopen(winner, "w");\r
+               if (fp==NULL) {\r
+                       printf("Invalid name.\n");\r
+               }\r
+       }\r
+\r
+       printf("Enter name to go on plaque (up to 30 characters):");\r
+       fgets(winner, 128, stdin);\r
+       winner[strlen(winner)-1] = '\0';\r
+       winner[30] = '\0';\r
+       nskip = 64 - strlen(winner)/2;\r
+\r
+       fprintf(fp,"\n\n\n\n");\r
+       /* --------DRAW ENTERPRISE PICTURE. */\r
+       fprintf(fp, "                                                                EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );\r
+       fprintf(fp, "                                      EEE                      E  : :                                         :  E\n" );\r
+       fprintf(fp, "                                    EE   EEE                   E  : :                   NCC-1701              :  E\n");\r
+       fprintf(fp, "                    EEEEEEEEEEEEEEEE        EEEEEEEEEEEEEEE    E  : :                                         : E\n");\r
+       fprintf(fp, "                     E                                     E    EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");\r
+       fprintf(fp, "                      EEEEEEEEE               EEEEEEEEEEEEE                 E  E\n");\r
+       fprintf(fp, "                               EEEEEEE   EEEEE    E          E              E  E\n");\r
+       fprintf(fp, "                                      EEE           E          E            E  E\n");\r
+       fprintf(fp, "                                                       E         E          E  E\n");\r
+       fprintf(fp, "                                                         EEEEEEEEEEEEE      E  E\n");\r
+       fprintf(fp, "                                                      EEE :           EEEEEEE  EEEEEEEE\n");\r
+       fprintf(fp, "                                                    :E    :                 EEEE       E\n");\r
+       fprintf(fp, "                                                   .-E   -:-----                       E\n");\r
+       fprintf(fp, "                                                    :E    :                            E\n");\r
+       fprintf(fp, "                                                      EE  :                    EEEEEEEE\n");\r
+       fprintf(fp, "                                                       EEEEEEEEEEEEEEEEEEEEEEE\n");\r
+       fprintf(fp, "\n\n\n");\r
+       fprintf(fp, "                                                       U. S. S. ENTERPRISE\n");\r
+       fprintf(fp, "\n\n\n\n");\r
+       fprintf(fp, "                                  For demonstrating outstanding ability as a starship captain\n");\r
+       fprintf(fp, "\n");\r
+       fprintf(fp, "                                                Starfleet Command bestows to you\n");\r
+       fprintf(fp, "\n");\r
+       fprintf(fp,"%*s%s\n\n", nskip, "", winner);\r
+       fprintf(fp, "                                                           the rank of\n\n");\r
+       fprintf(fp, "                                                       \"Commodore Emeritus\"\n\n");\r
+       fprintf(fp, "                                                          ");\r
+       switch (iskill) {\r
+               case 4: fprintf(fp," Expert level\n\n"); break;\r
+               case 5: fprintf(fp,"Emeritus level\n\n"); break;\r
+               default: fprintf(fp," Cheat level\n\n"); break;\r
+       }\r
+       t = time(NULL);\r
+       timestring = ctime(&t);\r
+       fprintf(fp, "                                                 This day of %.6s %.4s, %.8s\n\n",\r
+                       timestring+4, timestring+20, timestring+11);\r
+       fprintf(fp,"                                                        Your score:  %d\n\n", iscore);\r
+       fprintf(fp,"                                                    Klingons per stardate:  %.2f\n", perdate);\r
+       fclose(fp);\r
+}\r
diff --git a/linux.c b/linux.c
new file mode 100644 (file)
index 0000000..9bd3b13
--- /dev/null
+++ b/linux.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <time.h>
+#include <sys/ioctl.h>
+
+void randomize(void) {
+       srand((int)time(NULL));
+}
+
+
+int max(int a, int b) {
+       if (a > b) return a;
+       return b;
+}
+
+int min(int a, int b) {
+       if (a < b) return a;
+       return b;
+}
+
+int getch(void) {
+       char chbuf[1];
+       struct termio oldstate, newstate;
+    ioctl(0,TCGETA,&oldstate);
+       newstate = oldstate;
+       newstate.c_iflag = 0;
+       newstate.c_lflag = 0;
+       ioctl(0,TCSETA,&newstate);
+       read(0, &chbuf, 1);
+    ioctl(0,TCSETA,&oldstate);
+}
+
diff --git a/makefile b/makefile
new file mode 100644 (file)
index 0000000..3e35142
--- /dev/null
+++ b/makefile
@@ -0,0 +1,15 @@
+CFLAGS=     -O
+
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+OFILES=     sst.o finish.o reports.o setup.o linux.o moving.o battle.o events.o ai.o planets.o
+
+HFILES=     sst.h
+
+sstos2.exe:  $(OFILES)
+       gcc  -o sst $(OFILES) -lm
+
+        
+$(OFILES):  $(HFILES)
+
diff --git a/moving.c b/moving.c
new file mode 100644 (file)
index 0000000..fae20ff
--- /dev/null
+++ b/moving.c
@@ -0,0 +1,966 @@
+#include "sst.h"\r
+\r
+static void getcd(int, int);\r
+\r
+void move(void) {\r
+       double angle, deltax, deltay, bigger, x, y,\r
+       finald, finalx, finaly, stopegy;\r
+       int trbeam = 0, n, l, ix, iy, kink, kinks, iquad;\r
+\r
+       if (inorbit) {\r
+               prout("SULU- \"Leaving standard orbit.\"");\r
+               inorbit = 0;\r
+       }\r
+\r
+       angle = ((15.0 - direc) * 0.5235988);\r
+       deltax = -sin(angle);\r
+       deltay = cos(angle);\r
+       if (fabs(deltax) > fabs(deltay))\r
+               bigger = fabs(deltax);\r
+       else\r
+               bigger = fabs(deltay);\r
+               \r
+       deltay /= bigger;\r
+       deltax /= bigger;\r
+\r
+       /* If tractor beam is to occur, don't move full distance */\r
+       if (d.date+Time >= future[FTBEAM]) {\r
+               trbeam = 1;\r
+               condit = IHRED;\r
+               dist = dist*(future[FTBEAM]-d.date)/Time + 0.1;\r
+               Time = future[FTBEAM] - d.date + 1e-5;\r
+       }\r
+       /* Move within the quadrant */\r
+       quad[sectx][secty] = IHDOT;\r
+       x = sectx;\r
+       y = secty;\r
+       n = 10.0*dist*bigger+0.5;\r
+\r
+       if (n > 0) {\r
+               for (l = 1; l <= n; l++) {\r
+                       ix = (x += deltax) + 0.5;\r
+                       iy = (y += deltay) + 0.5;\r
+                       if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {\r
+                               /* Leaving quadrant -- allow final enemy attack */\r
+                               /* Don't do it if being pushed by Nova */\r
+                               if (nenhere != 0 && iattak != 2) {\r
+                                       newcnd();\r
+                                       for (l = 1; l <= nenhere; l++) {\r
+                                               finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
+                                                                         (iy-ky[l])*(double)(iy-ky[l]));\r
+                                               kavgd[l] = 0.5 * (finald+kdist[l]);\r
+                                       }\r
+                                       if (d.galaxy[quadx][quady] != 1000) attack(0);\r
+                                       if (alldone) return;\r
+                               }\r
+                               /* compute final position -- new quadrant and sector */\r
+                               x = 10*(quadx-1)+sectx;\r
+                               y = 10*(quady-1)+secty;\r
+                               ix = x+10.0*dist*bigger*deltax+0.5;\r
+                               iy = y+10.0*dist*bigger*deltay+0.5;\r
+                               /* check for edge of galaxy */\r
+                               kinks = 0;\r
+                               do {\r
+                                       kink = 0;\r
+                                       if (ix <= 0) {\r
+                                               ix = -ix + 1;\r
+                                               kink = 1;\r
+                                       }\r
+                                       if (iy <= 0) {\r
+                                               iy = -iy + 1;\r
+                                               kink = 1;\r
+                                       }\r
+                                       if (ix > 80) {\r
+                                               ix = 161 - ix;\r
+                                               kink = 1;\r
+                                       }\r
+                                       if (iy > 80) {\r
+                                               iy = 161 - iy;\r
+                                               kink = 1;\r
+                                       }\r
+                                       if (kink) kinks = 1;\r
+                               } while (kink);\r
+\r
+                               if (kinks) {\r
+                                       nkinks += 1;\r
+                                       if (nkinks == 3) {\r
+                                               /* Three strikes -- you're out! */\r
+                                               finish(FNEG3);\r
+                                               return;\r
+                                       }\r
+                                       prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"\r
+                                                "AT THE EDGE OF THE GALAXY.  THE THIRD TIME YOU TRY THIS,\n"\r
+                                                "YOU WILL BE DESTROYED.\n");\r
+                               }\r
+                               /* Compute final position in new quadrant */\r
+                               if (trbeam) return; /* Don't bother if we are to be beamed */\r
+                               quadx = (ix+9)/10;\r
+                               quady = (iy+9)/10;\r
+                               sectx = ix - 10*(quadx-1);\r
+                               secty = iy - 10*(quady-1);\r
+                               proutn("\nEntering");\r
+                               cramlc(1, quadx, quady);\r
+                               skip(1);\r
+                               quad[sectx][secty] = ship;\r
+                               newqad(0);\r
+                               return;\r
+                       }\r
+                       iquad = quad[ix][iy];\r
+                       if (iquad != IHDOT) {\r
+                               /* object encountered in flight path */\r
+                               stopegy = 50.0*dist/Time;\r
+                               dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
+                                                         (secty-iy)*(double)(secty-iy));\r
+                               switch (iquad) {\r
+                                       case IHT: /* Ram a Tholean */\r
+                                       case IHK: /* Ram enemy ship */\r
+                                       case IHC:\r
+                                       case IHS:\r
+                                       case IHR:\r
+                                               sectx = ix;\r
+                                               secty = iy;\r
+                                               ram(0, iquad, sectx, secty);\r
+                                               finalx = sectx;\r
+                                               finaly = secty;\r
+                                               break;\r
+                                       case IHBLANK:\r
+                                               skip(1);\r
+                                               prouts("***RED ALERT!  RED ALERT!");\r
+                                               skip(1);\r
+                                               proutn("***");\r
+                                               crmshp();\r
+                                               proutn(" pulled into black hole at");\r
+                                               cramlc(2, ix, iy);\r
+                                               skip(1);\r
+                                               finish(FHOLE);\r
+                                               return;\r
+                                       default:\r
+                                               /* something else */\r
+                                               skip(1);\r
+                                               crmshp();\r
+                                               if (iquad == IHWEB)\r
+                                                       proutn(" encounters Tholian web at");\r
+                                               else\r
+                                                       proutn(" blocked by object at");\r
+                                               cramlc(2, ix,iy);\r
+                                               prout(";");\r
+                                               proutn("Emergency stop required ");\r
+                                               cramf(stopegy, 0, 2);\r
+                                               prout(" units of energy.");\r
+                                               energy -= stopegy;\r
+                                               finalx = x-deltax+0.5;\r
+                                               sectx = finalx;\r
+                                               finaly = y-deltay+0.5;\r
+                                               secty = finaly;\r
+                                               if (energy <= 0) {\r
+                                                       finish(FNRG);\r
+                                                       return;\r
+                                               }\r
+                                               break;\r
+                               }\r
+                               goto label100;  /* sorry! */\r
+                       }\r
+               }\r
+               dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
+                                               (secty-iy)*(double)(secty-iy));\r
+               sectx = ix;\r
+               secty = iy;\r
+       }\r
+       finalx = sectx;\r
+       finaly = secty;\r
+label100:\r
+       /* No quadrant change -- compute new avg enemy distances */\r
+       quad[sectx][secty] = ship;\r
+       if (nenhere) {\r
+               for (l = 1; l <= nenhere; l++) {\r
+                       finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
+                                                 (iy-ky[l])*(double)(iy-ky[l]));\r
+                       kavgd[l] = 0.5 * (finald+kdist[l]);\r
+                       kdist[l] = finald;\r
+               }\r
+               sortkl();\r
+               if (d.galaxy[quadx][quady] != 1000 && iattak == 0)\r
+                       attack(0);\r
+               for (l = 1 ; l <= nenhere; l++) kavgd[l] = kdist[l];\r
+       }\r
+       newcnd();\r
+       iattak = 0;\r
+       return;\r
+}\r
+\r
+void dock(void) {\r
+       chew();\r
+       if (condit == IHDOCKED) {\r
+               prout("Already docked.");\r
+               return;\r
+       }\r
+       if (inorbit) {\r
+               prout("You must first leave standard orbit.");\r
+               return;\r
+       }\r
+       if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {\r
+               crmshp();\r
+               prout(" not adjacent to base.");\r
+               return;\r
+       }\r
+       condit = IHDOCKED;\r
+       prout("Docked.");\r
+       if (energy < inenrg) energy = inenrg;\r
+       shield = inshld;\r
+       torps = intorps;\r
+       lsupres = inlsr;\r
+       if (stdamtim != 1e30 &&\r
+               (future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {\r
+               /* get attack report from base */\r
+               prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");\r
+               attakreport();\r
+               iseenit = 1;\r
+       }\r
+}\r
+\r
+static void getcd(int isprobe, int akey) {\r
+       /* This program originally required input in terms of a (clock)\r
+          direction and distance. Somewhere in history, it was changed to\r
+          cartesian coordinates. So we need to convert. I think\r
+          "manual" input should still be done this way -- it's a real\r
+          pain if the computer isn't working! Manual mode is still confusing\r
+          because it involves giving x and y motions, yet the coordinates\r
+          are always displayed y - x, where +y is downward! */\r
+\r
+       \r
+       int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key;\r
+       double xi, xj, xk, xl;\r
+       double deltax, deltay;\r
+       int automatic = -1;\r
+\r
+       /* Get course direction and distance. If user types bad values, return\r
+          with DIREC = -1.0. */\r
+\r
+       direc = -1.0;\r
+       \r
+       if (landed == 1 && !isprobe) {\r
+               prout("Dummy! You can't leave standard orbit until you");\r
+               proutn("are back abourt the ");\r
+               crmshp();\r
+               prout(".");\r
+               chew();\r
+               return;\r
+       }\r
+       while (automatic == -1) {\r
+               if (damage[DCOMPTR]) {\r
+                       if (isprobe)\r
+                               prout("Computer damaged; manual navigation only");\r
+                       else\r
+                               prout("Computer damaged; manual movement only");\r
+                       chew();\r
+                       automatic = 0;\r
+                       key = IHEOL;\r
+                       break;\r
+               }\r
+               if (isprobe && akey != -1) {\r
+                       /* For probe launch, use pre-scaned value first time */\r
+                       key = akey;\r
+                       akey = -1;\r
+               }\r
+               else \r
+                       key = scan();\r
+\r
+               if (key == IHEOL) {\r
+                       proutn("Manual or automatic- ");\r
+                       iprompt = 1;\r
+                       chew();\r
+               }\r
+               else if (key == IHALPHA) {\r
+                       if (isit("manual")) {\r
+                               automatic =0;\r
+                               key = scan();\r
+                               break;\r
+                       }\r
+                       else if (isit("automatic")) {\r
+                               automatic = 1;\r
+                               key = scan();\r
+                               break;\r
+                       }\r
+                       else {\r
+                               huh();\r
+                               chew();\r
+                               return;\r
+                       }\r
+               }\r
+               else { /* numeric */\r
+                       if (isprobe)\r
+                               prout("(Manual navigation assumed.)");\r
+                       else\r
+                               prout("(Manual movement assumed.)");\r
+                       automatic = 0;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (automatic) {\r
+               while (key == IHEOL) {\r
+                       if (isprobe)\r
+                               proutn("Target quadrant or quadrant&sector- ");\r
+                       else\r
+                               proutn("Destination sector or quadrant&sector- ");\r
+                       chew();\r
+                       iprompt = 1;\r
+                       key = scan();\r
+               }\r
+\r
+               if (key != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               xi = aaitem;\r
+               key = scan();\r
+               if (key != IHREAL){\r
+                       huh();\r
+                       return;\r
+               }\r
+               xj = aaitem;\r
+               key = scan();\r
+               if (key == IHREAL) {\r
+                       /* both quadrant and sector specified */\r
+                       xk = aaitem;\r
+                       key = scan();\r
+                       if (key != IHREAL) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+                       xl = aaitem;\r
+\r
+                       irowq = xi + 0.5;\r
+                       icolq = xj + 0.5;\r
+                       irows = xk + 0.5;\r
+                       icols = xl + 0.5;\r
+               }\r
+               else {\r
+                       if (isprobe) {\r
+                               /* only quadrant specified -- go to center of dest quad */\r
+                               irowq = xi + 0.5;\r
+                               icolq = xj + 0.5;\r
+                               irows = icols = 5;\r
+                       }\r
+                       else {\r
+                               irows = xi + 0.5;\r
+                               icols = xj + 0.5;\r
+                       }\r
+                       itemp = 1;\r
+               }\r
+               if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 ||\r
+                       irows<1 || irows > 10 || icols<1 || icols > 10) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+               skip(1);\r
+               if (!isprobe) {\r
+                       if (itemp) {\r
+                               if (iprompt) {\r
+                                       proutn("Helmsman Sulu- \"Course locked in for");\r
+                                       cramlc(2, irows, icols);\r
+                                       prout(".\"");\r
+                               }\r
+                       }\r
+                       else prout("Ensign Chekov- \"Course laid in, Captain.\"");\r
+               }\r
+               deltax = icolq - quady + 0.1*(icols-secty);\r
+               deltay = quadx - irowq + 0.1*(sectx-irows);\r
+       }\r
+       else { /* manual */\r
+               while (key == IHEOL) {\r
+                       proutn("X and Y displacements- ");\r
+                       chew();\r
+                       iprompt = 1;\r
+                       key = scan();\r
+               }\r
+               itemp = 2;\r
+               if (key != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               deltax = aaitem;\r
+               key = scan();\r
+               if (key != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               deltay = aaitem;\r
+       }\r
+       /* Check for zero movement */\r
+       if (deltax == 0 && deltay == 0) {\r
+               chew();\r
+               return;\r
+       }\r
+       if (itemp == 2 && !isprobe) {\r
+               skip(1);\r
+               prout("Helmsman Sulu- \"Aye, Sir.\"");\r
+       }\r
+       dist = sqrt(deltax*deltax + deltay*deltay);\r
+       direc = atan2(deltax, deltay)*1.90985932;\r
+       if (direc < 0.0) direc += 12.0;\r
+       chew();\r
+       return;\r
+\r
+}\r
+               \r
+\r
+\r
+void impuls(void) {\r
+       double power;\r
+\r
+       ididit = 0;\r
+       if (damage[DIMPULS]) {\r
+               chew();\r
+               skip(1);\r
+               prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
+               return;\r
+       }\r
+\r
+       if (energy > 30.0) {\r
+               getcd(FALSE, 0);\r
+               if (direc == -1.0) return;\r
+               power = 20.0 + 100.0*dist;\r
+       }\r
+       else\r
+               power = 30.0;\r
+\r
+       if (power >= energy) {\r
+               /* Insufficient power for trip */\r
+               skip(1);\r
+               prout("First Officer Spock- \"Captain, the impulse engines");\r
+               prout("require 20.0 units to engage, plus 100.0 units per");\r
+               if (energy > 30) {\r
+                       proutn("quadrant.  We can go, therefore, a maximum of ");\r
+                       cramf(0.01 * (energy-20.0)-0.05, 0, 1);\r
+                       prout(" quadrants.\"");\r
+               }\r
+               else {\r
+                       prout("quadrant.  They are, therefore, useless.\"");\r
+               }\r
+               chew();\r
+               return;\r
+       }\r
+       /* Make sure enough time is left for the trip */\r
+       Time = dist/0.095;\r
+       if (Time >= d.remtime) {\r
+               prout("First Officer Spock- \"Captain, our speed under impulse");\r
+               prout("power is only 0.95 sectors per stardate. Are you sure");\r
+               prout("we dare spend the time?\"");\r
+               if (ja() == 0) return;\r
+       }\r
+       /* Activate impulse engines and pay the cost */\r
+       move();\r
+       ididit = 1;\r
+       if (alldone) return;\r
+       power = 20.0 + 100.0*dist;\r
+       energy -= power;\r
+       Time = dist/0.095;\r
+       if (energy <= 0) finish(FNRG);\r
+       return;\r
+}\r
+\r
+\r
+void warp(int i) {\r
+       int blooey=0, twarp=0, iwarp;\r
+       double power;\r
+\r
+       if (i!=2) { /* Not WARPX entry */\r
+               ididit = 0;\r
+               if (damage[DWARPEN] > 10.0) {\r
+                       chew();\r
+                       skip(1);\r
+                       prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
+                       return;\r
+               }\r
+               if (damage[DWARPEN] > 0.0 && warpfac > 4.0) {\r
+                       chew();\r
+                       skip(1);\r
+                       prout("Engineer Scott- \"Sorry, Captain. Until this damage");\r
+                       prout("  is repaired, I can only give you warp 4.\"");\r
+                       return;\r
+               }\r
+                       \r
+               /* Read in course and distance */\r
+               getcd(FALSE, 0);\r
+               if (direc == -1.0) return;\r
+\r
+               /* Make sure starship has enough energy for the trip */\r
+               power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);\r
+\r
+\r
+               if (power >= energy) {\r
+                       /* Insufficient power for trip */\r
+                       ididit = 0;\r
+                       skip(1);\r
+                       prout("Engineering to bridge--");\r
+                       if (shldup==0 || 0.5*power > energy) {\r
+                               iwarp = pow((energy/(dist+0.05)), 0.333333333);\r
+                               if (iwarp <= 0) {\r
+                                       prout("We can't do it, Captain. We haven't the energy.");\r
+                               }\r
+                               else {\r
+                                       proutn("We haven't the energy, but we could do it at warp ");\r
+                                       crami(iwarp, 1);\r
+                                       if (shldup)\r
+                                               prout(",\nif you'll lower the shields.");\r
+                                       else\r
+                                               prout(".");\r
+                               }\r
+                       }\r
+                       else\r
+                               prout("We haven't the energy to go that far with the shields up.");\r
+                       return;\r
+               }\r
+                                               \r
+               /* Make sure enough time is left for the trip */\r
+               Time = 10.0*dist/wfacsq;\r
+               if (Time >= 0.8*d.remtime) {\r
+                       skip(1);\r
+                       prout("First Officer Spock- \"Captain, I compute that such");\r
+                       proutn("  a trip would require approximately ");\r
+                       cramf(100.0*Time/d.remtime, 0, 2);\r
+                       prout(" percent of our");\r
+                       prout("  remaining time.  Are you sure this is wise?\"");\r
+                       if (ja() == 0) { ididit = 0; return;}\r
+               }\r
+       }\r
+       /* Entry WARPX */\r
+       if (warpfac > 6.0) {\r
+               /* Decide if engine damage will occur */\r
+               double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;\r
+               if (prob > Rand()) {\r
+                       blooey = 1;\r
+                       dist = Rand()*dist;\r
+               }\r
+               /* Decide if time warp will occur */\r
+               if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;\r
+#ifdef DEBUG\r
+               if (idebug &&warpfac==10 && twarp==0) {\r
+                       blooey=0;\r
+                       proutn("Force time warp? ");\r
+                       if (ja()==1) twarp=1;\r
+               }\r
+#endif\r
+               if (blooey || twarp) {\r
+                       /* If time warp or engine damage, check path */\r
+                       /* If it is obstructed, don't do warp or damage */\r
+                       double angle = ((15.0-direc)*0.5235998);\r
+                       double deltax = -sin(angle);\r
+                       double deltay = cos(angle);\r
+                       double bigger, x, y;\r
+                       int n, l, ix, iy;\r
+                       if (fabs(deltax) > fabs(deltay))\r
+                               bigger = fabs(deltax);\r
+                       else\r
+                               bigger = fabs(deltay);\r
+                       \r
+                       deltax /= bigger;\r
+                       deltay /= bigger;\r
+                       n = 10.0 * dist * bigger +0.5;\r
+                       x = sectx;\r
+                       y = secty;\r
+                       for (l = 1; l <= n; l++) {\r
+                               x += deltax;\r
+                               ix = x + 0.5;\r
+                               if (ix < 1 || ix > 10) break;\r
+                               y += deltay;\r
+                               iy = y +0.5;\r
+                               if (iy < 1 || iy > 10) break;\r
+                               if (quad[ix][iy] != IHDOT) {\r
+                                       blooey = 0;\r
+                                       twarp = 0;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+                               \r
+\r
+       /* Activate Warp Engines and pay the cost */\r
+       move();\r
+       if (alldone) return;\r
+       energy -= dist*warpfac*warpfac*warpfac*(shldup+1);\r
+       if (energy <= 0) finish(FNRG);\r
+       Time = 10.0*dist/wfacsq;\r
+       if (twarp) timwrp();\r
+       if (blooey) {\r
+               damage[DWARPEN] = damfac*(3.0*Rand()+1.0);\r
+               skip(1);\r
+               prout("Engineering to bridge--");\r
+               prout("  Scott here.  The warp engines are damaged.");\r
+               prout("  We'll have to reduce speed to warp 4.");\r
+       }\r
+       ididit = 1;\r
+       return;\r
+}\r
+\r
+\r
+\r
+void setwrp(void) {\r
+       int key;\r
+       double oldfac;\r
+       \r
+       while ((key=scan()) == IHEOL) {\r
+               chew();\r
+               proutn("Warp factor-");\r
+       }\r
+       chew();\r
+       if (key != IHREAL) {\r
+               huh();\r
+               return;\r
+       }\r
+       if (damage[DWARPEN] > 10.0) {\r
+               prout("Warp engines inoperative.");\r
+               return;\r
+       }\r
+       if (damage[DWARPEN] > 0.0 && aaitem > 4.0) {\r
+               prout("Engineer Scott- \"I'm doing my best, Captain,\n"\r
+                         "  but right now we can only go warp 4.\"");\r
+               return;\r
+       }\r
+       if (aaitem > 10.0) {\r
+               prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");\r
+               return;\r
+       }\r
+       if (aaitem < 1.0) {\r
+               prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");\r
+               return;\r
+       }\r
+       oldfac = warpfac;\r
+       warpfac = aaitem;\r
+       wfacsq=warpfac*warpfac;\r
+       if (warpfac <= oldfac || warpfac <= 6.0) {\r
+               proutn("Helmsman Sulu- \"Warp factor ");\r
+               cramf(warpfac, 0, 1);\r
+               prout(", Captain.\"");\r
+               return;\r
+       }\r
+       if (warpfac < 8.00) {\r
+               prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");\r
+               return;\r
+       }\r
+       if (warpfac == 10.0) {\r
+               prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");\r
+               return;\r
+       }\r
+       prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");\r
+       return;\r
+}\r
+\r
+void atover(int igrab) {\r
+       double power, distreq;\r
+\r
+       chew();\r
+       /* is captain on planet? */\r
+       if (landed==1) {\r
+               if (damage[DTRANSP]) {\r
+                       finish(FPNOVA);\r
+                       return;\r
+               }\r
+               prout("Scotty rushes to the transporter controls.");\r
+               if (shldup) {\r
+                       prout("But with the shields up it's hopeless.");\r
+                       finish(FPNOVA);\r
+               }\r
+               prouts("His desperate attempt to rescue you . . .");\r
+               if (Rand() <= 0.5) {\r
+                       prout("fails.");\r
+                       finish(FPNOVA);\r
+                       return;\r
+               }\r
+               prout("SUCCEEDS!");\r
+               if (imine) {\r
+                       imine = 0;\r
+                       proutn("The crystals mined were ");\r
+                       if (Rand() <= 0.25) {\r
+                               prout("lost.");\r
+                       }\r
+                       else {\r
+                               prout("saved.");\r
+                               icrystl = 1;\r
+                       }\r
+               }\r
+       }\r
+       if (igrab) return;\r
+\r
+       /* Check to see if captain in shuttle craft */\r
+       if (icraft) finish(FSTRACTOR);\r
+       if (alldone) return;\r
+\r
+       /* Inform captain of attempt to reach safety */\r
+       skip(1);\r
+       do {\r
+               if (justin) {\r
+                       prouts("***RED ALERT!  READ ALERT!");\r
+                       skip(1);\r
+                       proutn("The ");\r
+                       crmshp();\r
+                       prout(" has stopped in a quadrant containing");\r
+                       prouts("   a supernova.");\r
+                       skip(2);\r
+               }\r
+               proutn("***Emergency automatic override attempts to hurl ");\r
+               crmshp();\r
+               skip(1);\r
+               prout("safely out of quadrant.");\r
+               starch[quadx][quady] = damage[DRADIO] > 0.0 ? d.galaxy[quadx][quady]+1000:1;\r
+\r
+               /* Try to use warp engines */\r
+               if (damage[DWARPEN]) {\r
+                       skip(1);\r
+                       prout("Warp engines damaged.");\r
+                       finish(FSNOVAED);\r
+                       return;\r
+               }\r
+               warpfac = 6.0+2.0*Rand();\r
+               wfacsq = warpfac * warpfac;\r
+               proutn("Warp factor set to ");\r
+               cramf(warpfac, 1, 1);\r
+               skip(1);\r
+               power = 0.75*energy;\r
+               dist = power/(warpfac*warpfac*warpfac*(shldup+1));\r
+               distreq = 1.4142+Rand();\r
+               if (distreq < dist) dist = distreq;\r
+               Time = 10.0*dist/wfacsq;\r
+               direc = 12.0*Rand();    /* How dumb! */\r
+               justin = 0;\r
+               inorbit = 0;\r
+               warp(2);\r
+               if (justin == 0) {\r
+                       /* This is bad news, we didn't leave quadrant. */\r
+                       if (alldone) return;\r
+                       skip(1);\r
+                       prout("Insufficient energy to leave quadrant.");\r
+                       finish(FSNOVAED);\r
+                       return;\r
+               }\r
+               /* Repeat if another snova */\r
+       } while (d.galaxy[quadx][quady] == 1000);\r
+       if (d.remkl==0) finish(FWON); /* Snova killed remaining enemy. */\r
+}\r
+\r
+void timwrp() {\r
+       int l, ll, gotit;\r
+       prout("***TIME WARP ENTERED.");\r
+       if (d.snap && Rand() < 0.5) {\r
+               /* Go back in time */\r
+               proutn("You are traveling backwards in time ");\r
+               cramf(d.date-snapsht.date, 0, 2);\r
+               prout(" stardates.");\r
+               d = snapsht;\r
+               d.snap = 0;\r
+               if (d.remcom) {\r
+                       future[FTBEAM] = d.date + expran(intime/d.remcom);\r
+                       future[FBATTAK] = d.date + expran(0.3*intime);\r
+               }\r
+               future[FSNOVA] = d.date + expran(0.5*intime);\r
+               future[FSNAP] = d.date +expran(0.25*d.remtime); /* next snapshot will\r
+                                                                                                          be sooner */\r
+               if (d.nscrem) future[FSCMOVE] = 0.2777;\r
+               isatb = 0;\r
+               future[FCDBAS] = future[FSCDBAS] = 1e30;\r
+               batx = baty = 0;\r
+\r
+               /* Make sure Galileo is consistant -- Snapshot may have been taken\r
+                  when on planet, which would give us two Galileos! */\r
+               gotit = 0;\r
+               for (l = 1; l <= inplan; l++) {\r
+                       if (d.plnets[l].known == 2) {\r
+                               gotit = 1;\r
+                               if (iscraft==1 && ship==IHE) {\r
+                                       prout("Checkov-  \"Security reports the Galileo has disappeared, Sir!");\r
+                                       iscraft = 0;\r
+                               }\r
+                       }\r
+               }\r
+               /* Likewise, if in the original time the Galileo was abandoned, but\r
+                  was on ship earlier, it would have vanished -- lets restore it */\r
+               if (iscraft==0 && gotit==0 && damage[DSHUTTL] >= 0.0) {\r
+                       prout("Checkov-  \"Security reports the Galileo has reappeared in the dock!\"");\r
+                       iscraft = 1;\r
+               }\r
+\r
+               /* Revert star chart to earlier era, if it was known then*/\r
+               if (damage[DRADIO]==0.0 || stdamtim > d.date) {\r
+                       for (l = 1; l <= 8; l++)\r
+                               for (ll = 1; ll <= 8; ll++)\r
+                                       if (starch[l][ll] > 1)\r
+                                               starch[l][ll]=damage[DRADIO]>0.0 ? d.galaxy[l][ll]+1000 :1;\r
+                       prout("Spock has reconstructed a correct star chart from memory");\r
+                       if (damage[DRADIO] > 0.0) stdamtim = d.date;\r
+               }\r
+       }\r
+       else {\r
+               /* Go forward in time */\r
+               Time = -0.5*intime*log(Rand());\r
+               proutn("You are traveling forward in time ");\r
+               cramf(Time, 1, 2);\r
+               prout(" stardates.");\r
+               /* cheat to make sure no tractor beams occur during time warp */\r
+               future[FTBEAM] += Time;\r
+               damage[DRADIO] += Time;\r
+       }\r
+       newqad(0);\r
+}\r
+\r
+void probe(void) {\r
+       double angle, bigger;\r
+       int key;\r
+       /* New code to launch a deep space probe */\r
+       if (nprobes == 0) {\r
+               chew();\r
+               skip(1);\r
+               if (ship == IHE) \r
+                       prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");\r
+               else\r
+                       prout("Ye Faerie Queene has no deep space probes.");\r
+               return;\r
+       }\r
+       if (damage[DDSP] != 0.0) {\r
+               chew();\r
+               skip(1);\r
+               prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");\r
+               return;\r
+       }\r
+       if (future[FDSPROB] != 1e30) {\r
+               chew();\r
+               skip(1);\r
+               if (damage[DRADIO] != 0 && condit != IHDOCKED) {\r
+                       prout("Spock-  \"Records show the previous probe has not yet");\r
+                       prout("   reached it's destination.\"");\r
+               }\r
+               else\r
+                       prout("Uhura- \"The previous probe is still reporting data, Sir.\"");\r
+               return;\r
+       }\r
+       key = scan();\r
+\r
+       if (key == IHEOL) {\r
+               /* slow mode, so let Kirk know how many probes there are left */\r
+               crami(nprobes,1);\r
+               prout(nprobes==1 ? " probe left." : " probes left.");\r
+               proutn("Are you sure you want to fire a probe? ");\r
+               if (ja()==0) return;\r
+       }\r
+\r
+       isarmed = FALSE;\r
+       if (key == IHALPHA && strcmp(citem,"armed") == 0) {\r
+               isarmed = TRUE;\r
+               key = scan();\r
+       }\r
+       else if (key == IHEOL) {\r
+               proutn("Arm NOVAMAX warhead?");\r
+               isarmed = ja();\r
+       }\r
+       getcd(TRUE, key);\r
+       if (direc == -1.0) return;\r
+       nprobes--;\r
+               angle = ((15.0 - direc) * 0.5235988);\r
+       probeinx = -sin(angle);\r
+       probeiny = cos(angle);\r
+       if (fabs(probeinx) > fabs(probeiny))\r
+               bigger = fabs(probeinx);\r
+       else\r
+               bigger = fabs(probeiny);\r
+               \r
+       probeiny /= bigger;\r
+       probeinx /= bigger;\r
+       proben = 10.0*dist*bigger +0.5;\r
+       probex = quadx*10 + sectx - 1;  // We will use better packing than original\r
+       probey = quady*10 + secty - 1;\r
+       probecx = quadx;\r
+       probecy = quady;\r
+       future[FDSPROB] = d.date + 0.01; // Time to move one sector\r
+       prout("Ensign Chekov-  \"The deep space probe is launched, Captain.\"");\r
+       return;\r
+}\r
+\r
+void help(void) {\r
+       /* There's more than one way to move in this game! */\r
+       double ddist, xdist, probf;\r
+       int line, l, ix, iy;\r
+\r
+       chew();\r
+       /* Test for conditions which prevent calling for help */\r
+       if (condit == IHDOCKED) {\r
+               prout("Lt. Uhura-  \"But Captain, we're already docked.\"");\r
+               return;\r
+       }\r
+       if (damage[DRADIO] != 0) {\r
+               prout("Subspace radio damaged.");\r
+               return;\r
+       }\r
+       if (d.rembase==0) {\r
+               prout("Lt. Uhura-  \"Captain, I'm not getting any response from Starbase.\"");\r
+               return;\r
+       }\r
+       if (landed == 1) {\r
+               proutn("You must be aboard the ");\r
+               crmshp();\r
+               prout(".");\r
+               return;\r
+       }\r
+       /* OK -- call for help from nearest starbase */\r
+       nhelp++;\r
+       if (basex!=0) {\r
+               /* There's one in this quadrant */\r
+               ddist = sqrt(square(basex-sectx)+square(basey-secty));\r
+       }\r
+       else {\r
+               ddist = 1e30;\r
+               for (l = 1; l <= d.rembase; l++) {\r
+                       xdist=10.0*sqrt(square(d.baseqx[l]-quadx)+square(d.baseqy[l]-quady));\r
+                       if (xdist < ddist) {\r
+                               ddist = xdist;\r
+                               line = l;\r
+                       }\r
+               }\r
+               /* Since starbase not in quadrant, set up new quadrant */\r
+               quadx = d.baseqx[line];\r
+               quady = d.baseqy[line];\r
+               newqad(1);\r
+       }\r
+       /* dematerialize starship */\r
+       quad[sectx][secty]=IHDOT;\r
+       proutn("Starbase in");\r
+       cramlc(1, quadx, quady);\r
+       proutn(" responds--");\r
+       crmshp();\r
+       prout(" dematerializes.");\r
+       /* Give starbase three chances to rematerialize starship */\r
+       probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);\r
+       for (l = 1; l <= 3; l++) {\r
+               switch (l) {\r
+                       case 1: proutn("1st"); break;\r
+                       case 2: proutn("2nd"); break;\r
+                       case 3: proutn("3rd"); break;\r
+               }\r
+               proutn(" attempt to re-materialize ");\r
+               crmshp();\r
+               prouts(" . . . . . ");\r
+               if (Rand() > probf) break;\r
+               prout("fails.");\r
+       }\r
+       if (l > 3) {\r
+               finish(FMATERIALIZE);\r
+               return;\r
+       }\r
+       /* Rematerialization attempt should succeed if can get adj to base */\r
+       for (l = 1; l <= 5; l++) {\r
+               ix = basex+3.0*Rand()-1;\r
+               iy = basey+3.0*Rand()-1;\r
+               if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && quad[ix][iy]==IHDOT) {\r
+                       /* found one -- finish up */\r
+                       prout("succeeds.");\r
+                       sectx=ix;\r
+                       secty=iy;\r
+                       quad[ix][iy]=ship;\r
+                       dock();\r
+                       skip(1);\r
+                       prout("Lt. Uhura-  \"Captain, we made it!\"");\r
+                       return;\r
+               }\r
+       }\r
+       finish(FMATERIALIZE);\r
+       return;\r
+}\r
diff --git a/os2.c b/os2.c
new file mode 100644 (file)
index 0000000..c6a7835
--- /dev/null
+++ b/os2.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>\r
+#include <time.h>\r
+#include <sys/ioctl.h>\r
+#include <sys/termio.h>\r
+\r
+void randomize(void) {\r
+       srand((int)time(NULL));\r
+}\r
+\r
+\r
+int max(int a, int b) {\r
+       if (a > b) return a;\r
+       return b;\r
+}\r
+\r
+int min(int a, int b) {\r
+       if (a < b) return a;\r
+       return b;\r
+}\r
+\r
+int getch(void) {\r
+       char chbuf[1];\r
+       struct termio oldstate, newstate;\r
+    ioctl(0,TCGETA,&oldstate);\r
+       newstate = oldstate;\r
+       newstate.c_iflag = 0;\r
+       newstate.c_lflag = 0;\r
+       ioctl(0,TCSETA,&newstate);\r
+       read(0, &chbuf, 1);\r
+    ioctl(0,TCSETA,&oldstate);\r
+}
\ No newline at end of file
diff --git a/planets.c b/planets.c
new file mode 100644 (file)
index 0000000..39e0846
--- /dev/null
+++ b/planets.c
@@ -0,0 +1,504 @@
+#include "sst.h"\r
+\r
+static char classes[4][2]={"","M","N","O"};\r
+static int height;\r
+\r
+static int consumeTime(void) {\r
+/* I think most of this avoidance was caused by overlay scheme.\r
+   Let's see what happens if all events can occur here */\r
+\r
+//     double asave;\r
+       ididit = 1;\r
+#if 0\r
+       /* Don't wory about this */\r
+       if (future[FTBEAM] <= d.date+Time && d.remcom != 0 && condit != IHDOCKED) {\r
+               /* We are about to be tractor beamed -- operation fails */\r
+               return 1;\r
+       }\r
+#endif\r
+//     asave = future[FSNOVA];\r
+//     future[FSNOVA] = 1e30; /* defer supernovas */\r
+       events();       /* Used to avoid if future[FSCMOVE] within time */\r
+//     future[FSNOVA] = asave;\r
+       /*fails if game over, quadrant super-novas or we've moved to new quadrant*/\r
+       if (alldone || d.galaxy[quadx][quady] == 1000 || justin != 0) return 1;\r
+       return 0;\r
+}\r
+\r
+void preport(void) {\r
+       int iknow = 0, i;\r
+       skip(1);\r
+       chew();\r
+       prout("Spock-  \"Planet report follows, Captain.\"");\r
+       skip(1);\r
+       for (i = 1; i <= inplan; i++) {\r
+               if (d.plnets[i].known\r
+#ifdef DEBUG\r
+                       || ( idebug && d.plnets[i].x !=0)\r
+#endif\r
+                       ) {\r
+                       iknow = 1;\r
+#ifdef DEBUG\r
+                       if (idebug && d.plnets[i].known==0) proutn("(Unknown) ");\r
+#endif\r
+                       cramlc(1, d.plnets[i].x, d.plnets[i].y);\r
+                       proutn("   class ");\r
+                       proutn(classes[d.plnets[i].pclass]);\r
+                       proutn("   ");\r
+                       if (d.plnets[i].crystals == 0) proutn("no ");\r
+                       prout("dilithium crystals present.");\r
+                       if (d.plnets[i].known==2) \r
+                               prout("    Shuttle Craft Galileo on surface.");\r
+               }\r
+       }\r
+       if (iknow==0) prout("No information available.");\r
+}\r
+\r
+void orbit(void) {\r
+       double asave;\r
+\r
+       skip(1);\r
+       chew();\r
+       ididit=0;\r
+       if (inorbit!=0) {\r
+               prout("Already in standard orbit.");\r
+               return;\r
+       }\r
+       if (damage[DWARPEN] != 0 && damage[DIMPULS] != 0) {\r
+               prout("Both warp and impulse engines damaged.");\r
+               return;\r
+       }\r
+       if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) {\r
+               crmshp();\r
+               prout(" not adjacient to planet.\n");\r
+               return;\r
+       }\r
+       Time = 0.02+0.03*Rand();\r
+       prout("Helmsman Sulu-  \"Entering standard orbit, Sir.\"");\r
+       newcnd();\r
+       if (consumeTime()) return;\r
+       proutn("Sulu-  \"Entered orbit at altitude ");\r
+       cramf(height = (1400.+7200.*Rand()), 0, 2);\r
+       prout(" kilometers.\"");\r
+       inorbit = 1;\r
+       return;\r
+}\r
+\r
+void sensor(void) {\r
+       skip(1);\r
+       chew();\r
+       if (damage[DSRSENS] != 0.0) {\r
+               prout("Short range sensors damaged.");\r
+               return;\r
+       }\r
+       if (plnetx == 0) {\r
+               prout("No planet in this quadrant.");\r
+               return;\r
+       }\r
+       proutn("Spock-  \"Sensor scan for");\r
+       cramlc(1, quadx, quady);\r
+       prout("-");\r
+       skip(1);\r
+       proutn("         Planet at");\r
+       cramlc(2, plnetx, plnety);\r
+       proutn(" is of class ");\r
+       proutn(classes[d.plnets[iplnet].pclass]);\r
+       prout(".");\r
+       if (d.plnets[iplnet].known==2) \r
+               prout("         Sensors show Galileo still on surface.");\r
+       proutn("         Readings indicate");\r
+       if (d.plnets[iplnet].crystals == 0) proutn(" no");\r
+       prout(" dilithium crystals present.\"");\r
+       if (d.plnets[iplnet].known == 0) d.plnets[iplnet].known = 1;\r
+       return;\r
+}\r
+\r
+void beam(void) {\r
+       chew();\r
+       skip(1);\r
+       if (damage[DTRANSP] != 0) {\r
+               prout("Transporter damaged.");\r
+               if (damage[DSHUTTL]==0 && (d.plnets[iplnet].known==2 || iscraft == 1)) {\r
+                       skip(1);\r
+                       prout("Spock-  \"May I suggest the shuttle craft, Sir?\" ");\r
+                       if (ja() != 0) shuttle();\r
+               }\r
+               return;\r
+       }\r
+       if (inorbit==0) {\r
+               crmshp();\r
+               prout(" not in standard orbit.");\r
+               return;\r
+       }\r
+       if (shldup!=0) {\r
+               prout("Impossible to transport through shields.");\r
+               return;\r
+       }\r
+       if (d.plnets[iplnet].known==0) {\r
+               prout("Spock-  \"Captain, we have no information on this planet");\r
+               prout("  and Starfleet Regulations clearly state that in this situation");\r
+               prout("  you may not go down.\"");\r
+               return;\r
+       }\r
+       if (landed==1) {\r
+               /* Coming from planet */\r
+               if (d.plnets[iplnet].known==2) {\r
+                       proutn("Spock-  \"Wouldn't you rather take the Galileo?\" ");\r
+                       if (ja() != 0) {\r
+                               chew();\r
+                               return;\r
+                       }\r
+                       prout("Your crew hides the Galileo to prevent capture by aliens.");\r
+               }\r
+               prout("Landing party assembled, ready to beam up.");\r
+               skip(1);\r
+               prout("Kirk whips out communicator...");\r
+               prouts("BEEP  BEEP  BEEP");\r
+               skip(2);\r
+               prout("\"Kirk to enterprise-  Lock on coordinates...energize.\"");\r
+       }\r
+       else {\r
+               /* Going to planet */\r
+               if (d.plnets[iplnet].crystals==0) {\r
+                       prout("Spock-  \"Captain, I fail to see the logic in");\r
+                       prout("  exploring a planet with no dilithium crystals.");\r
+                       proutn("  Are you sure this is wise?\" ");\r
+                       if (ja()==0) {\r
+                               chew();\r
+                               return;\r
+                       }\r
+               }\r
+               prout("Scotty-  \"Transporter room ready, Sir.\"");\r
+               skip(1);\r
+               prout("Kirk, and landing party prepare to beam down to planet surface.");\r
+               skip(1);\r
+               prout("Kirk-  \"Energize.\"");\r
+       }\r
+       skip(1);\r
+       prouts("WWHOOOIIIIIRRRRREEEE.E.E.  .  .  .  .   .    .");\r
+       skip(2);\r
+       if (Rand() > 0.98) {\r
+               prouts("BOOOIIIOOOIIOOOOIIIOIING . . .");\r
+               skip(2);\r
+               prout("Scotty-  \"Oh my God!  I've lost them.\"");\r
+               finish(FLOST);\r
+               return;\r
+       }\r
+       prouts(".    .   .  .  .  .  .E.E.EEEERRRRRIIIIIOOOHWW");\r
+       skip(2);\r
+       prout("Transport complete.");\r
+       landed = -landed;\r
+       if (landed==1 && d.plnets[iplnet].known==2) {\r
+               prout("The shuttle craft Galileo is here!");\r
+       }\r
+       if (landed!=1 && imine==1) {\r
+               icrystl = 1;\r
+               cryprob = 0.05;\r
+       }\r
+       imine = 0;\r
+       return;\r
+}\r
+\r
+void mine(void) {\r
+\r
+       ididit = 0;\r
+       skip(1);\r
+       chew();\r
+       if (landed!= 1) {\r
+               prout("Mining party not on planet.");\r
+               return;\r
+       }\r
+       if (d.plnets[iplnet].crystals == 0) {\r
+               prout("No dilithium crystals on this planet.");\r
+               return;\r
+       }\r
+       if (imine == 1) {\r
+               prout("You've already mined enough crystals for this trip.");\r
+               return;\r
+       }\r
+       if (icrystl == 1 && cryprob == 0.05) {\r
+               proutn("With all those fresh crystals aboard the ");\r
+               crmshp();\r
+               skip(1);\r
+               prout("there's no reason to mine more at this time.");\r
+               return;\r
+       }\r
+       Time = (0.1+0.2*Rand())*d.plnets[iplnet].pclass;\r
+       if (consumeTime()) return;\r
+       prout("Mining operation complete.");\r
+       imine = 1;\r
+       return;\r
+}\r
+\r
+void usecrystals(void) {\r
+\r
+       skip(1);\r
+       chew();\r
+       if (icrystl!=1) {\r
+               prout("No dilithium crystals available.");\r
+               return;\r
+       }\r
+       if (energy >= 1000) {\r
+               prout("Spock-  \"Captain, Starfleet Regulations prohibit such an operation");\r
+               prout("  except when condition Yellow exists.");\r
+               return;\r
+       }\r
+       prout("Spock- \"Captain, I must warn you that loading");\r
+       prout("  raw dilithium crystals into the ship's power");\r
+       prout("  system may risk a severe explosion.");\r
+       proutn("  Are you sure this is wise?\" ");\r
+       if (ja()==0) {\r
+               chew();\r
+               return;\r
+       }\r
+       skip(1);\r
+       prout("Engineering Officer Scott-  \"(GULP) Aye Sir.");\r
+       prout("  Mr. Spock and I will try it.\"");\r
+       skip(1);\r
+       prout("Spock-  \"Crystals in place, Sir.");\r
+       prout("  Ready to activate circuit.\"");\r
+       skip(1);\r
+       prouts("Scotty-  \"Keep your fingers crossed, Sir!\"");\r
+       skip(1);\r
+       if (Rand() <= cryprob) {\r
+               prouts("  \"Activating now! - - No good!  It's***");\r
+               skip(2);\r
+               prouts("***RED ALERT!  RED A*L********************************");\r
+               skip(1);\r
+               stars();\r
+               prouts("******************   KA-BOOM!!!!   *******************");\r
+               skip(1);\r
+               kaboom();\r
+               return;\r
+       }\r
+       energy += 5000.0*(1.0 + 0.9*Rand());\r
+       prouts("  \"Activating now! - - ");\r
+       prout("The instruments");\r
+       prout("   are going crazy, but I think it's");\r
+       prout("   going to work!!  Congratulations, Sir!\"");\r
+       cryprob *= 2.0;\r
+       return;\r
+}\r
+\r
+void shuttle(void) {\r
+\r
+       chew();\r
+       skip(1);\r
+       ididit = 0;\r
+       if(damage[DSHUTTL] != 0.0) {\r
+               if (damage[DSHUTTL] == -1.0) {\r
+                       if (inorbit && d.plnets[iplnet].known == 2)\r
+                               prout("Ye Faerie Queene has no shuttle craft bay to dock it at.");\r
+                       else\r
+                               prout("Ye Faerie Queene had no shuttle craft.");\r
+               }\r
+               else if (damage[DSHUTTL] > 0)\r
+                       prout("The Galileo is damaged.");\r
+               else prout("Shuttle craft is now serving Big Mac's.");\r
+               return;\r
+       }\r
+       if (inorbit==0) {\r
+               crmshp();\r
+               prout(" not in standard orbit.");\r
+               return;\r
+       }\r
+       if ((d.plnets[iplnet].known != 2) && iscraft != 1) {\r
+               prout("Shuttle craft not currently available.");\r
+               return;\r
+       }\r
+       if (landed==-1 && d.plnets[iplnet].known==2) {\r
+               prout("You will have to beam down to retrieve the shuttle craft.");\r
+               return;\r
+       }\r
+       if (shldup!=0 || condit == IHDOCKED) {\r
+               prout("Shuttle craft cannot pass through shields.");\r
+               return;\r
+       }\r
+       if (d.plnets[iplnet].known==0) {\r
+               prout("Spock-  \"Captain, we have no information on this planet");\r
+               prout("  and Starfleet Regulations clearly state that in this situation");\r
+               prout("  you may not fly down.\"");\r
+               return;\r
+       }\r
+       Time = 3.0e-5*height;\r
+       if (Time >= 0.8*d.remtime) {\r
+               prout("First Officer Spock-  \"Captain, I compute that such");\r
+               prout("  a maneuver would require aproximately ");\r
+               cramf(100*Time/d.remtime,0,4);\r
+               prout("% of our");\r
+               prout("remaining time.");\r
+               prout("Are you sure this is wise?\" ");\r
+               if (ja()==0) {\r
+                       Time = 0.0;\r
+                       return;\r
+               }\r
+       }\r
+       if (landed == 1) {\r
+               /* Kirk on planet */\r
+               if (iscraft==1) {\r
+                       /* Galileo on ship! */\r
+                       if (damage[DTRANSP]==0) {\r
+                               proutn("Spock-  \"Would you rather use the transporter?\" ");\r
+                               if (ja() != 0) {\r
+                                       beam();\r
+                                       return;\r
+                               }\r
+                               proutn("Shuttle crew");\r
+                       }\r
+                       else\r
+                               proutn("Rescue party");\r
+                       prout(" boards Galileo and swoops toward planet surface.");\r
+                       iscraft = 0;\r
+                       skip(1);\r
+                       if (consumeTime()) return;\r
+                       d.plnets[iplnet].known=2;\r
+                       prout("Trip complete.");\r
+                       return;\r
+               }\r
+               else {\r
+                       /* Ready to go back to ship */\r
+                       prout("You and your mining party board the");\r
+                       prout("shuttle craft for the trip back to the Enterprise.");\r
+                       skip(1);\r
+                       prout("The short hop begins . . .");\r
+                       d.plnets[iplnet].known=1;\r
+                       icraft = 1;\r
+                       skip(1);\r
+                       landed = -1;\r
+                       if (consumeTime()) return;\r
+                       iscraft = 1;\r
+                       icraft = 0;\r
+                       if (imine!=0) {\r
+                               icrystl = 1;\r
+                               cryprob = 0.05;\r
+                       }\r
+                       imine = 0;\r
+                       prout("Trip complete.");\r
+                       return;\r
+               }\r
+       }\r
+       else {\r
+               /* Kirk on ship */\r
+               /* and so is Galileo */\r
+               prout("Mining party assembles in the hangar deck,");\r
+               prout("ready to board the shuttle craft \"Galileo\".");\r
+               skip(1);\r
+               prouts("The hangar doors open; the trip begins.");\r
+               skip(1);\r
+               icraft = 1;\r
+               iscraft = 0;\r
+               if (consumeTime()) return;\r
+               d.plnets[iplnet].known = 2;\r
+               landed = 1;\r
+               icraft = 0;\r
+               prout("Trip complete");\r
+               return;\r
+       }\r
+}\r
+               \r
+\r
+void deathray(void) {\r
+       double r = Rand();\r
+       \r
+       ididit = 0;\r
+       skip(1);\r
+       chew();\r
+       if (ship != IHE) {\r
+               prout("Ye Faerie Queene has no death ray.");\r
+               return;\r
+       }\r
+       if (nenhere==0) {\r
+               prout("Sulu-  \"But Sir, there are no enemies in this quadrant.\"");\r
+               return;\r
+       }\r
+       if (damage[DDRAY] > 0.0) {\r
+               prout("Death Ray is damaged.");\r
+               return;\r
+       }\r
+       prout("Spock-  \"Captain, the 'Experimental Death Ray'");\r
+       prout("  is highly unpredictible.  Considering the alternatives,");\r
+       prout("  are you sure this is wise?\" ");\r
+       if (ja()==0) return;\r
+       prout("Spock-  \"Acknowledged.\"");\r
+       skip(1);\r
+       ididit=1;\r
+       prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE");\r
+       skip(1);\r
+       prout("Crew scrambles in emergency preparation.");\r
+       prout("Spock and Scotty ready the death ray and");\r
+       prout("prepare to channel all ship's power to the device.");\r
+       skip(1);\r
+       prout("Spock-  \"Preparations complete, sir.\"");\r
+       prout("Kirk-  \"Engage!\"");\r
+       skip(1);\r
+       prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");\r
+       skip(1);\r
+       if (r > .30) {\r
+               prouts("Sulu- \"Captain!  It's working!\"");\r
+               skip(2);\r
+               while (nenhere > 0)\r
+                       deadkl(kx[1],ky[1],quad[kx[1]][ky[1]],kx[1],ky[1]);\r
+               prout("Ensign Chekov-  \"Congratulations, Captain!\"");\r
+               if (d.remkl == 0) finish(FWON);\r
+               prout("Spock-  \"Captain, I believe the `Experimental Death Ray'");\r
+               if (Rand() <= 0.05) {\r
+                       prout("   is still operational.\"");\r
+               }\r
+               else {\r
+                       prout("   has been rendered disfunctional.\"");\r
+                       damage[DDRAY] = 39.95;\r
+               }\r
+               return;\r
+       }\r
+       r = Rand();     // Pick failure method \r
+       if (r <= .30) {\r
+               prouts("Sulu- \"Captain!  It's working!\"");\r
+               skip(1);\r
+               prouts("***RED ALERT!  RED ALERT!");\r
+               skip(1);\r
+               prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!");\r
+               skip(1);\r
+               prouts("***RED ALERT!  RED A*L********************************");\r
+               skip(1);\r
+               stars();\r
+               prouts("******************   KA-BOOM!!!!   *******************");\r
+               skip(1);\r
+               kaboom();\r
+               return;\r
+       }\r
+       if (r <= .55) {\r
+               prouts("Sulu- \"Captain!  Yagabandaghangrapl, brachriigringlanbla!\"");\r
+               skip(1);\r
+               prout("Lt. Uhura-  \"Graaeek!  Graaeek!\"");\r
+               skip(1);\r
+               prout("Spock-  \"Facinating!  . . . All humans aboard");\r
+               prout("  have apparently been transformed into strange mutations.");\r
+               prout("  Vulcans do not seem to be affected.");\r
+               skip(1);\r
+               prout("Kirk-  \"Raauch!  Raauch!\"");\r
+               finish(FDRAY);\r
+               return;\r
+       }\r
+       if (r <= 0.75) {\r
+               int i,j;\r
+               prouts("Sulu- \"Captain!  It's   --WHAT?!?!\"");\r
+               skip(2);\r
+               proutn("Spock-  \"I believe the word is");\r
+               prouts(" *ASTONISHING*");\r
+               prout(" Mr. Sulu.");\r
+               for (i=1; i<=10; i++)\r
+                       for (j=1; j<=10; j++)\r
+                               if (quad[i][j] == IHDOT) quad[i][j] = IHQUEST;\r
+               prout("  Captain, our quadrant is now infested with");\r
+               prouts(" - - - - - -  *THINGS*.");\r
+               skip(1);\r
+               prout("  I have no logical explanation.\"");\r
+               return;\r
+       }\r
+       prouts("Sulu- \"Captain!  The Death Ray is creating tribbles!\"");\r
+       skip(1);\r
+       prout("Scotty-  \"There are so many tribbles down here");\r
+       prout("  in Engineering, we can't move for 'em, Captain.\"");\r
+       finish(FTRIBBLE);\r
+       return;\r
+}\r
diff --git a/reports.c b/reports.c
new file mode 100644 (file)
index 0000000..0c8f606
--- /dev/null
+++ b/reports.c
@@ -0,0 +1,495 @@
+#include "sst.h"\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+void attakreport(void) {\r
+       if (future[FCDBAS] < 1e30) {\r
+               proutn("Starbase in ");\r
+               cramlc(1, batx, baty);\r
+               prout(" is currently under attack.");\r
+               proutn("It can hold out until Stardate ");\r
+               cramf(future[FCDBAS], 0,1);\r
+               prout(".");\r
+       }\r
+       if (isatb == 1) {\r
+               proutn("Starbase in ");\r
+               cramlc(1, d.isx, d.isy);\r
+               prout(" is under Super-commander attack.");\r
+               proutn("It can hold out until Stardate ");\r
+               cramf(future[FSCDBAS], 0, 1);\r
+               prout(".");\r
+       }\r
+}\r
+       \r
+\r
+void report(int f) {\r
+       char *s1,*s2,*s3;\r
+\r
+       chew();\r
+       s1 = (thawed?"thawed ":"");\r
+       switch (length) {\r
+               case 1: s2="short"; break;\r
+               case 2: s2="medium"; break;\r
+               case 4: s2="long"; break;\r
+               default: s2="unknown length"; break;\r
+       }\r
+       switch (skill) {\r
+               case 1: s3="novice"; break;\r
+               case 2: s3="fair"; break;\r
+               case 3: s3="good"; break;\r
+               case 4: s3="expert"; break;\r
+               case 5: s3="emeritus"; break;\r
+               default: s3="skilled"; break;\r
+       }\r
+       printf("\nYou %s playing a %s%s %s game.\n",\r
+                  alldone? "were": "are now", s1, s2, s3);\r
+       if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");\r
+       if (tourn) printf("This is tournament game %d.\n", tourn);\r
+       if (f) printf("Your secret password is \"%s\"\n",passwd);\r
+       printf("%d of %d Klingons have been killed",\r
+                  d.killk+d.killc+d.nsckill, inkling);\r
+       if (d.killc) printf(", including %d Commander%s.\n", d.killc, d.killc==1?"":"s");\r
+       else if (d.killk+d.nsckill > 0) prout(", but no Commanders.");\r
+       else prout(".");\r
+       if (skill > 2) printf("The Super Commander has %sbeen destroyed.\n",\r
+                                                 d.nscrem?"not ":"");\r
+       if (d.rembase != inbase) {\r
+               proutn("There ");\r
+               if (inbase-d.rembase==1) proutn("has been 1 base");\r
+               else {\r
+                       proutn("have been ");\r
+                       crami(inbase-d.rembase, 1);\r
+                       proutn(" bases");\r
+               }\r
+               proutn(" destroyed, ");\r
+               crami(d.rembase, 1);\r
+               prout(" remaining.");\r
+       }\r
+       else printf("There are %d bases.\n", inbase);\r
+       if (damage[DRADIO] == 0.0 || condit == IHDOCKED || iseenit) {\r
+               /* Don't report this if not seen and\r
+                       either the radio is dead or not at base! */\r
+               attakreport();\r
+               iseenit = 1;\r
+       }\r
+       if (casual) printf("%d casualt%s suffered so far.\n",\r
+                                          casual, casual==1? "y" : "ies");\r
+       if (nhelp) printf("There were %d call%s for help.\n",\r
+                                         nhelp, nhelp==1 ? "" : "s");\r
+       if (ship == IHE) {\r
+               proutn("You have ");\r
+               if (nprobes) crami(nprobes,1);\r
+               else proutn("no");\r
+               proutn(" deep space probe");\r
+               if (nprobes!=1) proutn("s");\r
+               prout(".");\r
+       }\r
+       if ((damage[DRADIO] == 0.0 || condit == IHDOCKED)&&\r
+               future[FDSPROB] != 1e30) {\r
+               if (isarmed) \r
+                       proutn("An armed deep space probe is in");\r
+               else\r
+                       proutn("A deep space probe is in");\r
+               cramlc(1, probecx, probecy);\r
+               prout(".");\r
+       }\r
+       if (icrystl) {\r
+               if (cryprob <= .05)\r
+                       prout("Dilithium crystals aboard ship...not yet used.");\r
+               else {\r
+                       int i=0;\r
+                       double ai = 0.05;\r
+                       while (cryprob > ai) {\r
+                               ai *= 2.0;\r
+                               i++;\r
+                       }\r
+                       printf("Dilithium crystals have been used %d time%s.\n",\r
+                                  i, i==1? "" : "s");\r
+               }\r
+       }\r
+       skip(1);\r
+}\r
+       \r
+void lrscan(void) {\r
+       int x, y;\r
+       chew();\r
+       if (damage[DLRSENS] != 0.0) {\r
+               /* Now allow base's sensors if docked */\r
+               if (condit != IHDOCKED) {\r
+                       prout("LONG-RANGE SENSORS DAMAGED.");\r
+                       return;\r
+               }\r
+               skip(1);\r
+               proutn("Starbase's long-range scan for");\r
+       }\r
+       else {\r
+               skip(1);\r
+               proutn("Long-range scan for");\r
+       }\r
+       cramlc(1, quadx, quady);\r
+       skip(1);\r
+       for (x = quadx-1; x <= quadx+1; x++) {\r
+               for (y = quady-1; y <= quady+1; y++) {\r
+                       if (x == 0 || x > 8 || y == 0 || y > 8)\r
+                               printf("   -1");\r
+                       else {\r
+                               printf("%5d", d.galaxy[x][y]);\r
+                               starch[x][y] = damage[DRADIO] > 0 ? d.galaxy[x][y]+1000 :1;\r
+                       }\r
+               }\r
+               putchar('\n');\r
+       }\r
+\r
+}\r
+\r
+void dreprt(void) {\r
+       int jdam = FALSE, i;\r
+       chew();\r
+\r
+       for (i = 1; i <= ndevice; i++) {\r
+               if (damage[i] > 0.0) {\r
+                       if (!jdam) {\r
+                               skip(1);\r
+                               prout("DEVICE            -REPAIR TIMES-");\r
+                               prout("                IN FLIGHT   DOCKED");\r
+                               jdam = TRUE;\r
+                       }\r
+                       printf("  %16s ", device[i]);\r
+                       cramf(damage[i]+0.05, 8, 2);\r
+                       proutn("  ");\r
+                       cramf(docfac*damage[i]+0.005, 8, 2);\r
+                       skip(1);\r
+               }\r
+       }\r
+       if (!jdam) prout("All devices functional.");\r
+}\r
+\r
+void chart(int nn) {\r
+       int i,j;\r
+\r
+       chew();\r
+       skip(1);\r
+       if (stdamtim != 1e30 && stdamtim != d.date && condit == IHDOCKED) {\r
+               prout("Spock-  \"I revised the Star Chart from the");\r
+               prout("  starbase's records.\"");\r
+               skip(1);\r
+       }\r
+       if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY");\r
+       if (stdamtim != 1e30) {\r
+               if (condit == IHDOCKED) {\r
+                       /* We are docked, so restore chart from base information */\r
+                       stdamtim = d.date;\r
+                       for (i=1; i <= 8 ; i++)\r
+                               for (j=1; j <= 8; j++)\r
+                                       if (starch[i][j] == 1) starch[i][j] = d.galaxy[i][j]+1000;\r
+               }\r
+               else {\r
+                       proutn("(Last surveillance update ");\r
+                       cramf(d.date-stdamtim, 0, 1);\r
+                       prout(" stardates ago.)");\r
+               }\r
+       }\r
+       if (nn ==0) skip(1);\r
+\r
+       prout("      1    2    3    4    5    6    7    8");\r
+       prout("    ----------------------------------------");\r
+       if (nn==0) prout("  -");\r
+       for (i = 1; i <= 8; i++) {\r
+               printf("%d -", i);\r
+               for (j = 1; j <= 8; j++) {\r
+                       if (starch[i][j] < 0)\r
+                               printf("  .1.");\r
+                       else if (starch[i][j] == 0)\r
+                               printf("  ...");\r
+                       else if (starch[i][j] > 999)\r
+                               printf("%5d", starch[i][j]-1000);\r
+                       else\r
+                               printf("%5d", d.galaxy[i][j]);\r
+               }\r
+               prout("  -");\r
+       }\r
+       if (nn == 0) {\r
+               skip(1);\r
+               crmshp();\r
+               proutn(" is currently in");\r
+               cramlc(1, quadx, quady);\r
+               skip(1);\r
+       }\r
+}\r
+               \r
+               \r
+void srscan(int l) {\r
+       static char requests[][3] =\r
+               {"","da","co","po","ls","wa","en","to","sh","kl","ti"};\r
+       char *cp;\r
+       int leftside=TRUE, rightside=TRUE, i, j, jj, k=0, nn=FALSE;\r
+       int goodScan=TRUE;\r
+       switch (l) {\r
+               case 1: // SRSCAN\r
+                       if (damage[DSRSENS] != 0) {\r
+                               /* Allow base's sensors if docked */\r
+                               if (condit != IHDOCKED) {\r
+                                       prout("SHORT-RANGE SENSORS DAMAGED");\r
+                                       goodScan=FALSE;\r
+                               }\r
+                               else\r
+                                       prout("[Using starbase's sensors]");\r
+                       }\r
+                       if (goodScan)\r
+                               starch[quadx][quady] = damage[DRADIO]>0.0 ?\r
+                                                                          d.galaxy[quadx][quady]+1000:1;\r
+                       scan();\r
+                       if (isit("chart")) nn = TRUE;\r
+                       if (isit("no")) rightside = FALSE;\r
+                       chew();\r
+                       prout("\n    1 2 3 4 5 6 7 8 9 10");\r
+                       break;\r
+               case 2: // REQUEST\r
+                       while (scan() == IHEOL)\r
+                               printf("Information desired? ");\r
+                       chew();\r
+                       for (k = 1; k <= 10; k++)\r
+                               if (strncmp(citem,requests[k],min(2,strlen(citem)))==0)\r
+                                       break;\r
+                       if (k > 10) {\r
+                               prout("UNRECOGNIZED REQUEST. Legal requests are:\n"\r
+                                        "  date, condition, position, lsupport, warpfactor,\n"\r
+                                        "  energy, torpedoes, shields, klingons, time.");\r
+                               return;\r
+                       }\r
+                       // no "break"\r
+               case 3: // STATUS\r
+                       chew();\r
+                       leftside = FALSE;\r
+                       skip(1);\r
+       }\r
+       for (i = 1; i <= 10; i++) {\r
+               int jj = (k!=0 ? k : i);\r
+               if (leftside) {\r
+                       printf("%2d  ", i);\r
+                       for (j = 1; j <= 10; j++) {\r
+                               if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1))\r
+                                       printf("%c ",quad[i][j]);\r
+                               else\r
+                                       printf("- ");\r
+                       }\r
+               }\r
+               if (rightside) {\r
+                       switch (jj) {\r
+                               case 1:\r
+                                       printf(" Stardate      %.1f", d.date);\r
+                                       break;\r
+                               case 2:\r
+                                       if (condit != IHDOCKED) newcnd();\r
+                                       switch (condit) {\r
+                                               case IHRED: cp = "RED"; break;\r
+                                               case IHGREEN: cp = "GREEN"; break;\r
+                                               case IHYELLOW: cp = "YELLOW"; break;\r
+                                               case IHDOCKED: cp = "DOCKED"; break;\r
+                                       }\r
+                                       printf(" Condition     %s", cp);\r
+                                       break;\r
+                               case 3:\r
+                                       printf(" Position     ");\r
+                                       cramlc(0, quadx, quady);\r
+                                       putchar(',');\r
+                                       cramlc(0, sectx, secty);\r
+                                       break;\r
+                               case 4:\r
+                                       printf(" Life Support  ");\r
+                                       if (damage[DLIFSUP] != 0.0) {\r
+                                               if (condit == IHDOCKED)\r
+                                                       printf("DAMAGED, supported by starbase");\r
+                                               else\r
+                                                       printf("DAMAGED, reserves=%4.2f", lsupres);\r
+                                       }\r
+                                       else\r
+                                               printf("ACTIVE");\r
+                                       break;\r
+                               case 5:\r
+                                       printf(" Warp Factor   %.1f", warpfac);\r
+                                       break;\r
+                               case 6:\r
+                                       printf(" Energy        %.2f", energy);\r
+                                       break;\r
+                               case 7:\r
+                                       printf(" Torpedoes     %d", torps);\r
+                                       break;\r
+                               case 8:\r
+                                       printf(" Shields       ");\r
+                                       if (damage[DSHIELD] != 0)\r
+                                               printf("DAMAGED,");\r
+                                       else if (shldup)\r
+                                               printf("UP,");\r
+                                       else\r
+                                               printf("DOWN,");\r
+                                       printf(" %d%% %.1f units",\r
+                                                  (int)((100.0*shield)/inshld + 0.5), shield);\r
+                                       break;\r
+                               case 9:\r
+                                       printf(" Klingons Left %d", d.remkl);\r
+                                       break;\r
+                               case 10:\r
+                                       printf(" Time Left     %.2f", d.remtime);\r
+                                       break;\r
+                       }\r
+                                       \r
+               }\r
+               skip(1);\r
+               if (k!=0) return;\r
+       }\r
+       if (nn) chart(1);\r
+}\r
+                       \r
+                       \r
+void eta(void) {\r
+       int key, ix1, ix2, iy1, iy2, prompt=FALSE;\r
+       int wfl;\r
+       double ttime, twarp, tpower;\r
+       if (damage[DCOMPTR] != 0.0) {\r
+               prout("COMPUTER DAMAGED, USE A POCKET CALCULATOR.");\r
+               skip(1);\r
+               return;\r
+       }\r
+       if (scan() != IHREAL) {\r
+               prompt = TRUE;\r
+               chew();\r
+               proutn("Destination quadrant and/or sector? ");\r
+               if (scan()!=IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+       }\r
+       iy1 = aaitem +0.5;\r
+       if (scan() != IHREAL) {\r
+               huh();\r
+               return;\r
+       }\r
+       ix1 = aaitem + 0.5;\r
+       if (scan() == IHREAL) {\r
+               iy2 = aaitem + 0.5;\r
+               if (scan() != IHREAL) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               ix2 = aaitem + 0.5;\r
+       }\r
+       else {  // same quadrant\r
+               ix2 = ix1;\r
+               iy2 = iy1;\r
+               ix1 = quady;    // ya got me why x and y are reversed!\r
+               iy1 = quadx;\r
+       }\r
+\r
+       if (ix1 > 8 || ix1 < 1 || iy1 > 8 || iy1 < 1 ||\r
+               ix2 > 10 || ix2 < 1 || iy2 > 10 || iy2 < 1) {\r
+               huh();\r
+               return;\r
+       }\r
+       dist = sqrt(square(iy1-quadx+0.1*(iy2-sectx))+\r
+                               square(ix1-quady+0.1*(ix2-secty)));\r
+       wfl = FALSE;\r
+\r
+       if (prompt) prout("Answer \"no\" if you don't know the value:");\r
+       while (TRUE) {\r
+               chew();\r
+               proutn("Time or arrival date? ");\r
+               if (scan()==IHREAL) {\r
+                       ttime = aaitem;\r
+                       if (ttime > d.date) ttime -= d.date; // Actually a star date\r
+                       if (ttime <= 1e-10 ||\r
+                               (twarp=(floor(sqrt((10.0*dist)/ttime)*10.0)+1.0)/10.0) > 10) {\r
+                               prout("We'll never make it, sir.");\r
+                               chew();\r
+                               return;\r
+                       }\r
+                       if (twarp < 1.0) twarp = 1.0;\r
+                       break;\r
+               }\r
+               chew();\r
+               proutn("Warp factor? ");\r
+               if (scan()== IHREAL) {\r
+                       wfl = TRUE;\r
+                       twarp = aaitem;\r
+                       if (twarp<1.0 || twarp > 10.0) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+                       break;\r
+               }\r
+               prout("Captain, certainly you can give me one of these.");\r
+       }\r
+       while (TRUE) {\r
+               chew();\r
+               ttime = (10.0*dist)/square(twarp);\r
+               tpower = dist*twarp*twarp*twarp*(shldup+1);\r
+               if (tpower >= energy) {\r
+                       prout("Insufficient energy, sir.");\r
+                       if (shldup==0 || tpower > energy*2.0) {\r
+                               if (!wfl) return;\r
+                               proutn("New warp factor to try? ");\r
+                               if (scan() == IHREAL) {\r
+                                       wfl = TRUE;\r
+                                       twarp = aaitem;\r
+                                       if (twarp<1.0 || twarp > 10.0) {\r
+                                               huh();\r
+                                               return;\r
+                                       }\r
+                                       continue;\r
+                               }\r
+                               else {\r
+                                       chew();\r
+                                       skip(1);\r
+                                       return;\r
+                               }\r
+                       }\r
+                       prout("But if you lower your shields,");\r
+                       proutn("remaining");\r
+                       tpower /= 2;\r
+               }\r
+               else\r
+                       proutn("Remaining");\r
+               proutn(" energy will be ");\r
+               cramf(energy-tpower, 1, 1);\r
+               prout(".");\r
+               if (wfl) {\r
+                       proutn("And we will arrive at stardate ");\r
+                       cramf(d.date+ttime, 1, 1);\r
+                       prout(".");\r
+               }\r
+               else if (twarp==1.0)\r
+                       prout("Any warp speed is adequate.");\r
+               else {\r
+                       proutn("Minimum warp needed is ");\r
+                       cramf(twarp, 1, 2);\r
+                       skip(1);\r
+                       proutn("and we will arrive at stardate ");\r
+                       cramf(d.date+ttime, 1, 2);\r
+                       prout(".");\r
+               }\r
+               if (d.remtime < ttime)\r
+                       prout("Unfortunately, the Federation will be destroyed by then.");\r
+               if (twarp > 6.0)\r
+                       prout("You'll be taking risks at that speed, Captain");\r
+               if ((isatb==1 && d.isy == ix1 && d.isx == iy1 &&\r
+                        future[FSCDBAS]< ttime+d.date)||\r
+                       (future[FCDBAS]<ttime+d.date && baty==ix1 && batx == iy1))\r
+                       prout("The starbase there will be destroyed by then.");\r
+               proutn("New warp factor to try? ");\r
+               if (scan() == IHREAL) {\r
+                       wfl = TRUE;\r
+                       twarp = aaitem;\r
+                       if (twarp<1.0 || twarp > 10.0) {\r
+                               huh();\r
+                               return;\r
+                       }\r
+               }\r
+               else {\r
+                       chew();\r
+                       skip(1);\r
+                       return;\r
+               }\r
+       }\r
+                       \r
+}\r
diff --git a/setup.c b/setup.c
new file mode 100644 (file)
index 0000000..2306cb0
--- /dev/null
+++ b/setup.c
@@ -0,0 +1,701 @@
+#include <time.h>\r
+#include "sst.h"\r
+\r
+void prelim(void) {\r
+       skip(2);\r
+       prout("-SUPER- STAR TREK");\r
+       skip(1);\r
+       prout("Latest update-21 Sept 78");\r
+       skip(1);\r
+}\r
+\r
+void freeze(int boss) {\r
+       char *x, *y;\r
+       FILE *fp;\r
+       int key;\r
+       if (boss) {\r
+               strcpy(citem, "emsave.trk");\r
+       }\r
+       else {\r
+               if ((key = scan()) == IHEOL) {\r
+                       proutn("File name: ");\r
+                       key = scan();\r
+               }\r
+               if (key != IHALPHA) {\r
+                       huh();\r
+                       return;\r
+               }\r
+               chew();\r
+               if (strchr(citem, '.') == NULL) {\r
+                       strcat(citem, ".trk");\r
+               }\r
+       }\r
+       if ((fp = fopen(citem, "wb")) == NULL) {\r
+               proutn("Can't freeze game as file ");\r
+               proutn(citem);\r
+               skip(1);\r
+               return;\r
+       }\r
+       fwrite(&d, sizeof(d), 1, fp);\r
+       fwrite(&snapsht, sizeof(snapsht), 1, fp);\r
+       fwrite(quad, sizeof(quad), 1, fp);\r
+       fwrite(kx, sizeof(kx), 1, fp);\r
+       fwrite(ky, sizeof(ky), 1, fp);\r
+       fwrite(starch, sizeof(starch), 1, fp);\r
+       fwrite(kpower, sizeof(kpower), 1, fp);\r
+       fwrite(kdist, sizeof(kdist), 1, fp);\r
+       fwrite(kavgd, sizeof(kavgd), 1, fp);\r
+       fwrite(damage, sizeof(damage), 1, fp);\r
+       fwrite(future, sizeof(future), 1, fp);\r
+       fwrite(&a, sizeof(a), 1, fp);\r
+       fwrite(passwd, sizeof(passwd), 1, fp);\r
+\r
+       fclose(fp);\r
+\r
+       /* I hope that's enough! */\r
+}\r
+\r
+\r
+void thaw(void) {\r
+       char *x, *y;\r
+       FILE *fp;\r
+       int key;\r
+\r
+       passwd[0] = '\0';\r
+       if ((key = scan()) == IHEOL) {\r
+               proutn("File name: ");\r
+               key = scan();\r
+       }\r
+       if (key != IHALPHA) {\r
+               huh();\r
+               return;\r
+       }\r
+       chew();\r
+       if (strchr(citem, '.') == NULL) {\r
+               strcat(citem, ".trk");\r
+       }\r
+       if ((fp = fopen(citem, "rb")) == NULL) {\r
+               proutn("Can't find game file ");\r
+               proutn(citem);\r
+               skip(1);\r
+               return;\r
+       }\r
+       fread(&d, sizeof(d), 1, fp);\r
+       fread(&snapsht, sizeof(snapsht), 1, fp);\r
+       fread(quad, sizeof(quad), 1, fp);\r
+       fread(kx, sizeof(kx), 1, fp);\r
+       fread(ky, sizeof(ky), 1, fp);\r
+       fread(starch, sizeof(starch), 1, fp);\r
+       fread(kpower, sizeof(kpower), 1, fp);\r
+       fread(kdist, sizeof(kdist), 1, fp);\r
+       fread(kavgd, sizeof(kavgd), 1, fp);\r
+       fread(damage, sizeof(damage), 1, fp);\r
+       fread(future, sizeof(future), 1, fp);\r
+       fread(&a, sizeof(a), 1, fp);\r
+       fread(passwd, sizeof(passwd), 1, fp);\r
+\r
+       fclose(fp);\r
+\r
+       /* I hope that's enough! */\r
+}\r
+\r
+void abandn(void) {\r
+       int nb, l;\r
+\r
+       chew();\r
+       if (condit==IHDOCKED) {\r
+               if (ship!=IHE) {\r
+                       prout("You cannot abandon Ye Faerie Queene.");\r
+                       return;\r
+               }\r
+       }\r
+       else {\r
+               /* Must take shuttle craft to exit */\r
+               if (damage[DSHUTTL]==-1) {\r
+                       prout("Ye Faerie Queene has no shuttle craft.");\r
+                       return;\r
+               }\r
+               if (damage[DSHUTTL]<0) {\r
+                       prout("Shuttle craft now serving Big Mac's.");\r
+                       return;\r
+               }\r
+               if (damage[DSHUTTL]>0) {\r
+                       prout("Shuttle craft damaged.");\r
+                       return;\r
+               }\r
+               if (landed==1) {\r
+                       prout("You must be aboard the Enterprise.");\r
+                       return;\r
+               }\r
+               if (iscraft!=1) {\r
+                       prout("Shuttle craft not currently available.");\r
+                       return;\r
+               }\r
+               /* Print abandon ship messages */\r
+               skip(1);\r
+               prouts("***ABANDON SHIP!  ABANDON SHIP!");\r
+               skip(1);\r
+               prouts("***ALL HANDS ABANDON SHIP!");\r
+               skip(2);\r
+               prout("Captain and crew escape in shuttle craft.");\r
+               prout("Remainder of ship's complement beam down");\r
+               prout("to nearest habitable planet.");\r
+               if (d.rembase==0) {\r
+                       /* Ops! no place to go... */\r
+                       finish(FABANDN);\r
+                       return;\r
+               }\r
+               /* If at least one base left, give 'em the Faerie Queene */\r
+               skip(1);\r
+               icrystl = 0; /* crystals are lost */\r
+               nprobes = 0; /* No probes */\r
+               prout("You are captured by Klingons and released to");\r
+               prout("the Federation in a prisoner-of-war exchange.");\r
+               nb = Rand()*d.rembase+1;\r
+               /* Set up quadrant and position FQ adjacient to base */\r
+               if (quadx!=d.baseqx[nb] || quady!=d.baseqy[nb]) {\r
+                       quadx = d.baseqx[nb];\r
+                       quady = d.baseqy[nb];\r
+                       sectx = secty = 5;\r
+                       newqad(1);\r
+               }\r
+               for (;;) {\r
+                       /* position next to base by trial and error */\r
+                       quad[sectx][secty] = IHDOT;\r
+                       for (l = 1; l <= 10; l++) {\r
+                               sectx = 3.0*Rand() - 1.0 + basex;\r
+                               secty = 3.0*Rand() - 1.0 + basey;\r
+                               if (sectx >= 1 && sectx <= 10 &&\r
+                                       secty >= 1 && secty <= 10 &&\r
+                                       quad[sectx][secty] == IHDOT) break;\r
+                       }\r
+                       if (l < 11) break; /* found a spot */\r
+                       sectx=5;\r
+                       secty=5;\r
+                       newqad(1);\r
+               }\r
+       }\r
+       /* Get new commission */\r
+       quad[sectx][secty] = ship = IHF;\r
+       prout("Starfleet puts you in command of another ship,");\r
+       prout("the Faerie Queene, which is antiquated but,");\r
+       prout("still useable.");\r
+       if (icrystl!=0) prout("The dilithium crystals have been moved.");\r
+       imine=0;\r
+       iscraft=0; /* Gallileo disappears */\r
+       /* Resupply ship */\r
+       condit=IHDOCKED;\r
+       for (l = 1; l <= ndevice; l++) damage[l] = 0.0;\r
+       damage[DSHUTTL] = -1;\r
+       energy = inenrg = 3000.0;\r
+       shield = inshld = 1250.0;\r
+       torps = intorps = 6;\r
+       lsupres=inlsr=3.0;\r
+       shldup=0;\r
+       warpfac=5.0;\r
+       wfacsq=25.0;\r
+       return;\r
+}\r
+       \r
+void setup(void) {\r
+       int i,j, krem, klumper;\r
+       int ix, iy;\r
+       alldone = gamewon = 0;\r
+#ifdef DEBUG\r
+       idebug = 0;\r
+#endif\r
+       //  Decide how many of everything\r
+       if (choose()) return; // frozen game\r
+       // Prepare the Enterprise\r
+       ship = IHE;\r
+       energy = inenrg = 5000.0;\r
+       shield = inshld = 2500.0;\r
+       shldchg = shldup = 0;\r
+       inlsr = 4.0;\r
+       lsupres = 4.0;\r
+       iran8(&quadx, &quady);\r
+       iran10(&sectx, &secty);\r
+       torps = intorps = 10;\r
+       nprobes = (int)(3.0*Rand() + 2.0);      /* Give them 2-4 of these wonders */\r
+       warpfac = 5.0;\r
+       wfacsq = warpfac * warpfac;\r
+       for (i=0; i <= ndevice; i++) damage[i] = 0.0;\r
+       // Set up assorted game parameters\r
+       batx = baty = 0;\r
+       d.date = indate = 100.0*(int)(31.0*Rand()+20.0);\r
+       d.killk = d.killc = nkinks = nhelp = resting = casual = d.nromkl = 0;\r
+       isatb = iscate = imine = icrystl = icraft = d.nsckill = d.nplankl = 0;\r
+       iscraft = 1;\r
+       landed = -1;\r
+       alive = 1;\r
+       docfac = 0.25;\r
+       for (i = 1; i <= 8; i++)\r
+               for (j = 1; j <= 8; j++) d.newstuf[i][j] = starch[i][j] = 0;\r
+       // Initialize times for extraneous events\r
+       future[FSNOVA] = d.date + expran(0.5 * intime);\r
+       future[FTBEAM] = d.date + expran(1.5 * (intime / d.remcom));\r
+       future[FSNAP] = d.date + 1.0 + Rand(); // Force an early snapshot\r
+       future[FBATTAK] = d.date + expran(0.3*intime);\r
+       future[FCDBAS] = 1e30;\r
+       future[FSCMOVE] = d.nscrem ? d.date+0.2777 : 1e30;\r
+       future[FSCDBAS] = 1e30;\r
+       future[FDSPROB] = 1e30;\r
+       // Starchart is functional\r
+       stdamtim = 1e30;\r
+       // Put stars in the galaxy\r
+       instar = 0;\r
+       for (i=1; i<=8; i++)\r
+               for (j=1; j<=8; j++) {\r
+                       int k = Rand()*9.0 + 1.0;\r
+                       instar += k;\r
+                       d.galaxy[i][j] = k;\r
+               }\r
+       // Locate star bases in galaxy\r
+       for (i = 1; i <= inbase; i++) {\r
+               int contflag;\r
+               do {\r
+                       do iran8(&ix, &iy);\r
+                       while (d.galaxy[ix][iy] >= 10);\r
+                       contflag = FALSE;\r
+                       for (j = i-1; j > 0; j--) {\r
+                               /* Improved placement algorithm to spread out bases */\r
+                               double distq = square(ix-d.baseqx[j]) + square(iy-d.baseqy[j]);\r
+                               if (distq < 6.0*(6-inbase) && Rand() < 0.75) {\r
+                                       contflag = TRUE;\r
+#ifdef DEBUG\r
+                                       printf("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);\r
+#endif\r
+                                       break;\r
+                               }\r
+#ifdef DEBUG\r
+                               else if (distq < 6.0 * (6-inbase)) {\r
+                                       printf("DEBUG: saving base #%d, close to #%d\n", i, j);\r
+                               }\r
+#endif\r
+                       }\r
+               } while (contflag);\r
+                       \r
+               d.baseqx[i] = ix;\r
+               d.baseqy[i] = iy;\r
+               starch[ix][iy] = -1;\r
+               d.galaxy[ix][iy] += 10;\r
+       }\r
+       // Position ordinary Klingon Battle Cruisers\r
+       krem = inkling - incom - d.nscrem;\r
+       klumper = 0.25*skill*(9.0-length)+1.0;\r
+       if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant\r
+       do {\r
+               double r = Rand();\r
+               int klump = (1.0 - r*r)*klumper;\r
+               if (klump > krem) klump = krem;\r
+               krem -= klump;\r
+               klump *= 100;\r
+               do iran8(&ix, &iy);\r
+               while (d.galaxy[ix][iy] + klump >= 1000);\r
+               d.galaxy[ix][iy] += klump;\r
+       } while (krem > 0);\r
+       // Position Klingon Commander Ships\r
+#ifdef DEBUG\r
+       klumper = 1;\r
+#endif\r
+       for (i = 1; i <= incom; i++) {\r
+               do {\r
+                       do { /* IF debugging, put commanders by bases, always! */\r
+#ifdef DEBUG\r
+                               if (idebug && klumper <= inbase) {\r
+                                       ix = d.baseqx[klumper];\r
+                                       iy = d.baseqy[klumper];\r
+                                       klumper++;\r
+                               }\r
+                               else\r
+#endif\r
+                                       iran8(&ix, &iy);\r
+                       }\r
+                       while ((d.galaxy[ix][iy] < 99 && Rand() < 0.75)||\r
+                                  d.galaxy[ix][iy]>899);\r
+                       // check for duplicate\r
+                       for (j = 1; j < i; j++)\r
+                               if (d.cx[j]==ix && d.cy[j]==iy) break;\r
+               } while (j < i);\r
+               d.galaxy[ix][iy] += 100;\r
+               d.cx[i] = ix;\r
+               d.cy[i] = iy;\r
+       }\r
+       // Locate planets in galaxy\r
+       for (i = 1; i <= inplan; i++) {\r
+               do iran8(&ix, &iy);\r
+               while (d.newstuf[ix][iy] > 0);\r
+               d.newstuf[ix][iy] = 1;\r
+               d.plnets[i].x = ix;\r
+               d.plnets[i].y = iy;\r
+               d.plnets[i].pclass = Rand()*3.0 + 1.0; // Planet class M N or O\r
+               d.plnets[i].crystals = 1.5*Rand();              // 1 in 3 chance of crystals\r
+               d.plnets[i].known = 0;\r
+       }\r
+       // Locate Romulans\r
+       for (i = 1; i <= d.nromrem; i++) {\r
+               iran8(&ix, &iy);\r
+               d.newstuf[ix][iy] += 10;\r
+       }\r
+       // Locate the Super Commander\r
+       if (d.nscrem > 0) {\r
+               do iran8(&ix, &iy);\r
+               while (d.galaxy[ix][iy] >= 900);\r
+               d.isx = ix;\r
+               d.isy = iy;\r
+               d.galaxy[ix][iy] += 100;\r
+       }\r
+       // Place thing (in tournament game, thingx == -1, don't want one!)\r
+       if (Rand() < 0.1 && thingx != -1) {\r
+               iran8(&thingx, &thingy);\r
+       }\r
+       else {\r
+               thingx = thingy = 0;\r
+       }\r
+\r
+//     idate = date;\r
+       skip(3);\r
+       d.snap = 0;\r
+               \r
+       if (skill == 1) {\r
+               printf("It is stardate %d. The Federation is being attacked by\n",\r
+                          (int)d.date);\r
+               printf("a deadly Klingon invasion force. As captain of the United\n"\r
+                          "Starship U.S.S. Enterprise, it is your mission to seek out\n"\r
+                          "and destroy this invasion force of %d battle cruisers.\n",\r
+                          inkling);\r
+               printf("You have an initial allotment of %d stardates to complete\n"\r
+                          "your mission.  As you proceed you may be given more time.\n\n"\r
+                          "You will have %d supporting starbases.\n"\r
+                          "Starbase locations-  ",\r
+                          (int)intime, inbase);\r
+       }\r
+       else {\r
+               printf("Stardate %d.\n\n"\r
+                          "%d Klingons.\nAn unknown number of Romulans\n",\r
+                          (int)d.date, inkling);\r
+               if (d.nscrem) printf("and one (GULP) Super-Commander.\n");\r
+               printf("%d stardates\n%d starbases in  ",(int)intime, inbase);\r
+       }\r
+       for (i = 1; i <= inbase; i++) {\r
+               cramlc(0, d.baseqx[i], d.baseqy[i]);\r
+               if (i < inbase) proutn("  ");\r
+       }\r
+       skip(2);\r
+       proutn("The Enterprise is currently in");\r
+       cramlc(1, quadx, quady);\r
+       proutn(" ");\r
+       cramlc(2, sectx, secty);\r
+       skip(2);\r
+       prout("Good Luck!");\r
+       if (d.nscrem) proutn("  YOU'LL NEED IT.");\r
+       skip(1);\r
+       newqad(0);\r
+       if (nenhere) shldup=1.0;\r
+       if (neutz) attack(0);   // bad luck to start in a Romulan Neutral Zone\r
+}\r
+\r
+int choose(void) {\r
+       tourn = 0;\r
+       thawed = 0;\r
+       skill = 0;\r
+       length = 0;\r
+       while (TRUE) {\r
+               if (fromcommandline) /* Can start with command line options */\r
+                       fromcommandline = 0;\r
+               else\r
+                       proutn("Would you like a regular, tournament, or frozen game?");\r
+               scan();\r
+               if (strlen(citem)==0) continue; // Try again\r
+               if (isit("tournament")) {\r
+                       while (scan() == IHEOL) {\r
+                               proutn("Type in tournament number-");\r
+                       }\r
+                       if (aaitem == 0) {\r
+                               chew();\r
+                               continue; // We don't want a blank entry\r
+                       }\r
+                       tourn = (int)aaitem;\r
+                       thingx = -1;\r
+                       srand((unsigned int)(int)aaitem);\r
+                       break;\r
+               }\r
+               if (isit("frozen")) {\r
+                       thaw();\r
+                       chew();\r
+                       if (*passwd==0) continue;\r
+                       randomize();\r
+                       Rand(); Rand(); Rand(); Rand();\r
+                       if (!alldone) thawed = 1; // No plaque if not finished\r
+                       report(1);\r
+                       return TRUE;\r
+               }\r
+               if (isit("regular")) {\r
+                       skip(2);\r
+                       randomize();\r
+                       Rand(); Rand(); Rand(); Rand();\r
+                       break;\r
+               }\r
+               proutn("What is \"");\r
+               proutn(citem);\r
+               prout("\"?");\r
+               chew();\r
+       }\r
+       while (length==0 || skill==0) {\r
+               if (scan() == IHALPHA) {\r
+                       if (isit("short")) length = 1;\r
+                       else if (isit("medium")) length = 2;\r
+                       else if (isit("long")) length = 4;\r
+                       else if (isit("novice")) skill = 1;\r
+                       else if (isit("fair")) skill = 2;\r
+                       else if (isit("good")) skill = 3;\r
+                       else if (isit("expert")) skill = 4;\r
+                       else if (isit("emeritus")) skill = 5;\r
+                       else {\r
+                               proutn("What is \"");\r
+                               proutn(citem);\r
+                               prout("\"?");\r
+                       }\r
+               }\r
+               else {\r
+                       chew();\r
+                       if (length==0) proutn("Would you like a Short, Medium, or Long game? ");\r
+                       else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player?");\r
+               }\r
+       }\r
+       while (TRUE) {\r
+               scan();\r
+               strcpy(passwd, citem);\r
+               chew();\r
+               if (*passwd != 0) break;\r
+               proutn("Please type in a secret password-");\r
+       }\r
+#ifdef DEBUG\r
+       if (strcmp(passwd, "debug")==0) idebug = 1;\r
+#endif\r
+\r
+       // Use parameters to generate initial values of things\r
+       damfac = 0.5 * skill;\r
+       d.rembase = 3.0*Rand()+2.0;\r
+       inbase = d.rembase;\r
+       inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();\r
+       d.nromrem = (2.0+Rand())*skill;\r
+       d.nscrem = (skill > 2? 1 : 0);\r
+       d.remtime = 7.0 * length;\r
+       intime = d.remtime;\r
+       d.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);\r
+       inkling = d.remkl;\r
+       incom = skill + 0.0625*inkling*Rand();\r
+       d.remcom= min(10, incom);\r
+       incom = d.remcom;\r
+       d.remres = (inkling+4*incom)*intime;\r
+       inresor = d.remres;\r
+       if (inkling > 50) {\r
+               inbase = (d.rembase += 1);\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+void dropin(int iquad, int *ix, int *iy) {\r
+       do iran10(ix, iy);\r
+       while (quad[*ix][*iy] != IHDOT);\r
+       quad[*ix][*iy] = iquad;\r
+}\r
+\r
+void newcnd(void) {\r
+       condit = IHGREEN;\r
+       if (energy < 1000.0) condit = IHYELLOW;\r
+       if (d.galaxy[quadx][quady] > 99 || d.newstuf[quadx][quady] > 9)\r
+               condit = IHRED;\r
+}\r
+\r
+\r
+void newqad(int shutup) {\r
+       int quadnum = d.galaxy[quadx][quady];\r
+       int newnum = d.newstuf[quadx][quady];\r
+       int i, j, ix, iy, nplan;\r
+\r
+       iattak = 1;\r
+       justin = 1;\r
+       basex = basey = 0;\r
+       klhere = 0;\r
+       comhere = 0;\r
+       plnetx = plnety = 0;\r
+       ishere = 0;\r
+       irhere = 0;\r
+       iplnet = 0;\r
+       nenhere = 0;\r
+       neutz = 0;\r
+       inorbit = 0;\r
+       landed = -1;\r
+       ientesc = 0;\r
+       ithere = 0;\r
+       iseenit = 0;\r
+       if (iscate) {\r
+               // Attempt to escape Super-commander, so tbeam back!\r
+               iscate = 0;\r
+               ientesc = 1;\r
+       }\r
+       // Clear quadrant\r
+       for (i=1; i <= 10; i++)\r
+               for (j=1; j <= 10; j++) quad[i][j] = IHDOT;\r
+       // cope with supernova\r
+       if (quadnum > 999) {\r
+               return;\r
+       }\r
+       klhere = quadnum/100;\r
+       irhere = newnum/10;\r
+       nplan = newnum%10;\r
+       nenhere = klhere + irhere;\r
+\r
+       // Position Starship\r
+       quad[sectx][secty] = ship;\r
+\r
+       // Decide if quadrant needs a Tholian\r
+       if ((skill < 3 && Rand() <= 0.02) ||   /* Lighten up if skill is low */\r
+               (skill == 3 && Rand() <= 0.05) ||\r
+               (skill > 3 && Rand() <= 0.08)\r
+#ifdef DEBUG\r
+               || strcmp(passwd, "tholianx")==0\r
+#endif\r
+               ) {\r
+               do {\r
+                       ithx = Rand() > 0.5 ? 10 : 1;\r
+                       ithy = Rand() > 0.5 ? 10 : 1;\r
+               } while (quad[ithx][ithy] != IHDOT);\r
+               quad[ithx][ithy] = IHT;\r
+               ithere = 1;\r
+               /* Reserve unocupied corners */\r
+               if (quad[1][1]==IHDOT) quad[1][1] = 'X';\r
+               if (quad[1][10]==IHDOT) quad[1][10] = 'X';\r
+               if (quad[10][1]==IHDOT) quad[10][1] = 'X';\r
+               if (quad[10][10]==IHDOT) quad[10][10] = 'X';\r
+       }\r
+\r
+       if (quadnum >= 100) {\r
+               // Position ordinary Klingons\r
+               quadnum -= 100*klhere;\r
+               for (i = 1; i <= klhere; i++) {\r
+                       dropin(IHK, &ix, &iy);\r
+                       kx[i] = ix;\r
+                       ky[i] = iy;\r
+                       kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
+                       kpower[i] = Rand()*150.0 +300.0 +25.0*skill;\r
+               }\r
+               // If we need a commander, promote a Klingon\r
+               for (i = 1; i <= d.remcom ; i++) \r
+                       if (d.cx[i]==quadx && d.cy[i]==quady) break;\r
+                       \r
+               if (i <= d.remcom) {\r
+                       quad[ix][iy] = IHC;\r
+                       kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;\r
+                       comhere = 1;\r
+               }\r
+\r
+               // If we need a super-commander, promote a Klingon\r
+               if (quadx == d.isx && quady == d.isy) {\r
+                       quad[kx[1]][ky[1]] = IHS;\r
+                       kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;\r
+                       iscate = 1;\r
+                       ishere = 1;\r
+               }\r
+       }\r
+       // Put in Romulans if needed\r
+       for (i = klhere+1; i <= nenhere; i++) {\r
+               dropin(IHR, &ix, &iy);\r
+               kx[i] = ix;\r
+               ky[i] = iy;\r
+               kdist[i] = kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
+               kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;\r
+       }\r
+       sortkl();\r
+       // If quadrant needs a starbase, put it in\r
+       if (quadnum >= 10) {\r
+               quadnum -= 10;\r
+               dropin(IHB, &basex, &basey);\r
+       }\r
+       \r
+       if (nplan) {\r
+               // If quadrant needs a planet, put it in\r
+               for (i=1; i <= inplan; i++)\r
+                       if (d.plnets[i].x == quadx && d.plnets[i].y == quady) break;\r
+               if (i <= inplan) {\r
+                       iplnet = i;\r
+                       dropin(IHP, &plnetx, &plnety);\r
+               }\r
+       }\r
+       // Check for condition\r
+       newcnd();\r
+       // And finally the stars\r
+       for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);\r
+\r
+       // Check for RNZ\r
+       if (irhere > 0 && klhere == 0 && basex == 0) {\r
+               neutz = 1;\r
+               if (damage[DRADIO] <= 0.0) {\r
+                       skip(1);\r
+                       prout("LT. UHURA- \"Captain, an urgent message.");\r
+                       prout("  I'll put it on audio.\"  CLICK");\r
+                       skip(1);\r
+                       prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");\r
+                       prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");\r
+               }\r
+       }\r
+\r
+       if (shutup==0) {\r
+               // Put in THING if needed\r
+               if (thingx == quadx && thingy == quady) {\r
+                       dropin(IHQUEST, &ix, &iy);\r
+                       thingx = thingy = 0; // Transient\r
+                       if (damage[DSRSENS] == 0.0) {\r
+                               skip(1);\r
+                               prout("MR. SPOCK- \"Captain, this is most unusual.");\r
+                               prout("    Please examine your short-range scan.\"");\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Put in a few black holes\r
+       for (i = 1; i <= 3; i++)\r
+               if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);\r
+\r
+       // Take out X's in corners if Tholian present\r
+       if (ithere) {\r
+               if (quad[1][1]=='X') quad[1][1] = IHDOT;\r
+               if (quad[1][10]=='X') quad[1][10] = IHDOT;\r
+               if (quad[10][1]=='X') quad[10][1] = IHDOT;\r
+               if (quad[10][10]=='X') quad[10][10] = IHDOT;\r
+       }               \r
+}\r
+\r
+void sortkl(void) {\r
+       double t;\r
+       int sw, j, k;\r
+\r
+       // The author liked bubble sort. So we will use it. :-(\r
+\r
+       if (nenhere < 2) return;\r
+\r
+       do {\r
+               sw = FALSE;\r
+               for (j = 1; j < nenhere; j++)\r
+                       if (kdist[j] > kdist[j+1]) {\r
+                               sw = TRUE;\r
+                               t = kdist[j];\r
+                               kdist[j] = kdist[j+1];\r
+                               kdist[j+1] = t;\r
+                               t = kavgd[j];\r
+                               kavgd[j] = kavgd[j+1];\r
+                               kavgd[j+1] = t;\r
+                               k = kx[j];\r
+                               kx[j] = kx[j+1];\r
+                               kx[j+1] = k;\r
+                               k = ky[j];\r
+                               ky[j] = ky[j+1];\r
+                               ky[j+1] = k;\r
+                               t = kpower[j];\r
+                               kpower[j] = kpower[j+1];\r
+                               kpower[j+1] = t;\r
+                       }\r
+       } while (sw);\r
+}\r
diff --git a/sst.c b/sst.c
new file mode 100644 (file)
index 0000000..2c88844
--- /dev/null
+++ b/sst.c
@@ -0,0 +1,692 @@
+#define INCLUDED       // Define externs here\r
+#include "sst.h"\r
+#include <ctype.h>\r
+#ifdef MSDOS\r
+#include <dos.h>\r
+#endif\r
+#include <time.h>\r
+       \r
+int getch(void);\r
+\r
+static char line[128], *linep = line;\r
+static int linecount;  /* for paging */\r
+\r
+static void clearscreen(void);\r
+\r
+#define NUMCOMMANDS 34\r
+\r
+/* Compared to original version, I've changed the "help" command to\r
+   "call" and the "terminate" command to "quit" to better match\r
+   user expectations. The DECUS version apparently made those changes\r
+   as well as changing "freeze" to "save". However I like "freeze".\r
+\r
+   When I got a later version of Super Star Trek that I was converting\r
+   from, I added the emexit command.\r
+\r
+   That later version also mentions srscan and lrscan working when\r
+   docked (using the starbase's scanners), so I made some changes here\r
+   to do this (and indicating that fact to the player), and then realized\r
+   the base would have a subspace radio as well -- doing a Chart when docked\r
+   updates the star chart, and all radio reports will be heard. The Dock\r
+   command will also give a report if a base is under attack.\r
+\r
+   Movecom no longer reports movement if sensors are damaged so you wouldn't\r
+   otherwise know it.\r
+\r
+   Also added:\r
+\r
+   1. Better base positioning at startup\r
+\r
+   2. deathray improvement (but keeping original failure alternatives)\r
+\r
+   3. Tholian Web\r
+\r
+   4. Enemies can ram the Enterprise. Regular Klingons and Romulans can\r
+      move in Expert and Emeritus games. This code could use improvement.\r
+\r
+   5. The deep space probe looks interesting! DECUS version\r
+\r
+   6. Perhaps cloaking to be added later? BSD version\r
+\r
+\r
+   */\r
+\r
+\r
+static char *commands[NUMCOMMANDS] = {\r
+       "srscan",\r
+       "lrscan",\r
+       "phasers",\r
+       "photons",\r
+       "move",\r
+       "shields",\r
+       "dock",\r
+       "damages",\r
+       "chart",\r
+       "impulse",\r
+       "rest",\r
+       "warp",\r
+       "status",\r
+       "sensors",\r
+       "orbit",\r
+       "transport",\r
+       "mine",\r
+       "crystals",\r
+       "shuttle",\r
+       "planets",\r
+       "request",\r
+       "report",\r
+       "computer",\r
+       "commands",\r
+    "emexit",\r
+    "probe",\r
+       "abandon",\r
+       "destruct",\r
+       "freeze",\r
+       "deathray",\r
+       "debug",\r
+       "call",\r
+       "quit",\r
+       "help"\r
+};\r
+\r
+static void listCommands(int x) {\r
+       prout("   SRSCAN    MOVE      PHASERS   CALL\n"\r
+                 "   STATUS    IMPULSE   PHOTONS   ABANDON\n"\r
+                 "   LRSCAN    WARP      SHIELDS   DESTRUCT\n"\r
+                 "   CHART     REST      DOCK      QUIT\n"\r
+                 "   DAMAGES   REPORT    SENSORS   ORBIT\n"\r
+                 "   TRANSPORT MINE      CRYSTALS  SHUTTLE\n"\r
+                 "   PLANETS   REQUEST   DEATHRAY  FREEZE\n"\r
+                 "   COMPUTER  EMEXIT    PROBE     COMMANDS");\r
+       if (x) prout("   HELP");\r
+}\r
+\r
+static void helpme(void) {\r
+       int i, j;\r
+       char cmdbuf[32];\r
+       char linebuf[132];\r
+       FILE *fp;\r
+       /* Give help on commands */\r
+       int key;\r
+       key = scan();\r
+       while (TRUE) {\r
+               if (key == IHEOL) {\r
+                       proutn("Help on what command?");\r
+                       key = scan();\r
+               }\r
+               if (key == IHEOL) return;\r
+               for (i = 0; i < NUMCOMMANDS; i++) {\r
+                       if (strcmp(commands[i], citem)==0) break;\r
+               }\r
+               if (i != NUMCOMMANDS) break;\r
+               skip(1);\r
+               prout("Valid commands:");\r
+               listCommands(FALSE);\r
+               key = IHEOL;\r
+               chew();\r
+               skip(1);\r
+       }\r
+       if (i == 23) {\r
+               strcpy(cmdbuf, " ABBREV");\r
+       }\r
+       else {\r
+               strcpy(cmdbuf, "  Mnemonic:  ");\r
+               j = 0;\r
+               while ((cmdbuf[j+13] = toupper(commands[i][j])) != 0) j++;\r
+       }\r
+       fp = fopen("sst.doc", "r");\r
+       if (fp == NULL) {\r
+               prout("Spock-  \"Captain, that information is missing from the");\r
+               prout("   computer. You need to find SST.DOC and put it in the");\r
+               prout("   current directory.\"");\r
+               return;\r
+       }\r
+       i = strlen(cmdbuf);\r
+       do {\r
+               if (fgets(linebuf, 132, fp) == NULL) {\r
+                       prout("Spock- \"Captain, there is no information on that command.\"");\r
+                       fclose(fp);\r
+                       return;\r
+               }\r
+       } while (strncmp(linebuf, cmdbuf, i) != 0);\r
+\r
+       skip(1);\r
+       prout("Spock- \"Captain, I've found the following information:\"");\r
+       skip(1);\r
+\r
+       do {\r
+               if (linebuf[0]!=12) { // ignore page break lines \r
+                       linebuf[strlen(linebuf)-1] = '\0'; // No \n at end\r
+                       prout(linebuf);\r
+               }\r
+               fgets(linebuf,132,fp);\r
+       } while (strstr(linebuf, "******")==NULL);\r
+       fclose(fp);\r
+}\r
+\r
+static void makemoves(void) {\r
+       int i, hitme;\r
+       char ch;\r
+       while (TRUE) { /* command loop */\r
+               hitme = FALSE;\r
+               justin = 0;\r
+               Time = 0.0;\r
+               i = -1;\r
+               while (TRUE)  { /* get a command */\r
+                       chew();\r
+                       skip(1);\r
+                       proutn("COMMAND> ");\r
+                       if (scan() == IHEOL) continue;\r
+                       for (i=0; i < 26; i++)\r
+                               if (isit(commands[i]))\r
+                                       break;\r
+                       if (i < 26) break;\r
+                       for (; i < NUMCOMMANDS; i++)\r
+                               if (strcmp(commands[i], citem) == 0) break;\r
+                       if (i < NUMCOMMANDS) break;\r
+\r
+                       if (skill <= 2)  {\r
+                               prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");\r
+                               listCommands(TRUE);\r
+                       }\r
+                       else prout("UNRECOGNIZED COMMAND.");\r
+               }\r
+               switch (i) { /* command switch */\r
+                       case 0:                 // srscan\r
+                               srscan(1);\r
+                               break;\r
+                       case 1:                 // lrscan\r
+                               lrscan();\r
+                               break;\r
+                       case 2:                 // phasers\r
+                               phasers();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 3:                 // photons\r
+                               photon();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 4:                 // move\r
+                               warp(1);\r
+                               break;\r
+                       case 5:                 // shields\r
+                               sheild(1);\r
+                               if (ididit) {\r
+                                       attack(2);\r
+                                       shldchg = 0;\r
+                               }\r
+                               break;\r
+                       case 6:                 // dock\r
+                               dock();\r
+                               break;\r
+                       case 7:                 // damages\r
+                               dreprt();\r
+                               break;\r
+                       case 8:                 // chart\r
+                               chart(0);\r
+                               break;\r
+                       case 9:                 // impulse\r
+                               impuls();\r
+                               break;\r
+                       case 10:                // rest\r
+                               wait();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 11:                // warp\r
+                               setwrp();\r
+                               break;\r
+                       case 12:                // status\r
+                               srscan(3);\r
+                               break;\r
+                       case 13:                        // sensors\r
+                               sensor();\r
+                               break;\r
+                       case 14:                        // orbit\r
+                               orbit();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 15:                        // transport "beam"\r
+                               beam();\r
+                               break;\r
+                       case 16:                        // mine\r
+                               mine();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 17:                        // crystals\r
+                               usecrystals();\r
+                               break;\r
+                       case 18:                        // shuttle\r
+                               shuttle();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 19:                        // Planet list\r
+                               preport();\r
+                               break;\r
+                       case 20:                        // Status information\r
+                               srscan(2);\r
+                               break;\r
+                       case 21:                        // Game Report \r
+                               report(0);\r
+                               break;\r
+                       case 22:                        // use COMPUTER!\r
+                               eta();\r
+                               break;\r
+                       case 23:\r
+                               listCommands(TRUE);\r
+                               break;\r
+                       case 24:                // Emergency exit\r
+                               clearscreen();  // Hide screen\r
+                               freeze(TRUE);   // forced save\r
+                               exit(1);                // And quick exit\r
+                               break;\r
+                       case 25:\r
+                               probe();                // Launch probe\r
+                               break;\r
+                       case 26:                        // Abandon Ship\r
+                               abandn();\r
+                               break;\r
+                       case 27:                        // Self Destruct\r
+                               dstrct();\r
+                               break;\r
+                       case 28:                        // Save Game\r
+                               freeze(FALSE);\r
+                               if (skill > 3)\r
+                                       prout("WARNING--Frozen games produce no plaques!");\r
+                               break;\r
+                       case 29:                        // Try a desparation measure\r
+                               deathray();\r
+                               if (ididit) hitme = TRUE;\r
+                               break;\r
+                       case 30:                        // What do we want for debug???\r
+#ifdef DEBUG\r
+                               debugme();\r
+#endif\r
+                               break;\r
+                       case 31:                // Call for help\r
+                               help();\r
+                               break;\r
+                       case 32:\r
+                               alldone = 1;    // quit the game\r
+#ifdef DEBUG\r
+                               if (idebug) score();\r
+#endif\r
+                               break;\r
+                       case 33:\r
+                               helpme();       // get help\r
+                               break;\r
+               }\r
+               for (;;) {\r
+                       if (alldone) break;             // Game has ended\r
+#ifdef DEBUG\r
+                       if (idebug) prout("2500");\r
+#endif\r
+                       if (Time != 0.0) {\r
+                               events();\r
+                               if (alldone) break;             // Events did us in\r
+                       }\r
+                       if (d.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!\r
+                               atover(0);\r
+                               continue;\r
+                       }\r
+                       if (nenhere == 0) movetho();\r
+                       if (hitme && justin==0) {\r
+                               attack(2);\r
+                               if (alldone) break;\r
+                               if (d.galaxy[quadx][quady] == 1000) {   // went NOVA! \r
+                                       atover(0);\r
+                                       hitme = TRUE;\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       break;\r
+               }\r
+               if (alldone) break;\r
+       }\r
+}\r
+\r
+\r
+void main(int argc, char **argv) {\r
+       int i;\r
+       int hitme;\r
+       char ch;\r
+       prelim();\r
+\r
+       if (argc > 1) {\r
+               fromcommandline = 1;\r
+               line[0] = '\0';\r
+               while (--argc > 0) {\r
+                       strcat(line, *(++argv));\r
+                       strcat(line, " ");\r
+               }\r
+       }\r
+       else fromcommandline = 0;\r
+\r
+\r
+       while (TRUE) { /* Play a game */\r
+               setup();\r
+               if (alldone) {\r
+                       score();\r
+                       alldone = 0;\r
+               }\r
+               else makemoves();\r
+               skip(2);\r
+               stars();\r
+               skip(1);\r
+\r
+               if (tourn && alldone) {\r
+                       printf("Do you want your score recorded?");\r
+                       if (ja()) {\r
+                               chew2();\r
+                               freeze(FALSE);\r
+                       }\r
+               }\r
+               printf("Do you want to play again?");\r
+               if (!ja()) break;\r
+       }\r
+       skip(1);\r
+       prout("May the Great Bird of the Galaxy roost upon your home planet.");\r
+}\r
+\r
+\r
+void cramen(int i) {\r
+       /* return an enemy */\r
+       char *s;\r
+       \r
+       switch (i) {\r
+               case IHR: s = "Romulan"; break;\r
+               case IHK: s = "Klingon"; break;\r
+               case IHC: s = "Commander"; break;\r
+               case IHS: s = "Super-commander"; break;\r
+               case IHSTAR: s = "Star"; break;\r
+               case IHP: s = "Planet"; break;\r
+               case IHB: s = "Starbase"; break;\r
+               case IHBLANK: s = "Black hole"; break;\r
+               case IHT: s = "Tholean"; break;\r
+               case IHWEB: s = "Tholean web"; break;\r
+               default: s = "Unknown??"; break;\r
+       }\r
+       proutn(s);\r
+}\r
+\r
+void cramlc(int key, int x, int y) {\r
+       if (key == 1) proutn(" Quadrant");\r
+       else if (key == 2) proutn(" Sector");\r
+       proutn(" ");\r
+       crami(x, 1);\r
+       proutn(" - ");\r
+       crami(y, 1);\r
+}\r
+\r
+void crmena(int i, int enemy, int key, int x, int y) {\r
+       if (i == 1) proutn("***");\r
+       cramen(enemy);\r
+       proutn(" at");\r
+       cramlc(key, x, y);\r
+}\r
+\r
+void crmshp(void) {\r
+       char *s;\r
+       switch (ship) {\r
+               case IHE: s = "Enterprise"; break;\r
+               case IHF: s = "Faerie Queene"; break;\r
+               default:  s = "Ship???"; break;\r
+       }\r
+       proutn(s);\r
+}\r
+\r
+void stars(void) {\r
+       prouts("******************************************************");\r
+       skip(1);\r
+}\r
+\r
+double expran(double avrage) {\r
+       return -avrage*log(1e-7 + Rand());\r
+}\r
+\r
+double Rand(void) {\r
+       return rand()/(1.0 + (double)RAND_MAX);\r
+}\r
+\r
+void iran8(int *i, int *j) {\r
+       *i = Rand()*8.0 + 1.0;\r
+       *j = Rand()*8.0 + 1.0;\r
+}\r
+\r
+void iran10(int *i, int *j) {\r
+       *i = Rand()*10.0 + 1.0;\r
+       *j = Rand()*10.0 + 1.0;\r
+}\r
+\r
+void chew(void) {\r
+       linecount = 0;\r
+       linep = line;\r
+       *linep = 0;\r
+}\r
+\r
+void chew2(void) {\r
+       /* return IHEOL next time */\r
+       linecount = 0;\r
+       linep = line+1;\r
+       *linep = 0;\r
+}\r
+\r
+int scan(void) {\r
+       int i;\r
+       char *cp;\r
+\r
+       linecount = 0;\r
+\r
+       // Init result\r
+       aaitem = 0.0;\r
+       *citem = 0;\r
+\r
+       // Read a line if nothing here\r
+       if (*linep == 0) {\r
+               if (linep != line) {\r
+                       chew();\r
+                       return IHEOL;\r
+               }\r
+               gets(line);\r
+               linep = line;\r
+       }\r
+       // Skip leading white space\r
+       while (*linep == ' ') linep++;\r
+       // Nothing left\r
+       if (*linep == 0) {\r
+               chew();\r
+               return IHEOL;\r
+       }\r
+       if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {\r
+               // treat as a number\r
+           if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {\r
+               linep = line; // Invalid numbers are ignored\r
+               *linep = 0;\r
+               return IHEOL;\r
+           }\r
+           else {\r
+               // skip to end\r
+               linep += i;\r
+               return IHREAL;\r
+           }\r
+       }\r
+       // Treat as alpha\r
+       cp = citem;\r
+       while (*linep && *linep!=' ') {\r
+               if ((cp - citem) < 9) *cp++ = tolower(*linep);\r
+               linep++;\r
+       }\r
+       *cp = 0;\r
+       return IHALPHA;\r
+}\r
+\r
+int ja(void) {\r
+       chew();\r
+       while (TRUE) {\r
+               scan();\r
+               chew();\r
+               if (*citem == 'y') return TRUE;\r
+               if (*citem == 'n') return FALSE;\r
+               proutn("Please answer with \"Y\" or \"N\":");\r
+       }\r
+}\r
+\r
+void cramf(double x, int w, int d) {\r
+       char buf[64];\r
+       sprintf(buf, "%*.*f", w, d, x);\r
+       proutn(buf);\r
+}\r
+\r
+void crami(int i, int w) {\r
+       char buf[16];\r
+       sprintf(buf, "%*d", w, i);\r
+       proutn(buf);\r
+}\r
+\r
+double square(double i) { return i*i; }\r
+                                                                       \r
+static void clearscreen(void) {\r
+       /* Somehow we need to clear the screen */\r
+#ifdef __BORLANDC__\r
+       extern void clrscr(void);\r
+       clrscr();\r
+#else\r
+       proutn("\033[2J");      /* Hope for an ANSI display */\r
+#endif\r
+}\r
+\r
+/* We will pull these out in case we want to do something special later */\r
+\r
+void pause(int i) {\r
+       putchar('\n');\r
+       if (i==1) {\r
+               if (skill > 2)\r
+                       prout("[ANOUNCEMENT ARRIVING...]");\r
+               else\r
+                       prout("[IMPORTANT ANNOUNCEMENT ARRIVING -- HIT SPACE BAR TO CONTINUE]");\r
+               getch();\r
+       }\r
+       else {\r
+               if (skill > 2)\r
+                       proutn("[CONTINUE?]");\r
+               else\r
+                       proutn("[HIT SPACE BAR TO CONTINUE]");\r
+               getch();\r
+               proutn("\r                           \r");\r
+       }\r
+       if (i != 0) {\r
+               clearscreen();\r
+       }\r
+       linecount = 0;\r
+}\r
+\r
+\r
+void skip(int i) {\r
+       while (i-- > 0) {\r
+               linecount++;\r
+               if (linecount >= 23)\r
+                       pause(0);\r
+               else\r
+                       putchar('\n');\r
+       }\r
+}\r
+\r
+\r
+void proutn(char *s) {\r
+       fputs(s, stdout);\r
+}\r
+\r
+void prout(char *s) {\r
+       proutn(s);\r
+       skip(1);\r
+}\r
+\r
+void prouts(char *s) {\r
+       clock_t endTime;\r
+       /* print slowly! */\r
+       while (*s) {\r
+               endTime = clock() + CLOCKS_PER_SEC*0.05;\r
+               while (clock() < endTime) ;\r
+               putchar(*s++);\r
+               fflush(stdout);\r
+       }\r
+}\r
+\r
+void huh(void) {\r
+       chew();\r
+       skip(1);\r
+       prout("Beg your pardon, Captain?");\r
+}\r
+\r
+int isit(char *s) {\r
+       /* New function -- compares s to scaned citem and returns true if it\r
+          matches to the length of s */\r
+\r
+       return strncmp(s, citem, max(1, strlen(citem))) == 0;\r
+\r
+}\r
+\r
+#ifdef DEBUG\r
+void debugme(void) {\r
+       proutn("Reset levels? ");\r
+       if (ja() != 0) {\r
+               if (energy < inenrg) energy = inenrg;\r
+               shield = inshld;\r
+               torps = intorps;\r
+               lsupres = inlsr;\r
+       }\r
+       proutn("Reset damage? ");\r
+       if (ja() != 0) {\r
+               int i;\r
+               for (i=0; i <= ndevice; i++) if (damage[i] > 0.0) damage[i] = 0.0;\r
+               stdamtim = 1e30;\r
+       }\r
+       proutn("Toggle idebug? ");\r
+       if (ja() != 0) {\r
+               idebug = !idebug;\r
+               if (idebug) prout("Debug output ON");\r
+               else prout("Debug output OFF");\r
+       }\r
+       proutn("Cause selective damage? ");\r
+       if (ja() != 0) {\r
+               int i, key;\r
+               for (i=1; i <= ndevice; i++) {\r
+                       proutn("Kill ");\r
+                       proutn(device[i]);\r
+                       proutn("? ");\r
+                       chew();\r
+                       key = scan();\r
+                       if (key == IHALPHA &&  isit("y")) {\r
+                               damage[i] = 10.0;\r
+                               if (i == DRADIO) stdamtim = d.date;\r
+                       }\r
+               }\r
+       }\r
+       proutn("Examine/change events? ");\r
+       if (ja() != 0) {\r
+               int i;\r
+               for (i = 1; i < NEVENTS; i++) {\r
+                       int key;\r
+                       if (future[i] == 1e30) continue;\r
+                       switch (i) {\r
+                               case FSNOVA:  proutn("Supernova       "); break;\r
+                               case FTBEAM:  proutn("T Beam          "); break;\r
+                               case FSNAP:   proutn("Snapshot        "); break;\r
+                               case FBATTAK: proutn("Base Attack     "); break;\r
+                               case FCDBAS:  proutn("Base Destroy    "); break;\r
+                               case FSCMOVE: proutn("SC Move         "); break;\r
+                               case FSCDBAS: proutn("SC Base Destroy "); break;\r
+                       }\r
+                       cramf(future[i]-d.date, 8, 2);\r
+                       chew();\r
+                       proutn("  ?");\r
+                       key = scan();\r
+                       if (key == IHREAL) {\r
+                               future[i] = d.date + aaitem;\r
+                       }\r
+               }\r
+               chew();\r
+       }\r
+}\r
+                       \r
+\r
+#endif\r
diff --git a/sst.doc b/sst.doc
new file mode 100644 (file)
index 0000000..afc36c3
--- /dev/null
+++ b/sst.doc
@@ -0,0 +1,1527 @@
+                SSSSS   U   U   PPPPP   EEEEE   RRRRR\r
+                S       U   U   P   P   E       R   R\r
+                SSSSS   U   U   PPPPP   EEEE    RRRRR\r
+                    S   U   U   P       E       R  R\r
+                SSSSS   UUUUU   P       EEEEE   R   R\r
+\r
+\r
+                 SSSSSSS  TTTTTTTT     A     RRRRRRR\r
+                SSSSSSSS  TTTTTTTT    AAA    RRRRRRRR\r
+               SS            TT       AAA    RR     RR\r
+               SSSSSSS       TT      AA AA   RR     RR\r
+                SSSSSSS      TT      AA AA   RRRRRRRR\r
+                      SS     TT     AAAAAAA  RRRRRRR\r
+                      SS     TT     AAAAAAA  RR   RR\r
+               SSSSSSSS      TT    AA     AA RR    RR\r
+               SSSSSSS       TT    AA     AA RR     RR\r
+    \r
+    \r
+    \r
+                TTTTTTTT RRRRRRR   EEEEEEEEE KK     KK\r
+                TTTTTTTT RRRRRRRR  EEEEEEEEE KK    KK\r
+                   TT    RR     RR EE        KK   KK\r
+                   TT    RR     RR EEEEEE    KKKKKK\r
+                   TT    RRRRRRRR  EEEEEE    KKKKK\r
+                   TT    RRRRRRR   EE        KK  KK\r
+                   TT    RR   RR   EE        KK   KK\r
+                   TT    RR    RR  EEEEEEEEE KK    KK\r
+                   TT    RR     RR EEEEEEEEE KK     KK\r
+\r
+\r
+                     Produced For Your Enjoyment\r
+\r
+                                 By\r
+\r
+                            David Matuszek\r
+                                 and\r
+                            Paul Reynolds\r
+\r
+                        With Modifications By\r
+                              Don Smith\r
+\r
+                            Resurected By\r
+                               Tom Almy\r
+                                  \r
+     Permission is hereby granted for the copying, distribution,\r
+ modification and use of this program and associated documentation\r
+ for recreational purposes, provided that all references to the\r
+ authors are retained.  However, permission is not and will not be\r
+ granted for the sale or promotional use of this program or program\r
+ documentation, or for use in any situation in which profit may be\r
+ considered an objective, since it is the desire of the authors to\r
+ respect the copyrights of the originators of Star Trek.\r
+\r
+\f             ----------TABLE OF CONTENTS----------\r
+\r
+\r
+\r
+     SECTION                                               PAGE\r
+\r
+\r
+       INTRODUCTION TO THE GAME . . . . . . . . . . . . . .   1\r
+\r
+       HOW TO ISSUE COMMANDS. . . . . . . . . . . . . . . .   4\r
+\r
+       DESCRIPTIONS OF COMMANDS . . . . . . . . . . . . . .   5\r
+\r
+            SHORT-RANGE SCAN. . . . . . . . . . . . . . . .   5\r
+            STATUS REPORT . . . . . . . . . . . . . . . . .   6\r
+            LONG-RANGE SCAN . . . . . . . . . . . . . . . .   7\r
+            STAR CHART. . . . . . . . . . . . . . . . . . .   8\r
+            DAMAGE REPORT . . . . . . . . . . . . . . . . .   8\r
+            MOVE UNDER WARP DRIVE . . . . . . . . . . . . .   9\r
+            WARP FACTOR . . . . . . . . . . . . . . . . . .  10\r
+            IMPULSE ENGINES . . . . . . . . . . . . . . . .  10\r
+            DEFLECTOR SHIELDS . . . . . . . . . . . . . . .  11\r
+            PHASERS . . . . . . . . . . . . . . . . . . . .  12\r
+            REPORT. . . . . . . . . . . . . . . . . . . . .  13\r
+            COMPUTER. . . . . . . . . . . . . . . . . . . .  13\r
+            PHOTON TORPEDOES. . . . . . . . . . . . . . . .  14\r
+            DOCK AT STARBASE. . . . . . . . . . . . . . . .  15\r
+            REST. . . . . . . . . . . . . . . . . . . . . .  15\r
+            CALL STARBASE FOR HELP. . . . . . . . . . . . .  15\r
+            ABANDON SHIP. . . . . . . . . . . . . . . . . .  16\r
+            SELF-DESTRUCT . . . . . . . . . . . . . . . . .  16\r
+            TERMINATE THE CURRENT GAME. . . . . . . . . . .  16\r
+            SENSOR-SCAN . . . . . . . . . . . . . . . . . .  17\r
+            ENTER STANDARD ORBIT. . . . . . . . . . . . . .  17\r
+            TRANSPORTER-TRAVEL. . . . . . . . . . . . . . .  17\r
+            SHUTTLE CRAFT . . . . . . . . . . . . . . . . .  18\r
+            MINE DILITHIUM CRYSTALS . . . . . . . . . . . .  18\r
+            LOAD DILITHIUM CRYSTALS . . . . . . . . . . . .  18\r
+            PLANET REPORT . . . . . . . . . . . . . . . . .  19\r
+            FREEZE. . . . . . . . . . . . . . . . . . . . .  19\r
+            REQUEST . . . . . . . . . . . . . . . . . . . .  20\r
+            EXPERIMENTAL DEATH RAY. . . . . . . . . . . . .  20\r
+            LAUNCH DEEP SPACE PROBE . . . . . . . . . . . .  21\r
+            EMERGENCY EXIT. . . . . . . . . . . . . . . . .  21\r
+            ASK FOR HELP. . . . . . . . . . . . . . . . . .  21\r
+\r
+\r
+       MISCELLANEOUS NOTES. . . . . . . . . . . . . . . . .  22\r
+\r
+       SCORING. . . . . . . . . . . . . . . . . . . . . . .  23\r
+\r
+       HANDY REFERENCE PAGE . . . . . . . . . . . . . . . .  24\r
+\r
+       MODIFICATIONS. . . . . . . . . . . . . . . . . . . .  25\r
+\r
+       ACKNOWLEDGMENTS. . . . . . . . . . . . . . . . . . .  26\r
+\r
+       REFERENCES . . . . . . . . . . . . . . . . . . . . .  26\r
+\r
+\r
+\r
+\f               -----INTRODUCTION TO THE GAME-----                       1\r
+\r
+\r
+The Organian Peace Treaty has collapsed, and the Federation is at war\r
+with the Klingon Empire.  Joining the Klingons against the Federation\r
+are the members of the "Romulan Star Empire."  As commander of the\r
+Starship U.S.S. Enterprise, your job is to wipe out the Klingon\r
+invasion fleet and make the galaxy safe for democracy.\r
+\r
+Your battleground is the entire galaxy, which for convenience is\r
+divided up into eight rows of eight quadrants each, like a\r
+checkerboard.  Rows are numbered from top to bottom, and columns are\r
+numbered left to right, so quadrant 1 - 8 would be in the upper right\r
+hand corner of the galaxy.\r
+\r
+During battle you will be concerned only with those enemies that\r
+occupy the same quadrant as yourself.  Quadrants are divided up into\r
+sectors: ten rows of ten sectors each. Sectors are numbered in the\r
+same way as quadrants, so the sector in the upper right corner is\r
+sector 1 - 10.  You have a short-range scanner which allows you to\r
+look at the entire quadrant in a single display.\r
+\r
+Enemies recharge during your absence.  If you leave a quadrant\r
+containing a weakened enemy, when you return to that quadrant he will\r
+be strong again.  Also, each time you enter a quadrant, the positions\r
+of everthing in the quadrant (except your ship) are randomized, to\r
+save you the trouble of trying to remember where everything in the\r
+quadrant is.  Notice that this refers only to the positions of things\r
+in the quadrant--the numbers of each kind of thing are not changed\r
+(except for black holes and the Super-commander, which move around\r
+the galaxy).  If you kill something, it stays dead.\r
+\r
+The Romulans are not as serious a threat to the Federation as the\r
+Klingons.  For one thing, there are not as many of them.  For\r
+another, the Romulans are not as treacherous.  However, Romulans are\r
+not to be trifled with, especially when you are in violation of the\r
+"Romulan Neutral Zone."\r
+\r
+There are two kinds of Klingons: Ordinary Klingons, which are bad\r
+enough, and Klingon Commanders, which are even worse.  Commanders are\r
+about three times stronger than ordinary Klingons.  Commanders are\r
+more resistant to your weapons.  Commanders can move about during\r
+battle while Ordinary Klingons stay put.  And finally, Commanders\r
+have a thing called a "long-range tractor beam" which they can use,\r
+at random intervals, to yank you away from what you are doing into\r
+their quadrant, to do battle with them.  There is also a special\r
+commander, called the "Super-commander."  This character is so bad he\r
+is reserved for the Good, Expert, and Emeritus games.  Fortunately,\r
+there is just one Super-commander in a game.  In addition to the\r
+undesirable traits of Commanders, he can move from quadrant to\r
+quadrant at will, seeking out and destroying your starbases and any\r
+helpful planets he runs across.  He also has a spy planted aboard\r
+your ship, giving him valuable information about your condition.\r
+Using this information, he can do dastardly things like tractor beam\r
+your ship when you are in bad shape.  And once you've been tractor\r
+beamed by the Super-commander ---\r
+\f                                                                        2\r
+But the advantages are not all on the side of the enemy.  Your ship\r
+is more powerful, and has better weapons.  Besides, in the this\r
+galaxy there are from two to five starbases, at which you can stop to\r
+refuel and lick your wounds, safe from phaser attack or tractor\r
+beams.  But you had best not dally there too long, since time is not\r
+on your side.  The Klingons are not just after you; they are\r
+attacking the entire Federation.  There is always a finite "time\r
+left," which is how much longer the Federation can hold out if you\r
+just sit on your fat behind and do nothing.  As you wipe out\r
+Klingons, you reduce the rate at which the invasion fleet weakens the\r
+Federation, and so the time left until the Federation collapses may\r
+actually increase.  Since Klingons are the main threat to the\r
+Federation, the Romulans do not figure into the "time left."  In\r
+fact, you need not kill all the Romulans to win.  If you can get all\r
+the Klingons, the Federation will abide forever, and you have won the\r
+game.\r
+\r
+Space is vast, and it takes precious time to move from one place to\r
+another.  In comparison, other things happen so quickly that we\r
+assume the take no time at all. Two ways that time can pass are when\r
+you move, or when you issue a command to sit still and rest for a\r
+period of time.  You will sometimes want to do the latter, since the\r
+various devices aboard your starship may be damaged and require time\r
+to repair.  Of course, repairs can be made more quickly at a starbase\r
+than than can in flight.\r
+\r
+In addition to Klingons, Romulans, and starbases, the galaxy contains\r
+(surprise) stars.  Mostly, stars are a nuisance and just get in your\r
+way.  You can trigger a star into going nova by shooting one of your\r
+photon torpedoes at it.  When a star novas, it does a lot of dammage\r
+to anything immediately adjacent to it.  If another star is adjacent\r
+to a nova, it too will go nova.  Stars may also occasionally go\r
+supernova; a supernova in a quadrant destroys everything in the\r
+quadrant andmakes the quadrant permanently uninhabitable.  You may\r
+"jump over" a quadrant containing a supernova when you move, but you\r
+should not stop there.\r
+\r
+Supernovas may happen spontaneously, without provocation.  If a\r
+supernova occurs in the same quadrant you are in, your starship has\r
+an "emergency automatic override" which picks some random direction\r
+and some random warp factor, and tries to throw you clear of the\r
+supernova. If the supernova occurs in some other quadrant, you just\r
+get a warning message from starfleet about it (provided, of course,\r
+that your subspace radio is working).\r
+\r
+Also a few planets are scattered through the galaxy.  These can\r
+sometimes be a great help since some of them will have "dilithium\r
+crystals," which are capable of replenishing the ship's energy\r
+supply.  You can either beam down to the planet surface using the\r
+transporter, or take the shuttle craft "Galileo."\r
+\r
+Finally, each quadrant will contain from zero to three black holes.\r
+These can deflect or swallor torpedoes passing near them. They also\r
+swallow enemy ships knocked into them.  If your ship enters one - - -\r
+\f                                                                        3\r
+Star Trek is a rich game, full of detail.  These instructions are\r
+written at a moderate level--no attempt has been made fully to\r
+describe everything about the game, but there is quite a bit more\r
+here than you need to get started.  If you are new to the game, just\r
+get a rough idea of the kinds of commands available, and start\r
+playing.  After a game or two you will have learned everthing\r
+important, and the detailed command descriptions which follow will be\r
+a lot more meaningful to you.\r
+\r
+You have weapons: phasers and photon torpedoes. You have a defense:\r
+deflector shields.  You can look at things: long-range scaners,\r
+short-range scanners, and a star chart.  You can move about, under\r
+warp drive or impulse power.  You can also dock at a starbase, rest\r
+while repairs are being made, abandon ship, self destruct, or give up\r
+and start a new game.\r
+\r
+The Klingons are waiting.\r
+\r
+\r
+\f                 -----HOW TO ISSUE COMMANDS-----                        4\r
+\r
+When the game is waiting for you to enter a command it will print out\r
+\r
+       COMMAND>\r
+\r
+You may then type in your command.  All you have to remember for each\r
+command is the mnemonic. For example, if you want to move straight up\r
+one quadrant, you can type in the mnemonic (case insensitive)\r
+\r
+       move\r
+\r
+and the computer will prompt you with\r
+\r
+       Manual or automatic- \r
+\r
+Say you type in "manual". The computer then responds\r
+\r
+       X and Y displacements- \r
+\r
+Now you type in "0 1" which specifies an X movement of zero and a Y\r
+movement of one.\r
+\r
+When you have learned the commands, you can avoid being prompted\r
+simply by typing in the information without waiting to be asked for\r
+it. For example, in the above example, you could simply type in\r
+\r
+       move manual 0 1\r
+\r
+and it will be done.  Or you could type in\r
+\r
+       move manual\r
+\r
+and when the computer responds with the displacement prompt, you can type in\r
+\r
+       0 1\r
+\r
+and it will understand.\r
+\r
+You can abbreviate most mnemonics.  For "move", you can use any of\r
+\r
+       move mov mo m\r
+\r
+successfully.  For your safety, certain critical commands (such as to\r
+abandon ship) must be written out in full.  Also, in a few cases two\r
+or more commands begin with the same letter, and in this case that\r
+letter refers to a particular one of the commands; to get the other,\r
+your abbreviation must be two or more characters long.  This sounds\r
+complicated, but you will learn the abbreviations quickly enough.\r
+\r
+What this all boils down to is:\r
+       (1)  You can abbreviate practically anything\r
+       (2)  If you forget, the computer will proompt you\r
+       (3)  If you remember, you can type it all on one line\r
+\r
+If you are part way through entering a command and you change your\r
+minde, you can cancel the command by typing -1 as one of the\r
+parameters, with the exception of the manual move command.\r
+\r
+If anything is not clear to you, experiment.  The worst you can do is\r
+lose a game or two.\r
+\r
+\f-----DESCRIPTION OF COMMANDS-----                                       5\r
+\r
+ ********************\r
+ * SHORT-RANGE SCAN *\r
+ ********************\r
+\r
+  Mnemonic:  SRSCAN\r
+  Shortest abbreviation:  S\r
+  Full commands:  SRSCAN\r
+                  SRSCAN NO\r
+                  SRSCAN CHART\r
+\r
+The short-range scan gives you a considerable amount of information\r
+about the quadrant your starship is in.  A short-range scan is best\r
+described by an example.\r
+\r
+         1 2 3 4 5 6 7 8 9 10\r
+      1  * . . . . R . . . .  Stardate      2516.3\r
+      2  . . . E . . . . . .  Condition     RED  \r
+      3  . . . . . * . B . .  Position      5 - 1, 2 - 4\r
+      4  . . . S . . . . . .  Life Support  DAMAGED, Reserves=2.30\r
+      5  . . . . . . . K . .  Warp Factor   5.0\r
+      6  . K .   . . . . * .  Energy        2176.24\r
+      7  . . . . . P . . . .  Torpedoes     3\r
+      8  . . . . * . . . . .  Shields       UP, 42% 1050.0 units\r
+      9  . * . . * . . . C .  Klingons Left 12\r
+     10  . . . . . . . . . .  Time Left     3.72\r
+\r
+\r
+The left part is a picture of the quadrant.  The E at sector 2 - 4\r
+represents the Enterprise; the B at sector 3 - 8 is a starbase.\r
+There are ordinary Klingons (K) at sectors 5 - 8 and 6 - 2, and a\r
+Klingon Commander (C) at 9 - 9.  The (GULP) "Super-commander" (S) is\r
+occupies sector 4 - 4, and a Romulan (R) is at 1 - 6.  A planet (P)\r
+is at sector 7 - 6.  There are also a large number of stars (*). The\r
+periods (.) are just empty space--they are printed to help you get\r
+your bearings.  Sector 6 - 4 contains a black hole ( ).\r
+\r
+The information on the right is assorted status information. You can\r
+get this alone with the STATUS command.  The status information will\r
+be absent if you type "N" after SRSCAN.  Otherwise status information\r
+will be presented.\r
+\r
+If you type "C" after SRSCAN, you will be given a short-range scan\r
+and a Star Chart.\r
+\r
+Short-range scans are free.  That is, they use up no energy and no\r
+time.  If you are in battle, doing a short-range scan does not give\r
+the enemies another chance to hit you.  You can safely do a\r
+short-range scan anytime you like.\r
+\r
+If your short-range sensors are damaged, this command will only show\r
+the contents of adjacent sectors.\r
+\r
+\f                                                                        6\r
+ *****************\r
+ * STATUS REPORT *\r
+ *****************\r
+\r
+  Mnemonic:  STATUS\r
+  Shortest abbreviation: ST\r
+\r
+This command gives you information about the current state of your\r
+starship as follows:\r
+\r
+  STARDATE - The current date. A stardate is the same as a day.\r
+\r
+  CONDITION - There are four possible conditions:\r
+       DOCKED - docked at starbase.\r
+       RED    - in battle.\r
+       YELLOW - low on energy (<1000 units)\r
+        GREEN  - none of the above\r
+\r
+  POSITION - Quadrant is given first, then sector\r
+  \r
+  LIFE SUPPORT - If "ACTIVE" then life support systems are\r
+       functioning normally. If on "RESERVES" the number is how many\r
+       stardates your reserve food, air, etc. will last--you must\r
+       get repairs made or get to starbase before your reserves run\r
+       out. \r
+\r
+  WARP FACTOR - What your warp factor is currently set to.\r
+\r
+  ENERGY - The amount of energy you have left. If it drops to zero,\r
+       you die.\r
+\r
+  TORPEDOES - How many photon torpedoes you have left.\r
+\r
+  SHIELDS - Whether your shields are up or down, how strong they are\r
+       (what percentage of a hit they can deflect), and shield\r
+       energy. \r
+\r
+  KLINGONS LEFT - How many of the Klingons are still out there.\r
+\r
+  TIME LEFT - How long the Federation can hold out against the\r
+       present number of Klingons; that is, how long until the end\r
+       if you do nothing in the meantime.  If you kill Klingons\r
+       quickly, this number will go up--if not, it will go down.  If\r
+       it reaches zero, the federation is conquered and you lose.\r
+\r
+Status information is free--it uses no time or energy, and if you are\r
+in battle, the Klingons are not given another chance to hit you.\r
+\r
+Status information can also be obtained by doing a short-range scan.\r
+See the SRSCAN command for details.\r
+\r
+Each item of information can be obtained singly by requesting it.\r
+See REQUEST command for details.\r
+\r
+\f                                                                        7\r
+ *******************\r
+ * LONG-RANGE SCAN *\r
+ *******************\r
+\r
+  Mnemonic:  LRSCAN\r
+  Shortest abbreviation:  L\r
+\r
+A long-range scan gives you general information about where you are\r
+and what is around you.  Here is an example output.\r
+\r
+    Long-range scan for Quadrant 5 - 1\r
+       -1  107  103\r
+       -1  316    5\r
+       -1  105 1000\r
+\r
+This scan says that you are in row 5, column 1 of the 8 by 8 galaxy.\r
+The numbers in the scan indicate how many of each kind of thing there\r
+is in your quadrant and all adjacent quadrants.  The digits are\r
+interpreted as follows.\r
+\r
+    Thousands digit:  1000 indicates a supernova (only)\r
+    Hundreds digit:   number of Klingons present\r
+    Tens digit:       number of starbases present\r
+    Ones digit:       number of stars present\r
+\r
+For example, in your quadrant (5 - 1) the number is 316, which\r
+indicates 3 Klingons, 1 starbase, and 6 stars.  The long-range\r
+scanner does not distinguish between ordinary Klingons and Klingon\r
+command ships.  If there is a supernova, as in the quadrant below and\r
+to your right (quadrant 6 - 2), there is nothing else in the\r
+quadrant. \r
+\r
+Romulans possess a "cloaking device" which prevents their detection\r
+by long-range scan.  Because of this fact, Starfleet Command is never\r
+sure how many Romulans are "out there".  When you kill the last\r
+Klingon, the remaining Romulans surrender to the Federation.\r
+\r
+Planets are also undetectable by long-range scan.  The only way to\r
+detect a planet is to find it in your current quadrant with the\r
+short-range sensors.\r
+\r
+Since you are in column 1, there are no quadrants to your left. The\r
+minus oones indicate the negative energy barrier at the edge of the\r
+galaxy, which you are not permitted to cross.\r
+\r
+Long-range scans are free.  They use up no energy or time, and can be\r
+done safely regardless of battle conditions.\r
+\f                                                                        8\r
+ **************\r
+ * STAR CHART *\r
+ **************\r
+\r
+  Mnemonic:  CHART\r
+  Shortest abbreviation:  C\r
+\r
+As you proceed in the game, you learn more and more about what things\r
+are where in the galaxy. When ever you first do a scan in a quadrant,\r
+telemetry sensors are ejected which will report any changes in the\r
+quadrant(s) back to your ship, providing the sub-space radio is\r
+working. Spock will enter this information in the chart. If the radio\r
+is not working, Spock can only enter new information discovered from\r
+scans, and information in other quadrants may be obsolete.\r
+\r
+The chart looks like an 8 by 8 array of numbers.  These numbers are\r
+interpreted exactly as they are on a long-range scan. A period (.) in\r
+place of a digit means you do not know that information yet.  For\r
+example, ... means you know nothing about the quadrant, while .1.\r
+menas you know it contains a base, but an unknown number of Klingons\r
+and stars.\r
+\r
+Looking at the star chart is a free operation.  It costs neither time\r
+nor energy, and can be done safely whether in or out of battle.\r
+\r
+\r
+ *****************\r
+ * DAMAGE REPORT *\r
+ *****************\r
+\r
+  Mnemonic:  DAMAGES\r
+  Shortest abbreviation:  DA\r
+\r
+At any time you may ask for a damage report to find out what devices\r
+are damaged and how long it will take to repair them.  Naturally,\r
+repairs proceed faster at a starbase.\r
+\r
+If you suffer damages while moving, it is possible that a subsequent\r
+damage report will not show any damage.  This happens if the time\r
+spent on the move exceeds the repair time, since in this case the\r
+damaged devices were fixed en route.\r
+\r
+Damage reports are free.  They use no energy or time, and can be done\r
+safely even in the midst of battle.\r
+\r
+\f                                                                        9\r
+ *************************\r
+ * MOVE UNDER WARP DRIVE *\r
+ *************************\r
+\r
+  Mnemonic:  MOVE\r
+  Shortest abbreviation:  M\r
+  Full command:  MOVE MANUAL <displacement>\r
+                 MOVE AUTOMATIC <destination>\r
+\r
+This command is the usual way to move from one place to another\r
+within the galaxy.  You move under warp drive, according to the\r
+current warp factor (see "WARP FACTOR").\r
+\r
+There are two command modes for movement: MANUAL and AUTOMATIC.  The\r
+manual mode requires the following format:\r
+\r
+       MOVE MANUAL <deltax> <deltay>\r
+\r
+<deltax> and <deltay> are the horizontal and vertical displacements\r
+for your starship, in quadrants; a displacement of one sector is 0.1\r
+quadrants.  Specifying <deltax> and <deltay> causes your ship to move\r
+in a straight line to the specified destination. If <deltay> is\r
+omitted, it is assumed zero. For example, the shortest possible\r
+command to move one sector to the right would be\r
+\r
+       M M .1\r
+\r
+The following examples of manual movement refer to the short-range\r
+scan shown earlier.\r
+\r
+  Destination Sector   Manual Movement command\r
+       3 - 1                   M M -.3 -.1\r
+       2 - 1                   M M -.3\r
+       1 - 2                   M M -.2 .1\r
+       1 - 4                   M M 0 .1\r
+  (leaving quadrant)           M M 0 .2\r
+\r
+\r
+The automatic mode is as follows:\r
+\r
+       MOVE AUTOMATIC <qrow> <qcol> <srow> <scol>\r
+\r
+where <qrow> and <qcol> are the row and column numbers of the\r
+destination quadrant, and <srow> and <scol> are the row and column\r
+numbers of thedestination sector in that quadrant.  This command also\r
+moves your ship in a straight line path to the destination.  For\r
+moving within a quadrant, <qrow> and <qcol> may be omitted. For\r
+example, to move to sector 2 - 9 in the current quadrant, the\r
+shortest command would be\r
+\r
+       M A 2 9\r
+\r
+To move to quadrant 3 - 7, sector 5 - 8, type\r
+\r
+       M A 3 7 5 8\r
+\r
+and it will be done.  In automatic mode, either two or four numbers\r
+must be supplied.\r
+\f                                                                       10\r
+Automatic mode utilizes the ship's "battle computer."  If the\r
+computer is damaged, manual movement must be used.\r
+\r
+If warp engines are damaged less than 10 stardates (undocked) you can\r
+still go warp 4.\r
+\r
+It uses time and energy to move.  How much time and how much energy\r
+depends on your current warp factor, the distance you move, and\r
+whether your shields are up.  The higher the warp factor, the faster\r
+you move, but higher warp factors require more energy.  You may move\r
+with your shields up, but this doubles the energy required.\r
+\r
+You can move within a quadrant without being attacked if you just\r
+entered the quadrant or have bee attacked since your last move\r
+command.  This enables you to move and hit them before they\r
+retaliate. \r
+\r
+\r
+ ***************\r
+ * WARP FACTOR *\r
+ ***************\r
+\r
+  Mnemonic:  WARP\r
+  Shortest abbreviation:  W\r
+  Full command:  WARP <number>\r
+\r
+Your warp factor controls the speed of your starship.  The larger the\r
+warp factor, the faster you go and the more energy you use.\r
+\r
+Your minimum warp factor is 1.0 and your maximum warp factor is 10.0\r
+(which is 100 times as fast and uses 1000 times as much energy).  At\r
+speeds above warp 6 there is some danger of causing damage to your\r
+warp engines; this damage is larger at higher warp factors and also\r
+depends on how far you go at that warp factor.\r
+\r
+At exactly warp 10 there is some probability of entering a so-called\r
+"time warp" and being thrown foward or backward in time.  The farther\r
+you go at warp 10, the greater is the probability of entering the\r
+time warp.\r
+\r
+\r
+ *******************\r
+ * IMPULSE ENGINES *\r
+ *******************\r
+\r
+  Mnemonic:  IMPULSE\r
+  Shortest abbreviation:  I\r
+  Full command:  IMPULSE MANUAL <displacement>\r
+                 IMPULSE AUTOMATIC <destination>\r
+\r
+The impulse engines give you a way to move when your warp engines are\r
+damaged.  They move you at a speed of 0.95 sectors per stardate,\r
+which is the equivalent of a warp factor of about 0.975, so they are\r
+much too slow to use except in emergencies.\r
+\r
+Movement commands are indicated just as in the "MOVE" command.\r
+\r
+The impulse engines require 20 units of energy to engage, plus 10\r
+units per sector (100 units per quadrant) traveled. It does not cost\r
+extra to move with the shields up.\r
+\f                                                                       11\r
+ *********************\r
+ * DEFLECTOR SHIELDS *\r
+ *********************\r
+\r
+  Mnemonic:  SHIELDS\r
+  Shortest abbreviation:  SH\r
+  Full commands:  SHIELDS UP\r
+                  SHIELDS DOWN\r
+                  SHIELDS TRANSFER <amount of energy to transfer>\r
+\r
+Your deflector shields are a defensive device to protect you from\r
+Klingon attacks (and nearby novas).  As the shields protect you, they\r
+gradually weaken.  A shield strength of 75%, for example, means that\r
+the next time a Klingon hits you, your shields will deflect 75% of\r
+the hit, and let 25% get through to hurt you.\r
+\r
+It costs 50 units of energy to raise shields, nothing to lower them.\r
+You may move with your shields up; this costs nothing under impulse\r
+power, but doubles the energy required for warp drive.\r
+\r
+Each time you raise or lower yoru shields, the Klingons have another\r
+chance to attack.  Since shields do not raise and lower\r
+instantaneously, the hits you receive will be intermediate between\r
+what they would be if the shields were completely up or completely\r
+down. \r
+\r
+You may not fire phasers through your shields.  However you may use\r
+the "high-speed shield control" to lower shields, fire phasers, and\r
+raise the shields again before the Klingons can react.  Since rapid\r
+lowering and raising of the shields requires more energy than normal\r
+speed operation, it costs you 200 units of energy to activate this\r
+control.  It is automatically activated when you fire phasers while\r
+shields are up.  You may fire photon torpedoes, but they may be\r
+deflected considerably from their intended course as they pass\r
+through the shields (depending on shield strength).\r
+\r
+You may transfer energy beteen the ship's energy (given as "Energy"\r
+in the status) and the shields.  Thee word "TRANSFER" may be\r
+abbreviated "T".  The ammount of energy to transfer is the number of\r
+units of energy you wish to take from the ship's energy and put into\r
+the shields.  If you specify an negative number, energy is drained\r
+from the shields to the ship.  Transfering energy constitutes a turn.\r
+If you transfer energy to the shields while you are under attack,\r
+they will be at the new energy level when you are next hit.\r
+\r
+Enemy torpedoes hitting your ship explode on your shields (if they\r
+are up) and have essentially the same effect as phaser hits.\r
+\f                                                                       12\r
+ ***********\r
+ * PHASERS *\r
+ ***********\r
+\r
+  Mnemonic:  PHASERS\r
+  Shortest abbreviation:  P\r
+  Full commands:  PHASERS AUTOMATIC <AMOUNT TO FIRE> <NO>\r
+                  PHASERS <AMOUNT TO FIRE> <NO>\r
+                  PHASERS MANUAL <NO> <AMOUNT 1> <AMOUNT 2>...<AMOUNT N> \r
+\r
+Phasers are energy weapons. As you fire phasers at Klingons, you\r
+specify an "amount to fire" which is drawn from your energy reserves.\r
+The amount of total hit required to kill an enemy is partly random.\r
+but also depends on skill level.\r
+\r
+The average hit required to kill an ordinary Klingon varies from 200\r
+units in the Novice game to 250 units in the Emeritus game.\r
+Commanders normally require from 600 (Novice) to 700 (Emeritus).  The\r
+Super-commander requres from 875 (Good) to 1000 (Emeritus). Romulans\r
+require an average of 350 (Novice) to 450 (Emeritus).\r
+\r
+Hits on enemies are cumulative, as long as you don't leave the\r
+quadrant. \r
+\r
+In general, not all that you fire will reach the Klingons.  The\r
+farther away they are, the less phaser energy will reach them. If a\r
+Klingon is adjacent to you, he will receive about 90% of the phaser\r
+energy directed at him; a Klingon 5 sectors away will receive about\r
+60% and a Klingon 10 sectors away will receive about 35%. There is\r
+some randomness involved, so these figures are not exact. Phasers\r
+have no effect beyond the boundaries of the quadrant you are in.\r
+\r
+Phasers may overheat (and be damaged) if you fire too large a burst\r
+at once. Firing up to 1500 units is safe.  From 1500 on up the\r
+probability of overheat increases with the amount fired.\r
+\r
+If phaser firing is automatic, the computer decides how to divide up\r
+your <amount to fire> among the Klingons present.  If phaser firing\r
+is manual, you specify how much energy to fire at each Klingon\r
+present (nearest first), rather than just specifying a total amount.\r
+You can abreviate "MANUAL" and "AUTOMATIC" to one or more letters; if\r
+you mention neither, automatic fire is usually assumed.\r
+\r
+Battle computer information is available by firing phasers manually,\r
+and allowing the computer to prompt you.  If you enter zero for the\r
+amount to fire at each enemy, you will get a complete report, without\r
+cost.  The battle computer will tell you how much phaser energy to\r
+fire at each enemy for a sure kill.  This information appears in\r
+parentheses prior to the prompt for each enemy.  SInce the amount is\r
+computed from sensor data, if either the computer or the S.R. sensors\r
+are damaged, this information will be unavailable, and phasers must\r
+be fired manually.\r
+\f                                                                       13\r
+A safety interlock prevents phasers from being fired through the\r
+shields.  If this were not so, the shields would contain your fire\r
+and you would fry yourself.  However, you may utilize the\r
+"high-speed shield control" to drop shields, fire phasers, and raise\r
+shields before the enemy can react.  Since it takes more energy to\r
+work the shields rapidly with a shot, it costs you 200 units of\r
+energy each time you activate this control.  It is automatically\r
+activated when you fire phasers while the shields are up. By\r
+specifying the <no> option, shields are not raised after firing.\r
+\r
+Phasers have no effect on starbases (which are shielded) or on stars.\r
+\r
+\r
+ **********\r
+ * REPORT *\r
+ **********\r
+\r
+  Mnemonic:  REPORT\r
+  Shortest abbreviation: REP\r
+\r
+This command supplies you with information about the state of the\r
+current game.  Its purpose is to remind you of things that you have\r
+learned during play, but may have forgotten, and cannot otherwise\r
+retrieve if you are not playing at a hard-copy terminal.\r
+\r
+     You are told the following things:\r
+\r
+       . The length and skill level of the game you are playing\r
+       . The original number of Klingons\r
+       . How many Klingons you have destroyed\r
+       . Whether the Super-Commander has been destroyed\r
+       . How many bases have been destroyed\r
+       . How many bases are left\r
+       . What bases (if any) are under attack; your subspace radio\r
+         must have been working since the attack to get this \r
+         information.\r
+       . How many casualties you have suffered\r
+       . How many times you have called for help.\r
+\r
+This same information is automatically given to you when you start to\r
+play a frozen game.\r
+\r
+\r
+ ************\r
+ * COMPUTER *\r
+ ************\r
+\r
+  Mnemonic:  COMPUTER\r
+  Shortest abbreviation: CO\r
+\r
+This command allows using the ship's computer (if functional) to\r
+calculate travel times and energy usage.\r
+\r
+\r
+\f                                                                       14\r
+ ********************\r
+ * PHOTON TORPEDOES *\r
+ ********************\r
+\r
+  Mnemonic:  PHOTONS\r
+  Shortest abbreviation:  PHO\r
+  Full commands:  PHOTONS <NUMBER> <TARG1> <TARG2> <TARG3>\r
+\r
+Photon torpedoes are projectile weapons--you either hit what you aim\r
+at, or you don't.  There are no "partial hits".\r
+\r
+One photon torpedo will usually kill one ordinary Klingon, but it\r
+usually takes about two for a Klingon Commander.  Photon torpedoes\r
+can also blow up stars and starbases, if you aren't careful.\r
+\r
+You may fire photon torpedoes singly, or in bursts of two or three.\r
+Each torpedo is individually targetable.  The computer will prompt\r
+you, asking for the target sector for each torpedo.  Alternately, you\r
+may specify each target in the command line.\r
+\r
+Photon torpedoes cannot be aimed precisely--there is always some\r
+randomness involved in the direction they go.  Photon torpedoes may\r
+be fired with your shields up, but as they pass through the shields\r
+they are randomly deflected from their intended course even more.\r
+\r
+Photon torpedoes are proximity-fused.  The closer they explode to the\r
+enemy, the more damage they do.  There is a hit "window" about one\r
+sector wide.  If the torpedo misses the hit window, it does not\r
+explode and the enemy is unaffected.  Photon torpedoes are only\r
+effective within the quadrant.  They have no effect on things in\r
+adjacent quadrants.\r
+\r
+If more than one torpedo is fired and only one target sector is\r
+specified, all torpedoes are fired at that sector.  For example, to\r
+fire two torpedoes at sector 3 - 4, you type\r
+\r
+     PHO 2 3 4           (or)           PHO 2 3 4 3 4\r
+\r
+To fire torpedoes at, consecutively, sectors 2 - 6, 1 - 10, and 4 -\r
+7, type\r
+\r
+     PHO 3 2 6 1 10 4 7\r
+\r
+There is no restriction to fire directly at a sector.  For example,\r
+you can enter\r
+\r
+       PHO 1 3 2.5\r
+\r
+to aim between two sectors.  However, sector numbers must be 1 to 10\r
+inclusive.\r
+\r
+\f                                                                       15\r
+ ********************\r
+ * DOCK AT STARBASE *\r
+ ********************\r
+\r
+  Mnemonic:  DOCK\r
+  Shortest abbreviation:  D\r
+\r
+You may dock your starship whenever you are in one of the eight\r
+sector positions immediately adjacent to a starbase.  When you dock,\r
+your starship is resupplied with energy, shield energy photon\r
+torpedoes, and life support reserves.  Repairs also proceed faster at\r
+starbase, so if some of your devices are damaged, you may wish to\r
+stay at base (by using the "REST" command) until they are fixed.  If\r
+your ship has more than its normal maximum energy (which can happen\r
+if you've loaded crystals) the ship's energy is not changed.\r
+\r
+You may not dock while in standard orbit around a planet.\r
+\r
+Starbases have their own deflector shields, so you are completely\r
+safe from phaser attack while docked.  You are also safe from\r
+long-range tractor beams.\r
+\r
+Starbases also have both short and long range sensors, which you can\r
+use if yours are broken. There's also a subspace radio to get\r
+information about happenings in the galaxy. Mr. Spock will update the\r
+star chart if your ask for it while docked and your own radio is dead.\r
+\r
+\r
+ ********\r
+ * REST *\r
+ ********\r
+\r
+  Mnemonic:  REST\r
+  Shortest abbreviation:  R\r
+  Full command:  REST <NUMBER OF STARDATES>\r
+\r
+This command simply allows the specified number of stardates to go\r
+by.  This is useful if you have suffered damages and wish to wait\r
+until repairs are made before you go back into battle.\r
+\r
+It is not generally advisable to rest while you are under attack by\r
+Klingons.\r
+\r
+\r
+ **************************\r
+ * CALL STARBASE FOR HELP *\r
+ **************************\r
+\r
+  Mnemonic:  CALL\r
+  (No abbreviation)\r
+\r
+[Originally, this command was called "HELP", but these days it might\r
+be misinterpreted as built-in documentation!]\r
+\r
+When you get into serious trouble, you may call starbase for help.\r
+Starbases have a device called a "long-range transporter beam" which\r
+they can use to teleport you to base.  This works by dematerializing\r
+your starship at its current position and re-materializing it\r
+adjacent to the nearest starbase.  Teleportation is instantaneous,\r
+and starbase supplies the required energy--all you have to do is let\r
+them know (via subspace radio) that you need to be rescued.\r
+\f                                                                       16\r
+This command should be employed only when absolutely necessary.  In\r
+the first place, calling for help is an admission on your part that\r
+you got yourself into something you cannot get yourself out of, and\r
+you are heavily penalized for this in the final scoring.  Secondly,\r
+the long-range transporter beam is not reliable--starbase can always\r
+manage to dematerialize your starship, but (depending on distance)\r
+may or may not be able to re-materialize you again.  The long-range\r
+transporter beam has no absolute maximum range; if you are in the\r
+same quadrant as a starbase, you have a good chance (about 90%) of\r
+re-materializing successfully.  your chances drop to roughly 50-50 at\r
+just over 3 quadrants.\r
+\r
+\r
+ ****************\r
+ * ABANDON SHIP *\r
+ ****************\r
+\r
+  Mnemonic:  ABANDON\r
+  (no abbreviation)\r
+\r
+You may abandon the Enterprise if necessary.  If there is still a\r
+starbase in the galaxy, you will be sent there and put in charge of a\r
+weaker ship, the Faerie Queene.\r
+\r
+The Faerie Queene cannot be abandoned.\r
+\r
+\r
+ *****************\r
+ * SELF-DESTRUCT *\r
+ *****************\r
+\r
+  Mnemonic:  DESTRUCT\r
+  (no abbreviation)\r
+\r
+You may self-destruct, thus killing yourself and ending the game.  If\r
+there are nearby Klingons, you may take a few of them with you (the\r
+more energy you have left, the bigger the bang).\r
+\r
+In order to self-destruct you must remember the password you typed in\r
+at the beginning of the game.\r
+\r
+\r
+\r
+ ******************************\r
+ * TERMINATE THE CURRENT GAME *\r
+ ******************************\r
+\r
+  Mnemonic:  QUIT\r
+  (no abbreviation)\r
+\r
+Immediately cancel the current game; no conclusion is reached.  You\r
+will be given an opportunity to start a new game or to leave the Star\r
+Trek program.\r
+\r
+\r
+\f                                                                       17\r
+ ***************\r
+ * SENSOR-SCAN *\r
+ ***************\r
+\r
+  Mnemonic:  SENSORS\r
+  Shortest abbreviation:  SE\r
+\r
+Utilizing the short-range sensors, science officer Spock gives you a\r
+readout on any planet in your quadrant.  Planets come in three\r
+classes: M, N, and O.  Only class M planets have earth-like\r
+conditions.  Spock informs you if the planet has any dilithium\r
+crystals.  Sensor scans are free.\r
+\r
+\r
+ ************************\r
+ * ENTER STANDARD ORBIT *\r
+ ************************\r
+\r
+  Mnemonic:  ORBIT\r
+  Shortest abbreviation:  O\r
+\r
+To land on a planet you must first be in standard orbit.  You achieve\r
+this in a manner similar to docking at starbase.  Moving to one of\r
+the eight sector positions immediately adjacent to the planet, you\r
+give the orbit command which puts your ship into standard orbit about\r
+the planet.  Since this is a maneuver, a small amount of time is\r
+used; negligible energy is required.  If enemies are present, they\r
+will attack.\r
+\r
+\r
+ **********************\r
+ * TRANSPORTER-TRAVEL *\r
+ **********************\r
+\r
+  Mnemonic:  TRANSPORT\r
+  Shortest abbreviation:  T\r
+\r
+The transporter is a device which can convert any physical object\r
+into energy, beam the energy through space, and reconstruct the\r
+physical object at some destination.  Transporting is one way to land\r
+on a planet.  Since the transporter has a limited range, you must be\r
+in standard orbit to beam down to a planet.  Shields must be down\r
+while transporting.\r
+\r
+The transport command is used to beam a landing party onto a planet\r
+to mine "dilithium crystals".  Each time the command is given the\r
+landing party (which you lead) moves from the ship to the planet, or\r
+vice-versa.\r
+\r
+You are advised against needless transporting, since like all\r
+devices, the transporter will sometimes malfunction.\r
+\r
+The transporter consumes negligible time and energy.  Its use does\r
+not constitute a "turn".\r
+\r
+\f                                                                       18\r
+ *****************\r
+ * SHUTTLE CRAFT *\r
+ *****************\r
+\r
+  Mnemonic:  SHUTTLE\r
+  Shortest abbreviation:  SHU\r
+\r
+An alternate way to travel to and from planets.  Because of limited\r
+range, you must be in standard orbit to use the shuttle craft, named\r
+"Galileo".  Shields must be down.\r
+\r
+Unlike transporting, use of the shuttle craft does constitute a\r
+"turn" since time is consumed.  The time naturally depends on orbit\r
+altitude, and is equal to 3.0e-5 times altitude.  Shuttling uses no\r
+ship energy.\r
+\r
+You should use the same travel device going from the planet to the\r
+ship as you use to go from the ship to the planet. However it is\r
+possible to transport to the planet and have the Galileo crew come\r
+and pick your landing party up, or to take the Galileo to the planet\r
+and then transport back, leaving the shuttle craft on the planet.\r
+\r
+\r
+ ***************************\r
+ * MINE DILITHIUM CRYSTALS *\r
+ ***************************\r
+\r
+  Mnemonic:  MINE\r
+  Shortest abbreviation:  MI\r
+\r
+Once you and your mining party are on the surface of a planet which\r
+has dilithium crystals, this command will dig them for you.\r
+\r
+Mining requires time and constitutes a "turn".  No energy is used.\r
+Class M planets require 0.1 to 0.3 stardates to mine.  Class N\r
+planets take twice as long, and class O planets take three times as\r
+long.\r
+\r
+Dilithium crystals contain enormous energy in a form that is readily\r
+released in the ship's power system.  It is an excellent idea to mine\r
+them whenever possible, for use in emergencies.  You keep the\r
+crystals until the game is over or you abandon ship when not at a\r
+starbase.\r
+\r
+\r
+ ***************************\r
+ * LOAD DILITHIUM CRYSTALS *\r
+ ***************************\r
+\r
+  Mnemonic:  CRYSTALS\r
+  Shortest abbreviation:  CR\r
+\r
+This is a very powerful command which should be used with caution.\r
+Once you have dilithium crystals aboard ship, this command will\r
+instruct engineering officer Scott and Mr. Spock to place a raw\r
+dilithium crystal into the power channel of the ship's\r
+matter-antimatter converter.  When it works, this command will\r
+greatly boost the ship's energy.\r
+\f                                                                       19\r
+Because the crystals are raw and impure, instabilities can occur in\r
+the power channel.  Usually Scotty can control these.  When he\r
+cannot, the results are disastrous. Scotty will use those crystals\r
+that appear to be most stable first.\r
+\r
+Since using raw dilithium crystals for this purpose entails\r
+considerable risk, Starfleet Regulations allow its use only during\r
+"condition yellow".  No time or energy is used.\r
+\r
+\r
+ *****************\r
+ * PLANET REPORT *\r
+ *****************\r
+\r
+  Mnemonic:  PLANETS\r
+  Shortest abbreviation:  PL\r
+\r
+Mr. Spock presents you a list of the available information on planets\r
+in the galaxy.  Since planets do not show up on long-range scans, the\r
+only way to obtain this information is with the "SENSORS" command.\r
+\r
+\r
+ **********\r
+ * FREEZE *\r
+ **********\r
+\r
+  Mnemonic:  FREEZE\r
+  (no abbreviation)\r
+  Full command:  FREEZE <FILE NAME>\r
+\r
+The purpose of the FREEZE command is to allow a player to save the\r
+current state of the game, so that it can be finished later.  A\r
+plaque may not be generated from a frozen game. A file with the\r
+specified <file name> and type '.TRK' is created (if necessary) in\r
+the current directory, and all pertinent information about the game\r
+is written to that file. The game may be continued as usual or be\r
+terminated at the user's option.\r
+\r
+To restart a game created by the "FREEZE" command, the user need only\r
+type "FROZEN" in response to the initial question about the type of\r
+game desired, followed by the <file name>.\r
+\r
+NOTE: A "tournament" game is like a frozen game, with the following\r
+differences.  (1) Tournament games always start from the beginning,\r
+while a frozen game can start at any point.  (2) Tournament games\r
+require only that the player remember the name or number of the\r
+tournament, while the information about a frozen game must be kept on\r
+a file. Tournament games can be frozen, but then they behave like\r
+regular frozen games.\r
+\r
+A point worth noting is that 'FREEZE' does not save the seed for the\r
+random number generator, so that identical actions after restarting\r
+the same frozen game can lead to different results.  However,\r
+identical actions after starting a given tournament game always lead\r
+to the same results.\r
+\f                                                                       20\r
+ ***********\r
+ * REQUEST *\r
+ ***********\r
+\r
+  Mnemonic:  REQUEST\r
+  Shortest abbreviation:  REQ\r
+  Full command:  REQUEST <ITEM>\r
+\r
+This command allows you to get any single piece of information from\r
+the <STATUS> command.  <ITEM> specifies which information as follows:\r
+\r
+ INFORMATION       MNEMONIC FOR <ITEM>           SHORTEST ABBREVIATION\r
+\r
+ STARDATE              DATE                                D\r
+ CONDITION             CONDITION                           C\r
+ POSITION              POSITION                            P\r
+ LIFE SUPPORT          LSUPPORT                            L\r
+ WARP FACTOR           WARPFACTOR                          W\r
+ ENERGY                ENERGY                              E\r
+ TORPEDOES             TORPEDOES                           T\r
+ SHIELDS               SHIELDS                             S\r
+ KLINGONS LEFT         KLINGONS                            K\r
+ TIME LEFT             TIME                                TI\r
+\r
+\r
+ **************************\r
+ * EXPERIMENTAL DEATH RAY *\r
+ **************************\r
+\r
+  Mnemonic:  DEATHRAY\r
+  (No abbreviation)\r
+\r
+This command should be used only in those desperate cases where you\r
+have absolutely no alternative.  The death ray uses energy to\r
+rearrange matter.  Unfortunately, its working principles are not yet\r
+thoroughly understood, and the results are highly unpredictable.\r
+\r
+The only good thing that can result is the destruction of all enemies\r
+in your current quadrant.  This will happen about 70% of the time.\r
+Only enemies are destroyed; starbases, stars, and planets are\r
+unaffected.\r
+\r
+Constituting the remaining 30% are results varying from bad to fatal.\r
+\r
+The death ray requires no energy or time, but if you survive, enemies\r
+will hit you.\r
+\r
+The Faerie Queene has no death ray.\r
+\r
+If the death ray is damaged in its use, it must be totally replaced.\r
+This can only be done at starbase.  Because it is a very complex\r
+device, it takes 9.99 stardates at base to replace the death ray.\r
+The death ray cannot be repaired in flight.\r
+\r
+\f                                                                       21\r
+ ***************************\r
+ * LAUNCH DEEP SPACE PROBE *\r
+ ***************************\r
+\r
+  Mnemonic:  PROBE\r
+  Shortest abbreviation:  PR\r
+  Full command:  PROBE <ARMED> MANUAL <displacement>\r
+                 PROBE <ARMED> AUTOMATIC <destination>\r
+\r
+The Enterprise carries a limited number of Long Range Probes. These\r
+fly to the end of the galaxy and report back a count of the number of\r
+important things found in each quadrant through which it went. The\r
+probe flies at warp 10, and therefore uses time during its flight.\r
+Results are reported immediately via subspace radio and are recorded\r
+in the star chart.\r
+\r
+The probe can also be armed with a NOVAMAX warhead. When launched\r
+with the warhead armed, the probe flies the same except as soon as it\r
+reaches the target location, it detonates the warhead in the heart of\r
+a star, causing a supernova and destroying everything in the\r
+quadrant. It then flies no further. There must be a star in the\r
+target quadrant for the NOVAMAX to function. \r
+\r
+The probe can fly around objects in a galaxy, but is destroyed if it\r
+enters a quadrant containing a supernova, or if it leaves the galaxy.\r
+\r
+The target location is specified in the same manner as the MOVE\r
+command, however for automatic movement, if only one pair of\r
+coordinates are specified they are assumed to be the quadrant and not\r
+the sector in the current quadrant!\r
+\r
+The Faerie Queene has no probes.\r
+\r
+\r
+ ******************\r
+ * EMERGENCY EXIT *\r
+ ******************\r
+\r
+  Mnemonic:  EMEXIT\r
+  Shortest abbreviation:  E\r
+\r
+This command provides a quick way to exit from the game when you\r
+observe a Klingon battle cruiser approaching your terminal.  Its\r
+effect is to freeze the game on the file 'EMSAVE.TRK' in your current\r
+directory, erase the screen, and exit.\r
+\r
+Of course, you do loose the chance to get a plaque when you use this\r
+manouver.\r
+\r
+\r
+ ****************\r
+ * ASK FOR HELP *\r
+ ****************\r
+\r
+  Mnemonic:  HELP\r
+  Full command:  HELP <command>\r
+\r
+This command reads the appropriate section from the SST.DOC file,\r
+providing the file is in the current directory.\r
+\r
+\f            **********MISCELLANEOUS NOTES**********                    22\r
+\r
+Starbases can be attacked by either commanders or by the\r
+"Super-Commander".  When this happens, you will be notified by\r
+subspace radio, provided it is working.  The message will inform you\r
+how long the base under attack can last.  Since the "Super-Commander"\r
+is more powerful than an ordinary commander, he can destroy a base\r
+more quickly.\r
+\r
+The "Super-Commander" travels around the galaxy at a speed of about\r
+warp 6 or 7.  His movement is strictly time based; the more time\r
+passes, the further he can go.\r
+\r
+Scattered through the galaxy are certain zones of control,\r
+collectively designated the "Romulan Neutral Zone".  Any quadrant\r
+which contains Romulans without Klingons is part of the Neutral Zone,\r
+except if a base is present.  Since Romulans do not show on either\r
+the long-range scan or the star chart, it is easy for you to stumble\r
+into this zone.  When you do, if your subspace radio is working, you\r
+will receive a warning message from the Romulan, politely asking you\r
+to leave.\r
+\r
+In general, Romulans are a galactic nuisance.\r
+\r
+The high-speed shield control is fairly reliable, but it has been\r
+known to malfunction.\r
+\r
+You can observe the galactic movements of the "Super-Commander" on\r
+the star chart, provided he is in territory you have scanned and your\r
+subspace radio is working.\r
+\r
+Periodically, you will receive intelligence reports from starfleet\r
+command, indicating the current quadrant of the "Super-Commander".\r
+Your subspace radio must be working, of course.\r
+\r
+Each quadrant will contain from 0 to 3 black holes.  Torpedoes\r
+entering a black hole disappear.  In fact, anything entering a black\r
+hole disappears, permanently.  If you can displace an enemy into one,\r
+he is a goner.  Black holes do not necessarily remain in a quadrant.\r
+they are transient phenomena.\r
+\r
+Commanders will ram your ship, killing themselves and inflicting\r
+heavy damage to you, if they should happen to decide to advance into\r
+your sector.\r
+\r
+You can get a list of commands by typing "COMMANDS".\r
+\r
+\f                     ----------SCORING----------                       23\r
+\r
+\r
+Scoring is fairly simple.  You get points for good things, and you\r
+lose points for bad things.\r
+\r
+ You gain--\r
+\r
+     (1)   10 points for each ordinary Klingon you kill,\r
+     (2)   50 points for each commander you kill,\r
+     (3)  200 points for killing the "Super-Commander",\r
+     (4)   20 points for each Romulan killed,\r
+     (5)    1 point for each Romulan captured.\r
+     (6)  500 times your average Klingon/stardate kill rate.  If you\r
+               lose the game, your kill rate is based on a minimum of\r
+               5 stardates.\r
+     (7)  You get a bonus if you win the game, based on your rating:\r
+               Novice=100, Fair=200, Good=300, Expert=400, Emeritus=500.\r
+\r
+ You lose--\r
+\r
+     (8)  200 points if you get yourself killed,\r
+     (9)  100 points for each starbase you destroy,\r
+    (10)  100 points for each starship you lose,\r
+    (11)   45 points for each time you had to call for help,\r
+    (12)   10 points for each planet you destroyed,\r
+    (13)    5 points for each star you destroyed, and\r
+    (14)    1 point for each casualty you incurred.\r
+\r
+In addition to your score, you may also be promoted one grade in rank\r
+if you play well enough.  Promotion is based primarily on your\r
+Klingon/stardate kill rate, since this is the best indicator of\r
+whether you are ready to go on to the next higher rating.  However,\r
+if you have lost 100 or more points in penalties, the required kill\r
+rate goes up. Normally, the required kill rate is 0.1 * skill *\r
+(skill + 1.0) + 0.1, where skill ranges from 1 for Novice to 5 for\r
+Emeritus.\r
+\r
+You can be promoted from any level.  There is a special promotion\r
+available if you go beyond the "Expert" range.  You can also have a\r
+certificate of merit printed with your name, date, and Klingon kill\r
+rate, provided you are promoted from either the "Expert" or\r
+"Emeritus" levels. This "plaque" requires a 132 column printer. You\r
+may need print the certificate to a file, import it into your word\r
+processor, selecting Courier 8pt font, and then print in "landscape\r
+orientation".\r
+\r
+You should probably start out at the novice level, even if you are\r
+already familiar with one of the other versions of the Star Trek\r
+game--but, of course, the level of game you play is up to you.  If\r
+you want to start at the Expert level, go ahead.  It's your funeral.\r
+The emeritus game is strictly for masochists.\r
+\r
+\f           ----------HANDY REFERENCE PAGE----------                   24\r
+\r
+ ABBREV    FULL COMMAND                           DEVICE USED\r
+ ------    ------------                           -----------\r
+ ABANDON   ABANDON                                shuttle craft\r
+ C         CHART                                  (none)\r
+ CALL      CALL (for help)                        subspace radio\r
+ CO        COMPUTER                               computer\r
+ CR        CRYSTALS                               (none)\r
+ DA        DAMAGES                                (none)\r
+ DEATHRAY  DEATHRAY                               (none)  \r
+ DESTRUCT  DESTRUCT                               computer\r
+ D         DOCK                                   (none)\r
+ E         EMEXIT                                 (none)\r
+ FREEZE    FREEZE <FILE NAME>                     (none)\r
+ I         IMPULSE <MANUAL> <DISPLACEMENT>        impulse engines\r
+           IMPULSE AUTOMATIC <DESTINATION>        impulse engines and computer\r
+ L         LRSCAN                                 long-range sensors\r
+ MI        MINE                                   (none)\r
+ M         MOVE <MANUAL> <DISPLACEMENT>           warp engines\r
+           MOVE AUTOMATIC <DESTINATION>           warp engines and computer\r
+ O         ORBIT                                  warp or impulse engines\r
+ P         PHASERS <TOTAL AMOUNT>                 phasers and computer\r
+           PHASERS AUTOMATIC <TOTAL AMOUNT>       phasers, computer, sr sensors\r
+           PHASERS MANUAL <AMT1> <AMT2> ...       phasers\r
+ PHO       PHOTONS <NUMBER> <TARGETS>             torpedo tubes \r
+ PL        PLANETS                                (none)\r
+ PR        PROBE <ARMED> <MANUAL> <DISPLACEMENT>  probe launcher, radio \r
+           PROBE <ARMED> AUTOMATIC <DESTINATION>  launcher, radio, computer\r
+ REP       REPORT                                 (none)\r
+ REQ       REQUEST                                (none)\r
+ R         REST <NUMBER OF STARDATES>             (none)\r
+ QUIT      QUIT                                   (none)\r
+ S         SRSCAN <NO or CHART>                   short-range sensors\r
+ SE        SENSORS                                short-range sensors\r
+ SH        SHIELDS <UP, DOWN, or TRANSFER>        deflector shields\r
+ SHU       SHUTTLE                                shuttle craft\r
+ ST        STATUS                                 (none)\r
+ T         TRANSPORT                              transporter\r
+ W         WARP <FACTOR>                          (none)\r
+\r
+ L. R. Scan:   thousands digit:   supernova\r
+               hundreds digit:    Klingons\r
+               tens digit:        starbases\r
+               ones digit:        stars\r
+               period (.):        digit not known (star chart only)\r
+\r
+Courses are given in manual mode in X - Y displacements; in automatic\r
+    mode as destination quadrant and/or sector.  Manual mode is default.\r
+Distances are given in quadrants.  A distance of one sector is 0.1 quadrant.\r
+Ordinary Klingons have about 400 units of energy, Commanders about\r
+    1200.  Romulans normally have about 800 units of energy, and the\r
+    (GULP) "Super-Commander" has about 1800.\r
+Phaser fire diminishes to about 60 percent at 5 sectors.  Up to 1500\r
+    units may be fired in a single burst without danger of overheat.\r
+Warp 6 is the fastest safe speed.  At higher speeds, engine damage\r
+    may occur.  At warp 10 you may enter a time warp.\r
+Shields cost 50 units of energy to raise, and double the power\r
+    requirements of moving under warp drive.  Engaging the high-speed\r
+    shield control requires 200 units of energy.\r
+Warp drive requires (distance)*(warp factor cubed) units of energy\r
+    to travel at a speed of (warp factor squared)/10 quadrants per stardate.\r
+Impulse engines require 20 units to warm up, plus 100 units per\r
+     quadrant.  Speed is just under one sector per stardate.\r
+\f                  ********MODIFICATIONS********                       25\r
+\r
+Back in (about) 1977 I got a copy of this Super Star Trek game for\r
+the CDC 6600 mainframe computer. Someone had converted it to PDP-11\r
+Fortran but couldn't get it to run because of its size. I modified\r
+the program to use overlays and managed to shoehorn it in on the 56k\r
+byte machine.\r
+\r
+I liked the game so much I put some time into fixing bugs, mainly\r
+what could be called continuity errors and loopholes in the game's\r
+logic. We even played a couple tournaments.\r
+\r
+In 1979, I lost access to that PDP-11. I did save the source code\r
+listing. In 1995, missing that old friend, I started converting the\r
+program into portable ANSI C. It's been slow, tedious work that took\r
+over a year to accomplish.\r
+\r
+In early 1997, I got the bright idea to look for references to "Super\r
+Star Trek" on the World Wide Web. There weren't many hits, but there\r
+was one that came up with 1979 Fortran sources! This version had a\r
+few additional features that mine didn't have, however mine had some\r
+feature it didn't have. So I merged its features that I liked. I also\r
+took a peek at the DECUS version (a port, less sources, to the\r
+PDP-10), and some other variations.\r
+\r
+Modifications I made:\r
+\r
+  Compared to original version, I've changed the "help" command to\r
+  "call" and the "terminate" command to "quit" to better match user\r
+  expectations. The DECUS version apparently made those changes as well\r
+  as changing "freeze" to "save". However I like "freeze".\r
+\r
+  I added EMEXIT from the 1979 version.\r
+\r
+  That later version also mentions srscan and lrscan working when\r
+  docked (using the starbase's scanners), so I made some changes here\r
+  to do this (and indicating that fact to the player), and then\r
+  realized the base would have a subspace radio as well -- doing a\r
+  Chart when docked updates the star chart, and all radio reports will\r
+  be heard. The Dock command will also give a report if a base is under\r
+  attack.\r
+\r
+  It also had some added logic to spread the initial positioning of\r
+  bases. That made sense to add because most people abort games with\r
+  bad base placement.\r
+\r
+  The experimental deathray originally had only a 5% chance of success,\r
+  but could be used repeatedly. I guess after a couple years of use, it\r
+  was less "experimental" because the 1979 version had a 70% success\r
+  rate. However it was prone to breaking after use. I upgraded the\r
+  deathray, but kept the original set of failure modes (great humor!).\r
+\r
+  I put in the Tholian Web code from the 1979 version.\r
+\r
+  I added code so that Romulans and regular Klingons could move in \r
+  advanced games. I re-enabled the code which allows enemy ships to\r
+  ram the Enterprise; it had never worked right. The 1979 version\r
+  seems to have it all fixed up, but I'm still not overly happy with\r
+  the algorithm.\r
+\r
+  The DECUS version had a Deep Space Probe. Looked like a good idea\r
+  so I implimented it based on its description.\r
+\r
+\r
+\f               ----------ACKNOWLEDGMENTS----------                    26\r
+\r
+The authors would like to thank Professor Michael Duggan for his\r
+encouragement and administrative assistance with the development of\r
+the Star Trek game, without which it might never have been completed.\r
+\r
+Much credit is due to Patrick McGehearty and Rich Cohen, who assisted\r
+with the original design of the game and contributed greatly to its\r
+conceptual development.\r
+\r
+Thanks are also due to Carl Strange, Hardy Tichenor and Steven Bruell\r
+for their assistance with certain coding problems.\r
+\r
+This game was inspired by and rather loosely based on an earlier\r
+game, programmed in the BASIC language, by Jim Korp and Grady Hicks.\r
+It is the authors' understanding that the BASIC game was in turn\r
+derived from a still earlier version in use at Penn State University.\r
+\r
+\r
+\r
+\r
+                 ----------REFERENCES----------\r
+\r
+\r
+ 1.  "Star Trek" (the original television series), produced and\r
+     directed by Gene Rodenberry.\r
+\r
+ 2.  "Star Trek" (the animated television series), produced by Gene\r
+     Rodenberry and directed by Hal Sutherland.  Also excellent,\r
+     and not just kiddie fare.  If you enjoyed the original series\r
+     you should enjoy this one (unless you have some sort of a\r
+     hangup about watching cartoons).\r
+\r
+ 3.  "The Making of Star Trek", by Steven E. Whitfield and Gene\r
+     Rodenberry.  The best and most complete readily available\r
+     book about Star Trek.  (Ballantine Books)\r
+\r
+ 4.  "The World of Star Trek", by David Gerrold.  Similiar in scope\r
+     to the above book.  (Bantam)\r
+\r
+ 5.  "The Star Trek Guide", third revision 4/17/67, by Gene\r
+     Rodenberry.  The original writer's guide for the television\r
+     series, but less comprehensive than (3) above.\r
+     (Norway Productions)\r
+\r
+ 6.  "The Trouble With Tribbles", by David Gerrold.  Includes the\r
+     complete script of this popular show.  (Ballantine Books)\r
+\r
+ 7.  "Star Trek", "Star Trek 2", ..., "Star Trek 9", by James Blish.\r
+     The original shows in short story form.  (Bantam)\r
+\r
+ 8.  "Spock Must Die", by James Blish.  An original novel, but\r
+     rather similar to the show "The Enemy Within".  (Bantam)\r
+\r
+ 9.  Model kits of the Enterprise and a "Klingon Battle-Cruiser"\r
+     by AMT Corporation are available at most hobby shops.\r
diff --git a/sst.h b/sst.h
new file mode 100644 (file)
index 0000000..dcbb14d
--- /dev/null
+++ b/sst.h
@@ -0,0 +1,426 @@
+#include <stdio.h>\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#ifndef INCLUDED\r
+#define EXTERN extern\r
+#else\r
+#define EXTERN\r
+#endif\r
+\r
+// #define DEBUG\r
+\r
+#define ndevice (15)   // Number of devices\r
+#define phasefac (2.0)\r
+#define PLNETMAX (10)\r
+#define NEVENTS (8)\r
+\r
+typedef struct {\r
+       int x;  /* Quadrant location of planet */\r
+       int y;\r
+       int pclass; /* class M, N, or O (1, 2, or 3) */\r
+       int crystals; /* has crystals */\r
+       int known;   /* =1 contents known, =2 shuttle on this planet */\r
+} PLANETS;\r
+\r
+EXTERN struct foo {\r
+               int snap,               // snapshot taken\r
+               remkl,                  // remaining klingons\r
+           remcom,                     // remaining commanders\r
+               rembase,                // remaining bases\r
+               starkl,                 // destroyed stars\r
+               basekl,                 // destroyed bases\r
+               killk,                  // Klingons killed\r
+               killc,                  // commanders killed\r
+               galaxy[9][9],   // The Galaxy (subscript 0 not used)\r
+               cx[11],cy[11],  // Commander quadrant coordinates\r
+               baseqx[6],              // Base quadrant X\r
+               baseqy[6],              // Base quadrant Y\r
+               newstuf[9][9],  // Extended galaxy goodies\r
+               isx, isy,               // Coordinate of Super Commander\r
+               nscrem,                 // remaining super commanders\r
+               nromkl,                 // Romulans killed\r
+               nromrem,                // Romulans remaining\r
+               nsckill,                // super commanders killed\r
+               nplankl;                // destroyed planets\r
+       PLANETS plnets[PLNETMAX+1];  // Planet information\r
+       double date,            // stardate\r
+               remres,                 // remaining resources\r
+           remtime;            // remaining time\r
+} d, snapsht;                  // Data that is snapshot\r
+\r
+EXTERN char\r
+               quad[11][11];   // contents of our quadrant\r
+\r
+// Scalar variables that are needed for freezing the game\r
+// are placed in a structure. #defines are used to access by their\r
+// original names. Gee, I could have done this with the d structure,\r
+// but I just didn't think of it back when I started.\r
+\r
+EXTERN struct foo2 {\r
+       int inkling,\r
+       inbase,\r
+       incom,\r
+       instar,\r
+       intorps,\r
+       condit,\r
+       torps,\r
+       ship,\r
+       quadx,\r
+       quady,\r
+       sectx,\r
+       secty,\r
+       length,\r
+       skill,\r
+       basex,\r
+       basey,\r
+       klhere,\r
+       comhere,\r
+       casual,\r
+       nhelp,\r
+       nkinks,\r
+       ididit,\r
+       gamewon,\r
+       alive,\r
+       justin,\r
+       alldone,\r
+       shldchg,\r
+       thingx,\r
+       thingy,\r
+       plnetx,\r
+       plnety,\r
+       inorbit,\r
+       landed,\r
+       iplnet,\r
+       imine,\r
+       inplan,\r
+       nenhere,\r
+       ishere,\r
+       neutz,\r
+       irhere,\r
+       icraft,\r
+       ientesc,\r
+       iscraft,\r
+       isatb,\r
+       iscate,\r
+#ifdef DEBUG\r
+       idebug,\r
+#endif\r
+       iattak,\r
+       icrystl,\r
+       tourn,\r
+       thawed,\r
+       batx,\r
+       baty,\r
+       ithere,\r
+       ithx,\r
+       ithy,\r
+       iseenit,\r
+       probecx,\r
+       probecy,\r
+       proben,\r
+       isarmed,\r
+       nprobes;\r
+       double inresor,\r
+       intime,\r
+       inenrg,\r
+       inshld,\r
+       inlsr,\r
+       indate,\r
+       energy,\r
+       shield,\r
+       shldup,\r
+       warpfac,\r
+       wfacsq,\r
+       lsupres,\r
+       dist,\r
+       direc,\r
+       Time,\r
+       docfac,\r
+       resting,\r
+       damfac,\r
+       stdamtim,\r
+       cryprob,\r
+       probex,\r
+       probey,\r
+       probeinx,\r
+       probeiny;\r
+} a;\r
+\r
+#define inkling a.inkling              // Initial number of klingons\r
+#define inbase a.inbase                        // Initial number of bases\r
+#define incom a.incom                  // Initian number of commanders\r
+#define instar a.instar                        // Initial stars\r
+#define intorps a.intorps              // Initial/Max torpedoes\r
+#define condit a.condit                        // Condition (red, yellow, green docked)\r
+#define torps a.torps                  // number of torpedoes\r
+#define ship a.ship                            // Ship type -- 'E' is Enterprise\r
+#define quadx a.quadx                  // where we are\r
+#define quady a.quady                  //\r
+#define sectx a.sectx                  // where we are\r
+#define secty a.secty                  //\r
+#define length a.length                        // length of game\r
+#define skill a.skill                  // skill level\r
+#define basex a.basex                  // position of base in current quad\r
+#define basey a.basey                  //\r
+#define klhere a.klhere                        // klingons here\r
+#define comhere a.comhere              // commanders here\r
+#define casual a.casual                        // causalties\r
+#define nhelp a.nhelp                  // calls for help\r
+#define nkinks a.nkinks                        //\r
+#define ididit a.ididit                        // Action taken -- allows enemy to attack\r
+#define gamewon a.gamewon              // Finished!\r
+#define alive a.alive                  // We are alive (not killed)\r
+#define justin a.justin                        // just entered quadrant\r
+#define alldone a.alldone              // game is now finished\r
+#define shldchg a.shldchg              // shield is changing (affects efficiency)\r
+#define thingx a.thingx                        // location of strange object in galaxy\r
+#define thingy a.thingy                        //\r
+#define plnetx a.plnetx                        // location of planet in quadrant\r
+#define plnety a.plnety                        //\r
+#define inorbit a.inorbit              // orbiting\r
+#define landed a.landed                        // party on planet (1), on ship (-1)\r
+#define iplnet a.iplnet                        // planet # in quadrant\r
+#define imine a.imine                  // mining\r
+#define inplan a.inplan                        // initial planets\r
+#define nenhere a.nenhere              // Number of enemies in quadrant\r
+#define ishere a.ishere                        // Super-commander in quandrant\r
+#define neutz a.neutz                  // Romulan Neutral Zone\r
+#define irhere a.irhere                        // Romulans in quadrant\r
+#define icraft a.icraft                        // Kirk in Galileo\r
+#define ientesc a.ientesc              // Attempted escape from supercommander\r
+#define iscraft a.iscraft              // =1 if craft on ship, -1 if removed from game\r
+#define isatb a.isatb                  // =1 if SuperCommander is attacking base\r
+#define iscate a.iscate                        // Super Commander is here\r
+#ifdef DEBUG\r
+#define idebug a.idebug                        // Debug mode\r
+#endif\r
+#define iattak a.iattak                        // attack recursion elimination (was cracks[4])\r
+#define icrystl a.icrystl              // dilithium crystals aboard\r
+#define tourn a.tourn                  // Tournament number\r
+#define thawed a.thawed                        // Thawed game\r
+#define batx a.batx                            // Base coordinates being attacked\r
+#define baty a.baty                            //\r
+#define ithere a.ithere                        // Tholean is here \r
+#define ithx a.ithx                            // coordinates of tholean\r
+#define ithy a.ithy\r
+#define iseenit a.iseenit              // Seen base attack report\r
+#define inresor a.inresor              // initial resources\r
+#define intime a.intime                        // initial time\r
+#define inenrg a.inenrg                        // Initial/Max Energy\r
+#define inshld a.inshld                        // Initial/Max Shield\r
+#define inlsr a.inlsr                  // initial life support resources\r
+#define indate a.indate                        // Initial date\r
+#define energy a.energy                        // Energy level\r
+#define shield a.shield                        // Shield level\r
+#define shldup a.shldup                        // Shields are up\r
+#define warpfac a.warpfac              // Warp speed\r
+#define wfacsq a.wfacsq                        // squared warp factor\r
+#define lsupres a.lsupres              // life support reserves\r
+#define dist a.dist                            // movement distance\r
+#define direc a.direc                  // movement direction\r
+#define Time a.Time                            // time taken by current operation\r
+#define docfac a.docfac                        // repair factor when docking (constant?)\r
+#define resting a.resting              // rest time\r
+#define damfac a.damfac                        // damage factor\r
+#define stdamtim a.stdamtim            // time that star chart was damaged\r
+#define cryprob a.cryprob              // probability that crystal will work\r
+#define probex a.probex                        // location of probe\r
+#define probey a.probey\r
+#define probecx a.probecx              // current probe quadrant\r
+#define probecy a.probecy      \r
+#define probeinx a.probeinx            // Probe x,y increment\r
+#define probeiny a.probeiny            \r
+#define proben a.proben                        // number of moves for probe\r
+#define isarmed a.isarmed              // Probe is armed\r
+#define nprobes a.nprobes              // number of probes available\r
+\r
+EXTERN int\r
+               kx[21],                 // enemy sector locations\r
+               ky[21],\r
+               starch[9][9];   // star chart\r
+\r
+EXTERN int fromcommandline; // Game start from command line options\r
+\r
+\r
+EXTERN char    passwd[10],             // Self Destruct password\r
+               *device[ndevice+1];\r
+\r
+EXTERN PLANETS nulplanet;      // zeroed planet structure\r
+\r
+EXTERN double\r
+               kpower[21],             // enemy energy levels\r
+               kdist[21],              // enemy distances\r
+               kavgd[21],              // average distances\r
+               damage[ndevice+1],              // damage encountered\r
+               future[NEVENTS+1];              // future events\r
+\r
+EXTERN int iscore, iskill; // Common PLAQ\r
+EXTERN double perdate;\r
+\r
+typedef enum {FWON, FDEPLETE, FLIFESUP, FNRG, FBATTLE,\r
+              FNEG3, FNOVA, FSNOVAED, FABANDN, FDILITHIUM,\r
+                         FMATERIALIZE, FPHASER, FLOST, FMINING, FDPLANET,\r
+                         FPNOVA, FSSC, FSTRACTOR, FDRAY, FTRIBBLE,\r
+                         FHOLE} FINTYPE ;\r
+\r
+\r
+EXTERN double aaitem;\r
+EXTERN char citem[10];\r
+\r
+\r
+/* Define devices */\r
+#define DSRSENS 1\r
+#define DLRSENS 2\r
+#define DPHASER 3\r
+#define DPHOTON 4\r
+#define DLIFSUP 5\r
+#define DWARPEN 6\r
+#define DIMPULS 7\r
+#define DSHIELD 8\r
+#define DRADIO  9\r
+#define DSHUTTL 10\r
+#define DCOMPTR 11\r
+#define DTRANSP 12\r
+#define DSHCTRL 13\r
+#define DDRAY   14  // Added deathray\r
+#define DDSP    15  // Added deep space probe\r
+\r
+/* Define future events */\r
+#define FSPY   0       // Spy event happens always (no future[] entry)\r
+                                       // can cause SC to tractor beam Enterprise\r
+#define FSNOVA  1   // Supernova\r
+#define FTBEAM  2   // Commander tractor beams Enterprise\r
+#define FSNAP   3   // Snapshot for time warp\r
+#define FBATTAK 4   // Commander attacks base\r
+#define FCDBAS  5   // Commander destroys base\r
+#define FSCMOVE 6   // Supercommander moves (might attack base)\r
+#define FSCDBAS 7   // Supercommander destroys base\r
+#define FDSPROB 8   // Move deep space probe\r
+\r
+#ifdef INCLUDED\r
+PLANETS nulplanet = {0};\r
+char *device[ndevice+1] = {\r
+       "",\r
+       "S. R. Sensors",\r
+       "L. R. Sensors",\r
+       "Phasers",\r
+       "Photon Tubes",\r
+       "Life Support",\r
+       "Warp Engines",\r
+       "Impulse Engines",\r
+       "Shields",\r
+       "Subspace Radio",\r
+       "Shuttle Craft",\r
+       "Computer",\r
+       "Transporter",\r
+       "Shield Control",\r
+    "Death Ray",\r
+    "D. S. Probe"};                                                                    \r
+#endif\r
+\r
+#define TRUE (1)\r
+#define FALSE (0)\r
+\r
+#define IHR 'R'\r
+#define IHK 'K'\r
+#define IHC 'C'\r
+#define IHS 'S'\r
+#define IHSTAR '*'\r
+#define IHP 'P'\r
+#define IHB 'B'\r
+#define IHBLANK ' '\r
+#define IHDOT '.'\r
+#define IHQUEST '?'\r
+#define IHE 'E'\r
+#define IHF 'F'\r
+#define IHT 'T'\r
+#define IHWEB '#'\r
+#define IHGREEN 'G'\r
+#define IHYELLOW 'Y'\r
+#define IHRED 'R'\r
+#define IHDOCKED 'D'\r
+\r
+\r
+/* Function prototypes */\r
+void prelim(void);\r
+void attack(int);\r
+int choose(void);\r
+void setup(void);\r
+void score(void);\r
+void atover(int);\r
+void srscan(int);\r
+void lrscan(void);\r
+void phasers(void);\r
+void photon(void);\r
+void warp(int);\r
+void sheild(int);\r
+void dock(void);\r
+void dreprt(void);\r
+void chart(int);\r
+void impuls(void);\r
+void wait(void);\r
+void setwrp(void);\r
+void events(void);\r
+void report(int);\r
+void eta(void);\r
+void help(void);\r
+void abandn(void);\r
+void finish(FINTYPE);\r
+void dstrct(void);\r
+void kaboom(void);\r
+void freeze(int);\r
+void thaw(void);\r
+void plaque(void);\r
+int scan(void);\r
+#define IHEOL (0)\r
+#define IHALPHA (1)\r
+#define IHREAL (2)\r
+void chew(void);\r
+void chew2(void);\r
+void skip(int);\r
+void prout(char *s);\r
+void proutn(char *s);\r
+void stars(void);\r
+void newqad(int);\r
+int ja(void);\r
+void cramen(int);\r
+void crmshp(void);\r
+void cramlc(int, int, int);\r
+double expran(double);\r
+double Rand(void);\r
+void iran8(int *, int *);\r
+void iran10(int *, int *);\r
+double square(double);\r
+void dropin(int, int*, int*);\r
+void newcnd(void);\r
+void sortkl(void);\r
+void move(void);\r
+void ram(int, int, int, int);\r
+void crmena(int, int, int, int, int);\r
+void deadkl(int, int, int, int, int);\r
+void timwrp(void);\r
+void movcom(void);\r
+void torpedo(double, double, int, int, double *);\r
+void cramf(double, int, int);\r
+void crami(int, int);\r
+void huh(void);\r
+void pause(int);\r
+void nova(int, int);\r
+void snova(int, int);\r
+void scom(int *);\r
+void hittem(double *);\r
+void prouts(char *);\r
+int isit(char *);\r
+void preport(void);\r
+void orbit(void);\r
+void sensor(void);\r
+void beam(void);\r
+void mine(void);\r
+void usecrystals(void);\r
+void shuttle(void);\r
+void deathray(void);\r
+void debugme(void);\r
+void attakreport(void);\r
+void movetho(void);\r
+void probe(void);\r