Get rid of all DOS-generated CRs.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 20 Jan 2005 21:31:19 +0000 (21:31 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 20 Jan 2005 21:31:19 +0000 (21:31 +0000)
ai.c
battle.c
events.c
finish.c
moving.c
planets.c
reports.c
setup.c
sst.c
sst.h

diff --git a/ai.c b/ai.c
index ba970a36ee9f18dcdbf2f43aa1fcf564e19788cc..719c50c4bb51c62e659f9521aa71fb44ca67c937 100644 (file)
--- a/ai.c
+++ b/ai.c
-#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
-               game.state.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 <= game.state.remcom; l++)\r
-                               if (game.state.cx[l]==iqx && game.state.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 (game.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 (game.damage[DSRSENS] == 0.0 || game.damage[DLRSENS] == 0.0 ||\r
-               condit == IHDOCKED) {\r
-               crmena(1, ienm, 2, game.kx[loccom], game.ky[loccom]);\r
-               proutn(" escapes to %s (and regains strength).",\r
-                      cramlc(quadrant, iqx, iqy));\r
-       }\r
-       /* handle local matters related to escape */\r
-       game.quad[game.kx[loccom]][game.ky[loccom]] = IHDOT;\r
-       game.kx[loccom] = game.kx[nenhere];\r
-       game.ky[loccom] = game.ky[nenhere];\r
-       game.kavgd[loccom] = game.kavgd[nenhere];\r
-       game.kpower[loccom] = game.kpower[nenhere];\r
-       game.kdist[loccom] = game.kdist[nenhere];\r
-       klhere--;\r
-       nenhere--;\r
-       if (condit != IHDOCKED) newcnd();\r
-       /* Handle global matters related to escape */\r
-       game.state.galaxy[quadx][quady] -= 100;\r
-       game.state.galaxy[iqx][iqy] += 100;\r
-       if (ienm==IHS) {\r
-               ishere=0;\r
-               iscate=0;\r
-               ientesc=0;\r
-               isatb=0;\r
-               game.future[FSCMOVE]=0.2777+game.state.date;\r
-               game.future[FSCDBAS]=1e30;\r
-               game.state.isx=iqx;\r
-               game.state.isy=iqy;\r
-       }\r
-       else {\r
-               for (l=1; l<=game.state.remcom; l++) {\r
-                       if (game.state.cx[l]==quadx && game.state.cy[l]==quady) {\r
-                               game.state.cx[l]=iqx;\r
-                               game.state.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 = game.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
-               (game.kpower[loccom] <= 500.0 || (condit==IHDOCKED && game.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 = game.kpower[loccom]+100.0*nenhere+400*(nbaddys-1);\r
-               if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */\r
-               if (game.damage[DPHASER] == 0.0 || game.damage[DPHOTON] == 0.0) {\r
-                       if (game.damage[DPHASER] != 0) /* phasers damaged */\r
-                               forces += 300.0;\r
-                       else\r
-                               forces -= 0.2*(energy - 2500.0);\r
-                       if (game.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 = %1.2f", motion);\r
-                       proutn("  FORCES = %1,2f", forces);\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
-               prout("NSTEPS = %d", nsteps);\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
-       /* main move loop */\r
-       for (ll = 1; ll <= nsteps; ll++) {\r
-#ifdef DEBUG\r
-               if (idebug) {\r
-                       prout("%d", ll);\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 (game.quad[lookx][looky] != IHDOT) {\r
-                               /* See if we should ram ship */\r
-                               if (game.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
-                               prout(cramlc(neither, nextx, nexty));\r
-                       }\r
-#endif\r
-               }\r
-               else break; /* done early */\r
-       }\r
-       /* Put commander in place within same quadrant */\r
-       game.quad[comx][comy] = IHDOT;\r
-       game.quad[nextx][nexty] = ienm;\r
-       if (nextx != comx || nexty != comy) {\r
-               /* it moved */\r
-               game.kx[loccom] = nextx;\r
-               game.ky[loccom] = nexty;\r
-               game.kdist[loccom] = game.kavgd[loccom] =\r
-                                       sqrt(square(sectx-nextx)+square(secty-nexty));\r
-               if (game.damage[DSRSENS] == 0 || condit == IHDOCKED) {\r
-                       proutn("***");\r
-                       cramen(ienm);\r
-                       proutn(" from");\r
-                       cramlc(2, comx, comy);\r
-                       if (game.kdist[loccom] < dist1) proutn(" advances to");\r
-                       else proutn(" retreats to ");\r
-                       prout(cramlc(sector, nextx, nexty));\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 = game.kx[i];\r
-               iy = game.ky[i];\r
-               if (game.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 = game.kx[i];\r
-               iy = game.ky[i];\r
-               if (game.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 = game.kx[i];\r
-               iy = game.ky[i];\r
-               if (game.quad[ix][iy] == IHK || game.quad[ix][iy] == IHR)\r
-                       movebaddy(ix, iy, i, game.quad[ix][iy]);\r
-       }\r
-\r
-       sortkl();\r
-}\r
-\r
-static int movescom(int iqx, int iqy, int flag, int *ipage) {\r
-       int i;\r
-\r
-       if ((iqx==quadx && iqy==quady) ||\r
-               iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
-               game.state.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 <= game.state.rembase; i++)\r
-                       if (game.state.baseqx[i]==iqx && game.state.baseqy[i]==iqy) return 1;\r
-       }\r
-       if (justin && !iscate) return 1;\r
-       /* do the move */\r
-       game.state.galaxy[game.state.isx][game.state.isy] -= 100;\r
-       game.state.isx = iqx;\r
-       game.state.isy = iqy;\r
-       game.state.galaxy[game.state.isx][game.state.isy] += 100;\r
-       if (ishere) {\r
-               /* SC has scooted, Remove him from current quadrant */\r
-               iscate=0;\r
-               isatb=0;\r
-               ishere=0;\r
-               ientesc=0;\r
-               game.future[FSCDBAS]=1e30;\r
-               for (i = 1; i <= nenhere; i++) \r
-                       if (game.quad[game.kx[i]][game.ky[i]] == IHS) break;\r
-               game.quad[game.kx[i]][game.ky[i]] = IHDOT;\r
-               game.kx[i] = game.kx[nenhere];\r
-               game.ky[i] = game.ky[nenhere];\r
-               game.kdist[i] = game.kdist[nenhere];\r
-               game.kavgd[i] = game.kavgd[nenhere];\r
-               game.kpower[i] = game.kpower[nenhere];\r
-               klhere--;\r
-               nenhere--;\r
-               if (condit!=IHDOCKED) newcnd();\r
-               sortkl();\r
-       }\r
-       /* check for a helpful planet */\r
-       for (i = 0; i < inplan; i++) {\r
-               if (game.state.plnets[i].x==game.state.isx && game.state.plnets[i].y==game.state.isy &&\r
-                       game.state.plnets[i].crystals == 1) {\r
-                       /* destroy the planet */\r
-                       DESTROY(&game.state.plnets[i]);\r
-                       game.state.newstuf[game.state.isx][game.state.isy] -= 1;\r
-                       if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
-                               if (*ipage==0) pause_game(1);\r
-                               *ipage = 1;\r
-                               prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
-                               proutn("   a planet in ");\r
-                               proutn(cramlc(quadrant, game.state.isx, game.state.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 = ((game.state.killc+game.state.killk)/(game.state.date+0.01-indate) < 0.1*skill*(skill+1.0) ||\r
-                       (game.state.date-indate) < 3.0);\r
-       if (iscate==0 && flag) {\r
-               /* compute move away from Enterprise */\r
-               ideltax = game.state.isx-quadx;\r
-               ideltay = game.state.isy-quady;\r
-               if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {\r
-                       /* circulate in space */\r
-                       ideltax = game.state.isy-quady;\r
-                       ideltay = quadx-game.state.isx;\r
-               }\r
-       }\r
-       else {\r
-               /* compute distances to starbases */\r
-               if (game.state.rembase <= 0) {\r
-                       /* nothing left to do */\r
-                       game.future[FSCMOVE] = 1e30;\r
-                       return;\r
-               }\r
-               sx = game.state.isx;\r
-               sy = game.state.isy;\r
-               for (i = 1; i <= game.state.rembase; i++) {\r
-                       basetbl[i] = i;\r
-                       ibqx = game.state.baseqx[i];\r
-                       ibqy = game.state.baseqy[i];\r
-                       bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));\r
-               }\r
-               if (game.state.rembase > 1) {\r
-                       /* sort into nearest first order */\r
-                       int iswitch;\r
-                       do {\r
-                               iswitch = 0;\r
-                               for (i=1; i < game.state.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 <= game.state.rembase; i2++) {\r
-                       i = basetbl[i2];        /* bug in original had it not finding nearest*/\r
-                       ibqx = game.state.baseqx[i];\r
-                       ibqy = game.state.baseqy[i];\r
-                       if ((ibqx == quadx && ibqy == quady) ||\r
-                               (ibqx == batx && ibqy == baty) ||\r
-                               game.state.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 <= game.state.remcom; j++) {\r
-                               if (ibqx==game.state.cx[j] && ibqy==game.state.cy[j] && ifindit!= 2) {\r
-                                               ifindit = 2;\r
-                                               iwhichb = i;\r
-                                               break;\r
-                               }\r
-                       }\r
-                       if (j > game.state.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 = game.state.baseqx[iwhichb];\r
-               ibqy = game.state.baseqy[iwhichb];\r
-               /* decide how to move toward base */\r
-               ideltax = ibqx - game.state.isx;\r
-               ideltay = ibqy - game.state.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 = game.state.isx + ideltax;\r
-       iqy = game.state.isy + ideltax;\r
-       if (movescom(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 = game.state.isy + 1;\r
-                               if (movescom(iqx, iqy, flag, ipage)) {\r
-                                       iqy = game.state.isy - 1;\r
-                                       movescom(iqx, iqy, flag, ipage);\r
-                               }\r
-                       }\r
-                       else {\r
-                               iqx = game.state.isx + 1;\r
-                               if (movescom(iqx, iqy, flag, ipage)) {\r
-                                       iqx = game.state.isx - 1;\r
-                                       movescom(iqx, iqy, flag, ipage);\r
-                               }\r
-                       }\r
-               }\r
-               else {\r
-                       /* try moving just in x or y */\r
-                       iqy = game.state.isy;\r
-                       if (movescom(iqx, iqy, flag, ipage)) {\r
-                               iqy = game.state.isy + ideltay;\r
-                               iqx = game.state.isx;\r
-                               movescom(iqx, iqy, flag, ipage);\r
-                       }\r
-               }\r
-       }\r
-       /* check for a base */\r
-       if (game.state.rembase == 0) {\r
-               game.future[FSCMOVE] = 1e30;\r
-       }\r
-       else for (i=1; i<=game.state.rembase; i++) {\r
-               ibqx = game.state.baseqx[i];\r
-               ibqy = game.state.baseqy[i];\r
-               if (ibqx==game.state.isx && ibqy == game.state.isy && game.state.isx != batx && game.state.isy != baty) {\r
-                       /* attack the base */\r
-                       if (flag) return; /* no, don't attack base! */\r
-                       iseenit = 0;\r
-                       isatb=1;\r
-                       game.future[FSCDBAS] = game.state.date + 1.0 +2.0*Rand();\r
-                       if (game.future[FCDBAS] < 1e30) game.future[FSCDBAS] +=\r
-                               game.future[FCDBAS]-game.state.date;\r
-                       if (game.damage[DRADIO] > 0 && condit != IHDOCKED)\r
-                               return; /* no warning */\r
-                       iseenit = 1;\r
-                       if (*ipage == 0)  pause_game(1);\r
-                       *ipage=1;\r
-                       proutn("Lt. Uhura-  \"Captain, the starbase in ");\r
-                       proutn(cramlc(quadrant, game.state.isx, game.state.isy));\r
-                       skip(1);\r
-                       prout("   reports that it is under attack from the Klingon Super-commander.");\r
-                       proutn("   It can survive until stardate %d.\"",\r
-                              (int)game.future[FSCDBAS]);\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
-                (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) ||\r
-                game.starch[game.state.isx][game.state.isy] > 0))\r
-               return;\r
-       if (*ipage==0) pause_game(1);\r
-       *ipage = 1;\r
-       prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");\r
-       proutn("   the Super-commander is in ");\r
-       proutn(cramlc(quadrant, game.state.isx, game.state. isy));\r
-       prout(".\"");\r
-       return;\r
-}\r
-\r
-void movetho(void) {\r
-       int idx, idy, im, i, dum, my;\r
-       /* Move the Tholian */\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 (game.quad[idx][idy]!= IHDOT && game.quad[idx][idy]!= IHWEB) return;\r
-       game.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 (game.quad[ithx][ithy]==IHDOT) game.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 (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;\r
-               }\r
-       }\r
-       game.quad[ithx][ithy] = IHT;\r
-        game.kx[nenhere]=ithx;\r
-        game.ky[nenhere]=ithy;\r
-\r
-       /* check to see if all holes plugged */\r
-       for (i = 1; i < 11; i++) {\r
-               if (game.quad[1][i]!=IHWEB && game.quad[1][i]!=IHT) return;\r
-               if (game.quad[10][i]!=IHWEB && game.quad[10][i]!=IHT) return;\r
-               if (game.quad[i][1]!=IHWEB && game.quad[i][1]!=IHT) return;\r
-               if (game.quad[i][10]!=IHWEB && game.quad[i][10]!=IHT) return;\r
-       }\r
-       /* All plugged up -- Tholian splits */\r
-       game.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
-       nenhere--;\r
-       return;\r
-}\r
+#include "sst.h"
+
+static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {
+       int iqx, iqy, l;
+
+       iqx = quadx+(lookx+9)/10 - 1;
+       iqy = quady+(looky+9)/10 - 1;
+       if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||
+               game.state.galaxy[iqx][iqy] > 899)
+               return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */
+       if (ienm == IHR) return 0; /* Romulans cannot escape! */
+       if (irun == 0) {
+               /* avoid intruding on another commander's territory */
+               if (ienm == IHC) {
+                       for (l = 1; l <= game.state.remcom; l++)
+                               if (game.state.cx[l]==iqx && game.state.cy[l]==iqy) return 0;
+                       /* refuse to leave if currently attacking starbase */
+                       if (batx==quadx && baty==quady) return 0;
+               }
+               /* don't leave if over 1000 units of energy */
+               if (game.kpower[loccom] > 1000.) return 0;
+       }
+       /* print escape message and move out of quadrant.
+          We know this if either short or long range sensors are working */
+       if (game.damage[DSRSENS] == 0.0 || game.damage[DLRSENS] == 0.0 ||
+               condit == IHDOCKED) {
+               crmena(1, ienm, 2, game.kx[loccom], game.ky[loccom]);
+               proutn(" escapes to %s (and regains strength).",
+                      cramlc(quadrant, iqx, iqy));
+       }
+       /* handle local matters related to escape */
+       game.quad[game.kx[loccom]][game.ky[loccom]] = IHDOT;
+       game.kx[loccom] = game.kx[nenhere];
+       game.ky[loccom] = game.ky[nenhere];
+       game.kavgd[loccom] = game.kavgd[nenhere];
+       game.kpower[loccom] = game.kpower[nenhere];
+       game.kdist[loccom] = game.kdist[nenhere];
+       klhere--;
+       nenhere--;
+       if (condit != IHDOCKED) newcnd();
+       /* Handle global matters related to escape */
+       game.state.galaxy[quadx][quady] -= 100;
+       game.state.galaxy[iqx][iqy] += 100;
+       if (ienm==IHS) {
+               ishere=0;
+               iscate=0;
+               ientesc=0;
+               isatb=0;
+               game.future[FSCMOVE]=0.2777+game.state.date;
+               game.future[FSCDBAS]=1e30;
+               game.state.isx=iqx;
+               game.state.isy=iqy;
+       }
+       else {
+               for (l=1; l<=game.state.remcom; l++) {
+                       if (game.state.cx[l]==quadx && game.state.cy[l]==quady) {
+                               game.state.cx[l]=iqx;
+                               game.state.cy[l]=iqy;
+                               break;
+                       }
+               }
+               comhere = 0;
+       }
+       return 1; /* success */
+}
+
+
+static void movebaddy(int comx, int comy, int loccom, int ienm) {
+       int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;
+       int irun = 0;
+       int krawlx, krawly;
+       int success;
+       int attempts;
+       /* This should probably be just comhere + ishere */
+       int nbaddys = skill > 3 ?
+                                 (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):
+                                 (comhere + ishere);
+       double dist1, forces;
+
+       dist1 = game.kdist[loccom];
+       mdist = dist1 + 0.5; /* Nearest integer distance */
+
+       /* If SC, check with spy to see if should hi-tail it */
+       if (ienm==IHS &&
+               (game.kpower[loccom] <= 500.0 || (condit==IHDOCKED && game.damage[DPHOTON]==0))) {
+               irun = 1;
+               motion = -10;
+       }
+       else {
+               /* decide whether to advance, retreat, or hold position */
+/* Algorithm:
+   * Enterprise has "force" based on condition of phaser and photon torpedoes.
+     If both are operating full strength, force is 1000. If both are damaged,
+        force is -1000. Having shields down subtracts an additional 1000.
+
+   * Enemy has forces equal to the energy of the attacker plus
+     100*(K+R) + 500*(C+S) - 400 for novice through good levels OR
+        346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.
+
+        Attacker Initial energy levels (nominal):
+                 Klingon   Romulan   Commander   Super-Commander
+        Novice    400        700        1200        
+        Fair      425        750        1250
+        Good      450        800        1300        1750
+        Expert    475        850        1350        1875
+        Emeritus  500        900        1400        2000
+     VARIANCE   75        200         200         200
+
+        Enemy vessels only move prior to their attack. In Novice - Good games
+        only commanders move. In Expert games, all enemy vessels move if there
+        is a commander present. In Emeritus games all enemy vessels move.
+
+  *  If Enterprise is not docked, an agressive action is taken if enemy
+     forces are 1000 greater than Enterprise.
+
+        Agressive action on average cuts the distance between the ship and
+        the enemy to 1/4 the original.
+
+  *  At lower energy advantage, movement units are proportional to the
+     advantage with a 650 advantage being to hold ground, 800 to move forward
+        1, 950 for two, 150 for back 4, etc. Variance of 100.
+
+        If docked, is reduced by roughly 1.75*skill, generally forcing a
+        retreat, especially at high skill levels.
+
+  *  Motion is limited to skill level, except for SC hi-tailing it out.
+  */
+
+               forces = game.kpower[loccom]+100.0*nenhere+400*(nbaddys-1);
+               if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */
+               if (game.damage[DPHASER] == 0.0 || game.damage[DPHOTON] == 0.0) {
+                       if (game.damage[DPHASER] != 0) /* phasers damaged */
+                               forces += 300.0;
+                       else
+                               forces -= 0.2*(energy - 2500.0);
+                       if (game.damage[DPHOTON] != 0) /* photon torpedoes damaged */
+                               forces += 300.0;
+                       else
+                               forces -= 50.0*torps;
+               }
+               else {
+                       /* phasers and photon tubes both out! */
+                       forces += 1000.0;
+               }
+               motion = 0;
+               if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */
+                       motion = ((forces+200.0*Rand())/150.0) - 5.0;
+               else {
+                       if (forces > 1000.0) /* Very strong -- move in for kill */
+                               motion = (1.0-square(Rand()))*dist1 + 1.0;
+                       if (condit==IHDOCKED) /* protected by base -- back off ! */
+                               motion -= skill*(2.0-square(Rand()));
+               }
+#ifdef DEBUG
+               if (idebug) {
+                       proutn("MOTION = %1.2f", motion);
+                       proutn("  FORCES = %1,2f", forces);
+               }
+#endif
+               /* don't move if no motion */
+               if (motion==0) return;
+               /* Limit motion according to skill */
+               if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;
+       }
+       /* calcuate preferred number of steps */
+       nsteps = motion < 0 ? -motion : motion;
+       if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */
+       if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */
+       if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */
+#ifdef DEBUG
+       if (idebug) {
+               prout("NSTEPS = %d", nsteps);
+       }
+#endif
+       /* Compute preferred values of delta X and Y */
+       mx = sectx - comx;
+       my = secty - comy;
+       if (2.0 * abs(mx) < abs(my)) mx = 0;
+       if (2.0 * abs(my) < abs(sectx-comx)) my = 0;
+       if (mx != 0) mx = mx*motion < 0 ? -1 : 1;
+       if (my != 0) my = my*motion < 0 ? -1 : 1;
+       nextx = comx;
+       nexty = comy;
+       /* main move loop */
+       for (ll = 1; ll <= nsteps; ll++) {
+#ifdef DEBUG
+               if (idebug) {
+                       prout("%d", ll);
+               }
+#endif
+               /* Check if preferred position available */
+               lookx = nextx + mx;
+               looky = nexty + my;
+               krawlx = mx < 0 ? 1 : -1;
+               krawly = my < 0 ? 1 : -1;
+               success = 0;
+               attempts = 0; /* Settle mysterious hang problem */
+               while (attempts++ < 20 && !success) {
+                       if (lookx < 1 || lookx > 10) {
+                               if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))
+                                       return;
+                               if (krawlx == mx || my == 0) break;
+                               lookx = nextx + krawlx;
+                               krawlx = -krawlx;
+                       }
+                       else if (looky < 1 || looky > 10) {
+                               if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))
+                                       return;
+                               if (krawly == my || mx == 0) break;
+                               looky = nexty + krawly;
+                               krawly = -krawly;
+                       }
+                       else if (game.quad[lookx][looky] != IHDOT) {
+                               /* See if we should ram ship */
+                               if (game.quad[lookx][looky] == ship &&
+                                       (ienm == IHC || ienm == IHS)) {
+                                       ram(1, ienm, comx, comy);
+                                       return;
+                               }
+                               if (krawlx != mx && my != 0) {
+                                       lookx = nextx + krawlx;
+                                       krawlx = -krawlx;
+                               }
+                               else if (krawly != my && mx != 0) {
+                                       looky = nexty + krawly;
+                                       krawly = -krawly;
+                               }
+                               else break; /* we have failed */
+                       }
+                       else success = 1;
+               }
+               if (success) {
+                       nextx = lookx;
+                       nexty = looky;
+#ifdef DEBUG
+                       if (idebug) {
+                               prout(cramlc(neither, nextx, nexty));
+                       }
+#endif
+               }
+               else break; /* done early */
+       }
+       /* Put commander in place within same quadrant */
+       game.quad[comx][comy] = IHDOT;
+       game.quad[nextx][nexty] = ienm;
+       if (nextx != comx || nexty != comy) {
+               /* it moved */
+               game.kx[loccom] = nextx;
+               game.ky[loccom] = nexty;
+               game.kdist[loccom] = game.kavgd[loccom] =
+                                       sqrt(square(sectx-nextx)+square(secty-nexty));
+               if (game.damage[DSRSENS] == 0 || condit == IHDOCKED) {
+                       proutn("***");
+                       cramen(ienm);
+                       proutn(" from");
+                       cramlc(2, comx, comy);
+                       if (game.kdist[loccom] < dist1) proutn(" advances to");
+                       else proutn(" retreats to ");
+                       prout(cramlc(sector, nextx, nexty));
+               }
+       }
+}
+
+void movcom(void) {
+       int ix, iy, i;
+
+#ifdef DEBUG
+       if (idebug) prout("MOVCOM");
+#endif
+
+       /* Figure out which Klingon is the commander (or Supercommander)
+          and do move */
+       if (comhere) for (i = 1; i <= nenhere; i++) {
+               ix = game.kx[i];
+               iy = game.ky[i];
+               if (game.quad[ix][iy] == IHC) {
+                       movebaddy(ix, iy, i, IHC);
+                       break;
+               }
+       }
+       if (ishere) for (i = 1; i <= nenhere; i++) {
+               ix = game.kx[i];
+               iy = game.ky[i];
+               if (game.quad[ix][iy] == IHS) {
+                       movebaddy(ix, iy, i, IHS);
+                       break;
+               }
+       }
+       /* if skill level is high, move other Klingons and Romulans too!
+          Move these last so they can base their actions on what the
+       commander(s) do. */
+       if (skill > 3) for (i = 1; i <= nenhere; i++) {
+               ix = game.kx[i];
+               iy = game.ky[i];
+               if (game.quad[ix][iy] == IHK || game.quad[ix][iy] == IHR)
+                       movebaddy(ix, iy, i, game.quad[ix][iy]);
+       }
+
+       sortkl();
+}
+
+static int movescom(int iqx, int iqy, int flag, int *ipage) {
+       int i;
+
+       if ((iqx==quadx && iqy==quady) ||
+               iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||
+               game.state.galaxy[iqx][iqy] > 899) return 1;
+       if (flag) {
+               /* Avoid quadrants with bases if we want to avoid Enterprise */
+               for (i = 1; i <= game.state.rembase; i++)
+                       if (game.state.baseqx[i]==iqx && game.state.baseqy[i]==iqy) return 1;
+       }
+       if (justin && !iscate) return 1;
+       /* do the move */
+       game.state.galaxy[game.state.isx][game.state.isy] -= 100;
+       game.state.isx = iqx;
+       game.state.isy = iqy;
+       game.state.galaxy[game.state.isx][game.state.isy] += 100;
+       if (ishere) {
+               /* SC has scooted, Remove him from current quadrant */
+               iscate=0;
+               isatb=0;
+               ishere=0;
+               ientesc=0;
+               game.future[FSCDBAS]=1e30;
+               for (i = 1; i <= nenhere; i++) 
+                       if (game.quad[game.kx[i]][game.ky[i]] == IHS) break;
+               game.quad[game.kx[i]][game.ky[i]] = IHDOT;
+               game.kx[i] = game.kx[nenhere];
+               game.ky[i] = game.ky[nenhere];
+               game.kdist[i] = game.kdist[nenhere];
+               game.kavgd[i] = game.kavgd[nenhere];
+               game.kpower[i] = game.kpower[nenhere];
+               klhere--;
+               nenhere--;
+               if (condit!=IHDOCKED) newcnd();
+               sortkl();
+       }
+       /* check for a helpful planet */
+       for (i = 0; i < inplan; i++) {
+               if (game.state.plnets[i].x==game.state.isx && game.state.plnets[i].y==game.state.isy &&
+                       game.state.plnets[i].crystals == 1) {
+                       /* destroy the planet */
+                       DESTROY(&game.state.plnets[i]);
+                       game.state.newstuf[game.state.isx][game.state.isy] -= 1;
+                       if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
+                               if (*ipage==0) pause_game(1);
+                               *ipage = 1;
+                               prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");
+                               proutn("   a planet in ");
+                               proutn(cramlc(quadrant, game.state.isx, game.state.isy));
+                               prout(" has been destroyed");
+                               prout("   by the Super-commander.\"");
+                       }
+                       break;
+               }
+       }
+       return 0; /* looks good! */
+}
+                       
+               
+       
+
+
+void scom(int *ipage) {
+       int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;
+       int iqx, iqy;
+       int basetbl[6];
+       double bdist[6];
+       int flag;
+#ifdef DEBUG
+       if (idebug) prout("SCOM");
+#endif
+
+       /* Decide on being active or passive */
+       flag = ((game.state.killc+game.state.killk)/(game.state.date+0.01-indate) < 0.1*skill*(skill+1.0) ||
+                       (game.state.date-indate) < 3.0);
+       if (iscate==0 && flag) {
+               /* compute move away from Enterprise */
+               ideltax = game.state.isx-quadx;
+               ideltay = game.state.isy-quady;
+               if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {
+                       /* circulate in space */
+                       ideltax = game.state.isy-quady;
+                       ideltay = quadx-game.state.isx;
+               }
+       }
+       else {
+               /* compute distances to starbases */
+               if (game.state.rembase <= 0) {
+                       /* nothing left to do */
+                       game.future[FSCMOVE] = 1e30;
+                       return;
+               }
+               sx = game.state.isx;
+               sy = game.state.isy;
+               for (i = 1; i <= game.state.rembase; i++) {
+                       basetbl[i] = i;
+                       ibqx = game.state.baseqx[i];
+                       ibqy = game.state.baseqy[i];
+                       bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));
+               }
+               if (game.state.rembase > 1) {
+                       /* sort into nearest first order */
+                       int iswitch;
+                       do {
+                               iswitch = 0;
+                               for (i=1; i < game.state.rembase-1; i++) {
+                                       if (bdist[i] > bdist[i+1]) {
+                                               int ti = basetbl[i];
+                                               double t = bdist[i];
+                                               bdist[i] = bdist[i+1];
+                                               bdist[i+1] = t;
+                                               basetbl[i] = basetbl[i+1];
+                                               basetbl[i+1] =ti;
+                                               iswitch = 1;
+                                       }
+                               }
+                       } while (iswitch);
+               }
+               /* look for nearest base without a commander, no Enterprise, and
+                  without too many Klingons, and not already under attack. */
+               ifindit = iwhichb = 0;
+
+               for (i2 = 1; i2 <= game.state.rembase; i2++) {
+                       i = basetbl[i2];        /* bug in original had it not finding nearest*/
+                       ibqx = game.state.baseqx[i];
+                       ibqy = game.state.baseqy[i];
+                       if ((ibqx == quadx && ibqy == quady) ||
+                               (ibqx == batx && ibqy == baty) ||
+                               game.state.galaxy[ibqx][ibqy] > 899) continue;
+                       /* if there is a commander, an no other base is appropriate,
+                          we will take the one with the commander */
+                       for (j = 1; j <= game.state.remcom; j++) {
+                               if (ibqx==game.state.cx[j] && ibqy==game.state.cy[j] && ifindit!= 2) {
+                                               ifindit = 2;
+                                               iwhichb = i;
+                                               break;
+                               }
+                       }
+                       if (j > game.state.remcom) { /* no commander -- use this one */
+                               ifindit = 1;
+                               iwhichb = i;
+                               break;
+                       }
+               }
+               if (ifindit==0) return; /* Nothing suitable -- wait until next time*/
+               ibqx = game.state.baseqx[iwhichb];
+               ibqy = game.state.baseqy[iwhichb];
+               /* decide how to move toward base */
+               ideltax = ibqx - game.state.isx;
+               ideltay = ibqy - game.state.isy;
+       }
+       /* Maximum movement is 1 quadrant in either or both axis */
+       if (ideltax > 1) ideltax = 1;
+       if (ideltax < -1) ideltax = -1;
+       if (ideltay > 1) ideltay = 1;
+       if (ideltay < -1) ideltay = -1;
+
+       /* try moving in both x and y directions */
+       iqx = game.state.isx + ideltax;
+       iqy = game.state.isy + ideltax;
+       if (movescom(iqx, iqy, flag, ipage)) {
+               /* failed -- try some other maneuvers */
+               if (ideltax==0 || ideltay==0) {
+                       /* attempt angle move */
+                       if (ideltax != 0) {
+                               iqy = game.state.isy + 1;
+                               if (movescom(iqx, iqy, flag, ipage)) {
+                                       iqy = game.state.isy - 1;
+                                       movescom(iqx, iqy, flag, ipage);
+                               }
+                       }
+                       else {
+                               iqx = game.state.isx + 1;
+                               if (movescom(iqx, iqy, flag, ipage)) {
+                                       iqx = game.state.isx - 1;
+                                       movescom(iqx, iqy, flag, ipage);
+                               }
+                       }
+               }
+               else {
+                       /* try moving just in x or y */
+                       iqy = game.state.isy;
+                       if (movescom(iqx, iqy, flag, ipage)) {
+                               iqy = game.state.isy + ideltay;
+                               iqx = game.state.isx;
+                               movescom(iqx, iqy, flag, ipage);
+                       }
+               }
+       }
+       /* check for a base */
+       if (game.state.rembase == 0) {
+               game.future[FSCMOVE] = 1e30;
+       }
+       else for (i=1; i<=game.state.rembase; i++) {
+               ibqx = game.state.baseqx[i];
+               ibqy = game.state.baseqy[i];
+               if (ibqx==game.state.isx && ibqy == game.state.isy && game.state.isx != batx && game.state.isy != baty) {
+                       /* attack the base */
+                       if (flag) return; /* no, don't attack base! */
+                       iseenit = 0;
+                       isatb=1;
+                       game.future[FSCDBAS] = game.state.date + 1.0 +2.0*Rand();
+                       if (game.future[FCDBAS] < 1e30) game.future[FSCDBAS] +=
+                               game.future[FCDBAS]-game.state.date;
+                       if (game.damage[DRADIO] > 0 && condit != IHDOCKED)
+                               return; /* no warning */
+                       iseenit = 1;
+                       if (*ipage == 0)  pause_game(1);
+                       *ipage=1;
+                       proutn("Lt. Uhura-  \"Captain, the starbase in ");
+                       proutn(cramlc(quadrant, game.state.isx, game.state.isy));
+                       skip(1);
+                       prout("   reports that it is under attack from the Klingon Super-commander.");
+                       proutn("   It can survive until stardate %d.\"",
+                              (int)game.future[FSCDBAS]);
+                       if (resting==0) return;
+                       prout("Mr. Spock-  \"Captain, shall we cancel the rest period?\"");
+                       if (ja()==0) return;
+                       resting = 0;
+                       Time = 0.0; /* actually finished */
+                       return;
+               }
+       }
+       /* Check for intelligence report */
+       if (
+#ifdef DEBUG
+               idebug==0 &&
+#endif
+               (Rand() > 0.2 ||
+                (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) ||
+                game.starch[game.state.isx][game.state.isy] > 0))
+               return;
+       if (*ipage==0) pause_game(1);
+       *ipage = 1;
+       prout("Lt. Uhura-  \"Captain, Starfleet Intelligence reports");
+       proutn("   the Super-commander is in ");
+       proutn(cramlc(quadrant, game.state.isx, game.state. isy));
+       prout(".\"");
+       return;
+}
+
+void movetho(void) {
+       int idx, idy, im, i, dum, my;
+       /* Move the Tholian */
+       if (ithere==0 || justin == 1) return;
+
+       if (ithx == 1 && ithy == 1) {
+               idx = 1; idy = 10;
+       }
+       else if (ithx == 1 && ithy == 10) {
+               idx = 10; idy = 10;
+       }
+       else if (ithx == 10 && ithy == 10) {
+               idx = 10; idy = 1;
+       }
+       else if (ithx == 10 && ithy == 1) {
+               idx = 1; idy = 1;
+       }
+       else {
+               /* something is wrong! */
+               ithere = 0;
+               return;
+       }
+
+       /* Do nothing if we are blocked */
+       if (game.quad[idx][idy]!= IHDOT && game.quad[idx][idy]!= IHWEB) return;
+       game.quad[ithx][ithy] = IHWEB;
+
+       if (ithx != idx) {
+               /* move in x axis */
+               im = fabs((double)idx - ithx)/((double)idx - ithx);
+               while (ithx != idx) {
+                       ithx += im;
+                       if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;
+               }
+       }
+       else if (ithy != idy) {
+               /* move in y axis */
+               im = fabs((double)idy - ithy)/((double)idy - ithy);
+               while (ithy != idy) {
+                       ithy += im;
+                       if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;
+               }
+       }
+       game.quad[ithx][ithy] = IHT;
+        game.kx[nenhere]=ithx;
+        game.ky[nenhere]=ithy;
+
+       /* check to see if all holes plugged */
+       for (i = 1; i < 11; i++) {
+               if (game.quad[1][i]!=IHWEB && game.quad[1][i]!=IHT) return;
+               if (game.quad[10][i]!=IHWEB && game.quad[10][i]!=IHT) return;
+               if (game.quad[i][1]!=IHWEB && game.quad[i][1]!=IHT) return;
+               if (game.quad[i][10]!=IHWEB && game.quad[i][10]!=IHT) return;
+       }
+       /* All plugged up -- Tholian splits */
+       game.quad[ithx][ithy]=IHWEB;
+       dropin(IHBLANK, &dum, &my);
+       crmena(1,IHT, 2, ithx, ithy);
+       prout(" completes web.");
+       ithere = ithx = ithy = 0;
+       nenhere--;
+       return;
+}
index 97cea709fca529f5d140f6601c8f7fb3fb0699a4..845aa832937bcd98f2fd2c2052ce6aacceba8fed 100644 (file)
--- a/battle.c
+++ b/battle.c
-#ifdef SERGEEV\r
-#include <conio.h>\r
-#include <unistd.h>\r
-#include "sstlinux.h"\r
-#endif /* SERGEEV */\r
-#include "sst.h"\r
-\r
-void doshield(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 (game.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 (game.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
-               case NONE:;     /* avoid gcc warning */\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
-                case IHQUEST: type = 4.0; 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
-       prout("***Sickbay reports %d casualties", icas);\r
-       casual += icas;\r
-       for (l=1; l <= NDEVICES; l++) {\r
-               if (l == DDRAY) continue; // Don't damage deathray \r
-               if (game.damage[l] < 0) continue;\r
-               extradm = (10.0*type*Rand()+1.0)*damfac;\r
-               game.damage[l] += Time + extradm; /* Damage for at least time of travel! */\r
-       }\r
-       shldup = 0;\r
-       if (game.state.remkl) {\r
-               pause_game(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, int wait) {\r
-        int l, iquad=0, ix=0, iy=0, jx=0, jy=0, shoved=0, ll;\r
-#ifdef SERGEEV\r
-       int crx,cry;\r
-       \r
-#endif /* SERGEEV */\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
-#ifdef SERGEEV\r
-        crx=wherex();\r
-        cry=wherey();\r
-        if (game.damage[DSRSENS]==0 || condit==IHDOCKED) setwnd(1);\r
-       else setwnd(4);\r
-#endif /* SERGEEV */\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
-#ifndef SERGEEV\r
-               if (l==4 || l==9) skip(1);\r
-               proutn("%d - %d   ", (int)x, (int)y);\r
-               iquad=game.quad[ix][iy];\r
-#else\r
-                iquad=game.quad[ix][iy];\r
-                if (game.damage[DSRSENS]==0 || condit==IHDOCKED){\r
-                   drawmaps(2);\r
-                   delay((wait!=1)*400);\r
-                   wait=1;\r
-                   gotoxy(iy*2+3,ix+2);\r
-                   if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){\r
-                      game.quad[ix][iy]='+';\r
-                      drawmaps(2);\r
-                      game.quad[ix][iy]=iquad;\r
-                      sound(l*10);\r
-                      delay(100);\r
-                      nosound();\r
-                   }\r
-                   else {\r
-                        game.quad[ix][iy]|=128;\r
-                        drawmaps(2);\r
-                        game.quad[ix][iy]=iquad;\r
-                        _setcursortype(_NOCURSOR);\r
-                        sound(500);\r
-                        delay(1000);\r
-                        nosound();\r
-                        lowvideo();\r
-                        _setcursortype(_NORMALCURSOR);\r
-                   }\r
-                }\r
-                else {\r
-                 proutn("%d - %d   ", (int)x, (int)y);\r
-               }\r
-#endif /* SERGEEV */\r
-               if (iquad==IHDOT) continue;\r
-               /* hit something */\r
-#ifndef SERGEEV\r
-               skip(1);\r
-#else\r
-               setwnd(4);\r
-               gotoxy(crx,cry);\r
-#endif\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
-#ifndef SERGEEV\r
-                               newcnd(); /* undock */\r
-#endif /* SERGEEV */\r
-                               /* We may be displaced. */\r
-                               if (landed==1 || condit==IHDOCKED) 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 (game.quad[jx][jy]==IHBLANK) {\r
-                                       finish(FHOLE);\r
-                                       return;\r
-                               }\r
-                               if (game.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==game.kx[ll] && iy==game.ky[ll]) break;\r
-                               kp = fabs(game.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
-                               game.kpower[ll] -= (game.kpower[ll]<0 ? -h1 : h1);\r
-                               if (game.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 (game.quad[jx][jy]==IHBLANK) {\r
-                                       prout(" buffeted into black hole.");\r
-                                       deadkl(ix, iy, iquad, jx, jy);\r
-                                       return;\r
-                               }\r
-                               if (game.quad[jx][jy]!=IHDOT) {\r
-                                       /* can't move into object */\r
-                                       prout(" damaged but not destroyed.");\r
-                                       return;\r
-                               }\r
-                               proutn(" damaged--");\r
-                               game.kx[ll] = jx;\r
-                               game.ky[ll] = jy;\r
-                               shoved = 1;\r
-                               break;\r
-                       case IHB: /* Hit a base */\r
-                               skip(1);\r
-                               prout("***STARBASE DESTROYED..");\r
-                               if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;\r
-                               for (ll=1; ll<=game.state.rembase; ll++) {\r
-                                       if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {\r
-                                               game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];\r
-                                               game.state.baseqy[ll]=game.state.baseqy[game.state.rembase];\r
-                                               break;\r
-                                       }\r
-                               }\r
-                               game.quad[ix][iy]=IHDOT;\r
-                               game.state.rembase--;\r
-                               basex=basey=0;\r
-                               game.state.galaxy[quadx][quady] -= 10;\r
-                               game.state.basekl++;\r
-                               newcnd();\r
-                               return;\r
-                       case IHP: /* Hit a planet */\r
-                               crmena(1, iquad, 2, ix, iy);\r
-                               prout(" destroyed.");\r
-                               game.state.nplankl++;\r
-                               game.state.newstuf[quadx][quady] -= 1;\r
-                               DESTROY(&game.state.plnets[iplnet]);\r
-                               iplnet = 0;\r
-                               plnetx = plnety = 0;\r
-                               game.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
-                            if (Rand()>0.7) {  // Used to be certain death \r
-                               skip(1);\r
-                               prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");\r
-                               skip(1);\r
-                               prouts("    HACK!     HACK!    HACK!        *CHOKE!*  ");\r
-                               skip(1);\r
-                               proutn("Mr. Spock-");\r
-                               prouts("  \"Fascinating!\"");\r
-                               skip(1);\r
-                                deadkl(ix, iy, iquad, ix, iy);\r
-                            } else {\r
-                               /*\r
-                                * Stas Sergeev added the possibility that\r
-                                * you can shove the Thingy.\r
-                                */\r
-                                iqengry=1;\r
-                                shoved=1;\r
-                            }\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
-                               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
-#ifndef SERGEEV\r
-                                       prout(" destroyed.");\r
-#endif /* SERGEEV */\r
-                                       game.quad[ix][iy] = IHDOT;\r
-                                       ithere = 0;\r
-                                       ithx = ithy = 0;\r
-#ifdef SERGEEV\r
-                                        deadkl(ix, iy, iquad, ix, iy);\r
-#endif /* SERGEEV */\r
-                                       return;\r
-                               }\r
-                               skip(1);\r
-                               crmena(1, IHT, 2, ix, iy);\r
-                               if (Rand() > 0.05) {\r
-                                       prout(" survives photon blast.");\r
-                                       return;\r
-                               }\r
-                               prout(" disappears.");\r
-                               game.quad[ix][iy] = IHWEB;\r
-                               ithere = ithx = ithy = 0;\r
-                               nenhere--;\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
-#ifdef SERGEEV\r
-        if(curwnd!=4) {\r
-           setwnd(4);\r
-           gotoxy(crx,cry);\r
-       }\r
-#endif /* SERGEEV */\r
-       if (shoved) {\r
-               game.quad[jx][jy]=iquad;\r
-               game.quad[ix][iy]=IHDOT;\r
-               prout(" displaced by blast to %s ", cramlc(sector, jx, jy));\r
-               for (ll=1; ll<=nenhere; ll++)\r
-                       game.kdist[ll] = game.kavgd[ll] = sqrt(square(sectx-game.kx[ll])+square(secty-game.ky[ll]));\r
-               sortkl();\r
-               return;\r
-       }\r
-#ifndef SERGEEV\r
-       skip(1);\r
-#endif /* SERGEEV */\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[NDEVICES+1];\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 <= NDEVICES; l++) {\r
-               do {\r
-                       j = NDEVICES*Rand()+1.0;\r
-                       /* Cheat to prevent shuttle damage unless on ship */\r
-               } while (game.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
-               game.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 (game.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)&&(k!=0)) movcom();\r
-       if (nenhere==0 || (nenhere==1 && iqhere && iqengry==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 (game.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 (game.kpower[l] < 500) r *= 0.25; \r
-               jx = game.kx[l];\r
-               jy = game.ky[l];\r
-               iquad = game.quad[jx][jy];\r
-                if (iquad==IHT || (iquad==IHQUEST && !iqengry)) continue;\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
-                        (iquad==IHQUEST && r > 0.05);\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 = game.kpower[l]*pow(dustfac,game.kavgd[l]);\r
-                       game.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 (game.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*game.kpower[l]*r;\r
-                       torpedo(course, r, jx, jy, &hit, 0);\r
-                       if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */\r
-                       if (game.state.galaxy[quadx][quady] == 1000 ||\r
-                               alldone) return; /* Supernova or finished */\r
-                       if (hit == 0) continue;\r
-               }\r
-                if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {\r
-                       /* shields will take hits */\r
-                        double absorb, hitsh, propor = pfac*shield*(condit==IHDOCKED ? 2.1 : 1.0);\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 (condit==IHDOCKED) dock(0);\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
-               proutn("%d unit hit", (int)hit);\r
-               if ((game.damage[DSRSENS] > 0 && itflag) || skill <= 2) {\r
-                       proutn(" on the ");\r
-                       crmshp();\r
-               }\r
-               if (game.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
-               prout("Hit %g energy %g", hit, energy);\r
-               energy -= hit;\r
-                if (condit==IHDOCKED) dock(0);\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 %2d    shields ", (int)energy);\r
-               if (shldup) proutn("up ");\r
-               else if (game.damage[DSHIELD] == 0) proutn("down ");\r
-               else proutn("damaged, ");\r
-       }\r
-       prout("%d%%,   torpedoes left %d", percent, torps);\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
-                       prout("Mc Coy-  \"Sickbay to bridge.  We suffered %d casualties", icas);\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
-               game.kavgd[l] = game.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
-#ifdef SERGEEV \r
-        skip(1);\r
-#endif /* SERGEEV */\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
-               game.state.newstuf[quadx][quady] -= 10;\r
-               irhere--;\r
-               game.state.nromkl++;\r
-               game.state.nromrem--;\r
-       }\r
-       else if (type == IHT) {\r
-               /* Killed a Tholian */\r
-               ithere = 0;\r
-       }\r
-        else if (type == IHQUEST) {\r
-               /* Killed a Thingy */\r
-             iqhere=iqengry=thingx=thingy=0;\r
-        }\r
-       else {\r
-               /* Some type of a Klingon */\r
-               game.state.galaxy[quadx][quady] -= 100;\r
-               klhere--;\r
-               game.state.remkl--;\r
-               switch (type) {\r
-                       case IHC:\r
-                               comhere = 0;\r
-                               for (i=1; i<=game.state.remcom; i++)\r
-                                       if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;\r
-                               game.state.cx[i] = game.state.cx[game.state.remcom];\r
-                               game.state.cy[i] = game.state.cy[game.state.remcom];\r
-                               game.state.cx[game.state.remcom] = 0;\r
-                               game.state.cy[game.state.remcom] = 0;\r
-                               game.state.remcom--;\r
-                               game.future[FTBEAM] = 1e30;\r
-                               if (game.state.remcom != 0)\r
-                                       game.future[FTBEAM] = game.state.date + expran(1.0*incom/game.state.remcom);\r
-                               game.state.killc++;\r
-                               break;\r
-                       case IHK:\r
-                               game.state.killk++;\r
-                               break;\r
-                       case IHS:\r
-                               game.state.nscrem = ishere = game.state.isx = game.state.isy = isatb = iscate = 0;\r
-                               game.state.nsckill = 1;\r
-                               game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
-                               break;\r
-               }\r
-       }\r
-\r
-       /* For each kind of enemy, finish message to player */\r
-       prout(" destroyed.");\r
-       game.quad[ix][iy] = IHDOT;\r
-       if (game.state.remkl==0) return;\r
-\r
-       game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);\r
-\r
-       /* Remove enemy ship from arrays describing local conditions */\r
-        if (game.future[FCDBAS] < 1e30 && batx==quadx && baty==quady && type==IHC)\r
-           game.future[FCDBAS] = 1e30;\r
-       for (i=1; i<=nenhere; i++)\r
-               if (game.kx[i]==ix && game.ky[i]==iy) break;\r
-       nenhere--;\r
-       if (i <= nenhere)  {\r
-               for (j=i; j<=nenhere; j++) {\r
-                       game.kx[j] = game.kx[j+1];\r
-                       game.ky[j] = game.ky[j+1];\r
-                       game.kpower[j] = game.kpower[j+1];\r
-                       game.kavgd[j] = game.kdist[j] = game.kdist[j+1];\r
-               }\r
-       }\r
-       game.kx[nenhere+1] = 0;\r
-       game.ky[nenhere+1] = 0;\r
-       game.kdist[nenhere+1] = 0;\r
-       game.kavgd[nenhere+1] = 0;\r
-       game.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 (game.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
-                       prout("%d torpedoes left.", torps);\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
-                                return;\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 %d- ", i);\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 %d MISFIRES", i);\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
-                               game.damage[DPHOTON] = damfac*(1.0+2.0*Rand());\r
-                               break;\r
-                       }\r
-               }\r
-               if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;\r
-#ifndef SERGEEV\r
-               if (n != 1) {\r
-                       skip(1);\r
-                       proutn("Track for torpedo number %d-  ", i);\r
-               }\r
-               else {\r
-                       skip(1);\r
-                       proutn("Torpedo track- ");\r
-               }\r
-#endif /* SERGEEV */\r
-               torpedo(course[i], r, sectx, secty, &dummy, i);\r
-               if (alldone || game.state.galaxy[quadx][quady]==1000) return;\r
-       }\r
-       if (game.state.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
-                       game.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
-               prout("  %d casualties so far.\"", icas);\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=0, extra, powrem, over, temp;\r
-       int kz = 0, k=1, i, irec=0; /* Cheating inhibitor */\r
-       int ifast=0, no=0, ipoop=1, msgflag = 1;\r
-       enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;\r
-       int key=0;\r
-\r
-       skip(1);\r
-       /* SR sensors and Computer */\r
-       if (game.damage[DSRSENS]+game.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 (game.damage[DPHASER] != 0) {\r
-               prout("Phaser control damaged.");\r
-               chew();\r
-               return;\r
-       }\r
-       if (shldup) {\r
-               if (game.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
-       /* 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
-                               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
-                                prout("Phasers locked on target. Energy available: %.2f",\r
-                                   ifast?energy-200.0:energy,1,2);\r
-                       }\r
-                        irec=0;\r
-                       do {\r
-                                        chew();\r
-                                        if (!kz) for (i = 1; i <= nenhere; i++)\r
-                                                     irec+=fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]))*\r
-                                                     (1.01+0.05*Rand()) + 1.0;\r
-                                        kz=1;\r
-                                        proutn("(%d) units required. ", irec);\r
-                                       chew();\r
-                                       proutn("Units to fire= ");\r
-                                       key = scan();\r
-                                        if (key!=IHREAL) return;\r
-                                       rpow = aaitem;\r
-                                       if (rpow > (ifast?energy-200:energy)) {\r
-                                           proutn("Energy available= %.2f",\r
-                                           ifast?energy-200:energy);\r
-                                       skip(1);\r
-                                       key = IHEOL;\r
-                               }\r
-                       } while (rpow > (ifast?energy-200:energy));\r
-                       if (rpow<=0) {\r
-                               /* chicken out */\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(game.kpower[i])/(PHASEFAC*pow(0.90,game.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
-                                ididit=1;\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
-                                       prout("%d expended on empty space.", (int)extra);\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case FORCEMAN:\r
-                       chew();\r
-                       key = IHEOL;\r
-                       if (game.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 = game.kx[k], jj = game.ky[k];\r
-                               int ienm = game.quad[ii][jj];\r
-                               if (msgflag) {\r
-                                       proutn("Energy available= %.2f",\r
-                                              energy-.006-(ifast?200:0));\r
-                                       skip(1);\r
-                                       msgflag = 0;\r
-                                       rpow = 0.0;\r
-                               }\r
-                               if (game.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
-                                                irec=(fabs(game.kpower[k])/(PHASEFAC*pow(0.9,game.kdist[k])))*\r
-                                                                (1.01+0.05*Rand()) + 1.0;\r
-                                       kz = k;\r
-                                       proutn("(");\r
-                                        if (game.damage[DCOMPTR]==0) proutn("%d", irec);\r
-                                        else proutn("??");\r
-                                       proutn(")  ");\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
-                                       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
-                                       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
-                                        return;\r
-                               }\r
-                               key = scan(); /* scan for next value */\r
-                               k++;\r
-                       }\r
-                       if (rpow == 0.0) {\r
-                               /* zero energy -- abort */\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
-               case NOTSET:;   /* avoid gcc warning */\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
-#ifdef SERGEEV\r
-       int cx, cy;\r
-#endif /* SERGEEV */\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,game.kdist[kk]);\r
-               kpini = game.kpower[kk];\r
-               kp = fabs(kpini);\r
-               if (PHASEFAC*hit < kp) kp = PHASEFAC*hit;\r
-               game.kpower[kk] -= (game.kpower[kk] < 0 ? -kp: kp);\r
-               kpow = game.kpower[kk];\r
-               ii = game.kx[kk];\r
-               jj = game.ky[kk];\r
-               if (hit > 0.005) {\r
-#ifdef SERGEEV\r
-                        if (game.damage[DSRSENS]==0){\r
-                           crx=wherex();\r
-                           cry=wherey();\r
-                           setwnd(1);\r
-                           drawmaps(2);\r
-                           gotoxy(jj*2+3,ii+2);\r
-                           highvideo();\r
-                           proutn("%c", game.quad[ii][jj]);\r
-                           gotoxy(wherex()-1,wherey());\r
-                           sound(500);\r
-                           delay(1000);\r
-                           nosound();\r
-                           lowvideo();\r
-                           proutn("%c", game.quad[ii][jj]);\r
-                           setwnd(4);\r
-                           gotoxy(crx,cry);\r
-                           _setcursortype(_NORMALCURSOR);\r
-                           delay(500);\r
-                        }\r
-#endif /* SERGEEV */\r
-                       proutn("%d unit hit on ", (int)hit);\r
-               }\r
-               else\r
-                       proutn("Very small hit on ");\r
-               ienm = game.quad[ii][jj];\r
-                if (ienm==IHQUEST) iqengry=1;\r
-               crmena(0,ienm,2,ii,jj);\r
-               skip(1);\r
-               if (kpow == 0) {\r
-                       deadkl(ii, jj, ienm, ii, jj);\r
-                       if (game.state.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
-                               prout("***Mr. Spock-  \"Captain, the vessel at ",\r
-                                       cramlc(sector,ii,jj));\r
-                               prout("   has just lost its firepower.\"");\r
-                               game.kpower[kk] = -kpow;\r
-                       }\r
-       }\r
-       return;\r
-}\r
-\r
+#ifdef SERGEEV
+#include <conio.h>
+#include <unistd.h>
+#include "sstlinux.h"
+#endif /* SERGEEV */
+#include "sst.h"
+
+void doshield(int i) {
+       int key;
+       enum {NONE, SHUP, SHDN, NRG} action = NONE;
+
+       ididit = 0;
+
+       if (i == 2) action = SHUP;
+       else {
+               key = scan();
+               if (key == IHALPHA) {
+                       if (isit("transfer"))
+                               action = NRG;
+                       else {
+                               chew();
+                               if (game.damage[DSHIELD]) {
+                                       prout("Shields damaged and down.");
+                                       return;
+                               }
+                               if (isit("up"))
+                                       action = SHUP;
+                               else if (isit("down"))
+                                       action = SHDN;
+                       }
+               }
+               if (action==NONE) {
+                       proutn("Do you wish to change shield energy? ");
+                       if (ja()) {
+                               proutn("Energy to transfer to shields- ");
+                               action = NRG;
+                       }
+                       else if (game.damage[DSHIELD]) {
+                               prout("Shields damaged and down.");
+                               return;
+                       }
+                       else if (shldup) {
+                               proutn("Shields are up. Do you want them down? ");
+                               if (ja()) action = SHDN;
+                               else {
+                                       chew();
+                                       return;
+                               }
+                       }
+                       else {
+                               proutn("Shields are down. Do you want them up? ");
+                               if (ja()) action = SHUP;
+                               else {
+                                       chew();
+                                       return;
+                               }
+                       }
+               }
+       }
+       switch (action) {
+               case SHUP: /* raise shields */
+                       if (shldup) {
+                               prout("Shields already up.");
+                               return;
+                       }
+                       shldup = 1;
+                       shldchg = 1;
+                       if (condit != IHDOCKED) energy -= 50.0;
+                       prout("Shields raised.");
+                       if (energy <= 0) {
+                               skip(1);
+                               prout("Shields raising uses up last of energy.");
+                               finish(FNRG);
+                               return;
+                       }
+                       ididit=1;
+                       return;
+               case SHDN:
+                       if (shldup==0) {
+                               prout("Shields already down.");
+                               return;
+                       }
+                       shldup=0;
+                       shldchg=1;
+                       prout("Shields lowered.");
+                       ididit=1;
+                       return;
+               case NRG:
+                       while (scan() != IHREAL) {
+                               chew();
+                               proutn("Energy to transfer to shields- ");
+                       }
+                       chew();
+                       if (aaitem==0) return;
+                       if (aaitem > energy) {
+                               prout("Insufficient ship energy.");
+                               return;
+                       }
+                       ididit = 1;
+                       if (shield+aaitem >= inshld) {
+                               prout("Shield energy maximized.");
+                               if (shield+aaitem > inshld) {
+                                       prout("Excess energy requested returned to ship energy");
+                               }
+                               energy -= inshld-shield;
+                               shield = inshld;
+                               return;
+                       }
+                       if (aaitem < 0.0 && energy-aaitem > inenrg) {
+                               /* Prevent shield drain loophole */
+                               skip(1);
+                               prout("Engineering to bridge--");
+                               prout("  Scott here. Power circuit problem, Captain.");
+                               prout("  I can't drain the shields.");
+                               ididit = 0;
+                               return;
+                       }
+                       if (shield+aaitem < 0) {
+                               prout("All shield energy transferred to ship.");
+                               energy += shield;
+                               shield = 0.0;
+                               return;
+                       }
+                       proutn("Scotty- \"");
+                       if (aaitem > 0)
+                               prout("Transferring energy to shields.\"");
+                       else
+                               prout("Draining energy from shields.\"");
+                       shield += aaitem;
+                       energy -= aaitem;
+                       return;
+               case NONE:;     /* avoid gcc warning */
+       }
+}
+
+void ram(int ibumpd, int ienm, int ix, int iy) {
+       double type = 1.0, extradm;
+       int icas, l;
+       
+       prouts("***RED ALERT!  RED ALERT!");
+       skip(1);
+       prout("***COLLISION IMMINENT.");
+       skip(2);
+       proutn("***");
+       crmshp();
+       switch (ienm) {
+               case IHR: type = 1.5; break;
+               case IHC: type = 2.0; break;
+               case IHS: type = 2.5; break;
+               case IHT: type = 0.5; break;
+                case IHQUEST: type = 4.0; break;
+       }
+       proutn(ibumpd ? " rammed by " : " rams ");
+       crmena(0, ienm, 2, ix, iy);
+       if (ibumpd) proutn(" (original position)");
+       skip(1);
+       deadkl(ix, iy, ienm, sectx, secty);
+       proutn("***");
+       crmshp();
+       prout(" heavily damaged.");
+       icas = 10.0+20.0*Rand();
+       prout("***Sickbay reports %d casualties", icas);
+       casual += icas;
+       for (l=1; l <= NDEVICES; l++) {
+               if (l == DDRAY) continue; // Don't damage deathray 
+               if (game.damage[l] < 0) continue;
+               extradm = (10.0*type*Rand()+1.0)*damfac;
+               game.damage[l] += Time + extradm; /* Damage for at least time of travel! */
+       }
+       shldup = 0;
+       if (game.state.remkl) {
+               pause_game(2);
+               dreprt();
+       }
+       else finish(FWON);
+       return;
+}
+
+void torpedo(double course, double r, int inx, int iny, double *hit, int wait) {
+        int l, iquad=0, ix=0, iy=0, jx=0, jy=0, shoved=0, ll;
+#ifdef SERGEEV
+       int crx,cry;
+       
+#endif /* SERGEEV */
+       double ac=course + 0.25*r;
+       double angle = (15.0-ac)*0.5235988;
+       double bullseye = (15.0 - course)*0.5235988;
+       double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;
+       double ang, temp, xx, yy, kp, h1;
+
+       bigger = fabs(deltax);
+       if (fabs(deltay) > bigger) bigger = fabs(deltay);
+       deltax /= bigger;
+       deltay /= bigger;
+#ifdef SERGEEV
+        crx=wherex();
+        cry=wherey();
+        if (game.damage[DSRSENS]==0 || condit==IHDOCKED) setwnd(1);
+       else setwnd(4);
+#endif /* SERGEEV */
+       /* Loop to move a single torpedo */
+       for (l=1; l <= 15; l++) {
+               x += deltax;
+               ix = x + 0.5;
+               if (ix < 1 || ix > 10) break;
+               y += deltay;
+               iy = y + 0.5;
+               if (iy < 1 || iy > 10) break;
+#ifndef SERGEEV
+               if (l==4 || l==9) skip(1);
+               proutn("%d - %d   ", (int)x, (int)y);
+               iquad=game.quad[ix][iy];
+#else
+                iquad=game.quad[ix][iy];
+                if (game.damage[DSRSENS]==0 || condit==IHDOCKED){
+                   drawmaps(2);
+                   delay((wait!=1)*400);
+                   wait=1;
+                   gotoxy(iy*2+3,ix+2);
+                   if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){
+                      game.quad[ix][iy]='+';
+                      drawmaps(2);
+                      game.quad[ix][iy]=iquad;
+                      sound(l*10);
+                      delay(100);
+                      nosound();
+                   }
+                   else {
+                        game.quad[ix][iy]|=128;
+                        drawmaps(2);
+                        game.quad[ix][iy]=iquad;
+                        _setcursortype(_NOCURSOR);
+                        sound(500);
+                        delay(1000);
+                        nosound();
+                        lowvideo();
+                        _setcursortype(_NORMALCURSOR);
+                   }
+                }
+                else {
+                 proutn("%d - %d   ", (int)x, (int)y);
+               }
+#endif /* SERGEEV */
+               if (iquad==IHDOT) continue;
+               /* hit something */
+#ifndef SERGEEV
+               skip(1);
+#else
+               setwnd(4);
+               gotoxy(crx,cry);
+#endif
+               switch(iquad) {
+                       case IHE: /* Hit our ship */
+                       case IHF:
+                               skip(1);
+                               proutn("Torpedo hits ");
+                               crmshp();
+                               prout(".");
+                               *hit = 700.0 + 100.0*Rand() -
+                                          1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+                                          fabs(sin(bullseye-angle));
+                               *hit = fabs(*hit);
+#ifndef SERGEEV
+                               newcnd(); /* undock */
+#endif /* SERGEEV */
+                               /* We may be displaced. */
+                               if (landed==1 || condit==IHDOCKED) return; /* Cheat if on a planet */
+                               ang = angle + 2.5*(Rand()-0.5);
+                               temp = fabs(sin(ang));
+                               if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
+                               xx = -sin(ang)/temp;
+                               yy = cos(ang)/temp;
+                               jx=ix+xx+0.5;
+                               jy=iy+yy+0.5;
+                               if (jx<1 || jx>10 || jy<1 ||jy > 10) return;
+                               if (game.quad[jx][jy]==IHBLANK) {
+                                       finish(FHOLE);
+                                       return;
+                               }
+                               if (game.quad[jx][jy]!=IHDOT) {
+                                       /* can't move into object */
+                                       return;
+                               }
+                               sectx = jx;
+                               secty = jy;
+                               crmshp();
+                               shoved = 1;
+                               break;
+                                         
+                       case IHC: /* Hit a commander */
+                       case IHS:
+                               if (Rand() <= 0.05) {
+                                       crmena(1, iquad, 2, ix, iy);
+                                       prout(" uses anti-photon device;");
+                                       prout("   torpedo neutralized.");
+                                       return;
+                               }
+                       case IHR: /* Hit a regular enemy */
+                       case IHK:
+                               /* find the enemy */
+                               for (ll=1; ll <= nenhere; ll++)
+                                       if (ix==game.kx[ll] && iy==game.ky[ll]) break;
+                               kp = fabs(game.kpower[ll]);
+                               h1 = 700.0 + 100.0*Rand() -
+                                        1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+                                        fabs(sin(bullseye-angle));
+                               h1 = fabs(h1);
+                               if (kp < h1) h1 = kp;
+                               game.kpower[ll] -= (game.kpower[ll]<0 ? -h1 : h1);
+                               if (game.kpower[ll] == 0) {
+                                       deadkl(ix, iy, iquad, ix, iy);
+                                       return;
+                               }
+                               crmena(1, iquad, 2, ix, iy);
+                               /* If enemy damaged but not destroyed, try to displace */
+                               ang = angle + 2.5*(Rand()-0.5);
+                               temp = fabs(sin(ang));
+                               if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
+                               xx = -sin(ang)/temp;
+                               yy = cos(ang)/temp;
+                               jx=ix+xx+0.5;
+                               jy=iy+yy+0.5;
+                               if (jx<1 || jx>10 || jy<1 ||jy > 10) {
+                                       prout(" damaged but not destroyed.");
+                                       return;
+                               }
+                               if (game.quad[jx][jy]==IHBLANK) {
+                                       prout(" buffeted into black hole.");
+                                       deadkl(ix, iy, iquad, jx, jy);
+                                       return;
+                               }
+                               if (game.quad[jx][jy]!=IHDOT) {
+                                       /* can't move into object */
+                                       prout(" damaged but not destroyed.");
+                                       return;
+                               }
+                               proutn(" damaged--");
+                               game.kx[ll] = jx;
+                               game.ky[ll] = jy;
+                               shoved = 1;
+                               break;
+                       case IHB: /* Hit a base */
+                               skip(1);
+                               prout("***STARBASE DESTROYED..");
+                               if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;
+                               for (ll=1; ll<=game.state.rembase; ll++) {
+                                       if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {
+                                               game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];
+                                               game.state.baseqy[ll]=game.state.baseqy[game.state.rembase];
+                                               break;
+                                       }
+                               }
+                               game.quad[ix][iy]=IHDOT;
+                               game.state.rembase--;
+                               basex=basey=0;
+                               game.state.galaxy[quadx][quady] -= 10;
+                               game.state.basekl++;
+                               newcnd();
+                               return;
+                       case IHP: /* Hit a planet */
+                               crmena(1, iquad, 2, ix, iy);
+                               prout(" destroyed.");
+                               game.state.nplankl++;
+                               game.state.newstuf[quadx][quady] -= 1;
+                               DESTROY(&game.state.plnets[iplnet]);
+                               iplnet = 0;
+                               plnetx = plnety = 0;
+                               game.quad[ix][iy] = IHDOT;
+                               if (landed==1) {
+                                       /* captain parishes on planet */
+                                       finish(FDPLANET);
+                               }
+                               return;
+                       case IHSTAR: /* Hit a star */
+                               if (Rand() > 0.10) {
+                                       nova(ix, iy);
+                                       return;
+                               }
+                               crmena(1, IHSTAR, 2, ix, iy);
+                               prout(" unaffected by photon blast.");
+                               return;
+                       case IHQUEST: /* Hit a thingy */
+                            if (Rand()>0.7) {  // Used to be certain death 
+                               skip(1);
+                               prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");
+                               skip(1);
+                               prouts("    HACK!     HACK!    HACK!        *CHOKE!*  ");
+                               skip(1);
+                               proutn("Mr. Spock-");
+                               prouts("  \"Fascinating!\"");
+                               skip(1);
+                                deadkl(ix, iy, iquad, ix, iy);
+                            } else {
+                               /*
+                                * Stas Sergeev added the possibility that
+                                * you can shove the Thingy.
+                                */
+                                iqengry=1;
+                                shoved=1;
+                            }
+                           return;
+                       case IHBLANK: /* Black hole */
+                               skip(1);
+                               crmena(1, IHBLANK, 2, ix, iy);
+                               prout(" swallows torpedo.");
+                               return;
+                       case IHWEB: /* hit the web */
+                               skip(1);
+                               prout("***Torpedo absorbed by Tholian web.");
+                               return;
+                       case IHT:  /* Hit a Tholian */
+                               h1 = 700.0 + 100.0*Rand() -
+                                        1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+                                        fabs(sin(bullseye-angle));
+                               h1 = fabs(h1);
+                               if (h1 >= 600) {
+#ifndef SERGEEV
+                                       prout(" destroyed.");
+#endif /* SERGEEV */
+                                       game.quad[ix][iy] = IHDOT;
+                                       ithere = 0;
+                                       ithx = ithy = 0;
+#ifdef SERGEEV
+                                        deadkl(ix, iy, iquad, ix, iy);
+#endif /* SERGEEV */
+                                       return;
+                               }
+                               skip(1);
+                               crmena(1, IHT, 2, ix, iy);
+                               if (Rand() > 0.05) {
+                                       prout(" survives photon blast.");
+                                       return;
+                               }
+                               prout(" disappears.");
+                               game.quad[ix][iy] = IHWEB;
+                               ithere = ithx = ithy = 0;
+                               nenhere--;
+                               {
+                                       int dum, my;
+                                       dropin(IHBLANK, &dum, &my);
+                               }
+                               return;
+                                       
+                       default: /* Problem! */
+                               skip(1);
+                               proutn("Don't know how to handle collision with ");
+                               crmena(1, iquad, 2, ix, iy);
+                               skip(1);
+                               return;
+               }
+               break;
+       }
+#ifdef SERGEEV
+        if(curwnd!=4) {
+           setwnd(4);
+           gotoxy(crx,cry);
+       }
+#endif /* SERGEEV */
+       if (shoved) {
+               game.quad[jx][jy]=iquad;
+               game.quad[ix][iy]=IHDOT;
+               prout(" displaced by blast to %s ", cramlc(sector, jx, jy));
+               for (ll=1; ll<=nenhere; ll++)
+                       game.kdist[ll] = game.kavgd[ll] = sqrt(square(sectx-game.kx[ll])+square(secty-game.ky[ll]));
+               sortkl();
+               return;
+       }
+#ifndef SERGEEV
+       skip(1);
+#endif /* SERGEEV */
+       prout("Torpedo missed.");
+       return;
+}
+
+static void fry(double hit) {
+       double ncrit, extradm;
+       int ktr=1, l, ll, j, cdam[NDEVICES+1];
+
+       /* a critical hit occured */
+       if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;
+
+       ncrit = 1.0 + hit/(500.0+100.0*Rand());
+       proutn("***CRITICAL HIT--");
+       /* Select devices and cause damage */
+       for (l = 1; l <= ncrit && l <= NDEVICES; l++) {
+               do {
+                       j = NDEVICES*Rand()+1.0;
+                       /* Cheat to prevent shuttle damage unless on ship */
+               } while (game.damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||
+                                j == DDRAY);
+               cdam[l] = j;
+               extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));
+               game.damage[j] += extradm;
+               if (l > 1) {
+                       for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;
+                       if (ll<=l) continue;
+                       ktr += 1;
+                       if (ktr==3) skip(1);
+                       proutn(" and ");
+               }
+               proutn(device[j]);
+       }
+       prout(" damaged.");
+       if (game.damage[DSHIELD] && shldup) {
+               prout("***Shields knocked down.");
+               shldup=0;
+       }
+}
+
+void attack(int k) {
+       /* k == 0 forces use of phasers in an attack */
+       int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;
+       int atackd = 0, attempt = 0;
+       double hit;
+       double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;
+
+       iattak = 1;
+       if (alldone) return;
+#ifdef DEBUG
+       if (idebug) prout("ATTACK!");
+#endif
+
+       if (ithere) movetho();
+
+       if (neutz) { /* The one chance not to be attacked */
+               neutz = 0;
+               return;
+       }
+       if ((((comhere || ishere) && (justin == 0)) || skill == 5)&&(k!=0)) movcom();
+       if (nenhere==0 || (nenhere==1 && iqhere && iqengry==0)) return;
+       pfac = 1.0/inshld;
+       if (shldchg == 1) chgfac = 0.25+0.5*Rand();
+       skip(1);
+       if (skill <= 2) i = 2;
+       for (l=1; l <= nenhere; l++) {
+               if (game.kpower[l] < 0) continue;       /* too weak to attack */
+               /* compute hit strength and diminsh shield power */
+               r = Rand();
+               /* Increase chance of photon torpedos if docked or enemy energy low */
+               if (condit == IHDOCKED) r *= 0.25;
+               if (game.kpower[l] < 500) r *= 0.25; 
+               jx = game.kx[l];
+               jy = game.ky[l];
+               iquad = game.quad[jx][jy];
+                if (iquad==IHT || (iquad==IHQUEST && !iqengry)) continue;
+               itflag = (iquad == IHK && r > 0.0005) || k == 0 ||
+                       (iquad==IHC && r > 0.015) ||
+                       (iquad==IHR && r > 0.3) ||
+                        (iquad==IHS && r > 0.07) ||
+                        (iquad==IHQUEST && r > 0.05);
+               if (itflag) {
+                       /* Enemy uses phasers */
+                       if (condit == IHDOCKED) continue; /* Don't waste the effort! */
+                       attempt = 1; /* Attempt to attack */
+                       dustfac = 0.8+0.05*Rand();
+                       hit = game.kpower[l]*pow(dustfac,game.kavgd[l]);
+                       game.kpower[l] *= 0.75;
+               }
+               else { /* Enemy used photon torpedo */
+                       double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);
+                       hit = 0;
+                       proutn("***TORPEDO INCOMING");
+                       if (game.damage[DSRSENS] <= 0.0) {
+                               proutn(" From ");
+                               crmena(0, iquad, i, jx, jy);
+                       }
+                       attempt = 1;
+                       prout("  ");
+                       r = (Rand()+Rand())*0.5 -0.5;
+                       r += 0.002*game.kpower[l]*r;
+                       torpedo(course, r, jx, jy, &hit, 0);
+                       if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */
+                       if (game.state.galaxy[quadx][quady] == 1000 ||
+                               alldone) return; /* Supernova or finished */
+                       if (hit == 0) continue;
+               }
+                if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {
+                       /* shields will take hits */
+                        double absorb, hitsh, propor = pfac*shield*(condit==IHDOCKED ? 2.1 : 1.0);
+                       if(propor < 0.1) propor = 0.1;
+                       hitsh = propor*chgfac*hit+1.0;
+                       atackd=1;
+                       absorb = 0.8*hitsh;
+                       if (absorb > shield) absorb = shield;
+                       shield -= absorb;
+                       hit -= hitsh;
+                        if (condit==IHDOCKED) dock(0);
+                       if (propor > 0.1 && hit < 0.005*energy) continue;
+               }
+               /* It's a hit -- print out hit size */
+               atackd = 1; /* We weren't going to check casualties, etc. if
+                              shields were down for some strange reason. This
+                                          doesn't make any sense, so I've fixed it */
+               ihurt = 1;
+               proutn("%d unit hit", (int)hit);
+               if ((game.damage[DSRSENS] > 0 && itflag) || skill <= 2) {
+                       proutn(" on the ");
+                       crmshp();
+               }
+               if (game.damage[DSRSENS] <= 0.0 && itflag) {
+                       proutn(" from ");
+                       crmena(0, iquad, i, jx, jy);
+               }
+               skip(1);
+               /* Decide if hit is critical */
+               if (hit > hitmax) hitmax = hit;
+               hittot += hit;
+               fry(hit);
+               prout("Hit %g energy %g", hit, energy);
+               energy -= hit;
+                if (condit==IHDOCKED) dock(0);
+       }
+       if (energy <= 0) {
+               /* Returning home upon your shield, not with it... */
+               finish(FBATTLE);
+               return;
+       }
+       if (attempt == 0 && condit == IHDOCKED)
+               prout("***Enemies decide against attacking your ship.");
+       if (atackd == 0) return;
+       percent = 100.0*pfac*shield+0.5;
+       if (ihurt==0) {
+               /* Shields fully protect ship */
+               proutn("Enemy attack reduces shield strength to ");
+       }
+       else {
+               /* Print message if starship suffered hit(s) */
+               skip(1);
+               proutn("Energy left %2d    shields ", (int)energy);
+               if (shldup) proutn("up ");
+               else if (game.damage[DSHIELD] == 0) proutn("down ");
+               else proutn("damaged, ");
+       }
+       prout("%d%%,   torpedoes left %d", percent, torps);
+       /* Check if anyone was hurt */
+       if (hitmax >= 200 || hittot >= 500) {
+               int icas= hittot*Rand()*0.015;
+               if (icas >= 2) {
+                       skip(1);
+                       prout("Mc Coy-  \"Sickbay to bridge.  We suffered %d casualties", icas);
+                       prout("   in that last attack.\"");
+                       casual += icas;
+               }
+       }
+       /* After attack, reset average distance to enemies */
+       for (l = 1; l <= nenhere; l++)
+               game.kavgd[l] = game.kdist[l];
+       sortkl();
+       return;
+}
+               
+void deadkl(int ix, int iy, int type, int ixx, int iyy) {
+       /* Added ixx and iyy allow enemy to "move" before dying */
+
+       int i,j;
+
+#ifdef SERGEEV 
+        skip(1);
+#endif /* SERGEEV */
+       crmena(1, type, 2, ixx, iyy);
+       /* Decide what kind of enemy it is and update approriately */
+       if (type == IHR) {
+               /* chalk up a Romulan */
+               game.state.newstuf[quadx][quady] -= 10;
+               irhere--;
+               game.state.nromkl++;
+               game.state.nromrem--;
+       }
+       else if (type == IHT) {
+               /* Killed a Tholian */
+               ithere = 0;
+       }
+        else if (type == IHQUEST) {
+               /* Killed a Thingy */
+             iqhere=iqengry=thingx=thingy=0;
+        }
+       else {
+               /* Some type of a Klingon */
+               game.state.galaxy[quadx][quady] -= 100;
+               klhere--;
+               game.state.remkl--;
+               switch (type) {
+                       case IHC:
+                               comhere = 0;
+                               for (i=1; i<=game.state.remcom; i++)
+                                       if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;
+                               game.state.cx[i] = game.state.cx[game.state.remcom];
+                               game.state.cy[i] = game.state.cy[game.state.remcom];
+                               game.state.cx[game.state.remcom] = 0;
+                               game.state.cy[game.state.remcom] = 0;
+                               game.state.remcom--;
+                               game.future[FTBEAM] = 1e30;
+                               if (game.state.remcom != 0)
+                                       game.future[FTBEAM] = game.state.date + expran(1.0*incom/game.state.remcom);
+                               game.state.killc++;
+                               break;
+                       case IHK:
+                               game.state.killk++;
+                               break;
+                       case IHS:
+                               game.state.nscrem = ishere = game.state.isx = game.state.isy = isatb = iscate = 0;
+                               game.state.nsckill = 1;
+                               game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
+                               break;
+               }
+       }
+
+       /* For each kind of enemy, finish message to player */
+       prout(" destroyed.");
+       game.quad[ix][iy] = IHDOT;
+       if (game.state.remkl==0) return;
+
+       game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);
+
+       /* Remove enemy ship from arrays describing local conditions */
+        if (game.future[FCDBAS] < 1e30 && batx==quadx && baty==quady && type==IHC)
+           game.future[FCDBAS] = 1e30;
+       for (i=1; i<=nenhere; i++)
+               if (game.kx[i]==ix && game.ky[i]==iy) break;
+       nenhere--;
+       if (i <= nenhere)  {
+               for (j=i; j<=nenhere; j++) {
+                       game.kx[j] = game.kx[j+1];
+                       game.ky[j] = game.ky[j+1];
+                       game.kpower[j] = game.kpower[j+1];
+                       game.kavgd[j] = game.kdist[j] = game.kdist[j+1];
+               }
+       }
+       game.kx[nenhere+1] = 0;
+       game.ky[nenhere+1] = 0;
+       game.kdist[nenhere+1] = 0;
+       game.kavgd[nenhere+1] = 0;
+       game.kpower[nenhere+1] = 0;
+       return;
+}
+
+static int targetcheck(double x, double y, double *course) {
+       double deltx, delty;
+       /* Return TRUE if target is invalid */
+       if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {
+               huh();
+               return 1;
+       }
+       deltx = 0.1*(y - secty);
+       delty = 0.1*(sectx - x);
+       if (deltx==0 && delty== 0) {
+               skip(1);
+               prout("Spock-  \"Bridge to sickbay.  Dr. McCoy,");
+               prout("  I recommend an immediate review of");
+               prout("  the Captain's psychological profile.\"");
+               chew();
+               return 1;
+       }
+       *course = 1.90985932*atan2(deltx, delty);
+       return 0;
+}
+
+void photon(void) {
+       double targ[4][3], course[4];
+       double r, dummy;
+       int key, n, i, osuabor;
+
+       ididit = 0;
+
+       if (game.damage[DPHOTON]) {
+               prout("Photon tubes damaged.");
+               chew();
+               return;
+       }
+       if (torps == 0) {
+               prout("No torpedoes left.");
+               chew();
+               return;
+       }
+       key = scan();
+       for (;;) {
+               if (key == IHALPHA) {
+                       huh();
+                       return;
+               }
+               else if (key == IHEOL) {
+                       prout("%d torpedoes left.", torps);
+                       proutn("Number of torpedoes to fire- ");
+                       key = scan();
+               }
+               else /* key == IHREAL */ {
+                       n = aaitem + 0.5;
+                       if (n <= 0) { /* abort command */
+                               chew();
+                               return;
+                       }
+                       if (n > 3) {
+                               chew();
+                               prout("Maximum of 3 torpedoes per burst.");
+                               key = IHEOL;
+                                return;
+                       }
+                       if (n <= torps) break;
+                       chew();
+                       key = IHEOL;
+               }
+       }
+       for (i = 1; i <= n; i++) {
+               key = scan();
+               if (i==1 && key == IHEOL) {
+                       break;  /* we will try prompting */
+               }
+               if (i==2 && key == IHEOL) {
+                       /* direct all torpedoes at one target */
+                       while (i <= n) {
+                               targ[i][1] = targ[1][1];
+                               targ[i][2] = targ[1][2];
+                               course[i] = course[1];
+                               i++;
+                       }
+                       break;
+               }
+               if (key != IHREAL) {
+                       huh();
+                       return;
+               }
+               targ[i][1] = aaitem;
+               key = scan();
+               if (key != IHREAL) {
+                       huh();
+                       return;
+               }
+               targ[i][2] = aaitem;
+               if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
+       }
+       chew();
+       if (i == 1 && key == IHEOL) {
+               /* prompt for each one */
+               for (i = 1; i <= n; i++) {
+                   proutn("Target sector for torpedo number %d- ", i);
+                       key = scan();
+                       if (key != IHREAL) {
+                               huh();
+                               return;
+                       }
+                       targ[i][1] = aaitem;
+                       key = scan();
+                       if (key != IHREAL) {
+                               huh();
+                               return;
+                       }
+                       targ[i][2] = aaitem;
+                       chew();
+                       if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
+               }
+       }
+       ididit = 1;
+       /* Loop for moving <n> torpedoes */
+       osuabor = 0;
+       for (i = 1; i <= n && !osuabor; i++) {
+               if (condit != IHDOCKED) torps--;
+               r = (Rand()+Rand())*0.5 -0.5;
+               if (fabs(r) >= 0.47) {
+                       /* misfire! */
+                       r = (Rand()+1.2) * r;
+                       if (n>1) {
+                           prouts("***TORPEDO NUMBER %d MISFIRES", i);
+                       }
+                       else prouts("***TORPEDO MISFIRES.");
+                       skip(1);
+                       if (i < n)
+                               prout("  Remainder of burst aborted.");
+                       osuabor=1;
+                       if (Rand() <= 0.2) {
+                               prout("***Photon tubes damaged by misfire.");
+                               game.damage[DPHOTON] = damfac*(1.0+2.0*Rand());
+                               break;
+                       }
+               }
+               if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;
+#ifndef SERGEEV
+               if (n != 1) {
+                       skip(1);
+                       proutn("Track for torpedo number %d-  ", i);
+               }
+               else {
+                       skip(1);
+                       proutn("Torpedo track- ");
+               }
+#endif /* SERGEEV */
+               torpedo(course[i], r, sectx, secty, &dummy, i);
+               if (alldone || game.state.galaxy[quadx][quady]==1000) return;
+       }
+       if (game.state.remkl==0) finish(FWON);
+}
+
+       
+
+static void overheat(double rpow) {
+       if (rpow > 1500) {
+               double chekbrn = (rpow-1500.)*0.00038;
+               if (Rand() <= chekbrn) {
+                       prout("Weapons officer Sulu-  \"Phasers overheated, sir.\"");
+                       game.damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);
+               }
+       }
+}
+
+static int checkshctrl(double rpow) {
+       double hit;
+       int icas;
+       
+       skip(1);
+       if (Rand() < .998) {
+               prout("Shields lowered.");
+               return 0;
+       }
+       /* Something bad has happened */
+       prouts("***RED ALERT!  RED ALERT!");
+       skip(2);
+       hit = rpow*shield/inshld;
+       energy -= rpow+hit*0.8;
+       shield -= hit*0.2;
+       if (energy <= 0.0) {
+               prouts("Sulu-  \"Captain! Shield malf***********************\"");
+               skip(1);
+               stars();
+               finish(FPHASER);
+               return 1;
+       }
+       prouts("Sulu-  \"Captain! Shield malfunction! Phaser fire contained!\"");
+       skip(2);
+       prout("Lt. Uhura-  \"Sir, all decks reporting damage.\"");
+       icas = hit*Rand()*0.012;
+       skip(1);
+       fry(0.8*hit);
+       if (icas) {
+               skip(1);
+               prout("McCoy to bridge- \"Severe radiation burns, Jim.");
+               prout("  %d casualties so far.\"", icas);
+               casual -= icas;
+       }
+       skip(1);
+       prout("Phaser energy dispersed by shields.");
+       prout("Enemy unaffected.");
+       overheat(rpow);
+       return 1;
+}
+       
+
+void phasers(void) {
+       double hits[21], rpow=0, extra, powrem, over, temp;
+       int kz = 0, k=1, i, irec=0; /* Cheating inhibitor */
+       int ifast=0, no=0, ipoop=1, msgflag = 1;
+       enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;
+       int key=0;
+
+       skip(1);
+       /* SR sensors and Computer */
+       if (game.damage[DSRSENS]+game.damage[DCOMPTR] > 0) ipoop = 0;
+       if (condit == IHDOCKED) {
+               prout("Phasers can't be fired through base shields.");
+               chew();
+               return;
+       }
+       if (game.damage[DPHASER] != 0) {
+               prout("Phaser control damaged.");
+               chew();
+               return;
+       }
+       if (shldup) {
+               if (game.damage[DSHCTRL]) {
+                       prout("High speed shield control damaged.");
+                       chew();
+                       return;
+               }
+               if (energy <= 200.0) {
+                       prout("Insufficient energy to activate high-speed shield control.");
+                       chew();
+                       return;
+               }
+               prout("Weapons Officer Sulu-  \"High-speed shield control enabled, sir.\"");
+               ifast = 1;
+               
+       }
+       /* Original code so convoluted, I re-did it all */
+       while (automode==NOTSET) {
+               key=scan();
+               if (key == IHALPHA) {
+                       if (isit("manual")) {
+                               if (nenhere==0) {
+                                       prout("There is no enemy present to select.");
+                                       chew();
+                                       key = IHEOL;
+                                       automode=AUTOMATIC;
+                               }
+                               else {
+                                       automode = MANUAL;
+                                       key = scan();
+                               }
+                       }
+                       else if (isit("automatic")) {
+                               if ((!ipoop) && nenhere != 0) {
+                                       automode = FORCEMAN;
+                               }
+                               else {
+                                       if (nenhere==0)
+                                               prout("Energy will be expended into space.");
+                                       automode = AUTOMATIC;
+                                       key = scan();
+                               }
+                       }
+                       else if (isit("no")) {
+                               no = 1;
+                       }
+                       else {
+                               huh();
+                               return;
+                       }
+               }
+               else if (key == IHREAL) {
+                       if (nenhere==0) {
+                               prout("Energy will be expended into space.");
+                               automode = AUTOMATIC;
+                       }
+                       else if (!ipoop)
+                               automode = FORCEMAN;
+                       else
+                               automode = AUTOMATIC;
+               }
+               else {
+                       /* IHEOL */
+                       if (nenhere==0) {
+                               prout("Energy will be expended into space.");
+                               automode = AUTOMATIC;
+                       }
+                       else if (!ipoop)
+                               automode = FORCEMAN;
+                       else 
+                       proutn("Manual or automatic? ");
+               }
+       }
+                               
+       switch (automode) {
+               case AUTOMATIC:
+                       if (key == IHALPHA && isit("no")) {
+                               no = 1;
+                               key = scan();
+                       }
+                       if (key != IHREAL && nenhere != 0) {
+                                prout("Phasers locked on target. Energy available: %.2f",
+                                   ifast?energy-200.0:energy,1,2);
+                       }
+                        irec=0;
+                       do {
+                                        chew();
+                                        if (!kz) for (i = 1; i <= nenhere; i++)
+                                                     irec+=fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]))*
+                                                     (1.01+0.05*Rand()) + 1.0;
+                                        kz=1;
+                                        proutn("(%d) units required. ", irec);
+                                       chew();
+                                       proutn("Units to fire= ");
+                                       key = scan();
+                                        if (key!=IHREAL) return;
+                                       rpow = aaitem;
+                                       if (rpow > (ifast?energy-200:energy)) {
+                                           proutn("Energy available= %.2f",
+                                           ifast?energy-200:energy);
+                                       skip(1);
+                                       key = IHEOL;
+                               }
+                       } while (rpow > (ifast?energy-200:energy));
+                       if (rpow<=0) {
+                               /* chicken out */
+                               chew();
+                               return;
+                       }
+                       if ((key=scan()) == IHALPHA && isit("no")) {
+                               no = 1;
+                       }
+                       if (ifast) {
+                               energy -= 200; /* Go and do it! */
+                               if (checkshctrl(rpow)) return;
+                       }
+                       chew();
+                       energy -= rpow;
+                       extra = rpow;
+                       if (nenhere) {
+                               extra = 0.0;
+                               powrem = rpow;
+                               for (i = 1; i <= nenhere; i++) {
+                                       hits[i] = 0.0;
+                                       if (powrem <= 0) continue;
+                                       hits[i] = fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]));
+                                       over = (0.01 + 0.05*Rand())*hits[i];
+                                       temp = powrem;
+                                       powrem -= hits[i] + over;
+                                       if (powrem <= 0 && temp < hits[i]) hits[i] = temp;
+                                       if (powrem <= 0) over = 0.0;
+                                       extra += over;
+                               }
+                               if (powrem > 0.0) extra += powrem;
+                               hittem(hits);
+                                ididit=1;
+                       }
+                       if (extra > 0 && alldone == 0) {
+                               if (ithere) {
+                                       proutn("*** Tholian web absorbs ");
+                                       if (nenhere>0) proutn("excess ");
+                                       prout("phaser energy.");
+                               }
+                               else {
+                                       prout("%d expended on empty space.", (int)extra);
+                               }
+                       }
+                       break;
+
+               case FORCEMAN:
+                       chew();
+                       key = IHEOL;
+                       if (game.damage[DCOMPTR]!=0)
+                               prout("Battle comuter damaged, manual file only.");
+                       else {
+                               skip(1);
+                               prouts("---WORKING---");
+                               skip(1);
+                               prout("Short-range-sensors-damaged");
+                               prout("Insufficient-data-for-automatic-phaser-fire");
+                               prout("Manual-fire-must-be-used");
+                               skip(1);
+                       }
+               case MANUAL:
+                       rpow = 0.0;
+                       for (k = 1; k <= nenhere;) {
+                               int ii = game.kx[k], jj = game.ky[k];
+                               int ienm = game.quad[ii][jj];
+                               if (msgflag) {
+                                       proutn("Energy available= %.2f",
+                                              energy-.006-(ifast?200:0));
+                                       skip(1);
+                                       msgflag = 0;
+                                       rpow = 0.0;
+                               }
+                               if (game.damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&
+                                       (ienm == IHC || ienm == IHS)) {
+                                       cramen(ienm);
+                                       prout(" can't be located without short range scan.");
+                                       chew();
+                                       key = IHEOL;
+                                       hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */
+                                       k++;
+                                       continue;
+                               }
+                               if (key == IHEOL) {
+                                       chew();
+                                        if (ipoop && k > kz)
+                                                irec=(fabs(game.kpower[k])/(PHASEFAC*pow(0.9,game.kdist[k])))*
+                                                                (1.01+0.05*Rand()) + 1.0;
+                                       kz = k;
+                                       proutn("(");
+                                        if (game.damage[DCOMPTR]==0) proutn("%d", irec);
+                                        else proutn("??");
+                                       proutn(")  ");
+                                       proutn("units to fire at ");
+                                       crmena(0, ienm, 2, ii, jj);
+                                       proutn("-  ");
+                                       key = scan();
+                               }
+                               if (key == IHALPHA && isit("no")) {
+                                       no = 1;
+                                       key = scan();
+                                       continue;
+                                       }
+                               if (key == IHALPHA) {
+                                       huh();
+                                       return;
+                               }
+                               if (key == IHEOL) {
+                                       if (k==1) { /* Let me say I'm baffled by this */
+                                               msgflag = 1;
+                                       }
+                                       continue;
+                               }
+                               if (aaitem < 0) {
+                                       /* abort out */
+                                       chew();
+                                       return;
+                               }
+                               hits[k] = aaitem;
+                               rpow += aaitem;
+                               /* If total requested is too much, inform and start over */
+                               
+                               if (rpow > (ifast?energy-200:energy)) {
+                                       prout("Available energy exceeded -- try again.");
+                                       chew();
+                                        return;
+                               }
+                               key = scan(); /* scan for next value */
+                               k++;
+                       }
+                       if (rpow == 0.0) {
+                               /* zero energy -- abort */
+                               chew();
+                               return;
+                       }
+                       if (key == IHALPHA && isit("no")) {
+                               no = 1;
+                       }
+                       energy -= rpow;
+                       chew();
+                       if (ifast) {
+                               energy -= 200.0;
+                               if (checkshctrl(rpow)) return;
+                       }
+                       hittem(hits);
+                       ididit=1;
+               case NOTSET:;   /* avoid gcc warning */
+       }
+       /* Say shield raised or malfunction, if necessary */
+       if (alldone) return;
+       if (ifast) {
+               skip(1);
+               if (no == 0) {
+                       if (Rand() >= 0.99) {
+                               prout("Sulu-  \"Sir, the high-speed shield control has malfunctioned . . .");
+                               prouts("         CLICK   CLICK   POP  . . .");
+                               prout(" No  response, sir!");
+                               shldup = 0;
+                       }
+                       else
+                               prout("Shields raised.");
+               }
+               else
+                       shldup = 0;
+       }
+       overheat(rpow);
+}
+
+void hittem(double *hits) {
+       double kp, kpow, wham, hit, dustfac, kpini;
+#ifdef SERGEEV
+       int cx, cy;
+#endif /* SERGEEV */
+       int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;
+
+       skip(1);
+
+       for (; k <= nenhr2; k++, kk++) {
+               if ((wham = hits[k])==0) continue;
+               dustfac = 0.9 + 0.01*Rand();
+               hit = wham*pow(dustfac,game.kdist[kk]);
+               kpini = game.kpower[kk];
+               kp = fabs(kpini);
+               if (PHASEFAC*hit < kp) kp = PHASEFAC*hit;
+               game.kpower[kk] -= (game.kpower[kk] < 0 ? -kp: kp);
+               kpow = game.kpower[kk];
+               ii = game.kx[kk];
+               jj = game.ky[kk];
+               if (hit > 0.005) {
+#ifdef SERGEEV
+                        if (game.damage[DSRSENS]==0){
+                           crx=wherex();
+                           cry=wherey();
+                           setwnd(1);
+                           drawmaps(2);
+                           gotoxy(jj*2+3,ii+2);
+                           highvideo();
+                           proutn("%c", game.quad[ii][jj]);
+                           gotoxy(wherex()-1,wherey());
+                           sound(500);
+                           delay(1000);
+                           nosound();
+                           lowvideo();
+                           proutn("%c", game.quad[ii][jj]);
+                           setwnd(4);
+                           gotoxy(crx,cry);
+                           _setcursortype(_NORMALCURSOR);
+                           delay(500);
+                        }
+#endif /* SERGEEV */
+                       proutn("%d unit hit on ", (int)hit);
+               }
+               else
+                       proutn("Very small hit on ");
+               ienm = game.quad[ii][jj];
+                if (ienm==IHQUEST) iqengry=1;
+               crmena(0,ienm,2,ii,jj);
+               skip(1);
+               if (kpow == 0) {
+                       deadkl(ii, jj, ienm, ii, jj);
+                       if (game.state.remkl==0) finish(FWON);
+                       if (alldone) return;
+                       kk--; /* don't do the increment */
+               }
+               else /* decide whether or not to emasculate klingon */
+                       if (kpow > 0 && Rand() >= 0.9 &&
+                               kpow <= ((0.4 + 0.4*Rand())*kpini)) {
+                               prout("***Mr. Spock-  \"Captain, the vessel at ",
+                                       cramlc(sector,ii,jj));
+                               prout("   has just lost its firepower.\"");
+                               game.kpower[kk] = -kpow;
+                       }
+       }
+       return;
+}
+
index 641b77ad65f325944a9842f0ca345f7a8b052cb9..fd9d53c363ae4708b9bf7f11ac9f6566a78837af 100644 (file)
--- a/events.c
+++ b/events.c
-#include "sst.h"\r
-#include <math.h>\r
-\r
-void events(void) {\r
-        int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;\r
-        double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;\r
-\r
-#ifdef DEBUG\r
-       if (idebug) prout("EVENTS");\r
-#endif\r
-\r
-       if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {\r
-               /* chart will no longer be updated because radio is dead */\r
-               stdamtim = game.state.date;\r
-               for (i=1; i <= 8 ; i++)\r
-                       for (j=1; j <= 8; j++)\r
-                               if (game.starch[i][j] == 1) game.starch[i][j] = game.state.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 (game.future[l] < datemin) {\r
-                               line = l;\r
-                               datemin = game.future[l];\r
-                       }\r
-               xtime = datemin-game.state.date;\r
-               game.state.date = datemin;\r
-               /* Decrement Federation resources and recompute remaining time */\r
-               game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;\r
-               game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);\r
-               if (game.state.remtime <=0) {\r
-                       finish(FDEPLETE);\r
-                       return;\r
-               }\r
-               /* Is life support adequate? */\r
-               if (game.damage[DLIFSUP] && condit != IHDOCKED) {\r
-                       if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {\r
-                               finish(FLIFESUP);\r
-                               return;\r
-                       }\r
-                       lsupres -= xtime;\r
-                       if (game.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<=NDEVICES; l++)\r
-                       if (game.damage[l] > 0.0 && l != DDRAY)\r
-                               game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);\r
-               /* If radio repaired, update star chart and attack reports */\r
-               if (stdamtim != 1e30 && game.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 (game.starch[i][j] > 999) game.starch[i][j] = 1;\r
-                       if (iseenit==0) {\r
-                               attakreport(0);\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_game(1);\r
-                               ipage=1;\r
-                               snova(0,0);\r
-                               game.future[FSNOVA] = game.state.date + expran(0.5*intime);\r
-                               if (game.state.galaxy[quadx][quady] == 1000) return;\r
-                               break;\r
-                       case FSPY: /* Check with spy to see if S.C. should tractor beam */\r
-                               if (game.state.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
-                                       (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||\r
-                                       (game.damage[DSHIELD] > 0 &&\r
-                                        (energy < 2500 || game.damage[DPHASER] > 0) &&\r
-                                        (torps < 5 || game.damage[DPHOTON] > 0))) {\r
-                                       /* Tractor-beam her! */\r
-                                       istract=1;\r
-                                       yank = square(game.state.isx-quadx) + square(game.state.isy-quady);\r
-                                       /*********TBEAM CODE***********/\r
-                               }\r
-                               else return;\r
-                       case FTBEAM: /* Tractor beam */\r
-                               if (line==FTBEAM) {\r
-                                       if (game.state.remcom == 0) {\r
-                                               game.future[FTBEAM] = 1e30;\r
-                                               break;\r
-                                       }\r
-                                       i = Rand()*game.state.remcom+1.0;\r
-                                       yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);\r
-                                       if (istract || condit == IHDOCKED || yank == 0) {\r
-                                               /* Drats! Have to reschedule */\r
-                                               game.future[FTBEAM] = game.state.date + Time +\r
-                                                                                expran(1.5*intime/game.state.remcom);\r
-                                               break;\r
-                                       }\r
-                               }\r
-                               /* tractor beaming cases merge here */\r
-                               yank = sqrt(yank);\r
-                               if (ipage==0) pause_game(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
-                                               game.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 = game.state.isx;\r
-                                       quady = game.state.isy;\r
-                               }\r
-                               else {\r
-                                       quadx = game.state.cx[i];\r
-                                       quady = game.state.cy[i];\r
-                               }\r
-                               iran10(&sectx, &secty);\r
-                               crmshp();\r
-                               proutn(" is pulled to ");\r
-                               proutn(cramlc(quadrant, quadx, quady));\r
-                               proutn(", ");\r
-                               prout(cramlc(sector, sectx, secty));\r
-                               if (resting) {\r
-                                       prout("(Remainder of rest/repair period cancellegame.state.)");\r
-                                       resting = 0;\r
-                               }\r
-                               if (shldup==0) {\r
-                                       if (game.damage[DSHIELD]==0 && shield > 0) {\r
-                                               doshield(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 = game.state.date+Time;\r
-                                attack(0);\r
-                               if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;\r
-                               else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);\r
-                               break;\r
-                       case FSNAP: /* Snapshot of the universe (for time warp) */\r
-                               game.snapsht = game.state;\r
-                               game.state.snap = 1;\r
-                               game.future[FSNAP] = game.state.date + expran(0.5 * intime);\r
-                               break;\r
-                       case FBATTAK: /* Commander attacks starbase */\r
-                               if (game.state.remcom==0 || game.state.rembase==0) {\r
-                                       /* no can do */\r
-                                       game.future[FBATTAK] = game.future[FCDBAS] = 1e30;\r
-                                       break;\r
-                               }\r
-                               i = 0;\r
-                               for (j=1; j<=game.state.rembase; j++) {\r
-                                       for (k=1; k<=game.state.remcom; k++)\r
-                                               if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&\r
-                                                       (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&\r
-                                                       (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {\r
-                                                       i = 1;\r
-                                                       break;\r
-                                               }\r
-                                       if (i == 1) break;\r
-                               }\r
-                               if (j>game.state.rembase) {\r
-                                       /* no match found -- try later */\r
-                                       game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
-                                       game.future[FCDBAS] = 1e30;\r
-                                       break;\r
-                               }\r
-                               /* commander + starbase combination found -- launch attack */\r
-                               batx = game.state.baseqx[j];\r
-                               baty = game.state.baseqy[j];\r
-                               game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();\r
-                               if (isatb) /* extra time if SC already attacking */\r
-                                       game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;\r
-                               game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);\r
-                               iseenit = 0;\r
-                               if (game.damage[DRADIO] != 0.0 &&\r
-                                       condit != IHDOCKED) break; /* No warning :-( */\r
-                               iseenit = 1;\r
-                               if (ipage==0) pause_game(1);\r
-                               ipage = 1;\r
-                               skip(1);\r
-                               proutn("Lt. Uhura-  \"Captain, the starbase in ");\r
-                               prout(cramlc(quadrant, batx, baty));\r
-                               prout("   reports that it is under attack and that it can");\r
-                               proutn("   hold out only until stardate %d",\r
-                                       (int)game.future[FCDBAS]);\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
-                               game.future[FSCDBAS] = 1e30;\r
-                               isatb = 2;\r
-                               if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */\r
-                               ixhold = batx;\r
-                               iyhold = baty;\r
-                               batx = game.state.isx;\r
-                               baty = game.state.isy;\r
-                       case FCDBAS: /* Commander succeeds in destroying base */\r
-                               if (line==FCDBAS) {\r
-                                       game.future[FCDBAS] = 1e30;\r
-                                       /* find the lucky pair */\r
-                                       for (i = 1; i <= game.state.remcom; i++)\r
-                                               if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;\r
-                                       if (i > game.state.remcom || game.state.rembase == 0 ||\r
-                                               game.state.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 (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;\r
-                               /* Handle case where base is in same quadrant as starship */\r
-                               if (batx==quadx && baty==quady) {\r
-                                       if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;\r
-                                       game.quad[basex][basey]= IHDOT;\r
-                                       basex=basey=0;\r
-                                       newcnd();\r
-                                       skip(1);\r
-                                       prout("Spock-  \"Captain, I believe the starbase has been destroyegame.state.\"");\r
-                               }\r
-                               else if (game.state.rembase != 1 &&\r
-                                                (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {\r
-                                       /* Get word via subspace radio */\r
-                                       if (ipage==0) pause_game(1);\r
-                                       ipage = 1;\r
-                                       skip(1);\r
-                                       prout("Lt. Uhura-  \"Captain, Starfleet Command reports that");\r
-                                       proutn("   the starbase in ");\r
-                                       proutn(cramlc(quadrant, 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
-                               game.state.galaxy[batx][baty] -= 10;\r
-                               for (i=1; i <= game.state.rembase; i++)\r
-                                       if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {\r
-                                               game.state.baseqx[i]=game.state.baseqx[game.state.rembase];\r
-                                               game.state.baseqy[i]=game.state.baseqy[game.state.rembase];\r
-                                       }\r
-                               game.state.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
-                               game.future[FSCMOVE] = game.state.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
-                               game.future[FDSPROB] = game.state.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
-                                               game.state.galaxy[probecx][probecy] == 1000) {\r
-                                               // Left galaxy or ran into supernova\r
-                                               if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
-                                                       if (ipage==0) pause_game(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
-                                               game.future[FDSPROB] = 1e30;\r
-                                               break;\r
-                                       }\r
-                                       if (game.damage[DRADIO]==0.0   || condit == IHDOCKED) {\r
-                                               if (ipage==0) pause_game(1);\r
-                                               ipage = 1;\r
-                                               skip(1);\r
-                                               proutn("Lt. Uhura-  \"The deep space probe is now in ");\r
-                                               proutn(cramlc(quadrant, probecx, probecy));\r
-                                               prout(".\"");\r
-                                       }\r
-                               }\r
-                               /* Update star chart if Radio is working or have access to\r
-                                  radio. */\r
-                               if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)\r
-                                       game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?\r
-                                                                                  game.state.galaxy[probecx][probecy]+1000 : 1;\r
-                               proben--; // One less to travel\r
-                               if (proben == 0 && isarmed &&\r
-                                       game.state.galaxy[probecx][probecy] % 10 > 0) {\r
-                                       /* lets blow the sucker! */\r
-                                       snova(1,0);\r
-                                       game.future[FDSPROB] = 1e30;\r
-                                       if (game.state.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 >= game.state.remtime || nenhere != 0) {\r
-               proutn("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
-                       prout("%d stardates left.", (int)game.state.remtime);\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 (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
-                       game.damage[DDRAY] = 0.0;\r
-       } while (game.state.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, 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
-       game.quad[ix][iy] = IHDOT;\r
-       crmena(1, IHSTAR, 2, ix, iy);\r
-       prout(" novas.");\r
-       game.state.galaxy[quadx][quady] -= 1;\r
-       game.state.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 = game.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
-                                               game.state.galaxy[quadx][quady] -= 1;\r
-                                               game.state.starkl++;\r
-                                               crmena(1, IHSTAR, 2, ii, jj);\r
-                                               prout(" novas.");\r
-                                               game.quad[ii][jj] = IHDOT;\r
-                                               break;\r
-                                       case IHP: /* Destroy planet */\r
-                                               game.state.newstuf[quadx][quady] -= 1;\r
-                                               game.state.nplankl++;\r
-                                               crmena(1, IHP, 2, ii, jj);\r
-                                               prout(" destroyed.");\r
-                                               DESTROY(&game.state.plnets[iplnet]);\r
-                                               iplnet = plnetx = plnety = 0;\r
-                                               if (landed == 1) {\r
-                                                       finish(FPNOVA);\r
-                                                       return;\r
-                                               }\r
-                                               game.quad[ii][jj] = IHDOT;\r
-                                               break;\r
-                                       case IHB: /* Destroy base */\r
-                                               game.state.galaxy[quadx][quady] -= 10;\r
-                                               for (i = 1; i <= game.state.rembase; i++)\r
-                                                       if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;\r
-                                               game.state.baseqx[i] = game.state.baseqx[game.state.rembase];\r
-                                               game.state.baseqy[i] = game.state.baseqy[game.state.rembase];\r
-                                               game.state.rembase--;\r
-                                               basex = basey = 0;\r
-                                               game.state.basekl++;\r
-                                               newcnd();\r
-                                               crmena(1, IHB, 2, ii, jj);\r
-                                               prout(" destroyed.");\r
-                                               game.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
-                                                               game.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 (game.kx[ll]==ii && game.ky[ll]==jj) break;\r
-                                               game.kpower[ll] -= 800.0; /* If firepower is lost, die */\r
-                                               if (game.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 = game.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
-                                               proutn(cramlc(sector, newcx, newcy));\r
-                                               game.quad[ii][jj] = IHDOT;\r
-                                               game.quad[newcx][newcy] = iquad;\r
-                                               game.kx[ll] = newcx;\r
-                                               game.ky[ll] = newcy;\r
-                                               game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));\r
-                                               game.kdist[ll] = game.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
-       imove();\r
-       Time = 10.0*dist/16.0;\r
-       return;\r
-}\r
-       \r
-       \r
-void snova(int insx, int insy) {\r
-        int comdead, nqx=0, nqy=0, 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 += game.state.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 -= game.state.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 (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
-                               skip(1);\r
-                               prout("Message from Starfleet Command       Stardate %.2f", game.state.date);\r
-                               prout("     Supernova in %s; caution advised.",\r
-                                      cramlc(quadrant, nqx, nqy));\r
-                       }\r
-               }\r
-               else {\r
-                       /* we are in the quadrant! */\r
-                       insipient = 1;\r
-                       num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;\r
-                       for (nsx=1; nsx < 10; nsx++) {\r
-                               for (nsy=1; nsy < 10; nsy++) {\r
-                                       if (game.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
-               prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));\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=game.state.galaxy[nqx][nqy];\r
-       kldead = num/100;\r
-       comdead = iscdead = 0;\r
-       if (nqx==game.state.isx && nqy == game.state.isy) {\r
-               /* did in the Supercommander! */\r
-               game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;\r
-               iscdead = 1;\r
-               game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
-       }\r
-       game.state.remkl -= kldead;\r
-       if (game.state.remcom) {\r
-               int maxloop = game.state.remcom, l;\r
-               for (l = 1; l <= maxloop; l++) {\r
-                       if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {\r
-                               game.state.cx[l] = game.state.cx[game.state.remcom];\r
-                               game.state.cy[l] = game.state.cy[game.state.remcom];\r
-                               game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;\r
-                               game.state.remcom--;\r
-                               kldead--;\r
-                               comdead++;\r
-                               if (game.state.remcom==0) game.future[FTBEAM] = 1e30;\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-       /* destroy Romulans and planets in supernovaed quadrant */\r
-       num = game.state.newstuf[nqx][nqy];\r
-       game.state.newstuf[nqx][nqy] = 0;\r
-       nrmdead = num/10;\r
-       game.state.nromrem -= nrmdead;\r
-       npdead = num - nrmdead*10;\r
-       if (npdead) {\r
-               int l;\r
-               for (l = 0; l < inplan; l++)\r
-                       if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {\r
-                           DESTROY(&game.state.plnets[l]);\r
-                       }\r
-       }\r
-       /* Destroy any base in supernovaed quadrant */\r
-       if (game.state.rembase) {\r
-               int maxloop = game.state.rembase, l;\r
-               for (l = 1; l <= maxloop; l++)\r
-                       if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {\r
-                               game.state.baseqx[l] = game.state.baseqx[game.state.rembase];\r
-                               game.state.baseqy[l] = game.state.baseqy[game.state.rembase];\r
-                               game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;\r
-                               game.state.rembase--;\r
-                               break;\r
-                       }\r
-       }\r
-       /* If starship caused supernova, tally up destruction */\r
-       if (insx) {\r
-               num = game.state.galaxy[nqx][nqy] % 100;\r
-               game.state.starkl += num % 10;\r
-               game.state.basekl += num/10;\r
-               game.state.killk += kldead;\r
-               game.state.killc += comdead;\r
-               game.state.nromkl += nrmdead;\r
-               game.state.nplankl += npdead;\r
-               game.state.nsckill += iscdead;\r
-       }\r
-       /* mark supernova in galaxy and in star chart */\r
-       if ((quadx == nqx && quady == nqy) ||\r
-               game.damage[DRADIO] == 0 ||\r
-               condit == IHDOCKED)\r
-               game.starch[nqx][nqy] = 1;\r
-       game.state.galaxy[nqx][nqy] = 1000;\r
-       /* If supernova destroys last klingons give special message */\r
-       if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {\r
-               skip(2);\r
-               if (insx == 0) prout("Lucky you!");\r
-               proutn("A supernova in %s has just destroyed the last Klingons.",\r
-                      cramlc(quadrant, nqx, nqy));\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
+#include "sst.h"
+#include <math.h>
+
+void events(void) {
+        int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
+        double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;
+
+#ifdef DEBUG
+       if (idebug) prout("EVENTS");
+#endif
+
+       if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {
+               /* chart will no longer be updated because radio is dead */
+               stdamtim = game.state.date;
+               for (i=1; i <= 8 ; i++)
+                       for (j=1; j <= 8; j++)
+                               if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;
+       }
+
+       for (;;) {
+               /* Select earliest extraneous event, line==0 if no events */
+               line = FSPY;
+               if (alldone) return;
+               datemin = fintim;
+               for (l=1; l<=NEVENTS; l++)
+                       if (game.future[l] < datemin) {
+                               line = l;
+                               datemin = game.future[l];
+                       }
+               xtime = datemin-game.state.date;
+               game.state.date = datemin;
+               /* Decrement Federation resources and recompute remaining time */
+               game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
+               game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
+               if (game.state.remtime <=0) {
+                       finish(FDEPLETE);
+                       return;
+               }
+               /* Is life support adequate? */
+               if (game.damage[DLIFSUP] && condit != IHDOCKED) {
+                       if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {
+                               finish(FLIFESUP);
+                               return;
+                       }
+                       lsupres -= xtime;
+                       if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;
+               }
+               /* Fix devices */
+               repair = xtime;
+               if (condit == IHDOCKED) repair /= docfac;
+               /* Don't fix Deathray here */
+               for (l=1; l<=NDEVICES; l++)
+                       if (game.damage[l] > 0.0 && l != DDRAY)
+                               game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
+               /* If radio repaired, update star chart and attack reports */
+               if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {
+                       stdamtim = 1e30;
+                       prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
+                       prout("   surveillance reports are coming in.");
+                       skip(1);
+                       for (i=1; i <= 8 ; i++)
+                               for (j=1; j <= 8; j++)
+                                       if (game.starch[i][j] > 999) game.starch[i][j] = 1;
+                       if (iseenit==0) {
+                               attakreport(0);
+                               iseenit = 1;
+                       }
+                       skip(1);
+                       prout("   The star chart is now up to date.\"");
+                       skip(1);
+               }
+               /* Cause extraneous event LINE to occur */
+               Time -= xtime;
+               switch (line) {
+                       case FSNOVA: /* Supernova */
+                               if (ipage==0) pause_game(1);
+                               ipage=1;
+                               snova(0,0);
+                               game.future[FSNOVA] = game.state.date + expran(0.5*intime);
+                               if (game.state.galaxy[quadx][quady] == 1000) return;
+                               break;
+                       case FSPY: /* Check with spy to see if S.C. should tractor beam */
+                               if (game.state.nscrem == 0 ||
+                                       ictbeam+istract > 0 ||
+                                       condit==IHDOCKED || isatb==1 || iscate==1) return;
+                               if (ientesc ||
+                                       (energy < 2000 && torps < 4 && shield < 1250) ||
+                                       (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
+                                       (game.damage[DSHIELD] > 0 &&
+                                        (energy < 2500 || game.damage[DPHASER] > 0) &&
+                                        (torps < 5 || game.damage[DPHOTON] > 0))) {
+                                       /* Tractor-beam her! */
+                                       istract=1;
+                                       yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
+                                       /*********TBEAM CODE***********/
+                               }
+                               else return;
+                       case FTBEAM: /* Tractor beam */
+                               if (line==FTBEAM) {
+                                       if (game.state.remcom == 0) {
+                                               game.future[FTBEAM] = 1e30;
+                                               break;
+                                       }
+                                       i = Rand()*game.state.remcom+1.0;
+                                       yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
+                                       if (istract || condit == IHDOCKED || yank == 0) {
+                                               /* Drats! Have to reschedule */
+                                               game.future[FTBEAM] = game.state.date + Time +
+                                                                                expran(1.5*intime/game.state.remcom);
+                                               break;
+                                       }
+                               }
+                               /* tractor beaming cases merge here */
+                               yank = sqrt(yank);
+                               if (ipage==0) pause_game(1);
+                               ipage=1;
+                               Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
+                               ictbeam = 1;
+                               skip(1);
+                               proutn("***");
+                               crmshp();
+                               prout(" caught in long range tractor beam--");
+                               /* If Kirk & Co. screwing around on planet, handle */
+                               atover(1); /* atover(1) is Grab */
+                               if (alldone) return;
+                               if (icraft == 1) { /* Caught in Galileo? */
+                                       finish(FSTRACTOR);
+                                       return;
+                               }
+                               /* Check to see if shuttle is aboard */
+                               if (iscraft==0) {
+                                       skip(1);
+                                       if (Rand() >0.5) {
+                                               prout("Galileo, left on the planet surface, is captured");
+                                               prout("by aliens and made into a flying McDonald's.");
+                                               game.damage[DSHUTTL] = -10;
+                                               iscraft = -1;
+                                       }
+                                       else {
+                                               prout("Galileo, left on the planet surface, is well hidden.");
+                                       }
+                               }
+                               if (line==0) {
+                                       quadx = game.state.isx;
+                                       quady = game.state.isy;
+                               }
+                               else {
+                                       quadx = game.state.cx[i];
+                                       quady = game.state.cy[i];
+                               }
+                               iran10(&sectx, &secty);
+                               crmshp();
+                               proutn(" is pulled to ");
+                               proutn(cramlc(quadrant, quadx, quady));
+                               proutn(", ");
+                               prout(cramlc(sector, sectx, secty));
+                               if (resting) {
+                                       prout("(Remainder of rest/repair period cancellegame.state.)");
+                                       resting = 0;
+                               }
+                               if (shldup==0) {
+                                       if (game.damage[DSHIELD]==0 && shield > 0) {
+                                               doshield(2); /* Shldsup */
+                                               shldchg=0;
+                                       }
+                                       else prout("(Shields not currently useable.)");
+                               }
+                               newqad(0);
+                               /* Adjust finish time to time of tractor beaming */
+                               fintim = game.state.date+Time;
+                                attack(0);
+                               if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;
+                               else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
+                               break;
+                       case FSNAP: /* Snapshot of the universe (for time warp) */
+                               game.snapsht = game.state;
+                               game.state.snap = 1;
+                               game.future[FSNAP] = game.state.date + expran(0.5 * intime);
+                               break;
+                       case FBATTAK: /* Commander attacks starbase */
+                               if (game.state.remcom==0 || game.state.rembase==0) {
+                                       /* no can do */
+                                       game.future[FBATTAK] = game.future[FCDBAS] = 1e30;
+                                       break;
+                               }
+                               i = 0;
+                               for (j=1; j<=game.state.rembase; j++) {
+                                       for (k=1; k<=game.state.remcom; k++)
+                                               if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
+                                                       (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
+                                                       (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
+                                                       i = 1;
+                                                       break;
+                                               }
+                                       if (i == 1) break;
+                               }
+                               if (j>game.state.rembase) {
+                                       /* no match found -- try later */
+                                       game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+                                       game.future[FCDBAS] = 1e30;
+                                       break;
+                               }
+                               /* commander + starbase combination found -- launch attack */
+                               batx = game.state.baseqx[j];
+                               baty = game.state.baseqy[j];
+                               game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
+                               if (isatb) /* extra time if SC already attacking */
+                                       game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
+                               game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
+                               iseenit = 0;
+                               if (game.damage[DRADIO] != 0.0 &&
+                                       condit != IHDOCKED) break; /* No warning :-( */
+                               iseenit = 1;
+                               if (ipage==0) pause_game(1);
+                               ipage = 1;
+                               skip(1);
+                               proutn("Lt. Uhura-  \"Captain, the starbase in ");
+                               prout(cramlc(quadrant, batx, baty));
+                               prout("   reports that it is under attack and that it can");
+                               proutn("   hold out only until stardate %d",
+                                       (int)game.future[FCDBAS]);
+                               prout(".\"");
+                               if (resting) {
+                                       skip(1);
+                                       proutn("Mr. Spock-  \"Captain, shall we cancel the rest period?\" ");
+                                       if (ja()) {
+                                               resting = 0;
+                                               Time = 0.0;
+                                               return;
+                                       }
+                               }
+                               break;
+                       case FSCDBAS: /* Supercommander destroys base */
+                               game.future[FSCDBAS] = 1e30;
+                               isatb = 2;
+                               if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */
+                               ixhold = batx;
+                               iyhold = baty;
+                               batx = game.state.isx;
+                               baty = game.state.isy;
+                       case FCDBAS: /* Commander succeeds in destroying base */
+                               if (line==FCDBAS) {
+                                       game.future[FCDBAS] = 1e30;
+                                       /* find the lucky pair */
+                                       for (i = 1; i <= game.state.remcom; i++)
+                                               if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;
+                                       if (i > game.state.remcom || game.state.rembase == 0 ||
+                                               game.state.galaxy[batx][baty] % 100 < 10) {
+                                               /* No action to take after all */
+                                               batx = baty = 0;
+                                               break;
+                                       }
+                               }
+                               /* Code merges here for any commander destroying base */
+                               /* Not perfect, but will have to do */
+                               if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;
+                               /* Handle case where base is in same quadrant as starship */
+                               if (batx==quadx && baty==quady) {
+                                       if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;
+                                       game.quad[basex][basey]= IHDOT;
+                                       basex=basey=0;
+                                       newcnd();
+                                       skip(1);
+                                       prout("Spock-  \"Captain, I believe the starbase has been destroyegame.state.\"");
+                               }
+                               else if (game.state.rembase != 1 &&
+                                                (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
+                                       /* Get word via subspace radio */
+                                       if (ipage==0) pause_game(1);
+                                       ipage = 1;
+                                       skip(1);
+                                       prout("Lt. Uhura-  \"Captain, Starfleet Command reports that");
+                                       proutn("   the starbase in ");
+                                       proutn(cramlc(quadrant, batx, baty));
+                                       prout(" has been destroyed by");
+                                       if (isatb==2) prout("the Klingon Super-Commander");
+                                       else prout("a Klingon Commander");
+                               }
+                               /* Remove Starbase from galaxy */
+                               game.state.galaxy[batx][baty] -= 10;
+                               for (i=1; i <= game.state.rembase; i++)
+                                       if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
+                                               game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
+                                               game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
+                                       }
+                               game.state.rembase--;
+                               if (isatb == 2) {
+                                       /* reinstate a commander's base attack */
+                                       batx = ixhold;
+                                       baty = iyhold;
+                                       isatb = 0;
+                               }
+                               else {
+                                       batx = baty = 0;
+                               }
+                               break;
+                       case FSCMOVE: /* Supercommander moves */
+                               game.future[FSCMOVE] = game.state.date+0.2777;
+                               if (ientesc+istract==0 &&
+                                       isatb!=1 &&
+                                       (iscate!=1 || justin==1)) scom(&ipage);
+                               break;
+                       case FDSPROB: /* Move deep space probe */
+                               game.future[FDSPROB] = game.state.date + 0.01;
+                               probex += probeinx;
+                               probey += probeiny;
+                               i = (int)(probex/10 +0.05);
+                               j = (int)(probey/10 + 0.05);
+                               if (probecx != i || probecy != j) {
+                                       probecx = i;
+                                       probecy = j;
+                                       if (i < 1 || i > 8 || j < 1 || j > 8 ||
+                                               game.state.galaxy[probecx][probecy] == 1000) {
+                                               // Left galaxy or ran into supernova
+                                               if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
+                                                       if (ipage==0) pause_game(1);
+                                                       ipage = 1;
+                                                       skip(1);
+                                                       proutn("Lt. Uhura-  \"The deep space probe ");
+                                                       if (i < 1 ||i > 8 || j < 1 || j > 8)
+                                                               proutn("has left the galaxy");
+                                                       else
+                                                               proutn("is no longer transmitting");
+                                                       prout(".\"");
+                                               }
+                                               game.future[FDSPROB] = 1e30;
+                                               break;
+                                       }
+                                       if (game.damage[DRADIO]==0.0   || condit == IHDOCKED) {
+                                               if (ipage==0) pause_game(1);
+                                               ipage = 1;
+                                               skip(1);
+                                               proutn("Lt. Uhura-  \"The deep space probe is now in ");
+                                               proutn(cramlc(quadrant, probecx, probecy));
+                                               prout(".\"");
+                                       }
+                               }
+                               /* Update star chart if Radio is working or have access to
+                                  radio. */
+                               if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)
+                                       game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?
+                                                                                  game.state.galaxy[probecx][probecy]+1000 : 1;
+                               proben--; // One less to travel
+                               if (proben == 0 && isarmed &&
+                                       game.state.galaxy[probecx][probecy] % 10 > 0) {
+                                       /* lets blow the sucker! */
+                                       snova(1,0);
+                                       game.future[FDSPROB] = 1e30;
+                                       if (game.state.galaxy[quadx][quady] == 1000) return;
+                               }
+                               break;
+               }
+       }
+}
+
+                               
+void wait(void) {
+       int key;
+       double temp, delay, origTime;
+
+       ididit = 0;
+       for (;;) {
+               key = scan();
+               if (key  != IHEOL) break;
+               proutn("How long? ");
+       }
+       chew();
+       if (key != IHREAL) {
+               huh();
+               return;
+       }
+       origTime = delay = aaitem;
+       if (delay <= 0.0) return;
+       if (delay >= game.state.remtime || nenhere != 0) {
+               proutn("Are you sure? ");
+               if (ja() == 0) return;
+       }
+
+       /* Alternate resting periods (events) with attacks */
+
+       resting = 1;
+       do {
+               if (delay <= 0) resting = 0;
+               if (resting == 0) {
+                       prout("%d stardates left.", (int)game.state.remtime);
+                       return;
+               }
+               temp = Time = delay;
+
+               if (nenhere) {
+                       double rtime = 1.0 + Rand();
+                       if (rtime < temp) temp = rtime;
+                       Time = temp;
+               }
+               if (Time < delay) attack(0);
+               if (alldone) return;
+               events();
+               ididit = 1;
+               if (alldone) return;
+               delay -= temp;
+               /* Repair Deathray if long rest at starbase */
+               if (origTime-delay >= 9.99 && condit == IHDOCKED)
+                       game.damage[DDRAY] = 0.0;
+       } while (game.state.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas
+
+       resting = 0;
+       Time = 0;
+}
+
+void nova(int ix, int iy) {
+       static double course[] =
+               {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
+        int bot, top, top2, hits[11][3], kount, icx, icy, mm, nn, j;
+       int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
+       if (Rand() < 0.05) {
+               /* Wow! We've supernova'ed */
+               snova(ix, iy);
+               return;
+       }
+
+       /* handle initial nova */
+       game.quad[ix][iy] = IHDOT;
+       crmena(1, IHSTAR, 2, ix, iy);
+       prout(" novas.");
+       game.state.galaxy[quadx][quady] -= 1;
+       game.state.starkl++;
+       
+       /* Set up stack to recursively trigger adjacent stars */
+       bot = top = top2 = 1;
+       kount = 0;
+       icx = icy = 0;
+       hits[1][1] = ix;
+       hits[1][2] = iy;
+       while (1) {
+               for (mm = bot; mm <= top; mm++) 
+               for (nn = 1; nn <= 3; nn++)  /* nn,j represents coordinates around current */
+                       for (j = 1; j <= 3; j++) {
+                               if (j==2 && nn== 2) continue;
+                               ii = hits[mm][1]+nn-2;
+                               jj = hits[mm][2]+j-2;
+                               if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;
+                               iquad = game.quad[ii][jj];
+                               switch (iquad) {
+//                                     case IHDOT:     /* Empty space ends reaction
+//                                     case IHQUEST:
+//                                     case IHBLANK:
+//                                     case IHT:
+//                                     case IHWEB:
+                                       default:
+                                               break;
+                                       case IHSTAR: /* Affect another star */
+                                               if (Rand() < 0.05) {
+                                                       /* This star supernovas */
+                                                       snova(ii,jj);
+                                                       return;
+                                               }
+                                               top2++;
+                                               hits[top2][1]=ii;
+                                               hits[top2][2]=jj;
+                                               game.state.galaxy[quadx][quady] -= 1;
+                                               game.state.starkl++;
+                                               crmena(1, IHSTAR, 2, ii, jj);
+                                               prout(" novas.");
+                                               game.quad[ii][jj] = IHDOT;
+                                               break;
+                                       case IHP: /* Destroy planet */
+                                               game.state.newstuf[quadx][quady] -= 1;
+                                               game.state.nplankl++;
+                                               crmena(1, IHP, 2, ii, jj);
+                                               prout(" destroyed.");
+                                               DESTROY(&game.state.plnets[iplnet]);
+                                               iplnet = plnetx = plnety = 0;
+                                               if (landed == 1) {
+                                                       finish(FPNOVA);
+                                                       return;
+                                               }
+                                               game.quad[ii][jj] = IHDOT;
+                                               break;
+                                       case IHB: /* Destroy base */
+                                               game.state.galaxy[quadx][quady] -= 10;
+                                               for (i = 1; i <= game.state.rembase; i++)
+                                                       if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;
+                                               game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
+                                               game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
+                                               game.state.rembase--;
+                                               basex = basey = 0;
+                                               game.state.basekl++;
+                                               newcnd();
+                                               crmena(1, IHB, 2, ii, jj);
+                                               prout(" destroyed.");
+                                               game.quad[ii][jj] = IHDOT;
+                                               break;
+                                       case IHE: /* Buffet ship */
+                                       case IHF:
+                                               prout("***Starship buffeted by nova.");
+                                               if (shldup) {
+                                                       if (shield >= 2000.0) shield -= 2000.0;
+                                                       else {
+                                                               double diff = 2000.0 - shield;
+                                                               energy -= diff;
+                                                               shield = 0.0;
+                                                               shldup = 0;
+                                                               prout("***Shields knocked out.");
+                                                               game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
+                                                       }
+                                               }
+                                               else energy -= 2000.0;
+                                               if (energy <= 0) {
+                                                       finish(FNOVA);
+                                                       return;
+                                               }
+                                               /* add in course nova contributes to kicking starship*/
+                                               icx += sectx-hits[mm][1];
+                                               icy += secty-hits[mm][2];
+                                               kount++;
+                                               break;
+                                       case IHK: /* kill klingon */
+                                               deadkl(ii,jj,iquad, ii, jj);
+                                               break;
+                                       case IHC: /* Damage/destroy big enemies */
+                                       case IHS:
+                                       case IHR:
+                                               for (ll = 1; ll <= nenhere; ll++)
+                                                       if (game.kx[ll]==ii && game.ky[ll]==jj) break;
+                                               game.kpower[ll] -= 800.0; /* If firepower is lost, die */
+                                               if (game.kpower[ll] <= 0.0) {
+                                                       deadkl(ii, jj, iquad, ii, jj);
+                                                       break;
+                                               }
+                                               newcx = ii + ii - hits[mm][1];
+                                               newcy = jj + jj - hits[mm][2];
+                                               crmena(1, iquad, 2, ii, jj);
+                                               proutn(" damaged");
+                                               if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {
+                                                       /* can't leave quadrant */
+                                                       skip(1);
+                                                       break;
+                                               }
+                                               iquad1 = game.quad[newcx][newcy];
+                                               if (iquad1 == IHBLANK) {
+                                                       proutn(", blasted into ");
+                                                       crmena(0, IHBLANK, 2, newcx, newcy);
+                                                       skip(1);
+                                                       deadkl(ii, jj, iquad, newcx, newcy);
+                                                       break;
+                                               }
+                                               if (iquad1 != IHDOT) {
+                                                       /* can't move into something else */
+                                                       skip(1);
+                                                       break;
+                                               }
+                                               proutn(", buffeted to ");
+                                               proutn(cramlc(sector, newcx, newcy));
+                                               game.quad[ii][jj] = IHDOT;
+                                               game.quad[newcx][newcy] = iquad;
+                                               game.kx[ll] = newcx;
+                                               game.ky[ll] = newcy;
+                                               game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
+                                               game.kdist[ll] = game.kavgd[ll];
+                                               skip(1);
+                                               break;
+                               }
+                       }
+               if (top == top2) break;
+               bot = top + 1;
+               top = top2;
+       }
+       if (kount==0) return;
+
+       /* Starship affected by nova -- kick it away. */
+       dist = kount*0.1;
+       if (icx) icx = (icx < 0 ? -1 : 1);
+       if (icy) icy = (icy < 0 ? -1 : 1);
+       direc = course[3*(icx+1)+icy+2];
+       if (direc == 0.0) dist = 0.0;
+       if (dist == 0.0) return;
+       Time = 10.0*dist/16.0;
+       skip(1);
+       prout("Force of nova displaces starship.");
+       iattak=2;       /* Eliminates recursion problem */
+       imove();
+       Time = 10.0*dist/16.0;
+       return;
+}
+       
+       
+void snova(int insx, int insy) {
+        int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;
+       int nrmdead, npdead;
+       int insipient=0;
+
+       nsx = insy;
+       nsy = insy;
+
+       if (insy== 0) {
+               if (insx == 1) {
+                       /* NOVAMAX being used */
+                       nqx = probecx;
+                       nqy = probecy;
+               }
+               else {
+                       int stars = 0;
+                       /* Scheduled supernova -- select star */
+                       /* logic changed here so that we won't favor quadrants in top
+                       left of universe */
+                       for (nqx = 1; nqx<=8; nqx++) {
+                               for (nqy = 1; nqy<=8; nqy++) {
+                                       stars += game.state.galaxy[nqx][nqy] % 10;
+                               }
+                       }
+                       if (stars == 0) return; /* nothing to supernova exists */
+                       num = Rand()*stars + 1;
+                       for (nqx = 1; nqx<=8; nqx++) {
+                               for (nqy = 1; nqy<=8; nqy++) {
+                                       num -= game.state.galaxy[nqx][nqy] % 10;
+                                       if (num <= 0) break;
+                               }
+                               if (num <=0) break;
+                       }
+#ifdef DEBUG
+                       if (idebug) {
+                               proutn("Super nova here?");
+                               if (ja()==1) {
+                                       nqx = quadx;
+                                       nqy = quady;
+                               }
+                       }
+#endif
+               }
+
+               if (nqx != quady || nqy != quady || justin != 0) {
+                       /* it isn't here, or we just entered (treat as inroute) */
+                       if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
+                               skip(1);
+                               prout("Message from Starfleet Command       Stardate %.2f", game.state.date);
+                               prout("     Supernova in %s; caution advised.",
+                                      cramlc(quadrant, nqx, nqy));
+                       }
+               }
+               else {
+                       /* we are in the quadrant! */
+                       insipient = 1;
+                       num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;
+                       for (nsx=1; nsx < 10; nsx++) {
+                               for (nsy=1; nsy < 10; nsy++) {
+                                       if (game.quad[nsx][nsy]==IHSTAR) {
+                                               num--;
+                                               if (num==0) break;
+                                       }
+                               }
+                               if (num==0) break;
+                       }
+               }
+       }
+       else {
+               insipient = 1;
+       }
+
+       if (insipient) {
+               skip(1);
+               prouts("***RED ALERT!  RED ALERT!");
+               skip(1);
+               prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
+               nqx = quadx;
+               nqy = quady;
+               if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
+                       proutn("Emergency override attempts t");
+                       prouts("***************");
+                       skip(1);
+                       stars();
+                       alldone=1;
+               }
+       }
+       /* destroy any Klingons in supernovaed quadrant */
+       num=game.state.galaxy[nqx][nqy];
+       kldead = num/100;
+       comdead = iscdead = 0;
+       if (nqx==game.state.isx && nqy == game.state.isy) {
+               /* did in the Supercommander! */
+               game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
+               iscdead = 1;
+               game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
+       }
+       game.state.remkl -= kldead;
+       if (game.state.remcom) {
+               int maxloop = game.state.remcom, l;
+               for (l = 1; l <= maxloop; l++) {
+                       if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
+                               game.state.cx[l] = game.state.cx[game.state.remcom];
+                               game.state.cy[l] = game.state.cy[game.state.remcom];
+                               game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
+                               game.state.remcom--;
+                               kldead--;
+                               comdead++;
+                               if (game.state.remcom==0) game.future[FTBEAM] = 1e30;
+                               break;
+                       }
+               }
+       }
+       /* destroy Romulans and planets in supernovaed quadrant */
+       num = game.state.newstuf[nqx][nqy];
+       game.state.newstuf[nqx][nqy] = 0;
+       nrmdead = num/10;
+       game.state.nromrem -= nrmdead;
+       npdead = num - nrmdead*10;
+       if (npdead) {
+               int l;
+               for (l = 0; l < inplan; l++)
+                       if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
+                           DESTROY(&game.state.plnets[l]);
+                       }
+       }
+       /* Destroy any base in supernovaed quadrant */
+       if (game.state.rembase) {
+               int maxloop = game.state.rembase, l;
+               for (l = 1; l <= maxloop; l++)
+                       if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
+                               game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
+                               game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
+                               game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
+                               game.state.rembase--;
+                               break;
+                       }
+       }
+       /* If starship caused supernova, tally up destruction */
+       if (insx) {
+               num = game.state.galaxy[nqx][nqy] % 100;
+               game.state.starkl += num % 10;
+               game.state.basekl += num/10;
+               game.state.killk += kldead;
+               game.state.killc += comdead;
+               game.state.nromkl += nrmdead;
+               game.state.nplankl += npdead;
+               game.state.nsckill += iscdead;
+       }
+       /* mark supernova in galaxy and in star chart */
+       if ((quadx == nqx && quady == nqy) ||
+               game.damage[DRADIO] == 0 ||
+               condit == IHDOCKED)
+               game.starch[nqx][nqy] = 1;
+       game.state.galaxy[nqx][nqy] = 1000;
+       /* If supernova destroys last klingons give special message */
+       if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
+               skip(2);
+               if (insx == 0) prout("Lucky you!");
+               proutn("A supernova in %s has just destroyed the last Klingons.",
+                      cramlc(quadrant, nqx, nqy));
+               finish(FWON);
+               return;
+       }
+       /* if some Klingons remain, continue or die in supernova */
+       if (alldone) finish(FSNOVAED);
+       return;
+}
+               
+                               
index 8a8427a79c3c5b01ad68b9e3195d7327e993dcb6..2caf34d266830ee93dbfde9a8caec55b0e7cdda4 100644 (file)
--- a/finish.c
+++ b/finish.c
-#include "sst.h"\r
-#include <string.h>\r
-#include <time.h>\r
-\r
-void dstrct() {\r
-       /* Finish with a BANG! */\r
-       chew();\r
-       if (game.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(game.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 (game.kpower[l]*game.kdist[l] <= whammo) \r
-                               deadkl(game.kx[l],game.ky[l], game.quad[game.kx[l]][game.ky[l]], game.kx[l], game.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
-       prout("It is stardate %.1f.", game.state.date);\r
-       prout("");\r
-       switch (ifin) {\r
-               case FWON: // Game has been won\r
-                       if (game.state.nromrem != 0)\r
-                               prout("The remaining %d Romulans surrender to Starfleet Command.",\r
-                                          game.state.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.*game.state.starkl + casual + 10.*game.state.nplankl +\r
-                                               45.*nhelp+100.*game.state.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 (game.state.date-indate < 5.0 ||\r
-                                       // killsPerDate >= RateMax\r
-                                       (game.state.killk+game.state.killc+game.state.nsckill)/(game.state.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 (game.state.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 (game.state.remkl != 0) {\r
-               double goodies = game.state.remres/inresor;\r
-               double baddies = (game.state.remkl + 2.0*game.state.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 = game.state.date - indate;\r
-       int ithperd, iwon, klship;\r
-\r
-       pause_game(0);\r
-\r
-       iskill = skill;\r
-       if ((timused == 0 || game.state.remkl != 0) && timused < 5.0) timused = 5.0;\r
-       perdate = (game.state.killc + game.state.killk + game.state.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) game.state.nromrem = 0; // None captured if no win\r
-       iscore = 10*game.state.killk + 50*game.state.killc + ithperd + iwon\r
-                        - 100*game.state.basekl - 100*klship - 45*nhelp -5*game.state.starkl - casual\r
-                        + 20*game.state.nromkl + 200*game.state.nsckill - 10*game.state.nplankl + game.state.nromrem;\r
-       if (alive == 0) iscore -= 200;\r
-       skip(2);\r
-       prout("Your score --");\r
-       if (game.state.nromkl)\r
-               prout("%6d Romulans destroyed                 %5d",\r
-                          game.state.nromkl,20*game.state.nromkl);\r
-       if (game.state.nromrem)\r
-               prout("%6d Romulans captured                  %5d",\r
-                          game.state.nromrem, game.state.nromrem);\r
-       if (game.state.killk)\r
-               prout("%6d ordinary Klingons destroyed        %5d",\r
-                          game.state.killk, 10*game.state.killk);\r
-       if (game.state.killc)\r
-               prout("%6d Klingon commanders destroyed       %5d",\r
-                          game.state.killc, 50*game.state.killc);\r
-       if (game.state.nsckill)\r
-               prout("%6d Super-Commander destroyed          %5d",\r
-                          game.state.nsckill, 200*game.state.nsckill);\r
-       if (ithperd)\r
-               prout("%.2f Klingons per stardate              %5d",\r
-                          perdate, ithperd);\r
-       if (game.state.starkl)\r
-               prout("%6d stars destroyed by your action     %5d",\r
-                          game.state.starkl, -5*game.state.starkl);\r
-       if (game.state.nplankl)\r
-               prout("%6d planets destroyed by your action   %5d",\r
-                          game.state.nplankl, -10*game.state.nplankl);\r
-       if (game.state.basekl)\r
-               prout("%6d bases destroyed by your action     %5d",\r
-                          game.state.basekl, -100*game.state.basekl);\r
-       if (nhelp)\r
-               prout("%6d calls for help from starbase       %5d",\r
-                          nhelp, -45*nhelp);\r
-       if (casual)\r
-               prout("%6d casualties incurred                %5d",\r
-                          casual, -casual);\r
-       if (klship)\r
-               prout("%6d ship(s) lost or destroyed          %5d",\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
-               prout("           %5d", iwon);\r
-       }\r
-       skip(2);\r
-       prout("TOTAL SCORE                               %5d", 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
-               proutn("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
-                       prout("Invalid name.");\r
-               }\r
-       }\r
-\r
-       proutn("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
+#include "sst.h"
+#include <string.h>
+#include <time.h>
+
+void dstrct() {
+       /* Finish with a BANG! */
+       chew();
+       if (game.damage[DCOMPTR] != 0.0) {
+               prout("Computer damaged; cannot execute destruct sequence.");
+               return;
+       }
+       skip(1);
+       prouts("---WORKING---"); skip(1);
+       prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED");
+       prouts("   10"); skip(1);
+       prouts("       9"); skip(1);
+       prouts("          8"); skip(1);
+       prouts("             7"); skip(1);
+       prouts("                6"); skip(1);
+       prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");
+       prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");
+       prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");
+       scan();
+       chew();
+       if (strcmp(game.passwd, citem) != 0) {
+               prouts("PASSWORD-REJECTED;"); skip(1);
+               prout("CONTINUITY-EFFECTED");
+               skip(1);
+               return;
+       }
+       prouts("PASSWORD-ACCEPTED"); skip(1);
+       prouts("                   5"); skip(1);
+       prouts("                      4"); skip(1);
+       prouts("                         3"); skip(1);
+       prouts("                            2"); skip(1);
+       prouts("                              1"); skip(1);
+       if (Rand() < 0.15) {
+               prouts("GOODBYE-CRUEL-WORLD");
+               skip(1);
+       }
+       skip(2);
+       kaboom();
+}
+
+void kaboom(void) {
+       stars();
+       if (ship==IHE) prouts("***");
+       prouts("********* Entropy of ");
+       crmshp();
+       prouts(" maximized *********");
+       skip(1);
+       stars();
+       skip(1);
+       if (nenhere != 0) {
+               double whammo = 25.0 * energy;
+               int l=1;
+               while (l <= nenhere) {
+                       if (game.kpower[l]*game.kdist[l] <= whammo) 
+                               deadkl(game.kx[l],game.ky[l], game.quad[game.kx[l]][game.ky[l]], game.kx[l], game.ky[l]);
+                       l++;
+               }
+       }
+       finish(FDILITHIUM);
+}
+                               
+
+void finish(FINTYPE ifin) {
+       int igotit = 0;
+       alldone = 1;
+       skip(3);
+       prout("It is stardate %.1f.", game.state.date);
+       prout("");
+       switch (ifin) {
+               case FWON: // Game has been won
+                       if (game.state.nromrem != 0)
+                               prout("The remaining %d Romulans surrender to Starfleet Command.",
+                                          game.state.nromrem);
+                       
+                       prout("You have smashed the Klingon invasion fleet and saved");
+                       prout("the Federation.");
+                       gamewon=1;
+                       if (alive) {
+                               double badpt;
+                               badpt = 5.*game.state.starkl + casual + 10.*game.state.nplankl +
+                                               45.*nhelp+100.*game.state.basekl;
+                               if (ship == IHF) badpt += 100.0;
+                               else if (ship == 0) badpt += 200.0;
+                               if (badpt < 100.0) badpt = 0.0; // Close enough!
+                               if (game.state.date-indate < 5.0 ||
+                                       // killsPerDate >= RateMax
+                                       (game.state.killk+game.state.killc+game.state.nsckill)/(game.state.date-indate) >=
+                                       0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {
+                                       skip(1);
+                                       prout("In fact, you have done so well that Starfleet Command");
+                                       switch (skill) {
+                                               case 1:
+                                                       prout("promotes you one step in rank from \"Novice\" to \"Fair\".");
+                                                       break;
+                                               case 2:
+                                                       prout("promotes you one step in rank from \"Fair\" to \"Good\".");
+                                                       break;
+                                               case 3:
+                                                       prout("promotes you one step in rank from \"Good\" to \"Expert\".");
+                                                       break;
+                                               case 4:
+                                                       prout("promotes you to Commodore Emeritus.");
+                                                       skip(1);
+                                                       prout("Now that you think you're really good, try playing");
+                                                       prout("the \"Emeritus\" game. It will splatter your ego.");
+                                                       break;
+                                               case 5:
+                                                       skip(1);
+                                                       prout("Computer-  ERROR-ERROR-ERROR-ERROR");
+                                                       skip(1);
+                                                       prout("  YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");
+                                                       prout("  THIS-PROGRAM-MUST-SURVIVE");
+                                                       prout("  THIS-PROGRAM-MUST?- MUST ? - SUR? ? -?  VI");
+                                                       skip(1);
+                                                       prout("Now you can retire and write your own Star Trek game!");
+                                                       skip(1);
+                                                       break;
+                                       }
+                                       if (skill > 3) {
+                                               if (thawed
+#ifdef DEBUG
+                                                       && !idebug
+#endif
+                                                       )
+                                                       prout("You cannot get a citation, so...");
+                                               else {
+                                                       prout("Do you want your Commodore Emeritus Citation printed?");
+                                                       proutn("(You need a 132 column printer.)");
+                                                       chew();
+                                                       if (ja()) {
+                                                               igotit = 1;
+                                                       }
+                                               }
+                                       }
+                               }
+                               // Only grant long life if alive (original didn't!)
+                               skip(1);
+                               prout("LIVE LONG AND PROSPER.");
+                       }
+                       score();
+                       if (igotit != 0) plaque();
+                       return;
+               case FDEPLETE: // Federation Resources Depleted
+                       prout("Your time has run out and the Federation has been");
+                       prout("conquered.  Your starship is now Klingon property,");
+                       prout("and you are put on trial as a war criminal.  On the");
+                       proutn("basis of your record, you are ");
+                       if (game.state.remkl*3.0 > inkling) {
+                               prout("aquitted.");
+                               skip(1);
+                               prout("LIVE LONG AND PROSPER.");
+                       }
+                       else {
+                               prout("found guilty and");
+                               prout("sentenced to death by slow torture.");
+                               alive = 0;
+                       }
+                       score();
+                       return;
+               case FLIFESUP:
+                       prout("Your life support reserves have run out, and");
+                       prout("you die of thirst, starvation, and asphyxiation.");
+                       prout("Your starship is a derelict in space.");
+                       break;
+               case FNRG:
+                       prout("Your energy supply is exhausted.");
+                       skip(1);
+                       prout("Your starship is a derelict in space.");
+                       break;
+               case FBATTLE:
+                       proutn("The ");
+                       crmshp();
+                       prout("has been destroyed in battle.");
+                       skip(1);
+                       prout("Dulce et decorum est pro patria mori.");
+                       break;
+               case FNEG3:
+                       prout("You have made three attempts to cross the negative energy");
+                       prout("barrier which surrounds the galaxy.");
+                       skip(1);
+                       prout("Your navigation is abominable.");
+                       score();
+                       return;
+               case FNOVA:
+                       prout("Your starship has been destroyed by a nova.");
+                       prout("That was a great shot.");
+                       skip(1);
+                       break;
+               case FSNOVAED:
+                       proutn("The ");
+                       crmshp();
+                       prout(" has been fried by a supernova.");
+                       prout("...Not even cinders remain...");
+                       break;
+               case FABANDN:
+                       prout("You have been captured by the Klingons. If you still");
+                       prout("had a starbase to be returned to, you would have been");
+                       prout("repatriated and given another chance. Since you have");
+                       prout("no starbases, you will be mercilessly tortured to death.");
+                       break;
+               case FDILITHIUM:
+                       prout("Your starship is now an expanding cloud of subatomic particles");
+                       break;
+               case FMATERIALIZE:
+                       prout("Starbase was unable to re-materialize your starship.");
+                       prout("Sic transit gloria muntdi");
+                       break;
+               case FPHASER:
+                       proutn("The ");
+                       crmshp();
+                       prout(" has been cremated by its own phasers.");
+                       break;
+               case FLOST:
+                       prout("You and your landing party have been");
+                       prout("converted to energy, disipating through space.");
+                       break;
+               case FMINING:
+                       prout("You are left with your landing party on");
+                       prout("a wild jungle planet inhabited by primitive cannibals.");
+                       skip(1);
+                       prout("They are very fond of \"Captain Kirk\" soup.");
+                       skip(1);
+                       proutn("Without your leadership, the ");
+                       crmshp();
+                       prout(" is destroyed.");
+                       break;
+               case FDPLANET:
+                       prout("You and your mining party perish.");
+                       skip(1);
+                       prout("That was a great shot.");
+                       skip(1);
+                       break;
+               case FSSC:
+                       prout("The Galileo is instantly annihilated by the supernova.");
+                       // no break;
+               case FPNOVA:
+                       prout("You and your mining party are atomized.");
+                       skip(1);
+                       proutn("Mr. Spock takes command of the ");
+                       crmshp();
+                       prout(" and");
+                       prout("joins the Romulans, reigning terror on the Federation.");
+                       break;
+               case FSTRACTOR:
+                       prout("The shuttle craft Galileo is also caught,");
+                       prout("and breaks up under the strain.");
+                       skip(1);
+                       prout("Your debris is scattered for millions of miles.");
+                       proutn("Without your leadership, the ");
+                       crmshp();
+                       prout(" is destroyed.");
+                       break;
+               case FDRAY:
+                       prout("The mutants attack and kill Spock.");
+                       prout("Your ship is captured by Klingons, and");
+                       prout("your crew is put on display in a Klingon zoo.");
+                       break;
+               case FTRIBBLE:
+                       prout("Tribbles consume all remaining water,");
+                       prout("food, and oxygen on your ship.");
+                       skip(1);
+                       prout("You die of thirst, starvation, and asphyxiation.");
+                       prout("Your starship is a derelict in space.");
+                       break;
+               case FHOLE:
+                       prout("Your ship is drawn to the center of the black hole.");
+                       prout("You are crushed into extremely dense matter.");
+                       break;
+       }
+       if (ship==IHF) ship= 0;
+       else if (ship == IHE) ship = IHF;
+       alive = 0;
+       if (game.state.remkl != 0) {
+               double goodies = game.state.remres/inresor;
+               double baddies = (game.state.remkl + 2.0*game.state.remcom)/(inkling+2.0*incom);
+               if (goodies/baddies >= 1.0+0.5*Rand()) {
+                       prout("As a result of your actions, a treaty with the Klingon");
+                       prout("Empire has been signed. The terms of the treaty are");
+                       if (goodies/baddies >= 3.0+Rand()) {
+                               prout("favorable to the Federation.");
+                               skip(1);
+                               prout("Congratulations!");
+                       }
+                       else
+                               prout("highly unfavorable to the Federation.");
+               }
+               else
+                       prout("The Federation will be destroyed.");
+       }
+       else {
+               prout("Since you took the last Klingon with you, you are a");
+               prout("martyr and a hero. Someday maybe they'll erect a");
+               prout("statue in your memory. Rest in peace, and try not");
+               prout("to think about pigeons.");
+               gamewon = 1;
+       }
+       score();
+}
+
+void score(void) {
+       double timused = game.state.date - indate;
+       int ithperd, iwon, klship;
+
+       pause_game(0);
+
+       iskill = skill;
+       if ((timused == 0 || game.state.remkl != 0) && timused < 5.0) timused = 5.0;
+       perdate = (game.state.killc + game.state.killk + game.state.nsckill)/timused;
+       ithperd = 500*perdate + 0.5;
+       iwon = 0;
+       if (gamewon) iwon = 100*skill;
+       if (ship == IHE) klship = 0;
+       else if (ship == IHF) klship = 1;
+       else klship = 2;
+       if (gamewon == 0) game.state.nromrem = 0; // None captured if no win
+       iscore = 10*game.state.killk + 50*game.state.killc + ithperd + iwon
+                        - 100*game.state.basekl - 100*klship - 45*nhelp -5*game.state.starkl - casual
+                        + 20*game.state.nromkl + 200*game.state.nsckill - 10*game.state.nplankl + game.state.nromrem;
+       if (alive == 0) iscore -= 200;
+       skip(2);
+       prout("Your score --");
+       if (game.state.nromkl)
+               prout("%6d Romulans destroyed                 %5d",
+                          game.state.nromkl,20*game.state.nromkl);
+       if (game.state.nromrem)
+               prout("%6d Romulans captured                  %5d",
+                          game.state.nromrem, game.state.nromrem);
+       if (game.state.killk)
+               prout("%6d ordinary Klingons destroyed        %5d",
+                          game.state.killk, 10*game.state.killk);
+       if (game.state.killc)
+               prout("%6d Klingon commanders destroyed       %5d",
+                          game.state.killc, 50*game.state.killc);
+       if (game.state.nsckill)
+               prout("%6d Super-Commander destroyed          %5d",
+                          game.state.nsckill, 200*game.state.nsckill);
+       if (ithperd)
+               prout("%.2f Klingons per stardate              %5d",
+                          perdate, ithperd);
+       if (game.state.starkl)
+               prout("%6d stars destroyed by your action     %5d",
+                          game.state.starkl, -5*game.state.starkl);
+       if (game.state.nplankl)
+               prout("%6d planets destroyed by your action   %5d",
+                          game.state.nplankl, -10*game.state.nplankl);
+       if (game.state.basekl)
+               prout("%6d bases destroyed by your action     %5d",
+                          game.state.basekl, -100*game.state.basekl);
+       if (nhelp)
+               prout("%6d calls for help from starbase       %5d",
+                          nhelp, -45*nhelp);
+       if (casual)
+               prout("%6d casualties incurred                %5d",
+                          casual, -casual);
+       if (klship)
+               prout("%6d ship(s) lost or destroyed          %5d",
+                          klship, -100*klship);
+       if (alive==0)
+               prout("Penalty for getting yourself killed        -200");
+       if (gamewon) {
+               skip(1);
+               proutn("Bonus for winning ");
+               switch (skill) {
+                       case 1: proutn("Novice game  "); break;
+                       case 2: proutn("Fair game    "); break;
+                       case 3: proutn("Good game    "); break;
+                       case 4: proutn("Expert game  "); break;
+                       case 5: proutn("Emeritus game"); break;
+               }
+               prout("           %5d", iwon);
+       }
+       skip(2);
+       prout("TOTAL SCORE                               %5d", iscore);
+}
+
+void plaque(void) {
+       FILE *fp=NULL;
+       time_t t;
+       char *timestring;
+       int nskip;
+       char winner[128];
+
+       skip(2);
+       
+       while (fp == NULL) {
+               proutn("File or device name for your plaque:");
+               fgets(winner, 128, stdin);
+               winner[strlen(winner)-1] = '\0';
+               fp = fopen(winner, "w");
+               if (fp==NULL) {
+                       prout("Invalid name.");
+               }
+       }
+
+       proutn("Enter name to go on plaque (up to 30 characters):");
+       fgets(winner, 128, stdin);
+       winner[strlen(winner)-1] = '\0';
+       winner[30] = '\0';
+       nskip = 64 - strlen(winner)/2;
+
+       fprintf(fp,"\n\n\n\n");
+       /* --------DRAW ENTERPRISE PICTURE. */
+       fprintf(fp, "                                                                EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );
+       fprintf(fp, "                                      EEE                      E  : :                                         :  E\n" );
+       fprintf(fp, "                                    EE   EEE                   E  : :                   NCC-1701              :  E\n");
+       fprintf(fp, "                    EEEEEEEEEEEEEEEE        EEEEEEEEEEEEEEE    E  : :                                         : E\n");
+       fprintf(fp, "                     E                                     E    EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");
+       fprintf(fp, "                      EEEEEEEEE               EEEEEEEEEEEEE                 E  E\n");
+       fprintf(fp, "                               EEEEEEE   EEEEE    E          E              E  E\n");
+       fprintf(fp, "                                      EEE           E          E            E  E\n");
+       fprintf(fp, "                                                       E         E          E  E\n");
+       fprintf(fp, "                                                         EEEEEEEEEEEEE      E  E\n");
+       fprintf(fp, "                                                      EEE :           EEEEEEE  EEEEEEEE\n");
+       fprintf(fp, "                                                    :E    :                 EEEE       E\n");
+       fprintf(fp, "                                                   .-E   -:-----                       E\n");
+       fprintf(fp, "                                                    :E    :                            E\n");
+       fprintf(fp, "                                                      EE  :                    EEEEEEEE\n");
+       fprintf(fp, "                                                       EEEEEEEEEEEEEEEEEEEEEEE\n");
+       fprintf(fp, "\n\n\n");
+       fprintf(fp, "                                                       U. S. S. ENTERPRISE\n");
+       fprintf(fp, "\n\n\n\n");
+       fprintf(fp, "                                  For demonstrating outstanding ability as a starship captain\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "                                                Starfleet Command bestows to you\n");
+       fprintf(fp, "\n");
+       fprintf(fp,"%*s%s\n\n", nskip, "", winner);
+       fprintf(fp, "                                                           the rank of\n\n");
+       fprintf(fp, "                                                       \"Commodore Emeritus\"\n\n");
+       fprintf(fp, "                                                          ");
+       switch (iskill) {
+               case 4: fprintf(fp," Expert level\n\n"); break;
+               case 5: fprintf(fp,"Emeritus level\n\n"); break;
+               default: fprintf(fp," Cheat level\n\n"); break;
+       }
+       t = time(NULL);
+       timestring = ctime(&t);
+       fprintf(fp, "                                                 This day of %.6s %.4s, %.8s\n\n",
+                       timestring+4, timestring+20, timestring+11);
+       fprintf(fp,"                                                        Your score:  %d\n\n", iscore);
+       fprintf(fp,"                                                    Klingons per stardate:  %.2f\n", perdate);
+       fclose(fp);
+}
index b0e68cded51fbcd3ff6792e8a38ed02367864161..05c3d3ab95761cf83e570d13d7220b3d4aeed39c 100644 (file)
--- a/moving.c
+++ b/moving.c
-#include <unistd.h>\r
-#include "sst.h"\r
-\r
-static void getcd(int, int);\r
-\r
-void imove(void) {\r
-       double angle, deltax, deltay, bigger, x, y,\r
-        finald, finalx, finaly, stopegy, probf;\r
-        int trbeam = 0, n, l, ix=0, iy=0, kink, kinks, iquad;\r
-\r
-       if (inorbit) {\r
-               prout("Helmsman 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 (game.state.date+Time >= game.future[FTBEAM]) {\r
-               trbeam = 1;\r
-               condit = IHRED;\r
-               dist = dist*(game.future[FTBEAM]-game.state.date)/Time + 0.1;\r
-               Time = game.future[FTBEAM] - game.state.date + 1e-5;\r
-       }\r
-       /* Move within the quadrant */\r
-       game.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-game.kx[l])*(double)(ix-game.kx[l]) +\r
-                                                                         (iy-game.ky[l])*(double)(iy-game.ky[l]));\r
-                                               game.kavgd[l] = 0.5 * (finald+game.kdist[l]);\r
-                                       }\r
-                                       if (game.state.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("\n\rEntering %s.",\r
-                                     cramlc(quadrant, quadx, quady));\r
-                               game.quad[sectx][secty] = ship;\r
-                               newqad(0);\r
-                                if (skill>1) attack(0);\r
-                               return;\r
-                       }\r
-                       iquad = game.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 Tholian */\r
-                                       case IHK: /* Ram enemy ship */\r
-                                       case IHC:\r
-                                       case IHS:\r
-                                       case IHR:\r
-                                        case IHQUEST:\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
-                                               prout(cramlc(sector, ix, iy));\r
-                                               /*\r
-                                                * Getting pulled into a black \r
-                                                * hole was certain death in\r
-                                                * Almy's original.  Stas \r
-                                                * Sergeev added a possibility\r
-                                                * that you'll get timewarped\r
-                                                * instead.\r
-                                                */\r
-                                                n=0;\r
-                                                for (l=1;l<=NDEVICES+1;l++)\r
-                                                    if (game.damage[l]>0) n++;\r
-                                                probf=pow(1.4,(energy+shield)/5000.0-1.0)*\r
-                                                       pow(1.3,1.0/(n+1)-1.0);\r
-                                                if (Rand()>probf) \r
-                                                   timwrp();\r
-                                                else \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
-                                               proutn(cramlc(sector, ix,iy));\r
-                                               prout(";");\r
-                                               proutn("Emergency stop required ");\r
-                                               prout("%2d units of energy.", (int)stopegy);\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
-       game.quad[sectx][secty] = ship;\r
-       if (nenhere) {\r
-               for (l = 1; l <= nenhere; l++) {\r
-                       finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +\r
-                                                 (iy-game.ky[l])*(double)(iy-game.ky[l]));\r
-                       game.kavgd[l] = 0.5 * (finald+game.kdist[l]);\r
-                       game.kdist[l] = finald;\r
-               }\r
-               sortkl();\r
-               if (game.state.galaxy[quadx][quady] != 1000 && iattak == 0)\r
-                       attack(0);\r
-               for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];\r
-       }\r
-       newcnd();\r
-       iattak = 0;\r
-#ifdef SERGEEV\r
-       drawmaps(0);\r
-#endif /* SERGEEV */\r
-       return;\r
-}\r
-\r
-void dock(int l) {\r
-       chew();\r
-        if (condit == IHDOCKED && l) {\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
-        if (l) prout("Docked.");\r
-        ididit=1;\r
-       if (energy < inenrg) energy = inenrg;\r
-       shield = inshld;\r
-       torps = intorps;\r
-       lsupres = inlsr;\r
-       if (stdamtim != 1e30 &&\r
-               (game.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(0);\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=0;\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 (game.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 %s.\"",\r
-                                               cramlc(sector, irows, icols));\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 (game.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 %d", \r
-                              (int)(0.01 * (energy-20.0)-0.05));\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 >= game.state.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
-               proutn("we dare spend the time?\" ");\r
-               if (ja() == 0) return;\r
-       }\r
-       /* Activate impulse engines and pay the cost */\r
-       imove();\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 (game.damage[DWARPEN] > 10.0) {\r
-                       chew();\r
-                       skip(1);\r
-                       prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
-                       return;\r
-               }\r
-               if (game.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 %d", iwarp);\r
-                                       if (shldup) {\r
-                                               prout(",");\r
-                                               prout("if you'll lower the shields.");\r
-                                       }\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*game.state.remtime) {\r
-                       skip(1);\r
-                       prout("First Officer Spock- \"Captain, I compute that such");\r
-                       proutn("  a trip would require approximately %2.0f",\r
-                               100.0*Time/game.state.remtime);\r
-                       prout(" percent of our");\r
-                        proutn("  remaining time.  Are you sure this is wise?\" ");\r
-                        if (ja() == 0) { ididit = 0; Time=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 (game.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
-       imove();\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
-               game.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 (game.damage[DWARPEN] > 10.0) {\r
-               prout("Warp engines inoperative.");\r
-               return;\r
-       }\r
-       if (game.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 %d, Captain.\"", \r
-                       (int)warpfac);\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 (game.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
-               game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+1000:1;\r
-\r
-               /* Try to use warp engines */\r
-               if (game.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
-               prout("Warp factor set to %d", (int)warpfac);\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 (game.state.galaxy[quadx][quady] == 1000);\r
-       if (game.state.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 (game.state.snap && Rand() < 0.5) {\r
-               /* Go back in time */\r
-               prout("You are traveling backwards in time %d stardates.",\r
-                     (int)(game.state.date-game.snapsht.date));\r
-               game.state = game.snapsht;\r
-               game.state.snap = 0;\r
-               if (game.state.remcom) {\r
-                       game.future[FTBEAM] = game.state.date + expran(intime/game.state.remcom);\r
-                       game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
-               }\r
-               game.future[FSNOVA] = game.state.date + expran(0.5*intime);\r
-               game.future[FSNAP] = game.state.date +expran(0.25*game.state.remtime); /* next snapshot will\r
-                                                                                                          be sooner */\r
-               if (game.state.nscrem) game.future[FSCMOVE] = 0.2777;\r
-               isatb = 0;\r
-               game.future[FCDBAS] = game.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 = 0; l < inplan; l++) {\r
-                       if (game.state.plnets[l].known == shuttle_down) {\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 && game.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 (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) {\r
-                       for (l = 1; l <= 8; l++)\r
-                               for (ll = 1; ll <= 8; ll++)\r
-                                       if (game.starch[l][ll] > 1)\r
-                                               game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+1000 :1;\r
-                       prout("Spock has reconstructed a correct star chart from memory");\r
-                       if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date;\r
-               }\r
-       }\r
-       else {\r
-               /* Go forward in time */\r
-               Time = -0.5*intime*log(Rand());\r
-               prout("You are traveling forward in time %d stardates.", (int)Time);\r
-               /* cheat to make sure no tractor beams occur during time warp */\r
-               game.future[FTBEAM] += Time;\r
-               game.damage[DRADIO] += Time;\r
-       }\r
-       newqad(0);\r
-#ifdef SERGEEV\r
-        events();\r
-#endif /* SERGEEV */\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 (game.damage[DDSP] != 0.0) {\r
-               chew();\r
-               skip(1);\r
-               prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");\r
-               return;\r
-       }\r
-       if (game.future[FDSPROB] != 1e30) {\r
-               chew();\r
-               skip(1);\r
-               if (game.damage[DRADIO] != 0 && condit != IHDOCKED) {\r
-                       prout("Spock-  \"Records show the previous probe has not yet");\r
-                       prout("   reached its 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
-               prout(nprobes==1 ? "%d probe left." : "%d probes left.", nprobes);\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
-       game.future[FDSPROB] = game.state.date + 0.01; // Time to move one sector\r
-       prout("Ensign Chekov-  \"The deep space probe is launched, Captain.\"");\r
-       ididit = 1;\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 = 0, l, ix, iy;\r
-#ifdef SERGEEV\r
-       int pox, posy;\r
-#endif /* SERGEEV */\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 (game.damage[DRADIO] != 0) {\r
-               prout("Subspace radio damaged.");\r
-               return;\r
-       }\r
-       if (game.state.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 <= game.state.rembase; l++) {\r
-                       xdist=10.0*sqrt(square(game.state.baseqx[l]-quadx)+square(game.state.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 = game.state.baseqx[line];\r
-               quady = game.state.baseqy[line];\r
-               newqad(1);\r
-       }\r
-       /* dematerialize starship */\r
-       game.quad[sectx][secty]=IHDOT;\r
-       proutn("Starbase in %s responds--", cramlc(quadrant, quadx, quady));\r
-       proutn("");\r
-       crmshp();\r
-       prout(" dematerializes.");\r
-#ifdef SERGEEV\r
-        sectx=0;\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 && game.quad[ix][iy]==IHDOT) {\r
-                        /* found one -- finish up */\r
-                        sectx=ix;\r
-                        secty=iy;\r
-                        game.quad[ix][iy]=IHMATER0;\r
-                        break;\r
-                }\r
-        }\r
-        if (sectx==0){\r
-           prout("You have been lost in space...");\r
-           finish(FMATERIALIZE);\r
-           return;\r
-        }\r
-#endif /* SERGEEV */\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 && game.quad[ix][iy]==IHDOT) {\r
-                       /* found one -- finish up */\r
-                       prout("succeeds.");\r
-                       sectx=ix;\r
-                       secty=iy;\r
-                       game.quad[ix][iy]=ship;\r
-                       dock(0);\r
-                       skip(1);\r
-                       prout("Lt. Uhura-  \"Captain, we made it!\"");\r
-                       return;\r
-               }\r
-       }\r
-       finish(FMATERIALIZE);\r
-       return;\r
-}\r
+#include <unistd.h>
+#include "sst.h"
+
+static void getcd(int, int);
+
+void imove(void) {
+       double angle, deltax, deltay, bigger, x, y,
+        finald, finalx, finaly, stopegy, probf;
+        int trbeam = 0, n, l, ix=0, iy=0, kink, kinks, iquad;
+
+       if (inorbit) {
+               prout("Helmsman Sulu- \"Leaving standard orbit.\"");
+               inorbit = 0;
+       }
+
+       angle = ((15.0 - direc) * 0.5235988);
+       deltax = -sin(angle);
+       deltay = cos(angle);
+       if (fabs(deltax) > fabs(deltay))
+               bigger = fabs(deltax);
+       else
+               bigger = fabs(deltay);
+               
+       deltay /= bigger;
+       deltax /= bigger;
+
+       /* If tractor beam is to occur, don't move full distance */
+       if (game.state.date+Time >= game.future[FTBEAM]) {
+               trbeam = 1;
+               condit = IHRED;
+               dist = dist*(game.future[FTBEAM]-game.state.date)/Time + 0.1;
+               Time = game.future[FTBEAM] - game.state.date + 1e-5;
+       }
+       /* Move within the quadrant */
+       game.quad[sectx][secty] = IHDOT;
+       x = sectx;
+       y = secty;
+       n = 10.0*dist*bigger+0.5;
+
+       if (n > 0) {
+               for (l = 1; l <= n; l++) {
+                       ix = (x += deltax) + 0.5;
+                       iy = (y += deltay) + 0.5;
+                       if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {
+                               /* Leaving quadrant -- allow final enemy attack */
+                               /* Don't do it if being pushed by Nova */
+                               if (nenhere != 0 && iattak != 2) {
+                                       newcnd();
+                                       for (l = 1; l <= nenhere; l++) {
+                                               finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +
+                                                                         (iy-game.ky[l])*(double)(iy-game.ky[l]));
+                                               game.kavgd[l] = 0.5 * (finald+game.kdist[l]);
+                                       }
+                                       if (game.state.galaxy[quadx][quady] != 1000) attack(0);
+                                       if (alldone) return;
+                               }
+                               /* compute final position -- new quadrant and sector */
+                               x = 10*(quadx-1)+sectx;
+                               y = 10*(quady-1)+secty;
+                               ix = x+10.0*dist*bigger*deltax+0.5;
+                               iy = y+10.0*dist*bigger*deltay+0.5;
+                               /* check for edge of galaxy */
+                               kinks = 0;
+                               do {
+                                       kink = 0;
+                                       if (ix <= 0) {
+                                               ix = -ix + 1;
+                                               kink = 1;
+                                       }
+                                       if (iy <= 0) {
+                                               iy = -iy + 1;
+                                               kink = 1;
+                                       }
+                                       if (ix > 80) {
+                                               ix = 161 - ix;
+                                               kink = 1;
+                                       }
+                                       if (iy > 80) {
+                                               iy = 161 - iy;
+                                               kink = 1;
+                                       }
+                                       if (kink) kinks = 1;
+                               } while (kink);
+
+                               if (kinks) {
+                                       nkinks += 1;
+                                       if (nkinks == 3) {
+                                               /* Three strikes -- you're out! */
+                                               finish(FNEG3);
+                                               return;
+                                       }
+                                       prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"
+                                                "AT THE EDGE OF THE GALAXY.  THE THIRD TIME YOU TRY THIS,\n"
+                                                "YOU WILL BE DESTROYED.\n");
+                               }
+                               /* Compute final position in new quadrant */
+                               if (trbeam) return; /* Don't bother if we are to be beamed */
+                               quadx = (ix+9)/10;
+                               quady = (iy+9)/10;
+                               sectx = ix - 10*(quadx-1);
+                               secty = iy - 10*(quady-1);
+                               proutn("\n\rEntering %s.",
+                                     cramlc(quadrant, quadx, quady));
+                               game.quad[sectx][secty] = ship;
+                               newqad(0);
+                                if (skill>1) attack(0);
+                               return;
+                       }
+                       iquad = game.quad[ix][iy];
+                       if (iquad != IHDOT) {
+                               /* object encountered in flight path */
+                               stopegy = 50.0*dist/Time;
+                               dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +
+                                                         (secty-iy)*(double)(secty-iy));
+                               switch (iquad) {
+                                       case IHT: /* Ram a Tholian */
+                                       case IHK: /* Ram enemy ship */
+                                       case IHC:
+                                       case IHS:
+                                       case IHR:
+                                        case IHQUEST:
+                                               sectx = ix;
+                                               secty = iy;
+                                               ram(0, iquad, sectx, secty);
+                                               finalx = sectx;
+                                               finaly = secty;
+                                               break;
+                                       case IHBLANK:
+                                               skip(1);
+                                               prouts("***RED ALERT!  RED ALERT!");
+                                               skip(1);
+                                               proutn("***");
+                                               crmshp();
+                                               proutn(" pulled into black hole at ");
+                                               prout(cramlc(sector, ix, iy));
+                                               /*
+                                                * Getting pulled into a black 
+                                                * hole was certain death in
+                                                * Almy's original.  Stas 
+                                                * Sergeev added a possibility
+                                                * that you'll get timewarped
+                                                * instead.
+                                                */
+                                                n=0;
+                                                for (l=1;l<=NDEVICES+1;l++)
+                                                    if (game.damage[l]>0) n++;
+                                                probf=pow(1.4,(energy+shield)/5000.0-1.0)*
+                                                       pow(1.3,1.0/(n+1)-1.0);
+                                                if (Rand()>probf) 
+                                                   timwrp();
+                                                else 
+                                                   finish(FHOLE);
+                                               return;
+                                       default:
+                                               /* something else */
+                                               skip(1);
+                                               crmshp();
+                                               if (iquad == IHWEB)
+                                                       proutn(" encounters Tholian web at ");
+                                               else
+                                                       proutn(" blocked by object at ");
+                                               proutn(cramlc(sector, ix,iy));
+                                               prout(";");
+                                               proutn("Emergency stop required ");
+                                               prout("%2d units of energy.", (int)stopegy);
+                                               energy -= stopegy;
+                                               finalx = x-deltax+0.5;
+                                               sectx = finalx;
+                                               finaly = y-deltay+0.5;
+                                               secty = finaly;
+                                               if (energy <= 0) {
+                                                       finish(FNRG);
+                                                       return;
+                                               }
+                                               break;
+                               }
+                               goto label100;  /* sorry! */
+                       }
+               }
+               dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +
+                                               (secty-iy)*(double)(secty-iy));
+               sectx = ix;
+               secty = iy;
+       }
+       finalx = sectx;
+       finaly = secty;
+label100:
+       /* No quadrant change -- compute new avg enemy distances */
+       game.quad[sectx][secty] = ship;
+       if (nenhere) {
+               for (l = 1; l <= nenhere; l++) {
+                       finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +
+                                                 (iy-game.ky[l])*(double)(iy-game.ky[l]));
+                       game.kavgd[l] = 0.5 * (finald+game.kdist[l]);
+                       game.kdist[l] = finald;
+               }
+               sortkl();
+               if (game.state.galaxy[quadx][quady] != 1000 && iattak == 0)
+                       attack(0);
+               for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];
+       }
+       newcnd();
+       iattak = 0;
+#ifdef SERGEEV
+       drawmaps(0);
+#endif /* SERGEEV */
+       return;
+}
+
+void dock(int l) {
+       chew();
+        if (condit == IHDOCKED && l) {
+               prout("Already docked.");
+               return;
+       }
+       if (inorbit) {
+               prout("You must first leave standard orbit.");
+               return;
+       }
+       if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {
+               crmshp();
+               prout(" not adjacent to base.");
+               return;
+       }
+       condit = IHDOCKED;
+        if (l) prout("Docked.");
+        ididit=1;
+       if (energy < inenrg) energy = inenrg;
+       shield = inshld;
+       torps = intorps;
+       lsupres = inlsr;
+       if (stdamtim != 1e30 &&
+               (game.future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {
+               /* get attack report from base */
+               prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");
+               attakreport(0);
+               iseenit = 1;
+       }
+}
+
+static void getcd(int isprobe, int akey) {
+       /* This program originally required input in terms of a (clock)
+          direction and distance. Somewhere in history, it was changed to
+          cartesian coordinates. So we need to convert. I think
+          "manual" input should still be done this way -- it's a real
+          pain if the computer isn't working! Manual mode is still confusing
+          because it involves giving x and y motions, yet the coordinates
+          are always displayed y - x, where +y is downward! */
+
+       
+        int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key=0;
+       double xi, xj, xk, xl;
+       double deltax, deltay;
+       int automatic = -1;
+
+       /* Get course direction and distance. If user types bad values, return
+          with DIREC = -1.0. */
+
+       direc = -1.0;
+       
+       if (landed == 1 && !isprobe) {
+               prout("Dummy! You can't leave standard orbit until you");
+               proutn("are back abourt the ");
+               crmshp();
+               prout(".");
+               chew();
+               return;
+       }
+       while (automatic == -1) {
+               if (game.damage[DCOMPTR]) {
+                       if (isprobe)
+                               prout("Computer damaged; manual navigation only");
+                       else
+                               prout("Computer damaged; manual movement only");
+                       chew();
+                       automatic = 0;
+                       key = IHEOL;
+                       break;
+               }
+               if (isprobe && akey != -1) {
+                       /* For probe launch, use pre-scaned value first time */
+                       key = akey;
+                       akey = -1;
+               }
+               else 
+                       key = scan();
+
+               if (key == IHEOL) {
+                       proutn("Manual or automatic- ");
+                       iprompt = 1;
+                       chew();
+               }
+               else if (key == IHALPHA) {
+                       if (isit("manual")) {
+                               automatic =0;
+                               key = scan();
+                               break;
+                       }
+                       else if (isit("automatic")) {
+                               automatic = 1;
+                               key = scan();
+                               break;
+                       }
+                       else {
+                               huh();
+                               chew();
+                               return;
+                       }
+               }
+               else { /* numeric */
+                       if (isprobe)
+                               prout("(Manual navigation assumed.)");
+                       else
+                               prout("(Manual movement assumed.)");
+                       automatic = 0;
+                       break;
+               }
+       }
+
+       if (automatic) {
+               while (key == IHEOL) {
+                       if (isprobe)
+                               proutn("Target quadrant or quadrant&sector- ");
+                       else
+                               proutn("Destination sector or quadrant&sector- ");
+                       chew();
+                       iprompt = 1;
+                       key = scan();
+               }
+
+               if (key != IHREAL) {
+                       huh();
+                       return;
+               }
+               xi = aaitem;
+               key = scan();
+               if (key != IHREAL){
+                       huh();
+                       return;
+               }
+               xj = aaitem;
+               key = scan();
+               if (key == IHREAL) {
+                       /* both quadrant and sector specified */
+                       xk = aaitem;
+                       key = scan();
+                       if (key != IHREAL) {
+                               huh();
+                               return;
+                       }
+                       xl = aaitem;
+
+                       irowq = xi + 0.5;
+                       icolq = xj + 0.5;
+                       irows = xk + 0.5;
+                       icols = xl + 0.5;
+               }
+               else {
+                       if (isprobe) {
+                               /* only quadrant specified -- go to center of dest quad */
+                               irowq = xi + 0.5;
+                               icolq = xj + 0.5;
+                               irows = icols = 5;
+                       }
+                       else {
+                               irows = xi + 0.5;
+                               icols = xj + 0.5;
+                       }
+                       itemp = 1;
+               }
+               if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 ||
+                       irows<1 || irows > 10 || icols<1 || icols > 10) {
+                               huh();
+                               return;
+                       }
+               skip(1);
+               if (!isprobe) {
+                       if (itemp) {
+                               if (iprompt) {
+                                       proutn("Helmsman Sulu- \"Course locked in for %s.\"",
+                                               cramlc(sector, irows, icols));
+                               }
+                       }
+                       else prout("Ensign Chekov- \"Course laid in, Captain.\"");
+               }
+               deltax = icolq - quady + 0.1*(icols-secty);
+               deltay = quadx - irowq + 0.1*(sectx-irows);
+       }
+       else { /* manual */
+               while (key == IHEOL) {
+                       proutn("X and Y displacements- ");
+                       chew();
+                       iprompt = 1;
+                       key = scan();
+               }
+               itemp = 2;
+               if (key != IHREAL) {
+                       huh();
+                       return;
+               }
+               deltax = aaitem;
+               key = scan();
+               if (key != IHREAL) {
+                       huh();
+                       return;
+               }
+               deltay = aaitem;
+       }
+       /* Check for zero movement */
+       if (deltax == 0 && deltay == 0) {
+               chew();
+               return;
+       }
+       if (itemp == 2 && !isprobe) {
+               skip(1);
+               prout("Helmsman Sulu- \"Aye, Sir.\"");
+       }
+       dist = sqrt(deltax*deltax + deltay*deltay);
+       direc = atan2(deltax, deltay)*1.90985932;
+       if (direc < 0.0) direc += 12.0;
+       chew();
+       return;
+
+}
+               
+
+
+void impuls(void) {
+       double power;
+
+       ididit = 0;
+       if (game.damage[DIMPULS]) {
+               chew();
+               skip(1);
+               prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");
+               return;
+       }
+
+       if (energy > 30.0) {
+               getcd(FALSE, 0);
+               if (direc == -1.0) return;
+               power = 20.0 + 100.0*dist;
+       }
+       else
+               power = 30.0;
+
+       if (power >= energy) {
+               /* Insufficient power for trip */
+               skip(1);
+               prout("First Officer Spock- \"Captain, the impulse engines");
+               prout("require 20.0 units to engage, plus 100.0 units per");
+               if (energy > 30) {
+                       proutn("quadrant.  We can go, therefore, a maximum of %d", 
+                              (int)(0.01 * (energy-20.0)-0.05));
+                       prout(" quadrants.\"");
+               }
+               else {
+                       prout("quadrant.  They are, therefore, useless.\"");
+               }
+               chew();
+               return;
+       }
+       /* Make sure enough time is left for the trip */
+       Time = dist/0.095;
+       if (Time >= game.state.remtime) {
+               prout("First Officer Spock- \"Captain, our speed under impulse");
+               prout("power is only 0.95 sectors per stardate. Are you sure");
+               proutn("we dare spend the time?\" ");
+               if (ja() == 0) return;
+       }
+       /* Activate impulse engines and pay the cost */
+       imove();
+       ididit = 1;
+       if (alldone) return;
+       power = 20.0 + 100.0*dist;
+       energy -= power;
+       Time = dist/0.095;
+       if (energy <= 0) finish(FNRG);
+       return;
+}
+
+
+void warp(int i) {
+       int blooey=0, twarp=0, iwarp;
+       double power;
+
+       if (i!=2) { /* Not WARPX entry */
+               ididit = 0;
+               if (game.damage[DWARPEN] > 10.0) {
+                       chew();
+                       skip(1);
+                       prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");
+                       return;
+               }
+               if (game.damage[DWARPEN] > 0.0 && warpfac > 4.0) {
+                       chew();
+                       skip(1);
+                       prout("Engineer Scott- \"Sorry, Captain. Until this damage");
+                       prout("  is repaired, I can only give you warp 4.\"");
+                       return;
+               }
+                       
+               /* Read in course and distance */
+               getcd(FALSE, 0);
+               if (direc == -1.0) return;
+
+               /* Make sure starship has enough energy for the trip */
+               power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);
+
+
+               if (power >= energy) {
+                       /* Insufficient power for trip */
+                       ididit = 0;
+                       skip(1);
+                       prout("Engineering to bridge--");
+                       if (shldup==0 || 0.5*power > energy) {
+                               iwarp = pow((energy/(dist+0.05)), 0.333333333);
+                               if (iwarp <= 0) {
+                                       prout("We can't do it, Captain. We haven't the energy.");
+                               }
+                               else {
+                                       proutn("We haven't the energy, but we could do it at warp %d", iwarp);
+                                       if (shldup) {
+                                               prout(",");
+                                               prout("if you'll lower the shields.");
+                                       }
+                                       else
+                                               prout(".");
+                               }
+                       }
+                       else
+                               prout("We haven't the energy to go that far with the shields up.");
+                       return;
+               }
+                                               
+               /* Make sure enough time is left for the trip */
+               Time = 10.0*dist/wfacsq;
+               if (Time >= 0.8*game.state.remtime) {
+                       skip(1);
+                       prout("First Officer Spock- \"Captain, I compute that such");
+                       proutn("  a trip would require approximately %2.0f",
+                               100.0*Time/game.state.remtime);
+                       prout(" percent of our");
+                        proutn("  remaining time.  Are you sure this is wise?\" ");
+                        if (ja() == 0) { ididit = 0; Time=0; return;}
+               }
+       }
+       /* Entry WARPX */
+       if (warpfac > 6.0) {
+               /* Decide if engine damage will occur */
+               double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;
+               if (prob > Rand()) {
+                       blooey = 1;
+                       dist = Rand()*dist;
+               }
+               /* Decide if time warp will occur */
+               if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;
+#ifdef DEBUG
+               if (idebug &&warpfac==10 && twarp==0) {
+                       blooey=0;
+                       proutn("Force time warp? ");
+                       if (ja()==1) twarp=1;
+               }
+#endif
+               if (blooey || twarp) {
+                       /* If time warp or engine damage, check path */
+                       /* If it is obstructed, don't do warp or damage */
+                       double angle = ((15.0-direc)*0.5235998);
+                       double deltax = -sin(angle);
+                       double deltay = cos(angle);
+                       double bigger, x, y;
+                       int n, l, ix, iy;
+                       if (fabs(deltax) > fabs(deltay))
+                               bigger = fabs(deltax);
+                       else
+                               bigger = fabs(deltay);
+                       
+                       deltax /= bigger;
+                       deltay /= bigger;
+                       n = 10.0 * dist * bigger +0.5;
+                       x = sectx;
+                       y = secty;
+                       for (l = 1; l <= n; l++) {
+                               x += deltax;
+                               ix = x + 0.5;
+                               if (ix < 1 || ix > 10) break;
+                               y += deltay;
+                               iy = y +0.5;
+                               if (iy < 1 || iy > 10) break;
+                               if (game.quad[ix][iy] != IHDOT) {
+                                       blooey = 0;
+                                       twarp = 0;
+                               }
+                       }
+               }
+       }
+                               
+
+       /* Activate Warp Engines and pay the cost */
+       imove();
+       if (alldone) return;
+       energy -= dist*warpfac*warpfac*warpfac*(shldup+1);
+       if (energy <= 0) finish(FNRG);
+       Time = 10.0*dist/wfacsq;
+       if (twarp) timwrp();
+       if (blooey) {
+               game.damage[DWARPEN] = damfac*(3.0*Rand()+1.0);
+               skip(1);
+               prout("Engineering to bridge--");
+               prout("  Scott here.  The warp engines are damaged.");
+               prout("  We'll have to reduce speed to warp 4.");
+       }
+       ididit = 1;
+       return;
+}
+
+
+
+void setwrp(void) {
+       int key;
+       double oldfac;
+       
+       while ((key=scan()) == IHEOL) {
+               chew();
+               proutn("Warp factor- ");
+       }
+       chew();
+       if (key != IHREAL) {
+               huh();
+               return;
+       }
+       if (game.damage[DWARPEN] > 10.0) {
+               prout("Warp engines inoperative.");
+               return;
+       }
+       if (game.damage[DWARPEN] > 0.0 && aaitem > 4.0) {
+               prout("Engineer Scott- \"I'm doing my best, Captain,\n"
+                         "  but right now we can only go warp 4.\"");
+               return;
+       }
+       if (aaitem > 10.0) {
+               prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");
+               return;
+       }
+       if (aaitem < 1.0) {
+               prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");
+               return;
+       }
+       oldfac = warpfac;
+       warpfac = aaitem;
+       wfacsq=warpfac*warpfac;
+       if (warpfac <= oldfac || warpfac <= 6.0) {
+               proutn("Helmsman Sulu- \"Warp factor %d, Captain.\"", 
+                       (int)warpfac);
+               return;
+       }
+       if (warpfac < 8.00) {
+               prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");
+               return;
+       }
+       if (warpfac == 10.0) {
+               prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");
+               return;
+       }
+       prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");
+       return;
+}
+
+void atover(int igrab) {
+       double power, distreq;
+
+       chew();
+       /* is captain on planet? */
+       if (landed==1) {
+               if (game.damage[DTRANSP]) {
+                       finish(FPNOVA);
+                       return;
+               }
+               prout("Scotty rushes to the transporter controls.");
+               if (shldup) {
+                       prout("But with the shields up it's hopeless.");
+                       finish(FPNOVA);
+               }
+               prouts("His desperate attempt to rescue you . . .");
+               if (Rand() <= 0.5) {
+                       prout("fails.");
+                       finish(FPNOVA);
+                       return;
+               }
+               prout("SUCCEEDS!");
+               if (imine) {
+                       imine = 0;
+                       proutn("The crystals mined were ");
+                       if (Rand() <= 0.25) {
+                               prout("lost.");
+                       }
+                       else {
+                               prout("saved.");
+                               icrystl = 1;
+                       }
+               }
+       }
+       if (igrab) return;
+
+       /* Check to see if captain in shuttle craft */
+       if (icraft) finish(FSTRACTOR);
+       if (alldone) return;
+
+       /* Inform captain of attempt to reach safety */
+       skip(1);
+       do {
+               if (justin) {
+                       prouts("***RED ALERT!  READ ALERT!");
+                       skip(1);
+                       proutn("The ");
+                       crmshp();
+                       prout(" has stopped in a quadrant containing");
+                       prouts("   a supernova.");
+                       skip(2);
+               }
+               proutn("***Emergency automatic override attempts to hurl ");
+               crmshp();
+               skip(1);
+               prout("safely out of quadrant.");
+               game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+1000:1;
+
+               /* Try to use warp engines */
+               if (game.damage[DWARPEN]) {
+                       skip(1);
+                       prout("Warp engines damaged.");
+                       finish(FSNOVAED);
+                       return;
+               }
+               warpfac = 6.0+2.0*Rand();
+               wfacsq = warpfac * warpfac;
+               prout("Warp factor set to %d", (int)warpfac);
+               power = 0.75*energy;
+               dist = power/(warpfac*warpfac*warpfac*(shldup+1));
+               distreq = 1.4142+Rand();
+               if (distreq < dist) dist = distreq;
+               Time = 10.0*dist/wfacsq;
+               direc = 12.0*Rand();    /* How dumb! */
+               justin = 0;
+               inorbit = 0;
+               warp(2);
+               if (justin == 0) {
+                       /* This is bad news, we didn't leave quadrant. */
+                       if (alldone) return;
+                       skip(1);
+                       prout("Insufficient energy to leave quadrant.");
+                       finish(FSNOVAED);
+                       return;
+               }
+               /* Repeat if another snova */
+       } while (game.state.galaxy[quadx][quady] == 1000);
+       if (game.state.remkl==0) finish(FWON); /* Snova killed remaining enemy. */
+}
+
+void timwrp() {
+       int l, ll, gotit;
+       prout("***TIME WARP ENTERED.");
+       if (game.state.snap && Rand() < 0.5) {
+               /* Go back in time */
+               prout("You are traveling backwards in time %d stardates.",
+                     (int)(game.state.date-game.snapsht.date));
+               game.state = game.snapsht;
+               game.state.snap = 0;
+               if (game.state.remcom) {
+                       game.future[FTBEAM] = game.state.date + expran(intime/game.state.remcom);
+                       game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+               }
+               game.future[FSNOVA] = game.state.date + expran(0.5*intime);
+               game.future[FSNAP] = game.state.date +expran(0.25*game.state.remtime); /* next snapshot will
+                                                                                                          be sooner */
+               if (game.state.nscrem) game.future[FSCMOVE] = 0.2777;
+               isatb = 0;
+               game.future[FCDBAS] = game.future[FSCDBAS] = 1e30;
+               batx = baty = 0;
+
+               /* Make sure Galileo is consistant -- Snapshot may have been taken
+                  when on planet, which would give us two Galileos! */
+               gotit = 0;
+               for (l = 0; l < inplan; l++) {
+                       if (game.state.plnets[l].known == shuttle_down) {
+                               gotit = 1;
+                               if (iscraft==1 && ship==IHE) {
+                                       prout("Checkov-  \"Security reports the Galileo has disappeared, Sir!");
+                                       iscraft = 0;
+                               }
+                       }
+               }
+               /* Likewise, if in the original time the Galileo was abandoned, but
+                  was on ship earlier, it would have vanished -- lets restore it */
+               if (iscraft==0 && gotit==0 && game.damage[DSHUTTL] >= 0.0) {
+                       prout("Checkov-  \"Security reports the Galileo has reappeared in the dock!\"");
+                       iscraft = 1;
+               }
+
+               /* Revert star chart to earlier era, if it was known then*/
+               if (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) {
+                       for (l = 1; l <= 8; l++)
+                               for (ll = 1; ll <= 8; ll++)
+                                       if (game.starch[l][ll] > 1)
+                                               game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+1000 :1;
+                       prout("Spock has reconstructed a correct star chart from memory");
+                       if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date;
+               }
+       }
+       else {
+               /* Go forward in time */
+               Time = -0.5*intime*log(Rand());
+               prout("You are traveling forward in time %d stardates.", (int)Time);
+               /* cheat to make sure no tractor beams occur during time warp */
+               game.future[FTBEAM] += Time;
+               game.damage[DRADIO] += Time;
+       }
+       newqad(0);
+#ifdef SERGEEV
+        events();
+#endif /* SERGEEV */
+}
+
+void probe(void) {
+       double angle, bigger;
+       int key;
+       /* New code to launch a deep space probe */
+       if (nprobes == 0) {
+               chew();
+               skip(1);
+               if (ship == IHE) 
+                       prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");
+               else
+                       prout("Ye Faerie Queene has no deep space probes.");
+               return;
+       }
+       if (game.damage[DDSP] != 0.0) {
+               chew();
+               skip(1);
+               prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");
+               return;
+       }
+       if (game.future[FDSPROB] != 1e30) {
+               chew();
+               skip(1);
+               if (game.damage[DRADIO] != 0 && condit != IHDOCKED) {
+                       prout("Spock-  \"Records show the previous probe has not yet");
+                       prout("   reached its destination.\"");
+               }
+               else
+                       prout("Uhura- \"The previous probe is still reporting data, Sir.\"");
+               return;
+       }
+       key = scan();
+
+       if (key == IHEOL) {
+               /* slow mode, so let Kirk know how many probes there are left */
+               prout(nprobes==1 ? "%d probe left." : "%d probes left.", nprobes);
+               proutn("Are you sure you want to fire a probe? ");
+               if (ja()==0) return;
+       }
+
+       isarmed = FALSE;
+       if (key == IHALPHA && strcmp(citem,"armed") == 0) {
+               isarmed = TRUE;
+               key = scan();
+       }
+       else if (key == IHEOL) {
+               proutn("Arm NOVAMAX warhead? ");
+               isarmed = ja();
+       }
+       getcd(TRUE, key);
+       if (direc == -1.0) return;
+       nprobes--;
+               angle = ((15.0 - direc) * 0.5235988);
+       probeinx = -sin(angle);
+       probeiny = cos(angle);
+       if (fabs(probeinx) > fabs(probeiny))
+               bigger = fabs(probeinx);
+       else
+               bigger = fabs(probeiny);
+               
+       probeiny /= bigger;
+       probeinx /= bigger;
+       proben = 10.0*dist*bigger +0.5;
+       probex = quadx*10 + sectx - 1;  // We will use better packing than original
+       probey = quady*10 + secty - 1;
+       probecx = quadx;
+       probecy = quady;
+       game.future[FDSPROB] = game.state.date + 0.01; // Time to move one sector
+       prout("Ensign Chekov-  \"The deep space probe is launched, Captain.\"");
+       ididit = 1;
+       return;
+}
+
+void help(void) {
+       /* There's more than one way to move in this game! */
+       double ddist, xdist, probf;
+       int line = 0, l, ix, iy;
+#ifdef SERGEEV
+       int pox, posy;
+#endif /* SERGEEV */
+
+       chew();
+       /* Test for conditions which prevent calling for help */
+       if (condit == IHDOCKED) {
+               prout("Lt. Uhura-  \"But Captain, we're already docked.\"");
+               return;
+       }
+       if (game.damage[DRADIO] != 0) {
+               prout("Subspace radio damaged.");
+               return;
+       }
+       if (game.state.rembase==0) {
+               prout("Lt. Uhura-  \"Captain, I'm not getting any response from Starbase.\"");
+               return;
+       }
+       if (landed == 1) {
+               proutn("You must be aboard the ");
+               crmshp();
+               prout(".");
+               return;
+       }
+       /* OK -- call for help from nearest starbase */
+       nhelp++;
+       if (basex!=0) {
+               /* There's one in this quadrant */
+               ddist = sqrt(square(basex-sectx)+square(basey-secty));
+       }
+       else {
+               ddist = 1e30;
+               for (l = 1; l <= game.state.rembase; l++) {
+                       xdist=10.0*sqrt(square(game.state.baseqx[l]-quadx)+square(game.state.baseqy[l]-quady));
+                       if (xdist < ddist) {
+                               ddist = xdist;
+                               line = l;
+                       }
+               }
+               /* Since starbase not in quadrant, set up new quadrant */
+               quadx = game.state.baseqx[line];
+               quady = game.state.baseqy[line];
+               newqad(1);
+       }
+       /* dematerialize starship */
+       game.quad[sectx][secty]=IHDOT;
+       proutn("Starbase in %s responds--", cramlc(quadrant, quadx, quady));
+       proutn("");
+       crmshp();
+       prout(" dematerializes.");
+#ifdef SERGEEV
+        sectx=0;
+        for (l = 1; l <= 5; l++) {
+                ix = basex+3.0*Rand()-1;
+                iy = basey+3.0*Rand()-1;
+                if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {
+                        /* found one -- finish up */
+                        sectx=ix;
+                        secty=iy;
+                        game.quad[ix][iy]=IHMATER0;
+                        break;
+                }
+        }
+        if (sectx==0){
+           prout("You have been lost in space...");
+           finish(FMATERIALIZE);
+           return;
+        }
+#endif /* SERGEEV */
+       /* Give starbase three chances to rematerialize starship */
+       probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);
+       for (l = 1; l <= 3; l++) {
+               switch (l) {
+                       case 1: proutn("1st"); break;
+                       case 2: proutn("2nd"); break;
+                       case 3: proutn("3rd"); break;
+               }
+               proutn(" attempt to re-materialize ");
+               crmshp();
+               prouts(" . . . . . ");
+               if (Rand() > probf) break;
+               prout("fails.");
+       }
+       if (l > 3) {
+               finish(FMATERIALIZE);
+               return;
+       }
+       /* Rematerialization attempt should succeed if can get adj to base */
+       for (l = 1; l <= 5; l++) {
+               ix = basex+3.0*Rand()-1;
+               iy = basey+3.0*Rand()-1;
+               if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {
+                       /* found one -- finish up */
+                       prout("succeeds.");
+                       sectx=ix;
+                       secty=iy;
+                       game.quad[ix][iy]=ship;
+                       dock(0);
+                       skip(1);
+                       prout("Lt. Uhura-  \"Captain, we made it!\"");
+                       return;
+               }
+       }
+       finish(FMATERIALIZE);
+       return;
+}
index a9ec295fc76ad3c5affe5975c09632b9a8a6e436..3de87c34405b99a733bd54bc2ebb5e6a5e4c2288 100644 (file)
--- a/planets.c
+++ b/planets.c
-#include "sst.h"\r
-\r
-static int height;\r
-\r
-static char *classes[] = {"M","N","O"};\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] <= game.state.date+Time && game.state.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 || game.state.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 = 0; i < inplan; i++) {\r
-               if (game.state.plnets[i].known != unknown\r
-#ifdef DEBUG\r
-                       || ( idebug && game.state.plnets[i].x !=0)\r
-#endif\r
-                       ) {\r
-                       iknow = 1;\r
-#ifdef DEBUG\r
-                       if (idebug && game.state.plnets[i].known==unknown) proutn("(Unknown) ");\r
-#endif\r
-                       proutn(cramlc(quadrant, game.state.plnets[i].x, game.state.plnets[i].y));\r
-                       proutn("   class ");\r
-                       proutn(classes[game.state.plnets[i].pclass]);\r
-                       proutn("   ");\r
-                       if (game.state.plnets[i].crystals == 0) proutn("no ");\r
-                       prout("dilithium crystals present.");\r
-                       if (game.state.plnets[i].known==shuttle_down) \r
-                               prout("    Shuttle Craft Galileo on surface.");\r
-               }\r
-       }\r
-       if (iknow==0) prout("No information available.");\r
-}\r
-\r
-void orbit(void) {\r
-       skip(1);\r
-       chew();\r
-       if (inorbit!=0) {\r
-               prout("Already in standard orbit.");\r
-               return;\r
-       }\r
-       if (game.damage[DWARPEN] != 0 && game.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
-       height = (1400.+7200.*Rand());\r
-       prout("Sulu-  \"Entered orbit at altitude %.2f kilometers.\"", height);\r
-       inorbit = 1;\r
-       return;\r
-}\r
-\r
-void sensor(void) {\r
-       skip(1);\r
-       chew();\r
-       if (game.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
-       prout("Spock-  \"Sensor scan for %s-", cramlc(quadrant, quadx, quady));\r
-       skip(1);\r
-       prout("         Planet at %s is of class %s.", \r
-              cramlc(sector, plnetx, plnety),\r
-              classes[game.state.plnets[iplnet].pclass]);\r
-       if (game.state.plnets[iplnet].known==shuttle_down) \r
-               prout("         Sensors show Galileo still on surface.");\r
-       proutn("         Readings indicate");\r
-       if (game.state.plnets[iplnet].crystals == 0) proutn(" no");\r
-       prout(" dilithium crystals present.\"");\r
-       if (game.state.plnets[iplnet].known == unknown) game.state.plnets[iplnet].known = known;\r
-       return;\r
-}\r
-\r
-void beam(void) {\r
-       chew();\r
-       skip(1);\r
-       if (game.damage[DTRANSP] != 0) {\r
-               prout("Transporter damaged.");\r
-               if (game.damage[DSHUTTL]==0 && (game.state.plnets[iplnet].known==shuttle_down || iscraft == 1)) {\r
-                       skip(1);\r
-                       proutn("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 (game.state.plnets[iplnet].known==unknown) {\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 (game.state.plnets[iplnet].known==shuttle_down) {\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 (game.state.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 && game.state.plnets[iplnet].known==shuttle_down) {\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 (game.state.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())*game.state.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(game.damage[DSHUTTL] != 0.0) {\r
-               if (game.damage[DSHUTTL] == -1.0) {\r
-                       if (inorbit && game.state.plnets[iplnet].known == shuttle_down)\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 (game.damage[DSHUTTL] > 0)\r
-                       prout("The Galileo is damaged.");\r
-               else prout("Shuttle craft is now serving Big Macs.");\r
-               return;\r
-       }\r
-       if (inorbit==0) {\r
-               crmshp();\r
-               prout(" not in standard orbit.");\r
-               return;\r
-       }\r
-       if ((game.state.plnets[iplnet].known != shuttle_down) && iscraft != 1) {\r
-               prout("Shuttle craft not currently available.");\r
-               return;\r
-       }\r
-       if (landed==-1 && game.state.plnets[iplnet].known==shuttle_down) {\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 (game.state.plnets[iplnet].known==unknown) {\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*game.state.remtime) {\r
-               prout("First Officer Spock-  \"Captain, I compute that such");\r
-               proutn("  a maneuver would require approximately 2d%% of our",\r
-                     (int)(100*Time/game.state.remtime));\r
-               prout("remaining time.");\r
-               proutn("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 (game.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
-                       game.state.plnets[iplnet].known=shuttle_down;\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
-                       game.state.plnets[iplnet].known=known;\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
-               game.state.plnets[iplnet].known = shuttle_down;\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 (game.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
-       proutn("  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(game.kx[1],game.ky[1],game.quad[game.kx[1]][game.ky[1]],game.kx[1],game.ky[1]);\r
-               prout("Ensign Chekov-  \"Congratulations, Captain!\"");\r
-               if (game.state.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 nonfunctional.\"");\r
-                       game.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 (game.quad[i][j] == IHDOT) game.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
+#include "sst.h"
+
+static int height;
+
+static char *classes[] = {"M","N","O"};
+
+static int consumeTime(void) {
+/* I think most of this avoidance was caused by overlay scheme.
+   Let's see what happens if all events can occur here */
+
+//     double asave;
+       ididit = 1;
+#if 0
+       /* Don't wory about this */
+       if (future[FTBEAM] <= game.state.date+Time && game.state.remcom != 0 && condit != IHDOCKED) {
+               /* We are about to be tractor beamed -- operation fails */
+               return 1;
+       }
+#endif
+//     asave = future[FSNOVA];
+//     future[FSNOVA] = 1e30; /* defer supernovas */
+       events();       /* Used to avoid if future[FSCMOVE] within time */
+//     future[FSNOVA] = asave;
+       /*fails if game over, quadrant super-novas or we've moved to new quadrant*/
+       if (alldone || game.state.galaxy[quadx][quady] == 1000 || justin != 0) return 1;
+       return 0;
+}
+
+void preport(void) {
+       int iknow = 0, i;
+       skip(1);
+       chew();
+       prout("Spock-  \"Planet report follows, Captain.\"");
+       skip(1);
+       for (i = 0; i < inplan; i++) {
+               if (game.state.plnets[i].known != unknown
+#ifdef DEBUG
+                       || ( idebug && game.state.plnets[i].x !=0)
+#endif
+                       ) {
+                       iknow = 1;
+#ifdef DEBUG
+                       if (idebug && game.state.plnets[i].known==unknown) proutn("(Unknown) ");
+#endif
+                       proutn(cramlc(quadrant, game.state.plnets[i].x, game.state.plnets[i].y));
+                       proutn("   class ");
+                       proutn(classes[game.state.plnets[i].pclass]);
+                       proutn("   ");
+                       if (game.state.plnets[i].crystals == 0) proutn("no ");
+                       prout("dilithium crystals present.");
+                       if (game.state.plnets[i].known==shuttle_down) 
+                               prout("    Shuttle Craft Galileo on surface.");
+               }
+       }
+       if (iknow==0) prout("No information available.");
+}
+
+void orbit(void) {
+       skip(1);
+       chew();
+       if (inorbit!=0) {
+               prout("Already in standard orbit.");
+               return;
+       }
+       if (game.damage[DWARPEN] != 0 && game.damage[DIMPULS] != 0) {
+               prout("Both warp and impulse engines damaged.");
+               return;
+       }
+       if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) {
+               crmshp();
+               prout(" not adjacient to planet.\n");
+               return;
+       }
+       Time = 0.02+0.03*Rand();
+       prout("Helmsman Sulu-  \"Entering standard orbit, Sir.\"");
+       newcnd();
+       if (consumeTime()) return;
+       height = (1400.+7200.*Rand());
+       prout("Sulu-  \"Entered orbit at altitude %.2f kilometers.\"", height);
+       inorbit = 1;
+       return;
+}
+
+void sensor(void) {
+       skip(1);
+       chew();
+       if (game.damage[DSRSENS] != 0.0) {
+               prout("Short range sensors damaged.");
+               return;
+       }
+       if (plnetx == 0) {
+               prout("No planet in this quadrant.");
+               return;
+       }
+       prout("Spock-  \"Sensor scan for %s-", cramlc(quadrant, quadx, quady));
+       skip(1);
+       prout("         Planet at %s is of class %s.", 
+              cramlc(sector, plnetx, plnety),
+              classes[game.state.plnets[iplnet].pclass]);
+       if (game.state.plnets[iplnet].known==shuttle_down) 
+               prout("         Sensors show Galileo still on surface.");
+       proutn("         Readings indicate");
+       if (game.state.plnets[iplnet].crystals == 0) proutn(" no");
+       prout(" dilithium crystals present.\"");
+       if (game.state.plnets[iplnet].known == unknown) game.state.plnets[iplnet].known = known;
+       return;
+}
+
+void beam(void) {
+       chew();
+       skip(1);
+       if (game.damage[DTRANSP] != 0) {
+               prout("Transporter damaged.");
+               if (game.damage[DSHUTTL]==0 && (game.state.plnets[iplnet].known==shuttle_down || iscraft == 1)) {
+                       skip(1);
+                       proutn("Spock-  \"May I suggest the shuttle craft, Sir?\" ");
+                       if (ja() != 0) shuttle();
+               }
+               return;
+       }
+       if (inorbit==0) {
+               crmshp();
+               prout(" not in standard orbit.");
+               return;
+       }
+       if (shldup!=0) {
+               prout("Impossible to transport through shields.");
+               return;
+       }
+       if (game.state.plnets[iplnet].known==unknown) {
+               prout("Spock-  \"Captain, we have no information on this planet");
+               prout("  and Starfleet Regulations clearly state that in this situation");
+               prout("  you may not go down.\"");
+               return;
+       }
+       if (landed==1) {
+               /* Coming from planet */
+               if (game.state.plnets[iplnet].known==shuttle_down) {
+                       proutn("Spock-  \"Wouldn't you rather take the Galileo?\" ");
+                       if (ja() != 0) {
+                               chew();
+                               return;
+                       }
+                       prout("Your crew hides the Galileo to prevent capture by aliens.");
+               }
+               prout("Landing party assembled, ready to beam up.");
+               skip(1);
+               prout("Kirk whips out communicator...");
+               prouts("BEEP  BEEP  BEEP");
+               skip(2);
+               prout("\"Kirk to enterprise-  Lock on coordinates...energize.\"");
+       }
+       else {
+               /* Going to planet */
+               if (game.state.plnets[iplnet].crystals==0) {
+                       prout("Spock-  \"Captain, I fail to see the logic in");
+                       prout("  exploring a planet with no dilithium crystals.");
+                       proutn("  Are you sure this is wise?\" ");
+                       if (ja()==0) {
+                               chew();
+                               return;
+                       }
+               }
+               prout("Scotty-  \"Transporter room ready, Sir.\"");
+               skip(1);
+               prout("Kirk, and landing party prepare to beam down to planet surface.");
+               skip(1);
+               prout("Kirk-  \"Energize.\"");
+       }
+       skip(1);
+       prouts("WWHOOOIIIIIRRRRREEEE.E.E.  .  .  .  .   .    .");
+       skip(2);
+       if (Rand() > 0.98) {
+               prouts("BOOOIIIOOOIIOOOOIIIOIING . . .");
+               skip(2);
+               prout("Scotty-  \"Oh my God!  I've lost them.\"");
+               finish(FLOST);
+               return;
+       }
+       prouts(".    .   .  .  .  .  .E.E.EEEERRRRRIIIIIOOOHWW");
+       skip(2);
+       prout("Transport complete.");
+       landed = -landed;
+       if (landed==1 && game.state.plnets[iplnet].known==shuttle_down) {
+               prout("The shuttle craft Galileo is here!");
+       }
+       if (landed!=1 && imine==1) {
+               icrystl = 1;
+               cryprob = 0.05;
+       }
+       imine = 0;
+       return;
+}
+
+void mine(void) {
+
+       ididit = 0;
+       skip(1);
+       chew();
+       if (landed!= 1) {
+               prout("Mining party not on planet.");
+               return;
+       }
+       if (game.state.plnets[iplnet].crystals == 0) {
+               prout("No dilithium crystals on this planet.");
+               return;
+       }
+       if (imine == 1) {
+               prout("You've already mined enough crystals for this trip.");
+               return;
+       }
+       if (icrystl == 1 && cryprob == 0.05) {
+               proutn("With all those fresh crystals aboard the ");
+               crmshp();
+               skip(1);
+               prout("there's no reason to mine more at this time.");
+               return;
+       }
+       Time = (0.1+0.2*Rand())*game.state.plnets[iplnet].pclass;
+       if (consumeTime()) return;
+       prout("Mining operation complete.");
+       imine = 1;
+       return;
+}
+
+void usecrystals(void) {
+
+       skip(1);
+       chew();
+       if (icrystl!=1) {
+               prout("No dilithium crystals available.");
+               return;
+       }
+       if (energy >= 1000) {
+               prout("Spock-  \"Captain, Starfleet Regulations prohibit such an operation");
+               prout("  except when condition Yellow exists.");
+               return;
+       }
+       prout("Spock- \"Captain, I must warn you that loading");
+       prout("  raw dilithium crystals into the ship's power");
+       prout("  system may risk a severe explosion.");
+       proutn("  Are you sure this is wise?\" ");
+       if (ja()==0) {
+               chew();
+               return;
+       }
+       skip(1);
+       prout("Engineering Officer Scott-  \"(GULP) Aye Sir.");
+       prout("  Mr. Spock and I will try it.\"");
+       skip(1);
+       prout("Spock-  \"Crystals in place, Sir.");
+       prout("  Ready to activate circuit.\"");
+       skip(1);
+       prouts("Scotty-  \"Keep your fingers crossed, Sir!\"");
+       skip(1);
+       if (Rand() <= cryprob) {
+               prouts("  \"Activating now! - - No good!  It's***");
+               skip(2);
+               prouts("***RED ALERT!  RED A*L********************************");
+               skip(1);
+               stars();
+               prouts("******************   KA-BOOM!!!!   *******************");
+               skip(1);
+               kaboom();
+               return;
+       }
+       energy += 5000.0*(1.0 + 0.9*Rand());
+       prouts("  \"Activating now! - - ");
+       prout("The instruments");
+       prout("   are going crazy, but I think it's");
+       prout("   going to work!!  Congratulations, Sir!\"");
+       cryprob *= 2.0;
+       return;
+}
+
+void shuttle(void) {
+
+       chew();
+       skip(1);
+       ididit = 0;
+       if(game.damage[DSHUTTL] != 0.0) {
+               if (game.damage[DSHUTTL] == -1.0) {
+                       if (inorbit && game.state.plnets[iplnet].known == shuttle_down)
+                               prout("Ye Faerie Queene has no shuttle craft bay to dock it at.");
+                       else
+                               prout("Ye Faerie Queene had no shuttle craft.");
+               }
+               else if (game.damage[DSHUTTL] > 0)
+                       prout("The Galileo is damaged.");
+               else prout("Shuttle craft is now serving Big Macs.");
+               return;
+       }
+       if (inorbit==0) {
+               crmshp();
+               prout(" not in standard orbit.");
+               return;
+       }
+       if ((game.state.plnets[iplnet].known != shuttle_down) && iscraft != 1) {
+               prout("Shuttle craft not currently available.");
+               return;
+       }
+       if (landed==-1 && game.state.plnets[iplnet].known==shuttle_down) {
+               prout("You will have to beam down to retrieve the shuttle craft.");
+               return;
+       }
+       if (shldup!=0 || condit == IHDOCKED) {
+               prout("Shuttle craft cannot pass through shields.");
+               return;
+       }
+       if (game.state.plnets[iplnet].known==unknown) {
+               prout("Spock-  \"Captain, we have no information on this planet");
+               prout("  and Starfleet Regulations clearly state that in this situation");
+               prout("  you may not fly down.\"");
+               return;
+       }
+       Time = 3.0e-5*height;
+       if (Time >= 0.8*game.state.remtime) {
+               prout("First Officer Spock-  \"Captain, I compute that such");
+               proutn("  a maneuver would require approximately 2d%% of our",
+                     (int)(100*Time/game.state.remtime));
+               prout("remaining time.");
+               proutn("Are you sure this is wise?\" ");
+               if (ja()==0) {
+                       Time = 0.0;
+                       return;
+               }
+       }
+       if (landed == 1) {
+               /* Kirk on planet */
+               if (iscraft==1) {
+                       /* Galileo on ship! */
+                       if (game.damage[DTRANSP]==0) {
+                               proutn("Spock-  \"Would you rather use the transporter?\" ");
+                               if (ja() != 0) {
+                                       beam();
+                                       return;
+                               }
+                               proutn("Shuttle crew");
+                       }
+                       else
+                               proutn("Rescue party");
+                       prout(" boards Galileo and swoops toward planet surface.");
+                       iscraft = 0;
+                       skip(1);
+                       if (consumeTime()) return;
+                       game.state.plnets[iplnet].known=shuttle_down;
+                       prout("Trip complete.");
+                       return;
+               }
+               else {
+                       /* Ready to go back to ship */
+                       prout("You and your mining party board the");
+                       prout("shuttle craft for the trip back to the Enterprise.");
+                       skip(1);
+                       prout("The short hop begins . . .");
+                       game.state.plnets[iplnet].known=known;
+                       icraft = 1;
+                       skip(1);
+                       landed = -1;
+                       if (consumeTime()) return;
+                       iscraft = 1;
+                       icraft = 0;
+                       if (imine!=0) {
+                               icrystl = 1;
+                               cryprob = 0.05;
+                       }
+                       imine = 0;
+                       prout("Trip complete.");
+                       return;
+               }
+       }
+       else {
+               /* Kirk on ship */
+               /* and so is Galileo */
+               prout("Mining party assembles in the hangar deck,");
+               prout("ready to board the shuttle craft \"Galileo\".");
+               skip(1);
+               prouts("The hangar doors open; the trip begins.");
+               skip(1);
+               icraft = 1;
+               iscraft = 0;
+               if (consumeTime()) return;
+               game.state.plnets[iplnet].known = shuttle_down;
+               landed = 1;
+               icraft = 0;
+               prout("Trip complete");
+               return;
+       }
+}
+               
+
+void deathray(void) {
+       double r = Rand();
+       
+       ididit = 0;
+       skip(1);
+       chew();
+       if (ship != IHE) {
+               prout("Ye Faerie Queene has no death ray.");
+               return;
+       }
+       if (nenhere==0) {
+               prout("Sulu-  \"But Sir, there are no enemies in this quadrant.\"");
+               return;
+       }
+       if (game.damage[DDRAY] > 0.0) {
+               prout("Death Ray is damaged.");
+               return;
+       }
+       prout("Spock-  \"Captain, the 'Experimental Death Ray'");
+       prout("  is highly unpredictible.  Considering the alternatives,");
+       proutn("  are you sure this is wise?\" ");
+       if (ja()==0) return;
+       prout("Spock-  \"Acknowledged.\"");
+       skip(1);
+       ididit=1;
+       prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE");
+       skip(1);
+       prout("Crew scrambles in emergency preparation.");
+       prout("Spock and Scotty ready the death ray and");
+       prout("prepare to channel all ship's power to the device.");
+       skip(1);
+       prout("Spock-  \"Preparations complete, sir.\"");
+       prout("Kirk-  \"Engage!\"");
+       skip(1);
+       prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
+       skip(1);
+       if (r > .30) {
+               prouts("Sulu- \"Captain!  It's working!\"");
+               skip(2);
+               while (nenhere > 0)
+                       deadkl(game.kx[1],game.ky[1],game.quad[game.kx[1]][game.ky[1]],game.kx[1],game.ky[1]);
+               prout("Ensign Chekov-  \"Congratulations, Captain!\"");
+               if (game.state.remkl == 0) finish(FWON);
+               prout("Spock-  \"Captain, I believe the `Experimental Death Ray'");
+               if (Rand() <= 0.05) {
+                       prout("   is still operational.\"");
+               }
+               else {
+                       prout("   has been rendered nonfunctional.\"");
+                       game.damage[DDRAY] = 39.95;
+               }
+               return;
+       }
+       r = Rand();     // Pick failure method 
+       if (r <= .30) {
+               prouts("Sulu- \"Captain!  It's working!\"");
+               skip(1);
+               prouts("***RED ALERT!  RED ALERT!");
+               skip(1);
+               prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!");
+               skip(1);
+               prouts("***RED ALERT!  RED A*L********************************");
+               skip(1);
+               stars();
+               prouts("******************   KA-BOOM!!!!   *******************");
+               skip(1);
+               kaboom();
+               return;
+       }
+       if (r <= .55) {
+               prouts("Sulu- \"Captain!  Yagabandaghangrapl, brachriigringlanbla!\"");
+               skip(1);
+               prout("Lt. Uhura-  \"Graaeek!  Graaeek!\"");
+               skip(1);
+               prout("Spock-  \"Facinating!  . . . All humans aboard");
+               prout("  have apparently been transformed into strange mutations.");
+               prout("  Vulcans do not seem to be affected.");
+               skip(1);
+               prout("Kirk-  \"Raauch!  Raauch!\"");
+               finish(FDRAY);
+               return;
+       }
+       if (r <= 0.75) {
+               int i,j;
+               prouts("Sulu- \"Captain!  It's   --WHAT?!?!\"");
+               skip(2);
+               proutn("Spock-  \"I believe the word is");
+               prouts(" *ASTONISHING*");
+               prout(" Mr. Sulu.");
+               for (i=1; i<=10; i++)
+                       for (j=1; j<=10; j++)
+                               if (game.quad[i][j] == IHDOT) game.quad[i][j] = IHQUEST;
+               prout("  Captain, our quadrant is now infested with");
+               prouts(" - - - - - -  *THINGS*.");
+               skip(1);
+               prout("  I have no logical explanation.\"");
+               return;
+       }
+       prouts("Sulu- \"Captain!  The Death Ray is creating tribbles!\"");
+       skip(1);
+       prout("Scotty-  \"There are so many tribbles down here");
+       prout("  in Engineering, we can't move for 'em, Captain.\"");
+       finish(FTRIBBLE);
+       return;
+}
index 07a5196946a84c34e24e77d9419631bb9a036d29..5c187722b6133cd461c0836f33c2a31cf5148d8c 100644 (file)
--- a/reports.c
+++ b/reports.c
-#include "sst.h"\r
-#include <math.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-void attakreport(int l) {\r
-    if (!l) {\r
-       if (game.future[FCDBAS] < 1e30) {\r
-               prout("Starbase in %s is currently under Commander attack.",\r
-                     cramlc(quadrant, batx, baty));\r
-               prout("It can hold out until Stardate %d.", \r
-                     (int)game.future[FCDBAS]);\r
-       }\r
-       if (isatb == 1) {\r
-               prout("Starbase in %s is under Super-commander attack.",\r
-                     cramlc(quadrant, game.state.isx, game.state.isy));\r
-               prout("It can hold out until Stardate %d.", \r
-                     (int)game.future[FSCDBAS]);\r
-       }\r
-     } else {\r
-        if (game.future[FCDBAS] < 1e30)\r
-           proutn("Base in %i - %i attacked by C. Alive until %.1f", batx, baty, game.future[FCDBAS]);\r
-        if (isatb == 1)\r
-           proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, game.future[FSCDBAS]);\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
-       prout("");\r
-       prout("You %s playing a %s%s %s game.",\r
-                  alldone? "were": "are now", s1, s2, s3);\r
-       if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");\r
-       if (tourn) prout("This is tournament game %d.", tourn);\r
-       if (f) prout("Your secret password is \"%s\"",game.passwd);\r
-       proutn("%d of %d Klingons have been killed",\r
-                  game.state.killk+game.state.killc+game.state.nsckill, inkling);\r
-       if (game.state.killc) prout(", including %d Commander%s.", game.state.killc, game.state.killc==1?"":"s");\r
-       else if (game.state.killk+game.state.nsckill > 0) prout(", but no Commanders.");\r
-       else prout(".");\r
-       if (skill > 2) prout("The Super Commander has %sbeen destroyed.",\r
-                                                 game.state.nscrem?"not ":"");\r
-       if (game.state.rembase != inbase) {\r
-               proutn("There ");\r
-               if (inbase-game.state.rembase==1) proutn("has been 1 base");\r
-               else {\r
-                   proutn("have been %d bases", inbase-game.state.rembase);\r
-               }\r
-               prout(" destroyed, %d remaining.", game.state.rembase);\r
-       }\r
-       else prout("There are %d bases.", inbase);\r
-       if (game.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(0);\r
-               iseenit = 1;\r
-       }\r
-       if (casual) prout("%d casualt%s suffered so far.",\r
-                                          casual, casual==1? "y" : "ies");\r
-       if (nhelp) prout("There were %d call%s for help.",\r
-                                         nhelp, nhelp==1 ? "" : "s");\r
-       if (ship == IHE) {\r
-               proutn("You have ");\r
-               if (nprobes) proutn("%d", nprobes);\r
-               else proutn("no");\r
-               proutn(" deep space probe");\r
-               if (nprobes!=1) proutn("s");\r
-               prout(".");\r
-       }\r
-       if ((game.damage[DRADIO] == 0.0 || condit == IHDOCKED)&&\r
-               game.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
-               proutn(cramlc(quadrant, 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
-                       prout("Dilithium crystals have been used %d time%s.",\r
-                                  i, i==1? "" : "s");\r
-               }\r
-       }\r
-       skip(1);\r
-}\r
-       \r
-void lrscan(void) {\r
-       int x, y;\r
-       chew();\r
-       if (game.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
-       prout(cramlc(quadrant, quadx, quady));\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
-                               proutn("   -1");\r
-                       else {\r
-                               proutn("%5d", game.state.galaxy[x][y]);\r
-                               game.starch[x][y] = game.damage[DRADIO] > 0 ? game.state.galaxy[x][y]+1000 :1;\r
-                       }\r
-               }\r
-               skip(1);\r
-       }\r
-\r
-}\r
-\r
-void dreprt(void) {\r
-       int jdam = FALSE, i;\r
-       chew();\r
-\r
-       for (i = 1; i <= NDEVICES; i++) {\r
-               if (game.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
-                       prout("  %16s %8.2f  %8.2f", \r
-                               device[i],\r
-                               game.damage[i]+0.05,\r
-                               docfac*game.damage[i]+0.005);\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 != game.state.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 = game.state.date;\r
-                       for (i=1; i <= 8 ; i++)\r
-                               for (j=1; j <= 8; j++)\r
-                                       if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;\r
-               }\r
-               else {\r
-                   proutn("(Last surveillance update %d stardates ago.",\r
-                          (int)(game.state.date-stdamtim));\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
-               proutn("%d -", i);\r
-               for (j = 1; j <= 8; j++) {\r
-                       if (game.starch[i][j] < 0)\r
-                               proutn("  .1.");\r
-                       else if (game.starch[i][j] == 0)\r
-                               proutn("  ...");\r
-                       else if (game.starch[i][j] > 999)\r
-                               proutn("%5d", game.starch[i][j]-1000);\r
-                       else\r
-                               proutn("%5d", game.state.galaxy[i][j]);\r
-               }\r
-               prout("  -");\r
-       }\r
-       if (nn == 0) {\r
-               skip(1);\r
-               crmshp();\r
-               prout(" is currently in %s", cramlc(quadrant, quadx, quady));\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 = NULL;\r
-       int leftside=TRUE, rightside=TRUE, i, j, k=0, nn=FALSE;\r
-       int goodScan=TRUE;\r
-       switch (l) {\r
-               case 1: // SRSCAN\r
-                       if (game.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
-                           game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ?\r
-                                                                          game.state.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
-                               proutn("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
-                       proutn("%2d  ", i);\r
-                       for (j = 1; j <= 10; j++) {\r
-                               if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1))\r
-                                       proutn("%c ",game.quad[i][j]);\r
-                               else\r
-                                       proutn("- ");\r
-                       }\r
-               }\r
-               if (rightside) {\r
-                       switch (jj) {\r
-                               case 1:\r
-                                       proutn(" Stardate      %.1f", game.state.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
-                                       proutn(" Condition     %s", cp);\r
-                                       break;\r
-                               case 3:\r
-                                       proutn(" Position      ");\r
-                                       proutn(cramlc(neither, quadx, quady));\r
-                                       proutn(" , ");\r
-                                       proutn(cramlc(neither, sectx, secty));\r
-                                       break;\r
-                               case 4:\r
-                                       proutn(" Life Support  ");\r
-                                       if (game.damage[DLIFSUP] != 0.0) {\r
-                                               if (condit == IHDOCKED)\r
-                                                       proutn("DAMAGED, supported by starbase");\r
-                                               else\r
-                                                       proutn("DAMAGED, reserves=%.2f", lsupres);\r
-                                       }\r
-                                       else\r
-                                               proutn("ACTIVE");\r
-                                       break;\r
-                               case 5:\r
-                                       proutn(" Warp Factor   %.1f", warpfac);\r
-                                       break;\r
-                               case 6:\r
-                                       proutn(" Energy        %.2f", energy);\r
-                                       break;\r
-                               case 7:\r
-                                       proutn(" Torpedoes     %d", torps);\r
-                                       break;\r
-                               case 8:\r
-                                       proutn(" Shields       ");\r
-                                       if (game.damage[DSHIELD] != 0)\r
-                                               proutn("DAMAGED,");\r
-                                       else if (shldup)\r
-                                               proutn("UP,");\r
-                                       else\r
-                                               proutn("DOWN,");\r
-                                       proutn(" %d%% %.1f units",\r
-                                                  (int)((100.0*shield)/inshld + 0.5), shield);\r
-                                       break;\r
-                               case 9:\r
-                                       proutn(" Klingons Left %d", game.state.remkl);\r
-                                       break;\r
-                               case 10:\r
-                                       attakreport(1);\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 ix1, ix2, iy1, iy2, prompt=FALSE;\r
-       int wfl;\r
-       double ttime, twarp, tpower;\r
-       if (game.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 {\r
-                if (quady>ix1) ix2 = 1;\r
-                else ix2=10;\r
-                if (quadx>iy1) iy2 = 1;\r
-                else iy2=10;\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 > game.state.date) ttime -= game.state.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
-               prout(" energy will be %.2f.", energy-tpower);\r
-               if (wfl) {\r
-                       prout("And we will arrive at stardate %.2f.",\r
-                               game.state.date+ttime);\r
-               }\r
-               else if (twarp==1.0)\r
-                       prout("Any warp speed is adequate.");\r
-               else {\r
-                       prout("Minimum warp needed is %.2f,", twarp);\r
-                       prout("and we will arrive at stardate %.2f.",\r
-                               game.state.date+ttime);\r
-               }\r
-               if (game.state.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 && game.state.isy == ix1 && game.state.isx == iy1 &&\r
-                        game.future[FSCDBAS]< ttime+game.state.date)||\r
-                       (game.future[FCDBAS]<ttime+game.state.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
+#include "sst.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+void attakreport(int l) {
+    if (!l) {
+       if (game.future[FCDBAS] < 1e30) {
+               prout("Starbase in %s is currently under Commander attack.",
+                     cramlc(quadrant, batx, baty));
+               prout("It can hold out until Stardate %d.", 
+                     (int)game.future[FCDBAS]);
+       }
+       if (isatb == 1) {
+               prout("Starbase in %s is under Super-commander attack.",
+                     cramlc(quadrant, game.state.isx, game.state.isy));
+               prout("It can hold out until Stardate %d.", 
+                     (int)game.future[FSCDBAS]);
+       }
+     } else {
+        if (game.future[FCDBAS] < 1e30)
+           proutn("Base in %i - %i attacked by C. Alive until %.1f", batx, baty, game.future[FCDBAS]);
+        if (isatb == 1)
+           proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, game.future[FSCDBAS]);
+     }
+}
+       
+
+void report(int f) {
+       char *s1,*s2,*s3;
+
+       chew();
+       s1 = (thawed?"thawed ":"");
+       switch (length) {
+               case 1: s2="short"; break;
+               case 2: s2="medium"; break;
+               case 4: s2="long"; break;
+               default: s2="unknown length"; break;
+       }
+       switch (skill) {
+               case 1: s3="novice"; break;
+               case 2: s3="fair"; break;
+               case 3: s3="good"; break;
+               case 4: s3="expert"; break;
+               case 5: s3="emeritus"; break;
+               default: s3="skilled"; break;
+       }
+       prout("");
+       prout("You %s playing a %s%s %s game.",
+                  alldone? "were": "are now", s1, s2, s3);
+       if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");
+       if (tourn) prout("This is tournament game %d.", tourn);
+       if (f) prout("Your secret password is \"%s\"",game.passwd);
+       proutn("%d of %d Klingons have been killed",
+                  game.state.killk+game.state.killc+game.state.nsckill, inkling);
+       if (game.state.killc) prout(", including %d Commander%s.", game.state.killc, game.state.killc==1?"":"s");
+       else if (game.state.killk+game.state.nsckill > 0) prout(", but no Commanders.");
+       else prout(".");
+       if (skill > 2) prout("The Super Commander has %sbeen destroyed.",
+                                                 game.state.nscrem?"not ":"");
+       if (game.state.rembase != inbase) {
+               proutn("There ");
+               if (inbase-game.state.rembase==1) proutn("has been 1 base");
+               else {
+                   proutn("have been %d bases", inbase-game.state.rembase);
+               }
+               prout(" destroyed, %d remaining.", game.state.rembase);
+       }
+       else prout("There are %d bases.", inbase);
+       if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED || iseenit) {
+               /* Don't report this if not seen and
+                       either the radio is dead or not at base! */
+               attakreport(0);
+               iseenit = 1;
+       }
+       if (casual) prout("%d casualt%s suffered so far.",
+                                          casual, casual==1? "y" : "ies");
+       if (nhelp) prout("There were %d call%s for help.",
+                                         nhelp, nhelp==1 ? "" : "s");
+       if (ship == IHE) {
+               proutn("You have ");
+               if (nprobes) proutn("%d", nprobes);
+               else proutn("no");
+               proutn(" deep space probe");
+               if (nprobes!=1) proutn("s");
+               prout(".");
+       }
+       if ((game.damage[DRADIO] == 0.0 || condit == IHDOCKED)&&
+               game.future[FDSPROB] != 1e30) {
+               if (isarmed) 
+                       proutn("An armed deep space probe is in");
+               else
+                       proutn("A deep space probe is in");
+               proutn(cramlc(quadrant, probecx, probecy));
+               prout(".");
+       }
+       if (icrystl) {
+               if (cryprob <= .05)
+                       prout("Dilithium crystals aboard ship... not yet used.");
+               else {
+                       int i=0;
+                       double ai = 0.05;
+                       while (cryprob > ai) {
+                               ai *= 2.0;
+                               i++;
+                       }
+                       prout("Dilithium crystals have been used %d time%s.",
+                                  i, i==1? "" : "s");
+               }
+       }
+       skip(1);
+}
+       
+void lrscan(void) {
+       int x, y;
+       chew();
+       if (game.damage[DLRSENS] != 0.0) {
+               /* Now allow base's sensors if docked */
+               if (condit != IHDOCKED) {
+                       prout("LONG-RANGE SENSORS DAMAGED.");
+                       return;
+               }
+               skip(1);
+               proutn("Starbase's long-range scan for");
+       }
+       else {
+               skip(1);
+               proutn("Long-range scan for ");
+       }
+       prout(cramlc(quadrant, quadx, quady));
+       for (x = quadx-1; x <= quadx+1; x++) {
+               for (y = quady-1; y <= quady+1; y++) {
+                       if (x == 0 || x > 8 || y == 0 || y > 8)
+                               proutn("   -1");
+                       else {
+                               proutn("%5d", game.state.galaxy[x][y]);
+                               game.starch[x][y] = game.damage[DRADIO] > 0 ? game.state.galaxy[x][y]+1000 :1;
+                       }
+               }
+               skip(1);
+       }
+
+}
+
+void dreprt(void) {
+       int jdam = FALSE, i;
+       chew();
+
+       for (i = 1; i <= NDEVICES; i++) {
+               if (game.damage[i] > 0.0) {
+                       if (!jdam) {
+                               skip(1);
+                               prout("DEVICE            -REPAIR TIMES-");
+                               prout("                IN FLIGHT   DOCKED");
+                               jdam = TRUE;
+                       }
+                       prout("  %16s %8.2f  %8.2f", 
+                               device[i],
+                               game.damage[i]+0.05,
+                               docfac*game.damage[i]+0.005);
+               }
+       }
+       if (!jdam) prout("All devices functional.");
+}
+
+void chart(int nn) {
+       int i,j;
+
+       chew();
+       skip(1);
+       if (stdamtim != 1e30 && stdamtim != game.state.date && condit == IHDOCKED) {
+               prout("Spock-  \"I revised the Star Chart from the");
+               prout("  starbase's records.\"");
+               skip(1);
+       }
+       if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY");
+       if (stdamtim != 1e30) {
+               if (condit == IHDOCKED) {
+                       /* We are docked, so restore chart from base information */
+                       stdamtim = game.state.date;
+                       for (i=1; i <= 8 ; i++)
+                               for (j=1; j <= 8; j++)
+                                       if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;
+               }
+               else {
+                   proutn("(Last surveillance update %d stardates ago.",
+                          (int)(game.state.date-stdamtim));
+               }
+       }
+       if (nn ==0) skip(1);
+
+       prout("      1    2    3    4    5    6    7    8");
+       prout("    ----------------------------------------");
+       /* if (nn==0) prout("  -"); */
+       for (i = 1; i <= 8; i++) {
+               proutn("%d -", i);
+               for (j = 1; j <= 8; j++) {
+                       if (game.starch[i][j] < 0)
+                               proutn("  .1.");
+                       else if (game.starch[i][j] == 0)
+                               proutn("  ...");
+                       else if (game.starch[i][j] > 999)
+                               proutn("%5d", game.starch[i][j]-1000);
+                       else
+                               proutn("%5d", game.state.galaxy[i][j]);
+               }
+               prout("  -");
+       }
+       if (nn == 0) {
+               skip(1);
+               crmshp();
+               prout(" is currently in %s", cramlc(quadrant, quadx, quady));
+}
+}
+               
+               
+void srscan(int l) {
+       static char requests[][3] =
+               {"","da","co","po","ls","wa","en","to","sh","kl","ti"};
+       char *cp = NULL;
+       int leftside=TRUE, rightside=TRUE, i, j, k=0, nn=FALSE;
+       int goodScan=TRUE;
+       switch (l) {
+               case 1: // SRSCAN
+                       if (game.damage[DSRSENS] != 0) {
+                               /* Allow base's sensors if docked */
+                               if (condit != IHDOCKED) {
+                                       prout("SHORT-RANGE SENSORS DAMAGED");
+                                       goodScan=FALSE;
+                               }
+                               else
+                                       prout("[Using starbase's sensors]");
+                       }
+                       if (goodScan)
+                           game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ?
+                                                                          game.state.galaxy[quadx][quady]+1000:1;
+                       scan();
+                       if (isit("chart")) nn = TRUE;
+                       if (isit("no")) rightside = FALSE;
+                       chew();
+                       prout("\n    1 2 3 4 5 6 7 8 9 10");
+                       break;
+               case 2: // REQUEST
+                       while (scan() == IHEOL)
+                               proutn("Information desired? ");
+                       chew();
+                       for (k = 1; k <= 10; k++)
+                               if (strncmp(citem,requests[k],min(2,strlen(citem)))==0)
+                                       break;
+                       if (k > 10) {
+                               prout("UNRECOGNIZED REQUEST. Legal requests are:\n"
+                                        "  date, condition, position, lsupport, warpfactor,\n"
+                                        "  energy, torpedoes, shields, klingons, time.");
+                               return;
+                       }
+                       // no "break"
+               case 3: // STATUS
+                       chew();
+                       leftside = FALSE;
+                       skip(1);
+       }
+       for (i = 1; i <= 10; i++) {
+               int jj = (k!=0 ? k : i);
+               if (leftside) {
+                       proutn("%2d  ", i);
+                       for (j = 1; j <= 10; j++) {
+                               if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1))
+                                       proutn("%c ",game.quad[i][j]);
+                               else
+                                       proutn("- ");
+                       }
+               }
+               if (rightside) {
+                       switch (jj) {
+                               case 1:
+                                       proutn(" Stardate      %.1f", game.state.date);
+                                       break;
+                               case 2:
+                                       if (condit != IHDOCKED) newcnd();
+                                       switch (condit) {
+                                               case IHRED: cp = "RED"; break;
+                                               case IHGREEN: cp = "GREEN"; break;
+                                               case IHYELLOW: cp = "YELLOW"; break;
+                                               case IHDOCKED: cp = "DOCKED"; break;
+                                       }
+                                       proutn(" Condition     %s", cp);
+                                       break;
+                               case 3:
+                                       proutn(" Position      ");
+                                       proutn(cramlc(neither, quadx, quady));
+                                       proutn(" , ");
+                                       proutn(cramlc(neither, sectx, secty));
+                                       break;
+                               case 4:
+                                       proutn(" Life Support  ");
+                                       if (game.damage[DLIFSUP] != 0.0) {
+                                               if (condit == IHDOCKED)
+                                                       proutn("DAMAGED, supported by starbase");
+                                               else
+                                                       proutn("DAMAGED, reserves=%.2f", lsupres);
+                                       }
+                                       else
+                                               proutn("ACTIVE");
+                                       break;
+                               case 5:
+                                       proutn(" Warp Factor   %.1f", warpfac);
+                                       break;
+                               case 6:
+                                       proutn(" Energy        %.2f", energy);
+                                       break;
+                               case 7:
+                                       proutn(" Torpedoes     %d", torps);
+                                       break;
+                               case 8:
+                                       proutn(" Shields       ");
+                                       if (game.damage[DSHIELD] != 0)
+                                               proutn("DAMAGED,");
+                                       else if (shldup)
+                                               proutn("UP,");
+                                       else
+                                               proutn("DOWN,");
+                                       proutn(" %d%% %.1f units",
+                                                  (int)((100.0*shield)/inshld + 0.5), shield);
+                                       break;
+                               case 9:
+                                       proutn(" Klingons Left %d", game.state.remkl);
+                                       break;
+                               case 10:
+                                       attakreport(1);
+                                       break;
+                       }
+                                       
+               }
+               skip(1);
+               if (k!=0) return;
+       }
+       if (nn) chart(1);
+}
+                       
+                       
+void eta(void) {
+       int ix1, ix2, iy1, iy2, prompt=FALSE;
+       int wfl;
+       double ttime, twarp, tpower;
+       if (game.damage[DCOMPTR] != 0.0) {
+               prout("COMPUTER DAMAGED, USE A POCKET CALCULATOR.");
+               skip(1);
+               return;
+       }
+       if (scan() != IHREAL) {
+               prompt = TRUE;
+               chew();
+               proutn("Destination quadrant and/or sector? ");
+               if (scan()!=IHREAL) {
+                       huh();
+                       return;
+               }
+       }
+       iy1 = aaitem +0.5;
+       if (scan() != IHREAL) {
+               huh();
+               return;
+       }
+       ix1 = aaitem + 0.5;
+       if (scan() == IHREAL) {
+               iy2 = aaitem + 0.5;
+               if (scan() != IHREAL) {
+                       huh();
+                       return;
+               }
+               ix2 = aaitem + 0.5;
+       }
+        else {
+                if (quady>ix1) ix2 = 1;
+                else ix2=10;
+                if (quadx>iy1) iy2 = 1;
+                else iy2=10;
+       }
+
+       if (ix1 > 8 || ix1 < 1 || iy1 > 8 || iy1 < 1 ||
+               ix2 > 10 || ix2 < 1 || iy2 > 10 || iy2 < 1) {
+               huh();
+               return;
+       }
+       dist = sqrt(square(iy1-quadx+0.1*(iy2-sectx))+
+                               square(ix1-quady+0.1*(ix2-secty)));
+       wfl = FALSE;
+
+       if (prompt) prout("Answer \"no\" if you don't know the value:");
+       while (TRUE) {
+               chew();
+               proutn("Time or arrival date? ");
+               if (scan()==IHREAL) {
+                       ttime = aaitem;
+                       if (ttime > game.state.date) ttime -= game.state.date; // Actually a star date
+                       if (ttime <= 1e-10 ||
+                               (twarp=(floor(sqrt((10.0*dist)/ttime)*10.0)+1.0)/10.0) > 10) {
+                               prout("We'll never make it, sir.");
+                               chew();
+                               return;
+                       }
+                       if (twarp < 1.0) twarp = 1.0;
+                       break;
+               }
+               chew();
+               proutn("Warp factor? ");
+               if (scan()== IHREAL) {
+                       wfl = TRUE;
+                       twarp = aaitem;
+                       if (twarp<1.0 || twarp > 10.0) {
+                               huh();
+                               return;
+                       }
+                       break;
+               }
+               prout("Captain, certainly you can give me one of these.");
+       }
+       while (TRUE) {
+               chew();
+               ttime = (10.0*dist)/square(twarp);
+               tpower = dist*twarp*twarp*twarp*(shldup+1);
+               if (tpower >= energy) {
+                       prout("Insufficient energy, sir.");
+                       if (shldup==0 || tpower > energy*2.0) {
+                               if (!wfl) return;
+                               proutn("New warp factor to try? ");
+                               if (scan() == IHREAL) {
+                                       wfl = TRUE;
+                                       twarp = aaitem;
+                                       if (twarp<1.0 || twarp > 10.0) {
+                                               huh();
+                                               return;
+                                       }
+                                       continue;
+                               }
+                               else {
+                                       chew();
+                                       skip(1);
+                                       return;
+                               }
+                       }
+                       prout("But if you lower your shields,");
+                       proutn("remaining");
+                       tpower /= 2;
+               }
+               else
+                       proutn("Remaining");
+               prout(" energy will be %.2f.", energy-tpower);
+               if (wfl) {
+                       prout("And we will arrive at stardate %.2f.",
+                               game.state.date+ttime);
+               }
+               else if (twarp==1.0)
+                       prout("Any warp speed is adequate.");
+               else {
+                       prout("Minimum warp needed is %.2f,", twarp);
+                       prout("and we will arrive at stardate %.2f.",
+                               game.state.date+ttime);
+               }
+               if (game.state.remtime < ttime)
+                       prout("Unfortunately, the Federation will be destroyed by then.");
+               if (twarp > 6.0)
+                       prout("You'll be taking risks at that speed, Captain");
+               if ((isatb==1 && game.state.isy == ix1 && game.state.isx == iy1 &&
+                        game.future[FSCDBAS]< ttime+game.state.date)||
+                       (game.future[FCDBAS]<ttime+game.state.date && baty==ix1 && batx == iy1))
+                       prout("The starbase there will be destroyed by then.");
+               proutn("New warp factor to try? ");
+               if (scan() == IHREAL) {
+                       wfl = TRUE;
+                       twarp = aaitem;
+                       if (twarp<1.0 || twarp > 10.0) {
+                               huh();
+                               return;
+                       }
+               }
+               else {
+                       chew();
+                       skip(1);
+                       return;
+               }
+       }
+                       
+}
diff --git a/setup.c b/setup.c
index 932faa8a037c3fef105260ff2a4b033a726f73f3..3a5a794b105b228ccc2f06ea0d3f5bec2ff2d517 100644 (file)
--- a/setup.c
+++ b/setup.c
-#include <time.h>\r
-#ifdef SERGEEV\r
-#include <sys/stat.h>\r
-#include <conio.h>\r
-#endif /* SERGEEV */\r
-#include "sst.h"\r
-\r
-#ifdef SERGEEV\r
-#ifdef __linux__\r
-static long filelength(int fd) {\r
-struct stat buf;\r
-    fstat(fd, &buf);\r
-    return buf.st_size;\r
-}\r
-#endif\r
-#endif /* SERGEEV */\r
-\r
-void prelim(void) {\r
-       skip(2);\r
-       prout("-SUPER- STAR TREK");\r
-       skip(1);\r
-#ifndef SERGEEV\r
-       prout("Latest update-21 Sept 78");\r
-       skip(1);\r
-#endif /* SERGEEV */\r
-}\r
-\r
-void freeze(int boss) {\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
-       strcpy(game.magic, SSTMAGIC);\r
-       fwrite(&game, sizeof(game), 1, fp);\r
-\r
-       fclose(fp);\r
-\r
-       /* I hope that's enough! */\r
-}\r
-\r
-\r
-int thaw(void) {\r
-       FILE *fp;\r
-        int key;\r
-\r
-       game.passwd[0] = '\0';\r
-       if ((key = scan()) == IHEOL) {\r
-               proutn("File name: ");\r
-               key = scan();\r
-       }\r
-       if (key != IHALPHA) {\r
-               huh();\r
-               return 1;\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 1;\r
-       }\r
-       fread(&game, sizeof(game), 1, fp);\r
-       if (strcmp(game.magic, SSTMAGIC)) {\r
-               prout("Game file format is bad, should begin with " SSTMAGIC);\r
-               skip(1);\r
-               fclose(fp);\r
-               return 1;\r
-       }\r
-\r
-       fclose(fp);\r
-\r
-        return 0;\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 (game.damage[DSHUTTL]==-1) {\r
-                       prout("Ye Faerie Queene has no shuttle craft.");\r
-                       return;\r
-               }\r
-               if (game.damage[DSHUTTL]<0) {\r
-                       prout("Shuttle craft now serving Big Mac's.");\r
-                       return;\r
-               }\r
-               if (game.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 (game.state.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()*game.state.rembase+1;\r
-               /* Set up quadrant and position FQ adjacient to base */\r
-               if (quadx!=game.state.baseqx[nb] || quady!=game.state.baseqy[nb]) {\r
-                       quadx = game.state.baseqx[nb];\r
-                       quady = game.state.baseqy[nb];\r
-                       sectx = secty = 5;\r
-                       newqad(1);\r
-               }\r
-               for (;;) {\r
-                       /* position next to base by trial and error */\r
-                       game.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
-                                       game.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
-       game.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 <= NDEVICES; l++) game.damage[l] = 0.0;\r
-       game.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(int needprompt) {\r
-       int i,j, krem, klumper;\r
-       int ix, iy;\r
-#ifdef DEBUG\r
-       idebug = 0;\r
-#endif\r
-       //  Decide how many of everything\r
-       if (choose(needprompt)) return; // frozen game\r
-       // Prepare the Enterprise\r
-        alldone = gamewon = 0;\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 <= NDEVICES; i++) game.damage[i] = 0.0;\r
-       // Set up assorted game parameters\r
-       batx = baty = 0;\r
-       game.state.date = indate = 100.0*(int)(31.0*Rand()+20.0);\r
-       game.state.killk = game.state.killc = nkinks = nhelp = resting = casual = game.state.nromkl = 0;\r
-       isatb = iscate = imine = icrystl = icraft = game.state.nsckill = game.state.nplankl = 0;\r
-        game.state.starkl = game.state.basekl = 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++) game.state.newstuf[i][j] = game.starch[i][j] = 0;\r
-       // Initialize times for extraneous events\r
-       game.future[FSNOVA] = game.state.date + expran(0.5 * intime);\r
-       game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));\r
-       game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot\r
-       game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
-       game.future[FCDBAS] = 1e30;\r
-       game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : 1e30;\r
-       game.future[FSCDBAS] = 1e30;\r
-       game.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
-                       game.state.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 (game.state.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-game.state.baseqx[j]) + square(iy-game.state.baseqy[j]);\r
-                               if (distq < 6.0*(6-inbase) && Rand() < 0.75) {\r
-                                       contflag = TRUE;\r
-#ifdef DEBUG\r
-                                       proutn("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
-                                       proutn("DEBUG: saving base #%d, close to #%d\n", i, j);\r
-                               }\r
-#endif\r
-                       }\r
-               } while (contflag);\r
-                       \r
-               game.state.baseqx[i] = ix;\r
-               game.state.baseqy[i] = iy;\r
-               game.starch[ix][iy] = -1;\r
-               game.state.galaxy[ix][iy] += 10;\r
-       }\r
-       // Position ordinary Klingon Battle Cruisers\r
-       krem = inkling - incom - game.state.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 (game.state.galaxy[ix][iy] + klump >= 1000);\r
-               game.state.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 = game.state.baseqx[klumper];\r
-                                       iy = game.state.baseqy[klumper];\r
-                                       klumper++;\r
-                               }\r
-                               else\r
-#endif\r
-                                       iran8(&ix, &iy);\r
-                       }\r
-                       while ((game.state.galaxy[ix][iy] < 99 && Rand() < 0.75)||\r
-                                  game.state.galaxy[ix][iy]>899);\r
-                       // check for duplicate\r
-                       for (j = 1; j < i; j++)\r
-                               if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;\r
-               } while (j < i);\r
-               game.state.galaxy[ix][iy] += 100;\r
-               game.state.cx[i] = ix;\r
-               game.state.cy[i] = iy;\r
-       }\r
-       // Locate planets in galaxy\r
-       for (i = 0; i < inplan; i++) {\r
-               do iran8(&ix, &iy);\r
-               while (game.state.newstuf[ix][iy] > 0);\r
-               game.state.newstuf[ix][iy] = 1;\r
-               game.state.plnets[i].x = ix;\r
-               game.state.plnets[i].y = iy;\r
-               game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O\r
-               game.state.plnets[i].crystals = 1.5*Rand();             // 1 in 3 chance of crystals\r
-               game.state.plnets[i].known = unknown;\r
-       }\r
-       // Locate Romulans\r
-       for (i = 1; i <= game.state.nromrem; i++) {\r
-               iran8(&ix, &iy);\r
-               game.state.newstuf[ix][iy] += 10;\r
-       }\r
-       // Locate the Super Commander\r
-       if (game.state.nscrem > 0) {\r
-               do iran8(&ix, &iy);\r
-               while (game.state.galaxy[ix][iy] >= 900);\r
-               game.state.isx = ix;\r
-               game.state.isy = iy;\r
-               game.state.galaxy[ix][iy] += 100;\r
-       }\r
-       // Place thing (in tournament game, thingx == -1, don't want one!)\r
-       if (thingx != -1) {\r
-               iran8(&thingx, &thingy);\r
-       }\r
-       else {\r
-               thingx = thingy = 0;\r
-       }\r
-\r
-//     idate = date;\r
-       skip(2);\r
-       game.state.snap = 0;\r
-               \r
-       if (skill == 1) {\r
-               prout("It is stardate %d. The Federation is being attacked by",\r
-                          (int)game.state.date);\r
-               prout("a deadly Klingon invasion force. As captain of the United");\r
-               prout("Starship U.S.S. Enterprise, it is your mission to seek out");\r
-               prout("and destroy this invasion force of %d battle cruisers.",\r
-                          inkling);\r
-               prout("You have an initial allotment of %d stardates to complete", (int)intime);\r
-               prout("your mission.  As you proceed you may be given more time.");\r
-               prout("");\r
-               prout("You will have %d supporting starbases.", inbase);\r
-               proutn("Starbase locations-  ");\r
-       }\r
-       else {\r
-               prout("Stardate %d.", (int)game.state.date);\r
-               prout("");\r
-               prout("%d Klingons.", inkling);\r
-               prout("An unknown number of Romulans.");\r
-               if (game.state.nscrem) prout("and one (GULP) Super-Commander.");\r
-                       prout("%d stardates.",(int)intime);\r
-                       proutn("%d starbases in ", inbase);\r
-       }\r
-       for (i = 1; i <= inbase; i++) {\r
-               proutn(cramlc(0, game.state.baseqx[i], game.state.baseqy[i]));\r
-               proutn("  ");\r
-       }\r
-       skip(2);\r
-       proutn("The Enterprise is currently in ");\r
-       proutn(cramlc(quadrant, quadx, quady));\r
-       proutn(" ");\r
-        proutn(cramlc(sector, sectx, secty));\r
-       skip(2);\r
-       prout("Good Luck!");\r
-       if (game.state.nscrem) prout("  YOU'LL NEED IT.");\r
-#ifdef SERGEEV\r
-        getche();\r
-#endif /* SERGEEV */\r
-       newqad(0);\r
-        if (nenhere-iqhere-ithere) shldup=1.0;\r
-       if (neutz) attack(0);   // bad luck to start in a Romulan Neutral Zone\r
-}\r
-\r
-void randomize(void) {\r
-       srand((int)time(NULL));\r
-}\r
-\r
-int choose(int needprompt) {\r
-       tourn = 0;\r
-       thawed = 0;\r
-       skill = 0;\r
-       length = 0;\r
-       while (TRUE) {\r
-               if (needprompt) /* Can start with command line options */\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 (*game.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
-#ifndef SERGEEV\r
-       while (TRUE) {\r
-               scan();\r
-               strcpy(game.passwd, citem);\r
-               chew();\r
-               if (*game.passwd != 0) break;\r
-               proutn("Please type in a secret password-");\r
-       }\r
-#else\r
-        for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));\r
-        game.passwd[3]=0;\r
-#endif /* SERGEEV */\r
-#ifdef DEBUG\r
-       if (strcmp(game.passwd, "debug")==0) idebug = 1;\r
-#endif\r
-\r
-       // Use parameters to generate initial values of things\r
-       damfac = 0.5 * skill;\r
-       game.state.rembase = 3.0*Rand()+2.0;\r
-       inbase = game.state.rembase;\r
-       inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();\r
-       game.state.nromrem = (2.0+Rand())*skill;\r
-       game.state.nscrem = (skill > 2? 1 : 0);\r
-       game.state.remtime = 7.0 * length;\r
-       intime = game.state.remtime;\r
-       game.state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);\r
-       inkling = game.state.remkl;\r
-       incom = skill + 0.0625*inkling*Rand();\r
-       game.state.remcom= min(10, incom);\r
-       incom = game.state.remcom;\r
-       game.state.remres = (inkling+4*incom)*intime;\r
-       inresor = game.state.remres;\r
-       if (inkling > 50) {\r
-               inbase = (game.state.rembase += 1);\r
-       }\r
-       return FALSE;\r
-}\r
-\r
-void dropin(int iquad, int *ix, int *iy) {\r
-       do iran10(ix, iy);\r
-       while (game.quad[*ix][*iy] != IHDOT);\r
-       game.quad[*ix][*iy] = iquad;\r
-}\r
-\r
-void newcnd(void) {\r
-       condit = IHGREEN;\r
-       if (energy < 1000.0) condit = IHYELLOW;\r
-       if (game.state.galaxy[quadx][quady] > 99 || game.state.newstuf[quadx][quady] > 9)\r
-               condit = IHRED;\r
-        if (!alive) condit=IHDEAD;\r
-}\r
-\r
-\r
-void newqad(int shutup) {\r
-       int quadnum = game.state.galaxy[quadx][quady];\r
-       int newnum = game.state.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
-        iqhere=0;\r
-        iqengry=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++) game.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
-       game.quad[sectx][secty] = ship;\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
-                       game.kx[i] = ix;\r
-                       game.ky[i] = iy;\r
-                       game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
-                       game.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 <= game.state.remcom ; i++) \r
-                       if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;\r
-                       \r
-               if (i <= game.state.remcom) {\r
-                       game.quad[ix][iy] = IHC;\r
-                       game.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 == game.state.isx && quady == game.state.isy) {\r
-                       game.quad[game.kx[1]][game.ky[1]] = IHS;\r
-                       game.kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;\r
-                        iscate = game.state.remkl>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
-               game.kx[i] = ix;\r
-               game.ky[i] = iy;\r
-               game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
-               game.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=0; i < inplan; i++)\r
-                       if (game.state.plnets[i].x == quadx && game.state.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) {\r
-               neutz = 1;\r
-               if (game.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
-                        iran8(&thingx, &thingy);\r
-                        nenhere++;\r
-                        iqhere=1;\r
-                        game.kx[nenhere] = ix;\r
-                        game.ky[nenhere] = iy;\r
-                        game.kdist[nenhere] = game.kavgd[nenhere] =\r
-                           sqrt(square(sectx-ix) + square(secty-iy));\r
-                        game.kpower[nenhere] = Rand()*6000.0 +500.0 +250.0*skill;\r
-                       if (game.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
-        // 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 (game.quad[ithx][ithy] != IHDOT);\r
-                game.quad[ithx][ithy] = IHT;\r
-                ithere = 1;\r
-                nenhere++;\r
-                game.kx[nenhere] = ithx;\r
-                game.ky[nenhere] = ithy;\r
-                game.kdist[nenhere] = game.kavgd[nenhere] =\r
-                   sqrt(square(sectx-ithx) + square(secty-ithy));\r
-                game.kpower[nenhere] = Rand()*400.0 +100.0 +25.0*skill;\r
-                /* Reserve unocupied corners */\r
-                if (game.quad[1][1]==IHDOT) game.quad[1][1] = 'X';\r
-                if (game.quad[1][10]==IHDOT) game.quad[1][10] = 'X';\r
-                if (game.quad[10][1]==IHDOT) game.quad[10][1] = 'X';\r
-                if (game.quad[10][10]==IHDOT) game.quad[10][10] = 'X';\r
-        }\r
-        sortkl();\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 (game.quad[1][1]=='X') game.quad[1][1] = IHDOT;\r
-               if (game.quad[1][10]=='X') game.quad[1][10] = IHDOT;\r
-               if (game.quad[10][1]=='X') game.quad[10][1] = IHDOT;\r
-               if (game.quad[10][10]=='X') game.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-iqhere-ithere < 2) return;\r
-\r
-       do {\r
-               sw = FALSE;\r
-               for (j = 1; j < nenhere; j++)\r
-                       if (game.kdist[j] > game.kdist[j+1]) {\r
-                               sw = TRUE;\r
-                               t = game.kdist[j];\r
-                               game.kdist[j] = game.kdist[j+1];\r
-                               game.kdist[j+1] = t;\r
-                               t = game.kavgd[j];\r
-                               game.kavgd[j] = game.kavgd[j+1];\r
-                               game.kavgd[j+1] = t;\r
-                               k = game.kx[j];\r
-                               game.kx[j] = game.kx[j+1];\r
-                               game.kx[j+1] = k;\r
-                               k = game.ky[j];\r
-                               game.ky[j] = game.ky[j+1];\r
-                               game.ky[j+1] = k;\r
-                               t = game.kpower[j];\r
-                               game.kpower[j] = game.kpower[j+1];\r
-                               game.kpower[j+1] = t;\r
-                       }\r
-       } while (sw);\r
-}\r
+#include <time.h>
+#ifdef SERGEEV
+#include <sys/stat.h>
+#include <conio.h>
+#endif /* SERGEEV */
+#include "sst.h"
+
+#ifdef SERGEEV
+#ifdef __linux__
+static long filelength(int fd) {
+struct stat buf;
+    fstat(fd, &buf);
+    return buf.st_size;
+}
+#endif
+#endif /* SERGEEV */
+
+void prelim(void) {
+       skip(2);
+       prout("-SUPER- STAR TREK");
+       skip(1);
+#ifndef SERGEEV
+       prout("Latest update-21 Sept 78");
+       skip(1);
+#endif /* SERGEEV */
+}
+
+void freeze(int boss) {
+       FILE *fp;
+       int key;
+       if (boss) {
+               strcpy(citem, "emsave.trk");
+       }
+       else {
+               if ((key = scan()) == IHEOL) {
+                       proutn("File name: ");
+                       key = scan();
+               }
+               if (key != IHALPHA) {
+                       huh();
+                       return;
+               }
+               chew();
+               if (strchr(citem, '.') == NULL) {
+                       strcat(citem, ".trk");
+               }
+       }
+       if ((fp = fopen(citem, "wb")) == NULL) {
+               proutn("Can't freeze game as file ");
+               proutn(citem);
+               skip(1);
+               return;
+       }
+       strcpy(game.magic, SSTMAGIC);
+       fwrite(&game, sizeof(game), 1, fp);
+
+       fclose(fp);
+
+       /* I hope that's enough! */
+}
+
+
+int thaw(void) {
+       FILE *fp;
+        int key;
+
+       game.passwd[0] = '\0';
+       if ((key = scan()) == IHEOL) {
+               proutn("File name: ");
+               key = scan();
+       }
+       if (key != IHALPHA) {
+               huh();
+               return 1;
+       }
+       chew();
+       if (strchr(citem, '.') == NULL) {
+               strcat(citem, ".trk");
+       }
+       if ((fp = fopen(citem, "rb")) == NULL) {
+               proutn("Can't find game file ");
+               proutn(citem);
+               skip(1);
+               return 1;
+       }
+       fread(&game, sizeof(game), 1, fp);
+       if (strcmp(game.magic, SSTMAGIC)) {
+               prout("Game file format is bad, should begin with " SSTMAGIC);
+               skip(1);
+               fclose(fp);
+               return 1;
+       }
+
+       fclose(fp);
+
+        return 0;
+}
+
+void abandn(void) {
+       int nb, l;
+
+       chew();
+       if (condit==IHDOCKED) {
+               if (ship!=IHE) {
+                       prout("You cannot abandon Ye Faerie Queene.");
+                       return;
+               }
+       }
+       else {
+               /* Must take shuttle craft to exit */
+               if (game.damage[DSHUTTL]==-1) {
+                       prout("Ye Faerie Queene has no shuttle craft.");
+                       return;
+               }
+               if (game.damage[DSHUTTL]<0) {
+                       prout("Shuttle craft now serving Big Mac's.");
+                       return;
+               }
+               if (game.damage[DSHUTTL]>0) {
+                       prout("Shuttle craft damaged.");
+                       return;
+               }
+               if (landed==1) {
+                       prout("You must be aboard the Enterprise.");
+                       return;
+               }
+               if (iscraft!=1) {
+                       prout("Shuttle craft not currently available.");
+                       return;
+               }
+               /* Print abandon ship messages */
+               skip(1);
+               prouts("***ABANDON SHIP!  ABANDON SHIP!");
+               skip(1);
+               prouts("***ALL HANDS ABANDON SHIP!");
+               skip(2);
+               prout("Captain and crew escape in shuttle craft.");
+               prout("Remainder of ship's complement beam down");
+               prout("to nearest habitable planet.");
+               if (game.state.rembase==0) {
+                       /* Ops! no place to go... */
+                       finish(FABANDN);
+                       return;
+               }
+               /* If at least one base left, give 'em the Faerie Queene */
+               skip(1);
+               icrystl = 0; /* crystals are lost */
+               nprobes = 0; /* No probes */
+               prout("You are captured by Klingons and released to");
+               prout("the Federation in a prisoner-of-war exchange.");
+               nb = Rand()*game.state.rembase+1;
+               /* Set up quadrant and position FQ adjacient to base */
+               if (quadx!=game.state.baseqx[nb] || quady!=game.state.baseqy[nb]) {
+                       quadx = game.state.baseqx[nb];
+                       quady = game.state.baseqy[nb];
+                       sectx = secty = 5;
+                       newqad(1);
+               }
+               for (;;) {
+                       /* position next to base by trial and error */
+                       game.quad[sectx][secty] = IHDOT;
+                       for (l = 1; l <= 10; l++) {
+                               sectx = 3.0*Rand() - 1.0 + basex;
+                               secty = 3.0*Rand() - 1.0 + basey;
+                               if (sectx >= 1 && sectx <= 10 &&
+                                       secty >= 1 && secty <= 10 &&
+                                       game.quad[sectx][secty] == IHDOT) break;
+                       }
+                       if (l < 11) break; /* found a spot */
+                       sectx=5;
+                       secty=5;
+                       newqad(1);
+               }
+       }
+       /* Get new commission */
+       game.quad[sectx][secty] = ship = IHF;
+       prout("Starfleet puts you in command of another ship,");
+       prout("the Faerie Queene, which is antiquated but,");
+       prout("still useable.");
+       if (icrystl!=0) prout("The dilithium crystals have been moved.");
+       imine=0;
+       iscraft=0; /* Gallileo disappears */
+       /* Resupply ship */
+       condit=IHDOCKED;
+       for (l = 1; l <= NDEVICES; l++) game.damage[l] = 0.0;
+       game.damage[DSHUTTL] = -1;
+       energy = inenrg = 3000.0;
+       shield = inshld = 1250.0;
+       torps = intorps = 6;
+       lsupres=inlsr=3.0;
+       shldup=0;
+       warpfac=5.0;
+       wfacsq=25.0;
+       return;
+}
+       
+void setup(int needprompt) {
+       int i,j, krem, klumper;
+       int ix, iy;
+#ifdef DEBUG
+       idebug = 0;
+#endif
+       //  Decide how many of everything
+       if (choose(needprompt)) return; // frozen game
+       // Prepare the Enterprise
+        alldone = gamewon = 0;
+       ship = IHE;
+       energy = inenrg = 5000.0;
+       shield = inshld = 2500.0;
+       shldchg = shldup = 0;
+       inlsr = 4.0;
+       lsupres = 4.0;
+       iran8(&quadx, &quady);
+       iran10(&sectx, &secty);
+       torps = intorps = 10;
+       nprobes = (int)(3.0*Rand() + 2.0);      /* Give them 2-4 of these wonders */
+       warpfac = 5.0;
+       wfacsq = warpfac * warpfac;
+       for (i=0; i <= NDEVICES; i++) game.damage[i] = 0.0;
+       // Set up assorted game parameters
+       batx = baty = 0;
+       game.state.date = indate = 100.0*(int)(31.0*Rand()+20.0);
+       game.state.killk = game.state.killc = nkinks = nhelp = resting = casual = game.state.nromkl = 0;
+       isatb = iscate = imine = icrystl = icraft = game.state.nsckill = game.state.nplankl = 0;
+        game.state.starkl = game.state.basekl = 0;
+       iscraft = 1;
+       landed = -1;
+       alive = 1;
+       docfac = 0.25;
+       for (i = 1; i <= 8; i++)
+               for (j = 1; j <= 8; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0;
+       // Initialize times for extraneous events
+       game.future[FSNOVA] = game.state.date + expran(0.5 * intime);
+       game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));
+       game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot
+       game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+       game.future[FCDBAS] = 1e30;
+       game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : 1e30;
+       game.future[FSCDBAS] = 1e30;
+       game.future[FDSPROB] = 1e30;
+       // Starchart is functional
+       stdamtim = 1e30;
+       // Put stars in the galaxy
+       instar = 0;
+       for (i=1; i<=8; i++)
+               for (j=1; j<=8; j++) {
+                       int k = Rand()*9.0 + 1.0;
+                       instar += k;
+                       game.state.galaxy[i][j] = k;
+               }
+       // Locate star bases in galaxy
+       for (i = 1; i <= inbase; i++) {
+               int contflag;
+               do {
+                       do iran8(&ix, &iy);
+                       while (game.state.galaxy[ix][iy] >= 10);
+                       contflag = FALSE;
+                       for (j = i-1; j > 0; j--) {
+                               /* Improved placement algorithm to spread out bases */
+                               double distq = square(ix-game.state.baseqx[j]) + square(iy-game.state.baseqy[j]);
+                               if (distq < 6.0*(6-inbase) && Rand() < 0.75) {
+                                       contflag = TRUE;
+#ifdef DEBUG
+                                       proutn("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);
+#endif
+                                       break;
+                               }
+#ifdef DEBUG
+                               else if (distq < 6.0 * (6-inbase)) {
+                                       proutn("DEBUG: saving base #%d, close to #%d\n", i, j);
+                               }
+#endif
+                       }
+               } while (contflag);
+                       
+               game.state.baseqx[i] = ix;
+               game.state.baseqy[i] = iy;
+               game.starch[ix][iy] = -1;
+               game.state.galaxy[ix][iy] += 10;
+       }
+       // Position ordinary Klingon Battle Cruisers
+       krem = inkling - incom - game.state.nscrem;
+       klumper = 0.25*skill*(9.0-length)+1.0;
+       if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant
+       do {
+               double r = Rand();
+               int klump = (1.0 - r*r)*klumper;
+               if (klump > krem) klump = krem;
+               krem -= klump;
+               klump *= 100;
+               do iran8(&ix, &iy);
+               while (game.state.galaxy[ix][iy] + klump >= 1000);
+               game.state.galaxy[ix][iy] += klump;
+       } while (krem > 0);
+       // Position Klingon Commander Ships
+#ifdef DEBUG
+       klumper = 1;
+#endif
+       for (i = 1; i <= incom; i++) {
+               do {
+                       do { /* IF debugging, put commanders by bases, always! */
+#ifdef DEBUG
+                               if (idebug && klumper <= inbase) {
+                                       ix = game.state.baseqx[klumper];
+                                       iy = game.state.baseqy[klumper];
+                                       klumper++;
+                               }
+                               else
+#endif
+                                       iran8(&ix, &iy);
+                       }
+                       while ((game.state.galaxy[ix][iy] < 99 && Rand() < 0.75)||
+                                  game.state.galaxy[ix][iy]>899);
+                       // check for duplicate
+                       for (j = 1; j < i; j++)
+                               if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;
+               } while (j < i);
+               game.state.galaxy[ix][iy] += 100;
+               game.state.cx[i] = ix;
+               game.state.cy[i] = iy;
+       }
+       // Locate planets in galaxy
+       for (i = 0; i < inplan; i++) {
+               do iran8(&ix, &iy);
+               while (game.state.newstuf[ix][iy] > 0);
+               game.state.newstuf[ix][iy] = 1;
+               game.state.plnets[i].x = ix;
+               game.state.plnets[i].y = iy;
+               game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O
+               game.state.plnets[i].crystals = 1.5*Rand();             // 1 in 3 chance of crystals
+               game.state.plnets[i].known = unknown;
+       }
+       // Locate Romulans
+       for (i = 1; i <= game.state.nromrem; i++) {
+               iran8(&ix, &iy);
+               game.state.newstuf[ix][iy] += 10;
+       }
+       // Locate the Super Commander
+       if (game.state.nscrem > 0) {
+               do iran8(&ix, &iy);
+               while (game.state.galaxy[ix][iy] >= 900);
+               game.state.isx = ix;
+               game.state.isy = iy;
+               game.state.galaxy[ix][iy] += 100;
+       }
+       // Place thing (in tournament game, thingx == -1, don't want one!)
+       if (thingx != -1) {
+               iran8(&thingx, &thingy);
+       }
+       else {
+               thingx = thingy = 0;
+       }
+
+//     idate = date;
+       skip(2);
+       game.state.snap = 0;
+               
+       if (skill == 1) {
+               prout("It is stardate %d. The Federation is being attacked by",
+                          (int)game.state.date);
+               prout("a deadly Klingon invasion force. As captain of the United");
+               prout("Starship U.S.S. Enterprise, it is your mission to seek out");
+               prout("and destroy this invasion force of %d battle cruisers.",
+                          inkling);
+               prout("You have an initial allotment of %d stardates to complete", (int)intime);
+               prout("your mission.  As you proceed you may be given more time.");
+               prout("");
+               prout("You will have %d supporting starbases.", inbase);
+               proutn("Starbase locations-  ");
+       }
+       else {
+               prout("Stardate %d.", (int)game.state.date);
+               prout("");
+               prout("%d Klingons.", inkling);
+               prout("An unknown number of Romulans.");
+               if (game.state.nscrem) prout("and one (GULP) Super-Commander.");
+                       prout("%d stardates.",(int)intime);
+                       proutn("%d starbases in ", inbase);
+       }
+       for (i = 1; i <= inbase; i++) {
+               proutn(cramlc(0, game.state.baseqx[i], game.state.baseqy[i]));
+               proutn("  ");
+       }
+       skip(2);
+       proutn("The Enterprise is currently in ");
+       proutn(cramlc(quadrant, quadx, quady));
+       proutn(" ");
+        proutn(cramlc(sector, sectx, secty));
+       skip(2);
+       prout("Good Luck!");
+       if (game.state.nscrem) prout("  YOU'LL NEED IT.");
+#ifdef SERGEEV
+        getche();
+#endif /* SERGEEV */
+       newqad(0);
+        if (nenhere-iqhere-ithere) shldup=1.0;
+       if (neutz) attack(0);   // bad luck to start in a Romulan Neutral Zone
+}
+
+void randomize(void) {
+       srand((int)time(NULL));
+}
+
+int choose(int needprompt) {
+       tourn = 0;
+       thawed = 0;
+       skill = 0;
+       length = 0;
+       while (TRUE) {
+               if (needprompt) /* Can start with command line options */
+                   proutn("Would you like a regular, tournament, or frozen game?");
+               scan();
+               if (strlen(citem)==0) continue; // Try again
+               if (isit("tournament")) {
+                       while (scan() == IHEOL) {
+                               proutn("Type in tournament number-");
+                       }
+                       if (aaitem == 0) {
+                               chew();
+                               continue; // We don't want a blank entry
+                       }
+                       tourn = (int)aaitem;
+                       thingx = -1;
+                       srand((unsigned int)(int)aaitem);
+                       break;
+               }
+               if (isit("frozen")) {
+                       thaw();
+                       chew();
+                       if (*game.passwd==0) continue;
+                       randomize();
+                       Rand(); Rand(); Rand(); Rand();
+                       if (!alldone) thawed = 1; // No plaque if not finished
+                       report(1);
+                       return TRUE;
+               }
+               if (isit("regular")) {
+                       skip(2);
+                       randomize();
+                       Rand(); Rand(); Rand(); Rand();
+                       break;
+               }
+               proutn("What is \"");
+               proutn(citem);
+               prout("\"?");
+               chew();
+       }
+       while (length==0 || skill==0) {
+               if (scan() == IHALPHA) {
+                       if (isit("short")) length = 1;
+                       else if (isit("medium")) length = 2;
+                       else if (isit("long")) length = 4;
+                       else if (isit("novice")) skill = 1;
+                       else if (isit("fair")) skill = 2;
+                       else if (isit("good")) skill = 3;
+                       else if (isit("expert")) skill = 4;
+                       else if (isit("emeritus")) skill = 5;
+                       else {
+                               proutn("What is \"");
+                               proutn(citem);
+                               prout("\"?");
+                       }
+               }
+               else {
+                       chew();
+                       if (length==0) proutn("Would you like a Short, Medium, or Long game? ");
+                       else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player? ");
+               }
+       }
+#ifndef SERGEEV
+       while (TRUE) {
+               scan();
+               strcpy(game.passwd, citem);
+               chew();
+               if (*game.passwd != 0) break;
+               proutn("Please type in a secret password-");
+       }
+#else
+        for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
+        game.passwd[3]=0;
+#endif /* SERGEEV */
+#ifdef DEBUG
+       if (strcmp(game.passwd, "debug")==0) idebug = 1;
+#endif
+
+       // Use parameters to generate initial values of things
+       damfac = 0.5 * skill;
+       game.state.rembase = 3.0*Rand()+2.0;
+       inbase = game.state.rembase;
+       inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();
+       game.state.nromrem = (2.0+Rand())*skill;
+       game.state.nscrem = (skill > 2? 1 : 0);
+       game.state.remtime = 7.0 * length;
+       intime = game.state.remtime;
+       game.state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);
+       inkling = game.state.remkl;
+       incom = skill + 0.0625*inkling*Rand();
+       game.state.remcom= min(10, incom);
+       incom = game.state.remcom;
+       game.state.remres = (inkling+4*incom)*intime;
+       inresor = game.state.remres;
+       if (inkling > 50) {
+               inbase = (game.state.rembase += 1);
+       }
+       return FALSE;
+}
+
+void dropin(int iquad, int *ix, int *iy) {
+       do iran10(ix, iy);
+       while (game.quad[*ix][*iy] != IHDOT);
+       game.quad[*ix][*iy] = iquad;
+}
+
+void newcnd(void) {
+       condit = IHGREEN;
+       if (energy < 1000.0) condit = IHYELLOW;
+       if (game.state.galaxy[quadx][quady] > 99 || game.state.newstuf[quadx][quady] > 9)
+               condit = IHRED;
+        if (!alive) condit=IHDEAD;
+}
+
+
+void newqad(int shutup) {
+       int quadnum = game.state.galaxy[quadx][quady];
+       int newnum = game.state.newstuf[quadx][quady];
+       int i, j, ix, iy, nplan;
+
+       iattak = 1;
+       justin = 1;
+       basex = basey = 0;
+       klhere = 0;
+       comhere = 0;
+       plnetx = plnety = 0;
+       ishere = 0;
+       irhere = 0;
+       iplnet = 0;
+       nenhere = 0;
+       neutz = 0;
+       inorbit = 0;
+       landed = -1;
+       ientesc = 0;
+       ithere = 0;
+        iqhere=0;
+        iqengry=0;
+       iseenit = 0;
+       if (iscate) {
+               // Attempt to escape Super-commander, so tbeam back!
+               iscate = 0;
+               ientesc = 1;
+       }
+       // Clear quadrant
+       for (i=1; i <= 10; i++)
+               for (j=1; j <= 10; j++) game.quad[i][j] = IHDOT;
+       // cope with supernova
+       if (quadnum > 999) {
+               return;
+       }
+       klhere = quadnum/100;
+       irhere = newnum/10;
+       nplan = newnum%10;
+       nenhere = klhere + irhere;
+
+       // Position Starship
+       game.quad[sectx][secty] = ship;
+
+       if (quadnum >= 100) {
+               // Position ordinary Klingons
+               quadnum -= 100*klhere;
+               for (i = 1; i <= klhere; i++) {
+                       dropin(IHK, &ix, &iy);
+                       game.kx[i] = ix;
+                       game.ky[i] = iy;
+                       game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
+                       game.kpower[i] = Rand()*150.0 +300.0 +25.0*skill;
+               }
+               // If we need a commander, promote a Klingon
+               for (i = 1; i <= game.state.remcom ; i++) 
+                       if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;
+                       
+               if (i <= game.state.remcom) {
+                       game.quad[ix][iy] = IHC;
+                       game.kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;
+                       comhere = 1;
+               }
+
+               // If we need a super-commander, promote a Klingon
+               if (quadx == game.state.isx && quady == game.state.isy) {
+                       game.quad[game.kx[1]][game.ky[1]] = IHS;
+                       game.kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;
+                        iscate = game.state.remkl>1;
+                       ishere = 1;
+               }
+       }
+       // Put in Romulans if needed
+       for (i = klhere+1; i <= nenhere; i++) {
+               dropin(IHR, &ix, &iy);
+               game.kx[i] = ix;
+               game.ky[i] = iy;
+               game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
+               game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
+       }
+       sortkl();
+       // If quadrant needs a starbase, put it in
+       if (quadnum >= 10) {
+               quadnum -= 10;
+               dropin(IHB, &basex, &basey);
+       }
+       
+       if (nplan) {
+               // If quadrant needs a planet, put it in
+               for (i=0; i < inplan; i++)
+                       if (game.state.plnets[i].x == quadx && game.state.plnets[i].y == quady) break;
+               if (i < inplan) {
+                       iplnet = i;
+                       dropin(IHP, &plnetx, &plnety);
+               }
+       }
+       // Check for condition
+       newcnd();
+       // And finally the stars
+       for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
+
+       // Check for RNZ
+       if (irhere > 0 && klhere == 0) {
+               neutz = 1;
+               if (game.damage[DRADIO] <= 0.0) {
+                       skip(1);
+                       prout("LT. Uhura- \"Captain, an urgent message.");
+                       prout("  I'll put it on audio.\"  CLICK");
+                       skip(1);
+                       prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");
+                       prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");
+               }
+       }
+
+       if (shutup==0) {
+               // Put in THING if needed
+               if (thingx == quadx && thingy == quady) {
+                       dropin(IHQUEST, &ix, &iy);
+                        iran8(&thingx, &thingy);
+                        nenhere++;
+                        iqhere=1;
+                        game.kx[nenhere] = ix;
+                        game.ky[nenhere] = iy;
+                        game.kdist[nenhere] = game.kavgd[nenhere] =
+                           sqrt(square(sectx-ix) + square(secty-iy));
+                        game.kpower[nenhere] = Rand()*6000.0 +500.0 +250.0*skill;
+                       if (game.damage[DSRSENS] == 0.0) {
+                               skip(1);
+                               prout("MR. SPOCK- \"Captain, this is most unusual.");
+                               prout("    Please examine your short-range scan.\"");
+                       }
+               }
+       }
+
+        // Decide if quadrant needs a Tholian
+        if ((skill < 3 && Rand() <= 0.02) ||   /* Lighten up if skill is low */
+                (skill == 3 && Rand() <= 0.05) ||
+                (skill > 3 && Rand() <= 0.08)
+#ifdef DEBUG
+                || strcmp(passwd, "tholianx")==0
+#endif
+                ) {
+                do {
+                        ithx = Rand() > 0.5 ? 10 : 1;
+                        ithy = Rand() > 0.5 ? 10 : 1;
+                } while (game.quad[ithx][ithy] != IHDOT);
+                game.quad[ithx][ithy] = IHT;
+                ithere = 1;
+                nenhere++;
+                game.kx[nenhere] = ithx;
+                game.ky[nenhere] = ithy;
+                game.kdist[nenhere] = game.kavgd[nenhere] =
+                   sqrt(square(sectx-ithx) + square(secty-ithy));
+                game.kpower[nenhere] = Rand()*400.0 +100.0 +25.0*skill;
+                /* Reserve unocupied corners */
+                if (game.quad[1][1]==IHDOT) game.quad[1][1] = 'X';
+                if (game.quad[1][10]==IHDOT) game.quad[1][10] = 'X';
+                if (game.quad[10][1]==IHDOT) game.quad[10][1] = 'X';
+                if (game.quad[10][10]==IHDOT) game.quad[10][10] = 'X';
+        }
+        sortkl();
+
+       // Put in a few black holes
+       for (i = 1; i <= 3; i++)
+               if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
+
+       // Take out X's in corners if Tholian present
+       if (ithere) {
+               if (game.quad[1][1]=='X') game.quad[1][1] = IHDOT;
+               if (game.quad[1][10]=='X') game.quad[1][10] = IHDOT;
+               if (game.quad[10][1]=='X') game.quad[10][1] = IHDOT;
+               if (game.quad[10][10]=='X') game.quad[10][10] = IHDOT;
+       }               
+}
+
+void sortkl(void) {
+       double t;
+       int sw, j, k;
+
+       // The author liked bubble sort. So we will use it. :-(
+
+        if (nenhere-iqhere-ithere < 2) return;
+
+       do {
+               sw = FALSE;
+               for (j = 1; j < nenhere; j++)
+                       if (game.kdist[j] > game.kdist[j+1]) {
+                               sw = TRUE;
+                               t = game.kdist[j];
+                               game.kdist[j] = game.kdist[j+1];
+                               game.kdist[j+1] = t;
+                               t = game.kavgd[j];
+                               game.kavgd[j] = game.kavgd[j+1];
+                               game.kavgd[j+1] = t;
+                               k = game.kx[j];
+                               game.kx[j] = game.kx[j+1];
+                               game.kx[j+1] = k;
+                               k = game.ky[j];
+                               game.ky[j] = game.ky[j+1];
+                               game.ky[j+1] = k;
+                               t = game.kpower[j];
+                               game.kpower[j] = game.kpower[j+1];
+                               game.kpower[j+1] = t;
+                       }
+       } while (sw);
+}
diff --git a/sst.c b/sst.c
index 3567c2551b8aa14c25d622fdcc77a5de6d3097b4..b31200ecece75d2d857a83983d970aa208a57a35 100644 (file)
--- a/sst.c
+++ b/sst.c
-#define INCLUDED       // Define externs here\r
-#include <ctype.h>\r
-#include <getopt.h>\r
-#include "sst.h"\r
-\r
-#ifndef SSTDOC\r
-#define SSTDOC "sst.doc"\r
-#endif\r
-       \r
-static char line[128], *linep = line;\r
-\r
-/*\r
-\r
-Here are Tom Almy's changes:\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
-Here are Stas Sergeev's changes (controlled by the proprocessor symbol\r
-SERGEEV, not yet completely merged):\r
-\r
-   1. The Space Thingy can be shoved, if you it ram, and can fire back if \r
-      fired upon.\r
-\r
-   1 The Tholian can be hit with phasers\r
-\r
-   2. When you are docked, base covers you with an almost invincible shields \r
-      (a commander can still ram you, or a Romulan can destroy the base,\r
-      or a SCom can even succeed with direct attack IIRC, but this rarely \r
-      happens).\r
-\r
-    3. SCom can't escape from you if no more enemies remain (without this, \r
-       chasing SCom can take an eternity).\r
-\r
-    4. Probe target you enter is now the destination quadrant. Before I don't \r
-       remember what it was, but it was something I had difficulty using)\r
-\r
-    5. Secret password is now autogenerated.\r
-\r
-    6. "Plaque" is adjusted for A4 paper:)\r
-\r
-    7. Phasers now tells you how much energy needed, but only if the computer \r
-       is alive.\r
-\r
-    8. Planets are auto-scanned when you enter the quadrant.\r
-\r
-    9. Mining or using crystals in presense of enemy now yields an attack.\r
-       There are other minor adjustments to what yields an attack\r
-       and what does not.\r
-\r
-    10. Ramming a black hole is no longer instant death.  There is a\r
-        chance you might get timewarped instead.\r
-\r
-   */\r
-\r
-static char *commands[] = {\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
-#define NUMCOMMANDS    sizeof(commands)/sizeof(commands[0])\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
-#ifdef SERGEEV\r
-void setwnd(short wndnum){\r
-     int cury;\r
-     cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;\r
-     if ((curwnd==0)&&(wndnum!=0)) clrscr();\r
-     window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);\r
-     if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){\r
-        gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);\r
-       skip(1);\r
-     }\r
-     curwnd=wndnum;\r
-     gotoxy(1,cury);\r
-}\r
-#endif /* SERGEEV */\r
-\r
-static void helpme(void) {\r
-       int i, j;\r
-       char cmdbuf[32], *cp;\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
-#ifdef SERGEEV\r
-                        setwnd(5);\r
-#endif /* SERGEEV */\r
-                        proutn("Help on what command? ");\r
-                       key = scan();\r
-               }\r
-#ifdef SERGEEV\r
-                setwnd(4);\r
-#endif /* SERGEEV */\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
-           for (j = 0; commands[i][j]; j++)\r
-               cmdbuf[j] = toupper(commands[i][j]);\r
-           cmdbuf[j] = '\0';\r
-       }\r
-       fp = fopen(SSTDOC, "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
-       for (;;) {\r
-           if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {\r
-                       prout("Spock- \"Captain, there is no information on that command.\"");\r
-                       fclose(fp);\r
-                       return;\r
-               }\r
-           if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {\r
-               for (cp = linebuf+3; isspace(*cp); cp++)\r
-                       continue;\r
-               linebuf[strlen(linebuf)-1] = '\0';\r
-               if (strcmp(cp, cmdbuf) == 0)\r
-                   break;\r
-           }\r
-       }\r
-\r
-       skip(1);\r
-       prout("Spock- \"Captain, I've found the following information:\"");\r
-       skip(1);\r
-\r
-       while (fgets(linebuf, sizeof(linebuf),fp)) {\r
-               if (strstr(linebuf, "******"))\r
-                       break;\r
-               proutc(linebuf);\r
-       }\r
-       fclose(fp);\r
-}\r
-\r
-#ifdef SERGEEV\r
-void drawmaps(short l){\r
-     _setcursortype(_NOCURSOR);\r
-     if (l==1) sensor();\r
-     if (l!=2) setwnd(1);\r
-     gotoxy(1,1);\r
-     strcpy(line,"s");\r
-     srscan(1);\r
-     if (l!=2){\r
-        setwnd(2);\r
-        clrscr();\r
-        srscan(2);\r
-        setwnd(3);\r
-        clrscr();\r
-        strcpy(line,"l");\r
-        lrscan();\r
-        _setcursortype(_NORMALCURSOR);\r
-     }\r
-}\r
-#endif /* SERGEEV */\r
-\r
-static void makemoves(void) {\r
-       int i, hitme;\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
-               commandhook(commands[i], TRUE);\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
-                               doshield(1);\r
-                               if (ididit) {\r
-                                       attack(2);\r
-                                       shldchg = 0;\r
-                               }\r
-                               break;\r
-                       case 6:                 // dock\r
-                               dock(1);\r
-                                if (ididit) attack(0);\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
-               commandhook(commands[i], FALSE);\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 (game.state.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 (game.state.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
-int main(int argc, char **argv) {\r
-    int i, option, usecurses = TRUE;\r
-       while ((option = getopt(argc, argv, "t")) != -1) {\r
-           switch (option) {\r
-           case 't':\r
-               usecurses = FALSE;\r
-               break;\r
-           default:\r
-               fprintf(stderr, "usage: sst [-t] [startcommand...].\n");\r
-               exit(0);\r
-           }\r
-       }\r
-\r
-       iostart(usecurses);\r
-       prelim(); \r
-       line[0] = '\0';\r
-       for (i = optind; i < argc;  i++) {\r
-               strcat(line, argv[i]);\r
-               strcat(line, " ");\r
-       }\r
-       while (TRUE) { /* Play a game */\r
-               setup(line[0] == '\0');\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
-                       proutn("Do you want your score recorded?");\r
-                       if (ja()) {\r
-                               chew2();\r
-                               freeze(FALSE);\r
-                       }\r
-               }\r
-               proutn("Do you want to play again? ");\r
-               if (!ja()) break;\r
-#ifdef SERGEEV\r
-               setwnd(0);\r
-               clrscr();\r
-#endif /* SERGEEV */\r
-       }\r
-       skip(1);\r
-#ifndef SERGEEV\r
-       ioend();\r
-#endif /* SERGEEV */\r
-       puts("May the Great Bird of the Galaxy roost upon your home planet.");\r
-       exit(0);\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 = "Tholian"; break;\r
-               case IHWEB: s = "Tholian web"; break;\r
-                case IHQUEST: s = "Stranger"; break;\r
-               default: s = "Unknown??"; break;\r
-       }\r
-       proutn(s);\r
-}\r
-\r
-char *cramlc(enum loctype key, int x, int y) {\r
-       static char buf[32];\r
-       buf[0] = '\0';\r
-       if (key == quadrant) strcpy(buf, "Quadrant ");\r
-       else if (key == sector) strcpy(buf, "Sector ");\r
-       sprintf(buf+strlen(buf), "%d-%d", x, y);\r
-       return buf;\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
-       proutn(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
-       linep = line;\r
-       *linep = 0;\r
-}\r
-\r
-void chew2(void) {\r
-       /* return IHEOL next time */\r
-       linep = line+1;\r
-       *linep = 0;\r
-}\r
-\r
-int scan(void) {\r
-       int i;\r
-       char *cp;\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
-               getline(line, sizeof(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
-           i = 0;\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 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 <= NDEVICES; 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 <= NDEVICES; 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 = game.state.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
-                       proutn("%.2f", future[i]-game.state.date);\r
-                       chew();\r
-                       proutn("  ?");\r
-                       key = scan();\r
-                       if (key == IHREAL) {\r
-                               future[i] = game.state.date + aaitem;\r
-                       }\r
-               }\r
-               chew();\r
-       }\r
-}\r
-                       \r
-\r
-#endif\r
+#define INCLUDED       // Define externs here
+#include <ctype.h>
+#include <getopt.h>
+#include "sst.h"
+
+#ifndef SSTDOC
+#define SSTDOC "sst.doc"
+#endif
+       
+static char line[128], *linep = line;
+
+/*
+
+Here are Tom Almy's changes:
+
+ Compared to original version, I've changed the "help" command to
+   "call" and the "terminate" command to "quit" to better match
+   user expectations. The DECUS version apparently made those changes
+   as well as changing "freeze" to "save". However I like "freeze".
+
+   When I got a later version of Super Star Trek that I was converting
+   from, I added the emexit command.
+
+   That later version also mentions srscan and lrscan working when
+   docked (using the starbase's scanners), so I made some changes here
+   to do this (and indicating that fact to the player), and then realized
+   the base would have a subspace radio as well -- doing a Chart when docked
+   updates the star chart, and all radio reports will be heard. The Dock
+   command will also give a report if a base is under attack.
+
+   Movecom no longer reports movement if sensors are damaged so you wouldn't
+   otherwise know it.
+
+   Also added:
+
+   1. Better base positioning at startup
+
+   2. Deathray improvement (but keeping original failure alternatives)
+
+   3. Tholian Web.
+
+   4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
+      move in Expert and Emeritus games. This code could use improvement.
+
+   5. The deep space probe looks interesting! DECUS version
+
+   6. Perhaps cloaking to be added later? BSD version
+
+Here are Stas Sergeev's changes (controlled by the proprocessor symbol
+SERGEEV, not yet completely merged):
+
+   1. The Space Thingy can be shoved, if you it ram, and can fire back if 
+      fired upon.
+
+   1 The Tholian can be hit with phasers
+
+   2. When you are docked, base covers you with an almost invincible shields 
+      (a commander can still ram you, or a Romulan can destroy the base,
+      or a SCom can even succeed with direct attack IIRC, but this rarely 
+      happens).
+
+    3. SCom can't escape from you if no more enemies remain (without this, 
+       chasing SCom can take an eternity).
+
+    4. Probe target you enter is now the destination quadrant. Before I don't 
+       remember what it was, but it was something I had difficulty using)
+
+    5. Secret password is now autogenerated.
+
+    6. "Plaque" is adjusted for A4 paper:)
+
+    7. Phasers now tells you how much energy needed, but only if the computer 
+       is alive.
+
+    8. Planets are auto-scanned when you enter the quadrant.
+
+    9. Mining or using crystals in presense of enemy now yields an attack.
+       There are other minor adjustments to what yields an attack
+       and what does not.
+
+    10. Ramming a black hole is no longer instant death.  There is a
+        chance you might get timewarped instead.
+
+   */
+
+static char *commands[] = {
+       "srscan",
+       "lrscan",
+       "phasers",
+       "photons",
+       "move",
+       "shields",
+       "dock",
+       "damages",
+       "chart",
+       "impulse",
+       "rest",
+       "warp",
+       "status",
+       "sensors",
+       "orbit",
+       "transport",
+       "mine",
+       "crystals",
+       "shuttle",
+       "planets",
+       "request",
+       "report",
+       "computer",
+       "commands",
+    "emexit",
+    "probe",
+       "abandon",
+       "destruct",
+       "freeze",
+       "deathray",
+       "debug",
+       "call",
+       "quit",
+       "help"
+};
+#define NUMCOMMANDS    sizeof(commands)/sizeof(commands[0])
+
+static void listCommands(int x) {
+       prout("   SRSCAN    MOVE      PHASERS   CALL\n"
+                 "   STATUS    IMPULSE   PHOTONS   ABANDON\n"
+                 "   LRSCAN    WARP      SHIELDS   DESTRUCT\n"
+                 "   CHART     REST      DOCK      QUIT\n"
+                 "   DAMAGES   REPORT    SENSORS   ORBIT\n"
+                 "   TRANSPORT MINE      CRYSTALS  SHUTTLE\n"
+                 "   PLANETS   REQUEST   DEATHRAY  FREEZE\n"
+                 "   COMPUTER  EMEXIT    PROBE     COMMANDS");
+       if (x) prout("   HELP");
+}
+
+#ifdef SERGEEV
+void setwnd(short wndnum){
+     int cury;
+     cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;
+     if ((curwnd==0)&&(wndnum!=0)) clrscr();
+     window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);
+     if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){
+        gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);
+       skip(1);
+     }
+     curwnd=wndnum;
+     gotoxy(1,cury);
+}
+#endif /* SERGEEV */
+
+static void helpme(void) {
+       int i, j;
+       char cmdbuf[32], *cp;
+       char linebuf[132];
+       FILE *fp;
+       /* Give help on commands */
+       int key;
+       key = scan();
+       while (TRUE) {
+               if (key == IHEOL) {
+#ifdef SERGEEV
+                        setwnd(5);
+#endif /* SERGEEV */
+                        proutn("Help on what command? ");
+                       key = scan();
+               }
+#ifdef SERGEEV
+                setwnd(4);
+#endif /* SERGEEV */
+               if (key == IHEOL) return;
+               for (i = 0; i < NUMCOMMANDS; i++) {
+                       if (strcmp(commands[i], citem)==0) break;
+               }
+               if (i != NUMCOMMANDS) break;
+               skip(1);
+               prout("Valid commands:");
+               listCommands(FALSE);
+               key = IHEOL;
+               chew();
+               skip(1);
+       }
+       if (i == 23) {
+               strcpy(cmdbuf, " ABBREV");
+       }
+       else {
+           for (j = 0; commands[i][j]; j++)
+               cmdbuf[j] = toupper(commands[i][j]);
+           cmdbuf[j] = '\0';
+       }
+       fp = fopen(SSTDOC, "r");
+       if (fp == NULL) {
+               prout("Spock-  \"Captain, that information is missing from the");
+               prout("   computer. You need to find SST.DOC and put it in the");
+               prout("   current directory.\"");
+               return;
+       }
+       for (;;) {
+           if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
+                       prout("Spock- \"Captain, there is no information on that command.\"");
+                       fclose(fp);
+                       return;
+               }
+           if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
+               for (cp = linebuf+3; isspace(*cp); cp++)
+                       continue;
+               linebuf[strlen(linebuf)-1] = '\0';
+               if (strcmp(cp, cmdbuf) == 0)
+                   break;
+           }
+       }
+
+       skip(1);
+       prout("Spock- \"Captain, I've found the following information:\"");
+       skip(1);
+
+       while (fgets(linebuf, sizeof(linebuf),fp)) {
+               if (strstr(linebuf, "******"))
+                       break;
+               proutc(linebuf);
+       }
+       fclose(fp);
+}
+
+#ifdef SERGEEV
+void drawmaps(short l){
+     _setcursortype(_NOCURSOR);
+     if (l==1) sensor();
+     if (l!=2) setwnd(1);
+     gotoxy(1,1);
+     strcpy(line,"s");
+     srscan(1);
+     if (l!=2){
+        setwnd(2);
+        clrscr();
+        srscan(2);
+        setwnd(3);
+        clrscr();
+        strcpy(line,"l");
+        lrscan();
+        _setcursortype(_NORMALCURSOR);
+     }
+}
+#endif /* SERGEEV */
+
+static void makemoves(void) {
+       int i, hitme;
+       while (TRUE) { /* command loop */
+               hitme = FALSE;
+               justin = 0;
+               Time = 0.0;
+               i = -1;
+               while (TRUE)  { /* get a command */
+                       chew();
+                       skip(1);
+                       proutn("COMMAND> ");
+                       if (scan() == IHEOL) continue;
+                       for (i=0; i < 26; i++)
+                               if (isit(commands[i]))
+                                       break;
+                       if (i < 26) break;
+                       for (; i < NUMCOMMANDS; i++)
+                               if (strcmp(commands[i], citem) == 0) break;
+                       if (i < NUMCOMMANDS) break;
+
+                       if (skill <= 2)  {
+                               prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
+                               listCommands(TRUE);
+                       }
+                       else prout("UNRECOGNIZED COMMAND.");
+               }
+               commandhook(commands[i], TRUE);
+               switch (i) { /* command switch */
+                       case 0:                 // srscan
+                               srscan(1);
+                               break;
+                       case 1:                 // lrscan
+                               lrscan();
+                               break;
+                       case 2:                 // phasers
+                               phasers();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 3:                 // photons
+                               photon();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 4:                 // move
+                               warp(1);
+                               break;
+                       case 5:                 // shields
+                               doshield(1);
+                               if (ididit) {
+                                       attack(2);
+                                       shldchg = 0;
+                               }
+                               break;
+                       case 6:                 // dock
+                               dock(1);
+                                if (ididit) attack(0);
+                               break;
+                       case 7:                 // damages
+                               dreprt();
+                               break;
+                       case 8:                 // chart
+                               chart(0);
+                               break;
+                       case 9:                 // impulse
+                               impuls();
+                               break;
+                       case 10:                // rest
+                               wait();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 11:                // warp
+                               setwrp();
+                               break;
+                       case 12:                // status
+                               srscan(3);
+                               break;
+                       case 13:                        // sensors
+                               sensor();
+                               break;
+                       case 14:                        // orbit
+                               orbit();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 15:                        // transport "beam"
+                               beam();
+                               break;
+                       case 16:                        // mine
+                               mine();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 17:                        // crystals
+                               usecrystals();
+                               break;
+                       case 18:                        // shuttle
+                               shuttle();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 19:                        // Planet list
+                               preport();
+                               break;
+                       case 20:                        // Status information
+                               srscan(2);
+                               break;
+                       case 21:                        // Game Report 
+                               report(0);
+                               break;
+                       case 22:                        // use COMPUTER!
+                               eta();
+                               break;
+                       case 23:
+                               listCommands(TRUE);
+                               break;
+                       case 24:                // Emergency exit
+                               clearscreen();  // Hide screen
+                               freeze(TRUE);   // forced save
+                               exit(1);                // And quick exit
+                               break;
+                       case 25:
+                               probe();                // Launch probe
+                               break;
+                       case 26:                        // Abandon Ship
+                               abandn();
+                               break;
+                       case 27:                        // Self Destruct
+                               dstrct();
+                               break;
+                       case 28:                        // Save Game
+                               freeze(FALSE);
+                               if (skill > 3)
+                                       prout("WARNING--Frozen games produce no plaques!");
+                               break;
+                       case 29:                        // Try a desparation measure
+                               deathray();
+                               if (ididit) hitme = TRUE;
+                               break;
+                       case 30:                        // What do we want for debug???
+#ifdef DEBUG
+                               debugme();
+#endif
+                               break;
+                       case 31:                // Call for help
+                               help();
+                               break;
+                       case 32:
+                               alldone = 1;    // quit the game
+#ifdef DEBUG
+                               if (idebug) score();
+#endif
+                               break;
+                       case 33:
+                               helpme();       // get help
+                               break;
+               }
+               commandhook(commands[i], FALSE);
+               for (;;) {
+                       if (alldone) break;             // Game has ended
+#ifdef DEBUG
+                       if (idebug) prout("2500");
+#endif
+                       if (Time != 0.0) {
+                               events();
+                               if (alldone) break;             // Events did us in
+                       }
+                       if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
+                               atover(0);
+                               continue;
+                       }
+                       if (nenhere == 0) movetho();
+                       if (hitme && justin==0) {
+                               attack(2);
+                               if (alldone) break;
+                               if (game.state.galaxy[quadx][quady] == 1000) {  // went NOVA! 
+                                       atover(0);
+                                       hitme = TRUE;
+                                       continue;
+                               }
+                       }
+                       break;
+               }
+               if (alldone) break;
+       }
+}
+
+
+int main(int argc, char **argv) {
+    int i, option, usecurses = TRUE;
+       while ((option = getopt(argc, argv, "t")) != -1) {
+           switch (option) {
+           case 't':
+               usecurses = FALSE;
+               break;
+           default:
+               fprintf(stderr, "usage: sst [-t] [startcommand...].\n");
+               exit(0);
+           }
+       }
+
+       iostart(usecurses);
+       prelim(); 
+       line[0] = '\0';
+       for (i = optind; i < argc;  i++) {
+               strcat(line, argv[i]);
+               strcat(line, " ");
+       }
+       while (TRUE) { /* Play a game */
+               setup(line[0] == '\0');
+               if (alldone) {
+                       score();
+                       alldone = 0;
+               }
+               else makemoves();
+               skip(2);
+               stars();
+               skip(1);
+
+               if (tourn && alldone) {
+                       proutn("Do you want your score recorded?");
+                       if (ja()) {
+                               chew2();
+                               freeze(FALSE);
+                       }
+               }
+               proutn("Do you want to play again? ");
+               if (!ja()) break;
+#ifdef SERGEEV
+               setwnd(0);
+               clrscr();
+#endif /* SERGEEV */
+       }
+       skip(1);
+#ifndef SERGEEV
+       ioend();
+#endif /* SERGEEV */
+       puts("May the Great Bird of the Galaxy roost upon your home planet.");
+       exit(0);
+}
+
+
+void cramen(int i) {
+       /* return an enemy */
+       char *s;
+       
+       switch (i) {
+               case IHR: s = "Romulan"; break;
+               case IHK: s = "Klingon"; break;
+               case IHC: s = "Commander"; break;
+               case IHS: s = "Super-commander"; break;
+               case IHSTAR: s = "Star"; break;
+               case IHP: s = "Planet"; break;
+               case IHB: s = "Starbase"; break;
+               case IHBLANK: s = "Black hole"; break;
+               case IHT: s = "Tholian"; break;
+               case IHWEB: s = "Tholian web"; break;
+                case IHQUEST: s = "Stranger"; break;
+               default: s = "Unknown??"; break;
+       }
+       proutn(s);
+}
+
+char *cramlc(enum loctype key, int x, int y) {
+       static char buf[32];
+       buf[0] = '\0';
+       if (key == quadrant) strcpy(buf, "Quadrant ");
+       else if (key == sector) strcpy(buf, "Sector ");
+       sprintf(buf+strlen(buf), "%d-%d", x, y);
+       return buf;
+}
+
+void crmena(int i, int enemy, int key, int x, int y) {
+       if (i == 1) proutn("***");
+       cramen(enemy);
+       proutn(" at ");
+       proutn(cramlc(key, x, y));
+}
+
+void crmshp(void) {
+       char *s;
+       switch (ship) {
+               case IHE: s = "Enterprise"; break;
+               case IHF: s = "Faerie Queene"; break;
+               default:  s = "Ship???"; break;
+       }
+       proutn(s);
+}
+
+void stars(void) {
+       prouts("******************************************************");
+       skip(1);
+}
+
+double expran(double avrage) {
+       return -avrage*log(1e-7 + Rand());
+}
+
+double Rand(void) {
+       return rand()/(1.0 + (double)RAND_MAX);
+}
+
+void iran8(int *i, int *j) {
+       *i = Rand()*8.0 + 1.0;
+       *j = Rand()*8.0 + 1.0;
+}
+
+void iran10(int *i, int *j) {
+       *i = Rand()*10.0 + 1.0;
+       *j = Rand()*10.0 + 1.0;
+}
+
+void chew(void) {
+       linep = line;
+       *linep = 0;
+}
+
+void chew2(void) {
+       /* return IHEOL next time */
+       linep = line+1;
+       *linep = 0;
+}
+
+int scan(void) {
+       int i;
+       char *cp;
+
+       // Init result
+       aaitem = 0.0;
+       *citem = 0;
+
+       // Read a line if nothing here
+       if (*linep == 0) {
+               if (linep != line) {
+                       chew();
+                       return IHEOL;
+               }
+               getline(line, sizeof(line));
+               linep = line;
+       }
+       // Skip leading white space
+       while (*linep == ' ') linep++;
+       // Nothing left
+       if (*linep == 0) {
+               chew();
+               return IHEOL;
+       }
+       if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
+               // treat as a number
+           i = 0;
+           if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
+               linep = line; // Invalid numbers are ignored
+               *linep = 0;
+               return IHEOL;
+           }
+           else {
+               // skip to end
+               linep += i;
+               return IHREAL;
+           }
+       }
+       // Treat as alpha
+       cp = citem;
+       while (*linep && *linep!=' ') {
+               if ((cp - citem) < 9) *cp++ = tolower(*linep);
+               linep++;
+       }
+       *cp = 0;
+       return IHALPHA;
+}
+
+int ja(void) {
+       chew();
+       while (TRUE) {
+               scan();
+               chew();
+               if (*citem == 'y') return TRUE;
+               if (*citem == 'n') return FALSE;
+               proutn("Please answer with \"Y\" or \"N\": ");
+       }
+}
+
+void huh(void) {
+       chew();
+       skip(1);
+       prout("Beg your pardon, Captain?");
+}
+
+int isit(char *s) {
+       /* New function -- compares s to scaned citem and returns true if it
+          matches to the length of s */
+
+       return strncmp(s, citem, max(1, strlen(citem))) == 0;
+
+}
+
+#ifdef DEBUG
+void debugme(void) {
+       proutn("Reset levels? ");
+       if (ja() != 0) {
+               if (energy < inenrg) energy = inenrg;
+               shield = inshld;
+               torps = intorps;
+               lsupres = inlsr;
+       }
+       proutn("Reset damage? ");
+       if (ja() != 0) {
+               int i;
+               for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
+               stdamtim = 1e30;
+       }
+       proutn("Toggle idebug? ");
+       if (ja() != 0) {
+               idebug = !idebug;
+               if (idebug) prout("Debug output ON");
+               else prout("Debug output OFF");
+       }
+       proutn("Cause selective damage? ");
+       if (ja() != 0) {
+               int i, key;
+               for (i=1; i <= NDEVICES; i++) {
+                       proutn("Kill ");
+                       proutn(device[i]);
+                       proutn("? ");
+                       chew();
+                       key = scan();
+                       if (key == IHALPHA &&  isit("y")) {
+                               damage[i] = 10.0;
+                               if (i == DRADIO) stdamtim = game.state.date;
+                       }
+               }
+       }
+       proutn("Examine/change events? ");
+       if (ja() != 0) {
+               int i;
+               for (i = 1; i < NEVENTS; i++) {
+                       int key;
+                       if (future[i] == 1e30) continue;
+                       switch (i) {
+                               case FSNOVA:  proutn("Supernova       "); break;
+                               case FTBEAM:  proutn("T Beam          "); break;
+                               case FSNAP:   proutn("Snapshot        "); break;
+                               case FBATTAK: proutn("Base Attack     "); break;
+                               case FCDBAS:  proutn("Base Destroy    "); break;
+                               case FSCMOVE: proutn("SC Move         "); break;
+                               case FSCDBAS: proutn("SC Base Destroy "); break;
+                       }
+                       proutn("%.2f", future[i]-game.state.date);
+                       chew();
+                       proutn("  ?");
+                       key = scan();
+                       if (key == IHREAL) {
+                               future[i] = game.state.date + aaitem;
+                       }
+               }
+               chew();
+       }
+}
+                       
+
+#endif
diff --git a/sst.h b/sst.h
index 08977838d99c1e26a69e12af232b16760759a2b5..101b2ba45599277bb1dec563b0c230f55259f4a2 100644 (file)
--- a/sst.h
+++ b/sst.h
-#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 min(x, y)      ((x)<(y)?(x):(y))\r
-#define max(x, y)      ((x)>(y)?(x):(y))\r
-\r
-// #define DEBUG\r
-\r
-#define NDEVICES (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
-    enum {M=0, N=1, O=2} pclass;\r
-    int crystals; /* has crystals */\r
-    enum {unknown, known, shuttle_down} known;\r
-} planet;\r
-\r
-#define DESTROY(pl)    memset(pl, '\0', sizeof(planet))\r
-\r
-typedef struct {\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
-       planet plnets[PLNETMAX];  // Planet information\r
-       double date,            // stardate\r
-           remres,             // remaining resources\r
-           remtime;            // remaining time\r
-} snapshot;                            // Data that is snapshot\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
-#define SSTMAGIC       "SST2.0\n"\r
-\r
-EXTERN struct {\r
-    char magic[sizeof(SSTMAGIC)];\r
-    snapshot state;\r
-    snapshot snapsht;\r
-    char quad[11][11];         // contents of our quadrant\r
-    double kpower[21];         // enemy energy levels\r
-    double kdist[21];          // enemy distances\r
-    double kavgd[21];          // average distances\r
-    double damage[NDEVICES+1]; // damage encountered\r
-    double future[NEVENTS+1];  // future events\r
-    char passwd[10];           // Self Destruct password\r
-    int kx[21];                        // enemy sector locations\r
-    int ky[21];\r
-    int starch[9][9];          // star chart\r
-    /* members with macro definitions start here */\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
-        iqhere,\r
-        iqengry,\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
-} game;\r
-\r
-#define inkling game.inkling           // Initial number of klingons\r
-#define inbase game.inbase                     // Initial number of bases\r
-#define incom game.incom                       // Initian number of commanders\r
-#define instar game.instar                     // Initial stars\r
-#define intorps game.intorps           // Initial/Max torpedoes\r
-#define condit game.condit                     // Condition (red, yellow, green docked)\r
-#define torps game.torps                       // number of torpedoes\r
-#define ship game.ship                         // Ship type -- 'E' is Enterprise\r
-#define quadx game.quadx                       // where we are\r
-#define quady game.quady                       //\r
-#define sectx game.sectx                       // where we are\r
-#define secty game.secty                       //\r
-#define length game.length                     // length of game\r
-#define skill game.skill                       // skill level\r
-#define basex game.basex                       // position of base in current quad\r
-#define basey game.basey                       //\r
-#define klhere game.klhere                     // klingons here\r
-#define comhere game.comhere           // commanders here\r
-#define casual game.casual                     // causalties\r
-#define nhelp game.nhelp                       // calls for help\r
-#define nkinks game.nkinks                     //\r
-#define ididit game.ididit                     // Action taken -- allows enemy to attack\r
-#define gamewon game.gamewon           // Finished!\r
-#define alive game.alive                       // We are alive (not killed)\r
-#define justin game.justin                     // just entered quadrant\r
-#define alldone game.alldone           // game is now finished\r
-#define shldchg game.shldchg           // shield is changing (affects efficiency)\r
-#define thingx game.thingx                     // location of strange object in galaxy\r
-#define thingy game.thingy                     //\r
-#define plnetx game.plnetx                     // location of planet in quadrant\r
-#define plnety game.plnety                     //\r
-#define inorbit game.inorbit           // orbiting\r
-#define landed game.landed                     // party on planet (1), on ship (-1)\r
-#define iplnet game.iplnet                     // planet # in quadrant\r
-#define imine game.imine                       // mining\r
-#define inplan game.inplan                     // initial planets\r
-#define nenhere game.nenhere           // Number of enemies in quadrant\r
-#define ishere game.ishere                     // Super-commander in quandrant\r
-#define neutz game.neutz                       // Romulan Neutral Zone\r
-#define irhere game.irhere                     // Romulans in quadrant\r
-#define iqhere game.iqhere                     // Thing in quadrant\r
-#define iqengry game.iqengry                   // Thing attacking\r
-#define icraft game.icraft                     // Kirk in Galileo\r
-#define ientesc game.ientesc           // Attempted escape from supercommander\r
-#define iscraft game.iscraft           // =1 if craft on ship, -1 if removed from game\r
-#define isatb game.isatb                       // =1 if SuperCommander is attacking base\r
-#define iscate game.iscate                     // Super Commander is here\r
-#ifdef DEBUG\r
-#define idebug game.idebug                     // Debug mode\r
-#endif\r
-#define iattak game.iattak                     // attack recursion elimination (was cracks[4])\r
-#define icrystl game.icrystl           // dilithium crystals aboard\r
-#define tourn game.tourn                       // Tournament number\r
-#define thawed game.thawed                     // Thawed game\r
-#define batx game.batx                         // Base coordinates being attacked\r
-#define baty game.baty                         //\r
-#define ithere game.ithere                     // Tholean is here \r
-#define ithx game.ithx                         // coordinates of tholean\r
-#define ithy game.ithy\r
-#define iseenit game.iseenit           // Seen base attack report\r
-#define inresor game.inresor           // initial resources\r
-#define intime game.intime                     // initial time\r
-#define inenrg game.inenrg                     // Initial/Max Energy\r
-#define inshld game.inshld                     // Initial/Max Shield\r
-#define inlsr game.inlsr                       // initial life support resources\r
-#define indate game.indate                     // Initial date\r
-#define energy game.energy                     // Energy level\r
-#define shield game.shield                     // Shield level\r
-#define shldup game.shldup                     // Shields are up\r
-#define warpfac game.warpfac           // Warp speed\r
-#define wfacsq game.wfacsq                     // squared warp factor\r
-#define lsupres game.lsupres           // life support reserves\r
-#define dist game.dist                         // movement distance\r
-#define direc game.direc                       // movement direction\r
-#define Time game.Time                         // time taken by current operation\r
-#define docfac game.docfac                     // repair factor when docking (constant?)\r
-#define resting game.resting           // rest time\r
-#define damfac game.damfac                     // damage factor\r
-#define stdamtim game.stdamtim         // time that star chart was damaged\r
-#define cryprob game.cryprob           // probability that crystal will work\r
-#define probex game.probex                     // location of probe\r
-#define probey game.probey\r
-#define probecx game.probecx           // current probe quadrant\r
-#define probecy game.probecy   \r
-#define probeinx game.probeinx         // Probe x,y increment\r
-#define probeiny game.probeiny         \r
-#define proben game.proben                     // number of moves for probe\r
-#define isarmed game.isarmed           // Probe is armed\r
-#define nprobes game.nprobes           // number of probes available\r
-\r
-/* the following global state doesn't need to be saved */\r
-EXTERN char    *device[NDEVICES+1];\r
-EXTERN int iscore, iskill; // Common PLAQ\r
-EXTERN double perdate;\r
-EXTERN double aaitem;\r
-EXTERN char citem[10];\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
-enum loctype {neither, quadrant, sector};\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
-char *device[NDEVICES+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
-#ifndef TRUE\r
-#define TRUE (1)\r
-#define FALSE (0)\r
-#endif\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
-#define IHDEAD 'Z'\r
-#define IHMATER0 '-'\r
-#define IHMATER1 'o'\r
-#define IHMATER2 '0'\r
-\r
-\r
-/* Function prototypes */\r
-void prelim(void);\r
-void attack(int);\r
-int choose(int);\r
-void setup(int);\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 doshield(int);\r
-void dock(int);\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
-int 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 *, ...);\r
-void proutn(char *, ...);\r
-void stars(void);\r
-void newqad(int);\r
-int ja(void);\r
-void cramen(int);\r
-void crmshp(void);\r
-char *cramlc(enum loctype, int, int);\r
-double expran(double);\r
-double Rand(void);\r
-void iran8(int *, int *);\r
-void iran10(int *, int *);\r
-#define square(i) ((i)*(i))\r
-void dropin(int, int*, int*);\r
-void newcnd(void);\r
-void sortkl(void);\r
-void imove(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 *, int);\r
-void huh(void);\r
-void pause_game(int);\r
-void nova(int, int);\r
-void snova(int, int);\r
-void scom(int *);\r
-void hittem(double *);\r
-void prouts(char *, ...);\r
-void proutc(char *);\r
-int isit(char *);\r
-void preport(void);\r
-void orbit(void);\r
-void sensor(void);\r
-#ifdef SERGEEV\r
-void drawmaps(short);\r
-#endif /* SERGEEV */\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(int);\r
-void movetho(void);\r
-void probe(void);\r
-void clearscreen(void);\r
-void iostart(int);\r
-void ioend(void);\r
-void getline(char *, int);\r
-void commandhook(char *, int);\r
-\r
-#ifdef SERGEEV\r
-typedef struct {\r
-        int wndleft,wndtop,wndright,wndbottom;\r
-} wnd;\r
-extern wnd wnds[6];\r
-#endif /* SERGEEV */\r
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef INCLUDED
+#define EXTERN extern
+#else
+#define EXTERN
+#endif
+
+#define min(x, y)      ((x)<(y)?(x):(y))
+#define max(x, y)      ((x)>(y)?(x):(y))
+
+// #define DEBUG
+
+#define NDEVICES (15)  // Number of devices
+#define PHASEFAC (2.0)
+#define PLNETMAX (10)
+#define NEVENTS (8)
+
+typedef struct {
+    int x;     /* Quadrant location of planet */
+    int y;
+    enum {M=0, N=1, O=2} pclass;
+    int crystals; /* has crystals */
+    enum {unknown, known, shuttle_down} known;
+} planet;
+
+#define DESTROY(pl)    memset(pl, '\0', sizeof(planet))
+
+typedef struct {
+    int snap,          // snapshot taken
+       remkl,                  // remaining klingons
+       remcom,                 // remaining commanders
+       rembase,                // remaining bases
+       starkl,                 // destroyed stars
+       basekl,                 // destroyed bases
+       killk,                  // Klingons killed
+       killc,                  // commanders killed
+       galaxy[9][9],   // The Galaxy (subscript 0 not used)
+       cx[11],cy[11],  // Commander quadrant coordinates
+       baseqx[6],              // Base quadrant X
+       baseqy[6],              // Base quadrant Y
+       newstuf[9][9],  // Extended galaxy goodies
+       isx, isy,               // Coordinate of Super Commander
+       nscrem,                 // remaining super commanders
+       nromkl,                 // Romulans killed
+       nromrem,                // Romulans remaining
+       nsckill,                // super commanders killed
+       nplankl;                // destroyed planets
+       planet plnets[PLNETMAX];  // Planet information
+       double date,            // stardate
+           remres,             // remaining resources
+           remtime;            // remaining time
+} snapshot;                            // Data that is snapshot
+
+// Scalar variables that are needed for freezing the game
+// are placed in a structure. #defines are used to access by their
+// original names. Gee, I could have done this with the d structure,
+// but I just didn't think of it back when I started.
+
+#define SSTMAGIC       "SST2.0\n"
+
+EXTERN struct {
+    char magic[sizeof(SSTMAGIC)];
+    snapshot state;
+    snapshot snapsht;
+    char quad[11][11];         // contents of our quadrant
+    double kpower[21];         // enemy energy levels
+    double kdist[21];          // enemy distances
+    double kavgd[21];          // average distances
+    double damage[NDEVICES+1]; // damage encountered
+    double future[NEVENTS+1];  // future events
+    char passwd[10];           // Self Destruct password
+    int kx[21];                        // enemy sector locations
+    int ky[21];
+    int starch[9][9];          // star chart
+    /* members with macro definitions start here */
+    int inkling,
+       inbase,
+       incom,
+       instar,
+       intorps,
+       condit,
+       torps,
+       ship,
+       quadx,
+       quady,
+       sectx,
+       secty,
+       length,
+       skill,
+       basex,
+       basey,
+       klhere,
+       comhere,
+       casual,
+       nhelp,
+       nkinks,
+       ididit,
+       gamewon,
+       alive,
+       justin,
+       alldone,
+       shldchg,
+       thingx,
+       thingy,
+       plnetx,
+       plnety,
+       inorbit,
+       landed,
+       iplnet,
+       imine,
+       inplan,
+       nenhere,
+       ishere,
+       neutz,
+       irhere,
+       icraft,
+       ientesc,
+       iscraft,
+       isatb,
+       iscate,
+#ifdef DEBUG
+       idebug,
+#endif
+       iattak,
+       icrystl,
+       tourn,
+       thawed,
+       batx,
+       baty,
+       ithere,
+        iqhere,
+        iqengry,
+       ithx,
+       ithy,
+       iseenit,
+       probecx,
+       probecy,
+       proben,
+       isarmed,
+       nprobes;
+    double inresor,
+       intime,
+       inenrg,
+       inshld,
+       inlsr,
+       indate,
+       energy,
+       shield,
+       shldup,
+       warpfac,
+       wfacsq,
+       lsupres,
+       dist,
+       direc,
+       Time,
+       docfac,
+       resting,
+       damfac,
+       stdamtim,
+       cryprob,
+       probex,
+       probey,
+       probeinx,
+       probeiny;
+} game;
+
+#define inkling game.inkling           // Initial number of klingons
+#define inbase game.inbase                     // Initial number of bases
+#define incom game.incom                       // Initian number of commanders
+#define instar game.instar                     // Initial stars
+#define intorps game.intorps           // Initial/Max torpedoes
+#define condit game.condit                     // Condition (red, yellow, green docked)
+#define torps game.torps                       // number of torpedoes
+#define ship game.ship                         // Ship type -- 'E' is Enterprise
+#define quadx game.quadx                       // where we are
+#define quady game.quady                       //
+#define sectx game.sectx                       // where we are
+#define secty game.secty                       //
+#define length game.length                     // length of game
+#define skill game.skill                       // skill level
+#define basex game.basex                       // position of base in current quad
+#define basey game.basey                       //
+#define klhere game.klhere                     // klingons here
+#define comhere game.comhere           // commanders here
+#define casual game.casual                     // causalties
+#define nhelp game.nhelp                       // calls for help
+#define nkinks game.nkinks                     //
+#define ididit game.ididit                     // Action taken -- allows enemy to attack
+#define gamewon game.gamewon           // Finished!
+#define alive game.alive                       // We are alive (not killed)
+#define justin game.justin                     // just entered quadrant
+#define alldone game.alldone           // game is now finished
+#define shldchg game.shldchg           // shield is changing (affects efficiency)
+#define thingx game.thingx                     // location of strange object in galaxy
+#define thingy game.thingy                     //
+#define plnetx game.plnetx                     // location of planet in quadrant
+#define plnety game.plnety                     //
+#define inorbit game.inorbit           // orbiting
+#define landed game.landed                     // party on planet (1), on ship (-1)
+#define iplnet game.iplnet                     // planet # in quadrant
+#define imine game.imine                       // mining
+#define inplan game.inplan                     // initial planets
+#define nenhere game.nenhere           // Number of enemies in quadrant
+#define ishere game.ishere                     // Super-commander in quandrant
+#define neutz game.neutz                       // Romulan Neutral Zone
+#define irhere game.irhere                     // Romulans in quadrant
+#define iqhere game.iqhere                     // Thing in quadrant
+#define iqengry game.iqengry                   // Thing attacking
+#define icraft game.icraft                     // Kirk in Galileo
+#define ientesc game.ientesc           // Attempted escape from supercommander
+#define iscraft game.iscraft           // =1 if craft on ship, -1 if removed from game
+#define isatb game.isatb                       // =1 if SuperCommander is attacking base
+#define iscate game.iscate                     // Super Commander is here
+#ifdef DEBUG
+#define idebug game.idebug                     // Debug mode
+#endif
+#define iattak game.iattak                     // attack recursion elimination (was cracks[4])
+#define icrystl game.icrystl           // dilithium crystals aboard
+#define tourn game.tourn                       // Tournament number
+#define thawed game.thawed                     // Thawed game
+#define batx game.batx                         // Base coordinates being attacked
+#define baty game.baty                         //
+#define ithere game.ithere                     // Tholean is here 
+#define ithx game.ithx                         // coordinates of tholean
+#define ithy game.ithy
+#define iseenit game.iseenit           // Seen base attack report
+#define inresor game.inresor           // initial resources
+#define intime game.intime                     // initial time
+#define inenrg game.inenrg                     // Initial/Max Energy
+#define inshld game.inshld                     // Initial/Max Shield
+#define inlsr game.inlsr                       // initial life support resources
+#define indate game.indate                     // Initial date
+#define energy game.energy                     // Energy level
+#define shield game.shield                     // Shield level
+#define shldup game.shldup                     // Shields are up
+#define warpfac game.warpfac           // Warp speed
+#define wfacsq game.wfacsq                     // squared warp factor
+#define lsupres game.lsupres           // life support reserves
+#define dist game.dist                         // movement distance
+#define direc game.direc                       // movement direction
+#define Time game.Time                         // time taken by current operation
+#define docfac game.docfac                     // repair factor when docking (constant?)
+#define resting game.resting           // rest time
+#define damfac game.damfac                     // damage factor
+#define stdamtim game.stdamtim         // time that star chart was damaged
+#define cryprob game.cryprob           // probability that crystal will work
+#define probex game.probex                     // location of probe
+#define probey game.probey
+#define probecx game.probecx           // current probe quadrant
+#define probecy game.probecy   
+#define probeinx game.probeinx         // Probe x,y increment
+#define probeiny game.probeiny         
+#define proben game.proben                     // number of moves for probe
+#define isarmed game.isarmed           // Probe is armed
+#define nprobes game.nprobes           // number of probes available
+
+/* the following global state doesn't need to be saved */
+EXTERN char    *device[NDEVICES+1];
+EXTERN int iscore, iskill; // Common PLAQ
+EXTERN double perdate;
+EXTERN double aaitem;
+EXTERN char citem[10];
+
+typedef enum {FWON, FDEPLETE, FLIFESUP, FNRG, FBATTLE,
+              FNEG3, FNOVA, FSNOVAED, FABANDN, FDILITHIUM,
+                         FMATERIALIZE, FPHASER, FLOST, FMINING, FDPLANET,
+                         FPNOVA, FSSC, FSTRACTOR, FDRAY, FTRIBBLE,
+                         FHOLE} FINTYPE ;
+enum loctype {neither, quadrant, sector};
+
+/* Define devices */
+#define DSRSENS 1
+#define DLRSENS 2
+#define DPHASER 3
+#define DPHOTON 4
+#define DLIFSUP 5
+#define DWARPEN 6
+#define DIMPULS 7
+#define DSHIELD 8
+#define DRADIO  9
+#define DSHUTTL 10
+#define DCOMPTR 11
+#define DTRANSP 12
+#define DSHCTRL 13
+#define DDRAY   14  // Added deathray
+#define DDSP    15  // Added deep space probe
+
+/* Define future events */
+#define FSPY   0       // Spy event happens always (no future[] entry)
+                                       // can cause SC to tractor beam Enterprise
+#define FSNOVA  1   // Supernova
+#define FTBEAM  2   // Commander tractor beams Enterprise
+#define FSNAP   3   // Snapshot for time warp
+#define FBATTAK 4   // Commander attacks base
+#define FCDBAS  5   // Commander destroys base
+#define FSCMOVE 6   // Supercommander moves (might attack base)
+#define FSCDBAS 7   // Supercommander destroys base
+#define FDSPROB 8   // Move deep space probe
+
+#ifdef INCLUDED
+char *device[NDEVICES+1] = {
+       "",
+       "S. R. Sensors",
+       "L. R. Sensors",
+       "Phasers",
+       "Photon Tubes",
+       "Life Support",
+       "Warp Engines",
+       "Impulse Engines",
+       "Shields",
+       "Subspace Radio",
+       "Shuttle Craft",
+       "Computer",
+       "Transporter",
+       "Shield Control",
+    "Death Ray",
+    "D. S. Probe"};                                                                    
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#define FALSE (0)
+#endif
+
+#define IHR 'R'
+#define IHK 'K'
+#define IHC 'C'
+#define IHS 'S'
+#define IHSTAR '*'
+#define IHP 'P'
+#define IHB 'B'
+#define IHBLANK ' '
+#define IHDOT '.'
+#define IHQUEST '?'
+#define IHE 'E'
+#define IHF 'F'
+#define IHT 'T'
+#define IHWEB '#'
+#define IHGREEN 'G'
+#define IHYELLOW 'Y'
+#define IHRED 'R'
+#define IHDOCKED 'D'
+#define IHDEAD 'Z'
+#define IHMATER0 '-'
+#define IHMATER1 'o'
+#define IHMATER2 '0'
+
+
+/* Function prototypes */
+void prelim(void);
+void attack(int);
+int choose(int);
+void setup(int);
+void score(void);
+void atover(int);
+void srscan(int);
+void lrscan(void);
+void phasers(void);
+void photon(void);
+void warp(int);
+void doshield(int);
+void dock(int);
+void dreprt(void);
+void chart(int);
+void impuls(void);
+void wait(void);
+void setwrp(void);
+void events(void);
+void report(int);
+void eta(void);
+void help(void);
+void abandn(void);
+void finish(FINTYPE);
+void dstrct(void);
+void kaboom(void);
+void freeze(int);
+int thaw(void);
+void plaque(void);
+int scan(void);
+#define IHEOL (0)
+#define IHALPHA (1)
+#define IHREAL (2)
+void chew(void);
+void chew2(void);
+void skip(int);
+void prout(char *, ...);
+void proutn(char *, ...);
+void stars(void);
+void newqad(int);
+int ja(void);
+void cramen(int);
+void crmshp(void);
+char *cramlc(enum loctype, int, int);
+double expran(double);
+double Rand(void);
+void iran8(int *, int *);
+void iran10(int *, int *);
+#define square(i) ((i)*(i))
+void dropin(int, int*, int*);
+void newcnd(void);
+void sortkl(void);
+void imove(void);
+void ram(int, int, int, int);
+void crmena(int, int, int, int, int);
+void deadkl(int, int, int, int, int);
+void timwrp(void);
+void movcom(void);
+void torpedo(double, double, int, int, double *, int);
+void huh(void);
+void pause_game(int);
+void nova(int, int);
+void snova(int, int);
+void scom(int *);
+void hittem(double *);
+void prouts(char *, ...);
+void proutc(char *);
+int isit(char *);
+void preport(void);
+void orbit(void);
+void sensor(void);
+#ifdef SERGEEV
+void drawmaps(short);
+#endif /* SERGEEV */
+void beam(void);
+void mine(void);
+void usecrystals(void);
+void shuttle(void);
+void deathray(void);
+void debugme(void);
+void attakreport(int);
+void movetho(void);
+void probe(void);
+void clearscreen(void);
+void iostart(int);
+void ioend(void);
+void getline(char *, int);
+void commandhook(char *, int);
+
+#ifdef SERGEEV
+typedef struct {
+        int wndleft,wndtop,wndright,wndbottom;
+} wnd;
+extern wnd wnds[6];
+#endif /* SERGEEV */