-#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("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 (state.date+Time >= future[FTBEAM]) {\r
- trbeam = 1;\r
- condit = IHRED;\r
- dist = dist*(future[FTBEAM]-state.date)/Time + 0.1;\r
- Time = future[FTBEAM] - state.date + 1e-5;\r
- }\r
- /* Move within the quadrant */\r
- frozen.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 (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("\nEntering");\r
- cramlc(1, quadx, quady);\r
- skip(1);\r
- frozen.quad[sectx][secty] = ship;\r
- newqad(0);\r
- return;\r
- }\r
- iquad = frozen.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
- 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
- frozen.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 (state.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§or- ");\r
- else\r
- proutn("Destination sector or quadrant§or- ");\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 >= 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
- 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*state.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/state.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 (frozen.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 ? state.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 (state.galaxy[quadx][quady] == 1000);\r
- if (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 (state.snap && Rand() < 0.5) {\r
- /* Go back in time */\r
- proutn("You are traveling backwards in time ");\r
- cramf(state.date-snapsht.date, 0, 2);\r
- prout(" stardates.");\r
- state = snapsht;\r
- state.snap = 0;\r
- if (state.remcom) {\r
- future[FTBEAM] = state.date + expran(intime/state.remcom);\r
- future[FBATTAK] = state.date + expran(0.3*intime);\r
- }\r
- future[FSNOVA] = state.date + expran(0.5*intime);\r
- future[FSNAP] = state.date +expran(0.25*state.remtime); /* next snapshot will\r
- be sooner */\r
- if (state.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 (state.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 > state.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 ? state.galaxy[l][ll]+1000 :1;\r
- prout("Spock has reconstructed a correct star chart from memory");\r
- if (damage[DRADIO] > 0.0) stdamtim = state.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 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
- 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] = state.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 (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 <= state.rembase; l++) {\r
- xdist=10.0*sqrt(square(state.baseqx[l]-quadx)+square(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 = state.baseqx[line];\r
- quady = state.baseqy[line];\r
- newqad(1);\r
- }\r
- /* dematerialize starship */\r
- frozen.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 && frozen.quad[ix][iy]==IHDOT) {\r
- /* found one -- finish up */\r
- prout("succeeds.");\r
- sectx=ix;\r
- secty=iy;\r
- frozen.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 "conio.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]);
+ }
+ /*
+ * Stas Sergeev added the condition
+ * that attacks only happen if Klingons
+ * are present and your skill is > 3.
+ */
+ if (skill > 3 && klhere > 0 && 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("\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+9)/10;
+ quady = (iy+9)/10;
+ sectx = ix - 10*(quadx-1);
+ secty = iy - 10*(quady-1);
+ prout("\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;
+ 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§or- ");
+ else
+ proutn("Destination sector or quadrant§or- ");
+ 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) {
+ 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 > 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);
+ 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*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;
+
+ 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<=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;
+ }
+ /* 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(LIGHTGRAY);
+ }
+ if (l > 3) {
+ finish(FMATERIALIZE);
+ return;
+ }
+ game.quad[ix][iy]=ship;
+ textcolor(WHITE);
+ prout("succeeds.");
+ textcolor(LIGHTGRAY);
+ dock(0);
+ skip(1);
+ prout("Lt. Uhura- \"Captain, we made it!\"");
+}