Get rid of FORTRANisms.
[super-star-trek.git] / moving.c
index fae20ff504a56d0e1d7228881181174d3e755547..0c91f71cd33886e3f907c6adfd1db0ae8a329091 100644 (file)
--- a/moving.c
+++ b/moving.c
-#include "sst.h"\r
-\r
-static void getcd(int, int);\r
-\r
-void move(void) {\r
-       double angle, deltax, deltay, bigger, x, y,\r
-       finald, finalx, finaly, stopegy;\r
-       int trbeam = 0, n, l, ix, iy, kink, kinks, iquad;\r
-\r
-       if (inorbit) {\r
-               prout("SULU- \"Leaving standard orbit.\"");\r
-               inorbit = 0;\r
-       }\r
-\r
-       angle = ((15.0 - direc) * 0.5235988);\r
-       deltax = -sin(angle);\r
-       deltay = cos(angle);\r
-       if (fabs(deltax) > fabs(deltay))\r
-               bigger = fabs(deltax);\r
-       else\r
-               bigger = fabs(deltay);\r
-               \r
-       deltay /= bigger;\r
-       deltax /= bigger;\r
-\r
-       /* If tractor beam is to occur, don't move full distance */\r
-       if (d.date+Time >= future[FTBEAM]) {\r
-               trbeam = 1;\r
-               condit = IHRED;\r
-               dist = dist*(future[FTBEAM]-d.date)/Time + 0.1;\r
-               Time = future[FTBEAM] - d.date + 1e-5;\r
-       }\r
-       /* Move within the quadrant */\r
-       quad[sectx][secty] = IHDOT;\r
-       x = sectx;\r
-       y = secty;\r
-       n = 10.0*dist*bigger+0.5;\r
-\r
-       if (n > 0) {\r
-               for (l = 1; l <= n; l++) {\r
-                       ix = (x += deltax) + 0.5;\r
-                       iy = (y += deltay) + 0.5;\r
-                       if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {\r
-                               /* Leaving quadrant -- allow final enemy attack */\r
-                               /* Don't do it if being pushed by Nova */\r
-                               if (nenhere != 0 && iattak != 2) {\r
-                                       newcnd();\r
-                                       for (l = 1; l <= nenhere; l++) {\r
-                                               finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
-                                                                         (iy-ky[l])*(double)(iy-ky[l]));\r
-                                               kavgd[l] = 0.5 * (finald+kdist[l]);\r
-                                       }\r
-                                       if (d.galaxy[quadx][quady] != 1000) attack(0);\r
-                                       if (alldone) return;\r
-                               }\r
-                               /* compute final position -- new quadrant and sector */\r
-                               x = 10*(quadx-1)+sectx;\r
-                               y = 10*(quady-1)+secty;\r
-                               ix = x+10.0*dist*bigger*deltax+0.5;\r
-                               iy = y+10.0*dist*bigger*deltay+0.5;\r
-                               /* check for edge of galaxy */\r
-                               kinks = 0;\r
-                               do {\r
-                                       kink = 0;\r
-                                       if (ix <= 0) {\r
-                                               ix = -ix + 1;\r
-                                               kink = 1;\r
-                                       }\r
-                                       if (iy <= 0) {\r
-                                               iy = -iy + 1;\r
-                                               kink = 1;\r
-                                       }\r
-                                       if (ix > 80) {\r
-                                               ix = 161 - ix;\r
-                                               kink = 1;\r
-                                       }\r
-                                       if (iy > 80) {\r
-                                               iy = 161 - iy;\r
-                                               kink = 1;\r
-                                       }\r
-                                       if (kink) kinks = 1;\r
-                               } while (kink);\r
-\r
-                               if (kinks) {\r
-                                       nkinks += 1;\r
-                                       if (nkinks == 3) {\r
-                                               /* Three strikes -- you're out! */\r
-                                               finish(FNEG3);\r
-                                               return;\r
-                                       }\r
-                                       prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"\r
-                                                "AT THE EDGE OF THE GALAXY.  THE THIRD TIME YOU TRY THIS,\n"\r
-                                                "YOU WILL BE DESTROYED.\n");\r
-                               }\r
-                               /* Compute final position in new quadrant */\r
-                               if (trbeam) return; /* Don't bother if we are to be beamed */\r
-                               quadx = (ix+9)/10;\r
-                               quady = (iy+9)/10;\r
-                               sectx = ix - 10*(quadx-1);\r
-                               secty = iy - 10*(quady-1);\r
-                               proutn("\nEntering");\r
-                               cramlc(1, quadx, quady);\r
-                               skip(1);\r
-                               quad[sectx][secty] = ship;\r
-                               newqad(0);\r
-                               return;\r
-                       }\r
-                       iquad = quad[ix][iy];\r
-                       if (iquad != IHDOT) {\r
-                               /* object encountered in flight path */\r
-                               stopegy = 50.0*dist/Time;\r
-                               dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
-                                                         (secty-iy)*(double)(secty-iy));\r
-                               switch (iquad) {\r
-                                       case IHT: /* Ram a Tholean */\r
-                                       case IHK: /* Ram enemy ship */\r
-                                       case IHC:\r
-                                       case IHS:\r
-                                       case IHR:\r
-                                               sectx = ix;\r
-                                               secty = iy;\r
-                                               ram(0, iquad, sectx, secty);\r
-                                               finalx = sectx;\r
-                                               finaly = secty;\r
-                                               break;\r
-                                       case IHBLANK:\r
-                                               skip(1);\r
-                                               prouts("***RED ALERT!  RED ALERT!");\r
-                                               skip(1);\r
-                                               proutn("***");\r
-                                               crmshp();\r
-                                               proutn(" pulled into black hole at");\r
-                                               cramlc(2, ix, iy);\r
-                                               skip(1);\r
-                                               finish(FHOLE);\r
-                                               return;\r
-                                       default:\r
-                                               /* something else */\r
-                                               skip(1);\r
-                                               crmshp();\r
-                                               if (iquad == IHWEB)\r
-                                                       proutn(" encounters Tholian web at");\r
-                                               else\r
-                                                       proutn(" blocked by object at");\r
-                                               cramlc(2, ix,iy);\r
-                                               prout(";");\r
-                                               proutn("Emergency stop required ");\r
-                                               cramf(stopegy, 0, 2);\r
-                                               prout(" units of energy.");\r
-                                               energy -= stopegy;\r
-                                               finalx = x-deltax+0.5;\r
-                                               sectx = finalx;\r
-                                               finaly = y-deltay+0.5;\r
-                                               secty = finaly;\r
-                                               if (energy <= 0) {\r
-                                                       finish(FNRG);\r
-                                                       return;\r
-                                               }\r
-                                               break;\r
-                               }\r
-                               goto label100;  /* sorry! */\r
-                       }\r
-               }\r
-               dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
-                                               (secty-iy)*(double)(secty-iy));\r
-               sectx = ix;\r
-               secty = iy;\r
-       }\r
-       finalx = sectx;\r
-       finaly = secty;\r
-label100:\r
-       /* No quadrant change -- compute new avg enemy distances */\r
-       quad[sectx][secty] = ship;\r
-       if (nenhere) {\r
-               for (l = 1; l <= nenhere; l++) {\r
-                       finald = sqrt((ix-kx[l])*(double)(ix-kx[l]) +\r
-                                                 (iy-ky[l])*(double)(iy-ky[l]));\r
-                       kavgd[l] = 0.5 * (finald+kdist[l]);\r
-                       kdist[l] = finald;\r
-               }\r
-               sortkl();\r
-               if (d.galaxy[quadx][quady] != 1000 && iattak == 0)\r
-                       attack(0);\r
-               for (l = 1 ; l <= nenhere; l++) kavgd[l] = kdist[l];\r
-       }\r
-       newcnd();\r
-       iattak = 0;\r
-       return;\r
-}\r
-\r
-void dock(void) {\r
-       chew();\r
-       if (condit == IHDOCKED) {\r
-               prout("Already docked.");\r
-               return;\r
-       }\r
-       if (inorbit) {\r
-               prout("You must first leave standard orbit.");\r
-               return;\r
-       }\r
-       if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {\r
-               crmshp();\r
-               prout(" not adjacent to base.");\r
-               return;\r
-       }\r
-       condit = IHDOCKED;\r
-       prout("Docked.");\r
-       if (energy < inenrg) energy = inenrg;\r
-       shield = inshld;\r
-       torps = intorps;\r
-       lsupres = inlsr;\r
-       if (stdamtim != 1e30 &&\r
-               (future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {\r
-               /* get attack report from base */\r
-               prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");\r
-               attakreport();\r
-               iseenit = 1;\r
-       }\r
-}\r
-\r
-static void getcd(int isprobe, int akey) {\r
-       /* This program originally required input in terms of a (clock)\r
-          direction and distance. Somewhere in history, it was changed to\r
-          cartesian coordinates. So we need to convert. I think\r
-          "manual" input should still be done this way -- it's a real\r
-          pain if the computer isn't working! Manual mode is still confusing\r
-          because it involves giving x and y motions, yet the coordinates\r
-          are always displayed y - x, where +y is downward! */\r
-\r
-       \r
-       int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key;\r
-       double xi, xj, xk, xl;\r
-       double deltax, deltay;\r
-       int automatic = -1;\r
-\r
-       /* Get course direction and distance. If user types bad values, return\r
-          with DIREC = -1.0. */\r
-\r
-       direc = -1.0;\r
-       \r
-       if (landed == 1 && !isprobe) {\r
-               prout("Dummy! You can't leave standard orbit until you");\r
-               proutn("are back abourt the ");\r
-               crmshp();\r
-               prout(".");\r
-               chew();\r
-               return;\r
-       }\r
-       while (automatic == -1) {\r
-               if (damage[DCOMPTR]) {\r
-                       if (isprobe)\r
-                               prout("Computer damaged; manual navigation only");\r
-                       else\r
-                               prout("Computer damaged; manual movement only");\r
-                       chew();\r
-                       automatic = 0;\r
-                       key = IHEOL;\r
-                       break;\r
-               }\r
-               if (isprobe && akey != -1) {\r
-                       /* For probe launch, use pre-scaned value first time */\r
-                       key = akey;\r
-                       akey = -1;\r
-               }\r
-               else \r
-                       key = scan();\r
-\r
-               if (key == IHEOL) {\r
-                       proutn("Manual or automatic- ");\r
-                       iprompt = 1;\r
-                       chew();\r
-               }\r
-               else if (key == IHALPHA) {\r
-                       if (isit("manual")) {\r
-                               automatic =0;\r
-                               key = scan();\r
-                               break;\r
-                       }\r
-                       else if (isit("automatic")) {\r
-                               automatic = 1;\r
-                               key = scan();\r
-                               break;\r
-                       }\r
-                       else {\r
-                               huh();\r
-                               chew();\r
-                               return;\r
-                       }\r
-               }\r
-               else { /* numeric */\r
-                       if (isprobe)\r
-                               prout("(Manual navigation assumed.)");\r
-                       else\r
-                               prout("(Manual movement assumed.)");\r
-                       automatic = 0;\r
-                       break;\r
-               }\r
-       }\r
-\r
-       if (automatic) {\r
-               while (key == IHEOL) {\r
-                       if (isprobe)\r
-                               proutn("Target quadrant or quadrant&sector- ");\r
-                       else\r
-                               proutn("Destination sector or quadrant&sector- ");\r
-                       chew();\r
-                       iprompt = 1;\r
-                       key = scan();\r
-               }\r
-\r
-               if (key != IHREAL) {\r
-                       huh();\r
-                       return;\r
-               }\r
-               xi = aaitem;\r
-               key = scan();\r
-               if (key != IHREAL){\r
-                       huh();\r
-                       return;\r
-               }\r
-               xj = aaitem;\r
-               key = scan();\r
-               if (key == IHREAL) {\r
-                       /* both quadrant and sector specified */\r
-                       xk = aaitem;\r
-                       key = scan();\r
-                       if (key != IHREAL) {\r
-                               huh();\r
-                               return;\r
-                       }\r
-                       xl = aaitem;\r
-\r
-                       irowq = xi + 0.5;\r
-                       icolq = xj + 0.5;\r
-                       irows = xk + 0.5;\r
-                       icols = xl + 0.5;\r
-               }\r
-               else {\r
-                       if (isprobe) {\r
-                               /* only quadrant specified -- go to center of dest quad */\r
-                               irowq = xi + 0.5;\r
-                               icolq = xj + 0.5;\r
-                               irows = icols = 5;\r
-                       }\r
-                       else {\r
-                               irows = xi + 0.5;\r
-                               icols = xj + 0.5;\r
-                       }\r
-                       itemp = 1;\r
-               }\r
-               if (irowq<1 || irowq > 8 || icolq<1 || icolq > 8 ||\r
-                       irows<1 || irows > 10 || icols<1 || icols > 10) {\r
-                               huh();\r
-                               return;\r
-                       }\r
-               skip(1);\r
-               if (!isprobe) {\r
-                       if (itemp) {\r
-                               if (iprompt) {\r
-                                       proutn("Helmsman Sulu- \"Course locked in for");\r
-                                       cramlc(2, irows, icols);\r
-                                       prout(".\"");\r
-                               }\r
-                       }\r
-                       else prout("Ensign Chekov- \"Course laid in, Captain.\"");\r
-               }\r
-               deltax = icolq - quady + 0.1*(icols-secty);\r
-               deltay = quadx - irowq + 0.1*(sectx-irows);\r
-       }\r
-       else { /* manual */\r
-               while (key == IHEOL) {\r
-                       proutn("X and Y displacements- ");\r
-                       chew();\r
-                       iprompt = 1;\r
-                       key = scan();\r
-               }\r
-               itemp = 2;\r
-               if (key != IHREAL) {\r
-                       huh();\r
-                       return;\r
-               }\r
-               deltax = aaitem;\r
-               key = scan();\r
-               if (key != IHREAL) {\r
-                       huh();\r
-                       return;\r
-               }\r
-               deltay = aaitem;\r
-       }\r
-       /* Check for zero movement */\r
-       if (deltax == 0 && deltay == 0) {\r
-               chew();\r
-               return;\r
-       }\r
-       if (itemp == 2 && !isprobe) {\r
-               skip(1);\r
-               prout("Helmsman Sulu- \"Aye, Sir.\"");\r
-       }\r
-       dist = sqrt(deltax*deltax + deltay*deltay);\r
-       direc = atan2(deltax, deltay)*1.90985932;\r
-       if (direc < 0.0) direc += 12.0;\r
-       chew();\r
-       return;\r
-\r
-}\r
-               \r
-\r
-\r
-void impuls(void) {\r
-       double power;\r
-\r
-       ididit = 0;\r
-       if (damage[DIMPULS]) {\r
-               chew();\r
-               skip(1);\r
-               prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
-               return;\r
-       }\r
-\r
-       if (energy > 30.0) {\r
-               getcd(FALSE, 0);\r
-               if (direc == -1.0) return;\r
-               power = 20.0 + 100.0*dist;\r
-       }\r
-       else\r
-               power = 30.0;\r
-\r
-       if (power >= energy) {\r
-               /* Insufficient power for trip */\r
-               skip(1);\r
-               prout("First Officer Spock- \"Captain, the impulse engines");\r
-               prout("require 20.0 units to engage, plus 100.0 units per");\r
-               if (energy > 30) {\r
-                       proutn("quadrant.  We can go, therefore, a maximum of ");\r
-                       cramf(0.01 * (energy-20.0)-0.05, 0, 1);\r
-                       prout(" quadrants.\"");\r
-               }\r
-               else {\r
-                       prout("quadrant.  They are, therefore, useless.\"");\r
-               }\r
-               chew();\r
-               return;\r
-       }\r
-       /* Make sure enough time is left for the trip */\r
-       Time = dist/0.095;\r
-       if (Time >= d.remtime) {\r
-               prout("First Officer Spock- \"Captain, our speed under impulse");\r
-               prout("power is only 0.95 sectors per stardate. Are you sure");\r
-               prout("we dare spend the time?\"");\r
-               if (ja() == 0) return;\r
-       }\r
-       /* Activate impulse engines and pay the cost */\r
-       move();\r
-       ididit = 1;\r
-       if (alldone) return;\r
-       power = 20.0 + 100.0*dist;\r
-       energy -= power;\r
-       Time = dist/0.095;\r
-       if (energy <= 0) finish(FNRG);\r
-       return;\r
-}\r
-\r
-\r
-void warp(int i) {\r
-       int blooey=0, twarp=0, iwarp;\r
-       double power;\r
-\r
-       if (i!=2) { /* Not WARPX entry */\r
-               ididit = 0;\r
-               if (damage[DWARPEN] > 10.0) {\r
-                       chew();\r
-                       skip(1);\r
-                       prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
-                       return;\r
-               }\r
-               if (damage[DWARPEN] > 0.0 && warpfac > 4.0) {\r
-                       chew();\r
-                       skip(1);\r
-                       prout("Engineer Scott- \"Sorry, Captain. Until this damage");\r
-                       prout("  is repaired, I can only give you warp 4.\"");\r
-                       return;\r
-               }\r
-                       \r
-               /* Read in course and distance */\r
-               getcd(FALSE, 0);\r
-               if (direc == -1.0) return;\r
-\r
-               /* Make sure starship has enough energy for the trip */\r
-               power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);\r
-\r
-\r
-               if (power >= energy) {\r
-                       /* Insufficient power for trip */\r
-                       ididit = 0;\r
-                       skip(1);\r
-                       prout("Engineering to bridge--");\r
-                       if (shldup==0 || 0.5*power > energy) {\r
-                               iwarp = pow((energy/(dist+0.05)), 0.333333333);\r
-                               if (iwarp <= 0) {\r
-                                       prout("We can't do it, Captain. We haven't the energy.");\r
-                               }\r
-                               else {\r
-                                       proutn("We haven't the energy, but we could do it at warp ");\r
-                                       crami(iwarp, 1);\r
-                                       if (shldup)\r
-                                               prout(",\nif you'll lower the shields.");\r
-                                       else\r
-                                               prout(".");\r
-                               }\r
-                       }\r
-                       else\r
-                               prout("We haven't the energy to go that far with the shields up.");\r
-                       return;\r
-               }\r
-                                               \r
-               /* Make sure enough time is left for the trip */\r
-               Time = 10.0*dist/wfacsq;\r
-               if (Time >= 0.8*d.remtime) {\r
-                       skip(1);\r
-                       prout("First Officer Spock- \"Captain, I compute that such");\r
-                       proutn("  a trip would require approximately ");\r
-                       cramf(100.0*Time/d.remtime, 0, 2);\r
-                       prout(" percent of our");\r
-                       prout("  remaining time.  Are you sure this is wise?\"");\r
-                       if (ja() == 0) { ididit = 0; return;}\r
-               }\r
-       }\r
-       /* Entry WARPX */\r
-       if (warpfac > 6.0) {\r
-               /* Decide if engine damage will occur */\r
-               double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;\r
-               if (prob > Rand()) {\r
-                       blooey = 1;\r
-                       dist = Rand()*dist;\r
-               }\r
-               /* Decide if time warp will occur */\r
-               if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;\r
-#ifdef DEBUG\r
-               if (idebug &&warpfac==10 && twarp==0) {\r
-                       blooey=0;\r
-                       proutn("Force time warp? ");\r
-                       if (ja()==1) twarp=1;\r
-               }\r
-#endif\r
-               if (blooey || twarp) {\r
-                       /* If time warp or engine damage, check path */\r
-                       /* If it is obstructed, don't do warp or damage */\r
-                       double angle = ((15.0-direc)*0.5235998);\r
-                       double deltax = -sin(angle);\r
-                       double deltay = cos(angle);\r
-                       double bigger, x, y;\r
-                       int n, l, ix, iy;\r
-                       if (fabs(deltax) > fabs(deltay))\r
-                               bigger = fabs(deltax);\r
-                       else\r
-                               bigger = fabs(deltay);\r
-                       \r
-                       deltax /= bigger;\r
-                       deltay /= bigger;\r
-                       n = 10.0 * dist * bigger +0.5;\r
-                       x = sectx;\r
-                       y = secty;\r
-                       for (l = 1; l <= n; l++) {\r
-                               x += deltax;\r
-                               ix = x + 0.5;\r
-                               if (ix < 1 || ix > 10) break;\r
-                               y += deltay;\r
-                               iy = y +0.5;\r
-                               if (iy < 1 || iy > 10) break;\r
-                               if (quad[ix][iy] != IHDOT) {\r
-                                       blooey = 0;\r
-                                       twarp = 0;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-                               \r
-\r
-       /* Activate Warp Engines and pay the cost */\r
-       move();\r
-       if (alldone) return;\r
-       energy -= dist*warpfac*warpfac*warpfac*(shldup+1);\r
-       if (energy <= 0) finish(FNRG);\r
-       Time = 10.0*dist/wfacsq;\r
-       if (twarp) timwrp();\r
-       if (blooey) {\r
-               damage[DWARPEN] = damfac*(3.0*Rand()+1.0);\r
-               skip(1);\r
-               prout("Engineering to bridge--");\r
-               prout("  Scott here.  The warp engines are damaged.");\r
-               prout("  We'll have to reduce speed to warp 4.");\r
-       }\r
-       ididit = 1;\r
-       return;\r
-}\r
-\r
-\r
-\r
-void setwrp(void) {\r
-       int key;\r
-       double oldfac;\r
-       \r
-       while ((key=scan()) == IHEOL) {\r
-               chew();\r
-               proutn("Warp factor-");\r
-       }\r
-       chew();\r
-       if (key != IHREAL) {\r
-               huh();\r
-               return;\r
-       }\r
-       if (damage[DWARPEN] > 10.0) {\r
-               prout("Warp engines inoperative.");\r
-               return;\r
-       }\r
-       if (damage[DWARPEN] > 0.0 && aaitem > 4.0) {\r
-               prout("Engineer Scott- \"I'm doing my best, Captain,\n"\r
-                         "  but right now we can only go warp 4.\"");\r
-               return;\r
-       }\r
-       if (aaitem > 10.0) {\r
-               prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");\r
-               return;\r
-       }\r
-       if (aaitem < 1.0) {\r
-               prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");\r
-               return;\r
-       }\r
-       oldfac = warpfac;\r
-       warpfac = aaitem;\r
-       wfacsq=warpfac*warpfac;\r
-       if (warpfac <= oldfac || warpfac <= 6.0) {\r
-               proutn("Helmsman Sulu- \"Warp factor ");\r
-               cramf(warpfac, 0, 1);\r
-               prout(", Captain.\"");\r
-               return;\r
-       }\r
-       if (warpfac < 8.00) {\r
-               prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");\r
-               return;\r
-       }\r
-       if (warpfac == 10.0) {\r
-               prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");\r
-               return;\r
-       }\r
-       prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");\r
-       return;\r
-}\r
-\r
-void atover(int igrab) {\r
-       double power, distreq;\r
-\r
-       chew();\r
-       /* is captain on planet? */\r
-       if (landed==1) {\r
-               if (damage[DTRANSP]) {\r
-                       finish(FPNOVA);\r
-                       return;\r
-               }\r
-               prout("Scotty rushes to the transporter controls.");\r
-               if (shldup) {\r
-                       prout("But with the shields up it's hopeless.");\r
-                       finish(FPNOVA);\r
-               }\r
-               prouts("His desperate attempt to rescue you . . .");\r
-               if (Rand() <= 0.5) {\r
-                       prout("fails.");\r
-                       finish(FPNOVA);\r
-                       return;\r
-               }\r
-               prout("SUCCEEDS!");\r
-               if (imine) {\r
-                       imine = 0;\r
-                       proutn("The crystals mined were ");\r
-                       if (Rand() <= 0.25) {\r
-                               prout("lost.");\r
-                       }\r
-                       else {\r
-                               prout("saved.");\r
-                               icrystl = 1;\r
-                       }\r
-               }\r
-       }\r
-       if (igrab) return;\r
-\r
-       /* Check to see if captain in shuttle craft */\r
-       if (icraft) finish(FSTRACTOR);\r
-       if (alldone) return;\r
-\r
-       /* Inform captain of attempt to reach safety */\r
-       skip(1);\r
-       do {\r
-               if (justin) {\r
-                       prouts("***RED ALERT!  READ ALERT!");\r
-                       skip(1);\r
-                       proutn("The ");\r
-                       crmshp();\r
-                       prout(" has stopped in a quadrant containing");\r
-                       prouts("   a supernova.");\r
-                       skip(2);\r
-               }\r
-               proutn("***Emergency automatic override attempts to hurl ");\r
-               crmshp();\r
-               skip(1);\r
-               prout("safely out of quadrant.");\r
-               starch[quadx][quady] = damage[DRADIO] > 0.0 ? d.galaxy[quadx][quady]+1000:1;\r
-\r
-               /* Try to use warp engines */\r
-               if (damage[DWARPEN]) {\r
-                       skip(1);\r
-                       prout("Warp engines damaged.");\r
-                       finish(FSNOVAED);\r
-                       return;\r
-               }\r
-               warpfac = 6.0+2.0*Rand();\r
-               wfacsq = warpfac * warpfac;\r
-               proutn("Warp factor set to ");\r
-               cramf(warpfac, 1, 1);\r
-               skip(1);\r
-               power = 0.75*energy;\r
-               dist = power/(warpfac*warpfac*warpfac*(shldup+1));\r
-               distreq = 1.4142+Rand();\r
-               if (distreq < dist) dist = distreq;\r
-               Time = 10.0*dist/wfacsq;\r
-               direc = 12.0*Rand();    /* How dumb! */\r
-               justin = 0;\r
-               inorbit = 0;\r
-               warp(2);\r
-               if (justin == 0) {\r
-                       /* This is bad news, we didn't leave quadrant. */\r
-                       if (alldone) return;\r
-                       skip(1);\r
-                       prout("Insufficient energy to leave quadrant.");\r
-                       finish(FSNOVAED);\r
-                       return;\r
-               }\r
-               /* Repeat if another snova */\r
-       } while (d.galaxy[quadx][quady] == 1000);\r
-       if (d.remkl==0) finish(FWON); /* Snova killed remaining enemy. */\r
-}\r
-\r
-void timwrp() {\r
-       int l, ll, gotit;\r
-       prout("***TIME WARP ENTERED.");\r
-       if (d.snap && Rand() < 0.5) {\r
-               /* Go back in time */\r
-               proutn("You are traveling backwards in time ");\r
-               cramf(d.date-snapsht.date, 0, 2);\r
-               prout(" stardates.");\r
-               d = snapsht;\r
-               d.snap = 0;\r
-               if (d.remcom) {\r
-                       future[FTBEAM] = d.date + expran(intime/d.remcom);\r
-                       future[FBATTAK] = d.date + expran(0.3*intime);\r
-               }\r
-               future[FSNOVA] = d.date + expran(0.5*intime);\r
-               future[FSNAP] = d.date +expran(0.25*d.remtime); /* next snapshot will\r
-                                                                                                          be sooner */\r
-               if (d.nscrem) future[FSCMOVE] = 0.2777;\r
-               isatb = 0;\r
-               future[FCDBAS] = future[FSCDBAS] = 1e30;\r
-               batx = baty = 0;\r
-\r
-               /* Make sure Galileo is consistant -- Snapshot may have been taken\r
-                  when on planet, which would give us two Galileos! */\r
-               gotit = 0;\r
-               for (l = 1; l <= inplan; l++) {\r
-                       if (d.plnets[l].known == 2) {\r
-                               gotit = 1;\r
-                               if (iscraft==1 && ship==IHE) {\r
-                                       prout("Checkov-  \"Security reports the Galileo has disappeared, Sir!");\r
-                                       iscraft = 0;\r
-                               }\r
-                       }\r
-               }\r
-               /* Likewise, if in the original time the Galileo was abandoned, but\r
-                  was on ship earlier, it would have vanished -- lets restore it */\r
-               if (iscraft==0 && gotit==0 && damage[DSHUTTL] >= 0.0) {\r
-                       prout("Checkov-  \"Security reports the Galileo has reappeared in the dock!\"");\r
-                       iscraft = 1;\r
-               }\r
-\r
-               /* Revert star chart to earlier era, if it was known then*/\r
-               if (damage[DRADIO]==0.0 || stdamtim > d.date) {\r
-                       for (l = 1; l <= 8; l++)\r
-                               for (ll = 1; ll <= 8; ll++)\r
-                                       if (starch[l][ll] > 1)\r
-                                               starch[l][ll]=damage[DRADIO]>0.0 ? d.galaxy[l][ll]+1000 :1;\r
-                       prout("Spock has reconstructed a correct star chart from memory");\r
-                       if (damage[DRADIO] > 0.0) stdamtim = d.date;\r
-               }\r
-       }\r
-       else {\r
-               /* Go forward in time */\r
-               Time = -0.5*intime*log(Rand());\r
-               proutn("You are traveling forward in time ");\r
-               cramf(Time, 1, 2);\r
-               prout(" stardates.");\r
-               /* cheat to make sure no tractor beams occur during time warp */\r
-               future[FTBEAM] += Time;\r
-               damage[DRADIO] += Time;\r
-       }\r
-       newqad(0);\r
-}\r
-\r
-void probe(void) {\r
-       double angle, bigger;\r
-       int key;\r
-       /* New code to launch a deep space probe */\r
-       if (nprobes == 0) {\r
-               chew();\r
-               skip(1);\r
-               if (ship == IHE) \r
-                       prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");\r
-               else\r
-                       prout("Ye Faerie Queene has no deep space probes.");\r
-               return;\r
-       }\r
-       if (damage[DDSP] != 0.0) {\r
-               chew();\r
-               skip(1);\r
-               prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");\r
-               return;\r
-       }\r
-       if (future[FDSPROB] != 1e30) {\r
-               chew();\r
-               skip(1);\r
-               if (damage[DRADIO] != 0 && condit != IHDOCKED) {\r
-                       prout("Spock-  \"Records show the previous probe has not yet");\r
-                       prout("   reached it's destination.\"");\r
-               }\r
-               else\r
-                       prout("Uhura- \"The previous probe is still reporting data, Sir.\"");\r
-               return;\r
-       }\r
-       key = scan();\r
-\r
-       if (key == IHEOL) {\r
-               /* slow mode, so let Kirk know how many probes there are left */\r
-               crami(nprobes,1);\r
-               prout(nprobes==1 ? " probe left." : " probes left.");\r
-               proutn("Are you sure you want to fire a probe? ");\r
-               if (ja()==0) return;\r
-       }\r
-\r
-       isarmed = FALSE;\r
-       if (key == IHALPHA && strcmp(citem,"armed") == 0) {\r
-               isarmed = TRUE;\r
-               key = scan();\r
-       }\r
-       else if (key == IHEOL) {\r
-               proutn("Arm NOVAMAX warhead?");\r
-               isarmed = ja();\r
-       }\r
-       getcd(TRUE, key);\r
-       if (direc == -1.0) return;\r
-       nprobes--;\r
-               angle = ((15.0 - direc) * 0.5235988);\r
-       probeinx = -sin(angle);\r
-       probeiny = cos(angle);\r
-       if (fabs(probeinx) > fabs(probeiny))\r
-               bigger = fabs(probeinx);\r
-       else\r
-               bigger = fabs(probeiny);\r
-               \r
-       probeiny /= bigger;\r
-       probeinx /= bigger;\r
-       proben = 10.0*dist*bigger +0.5;\r
-       probex = quadx*10 + sectx - 1;  // We will use better packing than original\r
-       probey = quady*10 + secty - 1;\r
-       probecx = quadx;\r
-       probecy = quady;\r
-       future[FDSPROB] = d.date + 0.01; // Time to move one sector\r
-       prout("Ensign Chekov-  \"The deep space probe is launched, Captain.\"");\r
-       return;\r
-}\r
-\r
-void help(void) {\r
-       /* There's more than one way to move in this game! */\r
-       double ddist, xdist, probf;\r
-       int line, l, ix, iy;\r
-\r
-       chew();\r
-       /* Test for conditions which prevent calling for help */\r
-       if (condit == IHDOCKED) {\r
-               prout("Lt. Uhura-  \"But Captain, we're already docked.\"");\r
-               return;\r
-       }\r
-       if (damage[DRADIO] != 0) {\r
-               prout("Subspace radio damaged.");\r
-               return;\r
-       }\r
-       if (d.rembase==0) {\r
-               prout("Lt. Uhura-  \"Captain, I'm not getting any response from Starbase.\"");\r
-               return;\r
-       }\r
-       if (landed == 1) {\r
-               proutn("You must be aboard the ");\r
-               crmshp();\r
-               prout(".");\r
-               return;\r
-       }\r
-       /* OK -- call for help from nearest starbase */\r
-       nhelp++;\r
-       if (basex!=0) {\r
-               /* There's one in this quadrant */\r
-               ddist = sqrt(square(basex-sectx)+square(basey-secty));\r
-       }\r
-       else {\r
-               ddist = 1e30;\r
-               for (l = 1; l <= d.rembase; l++) {\r
-                       xdist=10.0*sqrt(square(d.baseqx[l]-quadx)+square(d.baseqy[l]-quady));\r
-                       if (xdist < ddist) {\r
-                               ddist = xdist;\r
-                               line = l;\r
-                       }\r
-               }\r
-               /* Since starbase not in quadrant, set up new quadrant */\r
-               quadx = d.baseqx[line];\r
-               quady = d.baseqy[line];\r
-               newqad(1);\r
-       }\r
-       /* dematerialize starship */\r
-       quad[sectx][secty]=IHDOT;\r
-       proutn("Starbase in");\r
-       cramlc(1, quadx, quady);\r
-       proutn(" responds--");\r
-       crmshp();\r
-       prout(" dematerializes.");\r
-       /* Give starbase three chances to rematerialize starship */\r
-       probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);\r
-       for (l = 1; l <= 3; l++) {\r
-               switch (l) {\r
-                       case 1: proutn("1st"); break;\r
-                       case 2: proutn("2nd"); break;\r
-                       case 3: proutn("3rd"); break;\r
-               }\r
-               proutn(" attempt to re-materialize ");\r
-               crmshp();\r
-               prouts(" . . . . . ");\r
-               if (Rand() > probf) break;\r
-               prout("fails.");\r
-       }\r
-       if (l > 3) {\r
-               finish(FMATERIALIZE);\r
-               return;\r
-       }\r
-       /* Rematerialization attempt should succeed if can get adj to base */\r
-       for (l = 1; l <= 5; l++) {\r
-               ix = basex+3.0*Rand()-1;\r
-               iy = basey+3.0*Rand()-1;\r
-               if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && quad[ix][iy]==IHDOT) {\r
-                       /* found one -- finish up */\r
-                       prout("succeeds.");\r
-                       sectx=ix;\r
-                       secty=iy;\r
-                       quad[ix][iy]=ship;\r
-                       dock();\r
-                       skip(1);\r
-                       prout("Lt. Uhura-  \"Captain, we made it!\"");\r
-                       return;\r
-               }\r
-       }\r
-       finish(FMATERIALIZE);\r
-       return;\r
-}\r
+#include <unistd.h>
+#include "sstlinux.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 = FALSE;
+    }
+
+    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 > QUADSIZE || iy < 1 || iy > QUADSIZE) {
+               /* 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]);
+                   }
+                   /*
+                    * Stas Sergeev added the condition
+                    * that attacks only happen if Klingons
+                    * are present and your skill is good.
+                    */
+                   if (skill > SKILL_GOOD && klhere > 0 && game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE)
+                       attack(0);
+                   if (alldone) return;
+               }
+               /* compute final position -- new quadrant and sector */
+               x = QUADSIZE*(quadx-1)+sectx;
+               y = QUADSIZE*(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 > GALSIZE*QUADSIZE) {
+                       ix = (GALSIZE*QUADSIZE*2)+1 - ix;
+                       kink = 1;
+                   }
+                   if (iy > GALSIZE*QUADSIZE) {
+                       iy = (GALSIZE*QUADSIZE*2)+1 - 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("\n\rYOU 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");
+               }
+               /* Compute final position in new quadrant */
+               if (trbeam) return; /* Don't bother if we are to be beamed */
+               quadx = (ix+(QUADSIZE-1))/QUADSIZE;
+               quady = (iy+(QUADSIZE-1))/QUADSIZE;
+               sectx = ix - QUADSIZE*(quadx-1);
+               secty = iy - QUADSIZE*(quady-1);
+               prout("\n\rEntering %s.",
+                     cramlc(quadrant, quadx, quady));
+               game.quad[sectx][secty] = ship;
+               newqad(0);
+               if (skill>SKILL_NOVICE) 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 no_quad_change;    /* sorry! */
+           }
+       }
+       dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +
+                       (secty-iy)*(double)(secty-iy));
+       sectx = ix;
+       secty = iy;
+    }
+    finalx = sectx;
+    finaly = secty;
+no_quad_change:
+    /* 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] != SUPERNOVA_PLACE && iattak == 0)
+           attack(0);
+       for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];
+    }
+    newcnd();
+    iattak = 0;
+    drawmaps(0);
+    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 > GALSIZE || icolq<1 || icolq > GALSIZE ||
+                       irows<1 || irows > QUADSIZE || icols<1 || icols > QUADSIZE) {
+                               huh();
+                               return;
+                       }
+               skip(1);
+               if (!isprobe) {
+                       if (itemp) {
+                               if (iprompt) {
+                                       prout("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 > QUADSIZE) break;
+               y += deltay;
+               iy = y +0.5;
+               if (iy < 1 || iy > QUADSIZE) 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]+SUPERNOVA_PLACE: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] == SUPERNOVA_PLACE);
+    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 <= GALSIZE; l++)
+               for (ll = 1; ll <= GALSIZE; ll++)
+                   if (game.starch[l][ll] > 1)
+                       game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+SUPERNOVA_PLACE :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);
+    events();  /* Stas Sergeev added this -- do pending events */
+}
+
+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*QUADSIZE + sectx - 1;       // We will use better packing than original
+    probey = quady*QUADSIZE + 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;
+
+    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.");
+    sectx=0;
+    for (l = 1; l <= 5; l++) {
+       ix = basex+3.0*Rand()-1;
+       iy = basey+3.0*Rand()-1;
+       if (ix>=1 && ix<=QUADSIZE && iy>=1 && iy<=QUADSIZE && 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;
+    }
+    /* 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();
+       warble();
+       if (Rand() > probf) break;
+       switch (l){
+       case 1: game.quad[ix][iy]=IHMATER1;
+           break;
+       case 2: game.quad[ix][iy]=IHMATER2;
+           break;
+       case 3: game.quad[ix][iy]=IHQUEST;
+           break;
+       }
+       textcolor(RED);
+       prout("fails.");
+       delay(500);
+       textcolor(DEFAULT);
+    }
+    if (l > 3) {
+       finish(FMATERIALIZE);
+       return;
+    }
+    game.quad[ix][iy]=ship;
+    textcolor(GREEN);
+    prout("succeeds.");
+    textcolor(DEFAULT);
+    dock(0);
+    skip(1);
+    prout("Lt. Uhura-  \"Captain, we made it!\"");
+}