-#include "sst.h"\r
-\r
-static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {\r
- int iqx, iqy, l;\r
-\r
- iqx = quadx+(lookx+9)/10 - 1;\r
- iqy = quady+(looky+9)/10 - 1;\r
- if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
- game.state.galaxy[iqx][iqy] > 899)\r
- return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */\r
- if (ienm == IHR) return 0; /* Romulans cannot escape! */\r
- if (irun == 0) {\r
- /* avoid intruding on another commander's territory */\r
- if (ienm == IHC) {\r
- for (l = 1; l <= game.state.remcom; l++)\r
- if (game.state.cx[l]==iqx && game.state.cy[l]==iqy) return 0;\r
- /* refuse to leave if currently attacking starbase */\r
- if (batx==quadx && baty==quady) return 0;\r
- }\r
- /* don't leave if over 1000 units of energy */\r
- if (game.kpower[loccom] > 1000.) return 0;\r
- }\r
- /* print escape message and move out of quadrant.\r
- We know this if either short or long range sensors are working */\r
- if (game.damage[DSRSENS] == 0.0 || game.damage[DLRSENS] == 0.0 ||\r
- condit == IHDOCKED) {\r
- crmena(1, ienm, 2, game.kx[loccom], game.ky[loccom]);\r
- proutn(" escapes to %s (and regains strength).",\r
- cramlc(quadrant, iqx, iqy));\r
- }\r
- /* handle local matters related to escape */\r
- game.quad[game.kx[loccom]][game.ky[loccom]] = IHDOT;\r
- game.kx[loccom] = game.kx[nenhere];\r
- game.ky[loccom] = game.ky[nenhere];\r
- game.kavgd[loccom] = game.kavgd[nenhere];\r
- game.kpower[loccom] = game.kpower[nenhere];\r
- game.kdist[loccom] = game.kdist[nenhere];\r
- klhere--;\r
- nenhere--;\r
- if (condit != IHDOCKED) newcnd();\r
- /* Handle global matters related to escape */\r
- game.state.galaxy[quadx][quady] -= 100;\r
- game.state.galaxy[iqx][iqy] += 100;\r
- if (ienm==IHS) {\r
- ishere=0;\r
- iscate=0;\r
- ientesc=0;\r
- isatb=0;\r
- game.future[FSCMOVE]=0.2777+game.state.date;\r
- game.future[FSCDBAS]=1e30;\r
- game.state.isx=iqx;\r
- game.state.isy=iqy;\r
- }\r
- else {\r
- for (l=1; l<=game.state.remcom; l++) {\r
- if (game.state.cx[l]==quadx && game.state.cy[l]==quady) {\r
- game.state.cx[l]=iqx;\r
- game.state.cy[l]=iqy;\r
- break;\r
- }\r
- }\r
- comhere = 0;\r
- }\r
- return 1; /* success */\r
-}\r
-\r
-\r
-static void movebaddy(int comx, int comy, int loccom, int ienm) {\r
- int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;\r
- int irun = 0;\r
- int krawlx, krawly;\r
- int success;\r
- int attempts;\r
- /* This should probably be just comhere + ishere */\r
- int nbaddys = skill > 3 ?\r
- (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):\r
- (comhere + ishere);\r
- double dist1, forces;\r
-\r
- dist1 = game.kdist[loccom];\r
- mdist = dist1 + 0.5; /* Nearest integer distance */\r
-\r
- /* If SC, check with spy to see if should hi-tail it */\r
- if (ienm==IHS &&\r
- (game.kpower[loccom] <= 500.0 || (condit==IHDOCKED && game.damage[DPHOTON]==0))) {\r
- irun = 1;\r
- motion = -10;\r
- }\r
- else {\r
- /* decide whether to advance, retreat, or hold position */\r
-/* Algorithm:\r
- * Enterprise has "force" based on condition of phaser and photon torpedoes.\r
- If both are operating full strength, force is 1000. If both are damaged,\r
- force is -1000. Having shields down subtracts an additional 1000.\r
-\r
- * Enemy has forces equal to the energy of the attacker plus\r
- 100*(K+R) + 500*(C+S) - 400 for novice through good levels OR\r
- 346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.\r
-\r
- Attacker Initial energy levels (nominal):\r
- Klingon Romulan Commander Super-Commander\r
- Novice 400 700 1200 \r
- Fair 425 750 1250\r
- Good 450 800 1300 1750\r
- Expert 475 850 1350 1875\r
- Emeritus 500 900 1400 2000\r
- VARIANCE 75 200 200 200\r
-\r
- Enemy vessels only move prior to their attack. In Novice - Good games\r
- only commanders move. In Expert games, all enemy vessels move if there\r
- is a commander present. In Emeritus games all enemy vessels move.\r
-\r
- * If Enterprise is not docked, an agressive action is taken if enemy\r
- forces are 1000 greater than Enterprise.\r
-\r
- Agressive action on average cuts the distance between the ship and\r
- the enemy to 1/4 the original.\r
-\r
- * At lower energy advantage, movement units are proportional to the\r
- advantage with a 650 advantage being to hold ground, 800 to move forward\r
- 1, 950 for two, 150 for back 4, etc. Variance of 100.\r
-\r
- If docked, is reduced by roughly 1.75*skill, generally forcing a\r
- retreat, especially at high skill levels.\r
-\r
- * Motion is limited to skill level, except for SC hi-tailing it out.\r
- */\r
-\r
- forces = game.kpower[loccom]+100.0*nenhere+400*(nbaddys-1);\r
- if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */\r
- if (game.damage[DPHASER] == 0.0 || game.damage[DPHOTON] == 0.0) {\r
- if (game.damage[DPHASER] != 0) /* phasers damaged */\r
- forces += 300.0;\r
- else\r
- forces -= 0.2*(energy - 2500.0);\r
- if (game.damage[DPHOTON] != 0) /* photon torpedoes damaged */\r
- forces += 300.0;\r
- else\r
- forces -= 50.0*torps;\r
- }\r
- else {\r
- /* phasers and photon tubes both out! */\r
- forces += 1000.0;\r
- }\r
- motion = 0;\r
- if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */\r
- motion = ((forces+200.0*Rand())/150.0) - 5.0;\r
- else {\r
- if (forces > 1000.0) /* Very strong -- move in for kill */\r
- motion = (1.0-square(Rand()))*dist1 + 1.0;\r
- if (condit==IHDOCKED) /* protected by base -- back off ! */\r
- motion -= skill*(2.0-square(Rand()));\r
- }\r
-#ifdef DEBUG\r
- if (idebug) {\r
- proutn("MOTION = %1.2f", motion);\r
- proutn(" FORCES = %1,2f", forces);\r
- }\r
-#endif\r
- /* don't move if no motion */\r
- if (motion==0) return;\r
- /* Limit motion according to skill */\r
- if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;\r
- }\r
- /* calcuate preferred number of steps */\r
- nsteps = motion < 0 ? -motion : motion;\r
- if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */\r
- if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */\r
- if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */\r
-#ifdef DEBUG\r
- if (idebug) {\r
- prout("NSTEPS = %d", nsteps);\r
- }\r
-#endif\r
- /* Compute preferred values of delta X and Y */\r
- mx = sectx - comx;\r
- my = secty - comy;\r
- if (2.0 * abs(mx) < abs(my)) mx = 0;\r
- if (2.0 * abs(my) < abs(sectx-comx)) my = 0;\r
- if (mx != 0) mx = mx*motion < 0 ? -1 : 1;\r
- if (my != 0) my = my*motion < 0 ? -1 : 1;\r
- nextx = comx;\r
- nexty = comy;\r
- /* main move loop */\r
- for (ll = 1; ll <= nsteps; ll++) {\r
-#ifdef DEBUG\r
- if (idebug) {\r
- prout("%d", ll);\r
- }\r
-#endif\r
- /* Check if preferred position available */\r
- lookx = nextx + mx;\r
- looky = nexty + my;\r
- krawlx = mx < 0 ? 1 : -1;\r
- krawly = my < 0 ? 1 : -1;\r
- success = 0;\r
- attempts = 0; /* Settle mysterious hang problem */\r
- while (attempts++ < 20 && !success) {\r
- if (lookx < 1 || lookx > 10) {\r
- if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
- return;\r
- if (krawlx == mx || my == 0) break;\r
- lookx = nextx + krawlx;\r
- krawlx = -krawlx;\r
- }\r
- else if (looky < 1 || looky > 10) {\r
- if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))\r
- return;\r
- if (krawly == my || mx == 0) break;\r
- looky = nexty + krawly;\r
- krawly = -krawly;\r
- }\r
- else if (game.quad[lookx][looky] != IHDOT) {\r
- /* See if we should ram ship */\r
- if (game.quad[lookx][looky] == ship &&\r
- (ienm == IHC || ienm == IHS)) {\r
- ram(1, ienm, comx, comy);\r
- return;\r
- }\r
- if (krawlx != mx && my != 0) {\r
- lookx = nextx + krawlx;\r
- krawlx = -krawlx;\r
- }\r
- else if (krawly != my && mx != 0) {\r
- looky = nexty + krawly;\r
- krawly = -krawly;\r
- }\r
- else break; /* we have failed */\r
- }\r
- else success = 1;\r
- }\r
- if (success) {\r
- nextx = lookx;\r
- nexty = looky;\r
-#ifdef DEBUG\r
- if (idebug) {\r
- prout(cramlc(neither, nextx, nexty));\r
- }\r
-#endif\r
- }\r
- else break; /* done early */\r
- }\r
- /* Put commander in place within same quadrant */\r
- game.quad[comx][comy] = IHDOT;\r
- game.quad[nextx][nexty] = ienm;\r
- if (nextx != comx || nexty != comy) {\r
- /* it moved */\r
- game.kx[loccom] = nextx;\r
- game.ky[loccom] = nexty;\r
- game.kdist[loccom] = game.kavgd[loccom] =\r
- sqrt(square(sectx-nextx)+square(secty-nexty));\r
- if (game.damage[DSRSENS] == 0 || condit == IHDOCKED) {\r
- proutn("***");\r
- cramen(ienm);\r
- proutn(" from");\r
- cramlc(2, comx, comy);\r
- if (game.kdist[loccom] < dist1) proutn(" advances to");\r
- else proutn(" retreats to ");\r
- prout(cramlc(sector, nextx, nexty));\r
- }\r
- }\r
-}\r
-\r
-void movcom(void) {\r
- int ix, iy, i;\r
-\r
-#ifdef DEBUG\r
- if (idebug) prout("MOVCOM");\r
-#endif\r
-\r
- /* Figure out which Klingon is the commander (or Supercommander)\r
- and do move */\r
- if (comhere) for (i = 1; i <= nenhere; i++) {\r
- ix = game.kx[i];\r
- iy = game.ky[i];\r
- if (game.quad[ix][iy] == IHC) {\r
- movebaddy(ix, iy, i, IHC);\r
- break;\r
- }\r
- }\r
- if (ishere) for (i = 1; i <= nenhere; i++) {\r
- ix = game.kx[i];\r
- iy = game.ky[i];\r
- if (game.quad[ix][iy] == IHS) {\r
- movebaddy(ix, iy, i, IHS);\r
- break;\r
- }\r
- }\r
- /* if skill level is high, move other Klingons and Romulans too!\r
- Move these last so they can base their actions on what the\r
- commander(s) do. */\r
- if (skill > 3) for (i = 1; i <= nenhere; i++) {\r
- ix = game.kx[i];\r
- iy = game.ky[i];\r
- if (game.quad[ix][iy] == IHK || game.quad[ix][iy] == IHR)\r
- movebaddy(ix, iy, i, game.quad[ix][iy]);\r
- }\r
-\r
- sortkl();\r
-}\r
-\r
-static int movescom(int iqx, int iqy, int flag, int *ipage) {\r
- int i;\r
-\r
- if ((iqx==quadx && iqy==quady) ||\r
- iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||\r
- game.state.galaxy[iqx][iqy] > 899) return 1;\r
- if (flag) {\r
- /* Avoid quadrants with bases if we want to avoid Enterprise */\r
- for (i = 1; i <= game.state.rembase; i++)\r
- if (game.state.baseqx[i]==iqx && game.state.baseqy[i]==iqy) return 1;\r
- }\r
- if (justin && !iscate) return 1;\r
- /* do the move */\r
- game.state.galaxy[game.state.isx][game.state.isy] -= 100;\r
- game.state.isx = iqx;\r
- game.state.isy = iqy;\r
- game.state.galaxy[game.state.isx][game.state.isy] += 100;\r
- if (ishere) {\r
- /* SC has scooted, Remove him from current quadrant */\r
- iscate=0;\r
- isatb=0;\r
- ishere=0;\r
- ientesc=0;\r
- game.future[FSCDBAS]=1e30;\r
- for (i = 1; i <= nenhere; i++) \r
- if (game.quad[game.kx[i]][game.ky[i]] == IHS) break;\r
- game.quad[game.kx[i]][game.ky[i]] = IHDOT;\r
- game.kx[i] = game.kx[nenhere];\r
- game.ky[i] = game.ky[nenhere];\r
- game.kdist[i] = game.kdist[nenhere];\r
- game.kavgd[i] = game.kavgd[nenhere];\r
- game.kpower[i] = game.kpower[nenhere];\r
- klhere--;\r
- nenhere--;\r
- if (condit!=IHDOCKED) newcnd();\r
- sortkl();\r
- }\r
- /* check for a helpful planet */\r
- for (i = 0; i < inplan; i++) {\r
- if (game.state.plnets[i].x==game.state.isx && game.state.plnets[i].y==game.state.isy &&\r
- game.state.plnets[i].crystals == 1) {\r
- /* destroy the planet */\r
- DESTROY(&game.state.plnets[i]);\r
- game.state.newstuf[game.state.isx][game.state.isy] -= 1;\r
- if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
- if (*ipage==0) pause_game(1);\r
- *ipage = 1;\r
- prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");\r
- proutn(" a planet in ");\r
- proutn(cramlc(quadrant, game.state.isx, game.state.isy));\r
- prout(" has been destroyed");\r
- prout(" by the Super-commander.\"");\r
- }\r
- break;\r
- }\r
- }\r
- return 0; /* looks good! */\r
-}\r
- \r
- \r
- \r
-\r
-\r
-void scom(int *ipage) {\r
- int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;\r
- int iqx, iqy;\r
- int basetbl[6];\r
- double bdist[6];\r
- int flag;\r
-#ifdef DEBUG\r
- if (idebug) prout("SCOM");\r
-#endif\r
-\r
- /* Decide on being active or passive */\r
- flag = ((game.state.killc+game.state.killk)/(game.state.date+0.01-indate) < 0.1*skill*(skill+1.0) ||\r
- (game.state.date-indate) < 3.0);\r
- if (iscate==0 && flag) {\r
- /* compute move away from Enterprise */\r
- ideltax = game.state.isx-quadx;\r
- ideltay = game.state.isy-quady;\r
- if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {\r
- /* circulate in space */\r
- ideltax = game.state.isy-quady;\r
- ideltay = quadx-game.state.isx;\r
- }\r
- }\r
- else {\r
- /* compute distances to starbases */\r
- if (game.state.rembase <= 0) {\r
- /* nothing left to do */\r
- game.future[FSCMOVE] = 1e30;\r
- return;\r
- }\r
- sx = game.state.isx;\r
- sy = game.state.isy;\r
- for (i = 1; i <= game.state.rembase; i++) {\r
- basetbl[i] = i;\r
- ibqx = game.state.baseqx[i];\r
- ibqy = game.state.baseqy[i];\r
- bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));\r
- }\r
- if (game.state.rembase > 1) {\r
- /* sort into nearest first order */\r
- int iswitch;\r
- do {\r
- iswitch = 0;\r
- for (i=1; i < game.state.rembase-1; i++) {\r
- if (bdist[i] > bdist[i+1]) {\r
- int ti = basetbl[i];\r
- double t = bdist[i];\r
- bdist[i] = bdist[i+1];\r
- bdist[i+1] = t;\r
- basetbl[i] = basetbl[i+1];\r
- basetbl[i+1] =ti;\r
- iswitch = 1;\r
- }\r
- }\r
- } while (iswitch);\r
- }\r
- /* look for nearest base without a commander, no Enterprise, and\r
- without too many Klingons, and not already under attack. */\r
- ifindit = iwhichb = 0;\r
-\r
- for (i2 = 1; i2 <= game.state.rembase; i2++) {\r
- i = basetbl[i2]; /* bug in original had it not finding nearest*/\r
- ibqx = game.state.baseqx[i];\r
- ibqy = game.state.baseqy[i];\r
- if ((ibqx == quadx && ibqy == quady) ||\r
- (ibqx == batx && ibqy == baty) ||\r
- game.state.galaxy[ibqx][ibqy] > 899) continue;\r
- /* if there is a commander, an no other base is appropriate,\r
- we will take the one with the commander */\r
- for (j = 1; j <= game.state.remcom; j++) {\r
- if (ibqx==game.state.cx[j] && ibqy==game.state.cy[j] && ifindit!= 2) {\r
- ifindit = 2;\r
- iwhichb = i;\r
- break;\r
- }\r
- }\r
- if (j > game.state.remcom) { /* no commander -- use this one */\r
- ifindit = 1;\r
- iwhichb = i;\r
- break;\r
- }\r
- }\r
- if (ifindit==0) return; /* Nothing suitable -- wait until next time*/\r
- ibqx = game.state.baseqx[iwhichb];\r
- ibqy = game.state.baseqy[iwhichb];\r
- /* decide how to move toward base */\r
- ideltax = ibqx - game.state.isx;\r
- ideltay = ibqy - game.state.isy;\r
- }\r
- /* Maximum movement is 1 quadrant in either or both axis */\r
- if (ideltax > 1) ideltax = 1;\r
- if (ideltax < -1) ideltax = -1;\r
- if (ideltay > 1) ideltay = 1;\r
- if (ideltay < -1) ideltay = -1;\r
-\r
- /* try moving in both x and y directions */\r
- iqx = game.state.isx + ideltax;\r
- iqy = game.state.isy + ideltax;\r
- if (movescom(iqx, iqy, flag, ipage)) {\r
- /* failed -- try some other maneuvers */\r
- if (ideltax==0 || ideltay==0) {\r
- /* attempt angle move */\r
- if (ideltax != 0) {\r
- iqy = game.state.isy + 1;\r
- if (movescom(iqx, iqy, flag, ipage)) {\r
- iqy = game.state.isy - 1;\r
- movescom(iqx, iqy, flag, ipage);\r
- }\r
- }\r
- else {\r
- iqx = game.state.isx + 1;\r
- if (movescom(iqx, iqy, flag, ipage)) {\r
- iqx = game.state.isx - 1;\r
- movescom(iqx, iqy, flag, ipage);\r
- }\r
- }\r
- }\r
- else {\r
- /* try moving just in x or y */\r
- iqy = game.state.isy;\r
- if (movescom(iqx, iqy, flag, ipage)) {\r
- iqy = game.state.isy + ideltay;\r
- iqx = game.state.isx;\r
- movescom(iqx, iqy, flag, ipage);\r
- }\r
- }\r
- }\r
- /* check for a base */\r
- if (game.state.rembase == 0) {\r
- game.future[FSCMOVE] = 1e30;\r
- }\r
- else for (i=1; i<=game.state.rembase; i++) {\r
- ibqx = game.state.baseqx[i];\r
- ibqy = game.state.baseqy[i];\r
- if (ibqx==game.state.isx && ibqy == game.state.isy && game.state.isx != batx && game.state.isy != baty) {\r
- /* attack the base */\r
- if (flag) return; /* no, don't attack base! */\r
- iseenit = 0;\r
- isatb=1;\r
- game.future[FSCDBAS] = game.state.date + 1.0 +2.0*Rand();\r
- if (game.future[FCDBAS] < 1e30) game.future[FSCDBAS] +=\r
- game.future[FCDBAS]-game.state.date;\r
- if (game.damage[DRADIO] > 0 && condit != IHDOCKED)\r
- return; /* no warning */\r
- iseenit = 1;\r
- if (*ipage == 0) pause_game(1);\r
- *ipage=1;\r
- proutn("Lt. Uhura- \"Captain, the starbase in ");\r
- proutn(cramlc(quadrant, game.state.isx, game.state.isy));\r
- skip(1);\r
- prout(" reports that it is under attack from the Klingon Super-commander.");\r
- proutn(" It can survive until stardate %d.\"",\r
- (int)game.future[FSCDBAS]);\r
- if (resting==0) return;\r
- prout("Mr. Spock- \"Captain, shall we cancel the rest period?\"");\r
- if (ja()==0) return;\r
- resting = 0;\r
- Time = 0.0; /* actually finished */\r
- return;\r
- }\r
- }\r
- /* Check for intelligence report */\r
- if (\r
-#ifdef DEBUG\r
- idebug==0 &&\r
-#endif\r
- (Rand() > 0.2 ||\r
- (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) ||\r
- game.starch[game.state.isx][game.state.isy] > 0))\r
- return;\r
- if (*ipage==0) pause_game(1);\r
- *ipage = 1;\r
- prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");\r
- proutn(" the Super-commander is in ");\r
- proutn(cramlc(quadrant, game.state.isx, game.state. isy));\r
- prout(".\"");\r
- return;\r
-}\r
-\r
-void movetho(void) {\r
- int idx, idy, im, i, dum, my;\r
- /* Move the Tholian */\r
- if (ithere==0 || justin == 1) return;\r
-\r
- if (ithx == 1 && ithy == 1) {\r
- idx = 1; idy = 10;\r
- }\r
- else if (ithx == 1 && ithy == 10) {\r
- idx = 10; idy = 10;\r
- }\r
- else if (ithx == 10 && ithy == 10) {\r
- idx = 10; idy = 1;\r
- }\r
- else if (ithx == 10 && ithy == 1) {\r
- idx = 1; idy = 1;\r
- }\r
- else {\r
- /* something is wrong! */\r
- ithere = 0;\r
- return;\r
- }\r
-\r
- /* Do nothing if we are blocked */\r
- if (game.quad[idx][idy]!= IHDOT && game.quad[idx][idy]!= IHWEB) return;\r
- game.quad[ithx][ithy] = IHWEB;\r
-\r
- if (ithx != idx) {\r
- /* move in x axis */\r
- im = fabs((double)idx - ithx)/((double)idx - ithx);\r
- while (ithx != idx) {\r
- ithx += im;\r
- if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;\r
- }\r
- }\r
- else if (ithy != idy) {\r
- /* move in y axis */\r
- im = fabs((double)idy - ithy)/((double)idy - ithy);\r
- while (ithy != idy) {\r
- ithy += im;\r
- if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;\r
- }\r
- }\r
- game.quad[ithx][ithy] = IHT;\r
- game.kx[nenhere]=ithx;\r
- game.ky[nenhere]=ithy;\r
-\r
- /* check to see if all holes plugged */\r
- for (i = 1; i < 11; i++) {\r
- if (game.quad[1][i]!=IHWEB && game.quad[1][i]!=IHT) return;\r
- if (game.quad[10][i]!=IHWEB && game.quad[10][i]!=IHT) return;\r
- if (game.quad[i][1]!=IHWEB && game.quad[i][1]!=IHT) return;\r
- if (game.quad[i][10]!=IHWEB && game.quad[i][10]!=IHT) return;\r
- }\r
- /* All plugged up -- Tholian splits */\r
- game.quad[ithx][ithy]=IHWEB;\r
- dropin(IHBLANK, &dum, &my);\r
- crmena(1,IHT, 2, ithx, ithy);\r
- prout(" completes web.");\r
- ithere = ithx = ithy = 0;\r
- nenhere--;\r
- return;\r
-}\r
+#include "sst.h"
+
+static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) {
+ int iqx, iqy, l;
+
+ iqx = quadx+(lookx+9)/10 - 1;
+ iqy = quady+(looky+9)/10 - 1;
+ if (iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||
+ game.state.galaxy[iqx][iqy] > 899)
+ return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */
+ if (ienm == IHR) return 0; /* Romulans cannot escape! */
+ if (irun == 0) {
+ /* avoid intruding on another commander's territory */
+ if (ienm == IHC) {
+ for (l = 1; l <= game.state.remcom; l++)
+ if (game.state.cx[l]==iqx && game.state.cy[l]==iqy) return 0;
+ /* refuse to leave if currently attacking starbase */
+ if (batx==quadx && baty==quady) return 0;
+ }
+ /* don't leave if over 1000 units of energy */
+ if (game.kpower[loccom] > 1000.) return 0;
+ }
+ /* print escape message and move out of quadrant.
+ We know this if either short or long range sensors are working */
+ if (game.damage[DSRSENS] == 0.0 || game.damage[DLRSENS] == 0.0 ||
+ condit == IHDOCKED) {
+ crmena(1, ienm, 2, game.kx[loccom], game.ky[loccom]);
+ proutn(" escapes to %s (and regains strength).",
+ cramlc(quadrant, iqx, iqy));
+ }
+ /* handle local matters related to escape */
+ game.quad[game.kx[loccom]][game.ky[loccom]] = IHDOT;
+ game.kx[loccom] = game.kx[nenhere];
+ game.ky[loccom] = game.ky[nenhere];
+ game.kavgd[loccom] = game.kavgd[nenhere];
+ game.kpower[loccom] = game.kpower[nenhere];
+ game.kdist[loccom] = game.kdist[nenhere];
+ klhere--;
+ nenhere--;
+ if (condit != IHDOCKED) newcnd();
+ /* Handle global matters related to escape */
+ game.state.galaxy[quadx][quady] -= 100;
+ game.state.galaxy[iqx][iqy] += 100;
+ if (ienm==IHS) {
+ ishere=0;
+ iscate=0;
+ ientesc=0;
+ isatb=0;
+ game.future[FSCMOVE]=0.2777+game.state.date;
+ game.future[FSCDBAS]=1e30;
+ game.state.isx=iqx;
+ game.state.isy=iqy;
+ }
+ else {
+ for (l=1; l<=game.state.remcom; l++) {
+ if (game.state.cx[l]==quadx && game.state.cy[l]==quady) {
+ game.state.cx[l]=iqx;
+ game.state.cy[l]=iqy;
+ break;
+ }
+ }
+ comhere = 0;
+ }
+ return 1; /* success */
+}
+
+
+static void movebaddy(int comx, int comy, int loccom, int ienm) {
+ int motion, mdist, nsteps, mx, my, nextx, nexty, lookx, looky, ll;
+ int irun = 0;
+ int krawlx, krawly;
+ int success;
+ int attempts;
+ /* This should probably be just comhere + ishere */
+ int nbaddys = skill > 3 ?
+ (int)((comhere*2 + ishere*2+klhere*1.23+irhere*1.5)/2.0):
+ (comhere + ishere);
+ double dist1, forces;
+
+ dist1 = game.kdist[loccom];
+ mdist = dist1 + 0.5; /* Nearest integer distance */
+
+ /* If SC, check with spy to see if should hi-tail it */
+ if (ienm==IHS &&
+ (game.kpower[loccom] <= 500.0 || (condit==IHDOCKED && game.damage[DPHOTON]==0))) {
+ irun = 1;
+ motion = -10;
+ }
+ else {
+ /* decide whether to advance, retreat, or hold position */
+/* Algorithm:
+ * Enterprise has "force" based on condition of phaser and photon torpedoes.
+ If both are operating full strength, force is 1000. If both are damaged,
+ force is -1000. Having shields down subtracts an additional 1000.
+
+ * Enemy has forces equal to the energy of the attacker plus
+ 100*(K+R) + 500*(C+S) - 400 for novice through good levels OR
+ 346*K + 400*R + 500*(C+S) - 400 for expert and emeritus.
+
+ Attacker Initial energy levels (nominal):
+ Klingon Romulan Commander Super-Commander
+ Novice 400 700 1200
+ Fair 425 750 1250
+ Good 450 800 1300 1750
+ Expert 475 850 1350 1875
+ Emeritus 500 900 1400 2000
+ VARIANCE 75 200 200 200
+
+ Enemy vessels only move prior to their attack. In Novice - Good games
+ only commanders move. In Expert games, all enemy vessels move if there
+ is a commander present. In Emeritus games all enemy vessels move.
+
+ * If Enterprise is not docked, an agressive action is taken if enemy
+ forces are 1000 greater than Enterprise.
+
+ Agressive action on average cuts the distance between the ship and
+ the enemy to 1/4 the original.
+
+ * At lower energy advantage, movement units are proportional to the
+ advantage with a 650 advantage being to hold ground, 800 to move forward
+ 1, 950 for two, 150 for back 4, etc. Variance of 100.
+
+ If docked, is reduced by roughly 1.75*skill, generally forcing a
+ retreat, especially at high skill levels.
+
+ * Motion is limited to skill level, except for SC hi-tailing it out.
+ */
+
+ forces = game.kpower[loccom]+100.0*nenhere+400*(nbaddys-1);
+ if (shldup==0) forces += 1000; /* Good for enemy if shield is down! */
+ if (game.damage[DPHASER] == 0.0 || game.damage[DPHOTON] == 0.0) {
+ if (game.damage[DPHASER] != 0) /* phasers damaged */
+ forces += 300.0;
+ else
+ forces -= 0.2*(energy - 2500.0);
+ if (game.damage[DPHOTON] != 0) /* photon torpedoes damaged */
+ forces += 300.0;
+ else
+ forces -= 50.0*torps;
+ }
+ else {
+ /* phasers and photon tubes both out! */
+ forces += 1000.0;
+ }
+ motion = 0;
+ if (forces <= 1000.0 && condit != IHDOCKED) /* Typical situation */
+ motion = ((forces+200.0*Rand())/150.0) - 5.0;
+ else {
+ if (forces > 1000.0) /* Very strong -- move in for kill */
+ motion = (1.0-square(Rand()))*dist1 + 1.0;
+ if (condit==IHDOCKED) /* protected by base -- back off ! */
+ motion -= skill*(2.0-square(Rand()));
+ }
+#ifdef DEBUG
+ if (idebug) {
+ proutn("MOTION = %1.2f", motion);
+ proutn(" FORCES = %1,2f", forces);
+ }
+#endif
+ /* don't move if no motion */
+ if (motion==0) return;
+ /* Limit motion according to skill */
+ if (abs(motion) > skill) motion = (motion < 0) ? -skill : skill;
+ }
+ /* calcuate preferred number of steps */
+ nsteps = motion < 0 ? -motion : motion;
+ if (motion > 0 && nsteps > mdist) nsteps = mdist; /* don't overshoot */
+ if (nsteps > 10) nsteps = 10; /* This shouldn't be necessary */
+ if (nsteps < 1) nsteps = 1; /* This shouldn't be necessary */
+#ifdef DEBUG
+ if (idebug) {
+ prout("NSTEPS = %d", nsteps);
+ }
+#endif
+ /* Compute preferred values of delta X and Y */
+ mx = sectx - comx;
+ my = secty - comy;
+ if (2.0 * abs(mx) < abs(my)) mx = 0;
+ if (2.0 * abs(my) < abs(sectx-comx)) my = 0;
+ if (mx != 0) mx = mx*motion < 0 ? -1 : 1;
+ if (my != 0) my = my*motion < 0 ? -1 : 1;
+ nextx = comx;
+ nexty = comy;
+ /* main move loop */
+ for (ll = 1; ll <= nsteps; ll++) {
+#ifdef DEBUG
+ if (idebug) {
+ prout("%d", ll);
+ }
+#endif
+ /* Check if preferred position available */
+ lookx = nextx + mx;
+ looky = nexty + my;
+ krawlx = mx < 0 ? 1 : -1;
+ krawly = my < 0 ? 1 : -1;
+ success = 0;
+ attempts = 0; /* Settle mysterious hang problem */
+ while (attempts++ < 20 && !success) {
+ if (lookx < 1 || lookx > 10) {
+ if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))
+ return;
+ if (krawlx == mx || my == 0) break;
+ lookx = nextx + krawlx;
+ krawlx = -krawlx;
+ }
+ else if (looky < 1 || looky > 10) {
+ if (motion < 0 && tryexit(lookx, looky, ienm, loccom, irun))
+ return;
+ if (krawly == my || mx == 0) break;
+ looky = nexty + krawly;
+ krawly = -krawly;
+ }
+ else if (game.quad[lookx][looky] != IHDOT) {
+ /* See if we should ram ship */
+ if (game.quad[lookx][looky] == ship &&
+ (ienm == IHC || ienm == IHS)) {
+ ram(1, ienm, comx, comy);
+ return;
+ }
+ if (krawlx != mx && my != 0) {
+ lookx = nextx + krawlx;
+ krawlx = -krawlx;
+ }
+ else if (krawly != my && mx != 0) {
+ looky = nexty + krawly;
+ krawly = -krawly;
+ }
+ else break; /* we have failed */
+ }
+ else success = 1;
+ }
+ if (success) {
+ nextx = lookx;
+ nexty = looky;
+#ifdef DEBUG
+ if (idebug) {
+ prout(cramlc(neither, nextx, nexty));
+ }
+#endif
+ }
+ else break; /* done early */
+ }
+ /* Put commander in place within same quadrant */
+ game.quad[comx][comy] = IHDOT;
+ game.quad[nextx][nexty] = ienm;
+ if (nextx != comx || nexty != comy) {
+ /* it moved */
+ game.kx[loccom] = nextx;
+ game.ky[loccom] = nexty;
+ game.kdist[loccom] = game.kavgd[loccom] =
+ sqrt(square(sectx-nextx)+square(secty-nexty));
+ if (game.damage[DSRSENS] == 0 || condit == IHDOCKED) {
+ proutn("***");
+ cramen(ienm);
+ proutn(" from");
+ cramlc(2, comx, comy);
+ if (game.kdist[loccom] < dist1) proutn(" advances to");
+ else proutn(" retreats to ");
+ prout(cramlc(sector, nextx, nexty));
+ }
+ }
+}
+
+void movcom(void) {
+ int ix, iy, i;
+
+#ifdef DEBUG
+ if (idebug) prout("MOVCOM");
+#endif
+
+ /* Figure out which Klingon is the commander (or Supercommander)
+ and do move */
+ if (comhere) for (i = 1; i <= nenhere; i++) {
+ ix = game.kx[i];
+ iy = game.ky[i];
+ if (game.quad[ix][iy] == IHC) {
+ movebaddy(ix, iy, i, IHC);
+ break;
+ }
+ }
+ if (ishere) for (i = 1; i <= nenhere; i++) {
+ ix = game.kx[i];
+ iy = game.ky[i];
+ if (game.quad[ix][iy] == IHS) {
+ movebaddy(ix, iy, i, IHS);
+ break;
+ }
+ }
+ /* if skill level is high, move other Klingons and Romulans too!
+ Move these last so they can base their actions on what the
+ commander(s) do. */
+ if (skill > 3) for (i = 1; i <= nenhere; i++) {
+ ix = game.kx[i];
+ iy = game.ky[i];
+ if (game.quad[ix][iy] == IHK || game.quad[ix][iy] == IHR)
+ movebaddy(ix, iy, i, game.quad[ix][iy]);
+ }
+
+ sortkl();
+}
+
+static int movescom(int iqx, int iqy, int flag, int *ipage) {
+ int i;
+
+ if ((iqx==quadx && iqy==quady) ||
+ iqx < 1 || iqx > 8 || iqy < 1 || iqy > 8 ||
+ game.state.galaxy[iqx][iqy] > 899) return 1;
+ if (flag) {
+ /* Avoid quadrants with bases if we want to avoid Enterprise */
+ for (i = 1; i <= game.state.rembase; i++)
+ if (game.state.baseqx[i]==iqx && game.state.baseqy[i]==iqy) return 1;
+ }
+ if (justin && !iscate) return 1;
+ /* do the move */
+ game.state.galaxy[game.state.isx][game.state.isy] -= 100;
+ game.state.isx = iqx;
+ game.state.isy = iqy;
+ game.state.galaxy[game.state.isx][game.state.isy] += 100;
+ if (ishere) {
+ /* SC has scooted, Remove him from current quadrant */
+ iscate=0;
+ isatb=0;
+ ishere=0;
+ ientesc=0;
+ game.future[FSCDBAS]=1e30;
+ for (i = 1; i <= nenhere; i++)
+ if (game.quad[game.kx[i]][game.ky[i]] == IHS) break;
+ game.quad[game.kx[i]][game.ky[i]] = IHDOT;
+ game.kx[i] = game.kx[nenhere];
+ game.ky[i] = game.ky[nenhere];
+ game.kdist[i] = game.kdist[nenhere];
+ game.kavgd[i] = game.kavgd[nenhere];
+ game.kpower[i] = game.kpower[nenhere];
+ klhere--;
+ nenhere--;
+ if (condit!=IHDOCKED) newcnd();
+ sortkl();
+ }
+ /* check for a helpful planet */
+ for (i = 0; i < inplan; i++) {
+ if (game.state.plnets[i].x==game.state.isx && game.state.plnets[i].y==game.state.isy &&
+ game.state.plnets[i].crystals == 1) {
+ /* destroy the planet */
+ DESTROY(&game.state.plnets[i]);
+ game.state.newstuf[game.state.isx][game.state.isy] -= 1;
+ if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
+ if (*ipage==0) pause_game(1);
+ *ipage = 1;
+ prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");
+ proutn(" a planet in ");
+ proutn(cramlc(quadrant, game.state.isx, game.state.isy));
+ prout(" has been destroyed");
+ prout(" by the Super-commander.\"");
+ }
+ break;
+ }
+ }
+ return 0; /* looks good! */
+}
+
+
+
+
+
+void scom(int *ipage) {
+ int i, i2, j, ideltax, ideltay, ibqx, ibqy, sx, sy, ifindit, iwhichb;
+ int iqx, iqy;
+ int basetbl[6];
+ double bdist[6];
+ int flag;
+#ifdef DEBUG
+ if (idebug) prout("SCOM");
+#endif
+
+ /* Decide on being active or passive */
+ flag = ((game.state.killc+game.state.killk)/(game.state.date+0.01-indate) < 0.1*skill*(skill+1.0) ||
+ (game.state.date-indate) < 3.0);
+ if (iscate==0 && flag) {
+ /* compute move away from Enterprise */
+ ideltax = game.state.isx-quadx;
+ ideltay = game.state.isy-quady;
+ if (sqrt(ideltax*(double)ideltax+ideltay*(double)ideltay) > 2.0) {
+ /* circulate in space */
+ ideltax = game.state.isy-quady;
+ ideltay = quadx-game.state.isx;
+ }
+ }
+ else {
+ /* compute distances to starbases */
+ if (game.state.rembase <= 0) {
+ /* nothing left to do */
+ game.future[FSCMOVE] = 1e30;
+ return;
+ }
+ sx = game.state.isx;
+ sy = game.state.isy;
+ for (i = 1; i <= game.state.rembase; i++) {
+ basetbl[i] = i;
+ ibqx = game.state.baseqx[i];
+ ibqy = game.state.baseqy[i];
+ bdist[i] = sqrt(square(ibqx-sx) + square(ibqy-sy));
+ }
+ if (game.state.rembase > 1) {
+ /* sort into nearest first order */
+ int iswitch;
+ do {
+ iswitch = 0;
+ for (i=1; i < game.state.rembase-1; i++) {
+ if (bdist[i] > bdist[i+1]) {
+ int ti = basetbl[i];
+ double t = bdist[i];
+ bdist[i] = bdist[i+1];
+ bdist[i+1] = t;
+ basetbl[i] = basetbl[i+1];
+ basetbl[i+1] =ti;
+ iswitch = 1;
+ }
+ }
+ } while (iswitch);
+ }
+ /* look for nearest base without a commander, no Enterprise, and
+ without too many Klingons, and not already under attack. */
+ ifindit = iwhichb = 0;
+
+ for (i2 = 1; i2 <= game.state.rembase; i2++) {
+ i = basetbl[i2]; /* bug in original had it not finding nearest*/
+ ibqx = game.state.baseqx[i];
+ ibqy = game.state.baseqy[i];
+ if ((ibqx == quadx && ibqy == quady) ||
+ (ibqx == batx && ibqy == baty) ||
+ game.state.galaxy[ibqx][ibqy] > 899) continue;
+ /* if there is a commander, an no other base is appropriate,
+ we will take the one with the commander */
+ for (j = 1; j <= game.state.remcom; j++) {
+ if (ibqx==game.state.cx[j] && ibqy==game.state.cy[j] && ifindit!= 2) {
+ ifindit = 2;
+ iwhichb = i;
+ break;
+ }
+ }
+ if (j > game.state.remcom) { /* no commander -- use this one */
+ ifindit = 1;
+ iwhichb = i;
+ break;
+ }
+ }
+ if (ifindit==0) return; /* Nothing suitable -- wait until next time*/
+ ibqx = game.state.baseqx[iwhichb];
+ ibqy = game.state.baseqy[iwhichb];
+ /* decide how to move toward base */
+ ideltax = ibqx - game.state.isx;
+ ideltay = ibqy - game.state.isy;
+ }
+ /* Maximum movement is 1 quadrant in either or both axis */
+ if (ideltax > 1) ideltax = 1;
+ if (ideltax < -1) ideltax = -1;
+ if (ideltay > 1) ideltay = 1;
+ if (ideltay < -1) ideltay = -1;
+
+ /* try moving in both x and y directions */
+ iqx = game.state.isx + ideltax;
+ iqy = game.state.isy + ideltax;
+ if (movescom(iqx, iqy, flag, ipage)) {
+ /* failed -- try some other maneuvers */
+ if (ideltax==0 || ideltay==0) {
+ /* attempt angle move */
+ if (ideltax != 0) {
+ iqy = game.state.isy + 1;
+ if (movescom(iqx, iqy, flag, ipage)) {
+ iqy = game.state.isy - 1;
+ movescom(iqx, iqy, flag, ipage);
+ }
+ }
+ else {
+ iqx = game.state.isx + 1;
+ if (movescom(iqx, iqy, flag, ipage)) {
+ iqx = game.state.isx - 1;
+ movescom(iqx, iqy, flag, ipage);
+ }
+ }
+ }
+ else {
+ /* try moving just in x or y */
+ iqy = game.state.isy;
+ if (movescom(iqx, iqy, flag, ipage)) {
+ iqy = game.state.isy + ideltay;
+ iqx = game.state.isx;
+ movescom(iqx, iqy, flag, ipage);
+ }
+ }
+ }
+ /* check for a base */
+ if (game.state.rembase == 0) {
+ game.future[FSCMOVE] = 1e30;
+ }
+ else for (i=1; i<=game.state.rembase; i++) {
+ ibqx = game.state.baseqx[i];
+ ibqy = game.state.baseqy[i];
+ if (ibqx==game.state.isx && ibqy == game.state.isy && game.state.isx != batx && game.state.isy != baty) {
+ /* attack the base */
+ if (flag) return; /* no, don't attack base! */
+ iseenit = 0;
+ isatb=1;
+ game.future[FSCDBAS] = game.state.date + 1.0 +2.0*Rand();
+ if (game.future[FCDBAS] < 1e30) game.future[FSCDBAS] +=
+ game.future[FCDBAS]-game.state.date;
+ if (game.damage[DRADIO] > 0 && condit != IHDOCKED)
+ return; /* no warning */
+ iseenit = 1;
+ if (*ipage == 0) pause_game(1);
+ *ipage=1;
+ proutn("Lt. Uhura- \"Captain, the starbase in ");
+ proutn(cramlc(quadrant, game.state.isx, game.state.isy));
+ skip(1);
+ prout(" reports that it is under attack from the Klingon Super-commander.");
+ proutn(" It can survive until stardate %d.\"",
+ (int)game.future[FSCDBAS]);
+ if (resting==0) return;
+ prout("Mr. Spock- \"Captain, shall we cancel the rest period?\"");
+ if (ja()==0) return;
+ resting = 0;
+ Time = 0.0; /* actually finished */
+ return;
+ }
+ }
+ /* Check for intelligence report */
+ if (
+#ifdef DEBUG
+ idebug==0 &&
+#endif
+ (Rand() > 0.2 ||
+ (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) ||
+ game.starch[game.state.isx][game.state.isy] > 0))
+ return;
+ if (*ipage==0) pause_game(1);
+ *ipage = 1;
+ prout("Lt. Uhura- \"Captain, Starfleet Intelligence reports");
+ proutn(" the Super-commander is in ");
+ proutn(cramlc(quadrant, game.state.isx, game.state. isy));
+ prout(".\"");
+ return;
+}
+
+void movetho(void) {
+ int idx, idy, im, i, dum, my;
+ /* Move the Tholian */
+ if (ithere==0 || justin == 1) return;
+
+ if (ithx == 1 && ithy == 1) {
+ idx = 1; idy = 10;
+ }
+ else if (ithx == 1 && ithy == 10) {
+ idx = 10; idy = 10;
+ }
+ else if (ithx == 10 && ithy == 10) {
+ idx = 10; idy = 1;
+ }
+ else if (ithx == 10 && ithy == 1) {
+ idx = 1; idy = 1;
+ }
+ else {
+ /* something is wrong! */
+ ithere = 0;
+ return;
+ }
+
+ /* Do nothing if we are blocked */
+ if (game.quad[idx][idy]!= IHDOT && game.quad[idx][idy]!= IHWEB) return;
+ game.quad[ithx][ithy] = IHWEB;
+
+ if (ithx != idx) {
+ /* move in x axis */
+ im = fabs((double)idx - ithx)/((double)idx - ithx);
+ while (ithx != idx) {
+ ithx += im;
+ if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;
+ }
+ }
+ else if (ithy != idy) {
+ /* move in y axis */
+ im = fabs((double)idy - ithy)/((double)idy - ithy);
+ while (ithy != idy) {
+ ithy += im;
+ if (game.quad[ithx][ithy]==IHDOT) game.quad[ithx][ithy] = IHWEB;
+ }
+ }
+ game.quad[ithx][ithy] = IHT;
+ game.kx[nenhere]=ithx;
+ game.ky[nenhere]=ithy;
+
+ /* check to see if all holes plugged */
+ for (i = 1; i < 11; i++) {
+ if (game.quad[1][i]!=IHWEB && game.quad[1][i]!=IHT) return;
+ if (game.quad[10][i]!=IHWEB && game.quad[10][i]!=IHT) return;
+ if (game.quad[i][1]!=IHWEB && game.quad[i][1]!=IHT) return;
+ if (game.quad[i][10]!=IHWEB && game.quad[i][10]!=IHT) return;
+ }
+ /* All plugged up -- Tholian splits */
+ game.quad[ithx][ithy]=IHWEB;
+ dropin(IHBLANK, &dum, &my);
+ crmena(1,IHT, 2, ithx, ithy);
+ prout(" completes web.");
+ ithere = ithx = ithy = 0;
+ nenhere--;
+ return;
+}
-#ifdef SERGEEV\r
-#include <conio.h>\r
-#include <unistd.h>\r
-#include "sstlinux.h"\r
-#endif /* SERGEEV */\r
-#include "sst.h"\r
-\r
-void doshield(int i) {\r
- int key;\r
- enum {NONE, SHUP, SHDN, NRG} action = NONE;\r
-\r
- ididit = 0;\r
-\r
- if (i == 2) action = SHUP;\r
- else {\r
- key = scan();\r
- if (key == IHALPHA) {\r
- if (isit("transfer"))\r
- action = NRG;\r
- else {\r
- chew();\r
- if (game.damage[DSHIELD]) {\r
- prout("Shields damaged and down.");\r
- return;\r
- }\r
- if (isit("up"))\r
- action = SHUP;\r
- else if (isit("down"))\r
- action = SHDN;\r
- }\r
- }\r
- if (action==NONE) {\r
- proutn("Do you wish to change shield energy? ");\r
- if (ja()) {\r
- proutn("Energy to transfer to shields- ");\r
- action = NRG;\r
- }\r
- else if (game.damage[DSHIELD]) {\r
- prout("Shields damaged and down.");\r
- return;\r
- }\r
- else if (shldup) {\r
- proutn("Shields are up. Do you want them down? ");\r
- if (ja()) action = SHDN;\r
- else {\r
- chew();\r
- return;\r
- }\r
- }\r
- else {\r
- proutn("Shields are down. Do you want them up? ");\r
- if (ja()) action = SHUP;\r
- else {\r
- chew();\r
- return;\r
- }\r
- }\r
- }\r
- }\r
- switch (action) {\r
- case SHUP: /* raise shields */\r
- if (shldup) {\r
- prout("Shields already up.");\r
- return;\r
- }\r
- shldup = 1;\r
- shldchg = 1;\r
- if (condit != IHDOCKED) energy -= 50.0;\r
- prout("Shields raised.");\r
- if (energy <= 0) {\r
- skip(1);\r
- prout("Shields raising uses up last of energy.");\r
- finish(FNRG);\r
- return;\r
- }\r
- ididit=1;\r
- return;\r
- case SHDN:\r
- if (shldup==0) {\r
- prout("Shields already down.");\r
- return;\r
- }\r
- shldup=0;\r
- shldchg=1;\r
- prout("Shields lowered.");\r
- ididit=1;\r
- return;\r
- case NRG:\r
- while (scan() != IHREAL) {\r
- chew();\r
- proutn("Energy to transfer to shields- ");\r
- }\r
- chew();\r
- if (aaitem==0) return;\r
- if (aaitem > energy) {\r
- prout("Insufficient ship energy.");\r
- return;\r
- }\r
- ididit = 1;\r
- if (shield+aaitem >= inshld) {\r
- prout("Shield energy maximized.");\r
- if (shield+aaitem > inshld) {\r
- prout("Excess energy requested returned to ship energy");\r
- }\r
- energy -= inshld-shield;\r
- shield = inshld;\r
- return;\r
- }\r
- if (aaitem < 0.0 && energy-aaitem > inenrg) {\r
- /* Prevent shield drain loophole */\r
- skip(1);\r
- prout("Engineering to bridge--");\r
- prout(" Scott here. Power circuit problem, Captain.");\r
- prout(" I can't drain the shields.");\r
- ididit = 0;\r
- return;\r
- }\r
- if (shield+aaitem < 0) {\r
- prout("All shield energy transferred to ship.");\r
- energy += shield;\r
- shield = 0.0;\r
- return;\r
- }\r
- proutn("Scotty- \"");\r
- if (aaitem > 0)\r
- prout("Transferring energy to shields.\"");\r
- else\r
- prout("Draining energy from shields.\"");\r
- shield += aaitem;\r
- energy -= aaitem;\r
- return;\r
- case NONE:; /* avoid gcc warning */\r
- }\r
-}\r
-\r
-void ram(int ibumpd, int ienm, int ix, int iy) {\r
- double type = 1.0, extradm;\r
- int icas, l;\r
- \r
- prouts("***RED ALERT! RED ALERT!");\r
- skip(1);\r
- prout("***COLLISION IMMINENT.");\r
- skip(2);\r
- proutn("***");\r
- crmshp();\r
- switch (ienm) {\r
- case IHR: type = 1.5; break;\r
- case IHC: type = 2.0; break;\r
- case IHS: type = 2.5; break;\r
- case IHT: type = 0.5; break;\r
- case IHQUEST: type = 4.0; break;\r
- }\r
- proutn(ibumpd ? " rammed by " : " rams ");\r
- crmena(0, ienm, 2, ix, iy);\r
- if (ibumpd) proutn(" (original position)");\r
- skip(1);\r
- deadkl(ix, iy, ienm, sectx, secty);\r
- proutn("***");\r
- crmshp();\r
- prout(" heavily damaged.");\r
- icas = 10.0+20.0*Rand();\r
- prout("***Sickbay reports %d casualties", icas);\r
- casual += icas;\r
- for (l=1; l <= NDEVICES; l++) {\r
- if (l == DDRAY) continue; // Don't damage deathray \r
- if (game.damage[l] < 0) continue;\r
- extradm = (10.0*type*Rand()+1.0)*damfac;\r
- game.damage[l] += Time + extradm; /* Damage for at least time of travel! */\r
- }\r
- shldup = 0;\r
- if (game.state.remkl) {\r
- pause_game(2);\r
- dreprt();\r
- }\r
- else finish(FWON);\r
- return;\r
-}\r
-\r
-void torpedo(double course, double r, int inx, int iny, double *hit, int wait) {\r
- int l, iquad=0, ix=0, iy=0, jx=0, jy=0, shoved=0, ll;\r
-#ifdef SERGEEV\r
- int crx,cry;\r
- \r
-#endif /* SERGEEV */\r
- double ac=course + 0.25*r;\r
- double angle = (15.0-ac)*0.5235988;\r
- double bullseye = (15.0 - course)*0.5235988;\r
- double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;\r
- double ang, temp, xx, yy, kp, h1;\r
-\r
- bigger = fabs(deltax);\r
- if (fabs(deltay) > bigger) bigger = fabs(deltay);\r
- deltax /= bigger;\r
- deltay /= bigger;\r
-#ifdef SERGEEV\r
- crx=wherex();\r
- cry=wherey();\r
- if (game.damage[DSRSENS]==0 || condit==IHDOCKED) setwnd(1);\r
- else setwnd(4);\r
-#endif /* SERGEEV */\r
- /* Loop to move a single torpedo */\r
- for (l=1; l <= 15; l++) {\r
- x += deltax;\r
- ix = x + 0.5;\r
- if (ix < 1 || ix > 10) break;\r
- y += deltay;\r
- iy = y + 0.5;\r
- if (iy < 1 || iy > 10) break;\r
-#ifndef SERGEEV\r
- if (l==4 || l==9) skip(1);\r
- proutn("%d - %d ", (int)x, (int)y);\r
- iquad=game.quad[ix][iy];\r
-#else\r
- iquad=game.quad[ix][iy];\r
- if (game.damage[DSRSENS]==0 || condit==IHDOCKED){\r
- drawmaps(2);\r
- delay((wait!=1)*400);\r
- wait=1;\r
- gotoxy(iy*2+3,ix+2);\r
- if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){\r
- game.quad[ix][iy]='+';\r
- drawmaps(2);\r
- game.quad[ix][iy]=iquad;\r
- sound(l*10);\r
- delay(100);\r
- nosound();\r
- }\r
- else {\r
- game.quad[ix][iy]|=128;\r
- drawmaps(2);\r
- game.quad[ix][iy]=iquad;\r
- _setcursortype(_NOCURSOR);\r
- sound(500);\r
- delay(1000);\r
- nosound();\r
- lowvideo();\r
- _setcursortype(_NORMALCURSOR);\r
- }\r
- }\r
- else {\r
- proutn("%d - %d ", (int)x, (int)y);\r
- }\r
-#endif /* SERGEEV */\r
- if (iquad==IHDOT) continue;\r
- /* hit something */\r
-#ifndef SERGEEV\r
- skip(1);\r
-#else\r
- setwnd(4);\r
- gotoxy(crx,cry);\r
-#endif\r
- switch(iquad) {\r
- case IHE: /* Hit our ship */\r
- case IHF:\r
- skip(1);\r
- proutn("Torpedo hits ");\r
- crmshp();\r
- prout(".");\r
- *hit = 700.0 + 100.0*Rand() -\r
- 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
- fabs(sin(bullseye-angle));\r
- *hit = fabs(*hit);\r
-#ifndef SERGEEV\r
- newcnd(); /* undock */\r
-#endif /* SERGEEV */\r
- /* We may be displaced. */\r
- if (landed==1 || condit==IHDOCKED) return; /* Cheat if on a planet */\r
- ang = angle + 2.5*(Rand()-0.5);\r
- temp = fabs(sin(ang));\r
- if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
- xx = -sin(ang)/temp;\r
- yy = cos(ang)/temp;\r
- jx=ix+xx+0.5;\r
- jy=iy+yy+0.5;\r
- if (jx<1 || jx>10 || jy<1 ||jy > 10) return;\r
- if (game.quad[jx][jy]==IHBLANK) {\r
- finish(FHOLE);\r
- return;\r
- }\r
- if (game.quad[jx][jy]!=IHDOT) {\r
- /* can't move into object */\r
- return;\r
- }\r
- sectx = jx;\r
- secty = jy;\r
- crmshp();\r
- shoved = 1;\r
- break;\r
- \r
- case IHC: /* Hit a commander */\r
- case IHS:\r
- if (Rand() <= 0.05) {\r
- crmena(1, iquad, 2, ix, iy);\r
- prout(" uses anti-photon device;");\r
- prout(" torpedo neutralized.");\r
- return;\r
- }\r
- case IHR: /* Hit a regular enemy */\r
- case IHK:\r
- /* find the enemy */\r
- for (ll=1; ll <= nenhere; ll++)\r
- if (ix==game.kx[ll] && iy==game.ky[ll]) break;\r
- kp = fabs(game.kpower[ll]);\r
- h1 = 700.0 + 100.0*Rand() -\r
- 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
- fabs(sin(bullseye-angle));\r
- h1 = fabs(h1);\r
- if (kp < h1) h1 = kp;\r
- game.kpower[ll] -= (game.kpower[ll]<0 ? -h1 : h1);\r
- if (game.kpower[ll] == 0) {\r
- deadkl(ix, iy, iquad, ix, iy);\r
- return;\r
- }\r
- crmena(1, iquad, 2, ix, iy);\r
- /* If enemy damaged but not destroyed, try to displace */\r
- ang = angle + 2.5*(Rand()-0.5);\r
- temp = fabs(sin(ang));\r
- if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));\r
- xx = -sin(ang)/temp;\r
- yy = cos(ang)/temp;\r
- jx=ix+xx+0.5;\r
- jy=iy+yy+0.5;\r
- if (jx<1 || jx>10 || jy<1 ||jy > 10) {\r
- prout(" damaged but not destroyed.");\r
- return;\r
- }\r
- if (game.quad[jx][jy]==IHBLANK) {\r
- prout(" buffeted into black hole.");\r
- deadkl(ix, iy, iquad, jx, jy);\r
- return;\r
- }\r
- if (game.quad[jx][jy]!=IHDOT) {\r
- /* can't move into object */\r
- prout(" damaged but not destroyed.");\r
- return;\r
- }\r
- proutn(" damaged--");\r
- game.kx[ll] = jx;\r
- game.ky[ll] = jy;\r
- shoved = 1;\r
- break;\r
- case IHB: /* Hit a base */\r
- skip(1);\r
- prout("***STARBASE DESTROYED..");\r
- if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;\r
- for (ll=1; ll<=game.state.rembase; ll++) {\r
- if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {\r
- game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];\r
- game.state.baseqy[ll]=game.state.baseqy[game.state.rembase];\r
- break;\r
- }\r
- }\r
- game.quad[ix][iy]=IHDOT;\r
- game.state.rembase--;\r
- basex=basey=0;\r
- game.state.galaxy[quadx][quady] -= 10;\r
- game.state.basekl++;\r
- newcnd();\r
- return;\r
- case IHP: /* Hit a planet */\r
- crmena(1, iquad, 2, ix, iy);\r
- prout(" destroyed.");\r
- game.state.nplankl++;\r
- game.state.newstuf[quadx][quady] -= 1;\r
- DESTROY(&game.state.plnets[iplnet]);\r
- iplnet = 0;\r
- plnetx = plnety = 0;\r
- game.quad[ix][iy] = IHDOT;\r
- if (landed==1) {\r
- /* captain parishes on planet */\r
- finish(FDPLANET);\r
- }\r
- return;\r
- case IHSTAR: /* Hit a star */\r
- if (Rand() > 0.10) {\r
- nova(ix, iy);\r
- return;\r
- }\r
- crmena(1, IHSTAR, 2, ix, iy);\r
- prout(" unaffected by photon blast.");\r
- return;\r
- case IHQUEST: /* Hit a thingy */\r
- if (Rand()>0.7) { // Used to be certain death \r
- skip(1);\r
- prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");\r
- skip(1);\r
- prouts(" HACK! HACK! HACK! *CHOKE!* ");\r
- skip(1);\r
- proutn("Mr. Spock-");\r
- prouts(" \"Fascinating!\"");\r
- skip(1);\r
- deadkl(ix, iy, iquad, ix, iy);\r
- } else {\r
- /*\r
- * Stas Sergeev added the possibility that\r
- * you can shove the Thingy.\r
- */\r
- iqengry=1;\r
- shoved=1;\r
- }\r
- return;\r
- case IHBLANK: /* Black hole */\r
- skip(1);\r
- crmena(1, IHBLANK, 2, ix, iy);\r
- prout(" swallows torpedo.");\r
- return;\r
- case IHWEB: /* hit the web */\r
- skip(1);\r
- prout("***Torpedo absorbed by Tholian web.");\r
- return;\r
- case IHT: /* Hit a Tholian */\r
- h1 = 700.0 + 100.0*Rand() -\r
- 1000.0*sqrt(square(ix-inx)+square(iy-iny))*\r
- fabs(sin(bullseye-angle));\r
- h1 = fabs(h1);\r
- if (h1 >= 600) {\r
-#ifndef SERGEEV\r
- prout(" destroyed.");\r
-#endif /* SERGEEV */\r
- game.quad[ix][iy] = IHDOT;\r
- ithere = 0;\r
- ithx = ithy = 0;\r
-#ifdef SERGEEV\r
- deadkl(ix, iy, iquad, ix, iy);\r
-#endif /* SERGEEV */\r
- return;\r
- }\r
- skip(1);\r
- crmena(1, IHT, 2, ix, iy);\r
- if (Rand() > 0.05) {\r
- prout(" survives photon blast.");\r
- return;\r
- }\r
- prout(" disappears.");\r
- game.quad[ix][iy] = IHWEB;\r
- ithere = ithx = ithy = 0;\r
- nenhere--;\r
- {\r
- int dum, my;\r
- dropin(IHBLANK, &dum, &my);\r
- }\r
- return;\r
- \r
- default: /* Problem! */\r
- skip(1);\r
- proutn("Don't know how to handle collision with ");\r
- crmena(1, iquad, 2, ix, iy);\r
- skip(1);\r
- return;\r
- }\r
- break;\r
- }\r
-#ifdef SERGEEV\r
- if(curwnd!=4) {\r
- setwnd(4);\r
- gotoxy(crx,cry);\r
- }\r
-#endif /* SERGEEV */\r
- if (shoved) {\r
- game.quad[jx][jy]=iquad;\r
- game.quad[ix][iy]=IHDOT;\r
- prout(" displaced by blast to %s ", cramlc(sector, jx, jy));\r
- for (ll=1; ll<=nenhere; ll++)\r
- game.kdist[ll] = game.kavgd[ll] = sqrt(square(sectx-game.kx[ll])+square(secty-game.ky[ll]));\r
- sortkl();\r
- return;\r
- }\r
-#ifndef SERGEEV\r
- skip(1);\r
-#endif /* SERGEEV */\r
- prout("Torpedo missed.");\r
- return;\r
-}\r
-\r
-static void fry(double hit) {\r
- double ncrit, extradm;\r
- int ktr=1, l, ll, j, cdam[NDEVICES+1];\r
-\r
- /* a critical hit occured */\r
- if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;\r
-\r
- ncrit = 1.0 + hit/(500.0+100.0*Rand());\r
- proutn("***CRITICAL HIT--");\r
- /* Select devices and cause damage */\r
- for (l = 1; l <= ncrit && l <= NDEVICES; l++) {\r
- do {\r
- j = NDEVICES*Rand()+1.0;\r
- /* Cheat to prevent shuttle damage unless on ship */\r
- } while (game.damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||\r
- j == DDRAY);\r
- cdam[l] = j;\r
- extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));\r
- game.damage[j] += extradm;\r
- if (l > 1) {\r
- for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;\r
- if (ll<=l) continue;\r
- ktr += 1;\r
- if (ktr==3) skip(1);\r
- proutn(" and ");\r
- }\r
- proutn(device[j]);\r
- }\r
- prout(" damaged.");\r
- if (game.damage[DSHIELD] && shldup) {\r
- prout("***Shields knocked down.");\r
- shldup=0;\r
- }\r
-}\r
-\r
-void attack(int k) {\r
- /* k == 0 forces use of phasers in an attack */\r
- int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;\r
- int atackd = 0, attempt = 0;\r
- double hit;\r
- double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;\r
-\r
- iattak = 1;\r
- if (alldone) return;\r
-#ifdef DEBUG\r
- if (idebug) prout("ATTACK!");\r
-#endif\r
-\r
- if (ithere) movetho();\r
-\r
- if (neutz) { /* The one chance not to be attacked */\r
- neutz = 0;\r
- return;\r
- }\r
- if ((((comhere || ishere) && (justin == 0)) || skill == 5)&&(k!=0)) movcom();\r
- if (nenhere==0 || (nenhere==1 && iqhere && iqengry==0)) return;\r
- pfac = 1.0/inshld;\r
- if (shldchg == 1) chgfac = 0.25+0.5*Rand();\r
- skip(1);\r
- if (skill <= 2) i = 2;\r
- for (l=1; l <= nenhere; l++) {\r
- if (game.kpower[l] < 0) continue; /* too weak to attack */\r
- /* compute hit strength and diminsh shield power */\r
- r = Rand();\r
- /* Increase chance of photon torpedos if docked or enemy energy low */\r
- if (condit == IHDOCKED) r *= 0.25;\r
- if (game.kpower[l] < 500) r *= 0.25; \r
- jx = game.kx[l];\r
- jy = game.ky[l];\r
- iquad = game.quad[jx][jy];\r
- if (iquad==IHT || (iquad==IHQUEST && !iqengry)) continue;\r
- itflag = (iquad == IHK && r > 0.0005) || k == 0 ||\r
- (iquad==IHC && r > 0.015) ||\r
- (iquad==IHR && r > 0.3) ||\r
- (iquad==IHS && r > 0.07) ||\r
- (iquad==IHQUEST && r > 0.05);\r
- if (itflag) {\r
- /* Enemy uses phasers */\r
- if (condit == IHDOCKED) continue; /* Don't waste the effort! */\r
- attempt = 1; /* Attempt to attack */\r
- dustfac = 0.8+0.05*Rand();\r
- hit = game.kpower[l]*pow(dustfac,game.kavgd[l]);\r
- game.kpower[l] *= 0.75;\r
- }\r
- else { /* Enemy used photon torpedo */\r
- double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);\r
- hit = 0;\r
- proutn("***TORPEDO INCOMING");\r
- if (game.damage[DSRSENS] <= 0.0) {\r
- proutn(" From ");\r
- crmena(0, iquad, i, jx, jy);\r
- }\r
- attempt = 1;\r
- prout(" ");\r
- r = (Rand()+Rand())*0.5 -0.5;\r
- r += 0.002*game.kpower[l]*r;\r
- torpedo(course, r, jx, jy, &hit, 0);\r
- if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */\r
- if (game.state.galaxy[quadx][quady] == 1000 ||\r
- alldone) return; /* Supernova or finished */\r
- if (hit == 0) continue;\r
- }\r
- if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {\r
- /* shields will take hits */\r
- double absorb, hitsh, propor = pfac*shield*(condit==IHDOCKED ? 2.1 : 1.0);\r
- if(propor < 0.1) propor = 0.1;\r
- hitsh = propor*chgfac*hit+1.0;\r
- atackd=1;\r
- absorb = 0.8*hitsh;\r
- if (absorb > shield) absorb = shield;\r
- shield -= absorb;\r
- hit -= hitsh;\r
- if (condit==IHDOCKED) dock(0);\r
- if (propor > 0.1 && hit < 0.005*energy) continue;\r
- }\r
- /* It's a hit -- print out hit size */\r
- atackd = 1; /* We weren't going to check casualties, etc. if\r
- shields were down for some strange reason. This\r
- doesn't make any sense, so I've fixed it */\r
- ihurt = 1;\r
- proutn("%d unit hit", (int)hit);\r
- if ((game.damage[DSRSENS] > 0 && itflag) || skill <= 2) {\r
- proutn(" on the ");\r
- crmshp();\r
- }\r
- if (game.damage[DSRSENS] <= 0.0 && itflag) {\r
- proutn(" from ");\r
- crmena(0, iquad, i, jx, jy);\r
- }\r
- skip(1);\r
- /* Decide if hit is critical */\r
- if (hit > hitmax) hitmax = hit;\r
- hittot += hit;\r
- fry(hit);\r
- prout("Hit %g energy %g", hit, energy);\r
- energy -= hit;\r
- if (condit==IHDOCKED) dock(0);\r
- }\r
- if (energy <= 0) {\r
- /* Returning home upon your shield, not with it... */\r
- finish(FBATTLE);\r
- return;\r
- }\r
- if (attempt == 0 && condit == IHDOCKED)\r
- prout("***Enemies decide against attacking your ship.");\r
- if (atackd == 0) return;\r
- percent = 100.0*pfac*shield+0.5;\r
- if (ihurt==0) {\r
- /* Shields fully protect ship */\r
- proutn("Enemy attack reduces shield strength to ");\r
- }\r
- else {\r
- /* Print message if starship suffered hit(s) */\r
- skip(1);\r
- proutn("Energy left %2d shields ", (int)energy);\r
- if (shldup) proutn("up ");\r
- else if (game.damage[DSHIELD] == 0) proutn("down ");\r
- else proutn("damaged, ");\r
- }\r
- prout("%d%%, torpedoes left %d", percent, torps);\r
- /* Check if anyone was hurt */\r
- if (hitmax >= 200 || hittot >= 500) {\r
- int icas= hittot*Rand()*0.015;\r
- if (icas >= 2) {\r
- skip(1);\r
- prout("Mc Coy- \"Sickbay to bridge. We suffered %d casualties", icas);\r
- prout(" in that last attack.\"");\r
- casual += icas;\r
- }\r
- }\r
- /* After attack, reset average distance to enemies */\r
- for (l = 1; l <= nenhere; l++)\r
- game.kavgd[l] = game.kdist[l];\r
- sortkl();\r
- return;\r
-}\r
- \r
-void deadkl(int ix, int iy, int type, int ixx, int iyy) {\r
- /* Added ixx and iyy allow enemy to "move" before dying */\r
-\r
- int i,j;\r
-\r
-#ifdef SERGEEV \r
- skip(1);\r
-#endif /* SERGEEV */\r
- crmena(1, type, 2, ixx, iyy);\r
- /* Decide what kind of enemy it is and update approriately */\r
- if (type == IHR) {\r
- /* chalk up a Romulan */\r
- game.state.newstuf[quadx][quady] -= 10;\r
- irhere--;\r
- game.state.nromkl++;\r
- game.state.nromrem--;\r
- }\r
- else if (type == IHT) {\r
- /* Killed a Tholian */\r
- ithere = 0;\r
- }\r
- else if (type == IHQUEST) {\r
- /* Killed a Thingy */\r
- iqhere=iqengry=thingx=thingy=0;\r
- }\r
- else {\r
- /* Some type of a Klingon */\r
- game.state.galaxy[quadx][quady] -= 100;\r
- klhere--;\r
- game.state.remkl--;\r
- switch (type) {\r
- case IHC:\r
- comhere = 0;\r
- for (i=1; i<=game.state.remcom; i++)\r
- if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;\r
- game.state.cx[i] = game.state.cx[game.state.remcom];\r
- game.state.cy[i] = game.state.cy[game.state.remcom];\r
- game.state.cx[game.state.remcom] = 0;\r
- game.state.cy[game.state.remcom] = 0;\r
- game.state.remcom--;\r
- game.future[FTBEAM] = 1e30;\r
- if (game.state.remcom != 0)\r
- game.future[FTBEAM] = game.state.date + expran(1.0*incom/game.state.remcom);\r
- game.state.killc++;\r
- break;\r
- case IHK:\r
- game.state.killk++;\r
- break;\r
- case IHS:\r
- game.state.nscrem = ishere = game.state.isx = game.state.isy = isatb = iscate = 0;\r
- game.state.nsckill = 1;\r
- game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
- break;\r
- }\r
- }\r
-\r
- /* For each kind of enemy, finish message to player */\r
- prout(" destroyed.");\r
- game.quad[ix][iy] = IHDOT;\r
- if (game.state.remkl==0) return;\r
-\r
- game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);\r
-\r
- /* Remove enemy ship from arrays describing local conditions */\r
- if (game.future[FCDBAS] < 1e30 && batx==quadx && baty==quady && type==IHC)\r
- game.future[FCDBAS] = 1e30;\r
- for (i=1; i<=nenhere; i++)\r
- if (game.kx[i]==ix && game.ky[i]==iy) break;\r
- nenhere--;\r
- if (i <= nenhere) {\r
- for (j=i; j<=nenhere; j++) {\r
- game.kx[j] = game.kx[j+1];\r
- game.ky[j] = game.ky[j+1];\r
- game.kpower[j] = game.kpower[j+1];\r
- game.kavgd[j] = game.kdist[j] = game.kdist[j+1];\r
- }\r
- }\r
- game.kx[nenhere+1] = 0;\r
- game.ky[nenhere+1] = 0;\r
- game.kdist[nenhere+1] = 0;\r
- game.kavgd[nenhere+1] = 0;\r
- game.kpower[nenhere+1] = 0;\r
- return;\r
-}\r
-\r
-static int targetcheck(double x, double y, double *course) {\r
- double deltx, delty;\r
- /* Return TRUE if target is invalid */\r
- if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {\r
- huh();\r
- return 1;\r
- }\r
- deltx = 0.1*(y - secty);\r
- delty = 0.1*(sectx - x);\r
- if (deltx==0 && delty== 0) {\r
- skip(1);\r
- prout("Spock- \"Bridge to sickbay. Dr. McCoy,");\r
- prout(" I recommend an immediate review of");\r
- prout(" the Captain's psychological profile.\"");\r
- chew();\r
- return 1;\r
- }\r
- *course = 1.90985932*atan2(deltx, delty);\r
- return 0;\r
-}\r
-\r
-void photon(void) {\r
- double targ[4][3], course[4];\r
- double r, dummy;\r
- int key, n, i, osuabor;\r
-\r
- ididit = 0;\r
-\r
- if (game.damage[DPHOTON]) {\r
- prout("Photon tubes damaged.");\r
- chew();\r
- return;\r
- }\r
- if (torps == 0) {\r
- prout("No torpedoes left.");\r
- chew();\r
- return;\r
- }\r
- key = scan();\r
- for (;;) {\r
- if (key == IHALPHA) {\r
- huh();\r
- return;\r
- }\r
- else if (key == IHEOL) {\r
- prout("%d torpedoes left.", torps);\r
- proutn("Number of torpedoes to fire- ");\r
- key = scan();\r
- }\r
- else /* key == IHREAL */ {\r
- n = aaitem + 0.5;\r
- if (n <= 0) { /* abort command */\r
- chew();\r
- return;\r
- }\r
- if (n > 3) {\r
- chew();\r
- prout("Maximum of 3 torpedoes per burst.");\r
- key = IHEOL;\r
- return;\r
- }\r
- if (n <= torps) break;\r
- chew();\r
- key = IHEOL;\r
- }\r
- }\r
- for (i = 1; i <= n; i++) {\r
- key = scan();\r
- if (i==1 && key == IHEOL) {\r
- break; /* we will try prompting */\r
- }\r
- if (i==2 && key == IHEOL) {\r
- /* direct all torpedoes at one target */\r
- while (i <= n) {\r
- targ[i][1] = targ[1][1];\r
- targ[i][2] = targ[1][2];\r
- course[i] = course[1];\r
- i++;\r
- }\r
- break;\r
- }\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- targ[i][1] = aaitem;\r
- key = scan();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- targ[i][2] = aaitem;\r
- if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
- }\r
- chew();\r
- if (i == 1 && key == IHEOL) {\r
- /* prompt for each one */\r
- for (i = 1; i <= n; i++) {\r
- proutn("Target sector for torpedo number %d- ", i);\r
- key = scan();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- targ[i][1] = aaitem;\r
- key = scan();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- targ[i][2] = aaitem;\r
- chew();\r
- if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;\r
- }\r
- }\r
- ididit = 1;\r
- /* Loop for moving <n> torpedoes */\r
- osuabor = 0;\r
- for (i = 1; i <= n && !osuabor; i++) {\r
- if (condit != IHDOCKED) torps--;\r
- r = (Rand()+Rand())*0.5 -0.5;\r
- if (fabs(r) >= 0.47) {\r
- /* misfire! */\r
- r = (Rand()+1.2) * r;\r
- if (n>1) {\r
- prouts("***TORPEDO NUMBER %d MISFIRES", i);\r
- }\r
- else prouts("***TORPEDO MISFIRES.");\r
- skip(1);\r
- if (i < n)\r
- prout(" Remainder of burst aborted.");\r
- osuabor=1;\r
- if (Rand() <= 0.2) {\r
- prout("***Photon tubes damaged by misfire.");\r
- game.damage[DPHOTON] = damfac*(1.0+2.0*Rand());\r
- break;\r
- }\r
- }\r
- if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;\r
-#ifndef SERGEEV\r
- if (n != 1) {\r
- skip(1);\r
- proutn("Track for torpedo number %d- ", i);\r
- }\r
- else {\r
- skip(1);\r
- proutn("Torpedo track- ");\r
- }\r
-#endif /* SERGEEV */\r
- torpedo(course[i], r, sectx, secty, &dummy, i);\r
- if (alldone || game.state.galaxy[quadx][quady]==1000) return;\r
- }\r
- if (game.state.remkl==0) finish(FWON);\r
-}\r
-\r
- \r
-\r
-static void overheat(double rpow) {\r
- if (rpow > 1500) {\r
- double chekbrn = (rpow-1500.)*0.00038;\r
- if (Rand() <= chekbrn) {\r
- prout("Weapons officer Sulu- \"Phasers overheated, sir.\"");\r
- game.damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);\r
- }\r
- }\r
-}\r
-\r
-static int checkshctrl(double rpow) {\r
- double hit;\r
- int icas;\r
- \r
- skip(1);\r
- if (Rand() < .998) {\r
- prout("Shields lowered.");\r
- return 0;\r
- }\r
- /* Something bad has happened */\r
- prouts("***RED ALERT! RED ALERT!");\r
- skip(2);\r
- hit = rpow*shield/inshld;\r
- energy -= rpow+hit*0.8;\r
- shield -= hit*0.2;\r
- if (energy <= 0.0) {\r
- prouts("Sulu- \"Captain! Shield malf***********************\"");\r
- skip(1);\r
- stars();\r
- finish(FPHASER);\r
- return 1;\r
- }\r
- prouts("Sulu- \"Captain! Shield malfunction! Phaser fire contained!\"");\r
- skip(2);\r
- prout("Lt. Uhura- \"Sir, all decks reporting damage.\"");\r
- icas = hit*Rand()*0.012;\r
- skip(1);\r
- fry(0.8*hit);\r
- if (icas) {\r
- skip(1);\r
- prout("McCoy to bridge- \"Severe radiation burns, Jim.");\r
- prout(" %d casualties so far.\"", icas);\r
- casual -= icas;\r
- }\r
- skip(1);\r
- prout("Phaser energy dispersed by shields.");\r
- prout("Enemy unaffected.");\r
- overheat(rpow);\r
- return 1;\r
-}\r
- \r
-\r
-void phasers(void) {\r
- double hits[21], rpow=0, extra, powrem, over, temp;\r
- int kz = 0, k=1, i, irec=0; /* Cheating inhibitor */\r
- int ifast=0, no=0, ipoop=1, msgflag = 1;\r
- enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;\r
- int key=0;\r
-\r
- skip(1);\r
- /* SR sensors and Computer */\r
- if (game.damage[DSRSENS]+game.damage[DCOMPTR] > 0) ipoop = 0;\r
- if (condit == IHDOCKED) {\r
- prout("Phasers can't be fired through base shields.");\r
- chew();\r
- return;\r
- }\r
- if (game.damage[DPHASER] != 0) {\r
- prout("Phaser control damaged.");\r
- chew();\r
- return;\r
- }\r
- if (shldup) {\r
- if (game.damage[DSHCTRL]) {\r
- prout("High speed shield control damaged.");\r
- chew();\r
- return;\r
- }\r
- if (energy <= 200.0) {\r
- prout("Insufficient energy to activate high-speed shield control.");\r
- chew();\r
- return;\r
- }\r
- prout("Weapons Officer Sulu- \"High-speed shield control enabled, sir.\"");\r
- ifast = 1;\r
- \r
- }\r
- /* Original code so convoluted, I re-did it all */\r
- while (automode==NOTSET) {\r
- key=scan();\r
- if (key == IHALPHA) {\r
- if (isit("manual")) {\r
- if (nenhere==0) {\r
- prout("There is no enemy present to select.");\r
- chew();\r
- key = IHEOL;\r
- automode=AUTOMATIC;\r
- }\r
- else {\r
- automode = MANUAL;\r
- key = scan();\r
- }\r
- }\r
- else if (isit("automatic")) {\r
- if ((!ipoop) && nenhere != 0) {\r
- automode = FORCEMAN;\r
- }\r
- else {\r
- if (nenhere==0)\r
- prout("Energy will be expended into space.");\r
- automode = AUTOMATIC;\r
- key = scan();\r
- }\r
- }\r
- else if (isit("no")) {\r
- no = 1;\r
- }\r
- else {\r
- huh();\r
- return;\r
- }\r
- }\r
- else if (key == IHREAL) {\r
- if (nenhere==0) {\r
- prout("Energy will be expended into space.");\r
- automode = AUTOMATIC;\r
- }\r
- else if (!ipoop)\r
- automode = FORCEMAN;\r
- else\r
- automode = AUTOMATIC;\r
- }\r
- else {\r
- /* IHEOL */\r
- if (nenhere==0) {\r
- prout("Energy will be expended into space.");\r
- automode = AUTOMATIC;\r
- }\r
- else if (!ipoop)\r
- automode = FORCEMAN;\r
- else \r
- proutn("Manual or automatic? ");\r
- }\r
- }\r
- \r
- switch (automode) {\r
- case AUTOMATIC:\r
- if (key == IHALPHA && isit("no")) {\r
- no = 1;\r
- key = scan();\r
- }\r
- if (key != IHREAL && nenhere != 0) {\r
- prout("Phasers locked on target. Energy available: %.2f",\r
- ifast?energy-200.0:energy,1,2);\r
- }\r
- irec=0;\r
- do {\r
- chew();\r
- if (!kz) for (i = 1; i <= nenhere; i++)\r
- irec+=fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]))*\r
- (1.01+0.05*Rand()) + 1.0;\r
- kz=1;\r
- proutn("(%d) units required. ", irec);\r
- chew();\r
- proutn("Units to fire= ");\r
- key = scan();\r
- if (key!=IHREAL) return;\r
- rpow = aaitem;\r
- if (rpow > (ifast?energy-200:energy)) {\r
- proutn("Energy available= %.2f",\r
- ifast?energy-200:energy);\r
- skip(1);\r
- key = IHEOL;\r
- }\r
- } while (rpow > (ifast?energy-200:energy));\r
- if (rpow<=0) {\r
- /* chicken out */\r
- chew();\r
- return;\r
- }\r
- if ((key=scan()) == IHALPHA && isit("no")) {\r
- no = 1;\r
- }\r
- if (ifast) {\r
- energy -= 200; /* Go and do it! */\r
- if (checkshctrl(rpow)) return;\r
- }\r
- chew();\r
- energy -= rpow;\r
- extra = rpow;\r
- if (nenhere) {\r
- extra = 0.0;\r
- powrem = rpow;\r
- for (i = 1; i <= nenhere; i++) {\r
- hits[i] = 0.0;\r
- if (powrem <= 0) continue;\r
- hits[i] = fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]));\r
- over = (0.01 + 0.05*Rand())*hits[i];\r
- temp = powrem;\r
- powrem -= hits[i] + over;\r
- if (powrem <= 0 && temp < hits[i]) hits[i] = temp;\r
- if (powrem <= 0) over = 0.0;\r
- extra += over;\r
- }\r
- if (powrem > 0.0) extra += powrem;\r
- hittem(hits);\r
- ididit=1;\r
- }\r
- if (extra > 0 && alldone == 0) {\r
- if (ithere) {\r
- proutn("*** Tholian web absorbs ");\r
- if (nenhere>0) proutn("excess ");\r
- prout("phaser energy.");\r
- }\r
- else {\r
- prout("%d expended on empty space.", (int)extra);\r
- }\r
- }\r
- break;\r
-\r
- case FORCEMAN:\r
- chew();\r
- key = IHEOL;\r
- if (game.damage[DCOMPTR]!=0)\r
- prout("Battle comuter damaged, manual file only.");\r
- else {\r
- skip(1);\r
- prouts("---WORKING---");\r
- skip(1);\r
- prout("Short-range-sensors-damaged");\r
- prout("Insufficient-data-for-automatic-phaser-fire");\r
- prout("Manual-fire-must-be-used");\r
- skip(1);\r
- }\r
- case MANUAL:\r
- rpow = 0.0;\r
- for (k = 1; k <= nenhere;) {\r
- int ii = game.kx[k], jj = game.ky[k];\r
- int ienm = game.quad[ii][jj];\r
- if (msgflag) {\r
- proutn("Energy available= %.2f",\r
- energy-.006-(ifast?200:0));\r
- skip(1);\r
- msgflag = 0;\r
- rpow = 0.0;\r
- }\r
- if (game.damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&\r
- (ienm == IHC || ienm == IHS)) {\r
- cramen(ienm);\r
- prout(" can't be located without short range scan.");\r
- chew();\r
- key = IHEOL;\r
- hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */\r
- k++;\r
- continue;\r
- }\r
- if (key == IHEOL) {\r
- chew();\r
- if (ipoop && k > kz)\r
- irec=(fabs(game.kpower[k])/(PHASEFAC*pow(0.9,game.kdist[k])))*\r
- (1.01+0.05*Rand()) + 1.0;\r
- kz = k;\r
- proutn("(");\r
- if (game.damage[DCOMPTR]==0) proutn("%d", irec);\r
- else proutn("??");\r
- proutn(") ");\r
- proutn("units to fire at ");\r
- crmena(0, ienm, 2, ii, jj);\r
- proutn("- ");\r
- key = scan();\r
- }\r
- if (key == IHALPHA && isit("no")) {\r
- no = 1;\r
- key = scan();\r
- continue;\r
- }\r
- if (key == IHALPHA) {\r
- huh();\r
- return;\r
- }\r
- if (key == IHEOL) {\r
- if (k==1) { /* Let me say I'm baffled by this */\r
- msgflag = 1;\r
- }\r
- continue;\r
- }\r
- if (aaitem < 0) {\r
- /* abort out */\r
- chew();\r
- return;\r
- }\r
- hits[k] = aaitem;\r
- rpow += aaitem;\r
- /* If total requested is too much, inform and start over */\r
- \r
- if (rpow > (ifast?energy-200:energy)) {\r
- prout("Available energy exceeded -- try again.");\r
- chew();\r
- return;\r
- }\r
- key = scan(); /* scan for next value */\r
- k++;\r
- }\r
- if (rpow == 0.0) {\r
- /* zero energy -- abort */\r
- chew();\r
- return;\r
- }\r
- if (key == IHALPHA && isit("no")) {\r
- no = 1;\r
- }\r
- energy -= rpow;\r
- chew();\r
- if (ifast) {\r
- energy -= 200.0;\r
- if (checkshctrl(rpow)) return;\r
- }\r
- hittem(hits);\r
- ididit=1;\r
- case NOTSET:; /* avoid gcc warning */\r
- }\r
- /* Say shield raised or malfunction, if necessary */\r
- if (alldone) return;\r
- if (ifast) {\r
- skip(1);\r
- if (no == 0) {\r
- if (Rand() >= 0.99) {\r
- prout("Sulu- \"Sir, the high-speed shield control has malfunctioned . . .");\r
- prouts(" CLICK CLICK POP . . .");\r
- prout(" No response, sir!");\r
- shldup = 0;\r
- }\r
- else\r
- prout("Shields raised.");\r
- }\r
- else\r
- shldup = 0;\r
- }\r
- overheat(rpow);\r
-}\r
-\r
-void hittem(double *hits) {\r
- double kp, kpow, wham, hit, dustfac, kpini;\r
-#ifdef SERGEEV\r
- int cx, cy;\r
-#endif /* SERGEEV */\r
- int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;\r
-\r
- skip(1);\r
-\r
- for (; k <= nenhr2; k++, kk++) {\r
- if ((wham = hits[k])==0) continue;\r
- dustfac = 0.9 + 0.01*Rand();\r
- hit = wham*pow(dustfac,game.kdist[kk]);\r
- kpini = game.kpower[kk];\r
- kp = fabs(kpini);\r
- if (PHASEFAC*hit < kp) kp = PHASEFAC*hit;\r
- game.kpower[kk] -= (game.kpower[kk] < 0 ? -kp: kp);\r
- kpow = game.kpower[kk];\r
- ii = game.kx[kk];\r
- jj = game.ky[kk];\r
- if (hit > 0.005) {\r
-#ifdef SERGEEV\r
- if (game.damage[DSRSENS]==0){\r
- crx=wherex();\r
- cry=wherey();\r
- setwnd(1);\r
- drawmaps(2);\r
- gotoxy(jj*2+3,ii+2);\r
- highvideo();\r
- proutn("%c", game.quad[ii][jj]);\r
- gotoxy(wherex()-1,wherey());\r
- sound(500);\r
- delay(1000);\r
- nosound();\r
- lowvideo();\r
- proutn("%c", game.quad[ii][jj]);\r
- setwnd(4);\r
- gotoxy(crx,cry);\r
- _setcursortype(_NORMALCURSOR);\r
- delay(500);\r
- }\r
-#endif /* SERGEEV */\r
- proutn("%d unit hit on ", (int)hit);\r
- }\r
- else\r
- proutn("Very small hit on ");\r
- ienm = game.quad[ii][jj];\r
- if (ienm==IHQUEST) iqengry=1;\r
- crmena(0,ienm,2,ii,jj);\r
- skip(1);\r
- if (kpow == 0) {\r
- deadkl(ii, jj, ienm, ii, jj);\r
- if (game.state.remkl==0) finish(FWON);\r
- if (alldone) return;\r
- kk--; /* don't do the increment */\r
- }\r
- else /* decide whether or not to emasculate klingon */\r
- if (kpow > 0 && Rand() >= 0.9 &&\r
- kpow <= ((0.4 + 0.4*Rand())*kpini)) {\r
- prout("***Mr. Spock- \"Captain, the vessel at ",\r
- cramlc(sector,ii,jj));\r
- prout(" has just lost its firepower.\"");\r
- game.kpower[kk] = -kpow;\r
- }\r
- }\r
- return;\r
-}\r
-\r
+#ifdef SERGEEV
+#include <conio.h>
+#include <unistd.h>
+#include "sstlinux.h"
+#endif /* SERGEEV */
+#include "sst.h"
+
+void doshield(int i) {
+ int key;
+ enum {NONE, SHUP, SHDN, NRG} action = NONE;
+
+ ididit = 0;
+
+ if (i == 2) action = SHUP;
+ else {
+ key = scan();
+ if (key == IHALPHA) {
+ if (isit("transfer"))
+ action = NRG;
+ else {
+ chew();
+ if (game.damage[DSHIELD]) {
+ prout("Shields damaged and down.");
+ return;
+ }
+ if (isit("up"))
+ action = SHUP;
+ else if (isit("down"))
+ action = SHDN;
+ }
+ }
+ if (action==NONE) {
+ proutn("Do you wish to change shield energy? ");
+ if (ja()) {
+ proutn("Energy to transfer to shields- ");
+ action = NRG;
+ }
+ else if (game.damage[DSHIELD]) {
+ prout("Shields damaged and down.");
+ return;
+ }
+ else if (shldup) {
+ proutn("Shields are up. Do you want them down? ");
+ if (ja()) action = SHDN;
+ else {
+ chew();
+ return;
+ }
+ }
+ else {
+ proutn("Shields are down. Do you want them up? ");
+ if (ja()) action = SHUP;
+ else {
+ chew();
+ return;
+ }
+ }
+ }
+ }
+ switch (action) {
+ case SHUP: /* raise shields */
+ if (shldup) {
+ prout("Shields already up.");
+ return;
+ }
+ shldup = 1;
+ shldchg = 1;
+ if (condit != IHDOCKED) energy -= 50.0;
+ prout("Shields raised.");
+ if (energy <= 0) {
+ skip(1);
+ prout("Shields raising uses up last of energy.");
+ finish(FNRG);
+ return;
+ }
+ ididit=1;
+ return;
+ case SHDN:
+ if (shldup==0) {
+ prout("Shields already down.");
+ return;
+ }
+ shldup=0;
+ shldchg=1;
+ prout("Shields lowered.");
+ ididit=1;
+ return;
+ case NRG:
+ while (scan() != IHREAL) {
+ chew();
+ proutn("Energy to transfer to shields- ");
+ }
+ chew();
+ if (aaitem==0) return;
+ if (aaitem > energy) {
+ prout("Insufficient ship energy.");
+ return;
+ }
+ ididit = 1;
+ if (shield+aaitem >= inshld) {
+ prout("Shield energy maximized.");
+ if (shield+aaitem > inshld) {
+ prout("Excess energy requested returned to ship energy");
+ }
+ energy -= inshld-shield;
+ shield = inshld;
+ return;
+ }
+ if (aaitem < 0.0 && energy-aaitem > inenrg) {
+ /* Prevent shield drain loophole */
+ skip(1);
+ prout("Engineering to bridge--");
+ prout(" Scott here. Power circuit problem, Captain.");
+ prout(" I can't drain the shields.");
+ ididit = 0;
+ return;
+ }
+ if (shield+aaitem < 0) {
+ prout("All shield energy transferred to ship.");
+ energy += shield;
+ shield = 0.0;
+ return;
+ }
+ proutn("Scotty- \"");
+ if (aaitem > 0)
+ prout("Transferring energy to shields.\"");
+ else
+ prout("Draining energy from shields.\"");
+ shield += aaitem;
+ energy -= aaitem;
+ return;
+ case NONE:; /* avoid gcc warning */
+ }
+}
+
+void ram(int ibumpd, int ienm, int ix, int iy) {
+ double type = 1.0, extradm;
+ int icas, l;
+
+ prouts("***RED ALERT! RED ALERT!");
+ skip(1);
+ prout("***COLLISION IMMINENT.");
+ skip(2);
+ proutn("***");
+ crmshp();
+ switch (ienm) {
+ case IHR: type = 1.5; break;
+ case IHC: type = 2.0; break;
+ case IHS: type = 2.5; break;
+ case IHT: type = 0.5; break;
+ case IHQUEST: type = 4.0; break;
+ }
+ proutn(ibumpd ? " rammed by " : " rams ");
+ crmena(0, ienm, 2, ix, iy);
+ if (ibumpd) proutn(" (original position)");
+ skip(1);
+ deadkl(ix, iy, ienm, sectx, secty);
+ proutn("***");
+ crmshp();
+ prout(" heavily damaged.");
+ icas = 10.0+20.0*Rand();
+ prout("***Sickbay reports %d casualties", icas);
+ casual += icas;
+ for (l=1; l <= NDEVICES; l++) {
+ if (l == DDRAY) continue; // Don't damage deathray
+ if (game.damage[l] < 0) continue;
+ extradm = (10.0*type*Rand()+1.0)*damfac;
+ game.damage[l] += Time + extradm; /* Damage for at least time of travel! */
+ }
+ shldup = 0;
+ if (game.state.remkl) {
+ pause_game(2);
+ dreprt();
+ }
+ else finish(FWON);
+ return;
+}
+
+void torpedo(double course, double r, int inx, int iny, double *hit, int wait) {
+ int l, iquad=0, ix=0, iy=0, jx=0, jy=0, shoved=0, ll;
+#ifdef SERGEEV
+ int crx,cry;
+
+#endif /* SERGEEV */
+ double ac=course + 0.25*r;
+ double angle = (15.0-ac)*0.5235988;
+ double bullseye = (15.0 - course)*0.5235988;
+ double deltax=-sin(angle), deltay=cos(angle), x=inx, y=iny, bigger;
+ double ang, temp, xx, yy, kp, h1;
+
+ bigger = fabs(deltax);
+ if (fabs(deltay) > bigger) bigger = fabs(deltay);
+ deltax /= bigger;
+ deltay /= bigger;
+#ifdef SERGEEV
+ crx=wherex();
+ cry=wherey();
+ if (game.damage[DSRSENS]==0 || condit==IHDOCKED) setwnd(1);
+ else setwnd(4);
+#endif /* SERGEEV */
+ /* Loop to move a single torpedo */
+ for (l=1; l <= 15; l++) {
+ x += deltax;
+ ix = x + 0.5;
+ if (ix < 1 || ix > 10) break;
+ y += deltay;
+ iy = y + 0.5;
+ if (iy < 1 || iy > 10) break;
+#ifndef SERGEEV
+ if (l==4 || l==9) skip(1);
+ proutn("%d - %d ", (int)x, (int)y);
+ iquad=game.quad[ix][iy];
+#else
+ iquad=game.quad[ix][iy];
+ if (game.damage[DSRSENS]==0 || condit==IHDOCKED){
+ drawmaps(2);
+ delay((wait!=1)*400);
+ wait=1;
+ gotoxy(iy*2+3,ix+2);
+ if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){
+ game.quad[ix][iy]='+';
+ drawmaps(2);
+ game.quad[ix][iy]=iquad;
+ sound(l*10);
+ delay(100);
+ nosound();
+ }
+ else {
+ game.quad[ix][iy]|=128;
+ drawmaps(2);
+ game.quad[ix][iy]=iquad;
+ _setcursortype(_NOCURSOR);
+ sound(500);
+ delay(1000);
+ nosound();
+ lowvideo();
+ _setcursortype(_NORMALCURSOR);
+ }
+ }
+ else {
+ proutn("%d - %d ", (int)x, (int)y);
+ }
+#endif /* SERGEEV */
+ if (iquad==IHDOT) continue;
+ /* hit something */
+#ifndef SERGEEV
+ skip(1);
+#else
+ setwnd(4);
+ gotoxy(crx,cry);
+#endif
+ switch(iquad) {
+ case IHE: /* Hit our ship */
+ case IHF:
+ skip(1);
+ proutn("Torpedo hits ");
+ crmshp();
+ prout(".");
+ *hit = 700.0 + 100.0*Rand() -
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+ fabs(sin(bullseye-angle));
+ *hit = fabs(*hit);
+#ifndef SERGEEV
+ newcnd(); /* undock */
+#endif /* SERGEEV */
+ /* We may be displaced. */
+ if (landed==1 || condit==IHDOCKED) return; /* Cheat if on a planet */
+ ang = angle + 2.5*(Rand()-0.5);
+ temp = fabs(sin(ang));
+ if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
+ xx = -sin(ang)/temp;
+ yy = cos(ang)/temp;
+ jx=ix+xx+0.5;
+ jy=iy+yy+0.5;
+ if (jx<1 || jx>10 || jy<1 ||jy > 10) return;
+ if (game.quad[jx][jy]==IHBLANK) {
+ finish(FHOLE);
+ return;
+ }
+ if (game.quad[jx][jy]!=IHDOT) {
+ /* can't move into object */
+ return;
+ }
+ sectx = jx;
+ secty = jy;
+ crmshp();
+ shoved = 1;
+ break;
+
+ case IHC: /* Hit a commander */
+ case IHS:
+ if (Rand() <= 0.05) {
+ crmena(1, iquad, 2, ix, iy);
+ prout(" uses anti-photon device;");
+ prout(" torpedo neutralized.");
+ return;
+ }
+ case IHR: /* Hit a regular enemy */
+ case IHK:
+ /* find the enemy */
+ for (ll=1; ll <= nenhere; ll++)
+ if (ix==game.kx[ll] && iy==game.ky[ll]) break;
+ kp = fabs(game.kpower[ll]);
+ h1 = 700.0 + 100.0*Rand() -
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+ fabs(sin(bullseye-angle));
+ h1 = fabs(h1);
+ if (kp < h1) h1 = kp;
+ game.kpower[ll] -= (game.kpower[ll]<0 ? -h1 : h1);
+ if (game.kpower[ll] == 0) {
+ deadkl(ix, iy, iquad, ix, iy);
+ return;
+ }
+ crmena(1, iquad, 2, ix, iy);
+ /* If enemy damaged but not destroyed, try to displace */
+ ang = angle + 2.5*(Rand()-0.5);
+ temp = fabs(sin(ang));
+ if (fabs(cos(ang)) > temp) temp = fabs(cos(ang));
+ xx = -sin(ang)/temp;
+ yy = cos(ang)/temp;
+ jx=ix+xx+0.5;
+ jy=iy+yy+0.5;
+ if (jx<1 || jx>10 || jy<1 ||jy > 10) {
+ prout(" damaged but not destroyed.");
+ return;
+ }
+ if (game.quad[jx][jy]==IHBLANK) {
+ prout(" buffeted into black hole.");
+ deadkl(ix, iy, iquad, jx, jy);
+ return;
+ }
+ if (game.quad[jx][jy]!=IHDOT) {
+ /* can't move into object */
+ prout(" damaged but not destroyed.");
+ return;
+ }
+ proutn(" damaged--");
+ game.kx[ll] = jx;
+ game.ky[ll] = jy;
+ shoved = 1;
+ break;
+ case IHB: /* Hit a base */
+ skip(1);
+ prout("***STARBASE DESTROYED..");
+ if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;
+ for (ll=1; ll<=game.state.rembase; ll++) {
+ if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {
+ game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];
+ game.state.baseqy[ll]=game.state.baseqy[game.state.rembase];
+ break;
+ }
+ }
+ game.quad[ix][iy]=IHDOT;
+ game.state.rembase--;
+ basex=basey=0;
+ game.state.galaxy[quadx][quady] -= 10;
+ game.state.basekl++;
+ newcnd();
+ return;
+ case IHP: /* Hit a planet */
+ crmena(1, iquad, 2, ix, iy);
+ prout(" destroyed.");
+ game.state.nplankl++;
+ game.state.newstuf[quadx][quady] -= 1;
+ DESTROY(&game.state.plnets[iplnet]);
+ iplnet = 0;
+ plnetx = plnety = 0;
+ game.quad[ix][iy] = IHDOT;
+ if (landed==1) {
+ /* captain parishes on planet */
+ finish(FDPLANET);
+ }
+ return;
+ case IHSTAR: /* Hit a star */
+ if (Rand() > 0.10) {
+ nova(ix, iy);
+ return;
+ }
+ crmena(1, IHSTAR, 2, ix, iy);
+ prout(" unaffected by photon blast.");
+ return;
+ case IHQUEST: /* Hit a thingy */
+ if (Rand()>0.7) { // Used to be certain death
+ skip(1);
+ prouts("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!");
+ skip(1);
+ prouts(" HACK! HACK! HACK! *CHOKE!* ");
+ skip(1);
+ proutn("Mr. Spock-");
+ prouts(" \"Fascinating!\"");
+ skip(1);
+ deadkl(ix, iy, iquad, ix, iy);
+ } else {
+ /*
+ * Stas Sergeev added the possibility that
+ * you can shove the Thingy.
+ */
+ iqengry=1;
+ shoved=1;
+ }
+ return;
+ case IHBLANK: /* Black hole */
+ skip(1);
+ crmena(1, IHBLANK, 2, ix, iy);
+ prout(" swallows torpedo.");
+ return;
+ case IHWEB: /* hit the web */
+ skip(1);
+ prout("***Torpedo absorbed by Tholian web.");
+ return;
+ case IHT: /* Hit a Tholian */
+ h1 = 700.0 + 100.0*Rand() -
+ 1000.0*sqrt(square(ix-inx)+square(iy-iny))*
+ fabs(sin(bullseye-angle));
+ h1 = fabs(h1);
+ if (h1 >= 600) {
+#ifndef SERGEEV
+ prout(" destroyed.");
+#endif /* SERGEEV */
+ game.quad[ix][iy] = IHDOT;
+ ithere = 0;
+ ithx = ithy = 0;
+#ifdef SERGEEV
+ deadkl(ix, iy, iquad, ix, iy);
+#endif /* SERGEEV */
+ return;
+ }
+ skip(1);
+ crmena(1, IHT, 2, ix, iy);
+ if (Rand() > 0.05) {
+ prout(" survives photon blast.");
+ return;
+ }
+ prout(" disappears.");
+ game.quad[ix][iy] = IHWEB;
+ ithere = ithx = ithy = 0;
+ nenhere--;
+ {
+ int dum, my;
+ dropin(IHBLANK, &dum, &my);
+ }
+ return;
+
+ default: /* Problem! */
+ skip(1);
+ proutn("Don't know how to handle collision with ");
+ crmena(1, iquad, 2, ix, iy);
+ skip(1);
+ return;
+ }
+ break;
+ }
+#ifdef SERGEEV
+ if(curwnd!=4) {
+ setwnd(4);
+ gotoxy(crx,cry);
+ }
+#endif /* SERGEEV */
+ if (shoved) {
+ game.quad[jx][jy]=iquad;
+ game.quad[ix][iy]=IHDOT;
+ prout(" displaced by blast to %s ", cramlc(sector, jx, jy));
+ for (ll=1; ll<=nenhere; ll++)
+ game.kdist[ll] = game.kavgd[ll] = sqrt(square(sectx-game.kx[ll])+square(secty-game.ky[ll]));
+ sortkl();
+ return;
+ }
+#ifndef SERGEEV
+ skip(1);
+#endif /* SERGEEV */
+ prout("Torpedo missed.");
+ return;
+}
+
+static void fry(double hit) {
+ double ncrit, extradm;
+ int ktr=1, l, ll, j, cdam[NDEVICES+1];
+
+ /* a critical hit occured */
+ if (hit < (275.0-25.0*skill)*(1.0+0.5*Rand())) return;
+
+ ncrit = 1.0 + hit/(500.0+100.0*Rand());
+ proutn("***CRITICAL HIT--");
+ /* Select devices and cause damage */
+ for (l = 1; l <= ncrit && l <= NDEVICES; l++) {
+ do {
+ j = NDEVICES*Rand()+1.0;
+ /* Cheat to prevent shuttle damage unless on ship */
+ } while (game.damage[j] < 0.0 || (j == DSHUTTL && iscraft != 1) ||
+ j == DDRAY);
+ cdam[l] = j;
+ extradm = (hit*damfac)/(ncrit*(75.0+25.0*Rand()));
+ game.damage[j] += extradm;
+ if (l > 1) {
+ for (ll=2; ll<=l && j != cdam[ll-1]; ll++) ;
+ if (ll<=l) continue;
+ ktr += 1;
+ if (ktr==3) skip(1);
+ proutn(" and ");
+ }
+ proutn(device[j]);
+ }
+ prout(" damaged.");
+ if (game.damage[DSHIELD] && shldup) {
+ prout("***Shields knocked down.");
+ shldup=0;
+ }
+}
+
+void attack(int k) {
+ /* k == 0 forces use of phasers in an attack */
+ int percent, ihurt=0, l, i=0, jx, jy, iquad, itflag;
+ int atackd = 0, attempt = 0;
+ double hit;
+ double pfac, dustfac, hitmax=0.0, hittot=0.0, chgfac=1.0, r;
+
+ iattak = 1;
+ if (alldone) return;
+#ifdef DEBUG
+ if (idebug) prout("ATTACK!");
+#endif
+
+ if (ithere) movetho();
+
+ if (neutz) { /* The one chance not to be attacked */
+ neutz = 0;
+ return;
+ }
+ if ((((comhere || ishere) && (justin == 0)) || skill == 5)&&(k!=0)) movcom();
+ if (nenhere==0 || (nenhere==1 && iqhere && iqengry==0)) return;
+ pfac = 1.0/inshld;
+ if (shldchg == 1) chgfac = 0.25+0.5*Rand();
+ skip(1);
+ if (skill <= 2) i = 2;
+ for (l=1; l <= nenhere; l++) {
+ if (game.kpower[l] < 0) continue; /* too weak to attack */
+ /* compute hit strength and diminsh shield power */
+ r = Rand();
+ /* Increase chance of photon torpedos if docked or enemy energy low */
+ if (condit == IHDOCKED) r *= 0.25;
+ if (game.kpower[l] < 500) r *= 0.25;
+ jx = game.kx[l];
+ jy = game.ky[l];
+ iquad = game.quad[jx][jy];
+ if (iquad==IHT || (iquad==IHQUEST && !iqengry)) continue;
+ itflag = (iquad == IHK && r > 0.0005) || k == 0 ||
+ (iquad==IHC && r > 0.015) ||
+ (iquad==IHR && r > 0.3) ||
+ (iquad==IHS && r > 0.07) ||
+ (iquad==IHQUEST && r > 0.05);
+ if (itflag) {
+ /* Enemy uses phasers */
+ if (condit == IHDOCKED) continue; /* Don't waste the effort! */
+ attempt = 1; /* Attempt to attack */
+ dustfac = 0.8+0.05*Rand();
+ hit = game.kpower[l]*pow(dustfac,game.kavgd[l]);
+ game.kpower[l] *= 0.75;
+ }
+ else { /* Enemy used photon torpedo */
+ double course = 1.90985*atan2((double)secty-jy, (double)jx-sectx);
+ hit = 0;
+ proutn("***TORPEDO INCOMING");
+ if (game.damage[DSRSENS] <= 0.0) {
+ proutn(" From ");
+ crmena(0, iquad, i, jx, jy);
+ }
+ attempt = 1;
+ prout(" ");
+ r = (Rand()+Rand())*0.5 -0.5;
+ r += 0.002*game.kpower[l]*r;
+ torpedo(course, r, jx, jy, &hit, 0);
+ if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */
+ if (game.state.galaxy[quadx][quady] == 1000 ||
+ alldone) return; /* Supernova or finished */
+ if (hit == 0) continue;
+ }
+ if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {
+ /* shields will take hits */
+ double absorb, hitsh, propor = pfac*shield*(condit==IHDOCKED ? 2.1 : 1.0);
+ if(propor < 0.1) propor = 0.1;
+ hitsh = propor*chgfac*hit+1.0;
+ atackd=1;
+ absorb = 0.8*hitsh;
+ if (absorb > shield) absorb = shield;
+ shield -= absorb;
+ hit -= hitsh;
+ if (condit==IHDOCKED) dock(0);
+ if (propor > 0.1 && hit < 0.005*energy) continue;
+ }
+ /* It's a hit -- print out hit size */
+ atackd = 1; /* We weren't going to check casualties, etc. if
+ shields were down for some strange reason. This
+ doesn't make any sense, so I've fixed it */
+ ihurt = 1;
+ proutn("%d unit hit", (int)hit);
+ if ((game.damage[DSRSENS] > 0 && itflag) || skill <= 2) {
+ proutn(" on the ");
+ crmshp();
+ }
+ if (game.damage[DSRSENS] <= 0.0 && itflag) {
+ proutn(" from ");
+ crmena(0, iquad, i, jx, jy);
+ }
+ skip(1);
+ /* Decide if hit is critical */
+ if (hit > hitmax) hitmax = hit;
+ hittot += hit;
+ fry(hit);
+ prout("Hit %g energy %g", hit, energy);
+ energy -= hit;
+ if (condit==IHDOCKED) dock(0);
+ }
+ if (energy <= 0) {
+ /* Returning home upon your shield, not with it... */
+ finish(FBATTLE);
+ return;
+ }
+ if (attempt == 0 && condit == IHDOCKED)
+ prout("***Enemies decide against attacking your ship.");
+ if (atackd == 0) return;
+ percent = 100.0*pfac*shield+0.5;
+ if (ihurt==0) {
+ /* Shields fully protect ship */
+ proutn("Enemy attack reduces shield strength to ");
+ }
+ else {
+ /* Print message if starship suffered hit(s) */
+ skip(1);
+ proutn("Energy left %2d shields ", (int)energy);
+ if (shldup) proutn("up ");
+ else if (game.damage[DSHIELD] == 0) proutn("down ");
+ else proutn("damaged, ");
+ }
+ prout("%d%%, torpedoes left %d", percent, torps);
+ /* Check if anyone was hurt */
+ if (hitmax >= 200 || hittot >= 500) {
+ int icas= hittot*Rand()*0.015;
+ if (icas >= 2) {
+ skip(1);
+ prout("Mc Coy- \"Sickbay to bridge. We suffered %d casualties", icas);
+ prout(" in that last attack.\"");
+ casual += icas;
+ }
+ }
+ /* After attack, reset average distance to enemies */
+ for (l = 1; l <= nenhere; l++)
+ game.kavgd[l] = game.kdist[l];
+ sortkl();
+ return;
+}
+
+void deadkl(int ix, int iy, int type, int ixx, int iyy) {
+ /* Added ixx and iyy allow enemy to "move" before dying */
+
+ int i,j;
+
+#ifdef SERGEEV
+ skip(1);
+#endif /* SERGEEV */
+ crmena(1, type, 2, ixx, iyy);
+ /* Decide what kind of enemy it is and update approriately */
+ if (type == IHR) {
+ /* chalk up a Romulan */
+ game.state.newstuf[quadx][quady] -= 10;
+ irhere--;
+ game.state.nromkl++;
+ game.state.nromrem--;
+ }
+ else if (type == IHT) {
+ /* Killed a Tholian */
+ ithere = 0;
+ }
+ else if (type == IHQUEST) {
+ /* Killed a Thingy */
+ iqhere=iqengry=thingx=thingy=0;
+ }
+ else {
+ /* Some type of a Klingon */
+ game.state.galaxy[quadx][quady] -= 100;
+ klhere--;
+ game.state.remkl--;
+ switch (type) {
+ case IHC:
+ comhere = 0;
+ for (i=1; i<=game.state.remcom; i++)
+ if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;
+ game.state.cx[i] = game.state.cx[game.state.remcom];
+ game.state.cy[i] = game.state.cy[game.state.remcom];
+ game.state.cx[game.state.remcom] = 0;
+ game.state.cy[game.state.remcom] = 0;
+ game.state.remcom--;
+ game.future[FTBEAM] = 1e30;
+ if (game.state.remcom != 0)
+ game.future[FTBEAM] = game.state.date + expran(1.0*incom/game.state.remcom);
+ game.state.killc++;
+ break;
+ case IHK:
+ game.state.killk++;
+ break;
+ case IHS:
+ game.state.nscrem = ishere = game.state.isx = game.state.isy = isatb = iscate = 0;
+ game.state.nsckill = 1;
+ game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
+ break;
+ }
+ }
+
+ /* For each kind of enemy, finish message to player */
+ prout(" destroyed.");
+ game.quad[ix][iy] = IHDOT;
+ if (game.state.remkl==0) return;
+
+ game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);
+
+ /* Remove enemy ship from arrays describing local conditions */
+ if (game.future[FCDBAS] < 1e30 && batx==quadx && baty==quady && type==IHC)
+ game.future[FCDBAS] = 1e30;
+ for (i=1; i<=nenhere; i++)
+ if (game.kx[i]==ix && game.ky[i]==iy) break;
+ nenhere--;
+ if (i <= nenhere) {
+ for (j=i; j<=nenhere; j++) {
+ game.kx[j] = game.kx[j+1];
+ game.ky[j] = game.ky[j+1];
+ game.kpower[j] = game.kpower[j+1];
+ game.kavgd[j] = game.kdist[j] = game.kdist[j+1];
+ }
+ }
+ game.kx[nenhere+1] = 0;
+ game.ky[nenhere+1] = 0;
+ game.kdist[nenhere+1] = 0;
+ game.kavgd[nenhere+1] = 0;
+ game.kpower[nenhere+1] = 0;
+ return;
+}
+
+static int targetcheck(double x, double y, double *course) {
+ double deltx, delty;
+ /* Return TRUE if target is invalid */
+ if (x < 1.0 || x > 10.0 || y < 1.0 || y > 10.0) {
+ huh();
+ return 1;
+ }
+ deltx = 0.1*(y - secty);
+ delty = 0.1*(sectx - x);
+ if (deltx==0 && delty== 0) {
+ skip(1);
+ prout("Spock- \"Bridge to sickbay. Dr. McCoy,");
+ prout(" I recommend an immediate review of");
+ prout(" the Captain's psychological profile.\"");
+ chew();
+ return 1;
+ }
+ *course = 1.90985932*atan2(deltx, delty);
+ return 0;
+}
+
+void photon(void) {
+ double targ[4][3], course[4];
+ double r, dummy;
+ int key, n, i, osuabor;
+
+ ididit = 0;
+
+ if (game.damage[DPHOTON]) {
+ prout("Photon tubes damaged.");
+ chew();
+ return;
+ }
+ if (torps == 0) {
+ prout("No torpedoes left.");
+ chew();
+ return;
+ }
+ key = scan();
+ for (;;) {
+ if (key == IHALPHA) {
+ huh();
+ return;
+ }
+ else if (key == IHEOL) {
+ prout("%d torpedoes left.", torps);
+ proutn("Number of torpedoes to fire- ");
+ key = scan();
+ }
+ else /* key == IHREAL */ {
+ n = aaitem + 0.5;
+ if (n <= 0) { /* abort command */
+ chew();
+ return;
+ }
+ if (n > 3) {
+ chew();
+ prout("Maximum of 3 torpedoes per burst.");
+ key = IHEOL;
+ return;
+ }
+ if (n <= torps) break;
+ chew();
+ key = IHEOL;
+ }
+ }
+ for (i = 1; i <= n; i++) {
+ key = scan();
+ if (i==1 && key == IHEOL) {
+ break; /* we will try prompting */
+ }
+ if (i==2 && key == IHEOL) {
+ /* direct all torpedoes at one target */
+ while (i <= n) {
+ targ[i][1] = targ[1][1];
+ targ[i][2] = targ[1][2];
+ course[i] = course[1];
+ i++;
+ }
+ break;
+ }
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ targ[i][1] = aaitem;
+ key = scan();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ targ[i][2] = aaitem;
+ if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
+ }
+ chew();
+ if (i == 1 && key == IHEOL) {
+ /* prompt for each one */
+ for (i = 1; i <= n; i++) {
+ proutn("Target sector for torpedo number %d- ", i);
+ key = scan();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ targ[i][1] = aaitem;
+ key = scan();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ targ[i][2] = aaitem;
+ chew();
+ if (targetcheck(targ[i][1], targ[i][2], &course[i])) return;
+ }
+ }
+ ididit = 1;
+ /* Loop for moving <n> torpedoes */
+ osuabor = 0;
+ for (i = 1; i <= n && !osuabor; i++) {
+ if (condit != IHDOCKED) torps--;
+ r = (Rand()+Rand())*0.5 -0.5;
+ if (fabs(r) >= 0.47) {
+ /* misfire! */
+ r = (Rand()+1.2) * r;
+ if (n>1) {
+ prouts("***TORPEDO NUMBER %d MISFIRES", i);
+ }
+ else prouts("***TORPEDO MISFIRES.");
+ skip(1);
+ if (i < n)
+ prout(" Remainder of burst aborted.");
+ osuabor=1;
+ if (Rand() <= 0.2) {
+ prout("***Photon tubes damaged by misfire.");
+ game.damage[DPHOTON] = damfac*(1.0+2.0*Rand());
+ break;
+ }
+ }
+ if (shldup || condit == IHDOCKED) r *= 1.0 + 0.0001*shield;
+#ifndef SERGEEV
+ if (n != 1) {
+ skip(1);
+ proutn("Track for torpedo number %d- ", i);
+ }
+ else {
+ skip(1);
+ proutn("Torpedo track- ");
+ }
+#endif /* SERGEEV */
+ torpedo(course[i], r, sectx, secty, &dummy, i);
+ if (alldone || game.state.galaxy[quadx][quady]==1000) return;
+ }
+ if (game.state.remkl==0) finish(FWON);
+}
+
+
+
+static void overheat(double rpow) {
+ if (rpow > 1500) {
+ double chekbrn = (rpow-1500.)*0.00038;
+ if (Rand() <= chekbrn) {
+ prout("Weapons officer Sulu- \"Phasers overheated, sir.\"");
+ game.damage[DPHASER] = damfac*(1.0 + Rand()) * (1.0+chekbrn);
+ }
+ }
+}
+
+static int checkshctrl(double rpow) {
+ double hit;
+ int icas;
+
+ skip(1);
+ if (Rand() < .998) {
+ prout("Shields lowered.");
+ return 0;
+ }
+ /* Something bad has happened */
+ prouts("***RED ALERT! RED ALERT!");
+ skip(2);
+ hit = rpow*shield/inshld;
+ energy -= rpow+hit*0.8;
+ shield -= hit*0.2;
+ if (energy <= 0.0) {
+ prouts("Sulu- \"Captain! Shield malf***********************\"");
+ skip(1);
+ stars();
+ finish(FPHASER);
+ return 1;
+ }
+ prouts("Sulu- \"Captain! Shield malfunction! Phaser fire contained!\"");
+ skip(2);
+ prout("Lt. Uhura- \"Sir, all decks reporting damage.\"");
+ icas = hit*Rand()*0.012;
+ skip(1);
+ fry(0.8*hit);
+ if (icas) {
+ skip(1);
+ prout("McCoy to bridge- \"Severe radiation burns, Jim.");
+ prout(" %d casualties so far.\"", icas);
+ casual -= icas;
+ }
+ skip(1);
+ prout("Phaser energy dispersed by shields.");
+ prout("Enemy unaffected.");
+ overheat(rpow);
+ return 1;
+}
+
+
+void phasers(void) {
+ double hits[21], rpow=0, extra, powrem, over, temp;
+ int kz = 0, k=1, i, irec=0; /* Cheating inhibitor */
+ int ifast=0, no=0, ipoop=1, msgflag = 1;
+ enum {NOTSET, MANUAL, FORCEMAN, AUTOMATIC} automode = NOTSET;
+ int key=0;
+
+ skip(1);
+ /* SR sensors and Computer */
+ if (game.damage[DSRSENS]+game.damage[DCOMPTR] > 0) ipoop = 0;
+ if (condit == IHDOCKED) {
+ prout("Phasers can't be fired through base shields.");
+ chew();
+ return;
+ }
+ if (game.damage[DPHASER] != 0) {
+ prout("Phaser control damaged.");
+ chew();
+ return;
+ }
+ if (shldup) {
+ if (game.damage[DSHCTRL]) {
+ prout("High speed shield control damaged.");
+ chew();
+ return;
+ }
+ if (energy <= 200.0) {
+ prout("Insufficient energy to activate high-speed shield control.");
+ chew();
+ return;
+ }
+ prout("Weapons Officer Sulu- \"High-speed shield control enabled, sir.\"");
+ ifast = 1;
+
+ }
+ /* Original code so convoluted, I re-did it all */
+ while (automode==NOTSET) {
+ key=scan();
+ if (key == IHALPHA) {
+ if (isit("manual")) {
+ if (nenhere==0) {
+ prout("There is no enemy present to select.");
+ chew();
+ key = IHEOL;
+ automode=AUTOMATIC;
+ }
+ else {
+ automode = MANUAL;
+ key = scan();
+ }
+ }
+ else if (isit("automatic")) {
+ if ((!ipoop) && nenhere != 0) {
+ automode = FORCEMAN;
+ }
+ else {
+ if (nenhere==0)
+ prout("Energy will be expended into space.");
+ automode = AUTOMATIC;
+ key = scan();
+ }
+ }
+ else if (isit("no")) {
+ no = 1;
+ }
+ else {
+ huh();
+ return;
+ }
+ }
+ else if (key == IHREAL) {
+ if (nenhere==0) {
+ prout("Energy will be expended into space.");
+ automode = AUTOMATIC;
+ }
+ else if (!ipoop)
+ automode = FORCEMAN;
+ else
+ automode = AUTOMATIC;
+ }
+ else {
+ /* IHEOL */
+ if (nenhere==0) {
+ prout("Energy will be expended into space.");
+ automode = AUTOMATIC;
+ }
+ else if (!ipoop)
+ automode = FORCEMAN;
+ else
+ proutn("Manual or automatic? ");
+ }
+ }
+
+ switch (automode) {
+ case AUTOMATIC:
+ if (key == IHALPHA && isit("no")) {
+ no = 1;
+ key = scan();
+ }
+ if (key != IHREAL && nenhere != 0) {
+ prout("Phasers locked on target. Energy available: %.2f",
+ ifast?energy-200.0:energy,1,2);
+ }
+ irec=0;
+ do {
+ chew();
+ if (!kz) for (i = 1; i <= nenhere; i++)
+ irec+=fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]))*
+ (1.01+0.05*Rand()) + 1.0;
+ kz=1;
+ proutn("(%d) units required. ", irec);
+ chew();
+ proutn("Units to fire= ");
+ key = scan();
+ if (key!=IHREAL) return;
+ rpow = aaitem;
+ if (rpow > (ifast?energy-200:energy)) {
+ proutn("Energy available= %.2f",
+ ifast?energy-200:energy);
+ skip(1);
+ key = IHEOL;
+ }
+ } while (rpow > (ifast?energy-200:energy));
+ if (rpow<=0) {
+ /* chicken out */
+ chew();
+ return;
+ }
+ if ((key=scan()) == IHALPHA && isit("no")) {
+ no = 1;
+ }
+ if (ifast) {
+ energy -= 200; /* Go and do it! */
+ if (checkshctrl(rpow)) return;
+ }
+ chew();
+ energy -= rpow;
+ extra = rpow;
+ if (nenhere) {
+ extra = 0.0;
+ powrem = rpow;
+ for (i = 1; i <= nenhere; i++) {
+ hits[i] = 0.0;
+ if (powrem <= 0) continue;
+ hits[i] = fabs(game.kpower[i])/(PHASEFAC*pow(0.90,game.kdist[i]));
+ over = (0.01 + 0.05*Rand())*hits[i];
+ temp = powrem;
+ powrem -= hits[i] + over;
+ if (powrem <= 0 && temp < hits[i]) hits[i] = temp;
+ if (powrem <= 0) over = 0.0;
+ extra += over;
+ }
+ if (powrem > 0.0) extra += powrem;
+ hittem(hits);
+ ididit=1;
+ }
+ if (extra > 0 && alldone == 0) {
+ if (ithere) {
+ proutn("*** Tholian web absorbs ");
+ if (nenhere>0) proutn("excess ");
+ prout("phaser energy.");
+ }
+ else {
+ prout("%d expended on empty space.", (int)extra);
+ }
+ }
+ break;
+
+ case FORCEMAN:
+ chew();
+ key = IHEOL;
+ if (game.damage[DCOMPTR]!=0)
+ prout("Battle comuter damaged, manual file only.");
+ else {
+ skip(1);
+ prouts("---WORKING---");
+ skip(1);
+ prout("Short-range-sensors-damaged");
+ prout("Insufficient-data-for-automatic-phaser-fire");
+ prout("Manual-fire-must-be-used");
+ skip(1);
+ }
+ case MANUAL:
+ rpow = 0.0;
+ for (k = 1; k <= nenhere;) {
+ int ii = game.kx[k], jj = game.ky[k];
+ int ienm = game.quad[ii][jj];
+ if (msgflag) {
+ proutn("Energy available= %.2f",
+ energy-.006-(ifast?200:0));
+ skip(1);
+ msgflag = 0;
+ rpow = 0.0;
+ }
+ if (game.damage[DSRSENS] && !(abs(sectx-ii) < 2 && abs(secty-jj) < 2) &&
+ (ienm == IHC || ienm == IHS)) {
+ cramen(ienm);
+ prout(" can't be located without short range scan.");
+ chew();
+ key = IHEOL;
+ hits[k] = 0; /* prevent overflow -- thanks to Alexei Voitenko */
+ k++;
+ continue;
+ }
+ if (key == IHEOL) {
+ chew();
+ if (ipoop && k > kz)
+ irec=(fabs(game.kpower[k])/(PHASEFAC*pow(0.9,game.kdist[k])))*
+ (1.01+0.05*Rand()) + 1.0;
+ kz = k;
+ proutn("(");
+ if (game.damage[DCOMPTR]==0) proutn("%d", irec);
+ else proutn("??");
+ proutn(") ");
+ proutn("units to fire at ");
+ crmena(0, ienm, 2, ii, jj);
+ proutn("- ");
+ key = scan();
+ }
+ if (key == IHALPHA && isit("no")) {
+ no = 1;
+ key = scan();
+ continue;
+ }
+ if (key == IHALPHA) {
+ huh();
+ return;
+ }
+ if (key == IHEOL) {
+ if (k==1) { /* Let me say I'm baffled by this */
+ msgflag = 1;
+ }
+ continue;
+ }
+ if (aaitem < 0) {
+ /* abort out */
+ chew();
+ return;
+ }
+ hits[k] = aaitem;
+ rpow += aaitem;
+ /* If total requested is too much, inform and start over */
+
+ if (rpow > (ifast?energy-200:energy)) {
+ prout("Available energy exceeded -- try again.");
+ chew();
+ return;
+ }
+ key = scan(); /* scan for next value */
+ k++;
+ }
+ if (rpow == 0.0) {
+ /* zero energy -- abort */
+ chew();
+ return;
+ }
+ if (key == IHALPHA && isit("no")) {
+ no = 1;
+ }
+ energy -= rpow;
+ chew();
+ if (ifast) {
+ energy -= 200.0;
+ if (checkshctrl(rpow)) return;
+ }
+ hittem(hits);
+ ididit=1;
+ case NOTSET:; /* avoid gcc warning */
+ }
+ /* Say shield raised or malfunction, if necessary */
+ if (alldone) return;
+ if (ifast) {
+ skip(1);
+ if (no == 0) {
+ if (Rand() >= 0.99) {
+ prout("Sulu- \"Sir, the high-speed shield control has malfunctioned . . .");
+ prouts(" CLICK CLICK POP . . .");
+ prout(" No response, sir!");
+ shldup = 0;
+ }
+ else
+ prout("Shields raised.");
+ }
+ else
+ shldup = 0;
+ }
+ overheat(rpow);
+}
+
+void hittem(double *hits) {
+ double kp, kpow, wham, hit, dustfac, kpini;
+#ifdef SERGEEV
+ int cx, cy;
+#endif /* SERGEEV */
+ int nenhr2=nenhere, k=1, kk=1, ii, jj, ienm;
+
+ skip(1);
+
+ for (; k <= nenhr2; k++, kk++) {
+ if ((wham = hits[k])==0) continue;
+ dustfac = 0.9 + 0.01*Rand();
+ hit = wham*pow(dustfac,game.kdist[kk]);
+ kpini = game.kpower[kk];
+ kp = fabs(kpini);
+ if (PHASEFAC*hit < kp) kp = PHASEFAC*hit;
+ game.kpower[kk] -= (game.kpower[kk] < 0 ? -kp: kp);
+ kpow = game.kpower[kk];
+ ii = game.kx[kk];
+ jj = game.ky[kk];
+ if (hit > 0.005) {
+#ifdef SERGEEV
+ if (game.damage[DSRSENS]==0){
+ crx=wherex();
+ cry=wherey();
+ setwnd(1);
+ drawmaps(2);
+ gotoxy(jj*2+3,ii+2);
+ highvideo();
+ proutn("%c", game.quad[ii][jj]);
+ gotoxy(wherex()-1,wherey());
+ sound(500);
+ delay(1000);
+ nosound();
+ lowvideo();
+ proutn("%c", game.quad[ii][jj]);
+ setwnd(4);
+ gotoxy(crx,cry);
+ _setcursortype(_NORMALCURSOR);
+ delay(500);
+ }
+#endif /* SERGEEV */
+ proutn("%d unit hit on ", (int)hit);
+ }
+ else
+ proutn("Very small hit on ");
+ ienm = game.quad[ii][jj];
+ if (ienm==IHQUEST) iqengry=1;
+ crmena(0,ienm,2,ii,jj);
+ skip(1);
+ if (kpow == 0) {
+ deadkl(ii, jj, ienm, ii, jj);
+ if (game.state.remkl==0) finish(FWON);
+ if (alldone) return;
+ kk--; /* don't do the increment */
+ }
+ else /* decide whether or not to emasculate klingon */
+ if (kpow > 0 && Rand() >= 0.9 &&
+ kpow <= ((0.4 + 0.4*Rand())*kpini)) {
+ prout("***Mr. Spock- \"Captain, the vessel at ",
+ cramlc(sector,ii,jj));
+ prout(" has just lost its firepower.\"");
+ game.kpower[kk] = -kpow;
+ }
+ }
+ return;
+}
+
-#include "sst.h"\r
-#include <math.h>\r
-\r
-void events(void) {\r
- int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;\r
- double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;\r
-\r
-#ifdef DEBUG\r
- if (idebug) prout("EVENTS");\r
-#endif\r
-\r
- if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {\r
- /* chart will no longer be updated because radio is dead */\r
- stdamtim = game.state.date;\r
- for (i=1; i <= 8 ; i++)\r
- for (j=1; j <= 8; j++)\r
- if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;\r
- }\r
-\r
- for (;;) {\r
- /* Select earliest extraneous event, line==0 if no events */\r
- line = FSPY;\r
- if (alldone) return;\r
- datemin = fintim;\r
- for (l=1; l<=NEVENTS; l++)\r
- if (game.future[l] < datemin) {\r
- line = l;\r
- datemin = game.future[l];\r
- }\r
- xtime = datemin-game.state.date;\r
- game.state.date = datemin;\r
- /* Decrement Federation resources and recompute remaining time */\r
- game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;\r
- game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);\r
- if (game.state.remtime <=0) {\r
- finish(FDEPLETE);\r
- return;\r
- }\r
- /* Is life support adequate? */\r
- if (game.damage[DLIFSUP] && condit != IHDOCKED) {\r
- if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {\r
- finish(FLIFESUP);\r
- return;\r
- }\r
- lsupres -= xtime;\r
- if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;\r
- }\r
- /* Fix devices */\r
- repair = xtime;\r
- if (condit == IHDOCKED) repair /= docfac;\r
- /* Don't fix Deathray here */\r
- for (l=1; l<=NDEVICES; l++)\r
- if (game.damage[l] > 0.0 && l != DDRAY)\r
- game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);\r
- /* If radio repaired, update star chart and attack reports */\r
- if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {\r
- stdamtim = 1e30;\r
- prout("Lt. Uhura- \"Captain, the sub-space radio is working and");\r
- prout(" surveillance reports are coming in.");\r
- skip(1);\r
- for (i=1; i <= 8 ; i++)\r
- for (j=1; j <= 8; j++)\r
- if (game.starch[i][j] > 999) game.starch[i][j] = 1;\r
- if (iseenit==0) {\r
- attakreport(0);\r
- iseenit = 1;\r
- }\r
- skip(1);\r
- prout(" The star chart is now up to date.\"");\r
- skip(1);\r
- }\r
- /* Cause extraneous event LINE to occur */\r
- Time -= xtime;\r
- switch (line) {\r
- case FSNOVA: /* Supernova */\r
- if (ipage==0) pause_game(1);\r
- ipage=1;\r
- snova(0,0);\r
- game.future[FSNOVA] = game.state.date + expran(0.5*intime);\r
- if (game.state.galaxy[quadx][quady] == 1000) return;\r
- break;\r
- case FSPY: /* Check with spy to see if S.C. should tractor beam */\r
- if (game.state.nscrem == 0 ||\r
- ictbeam+istract > 0 ||\r
- condit==IHDOCKED || isatb==1 || iscate==1) return;\r
- if (ientesc ||\r
- (energy < 2000 && torps < 4 && shield < 1250) ||\r
- (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||\r
- (game.damage[DSHIELD] > 0 &&\r
- (energy < 2500 || game.damage[DPHASER] > 0) &&\r
- (torps < 5 || game.damage[DPHOTON] > 0))) {\r
- /* Tractor-beam her! */\r
- istract=1;\r
- yank = square(game.state.isx-quadx) + square(game.state.isy-quady);\r
- /*********TBEAM CODE***********/\r
- }\r
- else return;\r
- case FTBEAM: /* Tractor beam */\r
- if (line==FTBEAM) {\r
- if (game.state.remcom == 0) {\r
- game.future[FTBEAM] = 1e30;\r
- break;\r
- }\r
- i = Rand()*game.state.remcom+1.0;\r
- yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);\r
- if (istract || condit == IHDOCKED || yank == 0) {\r
- /* Drats! Have to reschedule */\r
- game.future[FTBEAM] = game.state.date + Time +\r
- expran(1.5*intime/game.state.remcom);\r
- break;\r
- }\r
- }\r
- /* tractor beaming cases merge here */\r
- yank = sqrt(yank);\r
- if (ipage==0) pause_game(1);\r
- ipage=1;\r
- Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */\r
- ictbeam = 1;\r
- skip(1);\r
- proutn("***");\r
- crmshp();\r
- prout(" caught in long range tractor beam--");\r
- /* If Kirk & Co. screwing around on planet, handle */\r
- atover(1); /* atover(1) is Grab */\r
- if (alldone) return;\r
- if (icraft == 1) { /* Caught in Galileo? */\r
- finish(FSTRACTOR);\r
- return;\r
- }\r
- /* Check to see if shuttle is aboard */\r
- if (iscraft==0) {\r
- skip(1);\r
- if (Rand() >0.5) {\r
- prout("Galileo, left on the planet surface, is captured");\r
- prout("by aliens and made into a flying McDonald's.");\r
- game.damage[DSHUTTL] = -10;\r
- iscraft = -1;\r
- }\r
- else {\r
- prout("Galileo, left on the planet surface, is well hidden.");\r
- }\r
- }\r
- if (line==0) {\r
- quadx = game.state.isx;\r
- quady = game.state.isy;\r
- }\r
- else {\r
- quadx = game.state.cx[i];\r
- quady = game.state.cy[i];\r
- }\r
- iran10(§x, §y);\r
- crmshp();\r
- proutn(" is pulled to ");\r
- proutn(cramlc(quadrant, quadx, quady));\r
- proutn(", ");\r
- prout(cramlc(sector, sectx, secty));\r
- if (resting) {\r
- prout("(Remainder of rest/repair period cancellegame.state.)");\r
- resting = 0;\r
- }\r
- if (shldup==0) {\r
- if (game.damage[DSHIELD]==0 && shield > 0) {\r
- doshield(2); /* Shldsup */\r
- shldchg=0;\r
- }\r
- else prout("(Shields not currently useable.)");\r
- }\r
- newqad(0);\r
- /* Adjust finish time to time of tractor beaming */\r
- fintim = game.state.date+Time;\r
- attack(0);\r
- if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;\r
- else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);\r
- break;\r
- case FSNAP: /* Snapshot of the universe (for time warp) */\r
- game.snapsht = game.state;\r
- game.state.snap = 1;\r
- game.future[FSNAP] = game.state.date + expran(0.5 * intime);\r
- break;\r
- case FBATTAK: /* Commander attacks starbase */\r
- if (game.state.remcom==0 || game.state.rembase==0) {\r
- /* no can do */\r
- game.future[FBATTAK] = game.future[FCDBAS] = 1e30;\r
- break;\r
- }\r
- i = 0;\r
- for (j=1; j<=game.state.rembase; j++) {\r
- for (k=1; k<=game.state.remcom; k++)\r
- if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&\r
- (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&\r
- (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {\r
- i = 1;\r
- break;\r
- }\r
- if (i == 1) break;\r
- }\r
- if (j>game.state.rembase) {\r
- /* no match found -- try later */\r
- game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
- game.future[FCDBAS] = 1e30;\r
- break;\r
- }\r
- /* commander + starbase combination found -- launch attack */\r
- batx = game.state.baseqx[j];\r
- baty = game.state.baseqy[j];\r
- game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();\r
- if (isatb) /* extra time if SC already attacking */\r
- game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;\r
- game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);\r
- iseenit = 0;\r
- if (game.damage[DRADIO] != 0.0 &&\r
- condit != IHDOCKED) break; /* No warning :-( */\r
- iseenit = 1;\r
- if (ipage==0) pause_game(1);\r
- ipage = 1;\r
- skip(1);\r
- proutn("Lt. Uhura- \"Captain, the starbase in ");\r
- prout(cramlc(quadrant, batx, baty));\r
- prout(" reports that it is under attack and that it can");\r
- proutn(" hold out only until stardate %d",\r
- (int)game.future[FCDBAS]);\r
- prout(".\"");\r
- if (resting) {\r
- skip(1);\r
- proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");\r
- if (ja()) {\r
- resting = 0;\r
- Time = 0.0;\r
- return;\r
- }\r
- }\r
- break;\r
- case FSCDBAS: /* Supercommander destroys base */\r
- game.future[FSCDBAS] = 1e30;\r
- isatb = 2;\r
- if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */\r
- ixhold = batx;\r
- iyhold = baty;\r
- batx = game.state.isx;\r
- baty = game.state.isy;\r
- case FCDBAS: /* Commander succeeds in destroying base */\r
- if (line==FCDBAS) {\r
- game.future[FCDBAS] = 1e30;\r
- /* find the lucky pair */\r
- for (i = 1; i <= game.state.remcom; i++)\r
- if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;\r
- if (i > game.state.remcom || game.state.rembase == 0 ||\r
- game.state.galaxy[batx][baty] % 100 < 10) {\r
- /* No action to take after all */\r
- batx = baty = 0;\r
- break;\r
- }\r
- }\r
- /* Code merges here for any commander destroying base */\r
- /* Not perfect, but will have to do */\r
- if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;\r
- /* Handle case where base is in same quadrant as starship */\r
- if (batx==quadx && baty==quady) {\r
- if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;\r
- game.quad[basex][basey]= IHDOT;\r
- basex=basey=0;\r
- newcnd();\r
- skip(1);\r
- prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");\r
- }\r
- else if (game.state.rembase != 1 &&\r
- (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {\r
- /* Get word via subspace radio */\r
- if (ipage==0) pause_game(1);\r
- ipage = 1;\r
- skip(1);\r
- prout("Lt. Uhura- \"Captain, Starfleet Command reports that");\r
- proutn(" the starbase in ");\r
- proutn(cramlc(quadrant, batx, baty));\r
- prout(" has been destroyed by");\r
- if (isatb==2) prout("the Klingon Super-Commander");\r
- else prout("a Klingon Commander");\r
- }\r
- /* Remove Starbase from galaxy */\r
- game.state.galaxy[batx][baty] -= 10;\r
- for (i=1; i <= game.state.rembase; i++)\r
- if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {\r
- game.state.baseqx[i]=game.state.baseqx[game.state.rembase];\r
- game.state.baseqy[i]=game.state.baseqy[game.state.rembase];\r
- }\r
- game.state.rembase--;\r
- if (isatb == 2) {\r
- /* reinstate a commander's base attack */\r
- batx = ixhold;\r
- baty = iyhold;\r
- isatb = 0;\r
- }\r
- else {\r
- batx = baty = 0;\r
- }\r
- break;\r
- case FSCMOVE: /* Supercommander moves */\r
- game.future[FSCMOVE] = game.state.date+0.2777;\r
- if (ientesc+istract==0 &&\r
- isatb!=1 &&\r
- (iscate!=1 || justin==1)) scom(&ipage);\r
- break;\r
- case FDSPROB: /* Move deep space probe */\r
- game.future[FDSPROB] = game.state.date + 0.01;\r
- probex += probeinx;\r
- probey += probeiny;\r
- i = (int)(probex/10 +0.05);\r
- j = (int)(probey/10 + 0.05);\r
- if (probecx != i || probecy != j) {\r
- probecx = i;\r
- probecy = j;\r
- if (i < 1 || i > 8 || j < 1 || j > 8 ||\r
- game.state.galaxy[probecx][probecy] == 1000) {\r
- // Left galaxy or ran into supernova\r
- if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
- if (ipage==0) pause_game(1);\r
- ipage = 1;\r
- skip(1);\r
- proutn("Lt. Uhura- \"The deep space probe ");\r
- if (i < 1 ||i > 8 || j < 1 || j > 8)\r
- proutn("has left the galaxy");\r
- else\r
- proutn("is no longer transmitting");\r
- prout(".\"");\r
- }\r
- game.future[FDSPROB] = 1e30;\r
- break;\r
- }\r
- if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {\r
- if (ipage==0) pause_game(1);\r
- ipage = 1;\r
- skip(1);\r
- proutn("Lt. Uhura- \"The deep space probe is now in ");\r
- proutn(cramlc(quadrant, probecx, probecy));\r
- prout(".\"");\r
- }\r
- }\r
- /* Update star chart if Radio is working or have access to\r
- radio. */\r
- if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)\r
- game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?\r
- game.state.galaxy[probecx][probecy]+1000 : 1;\r
- proben--; // One less to travel\r
- if (proben == 0 && isarmed &&\r
- game.state.galaxy[probecx][probecy] % 10 > 0) {\r
- /* lets blow the sucker! */\r
- snova(1,0);\r
- game.future[FDSPROB] = 1e30;\r
- if (game.state.galaxy[quadx][quady] == 1000) return;\r
- }\r
- break;\r
- }\r
- }\r
-}\r
-\r
- \r
-void wait(void) {\r
- int key;\r
- double temp, delay, origTime;\r
-\r
- ididit = 0;\r
- for (;;) {\r
- key = scan();\r
- if (key != IHEOL) break;\r
- proutn("How long? ");\r
- }\r
- chew();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- origTime = delay = aaitem;\r
- if (delay <= 0.0) return;\r
- if (delay >= game.state.remtime || nenhere != 0) {\r
- proutn("Are you sure? ");\r
- if (ja() == 0) return;\r
- }\r
-\r
- /* Alternate resting periods (events) with attacks */\r
-\r
- resting = 1;\r
- do {\r
- if (delay <= 0) resting = 0;\r
- if (resting == 0) {\r
- prout("%d stardates left.", (int)game.state.remtime);\r
- return;\r
- }\r
- temp = Time = delay;\r
-\r
- if (nenhere) {\r
- double rtime = 1.0 + Rand();\r
- if (rtime < temp) temp = rtime;\r
- Time = temp;\r
- }\r
- if (Time < delay) attack(0);\r
- if (alldone) return;\r
- events();\r
- ididit = 1;\r
- if (alldone) return;\r
- delay -= temp;\r
- /* Repair Deathray if long rest at starbase */\r
- if (origTime-delay >= 9.99 && condit == IHDOCKED)\r
- game.damage[DDRAY] = 0.0;\r
- } while (game.state.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas\r
-\r
- resting = 0;\r
- Time = 0;\r
-}\r
-\r
-void nova(int ix, int iy) {\r
- static double course[] =\r
- {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};\r
- int bot, top, top2, hits[11][3], kount, icx, icy, mm, nn, j;\r
- int iquad, iquad1, i, ll, newcx, newcy, ii, jj;\r
- if (Rand() < 0.05) {\r
- /* Wow! We've supernova'ed */\r
- snova(ix, iy);\r
- return;\r
- }\r
-\r
- /* handle initial nova */\r
- game.quad[ix][iy] = IHDOT;\r
- crmena(1, IHSTAR, 2, ix, iy);\r
- prout(" novas.");\r
- game.state.galaxy[quadx][quady] -= 1;\r
- game.state.starkl++;\r
- \r
- /* Set up stack to recursively trigger adjacent stars */\r
- bot = top = top2 = 1;\r
- kount = 0;\r
- icx = icy = 0;\r
- hits[1][1] = ix;\r
- hits[1][2] = iy;\r
- while (1) {\r
- for (mm = bot; mm <= top; mm++) \r
- for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */\r
- for (j = 1; j <= 3; j++) {\r
- if (j==2 && nn== 2) continue;\r
- ii = hits[mm][1]+nn-2;\r
- jj = hits[mm][2]+j-2;\r
- if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;\r
- iquad = game.quad[ii][jj];\r
- switch (iquad) {\r
-// case IHDOT: /* Empty space ends reaction\r
-// case IHQUEST:\r
-// case IHBLANK:\r
-// case IHT:\r
-// case IHWEB:\r
- default:\r
- break;\r
- case IHSTAR: /* Affect another star */\r
- if (Rand() < 0.05) {\r
- /* This star supernovas */\r
- snova(ii,jj);\r
- return;\r
- }\r
- top2++;\r
- hits[top2][1]=ii;\r
- hits[top2][2]=jj;\r
- game.state.galaxy[quadx][quady] -= 1;\r
- game.state.starkl++;\r
- crmena(1, IHSTAR, 2, ii, jj);\r
- prout(" novas.");\r
- game.quad[ii][jj] = IHDOT;\r
- break;\r
- case IHP: /* Destroy planet */\r
- game.state.newstuf[quadx][quady] -= 1;\r
- game.state.nplankl++;\r
- crmena(1, IHP, 2, ii, jj);\r
- prout(" destroyed.");\r
- DESTROY(&game.state.plnets[iplnet]);\r
- iplnet = plnetx = plnety = 0;\r
- if (landed == 1) {\r
- finish(FPNOVA);\r
- return;\r
- }\r
- game.quad[ii][jj] = IHDOT;\r
- break;\r
- case IHB: /* Destroy base */\r
- game.state.galaxy[quadx][quady] -= 10;\r
- for (i = 1; i <= game.state.rembase; i++)\r
- if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;\r
- game.state.baseqx[i] = game.state.baseqx[game.state.rembase];\r
- game.state.baseqy[i] = game.state.baseqy[game.state.rembase];\r
- game.state.rembase--;\r
- basex = basey = 0;\r
- game.state.basekl++;\r
- newcnd();\r
- crmena(1, IHB, 2, ii, jj);\r
- prout(" destroyed.");\r
- game.quad[ii][jj] = IHDOT;\r
- break;\r
- case IHE: /* Buffet ship */\r
- case IHF:\r
- prout("***Starship buffeted by nova.");\r
- if (shldup) {\r
- if (shield >= 2000.0) shield -= 2000.0;\r
- else {\r
- double diff = 2000.0 - shield;\r
- energy -= diff;\r
- shield = 0.0;\r
- shldup = 0;\r
- prout("***Shields knocked out.");\r
- game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;\r
- }\r
- }\r
- else energy -= 2000.0;\r
- if (energy <= 0) {\r
- finish(FNOVA);\r
- return;\r
- }\r
- /* add in course nova contributes to kicking starship*/\r
- icx += sectx-hits[mm][1];\r
- icy += secty-hits[mm][2];\r
- kount++;\r
- break;\r
- case IHK: /* kill klingon */\r
- deadkl(ii,jj,iquad, ii, jj);\r
- break;\r
- case IHC: /* Damage/destroy big enemies */\r
- case IHS:\r
- case IHR:\r
- for (ll = 1; ll <= nenhere; ll++)\r
- if (game.kx[ll]==ii && game.ky[ll]==jj) break;\r
- game.kpower[ll] -= 800.0; /* If firepower is lost, die */\r
- if (game.kpower[ll] <= 0.0) {\r
- deadkl(ii, jj, iquad, ii, jj);\r
- break;\r
- }\r
- newcx = ii + ii - hits[mm][1];\r
- newcy = jj + jj - hits[mm][2];\r
- crmena(1, iquad, 2, ii, jj);\r
- proutn(" damaged");\r
- if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {\r
- /* can't leave quadrant */\r
- skip(1);\r
- break;\r
- }\r
- iquad1 = game.quad[newcx][newcy];\r
- if (iquad1 == IHBLANK) {\r
- proutn(", blasted into ");\r
- crmena(0, IHBLANK, 2, newcx, newcy);\r
- skip(1);\r
- deadkl(ii, jj, iquad, newcx, newcy);\r
- break;\r
- }\r
- if (iquad1 != IHDOT) {\r
- /* can't move into something else */\r
- skip(1);\r
- break;\r
- }\r
- proutn(", buffeted to ");\r
- proutn(cramlc(sector, newcx, newcy));\r
- game.quad[ii][jj] = IHDOT;\r
- game.quad[newcx][newcy] = iquad;\r
- game.kx[ll] = newcx;\r
- game.ky[ll] = newcy;\r
- game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));\r
- game.kdist[ll] = game.kavgd[ll];\r
- skip(1);\r
- break;\r
- }\r
- }\r
- if (top == top2) break;\r
- bot = top + 1;\r
- top = top2;\r
- }\r
- if (kount==0) return;\r
-\r
- /* Starship affected by nova -- kick it away. */\r
- dist = kount*0.1;\r
- if (icx) icx = (icx < 0 ? -1 : 1);\r
- if (icy) icy = (icy < 0 ? -1 : 1);\r
- direc = course[3*(icx+1)+icy+2];\r
- if (direc == 0.0) dist = 0.0;\r
- if (dist == 0.0) return;\r
- Time = 10.0*dist/16.0;\r
- skip(1);\r
- prout("Force of nova displaces starship.");\r
- iattak=2; /* Eliminates recursion problem */\r
- imove();\r
- Time = 10.0*dist/16.0;\r
- return;\r
-}\r
- \r
- \r
-void snova(int insx, int insy) {\r
- int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;\r
- int nrmdead, npdead;\r
- int insipient=0;\r
-\r
- nsx = insy;\r
- nsy = insy;\r
-\r
- if (insy== 0) {\r
- if (insx == 1) {\r
- /* NOVAMAX being used */\r
- nqx = probecx;\r
- nqy = probecy;\r
- }\r
- else {\r
- int stars = 0;\r
- /* Scheduled supernova -- select star */\r
- /* logic changed here so that we won't favor quadrants in top\r
- left of universe */\r
- for (nqx = 1; nqx<=8; nqx++) {\r
- for (nqy = 1; nqy<=8; nqy++) {\r
- stars += game.state.galaxy[nqx][nqy] % 10;\r
- }\r
- }\r
- if (stars == 0) return; /* nothing to supernova exists */\r
- num = Rand()*stars + 1;\r
- for (nqx = 1; nqx<=8; nqx++) {\r
- for (nqy = 1; nqy<=8; nqy++) {\r
- num -= game.state.galaxy[nqx][nqy] % 10;\r
- if (num <= 0) break;\r
- }\r
- if (num <=0) break;\r
- }\r
-#ifdef DEBUG\r
- if (idebug) {\r
- proutn("Super nova here?");\r
- if (ja()==1) {\r
- nqx = quadx;\r
- nqy = quady;\r
- }\r
- }\r
-#endif\r
- }\r
-\r
- if (nqx != quady || nqy != quady || justin != 0) {\r
- /* it isn't here, or we just entered (treat as inroute) */\r
- if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {\r
- skip(1);\r
- prout("Message from Starfleet Command Stardate %.2f", game.state.date);\r
- prout(" Supernova in %s; caution advised.",\r
- cramlc(quadrant, nqx, nqy));\r
- }\r
- }\r
- else {\r
- /* we are in the quadrant! */\r
- insipient = 1;\r
- num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;\r
- for (nsx=1; nsx < 10; nsx++) {\r
- for (nsy=1; nsy < 10; nsy++) {\r
- if (game.quad[nsx][nsy]==IHSTAR) {\r
- num--;\r
- if (num==0) break;\r
- }\r
- }\r
- if (num==0) break;\r
- }\r
- }\r
- }\r
- else {\r
- insipient = 1;\r
- }\r
-\r
- if (insipient) {\r
- skip(1);\r
- prouts("***RED ALERT! RED ALERT!");\r
- skip(1);\r
- prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));\r
- nqx = quadx;\r
- nqy = quady;\r
- if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {\r
- proutn("Emergency override attempts t");\r
- prouts("***************");\r
- skip(1);\r
- stars();\r
- alldone=1;\r
- }\r
- }\r
- /* destroy any Klingons in supernovaed quadrant */\r
- num=game.state.galaxy[nqx][nqy];\r
- kldead = num/100;\r
- comdead = iscdead = 0;\r
- if (nqx==game.state.isx && nqy == game.state.isy) {\r
- /* did in the Supercommander! */\r
- game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;\r
- iscdead = 1;\r
- game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;\r
- }\r
- game.state.remkl -= kldead;\r
- if (game.state.remcom) {\r
- int maxloop = game.state.remcom, l;\r
- for (l = 1; l <= maxloop; l++) {\r
- if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {\r
- game.state.cx[l] = game.state.cx[game.state.remcom];\r
- game.state.cy[l] = game.state.cy[game.state.remcom];\r
- game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;\r
- game.state.remcom--;\r
- kldead--;\r
- comdead++;\r
- if (game.state.remcom==0) game.future[FTBEAM] = 1e30;\r
- break;\r
- }\r
- }\r
- }\r
- /* destroy Romulans and planets in supernovaed quadrant */\r
- num = game.state.newstuf[nqx][nqy];\r
- game.state.newstuf[nqx][nqy] = 0;\r
- nrmdead = num/10;\r
- game.state.nromrem -= nrmdead;\r
- npdead = num - nrmdead*10;\r
- if (npdead) {\r
- int l;\r
- for (l = 0; l < inplan; l++)\r
- if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {\r
- DESTROY(&game.state.plnets[l]);\r
- }\r
- }\r
- /* Destroy any base in supernovaed quadrant */\r
- if (game.state.rembase) {\r
- int maxloop = game.state.rembase, l;\r
- for (l = 1; l <= maxloop; l++)\r
- if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {\r
- game.state.baseqx[l] = game.state.baseqx[game.state.rembase];\r
- game.state.baseqy[l] = game.state.baseqy[game.state.rembase];\r
- game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;\r
- game.state.rembase--;\r
- break;\r
- }\r
- }\r
- /* If starship caused supernova, tally up destruction */\r
- if (insx) {\r
- num = game.state.galaxy[nqx][nqy] % 100;\r
- game.state.starkl += num % 10;\r
- game.state.basekl += num/10;\r
- game.state.killk += kldead;\r
- game.state.killc += comdead;\r
- game.state.nromkl += nrmdead;\r
- game.state.nplankl += npdead;\r
- game.state.nsckill += iscdead;\r
- }\r
- /* mark supernova in galaxy and in star chart */\r
- if ((quadx == nqx && quady == nqy) ||\r
- game.damage[DRADIO] == 0 ||\r
- condit == IHDOCKED)\r
- game.starch[nqx][nqy] = 1;\r
- game.state.galaxy[nqx][nqy] = 1000;\r
- /* If supernova destroys last klingons give special message */\r
- if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {\r
- skip(2);\r
- if (insx == 0) prout("Lucky you!");\r
- proutn("A supernova in %s has just destroyed the last Klingons.",\r
- cramlc(quadrant, nqx, nqy));\r
- finish(FWON);\r
- return;\r
- }\r
- /* if some Klingons remain, continue or die in supernova */\r
- if (alldone) finish(FSNOVAED);\r
- return;\r
-}\r
- \r
- \r
+#include "sst.h"
+#include <math.h>
+
+void events(void) {
+ int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
+ double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;
+
+#ifdef DEBUG
+ if (idebug) prout("EVENTS");
+#endif
+
+ if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {
+ /* chart will no longer be updated because radio is dead */
+ stdamtim = game.state.date;
+ for (i=1; i <= 8 ; i++)
+ for (j=1; j <= 8; j++)
+ if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;
+ }
+
+ for (;;) {
+ /* Select earliest extraneous event, line==0 if no events */
+ line = FSPY;
+ if (alldone) return;
+ datemin = fintim;
+ for (l=1; l<=NEVENTS; l++)
+ if (game.future[l] < datemin) {
+ line = l;
+ datemin = game.future[l];
+ }
+ xtime = datemin-game.state.date;
+ game.state.date = datemin;
+ /* Decrement Federation resources and recompute remaining time */
+ game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime;
+ game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
+ if (game.state.remtime <=0) {
+ finish(FDEPLETE);
+ return;
+ }
+ /* Is life support adequate? */
+ if (game.damage[DLIFSUP] && condit != IHDOCKED) {
+ if (lsupres < xtime && game.damage[DLIFSUP] > lsupres) {
+ finish(FLIFESUP);
+ return;
+ }
+ lsupres -= xtime;
+ if (game.damage[DLIFSUP] <= xtime) lsupres = inlsr;
+ }
+ /* Fix devices */
+ repair = xtime;
+ if (condit == IHDOCKED) repair /= docfac;
+ /* Don't fix Deathray here */
+ for (l=1; l<=NDEVICES; l++)
+ if (game.damage[l] > 0.0 && l != DDRAY)
+ game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
+ /* If radio repaired, update star chart and attack reports */
+ if (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {
+ stdamtim = 1e30;
+ prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
+ prout(" surveillance reports are coming in.");
+ skip(1);
+ for (i=1; i <= 8 ; i++)
+ for (j=1; j <= 8; j++)
+ if (game.starch[i][j] > 999) game.starch[i][j] = 1;
+ if (iseenit==0) {
+ attakreport(0);
+ iseenit = 1;
+ }
+ skip(1);
+ prout(" The star chart is now up to date.\"");
+ skip(1);
+ }
+ /* Cause extraneous event LINE to occur */
+ Time -= xtime;
+ switch (line) {
+ case FSNOVA: /* Supernova */
+ if (ipage==0) pause_game(1);
+ ipage=1;
+ snova(0,0);
+ game.future[FSNOVA] = game.state.date + expran(0.5*intime);
+ if (game.state.galaxy[quadx][quady] == 1000) return;
+ break;
+ case FSPY: /* Check with spy to see if S.C. should tractor beam */
+ if (game.state.nscrem == 0 ||
+ ictbeam+istract > 0 ||
+ condit==IHDOCKED || isatb==1 || iscate==1) return;
+ if (ientesc ||
+ (energy < 2000 && torps < 4 && shield < 1250) ||
+ (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || torps < 4)) ||
+ (game.damage[DSHIELD] > 0 &&
+ (energy < 2500 || game.damage[DPHASER] > 0) &&
+ (torps < 5 || game.damage[DPHOTON] > 0))) {
+ /* Tractor-beam her! */
+ istract=1;
+ yank = square(game.state.isx-quadx) + square(game.state.isy-quady);
+ /*********TBEAM CODE***********/
+ }
+ else return;
+ case FTBEAM: /* Tractor beam */
+ if (line==FTBEAM) {
+ if (game.state.remcom == 0) {
+ game.future[FTBEAM] = 1e30;
+ break;
+ }
+ i = Rand()*game.state.remcom+1.0;
+ yank = square(game.state.cx[i]-quadx) + square(game.state.cy[i]-quady);
+ if (istract || condit == IHDOCKED || yank == 0) {
+ /* Drats! Have to reschedule */
+ game.future[FTBEAM] = game.state.date + Time +
+ expran(1.5*intime/game.state.remcom);
+ break;
+ }
+ }
+ /* tractor beaming cases merge here */
+ yank = sqrt(yank);
+ if (ipage==0) pause_game(1);
+ ipage=1;
+ Time = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
+ ictbeam = 1;
+ skip(1);
+ proutn("***");
+ crmshp();
+ prout(" caught in long range tractor beam--");
+ /* If Kirk & Co. screwing around on planet, handle */
+ atover(1); /* atover(1) is Grab */
+ if (alldone) return;
+ if (icraft == 1) { /* Caught in Galileo? */
+ finish(FSTRACTOR);
+ return;
+ }
+ /* Check to see if shuttle is aboard */
+ if (iscraft==0) {
+ skip(1);
+ if (Rand() >0.5) {
+ prout("Galileo, left on the planet surface, is captured");
+ prout("by aliens and made into a flying McDonald's.");
+ game.damage[DSHUTTL] = -10;
+ iscraft = -1;
+ }
+ else {
+ prout("Galileo, left on the planet surface, is well hidden.");
+ }
+ }
+ if (line==0) {
+ quadx = game.state.isx;
+ quady = game.state.isy;
+ }
+ else {
+ quadx = game.state.cx[i];
+ quady = game.state.cy[i];
+ }
+ iran10(§x, §y);
+ crmshp();
+ proutn(" is pulled to ");
+ proutn(cramlc(quadrant, quadx, quady));
+ proutn(", ");
+ prout(cramlc(sector, sectx, secty));
+ if (resting) {
+ prout("(Remainder of rest/repair period cancellegame.state.)");
+ resting = 0;
+ }
+ if (shldup==0) {
+ if (game.damage[DSHIELD]==0 && shield > 0) {
+ doshield(2); /* Shldsup */
+ shldchg=0;
+ }
+ else prout("(Shields not currently useable.)");
+ }
+ newqad(0);
+ /* Adjust finish time to time of tractor beaming */
+ fintim = game.state.date+Time;
+ attack(0);
+ if (game.state.remcom <= 0) game.future[FTBEAM] = 1e30;
+ else game.future[FTBEAM] = game.state.date+Time+expran(1.5*intime/game.state.remcom);
+ break;
+ case FSNAP: /* Snapshot of the universe (for time warp) */
+ game.snapsht = game.state;
+ game.state.snap = 1;
+ game.future[FSNAP] = game.state.date + expran(0.5 * intime);
+ break;
+ case FBATTAK: /* Commander attacks starbase */
+ if (game.state.remcom==0 || game.state.rembase==0) {
+ /* no can do */
+ game.future[FBATTAK] = game.future[FCDBAS] = 1e30;
+ break;
+ }
+ i = 0;
+ for (j=1; j<=game.state.rembase; j++) {
+ for (k=1; k<=game.state.remcom; k++)
+ if (game.state.baseqx[j]==game.state.cx[k] && game.state.baseqy[j]==game.state.cy[k] &&
+ (game.state.baseqx[j]!=quadx || game.state.baseqy[j]!=quady) &&
+ (game.state.baseqx[j]!=game.state.isx || game.state.baseqy[j]!=game.state.isy)) {
+ i = 1;
+ break;
+ }
+ if (i == 1) break;
+ }
+ if (j>game.state.rembase) {
+ /* no match found -- try later */
+ game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+ game.future[FCDBAS] = 1e30;
+ break;
+ }
+ /* commander + starbase combination found -- launch attack */
+ batx = game.state.baseqx[j];
+ baty = game.state.baseqy[j];
+ game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
+ if (isatb) /* extra time if SC already attacking */
+ game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
+ game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*intime);
+ iseenit = 0;
+ if (game.damage[DRADIO] != 0.0 &&
+ condit != IHDOCKED) break; /* No warning :-( */
+ iseenit = 1;
+ if (ipage==0) pause_game(1);
+ ipage = 1;
+ skip(1);
+ proutn("Lt. Uhura- \"Captain, the starbase in ");
+ prout(cramlc(quadrant, batx, baty));
+ prout(" reports that it is under attack and that it can");
+ proutn(" hold out only until stardate %d",
+ (int)game.future[FCDBAS]);
+ prout(".\"");
+ if (resting) {
+ skip(1);
+ proutn("Mr. Spock- \"Captain, shall we cancel the rest period?\" ");
+ if (ja()) {
+ resting = 0;
+ Time = 0.0;
+ return;
+ }
+ }
+ break;
+ case FSCDBAS: /* Supercommander destroys base */
+ game.future[FSCDBAS] = 1e30;
+ isatb = 2;
+ if (game.state.galaxy[game.state.isx][game.state.isy]%100 < 10) break; /* WAS RETURN! */
+ ixhold = batx;
+ iyhold = baty;
+ batx = game.state.isx;
+ baty = game.state.isy;
+ case FCDBAS: /* Commander succeeds in destroying base */
+ if (line==FCDBAS) {
+ game.future[FCDBAS] = 1e30;
+ /* find the lucky pair */
+ for (i = 1; i <= game.state.remcom; i++)
+ if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;
+ if (i > game.state.remcom || game.state.rembase == 0 ||
+ game.state.galaxy[batx][baty] % 100 < 10) {
+ /* No action to take after all */
+ batx = baty = 0;
+ break;
+ }
+ }
+ /* Code merges here for any commander destroying base */
+ /* Not perfect, but will have to do */
+ if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;
+ /* Handle case where base is in same quadrant as starship */
+ if (batx==quadx && baty==quady) {
+ if (game.starch[batx][baty] > 999) game.starch[batx][baty] -= 10;
+ game.quad[basex][basey]= IHDOT;
+ basex=basey=0;
+ newcnd();
+ skip(1);
+ prout("Spock- \"Captain, I believe the starbase has been destroyegame.state.\"");
+ }
+ else if (game.state.rembase != 1 &&
+ (game.damage[DRADIO] <= 0.0 || condit == IHDOCKED)) {
+ /* Get word via subspace radio */
+ if (ipage==0) pause_game(1);
+ ipage = 1;
+ skip(1);
+ prout("Lt. Uhura- \"Captain, Starfleet Command reports that");
+ proutn(" the starbase in ");
+ proutn(cramlc(quadrant, batx, baty));
+ prout(" has been destroyed by");
+ if (isatb==2) prout("the Klingon Super-Commander");
+ else prout("a Klingon Commander");
+ }
+ /* Remove Starbase from galaxy */
+ game.state.galaxy[batx][baty] -= 10;
+ for (i=1; i <= game.state.rembase; i++)
+ if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
+ game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
+ game.state.baseqy[i]=game.state.baseqy[game.state.rembase];
+ }
+ game.state.rembase--;
+ if (isatb == 2) {
+ /* reinstate a commander's base attack */
+ batx = ixhold;
+ baty = iyhold;
+ isatb = 0;
+ }
+ else {
+ batx = baty = 0;
+ }
+ break;
+ case FSCMOVE: /* Supercommander moves */
+ game.future[FSCMOVE] = game.state.date+0.2777;
+ if (ientesc+istract==0 &&
+ isatb!=1 &&
+ (iscate!=1 || justin==1)) scom(&ipage);
+ break;
+ case FDSPROB: /* Move deep space probe */
+ game.future[FDSPROB] = game.state.date + 0.01;
+ probex += probeinx;
+ probey += probeiny;
+ i = (int)(probex/10 +0.05);
+ j = (int)(probey/10 + 0.05);
+ if (probecx != i || probecy != j) {
+ probecx = i;
+ probecy = j;
+ if (i < 1 || i > 8 || j < 1 || j > 8 ||
+ game.state.galaxy[probecx][probecy] == 1000) {
+ // Left galaxy or ran into supernova
+ if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
+ if (ipage==0) pause_game(1);
+ ipage = 1;
+ skip(1);
+ proutn("Lt. Uhura- \"The deep space probe ");
+ if (i < 1 ||i > 8 || j < 1 || j > 8)
+ proutn("has left the galaxy");
+ else
+ proutn("is no longer transmitting");
+ prout(".\"");
+ }
+ game.future[FDSPROB] = 1e30;
+ break;
+ }
+ if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
+ if (ipage==0) pause_game(1);
+ ipage = 1;
+ skip(1);
+ proutn("Lt. Uhura- \"The deep space probe is now in ");
+ proutn(cramlc(quadrant, probecx, probecy));
+ prout(".\"");
+ }
+ }
+ /* Update star chart if Radio is working or have access to
+ radio. */
+ if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)
+ game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?
+ game.state.galaxy[probecx][probecy]+1000 : 1;
+ proben--; // One less to travel
+ if (proben == 0 && isarmed &&
+ game.state.galaxy[probecx][probecy] % 10 > 0) {
+ /* lets blow the sucker! */
+ snova(1,0);
+ game.future[FDSPROB] = 1e30;
+ if (game.state.galaxy[quadx][quady] == 1000) return;
+ }
+ break;
+ }
+ }
+}
+
+
+void wait(void) {
+ int key;
+ double temp, delay, origTime;
+
+ ididit = 0;
+ for (;;) {
+ key = scan();
+ if (key != IHEOL) break;
+ proutn("How long? ");
+ }
+ chew();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ origTime = delay = aaitem;
+ if (delay <= 0.0) return;
+ if (delay >= game.state.remtime || nenhere != 0) {
+ proutn("Are you sure? ");
+ if (ja() == 0) return;
+ }
+
+ /* Alternate resting periods (events) with attacks */
+
+ resting = 1;
+ do {
+ if (delay <= 0) resting = 0;
+ if (resting == 0) {
+ prout("%d stardates left.", (int)game.state.remtime);
+ return;
+ }
+ temp = Time = delay;
+
+ if (nenhere) {
+ double rtime = 1.0 + Rand();
+ if (rtime < temp) temp = rtime;
+ Time = temp;
+ }
+ if (Time < delay) attack(0);
+ if (alldone) return;
+ events();
+ ididit = 1;
+ if (alldone) return;
+ delay -= temp;
+ /* Repair Deathray if long rest at starbase */
+ if (origTime-delay >= 9.99 && condit == IHDOCKED)
+ game.damage[DDRAY] = 0.0;
+ } while (game.state.galaxy[quadx][quady] != 1000); // leave if quadrant supernovas
+
+ resting = 0;
+ Time = 0;
+}
+
+void nova(int ix, int iy) {
+ static double course[] =
+ {0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5};
+ int bot, top, top2, hits[11][3], kount, icx, icy, mm, nn, j;
+ int iquad, iquad1, i, ll, newcx, newcy, ii, jj;
+ if (Rand() < 0.05) {
+ /* Wow! We've supernova'ed */
+ snova(ix, iy);
+ return;
+ }
+
+ /* handle initial nova */
+ game.quad[ix][iy] = IHDOT;
+ crmena(1, IHSTAR, 2, ix, iy);
+ prout(" novas.");
+ game.state.galaxy[quadx][quady] -= 1;
+ game.state.starkl++;
+
+ /* Set up stack to recursively trigger adjacent stars */
+ bot = top = top2 = 1;
+ kount = 0;
+ icx = icy = 0;
+ hits[1][1] = ix;
+ hits[1][2] = iy;
+ while (1) {
+ for (mm = bot; mm <= top; mm++)
+ for (nn = 1; nn <= 3; nn++) /* nn,j represents coordinates around current */
+ for (j = 1; j <= 3; j++) {
+ if (j==2 && nn== 2) continue;
+ ii = hits[mm][1]+nn-2;
+ jj = hits[mm][2]+j-2;
+ if (ii < 1 || ii > 10 || jj < 1 || jj > 10) continue;
+ iquad = game.quad[ii][jj];
+ switch (iquad) {
+// case IHDOT: /* Empty space ends reaction
+// case IHQUEST:
+// case IHBLANK:
+// case IHT:
+// case IHWEB:
+ default:
+ break;
+ case IHSTAR: /* Affect another star */
+ if (Rand() < 0.05) {
+ /* This star supernovas */
+ snova(ii,jj);
+ return;
+ }
+ top2++;
+ hits[top2][1]=ii;
+ hits[top2][2]=jj;
+ game.state.galaxy[quadx][quady] -= 1;
+ game.state.starkl++;
+ crmena(1, IHSTAR, 2, ii, jj);
+ prout(" novas.");
+ game.quad[ii][jj] = IHDOT;
+ break;
+ case IHP: /* Destroy planet */
+ game.state.newstuf[quadx][quady] -= 1;
+ game.state.nplankl++;
+ crmena(1, IHP, 2, ii, jj);
+ prout(" destroyed.");
+ DESTROY(&game.state.plnets[iplnet]);
+ iplnet = plnetx = plnety = 0;
+ if (landed == 1) {
+ finish(FPNOVA);
+ return;
+ }
+ game.quad[ii][jj] = IHDOT;
+ break;
+ case IHB: /* Destroy base */
+ game.state.galaxy[quadx][quady] -= 10;
+ for (i = 1; i <= game.state.rembase; i++)
+ if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;
+ game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
+ game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
+ game.state.rembase--;
+ basex = basey = 0;
+ game.state.basekl++;
+ newcnd();
+ crmena(1, IHB, 2, ii, jj);
+ prout(" destroyed.");
+ game.quad[ii][jj] = IHDOT;
+ break;
+ case IHE: /* Buffet ship */
+ case IHF:
+ prout("***Starship buffeted by nova.");
+ if (shldup) {
+ if (shield >= 2000.0) shield -= 2000.0;
+ else {
+ double diff = 2000.0 - shield;
+ energy -= diff;
+ shield = 0.0;
+ shldup = 0;
+ prout("***Shields knocked out.");
+ game.damage[DSHIELD] += 0.005*damfac*Rand()*diff;
+ }
+ }
+ else energy -= 2000.0;
+ if (energy <= 0) {
+ finish(FNOVA);
+ return;
+ }
+ /* add in course nova contributes to kicking starship*/
+ icx += sectx-hits[mm][1];
+ icy += secty-hits[mm][2];
+ kount++;
+ break;
+ case IHK: /* kill klingon */
+ deadkl(ii,jj,iquad, ii, jj);
+ break;
+ case IHC: /* Damage/destroy big enemies */
+ case IHS:
+ case IHR:
+ for (ll = 1; ll <= nenhere; ll++)
+ if (game.kx[ll]==ii && game.ky[ll]==jj) break;
+ game.kpower[ll] -= 800.0; /* If firepower is lost, die */
+ if (game.kpower[ll] <= 0.0) {
+ deadkl(ii, jj, iquad, ii, jj);
+ break;
+ }
+ newcx = ii + ii - hits[mm][1];
+ newcy = jj + jj - hits[mm][2];
+ crmena(1, iquad, 2, ii, jj);
+ proutn(" damaged");
+ if (newcx<1 || newcx>10 || newcy<1 || newcy>10) {
+ /* can't leave quadrant */
+ skip(1);
+ break;
+ }
+ iquad1 = game.quad[newcx][newcy];
+ if (iquad1 == IHBLANK) {
+ proutn(", blasted into ");
+ crmena(0, IHBLANK, 2, newcx, newcy);
+ skip(1);
+ deadkl(ii, jj, iquad, newcx, newcy);
+ break;
+ }
+ if (iquad1 != IHDOT) {
+ /* can't move into something else */
+ skip(1);
+ break;
+ }
+ proutn(", buffeted to ");
+ proutn(cramlc(sector, newcx, newcy));
+ game.quad[ii][jj] = IHDOT;
+ game.quad[newcx][newcy] = iquad;
+ game.kx[ll] = newcx;
+ game.ky[ll] = newcy;
+ game.kavgd[ll] = sqrt(square(sectx-newcx)+square(secty-newcy));
+ game.kdist[ll] = game.kavgd[ll];
+ skip(1);
+ break;
+ }
+ }
+ if (top == top2) break;
+ bot = top + 1;
+ top = top2;
+ }
+ if (kount==0) return;
+
+ /* Starship affected by nova -- kick it away. */
+ dist = kount*0.1;
+ if (icx) icx = (icx < 0 ? -1 : 1);
+ if (icy) icy = (icy < 0 ? -1 : 1);
+ direc = course[3*(icx+1)+icy+2];
+ if (direc == 0.0) dist = 0.0;
+ if (dist == 0.0) return;
+ Time = 10.0*dist/16.0;
+ skip(1);
+ prout("Force of nova displaces starship.");
+ iattak=2; /* Eliminates recursion problem */
+ imove();
+ Time = 10.0*dist/16.0;
+ return;
+}
+
+
+void snova(int insx, int insy) {
+ int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;
+ int nrmdead, npdead;
+ int insipient=0;
+
+ nsx = insy;
+ nsy = insy;
+
+ if (insy== 0) {
+ if (insx == 1) {
+ /* NOVAMAX being used */
+ nqx = probecx;
+ nqy = probecy;
+ }
+ else {
+ int stars = 0;
+ /* Scheduled supernova -- select star */
+ /* logic changed here so that we won't favor quadrants in top
+ left of universe */
+ for (nqx = 1; nqx<=8; nqx++) {
+ for (nqy = 1; nqy<=8; nqy++) {
+ stars += game.state.galaxy[nqx][nqy] % 10;
+ }
+ }
+ if (stars == 0) return; /* nothing to supernova exists */
+ num = Rand()*stars + 1;
+ for (nqx = 1; nqx<=8; nqx++) {
+ for (nqy = 1; nqy<=8; nqy++) {
+ num -= game.state.galaxy[nqx][nqy] % 10;
+ if (num <= 0) break;
+ }
+ if (num <=0) break;
+ }
+#ifdef DEBUG
+ if (idebug) {
+ proutn("Super nova here?");
+ if (ja()==1) {
+ nqx = quadx;
+ nqy = quady;
+ }
+ }
+#endif
+ }
+
+ if (nqx != quady || nqy != quady || justin != 0) {
+ /* it isn't here, or we just entered (treat as inroute) */
+ if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
+ skip(1);
+ prout("Message from Starfleet Command Stardate %.2f", game.state.date);
+ prout(" Supernova in %s; caution advised.",
+ cramlc(quadrant, nqx, nqy));
+ }
+ }
+ else {
+ /* we are in the quadrant! */
+ insipient = 1;
+ num = Rand()* (game.state.galaxy[nqx][nqy]%10) + 1;
+ for (nsx=1; nsx < 10; nsx++) {
+ for (nsy=1; nsy < 10; nsy++) {
+ if (game.quad[nsx][nsy]==IHSTAR) {
+ num--;
+ if (num==0) break;
+ }
+ }
+ if (num==0) break;
+ }
+ }
+ }
+ else {
+ insipient = 1;
+ }
+
+ if (insipient) {
+ skip(1);
+ prouts("***RED ALERT! RED ALERT!");
+ skip(1);
+ prout("***Incipient supernova detected at ", cramlc(sector, nsx, nsy));
+ nqx = quadx;
+ nqy = quady;
+ if (square(nsx-sectx) + square(nsy-secty) <= 2.1) {
+ proutn("Emergency override attempts t");
+ prouts("***************");
+ skip(1);
+ stars();
+ alldone=1;
+ }
+ }
+ /* destroy any Klingons in supernovaed quadrant */
+ num=game.state.galaxy[nqx][nqy];
+ kldead = num/100;
+ comdead = iscdead = 0;
+ if (nqx==game.state.isx && nqy == game.state.isy) {
+ /* did in the Supercommander! */
+ game.state.nscrem = game.state.isx = game.state.isy = isatb = iscate = 0;
+ iscdead = 1;
+ game.future[FSCMOVE] = game.future[FSCDBAS] = 1e30;
+ }
+ game.state.remkl -= kldead;
+ if (game.state.remcom) {
+ int maxloop = game.state.remcom, l;
+ for (l = 1; l <= maxloop; l++) {
+ if (game.state.cx[l] == nqx && game.state.cy[l] == nqy) {
+ game.state.cx[l] = game.state.cx[game.state.remcom];
+ game.state.cy[l] = game.state.cy[game.state.remcom];
+ game.state.cx[game.state.remcom] = game.state.cy[game.state.remcom] = 0;
+ game.state.remcom--;
+ kldead--;
+ comdead++;
+ if (game.state.remcom==0) game.future[FTBEAM] = 1e30;
+ break;
+ }
+ }
+ }
+ /* destroy Romulans and planets in supernovaed quadrant */
+ num = game.state.newstuf[nqx][nqy];
+ game.state.newstuf[nqx][nqy] = 0;
+ nrmdead = num/10;
+ game.state.nromrem -= nrmdead;
+ npdead = num - nrmdead*10;
+ if (npdead) {
+ int l;
+ for (l = 0; l < inplan; l++)
+ if (game.state.plnets[l].x == nqx && game.state.plnets[l].y == nqy) {
+ DESTROY(&game.state.plnets[l]);
+ }
+ }
+ /* Destroy any base in supernovaed quadrant */
+ if (game.state.rembase) {
+ int maxloop = game.state.rembase, l;
+ for (l = 1; l <= maxloop; l++)
+ if (game.state.baseqx[l]==nqx && game.state.baseqy[l]==nqy) {
+ game.state.baseqx[l] = game.state.baseqx[game.state.rembase];
+ game.state.baseqy[l] = game.state.baseqy[game.state.rembase];
+ game.state.baseqx[game.state.rembase] = game.state.baseqy[game.state.rembase] = 0;
+ game.state.rembase--;
+ break;
+ }
+ }
+ /* If starship caused supernova, tally up destruction */
+ if (insx) {
+ num = game.state.galaxy[nqx][nqy] % 100;
+ game.state.starkl += num % 10;
+ game.state.basekl += num/10;
+ game.state.killk += kldead;
+ game.state.killc += comdead;
+ game.state.nromkl += nrmdead;
+ game.state.nplankl += npdead;
+ game.state.nsckill += iscdead;
+ }
+ /* mark supernova in galaxy and in star chart */
+ if ((quadx == nqx && quady == nqy) ||
+ game.damage[DRADIO] == 0 ||
+ condit == IHDOCKED)
+ game.starch[nqx][nqy] = 1;
+ game.state.galaxy[nqx][nqy] = 1000;
+ /* If supernova destroys last klingons give special message */
+ if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
+ skip(2);
+ if (insx == 0) prout("Lucky you!");
+ proutn("A supernova in %s has just destroyed the last Klingons.",
+ cramlc(quadrant, nqx, nqy));
+ finish(FWON);
+ return;
+ }
+ /* if some Klingons remain, continue or die in supernova */
+ if (alldone) finish(FSNOVAED);
+ return;
+}
+
+
-#include "sst.h"\r
-#include <string.h>\r
-#include <time.h>\r
-\r
-void dstrct() {\r
- /* Finish with a BANG! */\r
- chew();\r
- if (game.damage[DCOMPTR] != 0.0) {\r
- prout("Computer damaged; cannot execute destruct sequence.");\r
- return;\r
- }\r
- skip(1);\r
- prouts("---WORKING---"); skip(1);\r
- prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED");\r
- prouts(" 10"); skip(1);\r
- prouts(" 9"); skip(1);\r
- prouts(" 8"); skip(1);\r
- prouts(" 7"); skip(1);\r
- prouts(" 6"); skip(1);\r
- prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");\r
- prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");\r
- prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");\r
- scan();\r
- chew();\r
- if (strcmp(game.passwd, citem) != 0) {\r
- prouts("PASSWORD-REJECTED;"); skip(1);\r
- prout("CONTINUITY-EFFECTED");\r
- skip(1);\r
- return;\r
- }\r
- prouts("PASSWORD-ACCEPTED"); skip(1);\r
- prouts(" 5"); skip(1);\r
- prouts(" 4"); skip(1);\r
- prouts(" 3"); skip(1);\r
- prouts(" 2"); skip(1);\r
- prouts(" 1"); skip(1);\r
- if (Rand() < 0.15) {\r
- prouts("GOODBYE-CRUEL-WORLD");\r
- skip(1);\r
- }\r
- skip(2);\r
- kaboom();\r
-}\r
-\r
-void kaboom(void) {\r
- stars();\r
- if (ship==IHE) prouts("***");\r
- prouts("********* Entropy of ");\r
- crmshp();\r
- prouts(" maximized *********");\r
- skip(1);\r
- stars();\r
- skip(1);\r
- if (nenhere != 0) {\r
- double whammo = 25.0 * energy;\r
- int l=1;\r
- while (l <= nenhere) {\r
- if (game.kpower[l]*game.kdist[l] <= whammo) \r
- deadkl(game.kx[l],game.ky[l], game.quad[game.kx[l]][game.ky[l]], game.kx[l], game.ky[l]);\r
- l++;\r
- }\r
- }\r
- finish(FDILITHIUM);\r
-}\r
- \r
-\r
-void finish(FINTYPE ifin) {\r
- int igotit = 0;\r
- alldone = 1;\r
- skip(3);\r
- prout("It is stardate %.1f.", game.state.date);\r
- prout("");\r
- switch (ifin) {\r
- case FWON: // Game has been won\r
- if (game.state.nromrem != 0)\r
- prout("The remaining %d Romulans surrender to Starfleet Command.",\r
- game.state.nromrem);\r
- \r
- prout("You have smashed the Klingon invasion fleet and saved");\r
- prout("the Federation.");\r
- gamewon=1;\r
- if (alive) {\r
- double badpt;\r
- badpt = 5.*game.state.starkl + casual + 10.*game.state.nplankl +\r
- 45.*nhelp+100.*game.state.basekl;\r
- if (ship == IHF) badpt += 100.0;\r
- else if (ship == 0) badpt += 200.0;\r
- if (badpt < 100.0) badpt = 0.0; // Close enough!\r
- if (game.state.date-indate < 5.0 ||\r
- // killsPerDate >= RateMax\r
- (game.state.killk+game.state.killc+game.state.nsckill)/(game.state.date-indate) >=\r
- 0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {\r
- skip(1);\r
- prout("In fact, you have done so well that Starfleet Command");\r
- switch (skill) {\r
- case 1:\r
- prout("promotes you one step in rank from \"Novice\" to \"Fair\".");\r
- break;\r
- case 2:\r
- prout("promotes you one step in rank from \"Fair\" to \"Good\".");\r
- break;\r
- case 3:\r
- prout("promotes you one step in rank from \"Good\" to \"Expert\".");\r
- break;\r
- case 4:\r
- prout("promotes you to Commodore Emeritus.");\r
- skip(1);\r
- prout("Now that you think you're really good, try playing");\r
- prout("the \"Emeritus\" game. It will splatter your ego.");\r
- break;\r
- case 5:\r
- skip(1);\r
- prout("Computer- ERROR-ERROR-ERROR-ERROR");\r
- skip(1);\r
- prout(" YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");\r
- prout(" THIS-PROGRAM-MUST-SURVIVE");\r
- prout(" THIS-PROGRAM-MUST-SURVIVE");\r
- prout(" THIS-PROGRAM-MUST-SURVIVE");\r
- prout(" THIS-PROGRAM-MUST?- MUST ? - SUR? ? -? VI");\r
- skip(1);\r
- prout("Now you can retire and write your own Star Trek game!");\r
- skip(1);\r
- break;\r
- }\r
- if (skill > 3) {\r
- if (thawed\r
-#ifdef DEBUG\r
- && !idebug\r
-#endif\r
- )\r
- prout("You cannot get a citation, so...");\r
- else {\r
- prout("Do you want your Commodore Emeritus Citation printed?");\r
- proutn("(You need a 132 column printer.)");\r
- chew();\r
- if (ja()) {\r
- igotit = 1;\r
- }\r
- }\r
- }\r
- }\r
- // Only grant long life if alive (original didn't!)\r
- skip(1);\r
- prout("LIVE LONG AND PROSPER.");\r
- }\r
- score();\r
- if (igotit != 0) plaque();\r
- return;\r
- case FDEPLETE: // Federation Resources Depleted\r
- prout("Your time has run out and the Federation has been");\r
- prout("conquered. Your starship is now Klingon property,");\r
- prout("and you are put on trial as a war criminal. On the");\r
- proutn("basis of your record, you are ");\r
- if (game.state.remkl*3.0 > inkling) {\r
- prout("aquitted.");\r
- skip(1);\r
- prout("LIVE LONG AND PROSPER.");\r
- }\r
- else {\r
- prout("found guilty and");\r
- prout("sentenced to death by slow torture.");\r
- alive = 0;\r
- }\r
- score();\r
- return;\r
- case FLIFESUP:\r
- prout("Your life support reserves have run out, and");\r
- prout("you die of thirst, starvation, and asphyxiation.");\r
- prout("Your starship is a derelict in space.");\r
- break;\r
- case FNRG:\r
- prout("Your energy supply is exhausted.");\r
- skip(1);\r
- prout("Your starship is a derelict in space.");\r
- break;\r
- case FBATTLE:\r
- proutn("The ");\r
- crmshp();\r
- prout("has been destroyed in battle.");\r
- skip(1);\r
- prout("Dulce et decorum est pro patria mori.");\r
- break;\r
- case FNEG3:\r
- prout("You have made three attempts to cross the negative energy");\r
- prout("barrier which surrounds the galaxy.");\r
- skip(1);\r
- prout("Your navigation is abominable.");\r
- score();\r
- return;\r
- case FNOVA:\r
- prout("Your starship has been destroyed by a nova.");\r
- prout("That was a great shot.");\r
- skip(1);\r
- break;\r
- case FSNOVAED:\r
- proutn("The ");\r
- crmshp();\r
- prout(" has been fried by a supernova.");\r
- prout("...Not even cinders remain...");\r
- break;\r
- case FABANDN:\r
- prout("You have been captured by the Klingons. If you still");\r
- prout("had a starbase to be returned to, you would have been");\r
- prout("repatriated and given another chance. Since you have");\r
- prout("no starbases, you will be mercilessly tortured to death.");\r
- break;\r
- case FDILITHIUM:\r
- prout("Your starship is now an expanding cloud of subatomic particles");\r
- break;\r
- case FMATERIALIZE:\r
- prout("Starbase was unable to re-materialize your starship.");\r
- prout("Sic transit gloria muntdi");\r
- break;\r
- case FPHASER:\r
- proutn("The ");\r
- crmshp();\r
- prout(" has been cremated by its own phasers.");\r
- break;\r
- case FLOST:\r
- prout("You and your landing party have been");\r
- prout("converted to energy, disipating through space.");\r
- break;\r
- case FMINING:\r
- prout("You are left with your landing party on");\r
- prout("a wild jungle planet inhabited by primitive cannibals.");\r
- skip(1);\r
- prout("They are very fond of \"Captain Kirk\" soup.");\r
- skip(1);\r
- proutn("Without your leadership, the ");\r
- crmshp();\r
- prout(" is destroyed.");\r
- break;\r
- case FDPLANET:\r
- prout("You and your mining party perish.");\r
- skip(1);\r
- prout("That was a great shot.");\r
- skip(1);\r
- break;\r
- case FSSC:\r
- prout("The Galileo is instantly annihilated by the supernova.");\r
- // no break;\r
- case FPNOVA:\r
- prout("You and your mining party are atomized.");\r
- skip(1);\r
- proutn("Mr. Spock takes command of the ");\r
- crmshp();\r
- prout(" and");\r
- prout("joins the Romulans, reigning terror on the Federation.");\r
- break;\r
- case FSTRACTOR:\r
- prout("The shuttle craft Galileo is also caught,");\r
- prout("and breaks up under the strain.");\r
- skip(1);\r
- prout("Your debris is scattered for millions of miles.");\r
- proutn("Without your leadership, the ");\r
- crmshp();\r
- prout(" is destroyed.");\r
- break;\r
- case FDRAY:\r
- prout("The mutants attack and kill Spock.");\r
- prout("Your ship is captured by Klingons, and");\r
- prout("your crew is put on display in a Klingon zoo.");\r
- break;\r
- case FTRIBBLE:\r
- prout("Tribbles consume all remaining water,");\r
- prout("food, and oxygen on your ship.");\r
- skip(1);\r
- prout("You die of thirst, starvation, and asphyxiation.");\r
- prout("Your starship is a derelict in space.");\r
- break;\r
- case FHOLE:\r
- prout("Your ship is drawn to the center of the black hole.");\r
- prout("You are crushed into extremely dense matter.");\r
- break;\r
- }\r
- if (ship==IHF) ship= 0;\r
- else if (ship == IHE) ship = IHF;\r
- alive = 0;\r
- if (game.state.remkl != 0) {\r
- double goodies = game.state.remres/inresor;\r
- double baddies = (game.state.remkl + 2.0*game.state.remcom)/(inkling+2.0*incom);\r
- if (goodies/baddies >= 1.0+0.5*Rand()) {\r
- prout("As a result of your actions, a treaty with the Klingon");\r
- prout("Empire has been signed. The terms of the treaty are");\r
- if (goodies/baddies >= 3.0+Rand()) {\r
- prout("favorable to the Federation.");\r
- skip(1);\r
- prout("Congratulations!");\r
- }\r
- else\r
- prout("highly unfavorable to the Federation.");\r
- }\r
- else\r
- prout("The Federation will be destroyed.");\r
- }\r
- else {\r
- prout("Since you took the last Klingon with you, you are a");\r
- prout("martyr and a hero. Someday maybe they'll erect a");\r
- prout("statue in your memory. Rest in peace, and try not");\r
- prout("to think about pigeons.");\r
- gamewon = 1;\r
- }\r
- score();\r
-}\r
-\r
-void score(void) {\r
- double timused = game.state.date - indate;\r
- int ithperd, iwon, klship;\r
-\r
- pause_game(0);\r
-\r
- iskill = skill;\r
- if ((timused == 0 || game.state.remkl != 0) && timused < 5.0) timused = 5.0;\r
- perdate = (game.state.killc + game.state.killk + game.state.nsckill)/timused;\r
- ithperd = 500*perdate + 0.5;\r
- iwon = 0;\r
- if (gamewon) iwon = 100*skill;\r
- if (ship == IHE) klship = 0;\r
- else if (ship == IHF) klship = 1;\r
- else klship = 2;\r
- if (gamewon == 0) game.state.nromrem = 0; // None captured if no win\r
- iscore = 10*game.state.killk + 50*game.state.killc + ithperd + iwon\r
- - 100*game.state.basekl - 100*klship - 45*nhelp -5*game.state.starkl - casual\r
- + 20*game.state.nromkl + 200*game.state.nsckill - 10*game.state.nplankl + game.state.nromrem;\r
- if (alive == 0) iscore -= 200;\r
- skip(2);\r
- prout("Your score --");\r
- if (game.state.nromkl)\r
- prout("%6d Romulans destroyed %5d",\r
- game.state.nromkl,20*game.state.nromkl);\r
- if (game.state.nromrem)\r
- prout("%6d Romulans captured %5d",\r
- game.state.nromrem, game.state.nromrem);\r
- if (game.state.killk)\r
- prout("%6d ordinary Klingons destroyed %5d",\r
- game.state.killk, 10*game.state.killk);\r
- if (game.state.killc)\r
- prout("%6d Klingon commanders destroyed %5d",\r
- game.state.killc, 50*game.state.killc);\r
- if (game.state.nsckill)\r
- prout("%6d Super-Commander destroyed %5d",\r
- game.state.nsckill, 200*game.state.nsckill);\r
- if (ithperd)\r
- prout("%.2f Klingons per stardate %5d",\r
- perdate, ithperd);\r
- if (game.state.starkl)\r
- prout("%6d stars destroyed by your action %5d",\r
- game.state.starkl, -5*game.state.starkl);\r
- if (game.state.nplankl)\r
- prout("%6d planets destroyed by your action %5d",\r
- game.state.nplankl, -10*game.state.nplankl);\r
- if (game.state.basekl)\r
- prout("%6d bases destroyed by your action %5d",\r
- game.state.basekl, -100*game.state.basekl);\r
- if (nhelp)\r
- prout("%6d calls for help from starbase %5d",\r
- nhelp, -45*nhelp);\r
- if (casual)\r
- prout("%6d casualties incurred %5d",\r
- casual, -casual);\r
- if (klship)\r
- prout("%6d ship(s) lost or destroyed %5d",\r
- klship, -100*klship);\r
- if (alive==0)\r
- prout("Penalty for getting yourself killed -200");\r
- if (gamewon) {\r
- skip(1);\r
- proutn("Bonus for winning ");\r
- switch (skill) {\r
- case 1: proutn("Novice game "); break;\r
- case 2: proutn("Fair game "); break;\r
- case 3: proutn("Good game "); break;\r
- case 4: proutn("Expert game "); break;\r
- case 5: proutn("Emeritus game"); break;\r
- }\r
- prout(" %5d", iwon);\r
- }\r
- skip(2);\r
- prout("TOTAL SCORE %5d", iscore);\r
-}\r
-\r
-void plaque(void) {\r
- FILE *fp=NULL;\r
- time_t t;\r
- char *timestring;\r
- int nskip;\r
- char winner[128];\r
-\r
- skip(2);\r
- \r
- while (fp == NULL) {\r
- proutn("File or device name for your plaque:");\r
- fgets(winner, 128, stdin);\r
- winner[strlen(winner)-1] = '\0';\r
- fp = fopen(winner, "w");\r
- if (fp==NULL) {\r
- prout("Invalid name.");\r
- }\r
- }\r
-\r
- proutn("Enter name to go on plaque (up to 30 characters):");\r
- fgets(winner, 128, stdin);\r
- winner[strlen(winner)-1] = '\0';\r
- winner[30] = '\0';\r
- nskip = 64 - strlen(winner)/2;\r
-\r
- fprintf(fp,"\n\n\n\n");\r
- /* --------DRAW ENTERPRISE PICTURE. */\r
- fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );\r
- fprintf(fp, " EEE E : : : E\n" );\r
- fprintf(fp, " EE EEE E : : NCC-1701 : E\n");\r
- fprintf(fp, " EEEEEEEEEEEEEEEE EEEEEEEEEEEEEEE E : : : E\n");\r
- fprintf(fp, " E E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");\r
- fprintf(fp, " EEEEEEEEE EEEEEEEEEEEEE E E\n");\r
- fprintf(fp, " EEEEEEE EEEEE E E E E\n");\r
- fprintf(fp, " EEE E E E E\n");\r
- fprintf(fp, " E E E E\n");\r
- fprintf(fp, " EEEEEEEEEEEEE E E\n");\r
- fprintf(fp, " EEE : EEEEEEE EEEEEEEE\n");\r
- fprintf(fp, " :E : EEEE E\n");\r
- fprintf(fp, " .-E -:----- E\n");\r
- fprintf(fp, " :E : E\n");\r
- fprintf(fp, " EE : EEEEEEEE\n");\r
- fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEE\n");\r
- fprintf(fp, "\n\n\n");\r
- fprintf(fp, " U. S. S. ENTERPRISE\n");\r
- fprintf(fp, "\n\n\n\n");\r
- fprintf(fp, " For demonstrating outstanding ability as a starship captain\n");\r
- fprintf(fp, "\n");\r
- fprintf(fp, " Starfleet Command bestows to you\n");\r
- fprintf(fp, "\n");\r
- fprintf(fp,"%*s%s\n\n", nskip, "", winner);\r
- fprintf(fp, " the rank of\n\n");\r
- fprintf(fp, " \"Commodore Emeritus\"\n\n");\r
- fprintf(fp, " ");\r
- switch (iskill) {\r
- case 4: fprintf(fp," Expert level\n\n"); break;\r
- case 5: fprintf(fp,"Emeritus level\n\n"); break;\r
- default: fprintf(fp," Cheat level\n\n"); break;\r
- }\r
- t = time(NULL);\r
- timestring = ctime(&t);\r
- fprintf(fp, " This day of %.6s %.4s, %.8s\n\n",\r
- timestring+4, timestring+20, timestring+11);\r
- fprintf(fp," Your score: %d\n\n", iscore);\r
- fprintf(fp," Klingons per stardate: %.2f\n", perdate);\r
- fclose(fp);\r
-}\r
+#include "sst.h"
+#include <string.h>
+#include <time.h>
+
+void dstrct() {
+ /* Finish with a BANG! */
+ chew();
+ if (game.damage[DCOMPTR] != 0.0) {
+ prout("Computer damaged; cannot execute destruct sequence.");
+ return;
+ }
+ skip(1);
+ prouts("---WORKING---"); skip(1);
+ prout("SELF-DESTRUCT-SEQUENCE-ACTIVATED");
+ prouts(" 10"); skip(1);
+ prouts(" 9"); skip(1);
+ prouts(" 8"); skip(1);
+ prouts(" 7"); skip(1);
+ prouts(" 6"); skip(1);
+ prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");
+ prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");
+ prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");
+ scan();
+ chew();
+ if (strcmp(game.passwd, citem) != 0) {
+ prouts("PASSWORD-REJECTED;"); skip(1);
+ prout("CONTINUITY-EFFECTED");
+ skip(1);
+ return;
+ }
+ prouts("PASSWORD-ACCEPTED"); skip(1);
+ prouts(" 5"); skip(1);
+ prouts(" 4"); skip(1);
+ prouts(" 3"); skip(1);
+ prouts(" 2"); skip(1);
+ prouts(" 1"); skip(1);
+ if (Rand() < 0.15) {
+ prouts("GOODBYE-CRUEL-WORLD");
+ skip(1);
+ }
+ skip(2);
+ kaboom();
+}
+
+void kaboom(void) {
+ stars();
+ if (ship==IHE) prouts("***");
+ prouts("********* Entropy of ");
+ crmshp();
+ prouts(" maximized *********");
+ skip(1);
+ stars();
+ skip(1);
+ if (nenhere != 0) {
+ double whammo = 25.0 * energy;
+ int l=1;
+ while (l <= nenhere) {
+ if (game.kpower[l]*game.kdist[l] <= whammo)
+ deadkl(game.kx[l],game.ky[l], game.quad[game.kx[l]][game.ky[l]], game.kx[l], game.ky[l]);
+ l++;
+ }
+ }
+ finish(FDILITHIUM);
+}
+
+
+void finish(FINTYPE ifin) {
+ int igotit = 0;
+ alldone = 1;
+ skip(3);
+ prout("It is stardate %.1f.", game.state.date);
+ prout("");
+ switch (ifin) {
+ case FWON: // Game has been won
+ if (game.state.nromrem != 0)
+ prout("The remaining %d Romulans surrender to Starfleet Command.",
+ game.state.nromrem);
+
+ prout("You have smashed the Klingon invasion fleet and saved");
+ prout("the Federation.");
+ gamewon=1;
+ if (alive) {
+ double badpt;
+ badpt = 5.*game.state.starkl + casual + 10.*game.state.nplankl +
+ 45.*nhelp+100.*game.state.basekl;
+ if (ship == IHF) badpt += 100.0;
+ else if (ship == 0) badpt += 200.0;
+ if (badpt < 100.0) badpt = 0.0; // Close enough!
+ if (game.state.date-indate < 5.0 ||
+ // killsPerDate >= RateMax
+ (game.state.killk+game.state.killc+game.state.nsckill)/(game.state.date-indate) >=
+ 0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {
+ skip(1);
+ prout("In fact, you have done so well that Starfleet Command");
+ switch (skill) {
+ case 1:
+ prout("promotes you one step in rank from \"Novice\" to \"Fair\".");
+ break;
+ case 2:
+ prout("promotes you one step in rank from \"Fair\" to \"Good\".");
+ break;
+ case 3:
+ prout("promotes you one step in rank from \"Good\" to \"Expert\".");
+ break;
+ case 4:
+ prout("promotes you to Commodore Emeritus.");
+ skip(1);
+ prout("Now that you think you're really good, try playing");
+ prout("the \"Emeritus\" game. It will splatter your ego.");
+ break;
+ case 5:
+ skip(1);
+ prout("Computer- ERROR-ERROR-ERROR-ERROR");
+ skip(1);
+ prout(" YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");
+ prout(" THIS-PROGRAM-MUST-SURVIVE");
+ prout(" THIS-PROGRAM-MUST-SURVIVE");
+ prout(" THIS-PROGRAM-MUST-SURVIVE");
+ prout(" THIS-PROGRAM-MUST?- MUST ? - SUR? ? -? VI");
+ skip(1);
+ prout("Now you can retire and write your own Star Trek game!");
+ skip(1);
+ break;
+ }
+ if (skill > 3) {
+ if (thawed
+#ifdef DEBUG
+ && !idebug
+#endif
+ )
+ prout("You cannot get a citation, so...");
+ else {
+ prout("Do you want your Commodore Emeritus Citation printed?");
+ proutn("(You need a 132 column printer.)");
+ chew();
+ if (ja()) {
+ igotit = 1;
+ }
+ }
+ }
+ }
+ // Only grant long life if alive (original didn't!)
+ skip(1);
+ prout("LIVE LONG AND PROSPER.");
+ }
+ score();
+ if (igotit != 0) plaque();
+ return;
+ case FDEPLETE: // Federation Resources Depleted
+ prout("Your time has run out and the Federation has been");
+ prout("conquered. Your starship is now Klingon property,");
+ prout("and you are put on trial as a war criminal. On the");
+ proutn("basis of your record, you are ");
+ if (game.state.remkl*3.0 > inkling) {
+ prout("aquitted.");
+ skip(1);
+ prout("LIVE LONG AND PROSPER.");
+ }
+ else {
+ prout("found guilty and");
+ prout("sentenced to death by slow torture.");
+ alive = 0;
+ }
+ score();
+ return;
+ case FLIFESUP:
+ prout("Your life support reserves have run out, and");
+ prout("you die of thirst, starvation, and asphyxiation.");
+ prout("Your starship is a derelict in space.");
+ break;
+ case FNRG:
+ prout("Your energy supply is exhausted.");
+ skip(1);
+ prout("Your starship is a derelict in space.");
+ break;
+ case FBATTLE:
+ proutn("The ");
+ crmshp();
+ prout("has been destroyed in battle.");
+ skip(1);
+ prout("Dulce et decorum est pro patria mori.");
+ break;
+ case FNEG3:
+ prout("You have made three attempts to cross the negative energy");
+ prout("barrier which surrounds the galaxy.");
+ skip(1);
+ prout("Your navigation is abominable.");
+ score();
+ return;
+ case FNOVA:
+ prout("Your starship has been destroyed by a nova.");
+ prout("That was a great shot.");
+ skip(1);
+ break;
+ case FSNOVAED:
+ proutn("The ");
+ crmshp();
+ prout(" has been fried by a supernova.");
+ prout("...Not even cinders remain...");
+ break;
+ case FABANDN:
+ prout("You have been captured by the Klingons. If you still");
+ prout("had a starbase to be returned to, you would have been");
+ prout("repatriated and given another chance. Since you have");
+ prout("no starbases, you will be mercilessly tortured to death.");
+ break;
+ case FDILITHIUM:
+ prout("Your starship is now an expanding cloud of subatomic particles");
+ break;
+ case FMATERIALIZE:
+ prout("Starbase was unable to re-materialize your starship.");
+ prout("Sic transit gloria muntdi");
+ break;
+ case FPHASER:
+ proutn("The ");
+ crmshp();
+ prout(" has been cremated by its own phasers.");
+ break;
+ case FLOST:
+ prout("You and your landing party have been");
+ prout("converted to energy, disipating through space.");
+ break;
+ case FMINING:
+ prout("You are left with your landing party on");
+ prout("a wild jungle planet inhabited by primitive cannibals.");
+ skip(1);
+ prout("They are very fond of \"Captain Kirk\" soup.");
+ skip(1);
+ proutn("Without your leadership, the ");
+ crmshp();
+ prout(" is destroyed.");
+ break;
+ case FDPLANET:
+ prout("You and your mining party perish.");
+ skip(1);
+ prout("That was a great shot.");
+ skip(1);
+ break;
+ case FSSC:
+ prout("The Galileo is instantly annihilated by the supernova.");
+ // no break;
+ case FPNOVA:
+ prout("You and your mining party are atomized.");
+ skip(1);
+ proutn("Mr. Spock takes command of the ");
+ crmshp();
+ prout(" and");
+ prout("joins the Romulans, reigning terror on the Federation.");
+ break;
+ case FSTRACTOR:
+ prout("The shuttle craft Galileo is also caught,");
+ prout("and breaks up under the strain.");
+ skip(1);
+ prout("Your debris is scattered for millions of miles.");
+ proutn("Without your leadership, the ");
+ crmshp();
+ prout(" is destroyed.");
+ break;
+ case FDRAY:
+ prout("The mutants attack and kill Spock.");
+ prout("Your ship is captured by Klingons, and");
+ prout("your crew is put on display in a Klingon zoo.");
+ break;
+ case FTRIBBLE:
+ prout("Tribbles consume all remaining water,");
+ prout("food, and oxygen on your ship.");
+ skip(1);
+ prout("You die of thirst, starvation, and asphyxiation.");
+ prout("Your starship is a derelict in space.");
+ break;
+ case FHOLE:
+ prout("Your ship is drawn to the center of the black hole.");
+ prout("You are crushed into extremely dense matter.");
+ break;
+ }
+ if (ship==IHF) ship= 0;
+ else if (ship == IHE) ship = IHF;
+ alive = 0;
+ if (game.state.remkl != 0) {
+ double goodies = game.state.remres/inresor;
+ double baddies = (game.state.remkl + 2.0*game.state.remcom)/(inkling+2.0*incom);
+ if (goodies/baddies >= 1.0+0.5*Rand()) {
+ prout("As a result of your actions, a treaty with the Klingon");
+ prout("Empire has been signed. The terms of the treaty are");
+ if (goodies/baddies >= 3.0+Rand()) {
+ prout("favorable to the Federation.");
+ skip(1);
+ prout("Congratulations!");
+ }
+ else
+ prout("highly unfavorable to the Federation.");
+ }
+ else
+ prout("The Federation will be destroyed.");
+ }
+ else {
+ prout("Since you took the last Klingon with you, you are a");
+ prout("martyr and a hero. Someday maybe they'll erect a");
+ prout("statue in your memory. Rest in peace, and try not");
+ prout("to think about pigeons.");
+ gamewon = 1;
+ }
+ score();
+}
+
+void score(void) {
+ double timused = game.state.date - indate;
+ int ithperd, iwon, klship;
+
+ pause_game(0);
+
+ iskill = skill;
+ if ((timused == 0 || game.state.remkl != 0) && timused < 5.0) timused = 5.0;
+ perdate = (game.state.killc + game.state.killk + game.state.nsckill)/timused;
+ ithperd = 500*perdate + 0.5;
+ iwon = 0;
+ if (gamewon) iwon = 100*skill;
+ if (ship == IHE) klship = 0;
+ else if (ship == IHF) klship = 1;
+ else klship = 2;
+ if (gamewon == 0) game.state.nromrem = 0; // None captured if no win
+ iscore = 10*game.state.killk + 50*game.state.killc + ithperd + iwon
+ - 100*game.state.basekl - 100*klship - 45*nhelp -5*game.state.starkl - casual
+ + 20*game.state.nromkl + 200*game.state.nsckill - 10*game.state.nplankl + game.state.nromrem;
+ if (alive == 0) iscore -= 200;
+ skip(2);
+ prout("Your score --");
+ if (game.state.nromkl)
+ prout("%6d Romulans destroyed %5d",
+ game.state.nromkl,20*game.state.nromkl);
+ if (game.state.nromrem)
+ prout("%6d Romulans captured %5d",
+ game.state.nromrem, game.state.nromrem);
+ if (game.state.killk)
+ prout("%6d ordinary Klingons destroyed %5d",
+ game.state.killk, 10*game.state.killk);
+ if (game.state.killc)
+ prout("%6d Klingon commanders destroyed %5d",
+ game.state.killc, 50*game.state.killc);
+ if (game.state.nsckill)
+ prout("%6d Super-Commander destroyed %5d",
+ game.state.nsckill, 200*game.state.nsckill);
+ if (ithperd)
+ prout("%.2f Klingons per stardate %5d",
+ perdate, ithperd);
+ if (game.state.starkl)
+ prout("%6d stars destroyed by your action %5d",
+ game.state.starkl, -5*game.state.starkl);
+ if (game.state.nplankl)
+ prout("%6d planets destroyed by your action %5d",
+ game.state.nplankl, -10*game.state.nplankl);
+ if (game.state.basekl)
+ prout("%6d bases destroyed by your action %5d",
+ game.state.basekl, -100*game.state.basekl);
+ if (nhelp)
+ prout("%6d calls for help from starbase %5d",
+ nhelp, -45*nhelp);
+ if (casual)
+ prout("%6d casualties incurred %5d",
+ casual, -casual);
+ if (klship)
+ prout("%6d ship(s) lost or destroyed %5d",
+ klship, -100*klship);
+ if (alive==0)
+ prout("Penalty for getting yourself killed -200");
+ if (gamewon) {
+ skip(1);
+ proutn("Bonus for winning ");
+ switch (skill) {
+ case 1: proutn("Novice game "); break;
+ case 2: proutn("Fair game "); break;
+ case 3: proutn("Good game "); break;
+ case 4: proutn("Expert game "); break;
+ case 5: proutn("Emeritus game"); break;
+ }
+ prout(" %5d", iwon);
+ }
+ skip(2);
+ prout("TOTAL SCORE %5d", iscore);
+}
+
+void plaque(void) {
+ FILE *fp=NULL;
+ time_t t;
+ char *timestring;
+ int nskip;
+ char winner[128];
+
+ skip(2);
+
+ while (fp == NULL) {
+ proutn("File or device name for your plaque:");
+ fgets(winner, 128, stdin);
+ winner[strlen(winner)-1] = '\0';
+ fp = fopen(winner, "w");
+ if (fp==NULL) {
+ prout("Invalid name.");
+ }
+ }
+
+ proutn("Enter name to go on plaque (up to 30 characters):");
+ fgets(winner, 128, stdin);
+ winner[strlen(winner)-1] = '\0';
+ winner[30] = '\0';
+ nskip = 64 - strlen(winner)/2;
+
+ fprintf(fp,"\n\n\n\n");
+ /* --------DRAW ENTERPRISE PICTURE. */
+ fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );
+ fprintf(fp, " EEE E : : : E\n" );
+ fprintf(fp, " EE EEE E : : NCC-1701 : E\n");
+ fprintf(fp, " EEEEEEEEEEEEEEEE EEEEEEEEEEEEEEE E : : : E\n");
+ fprintf(fp, " E E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");
+ fprintf(fp, " EEEEEEEEE EEEEEEEEEEEEE E E\n");
+ fprintf(fp, " EEEEEEE EEEEE E E E E\n");
+ fprintf(fp, " EEE E E E E\n");
+ fprintf(fp, " E E E E\n");
+ fprintf(fp, " EEEEEEEEEEEEE E E\n");
+ fprintf(fp, " EEE : EEEEEEE EEEEEEEE\n");
+ fprintf(fp, " :E : EEEE E\n");
+ fprintf(fp, " .-E -:----- E\n");
+ fprintf(fp, " :E : E\n");
+ fprintf(fp, " EE : EEEEEEEE\n");
+ fprintf(fp, " EEEEEEEEEEEEEEEEEEEEEEE\n");
+ fprintf(fp, "\n\n\n");
+ fprintf(fp, " U. S. S. ENTERPRISE\n");
+ fprintf(fp, "\n\n\n\n");
+ fprintf(fp, " For demonstrating outstanding ability as a starship captain\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " Starfleet Command bestows to you\n");
+ fprintf(fp, "\n");
+ fprintf(fp,"%*s%s\n\n", nskip, "", winner);
+ fprintf(fp, " the rank of\n\n");
+ fprintf(fp, " \"Commodore Emeritus\"\n\n");
+ fprintf(fp, " ");
+ switch (iskill) {
+ case 4: fprintf(fp," Expert level\n\n"); break;
+ case 5: fprintf(fp,"Emeritus level\n\n"); break;
+ default: fprintf(fp," Cheat level\n\n"); break;
+ }
+ t = time(NULL);
+ timestring = ctime(&t);
+ fprintf(fp, " This day of %.6s %.4s, %.8s\n\n",
+ timestring+4, timestring+20, timestring+11);
+ fprintf(fp," Your score: %d\n\n", iscore);
+ fprintf(fp," Klingons per stardate: %.2f\n", perdate);
+ fclose(fp);
+}
-#include <unistd.h>\r
-#include "sst.h"\r
-\r
-static void getcd(int, int);\r
-\r
-void imove(void) {\r
- double angle, deltax, deltay, bigger, x, y,\r
- finald, finalx, finaly, stopegy, probf;\r
- int trbeam = 0, n, l, ix=0, iy=0, kink, kinks, iquad;\r
-\r
- if (inorbit) {\r
- prout("Helmsman Sulu- \"Leaving standard orbit.\"");\r
- inorbit = 0;\r
- }\r
-\r
- angle = ((15.0 - direc) * 0.5235988);\r
- deltax = -sin(angle);\r
- deltay = cos(angle);\r
- if (fabs(deltax) > fabs(deltay))\r
- bigger = fabs(deltax);\r
- else\r
- bigger = fabs(deltay);\r
- \r
- deltay /= bigger;\r
- deltax /= bigger;\r
-\r
- /* If tractor beam is to occur, don't move full distance */\r
- if (game.state.date+Time >= game.future[FTBEAM]) {\r
- trbeam = 1;\r
- condit = IHRED;\r
- dist = dist*(game.future[FTBEAM]-game.state.date)/Time + 0.1;\r
- Time = game.future[FTBEAM] - game.state.date + 1e-5;\r
- }\r
- /* Move within the quadrant */\r
- game.quad[sectx][secty] = IHDOT;\r
- x = sectx;\r
- y = secty;\r
- n = 10.0*dist*bigger+0.5;\r
-\r
- if (n > 0) {\r
- for (l = 1; l <= n; l++) {\r
- ix = (x += deltax) + 0.5;\r
- iy = (y += deltay) + 0.5;\r
- if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {\r
- /* Leaving quadrant -- allow final enemy attack */\r
- /* Don't do it if being pushed by Nova */\r
- if (nenhere != 0 && iattak != 2) {\r
- newcnd();\r
- for (l = 1; l <= nenhere; l++) {\r
- finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +\r
- (iy-game.ky[l])*(double)(iy-game.ky[l]));\r
- game.kavgd[l] = 0.5 * (finald+game.kdist[l]);\r
- }\r
- if (game.state.galaxy[quadx][quady] != 1000) attack(0);\r
- if (alldone) return;\r
- }\r
- /* compute final position -- new quadrant and sector */\r
- x = 10*(quadx-1)+sectx;\r
- y = 10*(quady-1)+secty;\r
- ix = x+10.0*dist*bigger*deltax+0.5;\r
- iy = y+10.0*dist*bigger*deltay+0.5;\r
- /* check for edge of galaxy */\r
- kinks = 0;\r
- do {\r
- kink = 0;\r
- if (ix <= 0) {\r
- ix = -ix + 1;\r
- kink = 1;\r
- }\r
- if (iy <= 0) {\r
- iy = -iy + 1;\r
- kink = 1;\r
- }\r
- if (ix > 80) {\r
- ix = 161 - ix;\r
- kink = 1;\r
- }\r
- if (iy > 80) {\r
- iy = 161 - iy;\r
- kink = 1;\r
- }\r
- if (kink) kinks = 1;\r
- } while (kink);\r
-\r
- if (kinks) {\r
- nkinks += 1;\r
- if (nkinks == 3) {\r
- /* Three strikes -- you're out! */\r
- finish(FNEG3);\r
- return;\r
- }\r
- prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"\r
- "AT THE EDGE OF THE GALAXY. THE THIRD TIME YOU TRY THIS,\n"\r
- "YOU WILL BE DESTROYED.\n");\r
- }\r
- /* Compute final position in new quadrant */\r
- if (trbeam) return; /* Don't bother if we are to be beamed */\r
- quadx = (ix+9)/10;\r
- quady = (iy+9)/10;\r
- sectx = ix - 10*(quadx-1);\r
- secty = iy - 10*(quady-1);\r
- proutn("\n\rEntering %s.",\r
- cramlc(quadrant, quadx, quady));\r
- game.quad[sectx][secty] = ship;\r
- newqad(0);\r
- if (skill>1) attack(0);\r
- return;\r
- }\r
- iquad = game.quad[ix][iy];\r
- if (iquad != IHDOT) {\r
- /* object encountered in flight path */\r
- stopegy = 50.0*dist/Time;\r
- dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
- (secty-iy)*(double)(secty-iy));\r
- switch (iquad) {\r
- case IHT: /* Ram a Tholian */\r
- case IHK: /* Ram enemy ship */\r
- case IHC:\r
- case IHS:\r
- case IHR:\r
- case IHQUEST:\r
- sectx = ix;\r
- secty = iy;\r
- ram(0, iquad, sectx, secty);\r
- finalx = sectx;\r
- finaly = secty;\r
- break;\r
- case IHBLANK:\r
- skip(1);\r
- prouts("***RED ALERT! RED ALERT!");\r
- skip(1);\r
- proutn("***");\r
- crmshp();\r
- proutn(" pulled into black hole at ");\r
- prout(cramlc(sector, ix, iy));\r
- /*\r
- * Getting pulled into a black \r
- * hole was certain death in\r
- * Almy's original. Stas \r
- * Sergeev added a possibility\r
- * that you'll get timewarped\r
- * instead.\r
- */\r
- n=0;\r
- for (l=1;l<=NDEVICES+1;l++)\r
- if (game.damage[l]>0) n++;\r
- probf=pow(1.4,(energy+shield)/5000.0-1.0)*\r
- pow(1.3,1.0/(n+1)-1.0);\r
- if (Rand()>probf) \r
- timwrp();\r
- else \r
- finish(FHOLE);\r
- return;\r
- default:\r
- /* something else */\r
- skip(1);\r
- crmshp();\r
- if (iquad == IHWEB)\r
- proutn(" encounters Tholian web at ");\r
- else\r
- proutn(" blocked by object at ");\r
- proutn(cramlc(sector, ix,iy));\r
- prout(";");\r
- proutn("Emergency stop required ");\r
- prout("%2d units of energy.", (int)stopegy);\r
- energy -= stopegy;\r
- finalx = x-deltax+0.5;\r
- sectx = finalx;\r
- finaly = y-deltay+0.5;\r
- secty = finaly;\r
- if (energy <= 0) {\r
- finish(FNRG);\r
- return;\r
- }\r
- break;\r
- }\r
- goto label100; /* sorry! */\r
- }\r
- }\r
- dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +\r
- (secty-iy)*(double)(secty-iy));\r
- sectx = ix;\r
- secty = iy;\r
- }\r
- finalx = sectx;\r
- finaly = secty;\r
-label100:\r
- /* No quadrant change -- compute new avg enemy distances */\r
- game.quad[sectx][secty] = ship;\r
- if (nenhere) {\r
- for (l = 1; l <= nenhere; l++) {\r
- finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +\r
- (iy-game.ky[l])*(double)(iy-game.ky[l]));\r
- game.kavgd[l] = 0.5 * (finald+game.kdist[l]);\r
- game.kdist[l] = finald;\r
- }\r
- sortkl();\r
- if (game.state.galaxy[quadx][quady] != 1000 && iattak == 0)\r
- attack(0);\r
- for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];\r
- }\r
- newcnd();\r
- iattak = 0;\r
-#ifdef SERGEEV\r
- drawmaps(0);\r
-#endif /* SERGEEV */\r
- return;\r
-}\r
-\r
-void dock(int l) {\r
- chew();\r
- if (condit == IHDOCKED && l) {\r
- prout("Already docked.");\r
- return;\r
- }\r
- if (inorbit) {\r
- prout("You must first leave standard orbit.");\r
- return;\r
- }\r
- if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {\r
- crmshp();\r
- prout(" not adjacent to base.");\r
- return;\r
- }\r
- condit = IHDOCKED;\r
- if (l) prout("Docked.");\r
- ididit=1;\r
- if (energy < inenrg) energy = inenrg;\r
- shield = inshld;\r
- torps = intorps;\r
- lsupres = inlsr;\r
- if (stdamtim != 1e30 &&\r
- (game.future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {\r
- /* get attack report from base */\r
- prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");\r
- attakreport(0);\r
- iseenit = 1;\r
- }\r
-}\r
-\r
-static void getcd(int isprobe, int akey) {\r
- /* This program originally required input in terms of a (clock)\r
- direction and distance. Somewhere in history, it was changed to\r
- cartesian coordinates. So we need to convert. I think\r
- "manual" input should still be done this way -- it's a real\r
- pain if the computer isn't working! Manual mode is still confusing\r
- because it involves giving x and y motions, yet the coordinates\r
- are always displayed y - x, where +y is downward! */\r
-\r
- \r
- int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key=0;\r
- double xi, xj, xk, xl;\r
- double deltax, deltay;\r
- int automatic = -1;\r
-\r
- /* Get course direction and distance. If user types bad values, return\r
- with DIREC = -1.0. */\r
-\r
- direc = -1.0;\r
- \r
- if (landed == 1 && !isprobe) {\r
- prout("Dummy! You can't leave standard orbit until you");\r
- proutn("are back abourt the ");\r
- crmshp();\r
- prout(".");\r
- chew();\r
- return;\r
- }\r
- while (automatic == -1) {\r
- if (game.damage[DCOMPTR]) {\r
- if (isprobe)\r
- prout("Computer damaged; manual navigation only");\r
- else\r
- prout("Computer damaged; manual movement only");\r
- chew();\r
- automatic = 0;\r
- key = IHEOL;\r
- break;\r
- }\r
- if (isprobe && akey != -1) {\r
- /* For probe launch, use pre-scaned value first time */\r
- key = akey;\r
- akey = -1;\r
- }\r
- else \r
- key = scan();\r
-\r
- if (key == IHEOL) {\r
- proutn("Manual or automatic- ");\r
- iprompt = 1;\r
- chew();\r
- }\r
- else if (key == IHALPHA) {\r
- if (isit("manual")) {\r
- automatic =0;\r
- key = scan();\r
- break;\r
- }\r
- else if (isit("automatic")) {\r
- automatic = 1;\r
- key = scan();\r
- break;\r
- }\r
- else {\r
- huh();\r
- chew();\r
- return;\r
- }\r
- }\r
- else { /* numeric */\r
- if (isprobe)\r
- prout("(Manual navigation assumed.)");\r
- else\r
- prout("(Manual movement assumed.)");\r
- automatic = 0;\r
- break;\r
- }\r
- }\r
-\r
- if (automatic) {\r
- while (key == IHEOL) {\r
- if (isprobe)\r
- proutn("Target quadrant or quadrant§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 %s.\"",\r
- cramlc(sector, irows, icols));\r
- }\r
- }\r
- else prout("Ensign Chekov- \"Course laid in, Captain.\"");\r
- }\r
- deltax = icolq - quady + 0.1*(icols-secty);\r
- deltay = quadx - irowq + 0.1*(sectx-irows);\r
- }\r
- else { /* manual */\r
- while (key == IHEOL) {\r
- proutn("X and Y displacements- ");\r
- chew();\r
- iprompt = 1;\r
- key = scan();\r
- }\r
- itemp = 2;\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- deltax = aaitem;\r
- key = scan();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- deltay = aaitem;\r
- }\r
- /* Check for zero movement */\r
- if (deltax == 0 && deltay == 0) {\r
- chew();\r
- return;\r
- }\r
- if (itemp == 2 && !isprobe) {\r
- skip(1);\r
- prout("Helmsman Sulu- \"Aye, Sir.\"");\r
- }\r
- dist = sqrt(deltax*deltax + deltay*deltay);\r
- direc = atan2(deltax, deltay)*1.90985932;\r
- if (direc < 0.0) direc += 12.0;\r
- chew();\r
- return;\r
-\r
-}\r
- \r
-\r
-\r
-void impuls(void) {\r
- double power;\r
-\r
- ididit = 0;\r
- if (game.damage[DIMPULS]) {\r
- chew();\r
- skip(1);\r
- prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
- return;\r
- }\r
-\r
- if (energy > 30.0) {\r
- getcd(FALSE, 0);\r
- if (direc == -1.0) return;\r
- power = 20.0 + 100.0*dist;\r
- }\r
- else\r
- power = 30.0;\r
-\r
- if (power >= energy) {\r
- /* Insufficient power for trip */\r
- skip(1);\r
- prout("First Officer Spock- \"Captain, the impulse engines");\r
- prout("require 20.0 units to engage, plus 100.0 units per");\r
- if (energy > 30) {\r
- proutn("quadrant. We can go, therefore, a maximum of %d", \r
- (int)(0.01 * (energy-20.0)-0.05));\r
- prout(" quadrants.\"");\r
- }\r
- else {\r
- prout("quadrant. They are, therefore, useless.\"");\r
- }\r
- chew();\r
- return;\r
- }\r
- /* Make sure enough time is left for the trip */\r
- Time = dist/0.095;\r
- if (Time >= game.state.remtime) {\r
- prout("First Officer Spock- \"Captain, our speed under impulse");\r
- prout("power is only 0.95 sectors per stardate. Are you sure");\r
- proutn("we dare spend the time?\" ");\r
- if (ja() == 0) return;\r
- }\r
- /* Activate impulse engines and pay the cost */\r
- imove();\r
- ididit = 1;\r
- if (alldone) return;\r
- power = 20.0 + 100.0*dist;\r
- energy -= power;\r
- Time = dist/0.095;\r
- if (energy <= 0) finish(FNRG);\r
- return;\r
-}\r
-\r
-\r
-void warp(int i) {\r
- int blooey=0, twarp=0, iwarp;\r
- double power;\r
-\r
- if (i!=2) { /* Not WARPX entry */\r
- ididit = 0;\r
- if (game.damage[DWARPEN] > 10.0) {\r
- chew();\r
- skip(1);\r
- prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");\r
- return;\r
- }\r
- if (game.damage[DWARPEN] > 0.0 && warpfac > 4.0) {\r
- chew();\r
- skip(1);\r
- prout("Engineer Scott- \"Sorry, Captain. Until this damage");\r
- prout(" is repaired, I can only give you warp 4.\"");\r
- return;\r
- }\r
- \r
- /* Read in course and distance */\r
- getcd(FALSE, 0);\r
- if (direc == -1.0) return;\r
-\r
- /* Make sure starship has enough energy for the trip */\r
- power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);\r
-\r
-\r
- if (power >= energy) {\r
- /* Insufficient power for trip */\r
- ididit = 0;\r
- skip(1);\r
- prout("Engineering to bridge--");\r
- if (shldup==0 || 0.5*power > energy) {\r
- iwarp = pow((energy/(dist+0.05)), 0.333333333);\r
- if (iwarp <= 0) {\r
- prout("We can't do it, Captain. We haven't the energy.");\r
- }\r
- else {\r
- proutn("We haven't the energy, but we could do it at warp %d", iwarp);\r
- if (shldup) {\r
- prout(",");\r
- prout("if you'll lower the shields.");\r
- }\r
- else\r
- prout(".");\r
- }\r
- }\r
- else\r
- prout("We haven't the energy to go that far with the shields up.");\r
- return;\r
- }\r
- \r
- /* Make sure enough time is left for the trip */\r
- Time = 10.0*dist/wfacsq;\r
- if (Time >= 0.8*game.state.remtime) {\r
- skip(1);\r
- prout("First Officer Spock- \"Captain, I compute that such");\r
- proutn(" a trip would require approximately %2.0f",\r
- 100.0*Time/game.state.remtime);\r
- prout(" percent of our");\r
- proutn(" remaining time. Are you sure this is wise?\" ");\r
- if (ja() == 0) { ididit = 0; Time=0; return;}\r
- }\r
- }\r
- /* Entry WARPX */\r
- if (warpfac > 6.0) {\r
- /* Decide if engine damage will occur */\r
- double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;\r
- if (prob > Rand()) {\r
- blooey = 1;\r
- dist = Rand()*dist;\r
- }\r
- /* Decide if time warp will occur */\r
- if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;\r
-#ifdef DEBUG\r
- if (idebug &&warpfac==10 && twarp==0) {\r
- blooey=0;\r
- proutn("Force time warp? ");\r
- if (ja()==1) twarp=1;\r
- }\r
-#endif\r
- if (blooey || twarp) {\r
- /* If time warp or engine damage, check path */\r
- /* If it is obstructed, don't do warp or damage */\r
- double angle = ((15.0-direc)*0.5235998);\r
- double deltax = -sin(angle);\r
- double deltay = cos(angle);\r
- double bigger, x, y;\r
- int n, l, ix, iy;\r
- if (fabs(deltax) > fabs(deltay))\r
- bigger = fabs(deltax);\r
- else\r
- bigger = fabs(deltay);\r
- \r
- deltax /= bigger;\r
- deltay /= bigger;\r
- n = 10.0 * dist * bigger +0.5;\r
- x = sectx;\r
- y = secty;\r
- for (l = 1; l <= n; l++) {\r
- x += deltax;\r
- ix = x + 0.5;\r
- if (ix < 1 || ix > 10) break;\r
- y += deltay;\r
- iy = y +0.5;\r
- if (iy < 1 || iy > 10) break;\r
- if (game.quad[ix][iy] != IHDOT) {\r
- blooey = 0;\r
- twarp = 0;\r
- }\r
- }\r
- }\r
- }\r
- \r
-\r
- /* Activate Warp Engines and pay the cost */\r
- imove();\r
- if (alldone) return;\r
- energy -= dist*warpfac*warpfac*warpfac*(shldup+1);\r
- if (energy <= 0) finish(FNRG);\r
- Time = 10.0*dist/wfacsq;\r
- if (twarp) timwrp();\r
- if (blooey) {\r
- game.damage[DWARPEN] = damfac*(3.0*Rand()+1.0);\r
- skip(1);\r
- prout("Engineering to bridge--");\r
- prout(" Scott here. The warp engines are damaged.");\r
- prout(" We'll have to reduce speed to warp 4.");\r
- }\r
- ididit = 1;\r
- return;\r
-}\r
-\r
-\r
-\r
-void setwrp(void) {\r
- int key;\r
- double oldfac;\r
- \r
- while ((key=scan()) == IHEOL) {\r
- chew();\r
- proutn("Warp factor- ");\r
- }\r
- chew();\r
- if (key != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- if (game.damage[DWARPEN] > 10.0) {\r
- prout("Warp engines inoperative.");\r
- return;\r
- }\r
- if (game.damage[DWARPEN] > 0.0 && aaitem > 4.0) {\r
- prout("Engineer Scott- \"I'm doing my best, Captain,\n"\r
- " but right now we can only go warp 4.\"");\r
- return;\r
- }\r
- if (aaitem > 10.0) {\r
- prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");\r
- return;\r
- }\r
- if (aaitem < 1.0) {\r
- prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");\r
- return;\r
- }\r
- oldfac = warpfac;\r
- warpfac = aaitem;\r
- wfacsq=warpfac*warpfac;\r
- if (warpfac <= oldfac || warpfac <= 6.0) {\r
- proutn("Helmsman Sulu- \"Warp factor %d, Captain.\"", \r
- (int)warpfac);\r
- return;\r
- }\r
- if (warpfac < 8.00) {\r
- prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");\r
- return;\r
- }\r
- if (warpfac == 10.0) {\r
- prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");\r
- return;\r
- }\r
- prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");\r
- return;\r
-}\r
-\r
-void atover(int igrab) {\r
- double power, distreq;\r
-\r
- chew();\r
- /* is captain on planet? */\r
- if (landed==1) {\r
- if (game.damage[DTRANSP]) {\r
- finish(FPNOVA);\r
- return;\r
- }\r
- prout("Scotty rushes to the transporter controls.");\r
- if (shldup) {\r
- prout("But with the shields up it's hopeless.");\r
- finish(FPNOVA);\r
- }\r
- prouts("His desperate attempt to rescue you . . .");\r
- if (Rand() <= 0.5) {\r
- prout("fails.");\r
- finish(FPNOVA);\r
- return;\r
- }\r
- prout("SUCCEEDS!");\r
- if (imine) {\r
- imine = 0;\r
- proutn("The crystals mined were ");\r
- if (Rand() <= 0.25) {\r
- prout("lost.");\r
- }\r
- else {\r
- prout("saved.");\r
- icrystl = 1;\r
- }\r
- }\r
- }\r
- if (igrab) return;\r
-\r
- /* Check to see if captain in shuttle craft */\r
- if (icraft) finish(FSTRACTOR);\r
- if (alldone) return;\r
-\r
- /* Inform captain of attempt to reach safety */\r
- skip(1);\r
- do {\r
- if (justin) {\r
- prouts("***RED ALERT! READ ALERT!");\r
- skip(1);\r
- proutn("The ");\r
- crmshp();\r
- prout(" has stopped in a quadrant containing");\r
- prouts(" a supernova.");\r
- skip(2);\r
- }\r
- proutn("***Emergency automatic override attempts to hurl ");\r
- crmshp();\r
- skip(1);\r
- prout("safely out of quadrant.");\r
- game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+1000:1;\r
-\r
- /* Try to use warp engines */\r
- if (game.damage[DWARPEN]) {\r
- skip(1);\r
- prout("Warp engines damaged.");\r
- finish(FSNOVAED);\r
- return;\r
- }\r
- warpfac = 6.0+2.0*Rand();\r
- wfacsq = warpfac * warpfac;\r
- prout("Warp factor set to %d", (int)warpfac);\r
- power = 0.75*energy;\r
- dist = power/(warpfac*warpfac*warpfac*(shldup+1));\r
- distreq = 1.4142+Rand();\r
- if (distreq < dist) dist = distreq;\r
- Time = 10.0*dist/wfacsq;\r
- direc = 12.0*Rand(); /* How dumb! */\r
- justin = 0;\r
- inorbit = 0;\r
- warp(2);\r
- if (justin == 0) {\r
- /* This is bad news, we didn't leave quadrant. */\r
- if (alldone) return;\r
- skip(1);\r
- prout("Insufficient energy to leave quadrant.");\r
- finish(FSNOVAED);\r
- return;\r
- }\r
- /* Repeat if another snova */\r
- } while (game.state.galaxy[quadx][quady] == 1000);\r
- if (game.state.remkl==0) finish(FWON); /* Snova killed remaining enemy. */\r
-}\r
-\r
-void timwrp() {\r
- int l, ll, gotit;\r
- prout("***TIME WARP ENTERED.");\r
- if (game.state.snap && Rand() < 0.5) {\r
- /* Go back in time */\r
- prout("You are traveling backwards in time %d stardates.",\r
- (int)(game.state.date-game.snapsht.date));\r
- game.state = game.snapsht;\r
- game.state.snap = 0;\r
- if (game.state.remcom) {\r
- game.future[FTBEAM] = game.state.date + expran(intime/game.state.remcom);\r
- game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
- }\r
- game.future[FSNOVA] = game.state.date + expran(0.5*intime);\r
- game.future[FSNAP] = game.state.date +expran(0.25*game.state.remtime); /* next snapshot will\r
- be sooner */\r
- if (game.state.nscrem) game.future[FSCMOVE] = 0.2777;\r
- isatb = 0;\r
- game.future[FCDBAS] = game.future[FSCDBAS] = 1e30;\r
- batx = baty = 0;\r
-\r
- /* Make sure Galileo is consistant -- Snapshot may have been taken\r
- when on planet, which would give us two Galileos! */\r
- gotit = 0;\r
- for (l = 0; l < inplan; l++) {\r
- if (game.state.plnets[l].known == shuttle_down) {\r
- gotit = 1;\r
- if (iscraft==1 && ship==IHE) {\r
- prout("Checkov- \"Security reports the Galileo has disappeared, Sir!");\r
- iscraft = 0;\r
- }\r
- }\r
- }\r
- /* Likewise, if in the original time the Galileo was abandoned, but\r
- was on ship earlier, it would have vanished -- lets restore it */\r
- if (iscraft==0 && gotit==0 && game.damage[DSHUTTL] >= 0.0) {\r
- prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\"");\r
- iscraft = 1;\r
- }\r
-\r
- /* Revert star chart to earlier era, if it was known then*/\r
- if (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) {\r
- for (l = 1; l <= 8; l++)\r
- for (ll = 1; ll <= 8; ll++)\r
- if (game.starch[l][ll] > 1)\r
- game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+1000 :1;\r
- prout("Spock has reconstructed a correct star chart from memory");\r
- if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date;\r
- }\r
- }\r
- else {\r
- /* Go forward in time */\r
- Time = -0.5*intime*log(Rand());\r
- prout("You are traveling forward in time %d stardates.", (int)Time);\r
- /* cheat to make sure no tractor beams occur during time warp */\r
- game.future[FTBEAM] += Time;\r
- game.damage[DRADIO] += Time;\r
- }\r
- newqad(0);\r
-#ifdef SERGEEV\r
- events();\r
-#endif /* SERGEEV */\r
-}\r
-\r
-void probe(void) {\r
- double angle, bigger;\r
- int key;\r
- /* New code to launch a deep space probe */\r
- if (nprobes == 0) {\r
- chew();\r
- skip(1);\r
- if (ship == IHE) \r
- prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");\r
- else\r
- prout("Ye Faerie Queene has no deep space probes.");\r
- return;\r
- }\r
- if (game.damage[DDSP] != 0.0) {\r
- chew();\r
- skip(1);\r
- prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");\r
- return;\r
- }\r
- if (game.future[FDSPROB] != 1e30) {\r
- chew();\r
- skip(1);\r
- if (game.damage[DRADIO] != 0 && condit != IHDOCKED) {\r
- prout("Spock- \"Records show the previous probe has not yet");\r
- prout(" reached its destination.\"");\r
- }\r
- else\r
- prout("Uhura- \"The previous probe is still reporting data, Sir.\"");\r
- return;\r
- }\r
- key = scan();\r
-\r
- if (key == IHEOL) {\r
- /* slow mode, so let Kirk know how many probes there are left */\r
- prout(nprobes==1 ? "%d probe left." : "%d probes left.", nprobes);\r
- proutn("Are you sure you want to fire a probe? ");\r
- if (ja()==0) return;\r
- }\r
-\r
- isarmed = FALSE;\r
- if (key == IHALPHA && strcmp(citem,"armed") == 0) {\r
- isarmed = TRUE;\r
- key = scan();\r
- }\r
- else if (key == IHEOL) {\r
- proutn("Arm NOVAMAX warhead? ");\r
- isarmed = ja();\r
- }\r
- getcd(TRUE, key);\r
- if (direc == -1.0) return;\r
- nprobes--;\r
- angle = ((15.0 - direc) * 0.5235988);\r
- probeinx = -sin(angle);\r
- probeiny = cos(angle);\r
- if (fabs(probeinx) > fabs(probeiny))\r
- bigger = fabs(probeinx);\r
- else\r
- bigger = fabs(probeiny);\r
- \r
- probeiny /= bigger;\r
- probeinx /= bigger;\r
- proben = 10.0*dist*bigger +0.5;\r
- probex = quadx*10 + sectx - 1; // We will use better packing than original\r
- probey = quady*10 + secty - 1;\r
- probecx = quadx;\r
- probecy = quady;\r
- game.future[FDSPROB] = game.state.date + 0.01; // Time to move one sector\r
- prout("Ensign Chekov- \"The deep space probe is launched, Captain.\"");\r
- ididit = 1;\r
- return;\r
-}\r
-\r
-void help(void) {\r
- /* There's more than one way to move in this game! */\r
- double ddist, xdist, probf;\r
- int line = 0, l, ix, iy;\r
-#ifdef SERGEEV\r
- int pox, posy;\r
-#endif /* SERGEEV */\r
-\r
- chew();\r
- /* Test for conditions which prevent calling for help */\r
- if (condit == IHDOCKED) {\r
- prout("Lt. Uhura- \"But Captain, we're already docked.\"");\r
- return;\r
- }\r
- if (game.damage[DRADIO] != 0) {\r
- prout("Subspace radio damaged.");\r
- return;\r
- }\r
- if (game.state.rembase==0) {\r
- prout("Lt. Uhura- \"Captain, I'm not getting any response from Starbase.\"");\r
- return;\r
- }\r
- if (landed == 1) {\r
- proutn("You must be aboard the ");\r
- crmshp();\r
- prout(".");\r
- return;\r
- }\r
- /* OK -- call for help from nearest starbase */\r
- nhelp++;\r
- if (basex!=0) {\r
- /* There's one in this quadrant */\r
- ddist = sqrt(square(basex-sectx)+square(basey-secty));\r
- }\r
- else {\r
- ddist = 1e30;\r
- for (l = 1; l <= game.state.rembase; l++) {\r
- xdist=10.0*sqrt(square(game.state.baseqx[l]-quadx)+square(game.state.baseqy[l]-quady));\r
- if (xdist < ddist) {\r
- ddist = xdist;\r
- line = l;\r
- }\r
- }\r
- /* Since starbase not in quadrant, set up new quadrant */\r
- quadx = game.state.baseqx[line];\r
- quady = game.state.baseqy[line];\r
- newqad(1);\r
- }\r
- /* dematerialize starship */\r
- game.quad[sectx][secty]=IHDOT;\r
- proutn("Starbase in %s responds--", cramlc(quadrant, quadx, quady));\r
- proutn("");\r
- crmshp();\r
- prout(" dematerializes.");\r
-#ifdef SERGEEV\r
- sectx=0;\r
- for (l = 1; l <= 5; l++) {\r
- ix = basex+3.0*Rand()-1;\r
- iy = basey+3.0*Rand()-1;\r
- if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {\r
- /* found one -- finish up */\r
- sectx=ix;\r
- secty=iy;\r
- game.quad[ix][iy]=IHMATER0;\r
- break;\r
- }\r
- }\r
- if (sectx==0){\r
- prout("You have been lost in space...");\r
- finish(FMATERIALIZE);\r
- return;\r
- }\r
-#endif /* SERGEEV */\r
- /* Give starbase three chances to rematerialize starship */\r
- probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);\r
- for (l = 1; l <= 3; l++) {\r
- switch (l) {\r
- case 1: proutn("1st"); break;\r
- case 2: proutn("2nd"); break;\r
- case 3: proutn("3rd"); break;\r
- }\r
- proutn(" attempt to re-materialize ");\r
- crmshp();\r
- prouts(" . . . . . ");\r
- if (Rand() > probf) break;\r
- prout("fails.");\r
- }\r
- if (l > 3) {\r
- finish(FMATERIALIZE);\r
- return;\r
- }\r
- /* Rematerialization attempt should succeed if can get adj to base */\r
- for (l = 1; l <= 5; l++) {\r
- ix = basex+3.0*Rand()-1;\r
- iy = basey+3.0*Rand()-1;\r
- if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {\r
- /* found one -- finish up */\r
- prout("succeeds.");\r
- sectx=ix;\r
- secty=iy;\r
- game.quad[ix][iy]=ship;\r
- dock(0);\r
- skip(1);\r
- prout("Lt. Uhura- \"Captain, we made it!\"");\r
- return;\r
- }\r
- }\r
- finish(FMATERIALIZE);\r
- return;\r
-}\r
+#include <unistd.h>
+#include "sst.h"
+
+static void getcd(int, int);
+
+void imove(void) {
+ double angle, deltax, deltay, bigger, x, y,
+ finald, finalx, finaly, stopegy, probf;
+ int trbeam = 0, n, l, ix=0, iy=0, kink, kinks, iquad;
+
+ if (inorbit) {
+ prout("Helmsman Sulu- \"Leaving standard orbit.\"");
+ inorbit = 0;
+ }
+
+ angle = ((15.0 - direc) * 0.5235988);
+ deltax = -sin(angle);
+ deltay = cos(angle);
+ if (fabs(deltax) > fabs(deltay))
+ bigger = fabs(deltax);
+ else
+ bigger = fabs(deltay);
+
+ deltay /= bigger;
+ deltax /= bigger;
+
+ /* If tractor beam is to occur, don't move full distance */
+ if (game.state.date+Time >= game.future[FTBEAM]) {
+ trbeam = 1;
+ condit = IHRED;
+ dist = dist*(game.future[FTBEAM]-game.state.date)/Time + 0.1;
+ Time = game.future[FTBEAM] - game.state.date + 1e-5;
+ }
+ /* Move within the quadrant */
+ game.quad[sectx][secty] = IHDOT;
+ x = sectx;
+ y = secty;
+ n = 10.0*dist*bigger+0.5;
+
+ if (n > 0) {
+ for (l = 1; l <= n; l++) {
+ ix = (x += deltax) + 0.5;
+ iy = (y += deltay) + 0.5;
+ if (ix < 1 || ix > 10 || iy < 1 || iy > 10) {
+ /* Leaving quadrant -- allow final enemy attack */
+ /* Don't do it if being pushed by Nova */
+ if (nenhere != 0 && iattak != 2) {
+ newcnd();
+ for (l = 1; l <= nenhere; l++) {
+ finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +
+ (iy-game.ky[l])*(double)(iy-game.ky[l]));
+ game.kavgd[l] = 0.5 * (finald+game.kdist[l]);
+ }
+ if (game.state.galaxy[quadx][quady] != 1000) attack(0);
+ if (alldone) return;
+ }
+ /* compute final position -- new quadrant and sector */
+ x = 10*(quadx-1)+sectx;
+ y = 10*(quady-1)+secty;
+ ix = x+10.0*dist*bigger*deltax+0.5;
+ iy = y+10.0*dist*bigger*deltay+0.5;
+ /* check for edge of galaxy */
+ kinks = 0;
+ do {
+ kink = 0;
+ if (ix <= 0) {
+ ix = -ix + 1;
+ kink = 1;
+ }
+ if (iy <= 0) {
+ iy = -iy + 1;
+ kink = 1;
+ }
+ if (ix > 80) {
+ ix = 161 - ix;
+ kink = 1;
+ }
+ if (iy > 80) {
+ iy = 161 - iy;
+ kink = 1;
+ }
+ if (kink) kinks = 1;
+ } while (kink);
+
+ if (kinks) {
+ nkinks += 1;
+ if (nkinks == 3) {
+ /* Three strikes -- you're out! */
+ finish(FNEG3);
+ return;
+ }
+ prout("\nYOU HAVE ATTEMPTED TO CROSS THE NEGATIVE ENERGY BARRIER\n"
+ "AT THE EDGE OF THE GALAXY. THE THIRD TIME YOU TRY THIS,\n"
+ "YOU WILL BE DESTROYED.\n");
+ }
+ /* Compute final position in new quadrant */
+ if (trbeam) return; /* Don't bother if we are to be beamed */
+ quadx = (ix+9)/10;
+ quady = (iy+9)/10;
+ sectx = ix - 10*(quadx-1);
+ secty = iy - 10*(quady-1);
+ proutn("\n\rEntering %s.",
+ cramlc(quadrant, quadx, quady));
+ game.quad[sectx][secty] = ship;
+ newqad(0);
+ if (skill>1) attack(0);
+ return;
+ }
+ iquad = game.quad[ix][iy];
+ if (iquad != IHDOT) {
+ /* object encountered in flight path */
+ stopegy = 50.0*dist/Time;
+ dist=0.1*sqrt((sectx-ix)*(double)(sectx-ix) +
+ (secty-iy)*(double)(secty-iy));
+ switch (iquad) {
+ case IHT: /* Ram a Tholian */
+ case IHK: /* Ram enemy ship */
+ case IHC:
+ case IHS:
+ case IHR:
+ case IHQUEST:
+ sectx = ix;
+ secty = iy;
+ ram(0, iquad, sectx, secty);
+ finalx = sectx;
+ finaly = secty;
+ break;
+ case IHBLANK:
+ skip(1);
+ prouts("***RED ALERT! RED ALERT!");
+ skip(1);
+ proutn("***");
+ crmshp();
+ proutn(" pulled into black hole at ");
+ prout(cramlc(sector, ix, iy));
+ /*
+ * Getting pulled into a black
+ * hole was certain death in
+ * Almy's original. Stas
+ * Sergeev added a possibility
+ * that you'll get timewarped
+ * instead.
+ */
+ n=0;
+ for (l=1;l<=NDEVICES+1;l++)
+ if (game.damage[l]>0) n++;
+ probf=pow(1.4,(energy+shield)/5000.0-1.0)*
+ pow(1.3,1.0/(n+1)-1.0);
+ if (Rand()>probf)
+ timwrp();
+ else
+ finish(FHOLE);
+ return;
+ default:
+ /* something else */
+ skip(1);
+ crmshp();
+ if (iquad == IHWEB)
+ proutn(" encounters Tholian web at ");
+ else
+ proutn(" blocked by object at ");
+ proutn(cramlc(sector, ix,iy));
+ prout(";");
+ proutn("Emergency stop required ");
+ prout("%2d units of energy.", (int)stopegy);
+ energy -= stopegy;
+ finalx = x-deltax+0.5;
+ sectx = finalx;
+ finaly = y-deltay+0.5;
+ secty = finaly;
+ if (energy <= 0) {
+ finish(FNRG);
+ return;
+ }
+ break;
+ }
+ goto label100; /* sorry! */
+ }
+ }
+ dist = 0.1*sqrt((sectx-ix)*(double)(sectx-ix) +
+ (secty-iy)*(double)(secty-iy));
+ sectx = ix;
+ secty = iy;
+ }
+ finalx = sectx;
+ finaly = secty;
+label100:
+ /* No quadrant change -- compute new avg enemy distances */
+ game.quad[sectx][secty] = ship;
+ if (nenhere) {
+ for (l = 1; l <= nenhere; l++) {
+ finald = sqrt((ix-game.kx[l])*(double)(ix-game.kx[l]) +
+ (iy-game.ky[l])*(double)(iy-game.ky[l]));
+ game.kavgd[l] = 0.5 * (finald+game.kdist[l]);
+ game.kdist[l] = finald;
+ }
+ sortkl();
+ if (game.state.galaxy[quadx][quady] != 1000 && iattak == 0)
+ attack(0);
+ for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];
+ }
+ newcnd();
+ iattak = 0;
+#ifdef SERGEEV
+ drawmaps(0);
+#endif /* SERGEEV */
+ return;
+}
+
+void dock(int l) {
+ chew();
+ if (condit == IHDOCKED && l) {
+ prout("Already docked.");
+ return;
+ }
+ if (inorbit) {
+ prout("You must first leave standard orbit.");
+ return;
+ }
+ if (basex==0 || abs(sectx-basex) > 1 || abs(secty-basey) > 1) {
+ crmshp();
+ prout(" not adjacent to base.");
+ return;
+ }
+ condit = IHDOCKED;
+ if (l) prout("Docked.");
+ ididit=1;
+ if (energy < inenrg) energy = inenrg;
+ shield = inshld;
+ torps = intorps;
+ lsupres = inlsr;
+ if (stdamtim != 1e30 &&
+ (game.future[FCDBAS] < 1e30 || isatb == 1) && iseenit == 0) {
+ /* get attack report from base */
+ prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");
+ attakreport(0);
+ iseenit = 1;
+ }
+}
+
+static void getcd(int isprobe, int akey) {
+ /* This program originally required input in terms of a (clock)
+ direction and distance. Somewhere in history, it was changed to
+ cartesian coordinates. So we need to convert. I think
+ "manual" input should still be done this way -- it's a real
+ pain if the computer isn't working! Manual mode is still confusing
+ because it involves giving x and y motions, yet the coordinates
+ are always displayed y - x, where +y is downward! */
+
+
+ int irowq=quadx, icolq=quady, irows, icols, itemp=0, iprompt=0, key=0;
+ double xi, xj, xk, xl;
+ double deltax, deltay;
+ int automatic = -1;
+
+ /* Get course direction and distance. If user types bad values, return
+ with DIREC = -1.0. */
+
+ direc = -1.0;
+
+ if (landed == 1 && !isprobe) {
+ prout("Dummy! You can't leave standard orbit until you");
+ proutn("are back abourt the ");
+ crmshp();
+ prout(".");
+ chew();
+ return;
+ }
+ while (automatic == -1) {
+ if (game.damage[DCOMPTR]) {
+ if (isprobe)
+ prout("Computer damaged; manual navigation only");
+ else
+ prout("Computer damaged; manual movement only");
+ chew();
+ automatic = 0;
+ key = IHEOL;
+ break;
+ }
+ if (isprobe && akey != -1) {
+ /* For probe launch, use pre-scaned value first time */
+ key = akey;
+ akey = -1;
+ }
+ else
+ key = scan();
+
+ if (key == IHEOL) {
+ proutn("Manual or automatic- ");
+ iprompt = 1;
+ chew();
+ }
+ else if (key == IHALPHA) {
+ if (isit("manual")) {
+ automatic =0;
+ key = scan();
+ break;
+ }
+ else if (isit("automatic")) {
+ automatic = 1;
+ key = scan();
+ break;
+ }
+ else {
+ huh();
+ chew();
+ return;
+ }
+ }
+ else { /* numeric */
+ if (isprobe)
+ prout("(Manual navigation assumed.)");
+ else
+ prout("(Manual movement assumed.)");
+ automatic = 0;
+ break;
+ }
+ }
+
+ if (automatic) {
+ while (key == IHEOL) {
+ if (isprobe)
+ proutn("Target quadrant or quadrant§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) {
+ proutn("Helmsman Sulu- \"Course locked in for %s.\"",
+ cramlc(sector, irows, icols));
+ }
+ }
+ else prout("Ensign Chekov- \"Course laid in, Captain.\"");
+ }
+ deltax = icolq - quady + 0.1*(icols-secty);
+ deltay = quadx - irowq + 0.1*(sectx-irows);
+ }
+ else { /* manual */
+ while (key == IHEOL) {
+ proutn("X and Y displacements- ");
+ chew();
+ iprompt = 1;
+ key = scan();
+ }
+ itemp = 2;
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ deltax = aaitem;
+ key = scan();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ deltay = aaitem;
+ }
+ /* Check for zero movement */
+ if (deltax == 0 && deltay == 0) {
+ chew();
+ return;
+ }
+ if (itemp == 2 && !isprobe) {
+ skip(1);
+ prout("Helmsman Sulu- \"Aye, Sir.\"");
+ }
+ dist = sqrt(deltax*deltax + deltay*deltay);
+ direc = atan2(deltax, deltay)*1.90985932;
+ if (direc < 0.0) direc += 12.0;
+ chew();
+ return;
+
+}
+
+
+
+void impuls(void) {
+ double power;
+
+ ididit = 0;
+ if (game.damage[DIMPULS]) {
+ chew();
+ skip(1);
+ prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");
+ return;
+ }
+
+ if (energy > 30.0) {
+ getcd(FALSE, 0);
+ if (direc == -1.0) return;
+ power = 20.0 + 100.0*dist;
+ }
+ else
+ power = 30.0;
+
+ if (power >= energy) {
+ /* Insufficient power for trip */
+ skip(1);
+ prout("First Officer Spock- \"Captain, the impulse engines");
+ prout("require 20.0 units to engage, plus 100.0 units per");
+ if (energy > 30) {
+ proutn("quadrant. We can go, therefore, a maximum of %d",
+ (int)(0.01 * (energy-20.0)-0.05));
+ prout(" quadrants.\"");
+ }
+ else {
+ prout("quadrant. They are, therefore, useless.\"");
+ }
+ chew();
+ return;
+ }
+ /* Make sure enough time is left for the trip */
+ Time = dist/0.095;
+ if (Time >= game.state.remtime) {
+ prout("First Officer Spock- \"Captain, our speed under impulse");
+ prout("power is only 0.95 sectors per stardate. Are you sure");
+ proutn("we dare spend the time?\" ");
+ if (ja() == 0) return;
+ }
+ /* Activate impulse engines and pay the cost */
+ imove();
+ ididit = 1;
+ if (alldone) return;
+ power = 20.0 + 100.0*dist;
+ energy -= power;
+ Time = dist/0.095;
+ if (energy <= 0) finish(FNRG);
+ return;
+}
+
+
+void warp(int i) {
+ int blooey=0, twarp=0, iwarp;
+ double power;
+
+ if (i!=2) { /* Not WARPX entry */
+ ididit = 0;
+ if (game.damage[DWARPEN] > 10.0) {
+ chew();
+ skip(1);
+ prout("Engineer Scott- \"The impulse engines are damaged, Sir.\"");
+ return;
+ }
+ if (game.damage[DWARPEN] > 0.0 && warpfac > 4.0) {
+ chew();
+ skip(1);
+ prout("Engineer Scott- \"Sorry, Captain. Until this damage");
+ prout(" is repaired, I can only give you warp 4.\"");
+ return;
+ }
+
+ /* Read in course and distance */
+ getcd(FALSE, 0);
+ if (direc == -1.0) return;
+
+ /* Make sure starship has enough energy for the trip */
+ power = (dist+0.05)*warpfac*warpfac*warpfac*(shldup+1);
+
+
+ if (power >= energy) {
+ /* Insufficient power for trip */
+ ididit = 0;
+ skip(1);
+ prout("Engineering to bridge--");
+ if (shldup==0 || 0.5*power > energy) {
+ iwarp = pow((energy/(dist+0.05)), 0.333333333);
+ if (iwarp <= 0) {
+ prout("We can't do it, Captain. We haven't the energy.");
+ }
+ else {
+ proutn("We haven't the energy, but we could do it at warp %d", iwarp);
+ if (shldup) {
+ prout(",");
+ prout("if you'll lower the shields.");
+ }
+ else
+ prout(".");
+ }
+ }
+ else
+ prout("We haven't the energy to go that far with the shields up.");
+ return;
+ }
+
+ /* Make sure enough time is left for the trip */
+ Time = 10.0*dist/wfacsq;
+ if (Time >= 0.8*game.state.remtime) {
+ skip(1);
+ prout("First Officer Spock- \"Captain, I compute that such");
+ proutn(" a trip would require approximately %2.0f",
+ 100.0*Time/game.state.remtime);
+ prout(" percent of our");
+ proutn(" remaining time. Are you sure this is wise?\" ");
+ if (ja() == 0) { ididit = 0; Time=0; return;}
+ }
+ }
+ /* Entry WARPX */
+ if (warpfac > 6.0) {
+ /* Decide if engine damage will occur */
+ double prob = dist*(6.0-warpfac)*(6.0-warpfac)/66.666666666;
+ if (prob > Rand()) {
+ blooey = 1;
+ dist = Rand()*dist;
+ }
+ /* Decide if time warp will occur */
+ if (0.5*dist*pow(7.0,warpfac-10.0) > Rand()) twarp=1;
+#ifdef DEBUG
+ if (idebug &&warpfac==10 && twarp==0) {
+ blooey=0;
+ proutn("Force time warp? ");
+ if (ja()==1) twarp=1;
+ }
+#endif
+ if (blooey || twarp) {
+ /* If time warp or engine damage, check path */
+ /* If it is obstructed, don't do warp or damage */
+ double angle = ((15.0-direc)*0.5235998);
+ double deltax = -sin(angle);
+ double deltay = cos(angle);
+ double bigger, x, y;
+ int n, l, ix, iy;
+ if (fabs(deltax) > fabs(deltay))
+ bigger = fabs(deltax);
+ else
+ bigger = fabs(deltay);
+
+ deltax /= bigger;
+ deltay /= bigger;
+ n = 10.0 * dist * bigger +0.5;
+ x = sectx;
+ y = secty;
+ for (l = 1; l <= n; l++) {
+ x += deltax;
+ ix = x + 0.5;
+ if (ix < 1 || ix > 10) break;
+ y += deltay;
+ iy = y +0.5;
+ if (iy < 1 || iy > 10) break;
+ if (game.quad[ix][iy] != IHDOT) {
+ blooey = 0;
+ twarp = 0;
+ }
+ }
+ }
+ }
+
+
+ /* Activate Warp Engines and pay the cost */
+ imove();
+ if (alldone) return;
+ energy -= dist*warpfac*warpfac*warpfac*(shldup+1);
+ if (energy <= 0) finish(FNRG);
+ Time = 10.0*dist/wfacsq;
+ if (twarp) timwrp();
+ if (blooey) {
+ game.damage[DWARPEN] = damfac*(3.0*Rand()+1.0);
+ skip(1);
+ prout("Engineering to bridge--");
+ prout(" Scott here. The warp engines are damaged.");
+ prout(" We'll have to reduce speed to warp 4.");
+ }
+ ididit = 1;
+ return;
+}
+
+
+
+void setwrp(void) {
+ int key;
+ double oldfac;
+
+ while ((key=scan()) == IHEOL) {
+ chew();
+ proutn("Warp factor- ");
+ }
+ chew();
+ if (key != IHREAL) {
+ huh();
+ return;
+ }
+ if (game.damage[DWARPEN] > 10.0) {
+ prout("Warp engines inoperative.");
+ return;
+ }
+ if (game.damage[DWARPEN] > 0.0 && aaitem > 4.0) {
+ prout("Engineer Scott- \"I'm doing my best, Captain,\n"
+ " but right now we can only go warp 4.\"");
+ return;
+ }
+ if (aaitem > 10.0) {
+ prout("Helmsman Sulu- \"Our top speed is warp 10, Captain.\"");
+ return;
+ }
+ if (aaitem < 1.0) {
+ prout("Helmsman Sulu- \"We can't go below warp 1, Captain.\"");
+ return;
+ }
+ oldfac = warpfac;
+ warpfac = aaitem;
+ wfacsq=warpfac*warpfac;
+ if (warpfac <= oldfac || warpfac <= 6.0) {
+ proutn("Helmsman Sulu- \"Warp factor %d, Captain.\"",
+ (int)warpfac);
+ return;
+ }
+ if (warpfac < 8.00) {
+ prout("Engineer Scott- \"Aye, but our maximum safe speed is warp 6.\"");
+ return;
+ }
+ if (warpfac == 10.0) {
+ prout("Engineer Scott- \"Aye, Captain, we'll try it.\"");
+ return;
+ }
+ prout("Engineer Scott- \"Aye, Captain, but our engines may not take it.\"");
+ return;
+}
+
+void atover(int igrab) {
+ double power, distreq;
+
+ chew();
+ /* is captain on planet? */
+ if (landed==1) {
+ if (game.damage[DTRANSP]) {
+ finish(FPNOVA);
+ return;
+ }
+ prout("Scotty rushes to the transporter controls.");
+ if (shldup) {
+ prout("But with the shields up it's hopeless.");
+ finish(FPNOVA);
+ }
+ prouts("His desperate attempt to rescue you . . .");
+ if (Rand() <= 0.5) {
+ prout("fails.");
+ finish(FPNOVA);
+ return;
+ }
+ prout("SUCCEEDS!");
+ if (imine) {
+ imine = 0;
+ proutn("The crystals mined were ");
+ if (Rand() <= 0.25) {
+ prout("lost.");
+ }
+ else {
+ prout("saved.");
+ icrystl = 1;
+ }
+ }
+ }
+ if (igrab) return;
+
+ /* Check to see if captain in shuttle craft */
+ if (icraft) finish(FSTRACTOR);
+ if (alldone) return;
+
+ /* Inform captain of attempt to reach safety */
+ skip(1);
+ do {
+ if (justin) {
+ prouts("***RED ALERT! READ ALERT!");
+ skip(1);
+ proutn("The ");
+ crmshp();
+ prout(" has stopped in a quadrant containing");
+ prouts(" a supernova.");
+ skip(2);
+ }
+ proutn("***Emergency automatic override attempts to hurl ");
+ crmshp();
+ skip(1);
+ prout("safely out of quadrant.");
+ game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+1000:1;
+
+ /* Try to use warp engines */
+ if (game.damage[DWARPEN]) {
+ skip(1);
+ prout("Warp engines damaged.");
+ finish(FSNOVAED);
+ return;
+ }
+ warpfac = 6.0+2.0*Rand();
+ wfacsq = warpfac * warpfac;
+ prout("Warp factor set to %d", (int)warpfac);
+ power = 0.75*energy;
+ dist = power/(warpfac*warpfac*warpfac*(shldup+1));
+ distreq = 1.4142+Rand();
+ if (distreq < dist) dist = distreq;
+ Time = 10.0*dist/wfacsq;
+ direc = 12.0*Rand(); /* How dumb! */
+ justin = 0;
+ inorbit = 0;
+ warp(2);
+ if (justin == 0) {
+ /* This is bad news, we didn't leave quadrant. */
+ if (alldone) return;
+ skip(1);
+ prout("Insufficient energy to leave quadrant.");
+ finish(FSNOVAED);
+ return;
+ }
+ /* Repeat if another snova */
+ } while (game.state.galaxy[quadx][quady] == 1000);
+ if (game.state.remkl==0) finish(FWON); /* Snova killed remaining enemy. */
+}
+
+void timwrp() {
+ int l, ll, gotit;
+ prout("***TIME WARP ENTERED.");
+ if (game.state.snap && Rand() < 0.5) {
+ /* Go back in time */
+ prout("You are traveling backwards in time %d stardates.",
+ (int)(game.state.date-game.snapsht.date));
+ game.state = game.snapsht;
+ game.state.snap = 0;
+ if (game.state.remcom) {
+ game.future[FTBEAM] = game.state.date + expran(intime/game.state.remcom);
+ game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+ }
+ game.future[FSNOVA] = game.state.date + expran(0.5*intime);
+ game.future[FSNAP] = game.state.date +expran(0.25*game.state.remtime); /* next snapshot will
+ be sooner */
+ if (game.state.nscrem) game.future[FSCMOVE] = 0.2777;
+ isatb = 0;
+ game.future[FCDBAS] = game.future[FSCDBAS] = 1e30;
+ batx = baty = 0;
+
+ /* Make sure Galileo is consistant -- Snapshot may have been taken
+ when on planet, which would give us two Galileos! */
+ gotit = 0;
+ for (l = 0; l < inplan; l++) {
+ if (game.state.plnets[l].known == shuttle_down) {
+ gotit = 1;
+ if (iscraft==1 && ship==IHE) {
+ prout("Checkov- \"Security reports the Galileo has disappeared, Sir!");
+ iscraft = 0;
+ }
+ }
+ }
+ /* Likewise, if in the original time the Galileo was abandoned, but
+ was on ship earlier, it would have vanished -- lets restore it */
+ if (iscraft==0 && gotit==0 && game.damage[DSHUTTL] >= 0.0) {
+ prout("Checkov- \"Security reports the Galileo has reappeared in the dock!\"");
+ iscraft = 1;
+ }
+
+ /* Revert star chart to earlier era, if it was known then*/
+ if (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) {
+ for (l = 1; l <= 8; l++)
+ for (ll = 1; ll <= 8; ll++)
+ if (game.starch[l][ll] > 1)
+ game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+1000 :1;
+ prout("Spock has reconstructed a correct star chart from memory");
+ if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date;
+ }
+ }
+ else {
+ /* Go forward in time */
+ Time = -0.5*intime*log(Rand());
+ prout("You are traveling forward in time %d stardates.", (int)Time);
+ /* cheat to make sure no tractor beams occur during time warp */
+ game.future[FTBEAM] += Time;
+ game.damage[DRADIO] += Time;
+ }
+ newqad(0);
+#ifdef SERGEEV
+ events();
+#endif /* SERGEEV */
+}
+
+void probe(void) {
+ double angle, bigger;
+ int key;
+ /* New code to launch a deep space probe */
+ if (nprobes == 0) {
+ chew();
+ skip(1);
+ if (ship == IHE)
+ prout("Engineer Scott- \"We have no more deep space probes, Sir.\"");
+ else
+ prout("Ye Faerie Queene has no deep space probes.");
+ return;
+ }
+ if (game.damage[DDSP] != 0.0) {
+ chew();
+ skip(1);
+ prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");
+ return;
+ }
+ if (game.future[FDSPROB] != 1e30) {
+ chew();
+ skip(1);
+ if (game.damage[DRADIO] != 0 && condit != IHDOCKED) {
+ prout("Spock- \"Records show the previous probe has not yet");
+ prout(" reached its destination.\"");
+ }
+ else
+ prout("Uhura- \"The previous probe is still reporting data, Sir.\"");
+ return;
+ }
+ key = scan();
+
+ if (key == IHEOL) {
+ /* slow mode, so let Kirk know how many probes there are left */
+ prout(nprobes==1 ? "%d probe left." : "%d probes left.", nprobes);
+ proutn("Are you sure you want to fire a probe? ");
+ if (ja()==0) return;
+ }
+
+ isarmed = FALSE;
+ if (key == IHALPHA && strcmp(citem,"armed") == 0) {
+ isarmed = TRUE;
+ key = scan();
+ }
+ else if (key == IHEOL) {
+ proutn("Arm NOVAMAX warhead? ");
+ isarmed = ja();
+ }
+ getcd(TRUE, key);
+ if (direc == -1.0) return;
+ nprobes--;
+ angle = ((15.0 - direc) * 0.5235988);
+ probeinx = -sin(angle);
+ probeiny = cos(angle);
+ if (fabs(probeinx) > fabs(probeiny))
+ bigger = fabs(probeinx);
+ else
+ bigger = fabs(probeiny);
+
+ probeiny /= bigger;
+ probeinx /= bigger;
+ proben = 10.0*dist*bigger +0.5;
+ probex = quadx*10 + sectx - 1; // We will use better packing than original
+ probey = quady*10 + secty - 1;
+ probecx = quadx;
+ probecy = quady;
+ game.future[FDSPROB] = game.state.date + 0.01; // Time to move one sector
+ prout("Ensign Chekov- \"The deep space probe is launched, Captain.\"");
+ ididit = 1;
+ return;
+}
+
+void help(void) {
+ /* There's more than one way to move in this game! */
+ double ddist, xdist, probf;
+ int line = 0, l, ix, iy;
+#ifdef SERGEEV
+ int pox, posy;
+#endif /* SERGEEV */
+
+ chew();
+ /* Test for conditions which prevent calling for help */
+ if (condit == IHDOCKED) {
+ prout("Lt. Uhura- \"But Captain, we're already docked.\"");
+ return;
+ }
+ if (game.damage[DRADIO] != 0) {
+ prout("Subspace radio damaged.");
+ return;
+ }
+ if (game.state.rembase==0) {
+ prout("Lt. Uhura- \"Captain, I'm not getting any response from Starbase.\"");
+ return;
+ }
+ if (landed == 1) {
+ proutn("You must be aboard the ");
+ crmshp();
+ prout(".");
+ return;
+ }
+ /* OK -- call for help from nearest starbase */
+ nhelp++;
+ if (basex!=0) {
+ /* There's one in this quadrant */
+ ddist = sqrt(square(basex-sectx)+square(basey-secty));
+ }
+ else {
+ ddist = 1e30;
+ for (l = 1; l <= game.state.rembase; l++) {
+ xdist=10.0*sqrt(square(game.state.baseqx[l]-quadx)+square(game.state.baseqy[l]-quady));
+ if (xdist < ddist) {
+ ddist = xdist;
+ line = l;
+ }
+ }
+ /* Since starbase not in quadrant, set up new quadrant */
+ quadx = game.state.baseqx[line];
+ quady = game.state.baseqy[line];
+ newqad(1);
+ }
+ /* dematerialize starship */
+ game.quad[sectx][secty]=IHDOT;
+ proutn("Starbase in %s responds--", cramlc(quadrant, quadx, quady));
+ proutn("");
+ crmshp();
+ prout(" dematerializes.");
+#ifdef SERGEEV
+ sectx=0;
+ for (l = 1; l <= 5; l++) {
+ ix = basex+3.0*Rand()-1;
+ iy = basey+3.0*Rand()-1;
+ if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {
+ /* found one -- finish up */
+ sectx=ix;
+ secty=iy;
+ game.quad[ix][iy]=IHMATER0;
+ break;
+ }
+ }
+ if (sectx==0){
+ prout("You have been lost in space...");
+ finish(FMATERIALIZE);
+ return;
+ }
+#endif /* SERGEEV */
+ /* Give starbase three chances to rematerialize starship */
+ probf = pow((1.0 - pow(0.98,ddist)), 0.33333333);
+ for (l = 1; l <= 3; l++) {
+ switch (l) {
+ case 1: proutn("1st"); break;
+ case 2: proutn("2nd"); break;
+ case 3: proutn("3rd"); break;
+ }
+ proutn(" attempt to re-materialize ");
+ crmshp();
+ prouts(" . . . . . ");
+ if (Rand() > probf) break;
+ prout("fails.");
+ }
+ if (l > 3) {
+ finish(FMATERIALIZE);
+ return;
+ }
+ /* Rematerialization attempt should succeed if can get adj to base */
+ for (l = 1; l <= 5; l++) {
+ ix = basex+3.0*Rand()-1;
+ iy = basey+3.0*Rand()-1;
+ if (ix>=1 && ix<=10 && iy>=1 && iy<=10 && game.quad[ix][iy]==IHDOT) {
+ /* found one -- finish up */
+ prout("succeeds.");
+ sectx=ix;
+ secty=iy;
+ game.quad[ix][iy]=ship;
+ dock(0);
+ skip(1);
+ prout("Lt. Uhura- \"Captain, we made it!\"");
+ return;
+ }
+ }
+ finish(FMATERIALIZE);
+ return;
+}
-#include "sst.h"\r
-\r
-static int height;\r
-\r
-static char *classes[] = {"M","N","O"};\r
-\r
-static int consumeTime(void) {\r
-/* I think most of this avoidance was caused by overlay scheme.\r
- Let's see what happens if all events can occur here */\r
-\r
-// double asave;\r
- ididit = 1;\r
-#if 0\r
- /* Don't wory about this */\r
- if (future[FTBEAM] <= game.state.date+Time && game.state.remcom != 0 && condit != IHDOCKED) {\r
- /* We are about to be tractor beamed -- operation fails */\r
- return 1;\r
- }\r
-#endif\r
-// asave = future[FSNOVA];\r
-// future[FSNOVA] = 1e30; /* defer supernovas */\r
- events(); /* Used to avoid if future[FSCMOVE] within time */\r
-// future[FSNOVA] = asave;\r
- /*fails if game over, quadrant super-novas or we've moved to new quadrant*/\r
- if (alldone || game.state.galaxy[quadx][quady] == 1000 || justin != 0) return 1;\r
- return 0;\r
-}\r
-\r
-void preport(void) {\r
- int iknow = 0, i;\r
- skip(1);\r
- chew();\r
- prout("Spock- \"Planet report follows, Captain.\"");\r
- skip(1);\r
- for (i = 0; i < inplan; i++) {\r
- if (game.state.plnets[i].known != unknown\r
-#ifdef DEBUG\r
- || ( idebug && game.state.plnets[i].x !=0)\r
-#endif\r
- ) {\r
- iknow = 1;\r
-#ifdef DEBUG\r
- if (idebug && game.state.plnets[i].known==unknown) proutn("(Unknown) ");\r
-#endif\r
- proutn(cramlc(quadrant, game.state.plnets[i].x, game.state.plnets[i].y));\r
- proutn(" class ");\r
- proutn(classes[game.state.plnets[i].pclass]);\r
- proutn(" ");\r
- if (game.state.plnets[i].crystals == 0) proutn("no ");\r
- prout("dilithium crystals present.");\r
- if (game.state.plnets[i].known==shuttle_down) \r
- prout(" Shuttle Craft Galileo on surface.");\r
- }\r
- }\r
- if (iknow==0) prout("No information available.");\r
-}\r
-\r
-void orbit(void) {\r
- skip(1);\r
- chew();\r
- if (inorbit!=0) {\r
- prout("Already in standard orbit.");\r
- return;\r
- }\r
- if (game.damage[DWARPEN] != 0 && game.damage[DIMPULS] != 0) {\r
- prout("Both warp and impulse engines damaged.");\r
- return;\r
- }\r
- if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) {\r
- crmshp();\r
- prout(" not adjacient to planet.\n");\r
- return;\r
- }\r
- Time = 0.02+0.03*Rand();\r
- prout("Helmsman Sulu- \"Entering standard orbit, Sir.\"");\r
- newcnd();\r
- if (consumeTime()) return;\r
- height = (1400.+7200.*Rand());\r
- prout("Sulu- \"Entered orbit at altitude %.2f kilometers.\"", height);\r
- inorbit = 1;\r
- return;\r
-}\r
-\r
-void sensor(void) {\r
- skip(1);\r
- chew();\r
- if (game.damage[DSRSENS] != 0.0) {\r
- prout("Short range sensors damaged.");\r
- return;\r
- }\r
- if (plnetx == 0) {\r
- prout("No planet in this quadrant.");\r
- return;\r
- }\r
- prout("Spock- \"Sensor scan for %s-", cramlc(quadrant, quadx, quady));\r
- skip(1);\r
- prout(" Planet at %s is of class %s.", \r
- cramlc(sector, plnetx, plnety),\r
- classes[game.state.plnets[iplnet].pclass]);\r
- if (game.state.plnets[iplnet].known==shuttle_down) \r
- prout(" Sensors show Galileo still on surface.");\r
- proutn(" Readings indicate");\r
- if (game.state.plnets[iplnet].crystals == 0) proutn(" no");\r
- prout(" dilithium crystals present.\"");\r
- if (game.state.plnets[iplnet].known == unknown) game.state.plnets[iplnet].known = known;\r
- return;\r
-}\r
-\r
-void beam(void) {\r
- chew();\r
- skip(1);\r
- if (game.damage[DTRANSP] != 0) {\r
- prout("Transporter damaged.");\r
- if (game.damage[DSHUTTL]==0 && (game.state.plnets[iplnet].known==shuttle_down || iscraft == 1)) {\r
- skip(1);\r
- proutn("Spock- \"May I suggest the shuttle craft, Sir?\" ");\r
- if (ja() != 0) shuttle();\r
- }\r
- return;\r
- }\r
- if (inorbit==0) {\r
- crmshp();\r
- prout(" not in standard orbit.");\r
- return;\r
- }\r
- if (shldup!=0) {\r
- prout("Impossible to transport through shields.");\r
- return;\r
- }\r
- if (game.state.plnets[iplnet].known==unknown) {\r
- prout("Spock- \"Captain, we have no information on this planet");\r
- prout(" and Starfleet Regulations clearly state that in this situation");\r
- prout(" you may not go down.\"");\r
- return;\r
- }\r
- if (landed==1) {\r
- /* Coming from planet */\r
- if (game.state.plnets[iplnet].known==shuttle_down) {\r
- proutn("Spock- \"Wouldn't you rather take the Galileo?\" ");\r
- if (ja() != 0) {\r
- chew();\r
- return;\r
- }\r
- prout("Your crew hides the Galileo to prevent capture by aliens.");\r
- }\r
- prout("Landing party assembled, ready to beam up.");\r
- skip(1);\r
- prout("Kirk whips out communicator...");\r
- prouts("BEEP BEEP BEEP");\r
- skip(2);\r
- prout("\"Kirk to enterprise- Lock on coordinates...energize.\"");\r
- }\r
- else {\r
- /* Going to planet */\r
- if (game.state.plnets[iplnet].crystals==0) {\r
- prout("Spock- \"Captain, I fail to see the logic in");\r
- prout(" exploring a planet with no dilithium crystals.");\r
- proutn(" Are you sure this is wise?\" ");\r
- if (ja()==0) {\r
- chew();\r
- return;\r
- }\r
- }\r
- prout("Scotty- \"Transporter room ready, Sir.\"");\r
- skip(1);\r
- prout("Kirk, and landing party prepare to beam down to planet surface.");\r
- skip(1);\r
- prout("Kirk- \"Energize.\"");\r
- }\r
- skip(1);\r
- prouts("WWHOOOIIIIIRRRRREEEE.E.E. . . . . . .");\r
- skip(2);\r
- if (Rand() > 0.98) {\r
- prouts("BOOOIIIOOOIIOOOOIIIOIING . . .");\r
- skip(2);\r
- prout("Scotty- \"Oh my God! I've lost them.\"");\r
- finish(FLOST);\r
- return;\r
- }\r
- prouts(". . . . . . .E.E.EEEERRRRRIIIIIOOOHWW");\r
- skip(2);\r
- prout("Transport complete.");\r
- landed = -landed;\r
- if (landed==1 && game.state.plnets[iplnet].known==shuttle_down) {\r
- prout("The shuttle craft Galileo is here!");\r
- }\r
- if (landed!=1 && imine==1) {\r
- icrystl = 1;\r
- cryprob = 0.05;\r
- }\r
- imine = 0;\r
- return;\r
-}\r
-\r
-void mine(void) {\r
-\r
- ididit = 0;\r
- skip(1);\r
- chew();\r
- if (landed!= 1) {\r
- prout("Mining party not on planet.");\r
- return;\r
- }\r
- if (game.state.plnets[iplnet].crystals == 0) {\r
- prout("No dilithium crystals on this planet.");\r
- return;\r
- }\r
- if (imine == 1) {\r
- prout("You've already mined enough crystals for this trip.");\r
- return;\r
- }\r
- if (icrystl == 1 && cryprob == 0.05) {\r
- proutn("With all those fresh crystals aboard the ");\r
- crmshp();\r
- skip(1);\r
- prout("there's no reason to mine more at this time.");\r
- return;\r
- }\r
- Time = (0.1+0.2*Rand())*game.state.plnets[iplnet].pclass;\r
- if (consumeTime()) return;\r
- prout("Mining operation complete.");\r
- imine = 1;\r
- return;\r
-}\r
-\r
-void usecrystals(void) {\r
-\r
- skip(1);\r
- chew();\r
- if (icrystl!=1) {\r
- prout("No dilithium crystals available.");\r
- return;\r
- }\r
- if (energy >= 1000) {\r
- prout("Spock- \"Captain, Starfleet Regulations prohibit such an operation");\r
- prout(" except when condition Yellow exists.");\r
- return;\r
- }\r
- prout("Spock- \"Captain, I must warn you that loading");\r
- prout(" raw dilithium crystals into the ship's power");\r
- prout(" system may risk a severe explosion.");\r
- proutn(" Are you sure this is wise?\" ");\r
- if (ja()==0) {\r
- chew();\r
- return;\r
- }\r
- skip(1);\r
- prout("Engineering Officer Scott- \"(GULP) Aye Sir.");\r
- prout(" Mr. Spock and I will try it.\"");\r
- skip(1);\r
- prout("Spock- \"Crystals in place, Sir.");\r
- prout(" Ready to activate circuit.\"");\r
- skip(1);\r
- prouts("Scotty- \"Keep your fingers crossed, Sir!\"");\r
- skip(1);\r
- if (Rand() <= cryprob) {\r
- prouts(" \"Activating now! - - No good! It's***");\r
- skip(2);\r
- prouts("***RED ALERT! RED A*L********************************");\r
- skip(1);\r
- stars();\r
- prouts("****************** KA-BOOM!!!! *******************");\r
- skip(1);\r
- kaboom();\r
- return;\r
- }\r
- energy += 5000.0*(1.0 + 0.9*Rand());\r
- prouts(" \"Activating now! - - ");\r
- prout("The instruments");\r
- prout(" are going crazy, but I think it's");\r
- prout(" going to work!! Congratulations, Sir!\"");\r
- cryprob *= 2.0;\r
- return;\r
-}\r
-\r
-void shuttle(void) {\r
-\r
- chew();\r
- skip(1);\r
- ididit = 0;\r
- if(game.damage[DSHUTTL] != 0.0) {\r
- if (game.damage[DSHUTTL] == -1.0) {\r
- if (inorbit && game.state.plnets[iplnet].known == shuttle_down)\r
- prout("Ye Faerie Queene has no shuttle craft bay to dock it at.");\r
- else\r
- prout("Ye Faerie Queene had no shuttle craft.");\r
- }\r
- else if (game.damage[DSHUTTL] > 0)\r
- prout("The Galileo is damaged.");\r
- else prout("Shuttle craft is now serving Big Macs.");\r
- return;\r
- }\r
- if (inorbit==0) {\r
- crmshp();\r
- prout(" not in standard orbit.");\r
- return;\r
- }\r
- if ((game.state.plnets[iplnet].known != shuttle_down) && iscraft != 1) {\r
- prout("Shuttle craft not currently available.");\r
- return;\r
- }\r
- if (landed==-1 && game.state.plnets[iplnet].known==shuttle_down) {\r
- prout("You will have to beam down to retrieve the shuttle craft.");\r
- return;\r
- }\r
- if (shldup!=0 || condit == IHDOCKED) {\r
- prout("Shuttle craft cannot pass through shields.");\r
- return;\r
- }\r
- if (game.state.plnets[iplnet].known==unknown) {\r
- prout("Spock- \"Captain, we have no information on this planet");\r
- prout(" and Starfleet Regulations clearly state that in this situation");\r
- prout(" you may not fly down.\"");\r
- return;\r
- }\r
- Time = 3.0e-5*height;\r
- if (Time >= 0.8*game.state.remtime) {\r
- prout("First Officer Spock- \"Captain, I compute that such");\r
- proutn(" a maneuver would require approximately 2d%% of our",\r
- (int)(100*Time/game.state.remtime));\r
- prout("remaining time.");\r
- proutn("Are you sure this is wise?\" ");\r
- if (ja()==0) {\r
- Time = 0.0;\r
- return;\r
- }\r
- }\r
- if (landed == 1) {\r
- /* Kirk on planet */\r
- if (iscraft==1) {\r
- /* Galileo on ship! */\r
- if (game.damage[DTRANSP]==0) {\r
- proutn("Spock- \"Would you rather use the transporter?\" ");\r
- if (ja() != 0) {\r
- beam();\r
- return;\r
- }\r
- proutn("Shuttle crew");\r
- }\r
- else\r
- proutn("Rescue party");\r
- prout(" boards Galileo and swoops toward planet surface.");\r
- iscraft = 0;\r
- skip(1);\r
- if (consumeTime()) return;\r
- game.state.plnets[iplnet].known=shuttle_down;\r
- prout("Trip complete.");\r
- return;\r
- }\r
- else {\r
- /* Ready to go back to ship */\r
- prout("You and your mining party board the");\r
- prout("shuttle craft for the trip back to the Enterprise.");\r
- skip(1);\r
- prout("The short hop begins . . .");\r
- game.state.plnets[iplnet].known=known;\r
- icraft = 1;\r
- skip(1);\r
- landed = -1;\r
- if (consumeTime()) return;\r
- iscraft = 1;\r
- icraft = 0;\r
- if (imine!=0) {\r
- icrystl = 1;\r
- cryprob = 0.05;\r
- }\r
- imine = 0;\r
- prout("Trip complete.");\r
- return;\r
- }\r
- }\r
- else {\r
- /* Kirk on ship */\r
- /* and so is Galileo */\r
- prout("Mining party assembles in the hangar deck,");\r
- prout("ready to board the shuttle craft \"Galileo\".");\r
- skip(1);\r
- prouts("The hangar doors open; the trip begins.");\r
- skip(1);\r
- icraft = 1;\r
- iscraft = 0;\r
- if (consumeTime()) return;\r
- game.state.plnets[iplnet].known = shuttle_down;\r
- landed = 1;\r
- icraft = 0;\r
- prout("Trip complete");\r
- return;\r
- }\r
-}\r
- \r
-\r
-void deathray(void) {\r
- double r = Rand();\r
- \r
- ididit = 0;\r
- skip(1);\r
- chew();\r
- if (ship != IHE) {\r
- prout("Ye Faerie Queene has no death ray.");\r
- return;\r
- }\r
- if (nenhere==0) {\r
- prout("Sulu- \"But Sir, there are no enemies in this quadrant.\"");\r
- return;\r
- }\r
- if (game.damage[DDRAY] > 0.0) {\r
- prout("Death Ray is damaged.");\r
- return;\r
- }\r
- prout("Spock- \"Captain, the 'Experimental Death Ray'");\r
- prout(" is highly unpredictible. Considering the alternatives,");\r
- proutn(" are you sure this is wise?\" ");\r
- if (ja()==0) return;\r
- prout("Spock- \"Acknowledged.\"");\r
- skip(1);\r
- ididit=1;\r
- prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE");\r
- skip(1);\r
- prout("Crew scrambles in emergency preparation.");\r
- prout("Spock and Scotty ready the death ray and");\r
- prout("prepare to channel all ship's power to the device.");\r
- skip(1);\r
- prout("Spock- \"Preparations complete, sir.\"");\r
- prout("Kirk- \"Engage!\"");\r
- skip(1);\r
- prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");\r
- skip(1);\r
- if (r > .30) {\r
- prouts("Sulu- \"Captain! It's working!\"");\r
- skip(2);\r
- while (nenhere > 0)\r
- deadkl(game.kx[1],game.ky[1],game.quad[game.kx[1]][game.ky[1]],game.kx[1],game.ky[1]);\r
- prout("Ensign Chekov- \"Congratulations, Captain!\"");\r
- if (game.state.remkl == 0) finish(FWON);\r
- prout("Spock- \"Captain, I believe the `Experimental Death Ray'");\r
- if (Rand() <= 0.05) {\r
- prout(" is still operational.\"");\r
- }\r
- else {\r
- prout(" has been rendered nonfunctional.\"");\r
- game.damage[DDRAY] = 39.95;\r
- }\r
- return;\r
- }\r
- r = Rand(); // Pick failure method \r
- if (r <= .30) {\r
- prouts("Sulu- \"Captain! It's working!\"");\r
- skip(1);\r
- prouts("***RED ALERT! RED ALERT!");\r
- skip(1);\r
- prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!");\r
- skip(1);\r
- prouts("***RED ALERT! RED A*L********************************");\r
- skip(1);\r
- stars();\r
- prouts("****************** KA-BOOM!!!! *******************");\r
- skip(1);\r
- kaboom();\r
- return;\r
- }\r
- if (r <= .55) {\r
- prouts("Sulu- \"Captain! Yagabandaghangrapl, brachriigringlanbla!\"");\r
- skip(1);\r
- prout("Lt. Uhura- \"Graaeek! Graaeek!\"");\r
- skip(1);\r
- prout("Spock- \"Facinating! . . . All humans aboard");\r
- prout(" have apparently been transformed into strange mutations.");\r
- prout(" Vulcans do not seem to be affected.");\r
- skip(1);\r
- prout("Kirk- \"Raauch! Raauch!\"");\r
- finish(FDRAY);\r
- return;\r
- }\r
- if (r <= 0.75) {\r
- int i,j;\r
- prouts("Sulu- \"Captain! It's --WHAT?!?!\"");\r
- skip(2);\r
- proutn("Spock- \"I believe the word is");\r
- prouts(" *ASTONISHING*");\r
- prout(" Mr. Sulu.");\r
- for (i=1; i<=10; i++)\r
- for (j=1; j<=10; j++)\r
- if (game.quad[i][j] == IHDOT) game.quad[i][j] = IHQUEST;\r
- prout(" Captain, our quadrant is now infested with");\r
- prouts(" - - - - - - *THINGS*.");\r
- skip(1);\r
- prout(" I have no logical explanation.\"");\r
- return;\r
- }\r
- prouts("Sulu- \"Captain! The Death Ray is creating tribbles!\"");\r
- skip(1);\r
- prout("Scotty- \"There are so many tribbles down here");\r
- prout(" in Engineering, we can't move for 'em, Captain.\"");\r
- finish(FTRIBBLE);\r
- return;\r
-}\r
+#include "sst.h"
+
+static int height;
+
+static char *classes[] = {"M","N","O"};
+
+static int consumeTime(void) {
+/* I think most of this avoidance was caused by overlay scheme.
+ Let's see what happens if all events can occur here */
+
+// double asave;
+ ididit = 1;
+#if 0
+ /* Don't wory about this */
+ if (future[FTBEAM] <= game.state.date+Time && game.state.remcom != 0 && condit != IHDOCKED) {
+ /* We are about to be tractor beamed -- operation fails */
+ return 1;
+ }
+#endif
+// asave = future[FSNOVA];
+// future[FSNOVA] = 1e30; /* defer supernovas */
+ events(); /* Used to avoid if future[FSCMOVE] within time */
+// future[FSNOVA] = asave;
+ /*fails if game over, quadrant super-novas or we've moved to new quadrant*/
+ if (alldone || game.state.galaxy[quadx][quady] == 1000 || justin != 0) return 1;
+ return 0;
+}
+
+void preport(void) {
+ int iknow = 0, i;
+ skip(1);
+ chew();
+ prout("Spock- \"Planet report follows, Captain.\"");
+ skip(1);
+ for (i = 0; i < inplan; i++) {
+ if (game.state.plnets[i].known != unknown
+#ifdef DEBUG
+ || ( idebug && game.state.plnets[i].x !=0)
+#endif
+ ) {
+ iknow = 1;
+#ifdef DEBUG
+ if (idebug && game.state.plnets[i].known==unknown) proutn("(Unknown) ");
+#endif
+ proutn(cramlc(quadrant, game.state.plnets[i].x, game.state.plnets[i].y));
+ proutn(" class ");
+ proutn(classes[game.state.plnets[i].pclass]);
+ proutn(" ");
+ if (game.state.plnets[i].crystals == 0) proutn("no ");
+ prout("dilithium crystals present.");
+ if (game.state.plnets[i].known==shuttle_down)
+ prout(" Shuttle Craft Galileo on surface.");
+ }
+ }
+ if (iknow==0) prout("No information available.");
+}
+
+void orbit(void) {
+ skip(1);
+ chew();
+ if (inorbit!=0) {
+ prout("Already in standard orbit.");
+ return;
+ }
+ if (game.damage[DWARPEN] != 0 && game.damage[DIMPULS] != 0) {
+ prout("Both warp and impulse engines damaged.");
+ return;
+ }
+ if (plnetx == 0 || abs(sectx-plnetx) > 1 || abs(secty-plnety) > 1) {
+ crmshp();
+ prout(" not adjacient to planet.\n");
+ return;
+ }
+ Time = 0.02+0.03*Rand();
+ prout("Helmsman Sulu- \"Entering standard orbit, Sir.\"");
+ newcnd();
+ if (consumeTime()) return;
+ height = (1400.+7200.*Rand());
+ prout("Sulu- \"Entered orbit at altitude %.2f kilometers.\"", height);
+ inorbit = 1;
+ return;
+}
+
+void sensor(void) {
+ skip(1);
+ chew();
+ if (game.damage[DSRSENS] != 0.0) {
+ prout("Short range sensors damaged.");
+ return;
+ }
+ if (plnetx == 0) {
+ prout("No planet in this quadrant.");
+ return;
+ }
+ prout("Spock- \"Sensor scan for %s-", cramlc(quadrant, quadx, quady));
+ skip(1);
+ prout(" Planet at %s is of class %s.",
+ cramlc(sector, plnetx, plnety),
+ classes[game.state.plnets[iplnet].pclass]);
+ if (game.state.plnets[iplnet].known==shuttle_down)
+ prout(" Sensors show Galileo still on surface.");
+ proutn(" Readings indicate");
+ if (game.state.plnets[iplnet].crystals == 0) proutn(" no");
+ prout(" dilithium crystals present.\"");
+ if (game.state.plnets[iplnet].known == unknown) game.state.plnets[iplnet].known = known;
+ return;
+}
+
+void beam(void) {
+ chew();
+ skip(1);
+ if (game.damage[DTRANSP] != 0) {
+ prout("Transporter damaged.");
+ if (game.damage[DSHUTTL]==0 && (game.state.plnets[iplnet].known==shuttle_down || iscraft == 1)) {
+ skip(1);
+ proutn("Spock- \"May I suggest the shuttle craft, Sir?\" ");
+ if (ja() != 0) shuttle();
+ }
+ return;
+ }
+ if (inorbit==0) {
+ crmshp();
+ prout(" not in standard orbit.");
+ return;
+ }
+ if (shldup!=0) {
+ prout("Impossible to transport through shields.");
+ return;
+ }
+ if (game.state.plnets[iplnet].known==unknown) {
+ prout("Spock- \"Captain, we have no information on this planet");
+ prout(" and Starfleet Regulations clearly state that in this situation");
+ prout(" you may not go down.\"");
+ return;
+ }
+ if (landed==1) {
+ /* Coming from planet */
+ if (game.state.plnets[iplnet].known==shuttle_down) {
+ proutn("Spock- \"Wouldn't you rather take the Galileo?\" ");
+ if (ja() != 0) {
+ chew();
+ return;
+ }
+ prout("Your crew hides the Galileo to prevent capture by aliens.");
+ }
+ prout("Landing party assembled, ready to beam up.");
+ skip(1);
+ prout("Kirk whips out communicator...");
+ prouts("BEEP BEEP BEEP");
+ skip(2);
+ prout("\"Kirk to enterprise- Lock on coordinates...energize.\"");
+ }
+ else {
+ /* Going to planet */
+ if (game.state.plnets[iplnet].crystals==0) {
+ prout("Spock- \"Captain, I fail to see the logic in");
+ prout(" exploring a planet with no dilithium crystals.");
+ proutn(" Are you sure this is wise?\" ");
+ if (ja()==0) {
+ chew();
+ return;
+ }
+ }
+ prout("Scotty- \"Transporter room ready, Sir.\"");
+ skip(1);
+ prout("Kirk, and landing party prepare to beam down to planet surface.");
+ skip(1);
+ prout("Kirk- \"Energize.\"");
+ }
+ skip(1);
+ prouts("WWHOOOIIIIIRRRRREEEE.E.E. . . . . . .");
+ skip(2);
+ if (Rand() > 0.98) {
+ prouts("BOOOIIIOOOIIOOOOIIIOIING . . .");
+ skip(2);
+ prout("Scotty- \"Oh my God! I've lost them.\"");
+ finish(FLOST);
+ return;
+ }
+ prouts(". . . . . . .E.E.EEEERRRRRIIIIIOOOHWW");
+ skip(2);
+ prout("Transport complete.");
+ landed = -landed;
+ if (landed==1 && game.state.plnets[iplnet].known==shuttle_down) {
+ prout("The shuttle craft Galileo is here!");
+ }
+ if (landed!=1 && imine==1) {
+ icrystl = 1;
+ cryprob = 0.05;
+ }
+ imine = 0;
+ return;
+}
+
+void mine(void) {
+
+ ididit = 0;
+ skip(1);
+ chew();
+ if (landed!= 1) {
+ prout("Mining party not on planet.");
+ return;
+ }
+ if (game.state.plnets[iplnet].crystals == 0) {
+ prout("No dilithium crystals on this planet.");
+ return;
+ }
+ if (imine == 1) {
+ prout("You've already mined enough crystals for this trip.");
+ return;
+ }
+ if (icrystl == 1 && cryprob == 0.05) {
+ proutn("With all those fresh crystals aboard the ");
+ crmshp();
+ skip(1);
+ prout("there's no reason to mine more at this time.");
+ return;
+ }
+ Time = (0.1+0.2*Rand())*game.state.plnets[iplnet].pclass;
+ if (consumeTime()) return;
+ prout("Mining operation complete.");
+ imine = 1;
+ return;
+}
+
+void usecrystals(void) {
+
+ skip(1);
+ chew();
+ if (icrystl!=1) {
+ prout("No dilithium crystals available.");
+ return;
+ }
+ if (energy >= 1000) {
+ prout("Spock- \"Captain, Starfleet Regulations prohibit such an operation");
+ prout(" except when condition Yellow exists.");
+ return;
+ }
+ prout("Spock- \"Captain, I must warn you that loading");
+ prout(" raw dilithium crystals into the ship's power");
+ prout(" system may risk a severe explosion.");
+ proutn(" Are you sure this is wise?\" ");
+ if (ja()==0) {
+ chew();
+ return;
+ }
+ skip(1);
+ prout("Engineering Officer Scott- \"(GULP) Aye Sir.");
+ prout(" Mr. Spock and I will try it.\"");
+ skip(1);
+ prout("Spock- \"Crystals in place, Sir.");
+ prout(" Ready to activate circuit.\"");
+ skip(1);
+ prouts("Scotty- \"Keep your fingers crossed, Sir!\"");
+ skip(1);
+ if (Rand() <= cryprob) {
+ prouts(" \"Activating now! - - No good! It's***");
+ skip(2);
+ prouts("***RED ALERT! RED A*L********************************");
+ skip(1);
+ stars();
+ prouts("****************** KA-BOOM!!!! *******************");
+ skip(1);
+ kaboom();
+ return;
+ }
+ energy += 5000.0*(1.0 + 0.9*Rand());
+ prouts(" \"Activating now! - - ");
+ prout("The instruments");
+ prout(" are going crazy, but I think it's");
+ prout(" going to work!! Congratulations, Sir!\"");
+ cryprob *= 2.0;
+ return;
+}
+
+void shuttle(void) {
+
+ chew();
+ skip(1);
+ ididit = 0;
+ if(game.damage[DSHUTTL] != 0.0) {
+ if (game.damage[DSHUTTL] == -1.0) {
+ if (inorbit && game.state.plnets[iplnet].known == shuttle_down)
+ prout("Ye Faerie Queene has no shuttle craft bay to dock it at.");
+ else
+ prout("Ye Faerie Queene had no shuttle craft.");
+ }
+ else if (game.damage[DSHUTTL] > 0)
+ prout("The Galileo is damaged.");
+ else prout("Shuttle craft is now serving Big Macs.");
+ return;
+ }
+ if (inorbit==0) {
+ crmshp();
+ prout(" not in standard orbit.");
+ return;
+ }
+ if ((game.state.plnets[iplnet].known != shuttle_down) && iscraft != 1) {
+ prout("Shuttle craft not currently available.");
+ return;
+ }
+ if (landed==-1 && game.state.plnets[iplnet].known==shuttle_down) {
+ prout("You will have to beam down to retrieve the shuttle craft.");
+ return;
+ }
+ if (shldup!=0 || condit == IHDOCKED) {
+ prout("Shuttle craft cannot pass through shields.");
+ return;
+ }
+ if (game.state.plnets[iplnet].known==unknown) {
+ prout("Spock- \"Captain, we have no information on this planet");
+ prout(" and Starfleet Regulations clearly state that in this situation");
+ prout(" you may not fly down.\"");
+ return;
+ }
+ Time = 3.0e-5*height;
+ if (Time >= 0.8*game.state.remtime) {
+ prout("First Officer Spock- \"Captain, I compute that such");
+ proutn(" a maneuver would require approximately 2d%% of our",
+ (int)(100*Time/game.state.remtime));
+ prout("remaining time.");
+ proutn("Are you sure this is wise?\" ");
+ if (ja()==0) {
+ Time = 0.0;
+ return;
+ }
+ }
+ if (landed == 1) {
+ /* Kirk on planet */
+ if (iscraft==1) {
+ /* Galileo on ship! */
+ if (game.damage[DTRANSP]==0) {
+ proutn("Spock- \"Would you rather use the transporter?\" ");
+ if (ja() != 0) {
+ beam();
+ return;
+ }
+ proutn("Shuttle crew");
+ }
+ else
+ proutn("Rescue party");
+ prout(" boards Galileo and swoops toward planet surface.");
+ iscraft = 0;
+ skip(1);
+ if (consumeTime()) return;
+ game.state.plnets[iplnet].known=shuttle_down;
+ prout("Trip complete.");
+ return;
+ }
+ else {
+ /* Ready to go back to ship */
+ prout("You and your mining party board the");
+ prout("shuttle craft for the trip back to the Enterprise.");
+ skip(1);
+ prout("The short hop begins . . .");
+ game.state.plnets[iplnet].known=known;
+ icraft = 1;
+ skip(1);
+ landed = -1;
+ if (consumeTime()) return;
+ iscraft = 1;
+ icraft = 0;
+ if (imine!=0) {
+ icrystl = 1;
+ cryprob = 0.05;
+ }
+ imine = 0;
+ prout("Trip complete.");
+ return;
+ }
+ }
+ else {
+ /* Kirk on ship */
+ /* and so is Galileo */
+ prout("Mining party assembles in the hangar deck,");
+ prout("ready to board the shuttle craft \"Galileo\".");
+ skip(1);
+ prouts("The hangar doors open; the trip begins.");
+ skip(1);
+ icraft = 1;
+ iscraft = 0;
+ if (consumeTime()) return;
+ game.state.plnets[iplnet].known = shuttle_down;
+ landed = 1;
+ icraft = 0;
+ prout("Trip complete");
+ return;
+ }
+}
+
+
+void deathray(void) {
+ double r = Rand();
+
+ ididit = 0;
+ skip(1);
+ chew();
+ if (ship != IHE) {
+ prout("Ye Faerie Queene has no death ray.");
+ return;
+ }
+ if (nenhere==0) {
+ prout("Sulu- \"But Sir, there are no enemies in this quadrant.\"");
+ return;
+ }
+ if (game.damage[DDRAY] > 0.0) {
+ prout("Death Ray is damaged.");
+ return;
+ }
+ prout("Spock- \"Captain, the 'Experimental Death Ray'");
+ prout(" is highly unpredictible. Considering the alternatives,");
+ proutn(" are you sure this is wise?\" ");
+ if (ja()==0) return;
+ prout("Spock- \"Acknowledged.\"");
+ skip(1);
+ ididit=1;
+ prouts("WHOOEE ... WHOOEE ... WHOOEE ... WHOOEE");
+ skip(1);
+ prout("Crew scrambles in emergency preparation.");
+ prout("Spock and Scotty ready the death ray and");
+ prout("prepare to channel all ship's power to the device.");
+ skip(1);
+ prout("Spock- \"Preparations complete, sir.\"");
+ prout("Kirk- \"Engage!\"");
+ skip(1);
+ prouts("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR");
+ skip(1);
+ if (r > .30) {
+ prouts("Sulu- \"Captain! It's working!\"");
+ skip(2);
+ while (nenhere > 0)
+ deadkl(game.kx[1],game.ky[1],game.quad[game.kx[1]][game.ky[1]],game.kx[1],game.ky[1]);
+ prout("Ensign Chekov- \"Congratulations, Captain!\"");
+ if (game.state.remkl == 0) finish(FWON);
+ prout("Spock- \"Captain, I believe the `Experimental Death Ray'");
+ if (Rand() <= 0.05) {
+ prout(" is still operational.\"");
+ }
+ else {
+ prout(" has been rendered nonfunctional.\"");
+ game.damage[DDRAY] = 39.95;
+ }
+ return;
+ }
+ r = Rand(); // Pick failure method
+ if (r <= .30) {
+ prouts("Sulu- \"Captain! It's working!\"");
+ skip(1);
+ prouts("***RED ALERT! RED ALERT!");
+ skip(1);
+ prout("***MATTER-ANTIMATTER IMPLOSION IMMINENT!");
+ skip(1);
+ prouts("***RED ALERT! RED A*L********************************");
+ skip(1);
+ stars();
+ prouts("****************** KA-BOOM!!!! *******************");
+ skip(1);
+ kaboom();
+ return;
+ }
+ if (r <= .55) {
+ prouts("Sulu- \"Captain! Yagabandaghangrapl, brachriigringlanbla!\"");
+ skip(1);
+ prout("Lt. Uhura- \"Graaeek! Graaeek!\"");
+ skip(1);
+ prout("Spock- \"Facinating! . . . All humans aboard");
+ prout(" have apparently been transformed into strange mutations.");
+ prout(" Vulcans do not seem to be affected.");
+ skip(1);
+ prout("Kirk- \"Raauch! Raauch!\"");
+ finish(FDRAY);
+ return;
+ }
+ if (r <= 0.75) {
+ int i,j;
+ prouts("Sulu- \"Captain! It's --WHAT?!?!\"");
+ skip(2);
+ proutn("Spock- \"I believe the word is");
+ prouts(" *ASTONISHING*");
+ prout(" Mr. Sulu.");
+ for (i=1; i<=10; i++)
+ for (j=1; j<=10; j++)
+ if (game.quad[i][j] == IHDOT) game.quad[i][j] = IHQUEST;
+ prout(" Captain, our quadrant is now infested with");
+ prouts(" - - - - - - *THINGS*.");
+ skip(1);
+ prout(" I have no logical explanation.\"");
+ return;
+ }
+ prouts("Sulu- \"Captain! The Death Ray is creating tribbles!\"");
+ skip(1);
+ prout("Scotty- \"There are so many tribbles down here");
+ prout(" in Engineering, we can't move for 'em, Captain.\"");
+ finish(FTRIBBLE);
+ return;
+}
-#include "sst.h"\r
-#include <math.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-void attakreport(int l) {\r
- if (!l) {\r
- if (game.future[FCDBAS] < 1e30) {\r
- prout("Starbase in %s is currently under Commander attack.",\r
- cramlc(quadrant, batx, baty));\r
- prout("It can hold out until Stardate %d.", \r
- (int)game.future[FCDBAS]);\r
- }\r
- if (isatb == 1) {\r
- prout("Starbase in %s is under Super-commander attack.",\r
- cramlc(quadrant, game.state.isx, game.state.isy));\r
- prout("It can hold out until Stardate %d.", \r
- (int)game.future[FSCDBAS]);\r
- }\r
- } else {\r
- if (game.future[FCDBAS] < 1e30)\r
- proutn("Base in %i - %i attacked by C. Alive until %.1f", batx, baty, game.future[FCDBAS]);\r
- if (isatb == 1)\r
- proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, game.future[FSCDBAS]);\r
- }\r
-}\r
- \r
-\r
-void report(int f) {\r
- char *s1,*s2,*s3;\r
-\r
- chew();\r
- s1 = (thawed?"thawed ":"");\r
- switch (length) {\r
- case 1: s2="short"; break;\r
- case 2: s2="medium"; break;\r
- case 4: s2="long"; break;\r
- default: s2="unknown length"; break;\r
- }\r
- switch (skill) {\r
- case 1: s3="novice"; break;\r
- case 2: s3="fair"; break;\r
- case 3: s3="good"; break;\r
- case 4: s3="expert"; break;\r
- case 5: s3="emeritus"; break;\r
- default: s3="skilled"; break;\r
- }\r
- prout("");\r
- prout("You %s playing a %s%s %s game.",\r
- alldone? "were": "are now", s1, s2, s3);\r
- if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");\r
- if (tourn) prout("This is tournament game %d.", tourn);\r
- if (f) prout("Your secret password is \"%s\"",game.passwd);\r
- proutn("%d of %d Klingons have been killed",\r
- game.state.killk+game.state.killc+game.state.nsckill, inkling);\r
- if (game.state.killc) prout(", including %d Commander%s.", game.state.killc, game.state.killc==1?"":"s");\r
- else if (game.state.killk+game.state.nsckill > 0) prout(", but no Commanders.");\r
- else prout(".");\r
- if (skill > 2) prout("The Super Commander has %sbeen destroyed.",\r
- game.state.nscrem?"not ":"");\r
- if (game.state.rembase != inbase) {\r
- proutn("There ");\r
- if (inbase-game.state.rembase==1) proutn("has been 1 base");\r
- else {\r
- proutn("have been %d bases", inbase-game.state.rembase);\r
- }\r
- prout(" destroyed, %d remaining.", game.state.rembase);\r
- }\r
- else prout("There are %d bases.", inbase);\r
- if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED || iseenit) {\r
- /* Don't report this if not seen and\r
- either the radio is dead or not at base! */\r
- attakreport(0);\r
- iseenit = 1;\r
- }\r
- if (casual) prout("%d casualt%s suffered so far.",\r
- casual, casual==1? "y" : "ies");\r
- if (nhelp) prout("There were %d call%s for help.",\r
- nhelp, nhelp==1 ? "" : "s");\r
- if (ship == IHE) {\r
- proutn("You have ");\r
- if (nprobes) proutn("%d", nprobes);\r
- else proutn("no");\r
- proutn(" deep space probe");\r
- if (nprobes!=1) proutn("s");\r
- prout(".");\r
- }\r
- if ((game.damage[DRADIO] == 0.0 || condit == IHDOCKED)&&\r
- game.future[FDSPROB] != 1e30) {\r
- if (isarmed) \r
- proutn("An armed deep space probe is in");\r
- else\r
- proutn("A deep space probe is in");\r
- proutn(cramlc(quadrant, probecx, probecy));\r
- prout(".");\r
- }\r
- if (icrystl) {\r
- if (cryprob <= .05)\r
- prout("Dilithium crystals aboard ship... not yet used.");\r
- else {\r
- int i=0;\r
- double ai = 0.05;\r
- while (cryprob > ai) {\r
- ai *= 2.0;\r
- i++;\r
- }\r
- prout("Dilithium crystals have been used %d time%s.",\r
- i, i==1? "" : "s");\r
- }\r
- }\r
- skip(1);\r
-}\r
- \r
-void lrscan(void) {\r
- int x, y;\r
- chew();\r
- if (game.damage[DLRSENS] != 0.0) {\r
- /* Now allow base's sensors if docked */\r
- if (condit != IHDOCKED) {\r
- prout("LONG-RANGE SENSORS DAMAGED.");\r
- return;\r
- }\r
- skip(1);\r
- proutn("Starbase's long-range scan for");\r
- }\r
- else {\r
- skip(1);\r
- proutn("Long-range scan for ");\r
- }\r
- prout(cramlc(quadrant, quadx, quady));\r
- for (x = quadx-1; x <= quadx+1; x++) {\r
- for (y = quady-1; y <= quady+1; y++) {\r
- if (x == 0 || x > 8 || y == 0 || y > 8)\r
- proutn(" -1");\r
- else {\r
- proutn("%5d", game.state.galaxy[x][y]);\r
- game.starch[x][y] = game.damage[DRADIO] > 0 ? game.state.galaxy[x][y]+1000 :1;\r
- }\r
- }\r
- skip(1);\r
- }\r
-\r
-}\r
-\r
-void dreprt(void) {\r
- int jdam = FALSE, i;\r
- chew();\r
-\r
- for (i = 1; i <= NDEVICES; i++) {\r
- if (game.damage[i] > 0.0) {\r
- if (!jdam) {\r
- skip(1);\r
- prout("DEVICE -REPAIR TIMES-");\r
- prout(" IN FLIGHT DOCKED");\r
- jdam = TRUE;\r
- }\r
- prout(" %16s %8.2f %8.2f", \r
- device[i],\r
- game.damage[i]+0.05,\r
- docfac*game.damage[i]+0.005);\r
- }\r
- }\r
- if (!jdam) prout("All devices functional.");\r
-}\r
-\r
-void chart(int nn) {\r
- int i,j;\r
-\r
- chew();\r
- skip(1);\r
- if (stdamtim != 1e30 && stdamtim != game.state.date && condit == IHDOCKED) {\r
- prout("Spock- \"I revised the Star Chart from the");\r
- prout(" starbase's records.\"");\r
- skip(1);\r
- }\r
- if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY");\r
- if (stdamtim != 1e30) {\r
- if (condit == IHDOCKED) {\r
- /* We are docked, so restore chart from base information */\r
- stdamtim = game.state.date;\r
- for (i=1; i <= 8 ; i++)\r
- for (j=1; j <= 8; j++)\r
- if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;\r
- }\r
- else {\r
- proutn("(Last surveillance update %d stardates ago.",\r
- (int)(game.state.date-stdamtim));\r
- }\r
- }\r
- if (nn ==0) skip(1);\r
-\r
- prout(" 1 2 3 4 5 6 7 8");\r
- prout(" ----------------------------------------");\r
- /* if (nn==0) prout(" -"); */\r
- for (i = 1; i <= 8; i++) {\r
- proutn("%d -", i);\r
- for (j = 1; j <= 8; j++) {\r
- if (game.starch[i][j] < 0)\r
- proutn(" .1.");\r
- else if (game.starch[i][j] == 0)\r
- proutn(" ...");\r
- else if (game.starch[i][j] > 999)\r
- proutn("%5d", game.starch[i][j]-1000);\r
- else\r
- proutn("%5d", game.state.galaxy[i][j]);\r
- }\r
- prout(" -");\r
- }\r
- if (nn == 0) {\r
- skip(1);\r
- crmshp();\r
- prout(" is currently in %s", cramlc(quadrant, quadx, quady));\r
-}\r
-}\r
- \r
- \r
-void srscan(int l) {\r
- static char requests[][3] =\r
- {"","da","co","po","ls","wa","en","to","sh","kl","ti"};\r
- char *cp = NULL;\r
- int leftside=TRUE, rightside=TRUE, i, j, k=0, nn=FALSE;\r
- int goodScan=TRUE;\r
- switch (l) {\r
- case 1: // SRSCAN\r
- if (game.damage[DSRSENS] != 0) {\r
- /* Allow base's sensors if docked */\r
- if (condit != IHDOCKED) {\r
- prout("SHORT-RANGE SENSORS DAMAGED");\r
- goodScan=FALSE;\r
- }\r
- else\r
- prout("[Using starbase's sensors]");\r
- }\r
- if (goodScan)\r
- game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ?\r
- game.state.galaxy[quadx][quady]+1000:1;\r
- scan();\r
- if (isit("chart")) nn = TRUE;\r
- if (isit("no")) rightside = FALSE;\r
- chew();\r
- prout("\n 1 2 3 4 5 6 7 8 9 10");\r
- break;\r
- case 2: // REQUEST\r
- while (scan() == IHEOL)\r
- proutn("Information desired? ");\r
- chew();\r
- for (k = 1; k <= 10; k++)\r
- if (strncmp(citem,requests[k],min(2,strlen(citem)))==0)\r
- break;\r
- if (k > 10) {\r
- prout("UNRECOGNIZED REQUEST. Legal requests are:\n"\r
- " date, condition, position, lsupport, warpfactor,\n"\r
- " energy, torpedoes, shields, klingons, time.");\r
- return;\r
- }\r
- // no "break"\r
- case 3: // STATUS\r
- chew();\r
- leftside = FALSE;\r
- skip(1);\r
- }\r
- for (i = 1; i <= 10; i++) {\r
- int jj = (k!=0 ? k : i);\r
- if (leftside) {\r
- proutn("%2d ", i);\r
- for (j = 1; j <= 10; j++) {\r
- if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1))\r
- proutn("%c ",game.quad[i][j]);\r
- else\r
- proutn("- ");\r
- }\r
- }\r
- if (rightside) {\r
- switch (jj) {\r
- case 1:\r
- proutn(" Stardate %.1f", game.state.date);\r
- break;\r
- case 2:\r
- if (condit != IHDOCKED) newcnd();\r
- switch (condit) {\r
- case IHRED: cp = "RED"; break;\r
- case IHGREEN: cp = "GREEN"; break;\r
- case IHYELLOW: cp = "YELLOW"; break;\r
- case IHDOCKED: cp = "DOCKED"; break;\r
- }\r
- proutn(" Condition %s", cp);\r
- break;\r
- case 3:\r
- proutn(" Position ");\r
- proutn(cramlc(neither, quadx, quady));\r
- proutn(" , ");\r
- proutn(cramlc(neither, sectx, secty));\r
- break;\r
- case 4:\r
- proutn(" Life Support ");\r
- if (game.damage[DLIFSUP] != 0.0) {\r
- if (condit == IHDOCKED)\r
- proutn("DAMAGED, supported by starbase");\r
- else\r
- proutn("DAMAGED, reserves=%.2f", lsupres);\r
- }\r
- else\r
- proutn("ACTIVE");\r
- break;\r
- case 5:\r
- proutn(" Warp Factor %.1f", warpfac);\r
- break;\r
- case 6:\r
- proutn(" Energy %.2f", energy);\r
- break;\r
- case 7:\r
- proutn(" Torpedoes %d", torps);\r
- break;\r
- case 8:\r
- proutn(" Shields ");\r
- if (game.damage[DSHIELD] != 0)\r
- proutn("DAMAGED,");\r
- else if (shldup)\r
- proutn("UP,");\r
- else\r
- proutn("DOWN,");\r
- proutn(" %d%% %.1f units",\r
- (int)((100.0*shield)/inshld + 0.5), shield);\r
- break;\r
- case 9:\r
- proutn(" Klingons Left %d", game.state.remkl);\r
- break;\r
- case 10:\r
- attakreport(1);\r
- break;\r
- }\r
- \r
- }\r
- skip(1);\r
- if (k!=0) return;\r
- }\r
- if (nn) chart(1);\r
-}\r
- \r
- \r
-void eta(void) {\r
- int ix1, ix2, iy1, iy2, prompt=FALSE;\r
- int wfl;\r
- double ttime, twarp, tpower;\r
- if (game.damage[DCOMPTR] != 0.0) {\r
- prout("COMPUTER DAMAGED, USE A POCKET CALCULATOR.");\r
- skip(1);\r
- return;\r
- }\r
- if (scan() != IHREAL) {\r
- prompt = TRUE;\r
- chew();\r
- proutn("Destination quadrant and/or sector? ");\r
- if (scan()!=IHREAL) {\r
- huh();\r
- return;\r
- }\r
- }\r
- iy1 = aaitem +0.5;\r
- if (scan() != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- ix1 = aaitem + 0.5;\r
- if (scan() == IHREAL) {\r
- iy2 = aaitem + 0.5;\r
- if (scan() != IHREAL) {\r
- huh();\r
- return;\r
- }\r
- ix2 = aaitem + 0.5;\r
- }\r
- else {\r
- if (quady>ix1) ix2 = 1;\r
- else ix2=10;\r
- if (quadx>iy1) iy2 = 1;\r
- else iy2=10;\r
- }\r
-\r
- if (ix1 > 8 || ix1 < 1 || iy1 > 8 || iy1 < 1 ||\r
- ix2 > 10 || ix2 < 1 || iy2 > 10 || iy2 < 1) {\r
- huh();\r
- return;\r
- }\r
- dist = sqrt(square(iy1-quadx+0.1*(iy2-sectx))+\r
- square(ix1-quady+0.1*(ix2-secty)));\r
- wfl = FALSE;\r
-\r
- if (prompt) prout("Answer \"no\" if you don't know the value:");\r
- while (TRUE) {\r
- chew();\r
- proutn("Time or arrival date? ");\r
- if (scan()==IHREAL) {\r
- ttime = aaitem;\r
- if (ttime > game.state.date) ttime -= game.state.date; // Actually a star date\r
- if (ttime <= 1e-10 ||\r
- (twarp=(floor(sqrt((10.0*dist)/ttime)*10.0)+1.0)/10.0) > 10) {\r
- prout("We'll never make it, sir.");\r
- chew();\r
- return;\r
- }\r
- if (twarp < 1.0) twarp = 1.0;\r
- break;\r
- }\r
- chew();\r
- proutn("Warp factor? ");\r
- if (scan()== IHREAL) {\r
- wfl = TRUE;\r
- twarp = aaitem;\r
- if (twarp<1.0 || twarp > 10.0) {\r
- huh();\r
- return;\r
- }\r
- break;\r
- }\r
- prout("Captain, certainly you can give me one of these.");\r
- }\r
- while (TRUE) {\r
- chew();\r
- ttime = (10.0*dist)/square(twarp);\r
- tpower = dist*twarp*twarp*twarp*(shldup+1);\r
- if (tpower >= energy) {\r
- prout("Insufficient energy, sir.");\r
- if (shldup==0 || tpower > energy*2.0) {\r
- if (!wfl) return;\r
- proutn("New warp factor to try? ");\r
- if (scan() == IHREAL) {\r
- wfl = TRUE;\r
- twarp = aaitem;\r
- if (twarp<1.0 || twarp > 10.0) {\r
- huh();\r
- return;\r
- }\r
- continue;\r
- }\r
- else {\r
- chew();\r
- skip(1);\r
- return;\r
- }\r
- }\r
- prout("But if you lower your shields,");\r
- proutn("remaining");\r
- tpower /= 2;\r
- }\r
- else\r
- proutn("Remaining");\r
- prout(" energy will be %.2f.", energy-tpower);\r
- if (wfl) {\r
- prout("And we will arrive at stardate %.2f.",\r
- game.state.date+ttime);\r
- }\r
- else if (twarp==1.0)\r
- prout("Any warp speed is adequate.");\r
- else {\r
- prout("Minimum warp needed is %.2f,", twarp);\r
- prout("and we will arrive at stardate %.2f.",\r
- game.state.date+ttime);\r
- }\r
- if (game.state.remtime < ttime)\r
- prout("Unfortunately, the Federation will be destroyed by then.");\r
- if (twarp > 6.0)\r
- prout("You'll be taking risks at that speed, Captain");\r
- if ((isatb==1 && game.state.isy == ix1 && game.state.isx == iy1 &&\r
- game.future[FSCDBAS]< ttime+game.state.date)||\r
- (game.future[FCDBAS]<ttime+game.state.date && baty==ix1 && batx == iy1))\r
- prout("The starbase there will be destroyed by then.");\r
- proutn("New warp factor to try? ");\r
- if (scan() == IHREAL) {\r
- wfl = TRUE;\r
- twarp = aaitem;\r
- if (twarp<1.0 || twarp > 10.0) {\r
- huh();\r
- return;\r
- }\r
- }\r
- else {\r
- chew();\r
- skip(1);\r
- return;\r
- }\r
- }\r
- \r
-}\r
+#include "sst.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+void attakreport(int l) {
+ if (!l) {
+ if (game.future[FCDBAS] < 1e30) {
+ prout("Starbase in %s is currently under Commander attack.",
+ cramlc(quadrant, batx, baty));
+ prout("It can hold out until Stardate %d.",
+ (int)game.future[FCDBAS]);
+ }
+ if (isatb == 1) {
+ prout("Starbase in %s is under Super-commander attack.",
+ cramlc(quadrant, game.state.isx, game.state.isy));
+ prout("It can hold out until Stardate %d.",
+ (int)game.future[FSCDBAS]);
+ }
+ } else {
+ if (game.future[FCDBAS] < 1e30)
+ proutn("Base in %i - %i attacked by C. Alive until %.1f", batx, baty, game.future[FCDBAS]);
+ if (isatb == 1)
+ proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, game.future[FSCDBAS]);
+ }
+}
+
+
+void report(int f) {
+ char *s1,*s2,*s3;
+
+ chew();
+ s1 = (thawed?"thawed ":"");
+ switch (length) {
+ case 1: s2="short"; break;
+ case 2: s2="medium"; break;
+ case 4: s2="long"; break;
+ default: s2="unknown length"; break;
+ }
+ switch (skill) {
+ case 1: s3="novice"; break;
+ case 2: s3="fair"; break;
+ case 3: s3="good"; break;
+ case 4: s3="expert"; break;
+ case 5: s3="emeritus"; break;
+ default: s3="skilled"; break;
+ }
+ prout("");
+ prout("You %s playing a %s%s %s game.",
+ alldone? "were": "are now", s1, s2, s3);
+ if (skill>3 && thawed && !alldone) prout("No plaque is allowed.");
+ if (tourn) prout("This is tournament game %d.", tourn);
+ if (f) prout("Your secret password is \"%s\"",game.passwd);
+ proutn("%d of %d Klingons have been killed",
+ game.state.killk+game.state.killc+game.state.nsckill, inkling);
+ if (game.state.killc) prout(", including %d Commander%s.", game.state.killc, game.state.killc==1?"":"s");
+ else if (game.state.killk+game.state.nsckill > 0) prout(", but no Commanders.");
+ else prout(".");
+ if (skill > 2) prout("The Super Commander has %sbeen destroyed.",
+ game.state.nscrem?"not ":"");
+ if (game.state.rembase != inbase) {
+ proutn("There ");
+ if (inbase-game.state.rembase==1) proutn("has been 1 base");
+ else {
+ proutn("have been %d bases", inbase-game.state.rembase);
+ }
+ prout(" destroyed, %d remaining.", game.state.rembase);
+ }
+ else prout("There are %d bases.", inbase);
+ if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED || iseenit) {
+ /* Don't report this if not seen and
+ either the radio is dead or not at base! */
+ attakreport(0);
+ iseenit = 1;
+ }
+ if (casual) prout("%d casualt%s suffered so far.",
+ casual, casual==1? "y" : "ies");
+ if (nhelp) prout("There were %d call%s for help.",
+ nhelp, nhelp==1 ? "" : "s");
+ if (ship == IHE) {
+ proutn("You have ");
+ if (nprobes) proutn("%d", nprobes);
+ else proutn("no");
+ proutn(" deep space probe");
+ if (nprobes!=1) proutn("s");
+ prout(".");
+ }
+ if ((game.damage[DRADIO] == 0.0 || condit == IHDOCKED)&&
+ game.future[FDSPROB] != 1e30) {
+ if (isarmed)
+ proutn("An armed deep space probe is in");
+ else
+ proutn("A deep space probe is in");
+ proutn(cramlc(quadrant, probecx, probecy));
+ prout(".");
+ }
+ if (icrystl) {
+ if (cryprob <= .05)
+ prout("Dilithium crystals aboard ship... not yet used.");
+ else {
+ int i=0;
+ double ai = 0.05;
+ while (cryprob > ai) {
+ ai *= 2.0;
+ i++;
+ }
+ prout("Dilithium crystals have been used %d time%s.",
+ i, i==1? "" : "s");
+ }
+ }
+ skip(1);
+}
+
+void lrscan(void) {
+ int x, y;
+ chew();
+ if (game.damage[DLRSENS] != 0.0) {
+ /* Now allow base's sensors if docked */
+ if (condit != IHDOCKED) {
+ prout("LONG-RANGE SENSORS DAMAGED.");
+ return;
+ }
+ skip(1);
+ proutn("Starbase's long-range scan for");
+ }
+ else {
+ skip(1);
+ proutn("Long-range scan for ");
+ }
+ prout(cramlc(quadrant, quadx, quady));
+ for (x = quadx-1; x <= quadx+1; x++) {
+ for (y = quady-1; y <= quady+1; y++) {
+ if (x == 0 || x > 8 || y == 0 || y > 8)
+ proutn(" -1");
+ else {
+ proutn("%5d", game.state.galaxy[x][y]);
+ game.starch[x][y] = game.damage[DRADIO] > 0 ? game.state.galaxy[x][y]+1000 :1;
+ }
+ }
+ skip(1);
+ }
+
+}
+
+void dreprt(void) {
+ int jdam = FALSE, i;
+ chew();
+
+ for (i = 1; i <= NDEVICES; i++) {
+ if (game.damage[i] > 0.0) {
+ if (!jdam) {
+ skip(1);
+ prout("DEVICE -REPAIR TIMES-");
+ prout(" IN FLIGHT DOCKED");
+ jdam = TRUE;
+ }
+ prout(" %16s %8.2f %8.2f",
+ device[i],
+ game.damage[i]+0.05,
+ docfac*game.damage[i]+0.005);
+ }
+ }
+ if (!jdam) prout("All devices functional.");
+}
+
+void chart(int nn) {
+ int i,j;
+
+ chew();
+ skip(1);
+ if (stdamtim != 1e30 && stdamtim != game.state.date && condit == IHDOCKED) {
+ prout("Spock- \"I revised the Star Chart from the");
+ prout(" starbase's records.\"");
+ skip(1);
+ }
+ if (nn == 0) prout("STAR CHART FOR THE KNOWN GALAXY");
+ if (stdamtim != 1e30) {
+ if (condit == IHDOCKED) {
+ /* We are docked, so restore chart from base information */
+ stdamtim = game.state.date;
+ for (i=1; i <= 8 ; i++)
+ for (j=1; j <= 8; j++)
+ if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+1000;
+ }
+ else {
+ proutn("(Last surveillance update %d stardates ago.",
+ (int)(game.state.date-stdamtim));
+ }
+ }
+ if (nn ==0) skip(1);
+
+ prout(" 1 2 3 4 5 6 7 8");
+ prout(" ----------------------------------------");
+ /* if (nn==0) prout(" -"); */
+ for (i = 1; i <= 8; i++) {
+ proutn("%d -", i);
+ for (j = 1; j <= 8; j++) {
+ if (game.starch[i][j] < 0)
+ proutn(" .1.");
+ else if (game.starch[i][j] == 0)
+ proutn(" ...");
+ else if (game.starch[i][j] > 999)
+ proutn("%5d", game.starch[i][j]-1000);
+ else
+ proutn("%5d", game.state.galaxy[i][j]);
+ }
+ prout(" -");
+ }
+ if (nn == 0) {
+ skip(1);
+ crmshp();
+ prout(" is currently in %s", cramlc(quadrant, quadx, quady));
+}
+}
+
+
+void srscan(int l) {
+ static char requests[][3] =
+ {"","da","co","po","ls","wa","en","to","sh","kl","ti"};
+ char *cp = NULL;
+ int leftside=TRUE, rightside=TRUE, i, j, k=0, nn=FALSE;
+ int goodScan=TRUE;
+ switch (l) {
+ case 1: // SRSCAN
+ if (game.damage[DSRSENS] != 0) {
+ /* Allow base's sensors if docked */
+ if (condit != IHDOCKED) {
+ prout("SHORT-RANGE SENSORS DAMAGED");
+ goodScan=FALSE;
+ }
+ else
+ prout("[Using starbase's sensors]");
+ }
+ if (goodScan)
+ game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ?
+ game.state.galaxy[quadx][quady]+1000:1;
+ scan();
+ if (isit("chart")) nn = TRUE;
+ if (isit("no")) rightside = FALSE;
+ chew();
+ prout("\n 1 2 3 4 5 6 7 8 9 10");
+ break;
+ case 2: // REQUEST
+ while (scan() == IHEOL)
+ proutn("Information desired? ");
+ chew();
+ for (k = 1; k <= 10; k++)
+ if (strncmp(citem,requests[k],min(2,strlen(citem)))==0)
+ break;
+ if (k > 10) {
+ prout("UNRECOGNIZED REQUEST. Legal requests are:\n"
+ " date, condition, position, lsupport, warpfactor,\n"
+ " energy, torpedoes, shields, klingons, time.");
+ return;
+ }
+ // no "break"
+ case 3: // STATUS
+ chew();
+ leftside = FALSE;
+ skip(1);
+ }
+ for (i = 1; i <= 10; i++) {
+ int jj = (k!=0 ? k : i);
+ if (leftside) {
+ proutn("%2d ", i);
+ for (j = 1; j <= 10; j++) {
+ if (goodScan || (abs(i-sectx)<= 1 && abs(j-secty) <= 1))
+ proutn("%c ",game.quad[i][j]);
+ else
+ proutn("- ");
+ }
+ }
+ if (rightside) {
+ switch (jj) {
+ case 1:
+ proutn(" Stardate %.1f", game.state.date);
+ break;
+ case 2:
+ if (condit != IHDOCKED) newcnd();
+ switch (condit) {
+ case IHRED: cp = "RED"; break;
+ case IHGREEN: cp = "GREEN"; break;
+ case IHYELLOW: cp = "YELLOW"; break;
+ case IHDOCKED: cp = "DOCKED"; break;
+ }
+ proutn(" Condition %s", cp);
+ break;
+ case 3:
+ proutn(" Position ");
+ proutn(cramlc(neither, quadx, quady));
+ proutn(" , ");
+ proutn(cramlc(neither, sectx, secty));
+ break;
+ case 4:
+ proutn(" Life Support ");
+ if (game.damage[DLIFSUP] != 0.0) {
+ if (condit == IHDOCKED)
+ proutn("DAMAGED, supported by starbase");
+ else
+ proutn("DAMAGED, reserves=%.2f", lsupres);
+ }
+ else
+ proutn("ACTIVE");
+ break;
+ case 5:
+ proutn(" Warp Factor %.1f", warpfac);
+ break;
+ case 6:
+ proutn(" Energy %.2f", energy);
+ break;
+ case 7:
+ proutn(" Torpedoes %d", torps);
+ break;
+ case 8:
+ proutn(" Shields ");
+ if (game.damage[DSHIELD] != 0)
+ proutn("DAMAGED,");
+ else if (shldup)
+ proutn("UP,");
+ else
+ proutn("DOWN,");
+ proutn(" %d%% %.1f units",
+ (int)((100.0*shield)/inshld + 0.5), shield);
+ break;
+ case 9:
+ proutn(" Klingons Left %d", game.state.remkl);
+ break;
+ case 10:
+ attakreport(1);
+ break;
+ }
+
+ }
+ skip(1);
+ if (k!=0) return;
+ }
+ if (nn) chart(1);
+}
+
+
+void eta(void) {
+ int ix1, ix2, iy1, iy2, prompt=FALSE;
+ int wfl;
+ double ttime, twarp, tpower;
+ if (game.damage[DCOMPTR] != 0.0) {
+ prout("COMPUTER DAMAGED, USE A POCKET CALCULATOR.");
+ skip(1);
+ return;
+ }
+ if (scan() != IHREAL) {
+ prompt = TRUE;
+ chew();
+ proutn("Destination quadrant and/or sector? ");
+ if (scan()!=IHREAL) {
+ huh();
+ return;
+ }
+ }
+ iy1 = aaitem +0.5;
+ if (scan() != IHREAL) {
+ huh();
+ return;
+ }
+ ix1 = aaitem + 0.5;
+ if (scan() == IHREAL) {
+ iy2 = aaitem + 0.5;
+ if (scan() != IHREAL) {
+ huh();
+ return;
+ }
+ ix2 = aaitem + 0.5;
+ }
+ else {
+ if (quady>ix1) ix2 = 1;
+ else ix2=10;
+ if (quadx>iy1) iy2 = 1;
+ else iy2=10;
+ }
+
+ if (ix1 > 8 || ix1 < 1 || iy1 > 8 || iy1 < 1 ||
+ ix2 > 10 || ix2 < 1 || iy2 > 10 || iy2 < 1) {
+ huh();
+ return;
+ }
+ dist = sqrt(square(iy1-quadx+0.1*(iy2-sectx))+
+ square(ix1-quady+0.1*(ix2-secty)));
+ wfl = FALSE;
+
+ if (prompt) prout("Answer \"no\" if you don't know the value:");
+ while (TRUE) {
+ chew();
+ proutn("Time or arrival date? ");
+ if (scan()==IHREAL) {
+ ttime = aaitem;
+ if (ttime > game.state.date) ttime -= game.state.date; // Actually a star date
+ if (ttime <= 1e-10 ||
+ (twarp=(floor(sqrt((10.0*dist)/ttime)*10.0)+1.0)/10.0) > 10) {
+ prout("We'll never make it, sir.");
+ chew();
+ return;
+ }
+ if (twarp < 1.0) twarp = 1.0;
+ break;
+ }
+ chew();
+ proutn("Warp factor? ");
+ if (scan()== IHREAL) {
+ wfl = TRUE;
+ twarp = aaitem;
+ if (twarp<1.0 || twarp > 10.0) {
+ huh();
+ return;
+ }
+ break;
+ }
+ prout("Captain, certainly you can give me one of these.");
+ }
+ while (TRUE) {
+ chew();
+ ttime = (10.0*dist)/square(twarp);
+ tpower = dist*twarp*twarp*twarp*(shldup+1);
+ if (tpower >= energy) {
+ prout("Insufficient energy, sir.");
+ if (shldup==0 || tpower > energy*2.0) {
+ if (!wfl) return;
+ proutn("New warp factor to try? ");
+ if (scan() == IHREAL) {
+ wfl = TRUE;
+ twarp = aaitem;
+ if (twarp<1.0 || twarp > 10.0) {
+ huh();
+ return;
+ }
+ continue;
+ }
+ else {
+ chew();
+ skip(1);
+ return;
+ }
+ }
+ prout("But if you lower your shields,");
+ proutn("remaining");
+ tpower /= 2;
+ }
+ else
+ proutn("Remaining");
+ prout(" energy will be %.2f.", energy-tpower);
+ if (wfl) {
+ prout("And we will arrive at stardate %.2f.",
+ game.state.date+ttime);
+ }
+ else if (twarp==1.0)
+ prout("Any warp speed is adequate.");
+ else {
+ prout("Minimum warp needed is %.2f,", twarp);
+ prout("and we will arrive at stardate %.2f.",
+ game.state.date+ttime);
+ }
+ if (game.state.remtime < ttime)
+ prout("Unfortunately, the Federation will be destroyed by then.");
+ if (twarp > 6.0)
+ prout("You'll be taking risks at that speed, Captain");
+ if ((isatb==1 && game.state.isy == ix1 && game.state.isx == iy1 &&
+ game.future[FSCDBAS]< ttime+game.state.date)||
+ (game.future[FCDBAS]<ttime+game.state.date && baty==ix1 && batx == iy1))
+ prout("The starbase there will be destroyed by then.");
+ proutn("New warp factor to try? ");
+ if (scan() == IHREAL) {
+ wfl = TRUE;
+ twarp = aaitem;
+ if (twarp<1.0 || twarp > 10.0) {
+ huh();
+ return;
+ }
+ }
+ else {
+ chew();
+ skip(1);
+ return;
+ }
+ }
+
+}
-#include <time.h>\r
-#ifdef SERGEEV\r
-#include <sys/stat.h>\r
-#include <conio.h>\r
-#endif /* SERGEEV */\r
-#include "sst.h"\r
-\r
-#ifdef SERGEEV\r
-#ifdef __linux__\r
-static long filelength(int fd) {\r
-struct stat buf;\r
- fstat(fd, &buf);\r
- return buf.st_size;\r
-}\r
-#endif\r
-#endif /* SERGEEV */\r
-\r
-void prelim(void) {\r
- skip(2);\r
- prout("-SUPER- STAR TREK");\r
- skip(1);\r
-#ifndef SERGEEV\r
- prout("Latest update-21 Sept 78");\r
- skip(1);\r
-#endif /* SERGEEV */\r
-}\r
-\r
-void freeze(int boss) {\r
- FILE *fp;\r
- int key;\r
- if (boss) {\r
- strcpy(citem, "emsave.trk");\r
- }\r
- else {\r
- if ((key = scan()) == IHEOL) {\r
- proutn("File name: ");\r
- key = scan();\r
- }\r
- if (key != IHALPHA) {\r
- huh();\r
- return;\r
- }\r
- chew();\r
- if (strchr(citem, '.') == NULL) {\r
- strcat(citem, ".trk");\r
- }\r
- }\r
- if ((fp = fopen(citem, "wb")) == NULL) {\r
- proutn("Can't freeze game as file ");\r
- proutn(citem);\r
- skip(1);\r
- return;\r
- }\r
- strcpy(game.magic, SSTMAGIC);\r
- fwrite(&game, sizeof(game), 1, fp);\r
-\r
- fclose(fp);\r
-\r
- /* I hope that's enough! */\r
-}\r
-\r
-\r
-int thaw(void) {\r
- FILE *fp;\r
- int key;\r
-\r
- game.passwd[0] = '\0';\r
- if ((key = scan()) == IHEOL) {\r
- proutn("File name: ");\r
- key = scan();\r
- }\r
- if (key != IHALPHA) {\r
- huh();\r
- return 1;\r
- }\r
- chew();\r
- if (strchr(citem, '.') == NULL) {\r
- strcat(citem, ".trk");\r
- }\r
- if ((fp = fopen(citem, "rb")) == NULL) {\r
- proutn("Can't find game file ");\r
- proutn(citem);\r
- skip(1);\r
- return 1;\r
- }\r
- fread(&game, sizeof(game), 1, fp);\r
- if (strcmp(game.magic, SSTMAGIC)) {\r
- prout("Game file format is bad, should begin with " SSTMAGIC);\r
- skip(1);\r
- fclose(fp);\r
- return 1;\r
- }\r
-\r
- fclose(fp);\r
-\r
- return 0;\r
-}\r
-\r
-void abandn(void) {\r
- int nb, l;\r
-\r
- chew();\r
- if (condit==IHDOCKED) {\r
- if (ship!=IHE) {\r
- prout("You cannot abandon Ye Faerie Queene.");\r
- return;\r
- }\r
- }\r
- else {\r
- /* Must take shuttle craft to exit */\r
- if (game.damage[DSHUTTL]==-1) {\r
- prout("Ye Faerie Queene has no shuttle craft.");\r
- return;\r
- }\r
- if (game.damage[DSHUTTL]<0) {\r
- prout("Shuttle craft now serving Big Mac's.");\r
- return;\r
- }\r
- if (game.damage[DSHUTTL]>0) {\r
- prout("Shuttle craft damaged.");\r
- return;\r
- }\r
- if (landed==1) {\r
- prout("You must be aboard the Enterprise.");\r
- return;\r
- }\r
- if (iscraft!=1) {\r
- prout("Shuttle craft not currently available.");\r
- return;\r
- }\r
- /* Print abandon ship messages */\r
- skip(1);\r
- prouts("***ABANDON SHIP! ABANDON SHIP!");\r
- skip(1);\r
- prouts("***ALL HANDS ABANDON SHIP!");\r
- skip(2);\r
- prout("Captain and crew escape in shuttle craft.");\r
- prout("Remainder of ship's complement beam down");\r
- prout("to nearest habitable planet.");\r
- if (game.state.rembase==0) {\r
- /* Ops! no place to go... */\r
- finish(FABANDN);\r
- return;\r
- }\r
- /* If at least one base left, give 'em the Faerie Queene */\r
- skip(1);\r
- icrystl = 0; /* crystals are lost */\r
- nprobes = 0; /* No probes */\r
- prout("You are captured by Klingons and released to");\r
- prout("the Federation in a prisoner-of-war exchange.");\r
- nb = Rand()*game.state.rembase+1;\r
- /* Set up quadrant and position FQ adjacient to base */\r
- if (quadx!=game.state.baseqx[nb] || quady!=game.state.baseqy[nb]) {\r
- quadx = game.state.baseqx[nb];\r
- quady = game.state.baseqy[nb];\r
- sectx = secty = 5;\r
- newqad(1);\r
- }\r
- for (;;) {\r
- /* position next to base by trial and error */\r
- game.quad[sectx][secty] = IHDOT;\r
- for (l = 1; l <= 10; l++) {\r
- sectx = 3.0*Rand() - 1.0 + basex;\r
- secty = 3.0*Rand() - 1.0 + basey;\r
- if (sectx >= 1 && sectx <= 10 &&\r
- secty >= 1 && secty <= 10 &&\r
- game.quad[sectx][secty] == IHDOT) break;\r
- }\r
- if (l < 11) break; /* found a spot */\r
- sectx=5;\r
- secty=5;\r
- newqad(1);\r
- }\r
- }\r
- /* Get new commission */\r
- game.quad[sectx][secty] = ship = IHF;\r
- prout("Starfleet puts you in command of another ship,");\r
- prout("the Faerie Queene, which is antiquated but,");\r
- prout("still useable.");\r
- if (icrystl!=0) prout("The dilithium crystals have been moved.");\r
- imine=0;\r
- iscraft=0; /* Gallileo disappears */\r
- /* Resupply ship */\r
- condit=IHDOCKED;\r
- for (l = 1; l <= NDEVICES; l++) game.damage[l] = 0.0;\r
- game.damage[DSHUTTL] = -1;\r
- energy = inenrg = 3000.0;\r
- shield = inshld = 1250.0;\r
- torps = intorps = 6;\r
- lsupres=inlsr=3.0;\r
- shldup=0;\r
- warpfac=5.0;\r
- wfacsq=25.0;\r
- return;\r
-}\r
- \r
-void setup(int needprompt) {\r
- int i,j, krem, klumper;\r
- int ix, iy;\r
-#ifdef DEBUG\r
- idebug = 0;\r
-#endif\r
- // Decide how many of everything\r
- if (choose(needprompt)) return; // frozen game\r
- // Prepare the Enterprise\r
- alldone = gamewon = 0;\r
- ship = IHE;\r
- energy = inenrg = 5000.0;\r
- shield = inshld = 2500.0;\r
- shldchg = shldup = 0;\r
- inlsr = 4.0;\r
- lsupres = 4.0;\r
- iran8(&quadx, &quady);\r
- iran10(§x, §y);\r
- torps = intorps = 10;\r
- nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */\r
- warpfac = 5.0;\r
- wfacsq = warpfac * warpfac;\r
- for (i=0; i <= NDEVICES; i++) game.damage[i] = 0.0;\r
- // Set up assorted game parameters\r
- batx = baty = 0;\r
- game.state.date = indate = 100.0*(int)(31.0*Rand()+20.0);\r
- game.state.killk = game.state.killc = nkinks = nhelp = resting = casual = game.state.nromkl = 0;\r
- isatb = iscate = imine = icrystl = icraft = game.state.nsckill = game.state.nplankl = 0;\r
- game.state.starkl = game.state.basekl = 0;\r
- iscraft = 1;\r
- landed = -1;\r
- alive = 1;\r
- docfac = 0.25;\r
- for (i = 1; i <= 8; i++)\r
- for (j = 1; j <= 8; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0;\r
- // Initialize times for extraneous events\r
- game.future[FSNOVA] = game.state.date + expran(0.5 * intime);\r
- game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));\r
- game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot\r
- game.future[FBATTAK] = game.state.date + expran(0.3*intime);\r
- game.future[FCDBAS] = 1e30;\r
- game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : 1e30;\r
- game.future[FSCDBAS] = 1e30;\r
- game.future[FDSPROB] = 1e30;\r
- // Starchart is functional\r
- stdamtim = 1e30;\r
- // Put stars in the galaxy\r
- instar = 0;\r
- for (i=1; i<=8; i++)\r
- for (j=1; j<=8; j++) {\r
- int k = Rand()*9.0 + 1.0;\r
- instar += k;\r
- game.state.galaxy[i][j] = k;\r
- }\r
- // Locate star bases in galaxy\r
- for (i = 1; i <= inbase; i++) {\r
- int contflag;\r
- do {\r
- do iran8(&ix, &iy);\r
- while (game.state.galaxy[ix][iy] >= 10);\r
- contflag = FALSE;\r
- for (j = i-1; j > 0; j--) {\r
- /* Improved placement algorithm to spread out bases */\r
- double distq = square(ix-game.state.baseqx[j]) + square(iy-game.state.baseqy[j]);\r
- if (distq < 6.0*(6-inbase) && Rand() < 0.75) {\r
- contflag = TRUE;\r
-#ifdef DEBUG\r
- proutn("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);\r
-#endif\r
- break;\r
- }\r
-#ifdef DEBUG\r
- else if (distq < 6.0 * (6-inbase)) {\r
- proutn("DEBUG: saving base #%d, close to #%d\n", i, j);\r
- }\r
-#endif\r
- }\r
- } while (contflag);\r
- \r
- game.state.baseqx[i] = ix;\r
- game.state.baseqy[i] = iy;\r
- game.starch[ix][iy] = -1;\r
- game.state.galaxy[ix][iy] += 10;\r
- }\r
- // Position ordinary Klingon Battle Cruisers\r
- krem = inkling - incom - game.state.nscrem;\r
- klumper = 0.25*skill*(9.0-length)+1.0;\r
- if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant\r
- do {\r
- double r = Rand();\r
- int klump = (1.0 - r*r)*klumper;\r
- if (klump > krem) klump = krem;\r
- krem -= klump;\r
- klump *= 100;\r
- do iran8(&ix, &iy);\r
- while (game.state.galaxy[ix][iy] + klump >= 1000);\r
- game.state.galaxy[ix][iy] += klump;\r
- } while (krem > 0);\r
- // Position Klingon Commander Ships\r
-#ifdef DEBUG\r
- klumper = 1;\r
-#endif\r
- for (i = 1; i <= incom; i++) {\r
- do {\r
- do { /* IF debugging, put commanders by bases, always! */\r
-#ifdef DEBUG\r
- if (idebug && klumper <= inbase) {\r
- ix = game.state.baseqx[klumper];\r
- iy = game.state.baseqy[klumper];\r
- klumper++;\r
- }\r
- else\r
-#endif\r
- iran8(&ix, &iy);\r
- }\r
- while ((game.state.galaxy[ix][iy] < 99 && Rand() < 0.75)||\r
- game.state.galaxy[ix][iy]>899);\r
- // check for duplicate\r
- for (j = 1; j < i; j++)\r
- if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;\r
- } while (j < i);\r
- game.state.galaxy[ix][iy] += 100;\r
- game.state.cx[i] = ix;\r
- game.state.cy[i] = iy;\r
- }\r
- // Locate planets in galaxy\r
- for (i = 0; i < inplan; i++) {\r
- do iran8(&ix, &iy);\r
- while (game.state.newstuf[ix][iy] > 0);\r
- game.state.newstuf[ix][iy] = 1;\r
- game.state.plnets[i].x = ix;\r
- game.state.plnets[i].y = iy;\r
- game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O\r
- game.state.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals\r
- game.state.plnets[i].known = unknown;\r
- }\r
- // Locate Romulans\r
- for (i = 1; i <= game.state.nromrem; i++) {\r
- iran8(&ix, &iy);\r
- game.state.newstuf[ix][iy] += 10;\r
- }\r
- // Locate the Super Commander\r
- if (game.state.nscrem > 0) {\r
- do iran8(&ix, &iy);\r
- while (game.state.galaxy[ix][iy] >= 900);\r
- game.state.isx = ix;\r
- game.state.isy = iy;\r
- game.state.galaxy[ix][iy] += 100;\r
- }\r
- // Place thing (in tournament game, thingx == -1, don't want one!)\r
- if (thingx != -1) {\r
- iran8(&thingx, &thingy);\r
- }\r
- else {\r
- thingx = thingy = 0;\r
- }\r
-\r
-// idate = date;\r
- skip(2);\r
- game.state.snap = 0;\r
- \r
- if (skill == 1) {\r
- prout("It is stardate %d. The Federation is being attacked by",\r
- (int)game.state.date);\r
- prout("a deadly Klingon invasion force. As captain of the United");\r
- prout("Starship U.S.S. Enterprise, it is your mission to seek out");\r
- prout("and destroy this invasion force of %d battle cruisers.",\r
- inkling);\r
- prout("You have an initial allotment of %d stardates to complete", (int)intime);\r
- prout("your mission. As you proceed you may be given more time.");\r
- prout("");\r
- prout("You will have %d supporting starbases.", inbase);\r
- proutn("Starbase locations- ");\r
- }\r
- else {\r
- prout("Stardate %d.", (int)game.state.date);\r
- prout("");\r
- prout("%d Klingons.", inkling);\r
- prout("An unknown number of Romulans.");\r
- if (game.state.nscrem) prout("and one (GULP) Super-Commander.");\r
- prout("%d stardates.",(int)intime);\r
- proutn("%d starbases in ", inbase);\r
- }\r
- for (i = 1; i <= inbase; i++) {\r
- proutn(cramlc(0, game.state.baseqx[i], game.state.baseqy[i]));\r
- proutn(" ");\r
- }\r
- skip(2);\r
- proutn("The Enterprise is currently in ");\r
- proutn(cramlc(quadrant, quadx, quady));\r
- proutn(" ");\r
- proutn(cramlc(sector, sectx, secty));\r
- skip(2);\r
- prout("Good Luck!");\r
- if (game.state.nscrem) prout(" YOU'LL NEED IT.");\r
-#ifdef SERGEEV\r
- getche();\r
-#endif /* SERGEEV */\r
- newqad(0);\r
- if (nenhere-iqhere-ithere) shldup=1.0;\r
- if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone\r
-}\r
-\r
-void randomize(void) {\r
- srand((int)time(NULL));\r
-}\r
-\r
-int choose(int needprompt) {\r
- tourn = 0;\r
- thawed = 0;\r
- skill = 0;\r
- length = 0;\r
- while (TRUE) {\r
- if (needprompt) /* Can start with command line options */\r
- proutn("Would you like a regular, tournament, or frozen game?");\r
- scan();\r
- if (strlen(citem)==0) continue; // Try again\r
- if (isit("tournament")) {\r
- while (scan() == IHEOL) {\r
- proutn("Type in tournament number-");\r
- }\r
- if (aaitem == 0) {\r
- chew();\r
- continue; // We don't want a blank entry\r
- }\r
- tourn = (int)aaitem;\r
- thingx = -1;\r
- srand((unsigned int)(int)aaitem);\r
- break;\r
- }\r
- if (isit("frozen")) {\r
- thaw();\r
- chew();\r
- if (*game.passwd==0) continue;\r
- randomize();\r
- Rand(); Rand(); Rand(); Rand();\r
- if (!alldone) thawed = 1; // No plaque if not finished\r
- report(1);\r
- return TRUE;\r
- }\r
- if (isit("regular")) {\r
- skip(2);\r
- randomize();\r
- Rand(); Rand(); Rand(); Rand();\r
- break;\r
- }\r
- proutn("What is \"");\r
- proutn(citem);\r
- prout("\"?");\r
- chew();\r
- }\r
- while (length==0 || skill==0) {\r
- if (scan() == IHALPHA) {\r
- if (isit("short")) length = 1;\r
- else if (isit("medium")) length = 2;\r
- else if (isit("long")) length = 4;\r
- else if (isit("novice")) skill = 1;\r
- else if (isit("fair")) skill = 2;\r
- else if (isit("good")) skill = 3;\r
- else if (isit("expert")) skill = 4;\r
- else if (isit("emeritus")) skill = 5;\r
- else {\r
- proutn("What is \"");\r
- proutn(citem);\r
- prout("\"?");\r
- }\r
- }\r
- else {\r
- chew();\r
- if (length==0) proutn("Would you like a Short, Medium, or Long game? ");\r
- else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player? ");\r
- }\r
- }\r
-#ifndef SERGEEV\r
- while (TRUE) {\r
- scan();\r
- strcpy(game.passwd, citem);\r
- chew();\r
- if (*game.passwd != 0) break;\r
- proutn("Please type in a secret password-");\r
- }\r
-#else\r
- for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));\r
- game.passwd[3]=0;\r
-#endif /* SERGEEV */\r
-#ifdef DEBUG\r
- if (strcmp(game.passwd, "debug")==0) idebug = 1;\r
-#endif\r
-\r
- // Use parameters to generate initial values of things\r
- damfac = 0.5 * skill;\r
- game.state.rembase = 3.0*Rand()+2.0;\r
- inbase = game.state.rembase;\r
- inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();\r
- game.state.nromrem = (2.0+Rand())*skill;\r
- game.state.nscrem = (skill > 2? 1 : 0);\r
- game.state.remtime = 7.0 * length;\r
- intime = game.state.remtime;\r
- game.state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);\r
- inkling = game.state.remkl;\r
- incom = skill + 0.0625*inkling*Rand();\r
- game.state.remcom= min(10, incom);\r
- incom = game.state.remcom;\r
- game.state.remres = (inkling+4*incom)*intime;\r
- inresor = game.state.remres;\r
- if (inkling > 50) {\r
- inbase = (game.state.rembase += 1);\r
- }\r
- return FALSE;\r
-}\r
-\r
-void dropin(int iquad, int *ix, int *iy) {\r
- do iran10(ix, iy);\r
- while (game.quad[*ix][*iy] != IHDOT);\r
- game.quad[*ix][*iy] = iquad;\r
-}\r
-\r
-void newcnd(void) {\r
- condit = IHGREEN;\r
- if (energy < 1000.0) condit = IHYELLOW;\r
- if (game.state.galaxy[quadx][quady] > 99 || game.state.newstuf[quadx][quady] > 9)\r
- condit = IHRED;\r
- if (!alive) condit=IHDEAD;\r
-}\r
-\r
-\r
-void newqad(int shutup) {\r
- int quadnum = game.state.galaxy[quadx][quady];\r
- int newnum = game.state.newstuf[quadx][quady];\r
- int i, j, ix, iy, nplan;\r
-\r
- iattak = 1;\r
- justin = 1;\r
- basex = basey = 0;\r
- klhere = 0;\r
- comhere = 0;\r
- plnetx = plnety = 0;\r
- ishere = 0;\r
- irhere = 0;\r
- iplnet = 0;\r
- nenhere = 0;\r
- neutz = 0;\r
- inorbit = 0;\r
- landed = -1;\r
- ientesc = 0;\r
- ithere = 0;\r
- iqhere=0;\r
- iqengry=0;\r
- iseenit = 0;\r
- if (iscate) {\r
- // Attempt to escape Super-commander, so tbeam back!\r
- iscate = 0;\r
- ientesc = 1;\r
- }\r
- // Clear quadrant\r
- for (i=1; i <= 10; i++)\r
- for (j=1; j <= 10; j++) game.quad[i][j] = IHDOT;\r
- // cope with supernova\r
- if (quadnum > 999) {\r
- return;\r
- }\r
- klhere = quadnum/100;\r
- irhere = newnum/10;\r
- nplan = newnum%10;\r
- nenhere = klhere + irhere;\r
-\r
- // Position Starship\r
- game.quad[sectx][secty] = ship;\r
-\r
- if (quadnum >= 100) {\r
- // Position ordinary Klingons\r
- quadnum -= 100*klhere;\r
- for (i = 1; i <= klhere; i++) {\r
- dropin(IHK, &ix, &iy);\r
- game.kx[i] = ix;\r
- game.ky[i] = iy;\r
- game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
- game.kpower[i] = Rand()*150.0 +300.0 +25.0*skill;\r
- }\r
- // If we need a commander, promote a Klingon\r
- for (i = 1; i <= game.state.remcom ; i++) \r
- if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;\r
- \r
- if (i <= game.state.remcom) {\r
- game.quad[ix][iy] = IHC;\r
- game.kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;\r
- comhere = 1;\r
- }\r
-\r
- // If we need a super-commander, promote a Klingon\r
- if (quadx == game.state.isx && quady == game.state.isy) {\r
- game.quad[game.kx[1]][game.ky[1]] = IHS;\r
- game.kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;\r
- iscate = game.state.remkl>1;\r
- ishere = 1;\r
- }\r
- }\r
- // Put in Romulans if needed\r
- for (i = klhere+1; i <= nenhere; i++) {\r
- dropin(IHR, &ix, &iy);\r
- game.kx[i] = ix;\r
- game.ky[i] = iy;\r
- game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));\r
- game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;\r
- }\r
- sortkl();\r
- // If quadrant needs a starbase, put it in\r
- if (quadnum >= 10) {\r
- quadnum -= 10;\r
- dropin(IHB, &basex, &basey);\r
- }\r
- \r
- if (nplan) {\r
- // If quadrant needs a planet, put it in\r
- for (i=0; i < inplan; i++)\r
- if (game.state.plnets[i].x == quadx && game.state.plnets[i].y == quady) break;\r
- if (i < inplan) {\r
- iplnet = i;\r
- dropin(IHP, &plnetx, &plnety);\r
- }\r
- }\r
- // Check for condition\r
- newcnd();\r
- // And finally the stars\r
- for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);\r
-\r
- // Check for RNZ\r
- if (irhere > 0 && klhere == 0) {\r
- neutz = 1;\r
- if (game.damage[DRADIO] <= 0.0) {\r
- skip(1);\r
- prout("LT. Uhura- \"Captain, an urgent message.");\r
- prout(" I'll put it on audio.\" CLICK");\r
- skip(1);\r
- prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");\r
- prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");\r
- }\r
- }\r
-\r
- if (shutup==0) {\r
- // Put in THING if needed\r
- if (thingx == quadx && thingy == quady) {\r
- dropin(IHQUEST, &ix, &iy);\r
- iran8(&thingx, &thingy);\r
- nenhere++;\r
- iqhere=1;\r
- game.kx[nenhere] = ix;\r
- game.ky[nenhere] = iy;\r
- game.kdist[nenhere] = game.kavgd[nenhere] =\r
- sqrt(square(sectx-ix) + square(secty-iy));\r
- game.kpower[nenhere] = Rand()*6000.0 +500.0 +250.0*skill;\r
- if (game.damage[DSRSENS] == 0.0) {\r
- skip(1);\r
- prout("MR. SPOCK- \"Captain, this is most unusual.");\r
- prout(" Please examine your short-range scan.\"");\r
- }\r
- }\r
- }\r
-\r
- // Decide if quadrant needs a Tholian\r
- if ((skill < 3 && Rand() <= 0.02) || /* Lighten up if skill is low */\r
- (skill == 3 && Rand() <= 0.05) ||\r
- (skill > 3 && Rand() <= 0.08)\r
-#ifdef DEBUG\r
- || strcmp(passwd, "tholianx")==0\r
-#endif\r
- ) {\r
- do {\r
- ithx = Rand() > 0.5 ? 10 : 1;\r
- ithy = Rand() > 0.5 ? 10 : 1;\r
- } while (game.quad[ithx][ithy] != IHDOT);\r
- game.quad[ithx][ithy] = IHT;\r
- ithere = 1;\r
- nenhere++;\r
- game.kx[nenhere] = ithx;\r
- game.ky[nenhere] = ithy;\r
- game.kdist[nenhere] = game.kavgd[nenhere] =\r
- sqrt(square(sectx-ithx) + square(secty-ithy));\r
- game.kpower[nenhere] = Rand()*400.0 +100.0 +25.0*skill;\r
- /* Reserve unocupied corners */\r
- if (game.quad[1][1]==IHDOT) game.quad[1][1] = 'X';\r
- if (game.quad[1][10]==IHDOT) game.quad[1][10] = 'X';\r
- if (game.quad[10][1]==IHDOT) game.quad[10][1] = 'X';\r
- if (game.quad[10][10]==IHDOT) game.quad[10][10] = 'X';\r
- }\r
- sortkl();\r
-\r
- // Put in a few black holes\r
- for (i = 1; i <= 3; i++)\r
- if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);\r
-\r
- // Take out X's in corners if Tholian present\r
- if (ithere) {\r
- if (game.quad[1][1]=='X') game.quad[1][1] = IHDOT;\r
- if (game.quad[1][10]=='X') game.quad[1][10] = IHDOT;\r
- if (game.quad[10][1]=='X') game.quad[10][1] = IHDOT;\r
- if (game.quad[10][10]=='X') game.quad[10][10] = IHDOT;\r
- } \r
-}\r
-\r
-void sortkl(void) {\r
- double t;\r
- int sw, j, k;\r
-\r
- // The author liked bubble sort. So we will use it. :-(\r
-\r
- if (nenhere-iqhere-ithere < 2) return;\r
-\r
- do {\r
- sw = FALSE;\r
- for (j = 1; j < nenhere; j++)\r
- if (game.kdist[j] > game.kdist[j+1]) {\r
- sw = TRUE;\r
- t = game.kdist[j];\r
- game.kdist[j] = game.kdist[j+1];\r
- game.kdist[j+1] = t;\r
- t = game.kavgd[j];\r
- game.kavgd[j] = game.kavgd[j+1];\r
- game.kavgd[j+1] = t;\r
- k = game.kx[j];\r
- game.kx[j] = game.kx[j+1];\r
- game.kx[j+1] = k;\r
- k = game.ky[j];\r
- game.ky[j] = game.ky[j+1];\r
- game.ky[j+1] = k;\r
- t = game.kpower[j];\r
- game.kpower[j] = game.kpower[j+1];\r
- game.kpower[j+1] = t;\r
- }\r
- } while (sw);\r
-}\r
+#include <time.h>
+#ifdef SERGEEV
+#include <sys/stat.h>
+#include <conio.h>
+#endif /* SERGEEV */
+#include "sst.h"
+
+#ifdef SERGEEV
+#ifdef __linux__
+static long filelength(int fd) {
+struct stat buf;
+ fstat(fd, &buf);
+ return buf.st_size;
+}
+#endif
+#endif /* SERGEEV */
+
+void prelim(void) {
+ skip(2);
+ prout("-SUPER- STAR TREK");
+ skip(1);
+#ifndef SERGEEV
+ prout("Latest update-21 Sept 78");
+ skip(1);
+#endif /* SERGEEV */
+}
+
+void freeze(int boss) {
+ FILE *fp;
+ int key;
+ if (boss) {
+ strcpy(citem, "emsave.trk");
+ }
+ else {
+ if ((key = scan()) == IHEOL) {
+ proutn("File name: ");
+ key = scan();
+ }
+ if (key != IHALPHA) {
+ huh();
+ return;
+ }
+ chew();
+ if (strchr(citem, '.') == NULL) {
+ strcat(citem, ".trk");
+ }
+ }
+ if ((fp = fopen(citem, "wb")) == NULL) {
+ proutn("Can't freeze game as file ");
+ proutn(citem);
+ skip(1);
+ return;
+ }
+ strcpy(game.magic, SSTMAGIC);
+ fwrite(&game, sizeof(game), 1, fp);
+
+ fclose(fp);
+
+ /* I hope that's enough! */
+}
+
+
+int thaw(void) {
+ FILE *fp;
+ int key;
+
+ game.passwd[0] = '\0';
+ if ((key = scan()) == IHEOL) {
+ proutn("File name: ");
+ key = scan();
+ }
+ if (key != IHALPHA) {
+ huh();
+ return 1;
+ }
+ chew();
+ if (strchr(citem, '.') == NULL) {
+ strcat(citem, ".trk");
+ }
+ if ((fp = fopen(citem, "rb")) == NULL) {
+ proutn("Can't find game file ");
+ proutn(citem);
+ skip(1);
+ return 1;
+ }
+ fread(&game, sizeof(game), 1, fp);
+ if (strcmp(game.magic, SSTMAGIC)) {
+ prout("Game file format is bad, should begin with " SSTMAGIC);
+ skip(1);
+ fclose(fp);
+ return 1;
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+void abandn(void) {
+ int nb, l;
+
+ chew();
+ if (condit==IHDOCKED) {
+ if (ship!=IHE) {
+ prout("You cannot abandon Ye Faerie Queene.");
+ return;
+ }
+ }
+ else {
+ /* Must take shuttle craft to exit */
+ if (game.damage[DSHUTTL]==-1) {
+ prout("Ye Faerie Queene has no shuttle craft.");
+ return;
+ }
+ if (game.damage[DSHUTTL]<0) {
+ prout("Shuttle craft now serving Big Mac's.");
+ return;
+ }
+ if (game.damage[DSHUTTL]>0) {
+ prout("Shuttle craft damaged.");
+ return;
+ }
+ if (landed==1) {
+ prout("You must be aboard the Enterprise.");
+ return;
+ }
+ if (iscraft!=1) {
+ prout("Shuttle craft not currently available.");
+ return;
+ }
+ /* Print abandon ship messages */
+ skip(1);
+ prouts("***ABANDON SHIP! ABANDON SHIP!");
+ skip(1);
+ prouts("***ALL HANDS ABANDON SHIP!");
+ skip(2);
+ prout("Captain and crew escape in shuttle craft.");
+ prout("Remainder of ship's complement beam down");
+ prout("to nearest habitable planet.");
+ if (game.state.rembase==0) {
+ /* Ops! no place to go... */
+ finish(FABANDN);
+ return;
+ }
+ /* If at least one base left, give 'em the Faerie Queene */
+ skip(1);
+ icrystl = 0; /* crystals are lost */
+ nprobes = 0; /* No probes */
+ prout("You are captured by Klingons and released to");
+ prout("the Federation in a prisoner-of-war exchange.");
+ nb = Rand()*game.state.rembase+1;
+ /* Set up quadrant and position FQ adjacient to base */
+ if (quadx!=game.state.baseqx[nb] || quady!=game.state.baseqy[nb]) {
+ quadx = game.state.baseqx[nb];
+ quady = game.state.baseqy[nb];
+ sectx = secty = 5;
+ newqad(1);
+ }
+ for (;;) {
+ /* position next to base by trial and error */
+ game.quad[sectx][secty] = IHDOT;
+ for (l = 1; l <= 10; l++) {
+ sectx = 3.0*Rand() - 1.0 + basex;
+ secty = 3.0*Rand() - 1.0 + basey;
+ if (sectx >= 1 && sectx <= 10 &&
+ secty >= 1 && secty <= 10 &&
+ game.quad[sectx][secty] == IHDOT) break;
+ }
+ if (l < 11) break; /* found a spot */
+ sectx=5;
+ secty=5;
+ newqad(1);
+ }
+ }
+ /* Get new commission */
+ game.quad[sectx][secty] = ship = IHF;
+ prout("Starfleet puts you in command of another ship,");
+ prout("the Faerie Queene, which is antiquated but,");
+ prout("still useable.");
+ if (icrystl!=0) prout("The dilithium crystals have been moved.");
+ imine=0;
+ iscraft=0; /* Gallileo disappears */
+ /* Resupply ship */
+ condit=IHDOCKED;
+ for (l = 1; l <= NDEVICES; l++) game.damage[l] = 0.0;
+ game.damage[DSHUTTL] = -1;
+ energy = inenrg = 3000.0;
+ shield = inshld = 1250.0;
+ torps = intorps = 6;
+ lsupres=inlsr=3.0;
+ shldup=0;
+ warpfac=5.0;
+ wfacsq=25.0;
+ return;
+}
+
+void setup(int needprompt) {
+ int i,j, krem, klumper;
+ int ix, iy;
+#ifdef DEBUG
+ idebug = 0;
+#endif
+ // Decide how many of everything
+ if (choose(needprompt)) return; // frozen game
+ // Prepare the Enterprise
+ alldone = gamewon = 0;
+ ship = IHE;
+ energy = inenrg = 5000.0;
+ shield = inshld = 2500.0;
+ shldchg = shldup = 0;
+ inlsr = 4.0;
+ lsupres = 4.0;
+ iran8(&quadx, &quady);
+ iran10(§x, §y);
+ torps = intorps = 10;
+ nprobes = (int)(3.0*Rand() + 2.0); /* Give them 2-4 of these wonders */
+ warpfac = 5.0;
+ wfacsq = warpfac * warpfac;
+ for (i=0; i <= NDEVICES; i++) game.damage[i] = 0.0;
+ // Set up assorted game parameters
+ batx = baty = 0;
+ game.state.date = indate = 100.0*(int)(31.0*Rand()+20.0);
+ game.state.killk = game.state.killc = nkinks = nhelp = resting = casual = game.state.nromkl = 0;
+ isatb = iscate = imine = icrystl = icraft = game.state.nsckill = game.state.nplankl = 0;
+ game.state.starkl = game.state.basekl = 0;
+ iscraft = 1;
+ landed = -1;
+ alive = 1;
+ docfac = 0.25;
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0;
+ // Initialize times for extraneous events
+ game.future[FSNOVA] = game.state.date + expran(0.5 * intime);
+ game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));
+ game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot
+ game.future[FBATTAK] = game.state.date + expran(0.3*intime);
+ game.future[FCDBAS] = 1e30;
+ game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : 1e30;
+ game.future[FSCDBAS] = 1e30;
+ game.future[FDSPROB] = 1e30;
+ // Starchart is functional
+ stdamtim = 1e30;
+ // Put stars in the galaxy
+ instar = 0;
+ for (i=1; i<=8; i++)
+ for (j=1; j<=8; j++) {
+ int k = Rand()*9.0 + 1.0;
+ instar += k;
+ game.state.galaxy[i][j] = k;
+ }
+ // Locate star bases in galaxy
+ for (i = 1; i <= inbase; i++) {
+ int contflag;
+ do {
+ do iran8(&ix, &iy);
+ while (game.state.galaxy[ix][iy] >= 10);
+ contflag = FALSE;
+ for (j = i-1; j > 0; j--) {
+ /* Improved placement algorithm to spread out bases */
+ double distq = square(ix-game.state.baseqx[j]) + square(iy-game.state.baseqy[j]);
+ if (distq < 6.0*(6-inbase) && Rand() < 0.75) {
+ contflag = TRUE;
+#ifdef DEBUG
+ proutn("DEBUG: Abandoning base #%d at %d-%d\n", i, ix, iy);
+#endif
+ break;
+ }
+#ifdef DEBUG
+ else if (distq < 6.0 * (6-inbase)) {
+ proutn("DEBUG: saving base #%d, close to #%d\n", i, j);
+ }
+#endif
+ }
+ } while (contflag);
+
+ game.state.baseqx[i] = ix;
+ game.state.baseqy[i] = iy;
+ game.starch[ix][iy] = -1;
+ game.state.galaxy[ix][iy] += 10;
+ }
+ // Position ordinary Klingon Battle Cruisers
+ krem = inkling - incom - game.state.nscrem;
+ klumper = 0.25*skill*(9.0-length)+1.0;
+ if (klumper > 9) klumper = 9; // Can't have more than 9 in quadrant
+ do {
+ double r = Rand();
+ int klump = (1.0 - r*r)*klumper;
+ if (klump > krem) klump = krem;
+ krem -= klump;
+ klump *= 100;
+ do iran8(&ix, &iy);
+ while (game.state.galaxy[ix][iy] + klump >= 1000);
+ game.state.galaxy[ix][iy] += klump;
+ } while (krem > 0);
+ // Position Klingon Commander Ships
+#ifdef DEBUG
+ klumper = 1;
+#endif
+ for (i = 1; i <= incom; i++) {
+ do {
+ do { /* IF debugging, put commanders by bases, always! */
+#ifdef DEBUG
+ if (idebug && klumper <= inbase) {
+ ix = game.state.baseqx[klumper];
+ iy = game.state.baseqy[klumper];
+ klumper++;
+ }
+ else
+#endif
+ iran8(&ix, &iy);
+ }
+ while ((game.state.galaxy[ix][iy] < 99 && Rand() < 0.75)||
+ game.state.galaxy[ix][iy]>899);
+ // check for duplicate
+ for (j = 1; j < i; j++)
+ if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;
+ } while (j < i);
+ game.state.galaxy[ix][iy] += 100;
+ game.state.cx[i] = ix;
+ game.state.cy[i] = iy;
+ }
+ // Locate planets in galaxy
+ for (i = 0; i < inplan; i++) {
+ do iran8(&ix, &iy);
+ while (game.state.newstuf[ix][iy] > 0);
+ game.state.newstuf[ix][iy] = 1;
+ game.state.plnets[i].x = ix;
+ game.state.plnets[i].y = iy;
+ game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O
+ game.state.plnets[i].crystals = 1.5*Rand(); // 1 in 3 chance of crystals
+ game.state.plnets[i].known = unknown;
+ }
+ // Locate Romulans
+ for (i = 1; i <= game.state.nromrem; i++) {
+ iran8(&ix, &iy);
+ game.state.newstuf[ix][iy] += 10;
+ }
+ // Locate the Super Commander
+ if (game.state.nscrem > 0) {
+ do iran8(&ix, &iy);
+ while (game.state.galaxy[ix][iy] >= 900);
+ game.state.isx = ix;
+ game.state.isy = iy;
+ game.state.galaxy[ix][iy] += 100;
+ }
+ // Place thing (in tournament game, thingx == -1, don't want one!)
+ if (thingx != -1) {
+ iran8(&thingx, &thingy);
+ }
+ else {
+ thingx = thingy = 0;
+ }
+
+// idate = date;
+ skip(2);
+ game.state.snap = 0;
+
+ if (skill == 1) {
+ prout("It is stardate %d. The Federation is being attacked by",
+ (int)game.state.date);
+ prout("a deadly Klingon invasion force. As captain of the United");
+ prout("Starship U.S.S. Enterprise, it is your mission to seek out");
+ prout("and destroy this invasion force of %d battle cruisers.",
+ inkling);
+ prout("You have an initial allotment of %d stardates to complete", (int)intime);
+ prout("your mission. As you proceed you may be given more time.");
+ prout("");
+ prout("You will have %d supporting starbases.", inbase);
+ proutn("Starbase locations- ");
+ }
+ else {
+ prout("Stardate %d.", (int)game.state.date);
+ prout("");
+ prout("%d Klingons.", inkling);
+ prout("An unknown number of Romulans.");
+ if (game.state.nscrem) prout("and one (GULP) Super-Commander.");
+ prout("%d stardates.",(int)intime);
+ proutn("%d starbases in ", inbase);
+ }
+ for (i = 1; i <= inbase; i++) {
+ proutn(cramlc(0, game.state.baseqx[i], game.state.baseqy[i]));
+ proutn(" ");
+ }
+ skip(2);
+ proutn("The Enterprise is currently in ");
+ proutn(cramlc(quadrant, quadx, quady));
+ proutn(" ");
+ proutn(cramlc(sector, sectx, secty));
+ skip(2);
+ prout("Good Luck!");
+ if (game.state.nscrem) prout(" YOU'LL NEED IT.");
+#ifdef SERGEEV
+ getche();
+#endif /* SERGEEV */
+ newqad(0);
+ if (nenhere-iqhere-ithere) shldup=1.0;
+ if (neutz) attack(0); // bad luck to start in a Romulan Neutral Zone
+}
+
+void randomize(void) {
+ srand((int)time(NULL));
+}
+
+int choose(int needprompt) {
+ tourn = 0;
+ thawed = 0;
+ skill = 0;
+ length = 0;
+ while (TRUE) {
+ if (needprompt) /* Can start with command line options */
+ proutn("Would you like a regular, tournament, or frozen game?");
+ scan();
+ if (strlen(citem)==0) continue; // Try again
+ if (isit("tournament")) {
+ while (scan() == IHEOL) {
+ proutn("Type in tournament number-");
+ }
+ if (aaitem == 0) {
+ chew();
+ continue; // We don't want a blank entry
+ }
+ tourn = (int)aaitem;
+ thingx = -1;
+ srand((unsigned int)(int)aaitem);
+ break;
+ }
+ if (isit("frozen")) {
+ thaw();
+ chew();
+ if (*game.passwd==0) continue;
+ randomize();
+ Rand(); Rand(); Rand(); Rand();
+ if (!alldone) thawed = 1; // No plaque if not finished
+ report(1);
+ return TRUE;
+ }
+ if (isit("regular")) {
+ skip(2);
+ randomize();
+ Rand(); Rand(); Rand(); Rand();
+ break;
+ }
+ proutn("What is \"");
+ proutn(citem);
+ prout("\"?");
+ chew();
+ }
+ while (length==0 || skill==0) {
+ if (scan() == IHALPHA) {
+ if (isit("short")) length = 1;
+ else if (isit("medium")) length = 2;
+ else if (isit("long")) length = 4;
+ else if (isit("novice")) skill = 1;
+ else if (isit("fair")) skill = 2;
+ else if (isit("good")) skill = 3;
+ else if (isit("expert")) skill = 4;
+ else if (isit("emeritus")) skill = 5;
+ else {
+ proutn("What is \"");
+ proutn(citem);
+ prout("\"?");
+ }
+ }
+ else {
+ chew();
+ if (length==0) proutn("Would you like a Short, Medium, or Long game? ");
+ else if (skill == 0) proutn("Are you a Novice, Fair, Good, Expert, or Emeritus player? ");
+ }
+ }
+#ifndef SERGEEV
+ while (TRUE) {
+ scan();
+ strcpy(game.passwd, citem);
+ chew();
+ if (*game.passwd != 0) break;
+ proutn("Please type in a secret password-");
+ }
+#else
+ for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
+ game.passwd[3]=0;
+#endif /* SERGEEV */
+#ifdef DEBUG
+ if (strcmp(game.passwd, "debug")==0) idebug = 1;
+#endif
+
+ // Use parameters to generate initial values of things
+ damfac = 0.5 * skill;
+ game.state.rembase = 3.0*Rand()+2.0;
+ inbase = game.state.rembase;
+ inplan = (PLNETMAX/2) + (PLNETMAX/2+1)*Rand();
+ game.state.nromrem = (2.0+Rand())*skill;
+ game.state.nscrem = (skill > 2? 1 : 0);
+ game.state.remtime = 7.0 * length;
+ intime = game.state.remtime;
+ game.state.remkl = 2.0*intime*((skill+1 - 2*Rand())*skill*0.1+.15);
+ inkling = game.state.remkl;
+ incom = skill + 0.0625*inkling*Rand();
+ game.state.remcom= min(10, incom);
+ incom = game.state.remcom;
+ game.state.remres = (inkling+4*incom)*intime;
+ inresor = game.state.remres;
+ if (inkling > 50) {
+ inbase = (game.state.rembase += 1);
+ }
+ return FALSE;
+}
+
+void dropin(int iquad, int *ix, int *iy) {
+ do iran10(ix, iy);
+ while (game.quad[*ix][*iy] != IHDOT);
+ game.quad[*ix][*iy] = iquad;
+}
+
+void newcnd(void) {
+ condit = IHGREEN;
+ if (energy < 1000.0) condit = IHYELLOW;
+ if (game.state.galaxy[quadx][quady] > 99 || game.state.newstuf[quadx][quady] > 9)
+ condit = IHRED;
+ if (!alive) condit=IHDEAD;
+}
+
+
+void newqad(int shutup) {
+ int quadnum = game.state.galaxy[quadx][quady];
+ int newnum = game.state.newstuf[quadx][quady];
+ int i, j, ix, iy, nplan;
+
+ iattak = 1;
+ justin = 1;
+ basex = basey = 0;
+ klhere = 0;
+ comhere = 0;
+ plnetx = plnety = 0;
+ ishere = 0;
+ irhere = 0;
+ iplnet = 0;
+ nenhere = 0;
+ neutz = 0;
+ inorbit = 0;
+ landed = -1;
+ ientesc = 0;
+ ithere = 0;
+ iqhere=0;
+ iqengry=0;
+ iseenit = 0;
+ if (iscate) {
+ // Attempt to escape Super-commander, so tbeam back!
+ iscate = 0;
+ ientesc = 1;
+ }
+ // Clear quadrant
+ for (i=1; i <= 10; i++)
+ for (j=1; j <= 10; j++) game.quad[i][j] = IHDOT;
+ // cope with supernova
+ if (quadnum > 999) {
+ return;
+ }
+ klhere = quadnum/100;
+ irhere = newnum/10;
+ nplan = newnum%10;
+ nenhere = klhere + irhere;
+
+ // Position Starship
+ game.quad[sectx][secty] = ship;
+
+ if (quadnum >= 100) {
+ // Position ordinary Klingons
+ quadnum -= 100*klhere;
+ for (i = 1; i <= klhere; i++) {
+ dropin(IHK, &ix, &iy);
+ game.kx[i] = ix;
+ game.ky[i] = iy;
+ game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
+ game.kpower[i] = Rand()*150.0 +300.0 +25.0*skill;
+ }
+ // If we need a commander, promote a Klingon
+ for (i = 1; i <= game.state.remcom ; i++)
+ if (game.state.cx[i]==quadx && game.state.cy[i]==quady) break;
+
+ if (i <= game.state.remcom) {
+ game.quad[ix][iy] = IHC;
+ game.kpower[klhere] = 950.0+400.0*Rand()+50.0*skill;
+ comhere = 1;
+ }
+
+ // If we need a super-commander, promote a Klingon
+ if (quadx == game.state.isx && quady == game.state.isy) {
+ game.quad[game.kx[1]][game.ky[1]] = IHS;
+ game.kpower[1] = 1175.0 + 400.0*Rand() + 125.0*skill;
+ iscate = game.state.remkl>1;
+ ishere = 1;
+ }
+ }
+ // Put in Romulans if needed
+ for (i = klhere+1; i <= nenhere; i++) {
+ dropin(IHR, &ix, &iy);
+ game.kx[i] = ix;
+ game.ky[i] = iy;
+ game.kdist[i] = game.kavgd[i] = sqrt(square(sectx-ix) + square(secty-iy));
+ game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
+ }
+ sortkl();
+ // If quadrant needs a starbase, put it in
+ if (quadnum >= 10) {
+ quadnum -= 10;
+ dropin(IHB, &basex, &basey);
+ }
+
+ if (nplan) {
+ // If quadrant needs a planet, put it in
+ for (i=0; i < inplan; i++)
+ if (game.state.plnets[i].x == quadx && game.state.plnets[i].y == quady) break;
+ if (i < inplan) {
+ iplnet = i;
+ dropin(IHP, &plnetx, &plnety);
+ }
+ }
+ // Check for condition
+ newcnd();
+ // And finally the stars
+ for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
+
+ // Check for RNZ
+ if (irhere > 0 && klhere == 0) {
+ neutz = 1;
+ if (game.damage[DRADIO] <= 0.0) {
+ skip(1);
+ prout("LT. Uhura- \"Captain, an urgent message.");
+ prout(" I'll put it on audio.\" CLICK");
+ skip(1);
+ prout("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.");
+ prout("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!");
+ }
+ }
+
+ if (shutup==0) {
+ // Put in THING if needed
+ if (thingx == quadx && thingy == quady) {
+ dropin(IHQUEST, &ix, &iy);
+ iran8(&thingx, &thingy);
+ nenhere++;
+ iqhere=1;
+ game.kx[nenhere] = ix;
+ game.ky[nenhere] = iy;
+ game.kdist[nenhere] = game.kavgd[nenhere] =
+ sqrt(square(sectx-ix) + square(secty-iy));
+ game.kpower[nenhere] = Rand()*6000.0 +500.0 +250.0*skill;
+ if (game.damage[DSRSENS] == 0.0) {
+ skip(1);
+ prout("MR. SPOCK- \"Captain, this is most unusual.");
+ prout(" Please examine your short-range scan.\"");
+ }
+ }
+ }
+
+ // Decide if quadrant needs a Tholian
+ if ((skill < 3 && Rand() <= 0.02) || /* Lighten up if skill is low */
+ (skill == 3 && Rand() <= 0.05) ||
+ (skill > 3 && Rand() <= 0.08)
+#ifdef DEBUG
+ || strcmp(passwd, "tholianx")==0
+#endif
+ ) {
+ do {
+ ithx = Rand() > 0.5 ? 10 : 1;
+ ithy = Rand() > 0.5 ? 10 : 1;
+ } while (game.quad[ithx][ithy] != IHDOT);
+ game.quad[ithx][ithy] = IHT;
+ ithere = 1;
+ nenhere++;
+ game.kx[nenhere] = ithx;
+ game.ky[nenhere] = ithy;
+ game.kdist[nenhere] = game.kavgd[nenhere] =
+ sqrt(square(sectx-ithx) + square(secty-ithy));
+ game.kpower[nenhere] = Rand()*400.0 +100.0 +25.0*skill;
+ /* Reserve unocupied corners */
+ if (game.quad[1][1]==IHDOT) game.quad[1][1] = 'X';
+ if (game.quad[1][10]==IHDOT) game.quad[1][10] = 'X';
+ if (game.quad[10][1]==IHDOT) game.quad[10][1] = 'X';
+ if (game.quad[10][10]==IHDOT) game.quad[10][10] = 'X';
+ }
+ sortkl();
+
+ // Put in a few black holes
+ for (i = 1; i <= 3; i++)
+ if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
+
+ // Take out X's in corners if Tholian present
+ if (ithere) {
+ if (game.quad[1][1]=='X') game.quad[1][1] = IHDOT;
+ if (game.quad[1][10]=='X') game.quad[1][10] = IHDOT;
+ if (game.quad[10][1]=='X') game.quad[10][1] = IHDOT;
+ if (game.quad[10][10]=='X') game.quad[10][10] = IHDOT;
+ }
+}
+
+void sortkl(void) {
+ double t;
+ int sw, j, k;
+
+ // The author liked bubble sort. So we will use it. :-(
+
+ if (nenhere-iqhere-ithere < 2) return;
+
+ do {
+ sw = FALSE;
+ for (j = 1; j < nenhere; j++)
+ if (game.kdist[j] > game.kdist[j+1]) {
+ sw = TRUE;
+ t = game.kdist[j];
+ game.kdist[j] = game.kdist[j+1];
+ game.kdist[j+1] = t;
+ t = game.kavgd[j];
+ game.kavgd[j] = game.kavgd[j+1];
+ game.kavgd[j+1] = t;
+ k = game.kx[j];
+ game.kx[j] = game.kx[j+1];
+ game.kx[j+1] = k;
+ k = game.ky[j];
+ game.ky[j] = game.ky[j+1];
+ game.ky[j+1] = k;
+ t = game.kpower[j];
+ game.kpower[j] = game.kpower[j+1];
+ game.kpower[j+1] = t;
+ }
+ } while (sw);
+}
-#define INCLUDED // Define externs here\r
-#include <ctype.h>\r
-#include <getopt.h>\r
-#include "sst.h"\r
-\r
-#ifndef SSTDOC\r
-#define SSTDOC "sst.doc"\r
-#endif\r
- \r
-static char line[128], *linep = line;\r
-\r
-/*\r
-\r
-Here are Tom Almy's changes:\r
-\r
- Compared to original version, I've changed the "help" command to\r
- "call" and the "terminate" command to "quit" to better match\r
- user expectations. The DECUS version apparently made those changes\r
- as well as changing "freeze" to "save". However I like "freeze".\r
-\r
- When I got a later version of Super Star Trek that I was converting\r
- from, I added the emexit command.\r
-\r
- That later version also mentions srscan and lrscan working when\r
- docked (using the starbase's scanners), so I made some changes here\r
- to do this (and indicating that fact to the player), and then realized\r
- the base would have a subspace radio as well -- doing a Chart when docked\r
- updates the star chart, and all radio reports will be heard. The Dock\r
- command will also give a report if a base is under attack.\r
-\r
- Movecom no longer reports movement if sensors are damaged so you wouldn't\r
- otherwise know it.\r
-\r
- Also added:\r
-\r
- 1. Better base positioning at startup\r
-\r
- 2. Deathray improvement (but keeping original failure alternatives)\r
-\r
- 3. Tholian Web.\r
-\r
- 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can\r
- move in Expert and Emeritus games. This code could use improvement.\r
-\r
- 5. The deep space probe looks interesting! DECUS version\r
-\r
- 6. Perhaps cloaking to be added later? BSD version\r
-\r
-Here are Stas Sergeev's changes (controlled by the proprocessor symbol\r
-SERGEEV, not yet completely merged):\r
-\r
- 1. The Space Thingy can be shoved, if you it ram, and can fire back if \r
- fired upon.\r
-\r
- 1 The Tholian can be hit with phasers\r
-\r
- 2. When you are docked, base covers you with an almost invincible shields \r
- (a commander can still ram you, or a Romulan can destroy the base,\r
- or a SCom can even succeed with direct attack IIRC, but this rarely \r
- happens).\r
-\r
- 3. SCom can't escape from you if no more enemies remain (without this, \r
- chasing SCom can take an eternity).\r
-\r
- 4. Probe target you enter is now the destination quadrant. Before I don't \r
- remember what it was, but it was something I had difficulty using)\r
-\r
- 5. Secret password is now autogenerated.\r
-\r
- 6. "Plaque" is adjusted for A4 paper:)\r
-\r
- 7. Phasers now tells you how much energy needed, but only if the computer \r
- is alive.\r
-\r
- 8. Planets are auto-scanned when you enter the quadrant.\r
-\r
- 9. Mining or using crystals in presense of enemy now yields an attack.\r
- There are other minor adjustments to what yields an attack\r
- and what does not.\r
-\r
- 10. Ramming a black hole is no longer instant death. There is a\r
- chance you might get timewarped instead.\r
-\r
- */\r
-\r
-static char *commands[] = {\r
- "srscan",\r
- "lrscan",\r
- "phasers",\r
- "photons",\r
- "move",\r
- "shields",\r
- "dock",\r
- "damages",\r
- "chart",\r
- "impulse",\r
- "rest",\r
- "warp",\r
- "status",\r
- "sensors",\r
- "orbit",\r
- "transport",\r
- "mine",\r
- "crystals",\r
- "shuttle",\r
- "planets",\r
- "request",\r
- "report",\r
- "computer",\r
- "commands",\r
- "emexit",\r
- "probe",\r
- "abandon",\r
- "destruct",\r
- "freeze",\r
- "deathray",\r
- "debug",\r
- "call",\r
- "quit",\r
- "help"\r
-};\r
-#define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])\r
-\r
-static void listCommands(int x) {\r
- prout(" SRSCAN MOVE PHASERS CALL\n"\r
- " STATUS IMPULSE PHOTONS ABANDON\n"\r
- " LRSCAN WARP SHIELDS DESTRUCT\n"\r
- " CHART REST DOCK QUIT\n"\r
- " DAMAGES REPORT SENSORS ORBIT\n"\r
- " TRANSPORT MINE CRYSTALS SHUTTLE\n"\r
- " PLANETS REQUEST DEATHRAY FREEZE\n"\r
- " COMPUTER EMEXIT PROBE COMMANDS");\r
- if (x) prout(" HELP");\r
-}\r
-\r
-#ifdef SERGEEV\r
-void setwnd(short wndnum){\r
- int cury;\r
- cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;\r
- if ((curwnd==0)&&(wndnum!=0)) clrscr();\r
- window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);\r
- if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){\r
- gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);\r
- skip(1);\r
- }\r
- curwnd=wndnum;\r
- gotoxy(1,cury);\r
-}\r
-#endif /* SERGEEV */\r
-\r
-static void helpme(void) {\r
- int i, j;\r
- char cmdbuf[32], *cp;\r
- char linebuf[132];\r
- FILE *fp;\r
- /* Give help on commands */\r
- int key;\r
- key = scan();\r
- while (TRUE) {\r
- if (key == IHEOL) {\r
-#ifdef SERGEEV\r
- setwnd(5);\r
-#endif /* SERGEEV */\r
- proutn("Help on what command? ");\r
- key = scan();\r
- }\r
-#ifdef SERGEEV\r
- setwnd(4);\r
-#endif /* SERGEEV */\r
- if (key == IHEOL) return;\r
- for (i = 0; i < NUMCOMMANDS; i++) {\r
- if (strcmp(commands[i], citem)==0) break;\r
- }\r
- if (i != NUMCOMMANDS) break;\r
- skip(1);\r
- prout("Valid commands:");\r
- listCommands(FALSE);\r
- key = IHEOL;\r
- chew();\r
- skip(1);\r
- }\r
- if (i == 23) {\r
- strcpy(cmdbuf, " ABBREV");\r
- }\r
- else {\r
- for (j = 0; commands[i][j]; j++)\r
- cmdbuf[j] = toupper(commands[i][j]);\r
- cmdbuf[j] = '\0';\r
- }\r
- fp = fopen(SSTDOC, "r");\r
- if (fp == NULL) {\r
- prout("Spock- \"Captain, that information is missing from the");\r
- prout(" computer. You need to find SST.DOC and put it in the");\r
- prout(" current directory.\"");\r
- return;\r
- }\r
- for (;;) {\r
- if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {\r
- prout("Spock- \"Captain, there is no information on that command.\"");\r
- fclose(fp);\r
- return;\r
- }\r
- if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {\r
- for (cp = linebuf+3; isspace(*cp); cp++)\r
- continue;\r
- linebuf[strlen(linebuf)-1] = '\0';\r
- if (strcmp(cp, cmdbuf) == 0)\r
- break;\r
- }\r
- }\r
-\r
- skip(1);\r
- prout("Spock- \"Captain, I've found the following information:\"");\r
- skip(1);\r
-\r
- while (fgets(linebuf, sizeof(linebuf),fp)) {\r
- if (strstr(linebuf, "******"))\r
- break;\r
- proutc(linebuf);\r
- }\r
- fclose(fp);\r
-}\r
-\r
-#ifdef SERGEEV\r
-void drawmaps(short l){\r
- _setcursortype(_NOCURSOR);\r
- if (l==1) sensor();\r
- if (l!=2) setwnd(1);\r
- gotoxy(1,1);\r
- strcpy(line,"s");\r
- srscan(1);\r
- if (l!=2){\r
- setwnd(2);\r
- clrscr();\r
- srscan(2);\r
- setwnd(3);\r
- clrscr();\r
- strcpy(line,"l");\r
- lrscan();\r
- _setcursortype(_NORMALCURSOR);\r
- }\r
-}\r
-#endif /* SERGEEV */\r
-\r
-static void makemoves(void) {\r
- int i, hitme;\r
- while (TRUE) { /* command loop */\r
- hitme = FALSE;\r
- justin = 0;\r
- Time = 0.0;\r
- i = -1;\r
- while (TRUE) { /* get a command */\r
- chew();\r
- skip(1);\r
- proutn("COMMAND> ");\r
- if (scan() == IHEOL) continue;\r
- for (i=0; i < 26; i++)\r
- if (isit(commands[i]))\r
- break;\r
- if (i < 26) break;\r
- for (; i < NUMCOMMANDS; i++)\r
- if (strcmp(commands[i], citem) == 0) break;\r
- if (i < NUMCOMMANDS) break;\r
-\r
- if (skill <= 2) {\r
- prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");\r
- listCommands(TRUE);\r
- }\r
- else prout("UNRECOGNIZED COMMAND.");\r
- }\r
- commandhook(commands[i], TRUE);\r
- switch (i) { /* command switch */\r
- case 0: // srscan\r
- srscan(1);\r
- break;\r
- case 1: // lrscan\r
- lrscan();\r
- break;\r
- case 2: // phasers\r
- phasers();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 3: // photons\r
- photon();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 4: // move\r
- warp(1);\r
- break;\r
- case 5: // shields\r
- doshield(1);\r
- if (ididit) {\r
- attack(2);\r
- shldchg = 0;\r
- }\r
- break;\r
- case 6: // dock\r
- dock(1);\r
- if (ididit) attack(0);\r
- break;\r
- case 7: // damages\r
- dreprt();\r
- break;\r
- case 8: // chart\r
- chart(0);\r
- break;\r
- case 9: // impulse\r
- impuls();\r
- break;\r
- case 10: // rest\r
- wait();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 11: // warp\r
- setwrp();\r
- break;\r
- case 12: // status\r
- srscan(3);\r
- break;\r
- case 13: // sensors\r
- sensor();\r
- break;\r
- case 14: // orbit\r
- orbit();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 15: // transport "beam"\r
- beam();\r
- break;\r
- case 16: // mine\r
- mine();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 17: // crystals\r
- usecrystals();\r
- break;\r
- case 18: // shuttle\r
- shuttle();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 19: // Planet list\r
- preport();\r
- break;\r
- case 20: // Status information\r
- srscan(2);\r
- break;\r
- case 21: // Game Report \r
- report(0);\r
- break;\r
- case 22: // use COMPUTER!\r
- eta();\r
- break;\r
- case 23:\r
- listCommands(TRUE);\r
- break;\r
- case 24: // Emergency exit\r
- clearscreen(); // Hide screen\r
- freeze(TRUE); // forced save\r
- exit(1); // And quick exit\r
- break;\r
- case 25:\r
- probe(); // Launch probe\r
- break;\r
- case 26: // Abandon Ship\r
- abandn();\r
- break;\r
- case 27: // Self Destruct\r
- dstrct();\r
- break;\r
- case 28: // Save Game\r
- freeze(FALSE);\r
- if (skill > 3)\r
- prout("WARNING--Frozen games produce no plaques!");\r
- break;\r
- case 29: // Try a desparation measure\r
- deathray();\r
- if (ididit) hitme = TRUE;\r
- break;\r
- case 30: // What do we want for debug???\r
-#ifdef DEBUG\r
- debugme();\r
-#endif\r
- break;\r
- case 31: // Call for help\r
- help();\r
- break;\r
- case 32:\r
- alldone = 1; // quit the game\r
-#ifdef DEBUG\r
- if (idebug) score();\r
-#endif\r
- break;\r
- case 33:\r
- helpme(); // get help\r
- break;\r
- }\r
- commandhook(commands[i], FALSE);\r
- for (;;) {\r
- if (alldone) break; // Game has ended\r
-#ifdef DEBUG\r
- if (idebug) prout("2500");\r
-#endif\r
- if (Time != 0.0) {\r
- events();\r
- if (alldone) break; // Events did us in\r
- }\r
- if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!\r
- atover(0);\r
- continue;\r
- }\r
- if (nenhere == 0) movetho();\r
- if (hitme && justin==0) {\r
- attack(2);\r
- if (alldone) break;\r
- if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA! \r
- atover(0);\r
- hitme = TRUE;\r
- continue;\r
- }\r
- }\r
- break;\r
- }\r
- if (alldone) break;\r
- }\r
-}\r
-\r
-\r
-int main(int argc, char **argv) {\r
- int i, option, usecurses = TRUE;\r
- while ((option = getopt(argc, argv, "t")) != -1) {\r
- switch (option) {\r
- case 't':\r
- usecurses = FALSE;\r
- break;\r
- default:\r
- fprintf(stderr, "usage: sst [-t] [startcommand...].\n");\r
- exit(0);\r
- }\r
- }\r
-\r
- iostart(usecurses);\r
- prelim(); \r
- line[0] = '\0';\r
- for (i = optind; i < argc; i++) {\r
- strcat(line, argv[i]);\r
- strcat(line, " ");\r
- }\r
- while (TRUE) { /* Play a game */\r
- setup(line[0] == '\0');\r
- if (alldone) {\r
- score();\r
- alldone = 0;\r
- }\r
- else makemoves();\r
- skip(2);\r
- stars();\r
- skip(1);\r
-\r
- if (tourn && alldone) {\r
- proutn("Do you want your score recorded?");\r
- if (ja()) {\r
- chew2();\r
- freeze(FALSE);\r
- }\r
- }\r
- proutn("Do you want to play again? ");\r
- if (!ja()) break;\r
-#ifdef SERGEEV\r
- setwnd(0);\r
- clrscr();\r
-#endif /* SERGEEV */\r
- }\r
- skip(1);\r
-#ifndef SERGEEV\r
- ioend();\r
-#endif /* SERGEEV */\r
- puts("May the Great Bird of the Galaxy roost upon your home planet.");\r
- exit(0);\r
-}\r
-\r
-\r
-void cramen(int i) {\r
- /* return an enemy */\r
- char *s;\r
- \r
- switch (i) {\r
- case IHR: s = "Romulan"; break;\r
- case IHK: s = "Klingon"; break;\r
- case IHC: s = "Commander"; break;\r
- case IHS: s = "Super-commander"; break;\r
- case IHSTAR: s = "Star"; break;\r
- case IHP: s = "Planet"; break;\r
- case IHB: s = "Starbase"; break;\r
- case IHBLANK: s = "Black hole"; break;\r
- case IHT: s = "Tholian"; break;\r
- case IHWEB: s = "Tholian web"; break;\r
- case IHQUEST: s = "Stranger"; break;\r
- default: s = "Unknown??"; break;\r
- }\r
- proutn(s);\r
-}\r
-\r
-char *cramlc(enum loctype key, int x, int y) {\r
- static char buf[32];\r
- buf[0] = '\0';\r
- if (key == quadrant) strcpy(buf, "Quadrant ");\r
- else if (key == sector) strcpy(buf, "Sector ");\r
- sprintf(buf+strlen(buf), "%d-%d", x, y);\r
- return buf;\r
-}\r
-\r
-void crmena(int i, int enemy, int key, int x, int y) {\r
- if (i == 1) proutn("***");\r
- cramen(enemy);\r
- proutn(" at ");\r
- proutn(cramlc(key, x, y));\r
-}\r
-\r
-void crmshp(void) {\r
- char *s;\r
- switch (ship) {\r
- case IHE: s = "Enterprise"; break;\r
- case IHF: s = "Faerie Queene"; break;\r
- default: s = "Ship???"; break;\r
- }\r
- proutn(s);\r
-}\r
-\r
-void stars(void) {\r
- prouts("******************************************************");\r
- skip(1);\r
-}\r
-\r
-double expran(double avrage) {\r
- return -avrage*log(1e-7 + Rand());\r
-}\r
-\r
-double Rand(void) {\r
- return rand()/(1.0 + (double)RAND_MAX);\r
-}\r
-\r
-void iran8(int *i, int *j) {\r
- *i = Rand()*8.0 + 1.0;\r
- *j = Rand()*8.0 + 1.0;\r
-}\r
-\r
-void iran10(int *i, int *j) {\r
- *i = Rand()*10.0 + 1.0;\r
- *j = Rand()*10.0 + 1.0;\r
-}\r
-\r
-void chew(void) {\r
- linep = line;\r
- *linep = 0;\r
-}\r
-\r
-void chew2(void) {\r
- /* return IHEOL next time */\r
- linep = line+1;\r
- *linep = 0;\r
-}\r
-\r
-int scan(void) {\r
- int i;\r
- char *cp;\r
-\r
- // Init result\r
- aaitem = 0.0;\r
- *citem = 0;\r
-\r
- // Read a line if nothing here\r
- if (*linep == 0) {\r
- if (linep != line) {\r
- chew();\r
- return IHEOL;\r
- }\r
- getline(line, sizeof(line));\r
- linep = line;\r
- }\r
- // Skip leading white space\r
- while (*linep == ' ') linep++;\r
- // Nothing left\r
- if (*linep == 0) {\r
- chew();\r
- return IHEOL;\r
- }\r
- if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {\r
- // treat as a number\r
- i = 0;\r
- if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {\r
- linep = line; // Invalid numbers are ignored\r
- *linep = 0;\r
- return IHEOL;\r
- }\r
- else {\r
- // skip to end\r
- linep += i;\r
- return IHREAL;\r
- }\r
- }\r
- // Treat as alpha\r
- cp = citem;\r
- while (*linep && *linep!=' ') {\r
- if ((cp - citem) < 9) *cp++ = tolower(*linep);\r
- linep++;\r
- }\r
- *cp = 0;\r
- return IHALPHA;\r
-}\r
-\r
-int ja(void) {\r
- chew();\r
- while (TRUE) {\r
- scan();\r
- chew();\r
- if (*citem == 'y') return TRUE;\r
- if (*citem == 'n') return FALSE;\r
- proutn("Please answer with \"Y\" or \"N\": ");\r
- }\r
-}\r
-\r
-void huh(void) {\r
- chew();\r
- skip(1);\r
- prout("Beg your pardon, Captain?");\r
-}\r
-\r
-int isit(char *s) {\r
- /* New function -- compares s to scaned citem and returns true if it\r
- matches to the length of s */\r
-\r
- return strncmp(s, citem, max(1, strlen(citem))) == 0;\r
-\r
-}\r
-\r
-#ifdef DEBUG\r
-void debugme(void) {\r
- proutn("Reset levels? ");\r
- if (ja() != 0) {\r
- if (energy < inenrg) energy = inenrg;\r
- shield = inshld;\r
- torps = intorps;\r
- lsupres = inlsr;\r
- }\r
- proutn("Reset damage? ");\r
- if (ja() != 0) {\r
- int i;\r
- for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;\r
- stdamtim = 1e30;\r
- }\r
- proutn("Toggle idebug? ");\r
- if (ja() != 0) {\r
- idebug = !idebug;\r
- if (idebug) prout("Debug output ON");\r
- else prout("Debug output OFF");\r
- }\r
- proutn("Cause selective damage? ");\r
- if (ja() != 0) {\r
- int i, key;\r
- for (i=1; i <= NDEVICES; i++) {\r
- proutn("Kill ");\r
- proutn(device[i]);\r
- proutn("? ");\r
- chew();\r
- key = scan();\r
- if (key == IHALPHA && isit("y")) {\r
- damage[i] = 10.0;\r
- if (i == DRADIO) stdamtim = game.state.date;\r
- }\r
- }\r
- }\r
- proutn("Examine/change events? ");\r
- if (ja() != 0) {\r
- int i;\r
- for (i = 1; i < NEVENTS; i++) {\r
- int key;\r
- if (future[i] == 1e30) continue;\r
- switch (i) {\r
- case FSNOVA: proutn("Supernova "); break;\r
- case FTBEAM: proutn("T Beam "); break;\r
- case FSNAP: proutn("Snapshot "); break;\r
- case FBATTAK: proutn("Base Attack "); break;\r
- case FCDBAS: proutn("Base Destroy "); break;\r
- case FSCMOVE: proutn("SC Move "); break;\r
- case FSCDBAS: proutn("SC Base Destroy "); break;\r
- }\r
- proutn("%.2f", future[i]-game.state.date);\r
- chew();\r
- proutn(" ?");\r
- key = scan();\r
- if (key == IHREAL) {\r
- future[i] = game.state.date + aaitem;\r
- }\r
- }\r
- chew();\r
- }\r
-}\r
- \r
-\r
-#endif\r
+#define INCLUDED // Define externs here
+#include <ctype.h>
+#include <getopt.h>
+#include "sst.h"
+
+#ifndef SSTDOC
+#define SSTDOC "sst.doc"
+#endif
+
+static char line[128], *linep = line;
+
+/*
+
+Here are Tom Almy's changes:
+
+ Compared to original version, I've changed the "help" command to
+ "call" and the "terminate" command to "quit" to better match
+ user expectations. The DECUS version apparently made those changes
+ as well as changing "freeze" to "save". However I like "freeze".
+
+ When I got a later version of Super Star Trek that I was converting
+ from, I added the emexit command.
+
+ That later version also mentions srscan and lrscan working when
+ docked (using the starbase's scanners), so I made some changes here
+ to do this (and indicating that fact to the player), and then realized
+ the base would have a subspace radio as well -- doing a Chart when docked
+ updates the star chart, and all radio reports will be heard. The Dock
+ command will also give a report if a base is under attack.
+
+ Movecom no longer reports movement if sensors are damaged so you wouldn't
+ otherwise know it.
+
+ Also added:
+
+ 1. Better base positioning at startup
+
+ 2. Deathray improvement (but keeping original failure alternatives)
+
+ 3. Tholian Web.
+
+ 4. Enemies can ram the Enterprise. Regular Klingons and Romulans can
+ move in Expert and Emeritus games. This code could use improvement.
+
+ 5. The deep space probe looks interesting! DECUS version
+
+ 6. Perhaps cloaking to be added later? BSD version
+
+Here are Stas Sergeev's changes (controlled by the proprocessor symbol
+SERGEEV, not yet completely merged):
+
+ 1. The Space Thingy can be shoved, if you it ram, and can fire back if
+ fired upon.
+
+ 1 The Tholian can be hit with phasers
+
+ 2. When you are docked, base covers you with an almost invincible shields
+ (a commander can still ram you, or a Romulan can destroy the base,
+ or a SCom can even succeed with direct attack IIRC, but this rarely
+ happens).
+
+ 3. SCom can't escape from you if no more enemies remain (without this,
+ chasing SCom can take an eternity).
+
+ 4. Probe target you enter is now the destination quadrant. Before I don't
+ remember what it was, but it was something I had difficulty using)
+
+ 5. Secret password is now autogenerated.
+
+ 6. "Plaque" is adjusted for A4 paper:)
+
+ 7. Phasers now tells you how much energy needed, but only if the computer
+ is alive.
+
+ 8. Planets are auto-scanned when you enter the quadrant.
+
+ 9. Mining or using crystals in presense of enemy now yields an attack.
+ There are other minor adjustments to what yields an attack
+ and what does not.
+
+ 10. Ramming a black hole is no longer instant death. There is a
+ chance you might get timewarped instead.
+
+ */
+
+static char *commands[] = {
+ "srscan",
+ "lrscan",
+ "phasers",
+ "photons",
+ "move",
+ "shields",
+ "dock",
+ "damages",
+ "chart",
+ "impulse",
+ "rest",
+ "warp",
+ "status",
+ "sensors",
+ "orbit",
+ "transport",
+ "mine",
+ "crystals",
+ "shuttle",
+ "planets",
+ "request",
+ "report",
+ "computer",
+ "commands",
+ "emexit",
+ "probe",
+ "abandon",
+ "destruct",
+ "freeze",
+ "deathray",
+ "debug",
+ "call",
+ "quit",
+ "help"
+};
+#define NUMCOMMANDS sizeof(commands)/sizeof(commands[0])
+
+static void listCommands(int x) {
+ prout(" SRSCAN MOVE PHASERS CALL\n"
+ " STATUS IMPULSE PHOTONS ABANDON\n"
+ " LRSCAN WARP SHIELDS DESTRUCT\n"
+ " CHART REST DOCK QUIT\n"
+ " DAMAGES REPORT SENSORS ORBIT\n"
+ " TRANSPORT MINE CRYSTALS SHUTTLE\n"
+ " PLANETS REQUEST DEATHRAY FREEZE\n"
+ " COMPUTER EMEXIT PROBE COMMANDS");
+ if (x) prout(" HELP");
+}
+
+#ifdef SERGEEV
+void setwnd(short wndnum){
+ int cury;
+ cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;
+ if ((curwnd==0)&&(wndnum!=0)) clrscr();
+ window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);
+ if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){
+ gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);
+ skip(1);
+ }
+ curwnd=wndnum;
+ gotoxy(1,cury);
+}
+#endif /* SERGEEV */
+
+static void helpme(void) {
+ int i, j;
+ char cmdbuf[32], *cp;
+ char linebuf[132];
+ FILE *fp;
+ /* Give help on commands */
+ int key;
+ key = scan();
+ while (TRUE) {
+ if (key == IHEOL) {
+#ifdef SERGEEV
+ setwnd(5);
+#endif /* SERGEEV */
+ proutn("Help on what command? ");
+ key = scan();
+ }
+#ifdef SERGEEV
+ setwnd(4);
+#endif /* SERGEEV */
+ if (key == IHEOL) return;
+ for (i = 0; i < NUMCOMMANDS; i++) {
+ if (strcmp(commands[i], citem)==0) break;
+ }
+ if (i != NUMCOMMANDS) break;
+ skip(1);
+ prout("Valid commands:");
+ listCommands(FALSE);
+ key = IHEOL;
+ chew();
+ skip(1);
+ }
+ if (i == 23) {
+ strcpy(cmdbuf, " ABBREV");
+ }
+ else {
+ for (j = 0; commands[i][j]; j++)
+ cmdbuf[j] = toupper(commands[i][j]);
+ cmdbuf[j] = '\0';
+ }
+ fp = fopen(SSTDOC, "r");
+ if (fp == NULL) {
+ prout("Spock- \"Captain, that information is missing from the");
+ prout(" computer. You need to find SST.DOC and put it in the");
+ prout(" current directory.\"");
+ return;
+ }
+ for (;;) {
+ if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
+ prout("Spock- \"Captain, there is no information on that command.\"");
+ fclose(fp);
+ return;
+ }
+ if (linebuf[0] == '%' && linebuf[1] == '%'&& linebuf[2] == ' ') {
+ for (cp = linebuf+3; isspace(*cp); cp++)
+ continue;
+ linebuf[strlen(linebuf)-1] = '\0';
+ if (strcmp(cp, cmdbuf) == 0)
+ break;
+ }
+ }
+
+ skip(1);
+ prout("Spock- \"Captain, I've found the following information:\"");
+ skip(1);
+
+ while (fgets(linebuf, sizeof(linebuf),fp)) {
+ if (strstr(linebuf, "******"))
+ break;
+ proutc(linebuf);
+ }
+ fclose(fp);
+}
+
+#ifdef SERGEEV
+void drawmaps(short l){
+ _setcursortype(_NOCURSOR);
+ if (l==1) sensor();
+ if (l!=2) setwnd(1);
+ gotoxy(1,1);
+ strcpy(line,"s");
+ srscan(1);
+ if (l!=2){
+ setwnd(2);
+ clrscr();
+ srscan(2);
+ setwnd(3);
+ clrscr();
+ strcpy(line,"l");
+ lrscan();
+ _setcursortype(_NORMALCURSOR);
+ }
+}
+#endif /* SERGEEV */
+
+static void makemoves(void) {
+ int i, hitme;
+ while (TRUE) { /* command loop */
+ hitme = FALSE;
+ justin = 0;
+ Time = 0.0;
+ i = -1;
+ while (TRUE) { /* get a command */
+ chew();
+ skip(1);
+ proutn("COMMAND> ");
+ if (scan() == IHEOL) continue;
+ for (i=0; i < 26; i++)
+ if (isit(commands[i]))
+ break;
+ if (i < 26) break;
+ for (; i < NUMCOMMANDS; i++)
+ if (strcmp(commands[i], citem) == 0) break;
+ if (i < NUMCOMMANDS) break;
+
+ if (skill <= 2) {
+ prout("UNRECOGNIZED COMMAND. LEGAL COMMANDS ARE:");
+ listCommands(TRUE);
+ }
+ else prout("UNRECOGNIZED COMMAND.");
+ }
+ commandhook(commands[i], TRUE);
+ switch (i) { /* command switch */
+ case 0: // srscan
+ srscan(1);
+ break;
+ case 1: // lrscan
+ lrscan();
+ break;
+ case 2: // phasers
+ phasers();
+ if (ididit) hitme = TRUE;
+ break;
+ case 3: // photons
+ photon();
+ if (ididit) hitme = TRUE;
+ break;
+ case 4: // move
+ warp(1);
+ break;
+ case 5: // shields
+ doshield(1);
+ if (ididit) {
+ attack(2);
+ shldchg = 0;
+ }
+ break;
+ case 6: // dock
+ dock(1);
+ if (ididit) attack(0);
+ break;
+ case 7: // damages
+ dreprt();
+ break;
+ case 8: // chart
+ chart(0);
+ break;
+ case 9: // impulse
+ impuls();
+ break;
+ case 10: // rest
+ wait();
+ if (ididit) hitme = TRUE;
+ break;
+ case 11: // warp
+ setwrp();
+ break;
+ case 12: // status
+ srscan(3);
+ break;
+ case 13: // sensors
+ sensor();
+ break;
+ case 14: // orbit
+ orbit();
+ if (ididit) hitme = TRUE;
+ break;
+ case 15: // transport "beam"
+ beam();
+ break;
+ case 16: // mine
+ mine();
+ if (ididit) hitme = TRUE;
+ break;
+ case 17: // crystals
+ usecrystals();
+ break;
+ case 18: // shuttle
+ shuttle();
+ if (ididit) hitme = TRUE;
+ break;
+ case 19: // Planet list
+ preport();
+ break;
+ case 20: // Status information
+ srscan(2);
+ break;
+ case 21: // Game Report
+ report(0);
+ break;
+ case 22: // use COMPUTER!
+ eta();
+ break;
+ case 23:
+ listCommands(TRUE);
+ break;
+ case 24: // Emergency exit
+ clearscreen(); // Hide screen
+ freeze(TRUE); // forced save
+ exit(1); // And quick exit
+ break;
+ case 25:
+ probe(); // Launch probe
+ break;
+ case 26: // Abandon Ship
+ abandn();
+ break;
+ case 27: // Self Destruct
+ dstrct();
+ break;
+ case 28: // Save Game
+ freeze(FALSE);
+ if (skill > 3)
+ prout("WARNING--Frozen games produce no plaques!");
+ break;
+ case 29: // Try a desparation measure
+ deathray();
+ if (ididit) hitme = TRUE;
+ break;
+ case 30: // What do we want for debug???
+#ifdef DEBUG
+ debugme();
+#endif
+ break;
+ case 31: // Call for help
+ help();
+ break;
+ case 32:
+ alldone = 1; // quit the game
+#ifdef DEBUG
+ if (idebug) score();
+#endif
+ break;
+ case 33:
+ helpme(); // get help
+ break;
+ }
+ commandhook(commands[i], FALSE);
+ for (;;) {
+ if (alldone) break; // Game has ended
+#ifdef DEBUG
+ if (idebug) prout("2500");
+#endif
+ if (Time != 0.0) {
+ events();
+ if (alldone) break; // Events did us in
+ }
+ if (game.state.galaxy[quadx][quady] == 1000) { // Galaxy went Nova!
+ atover(0);
+ continue;
+ }
+ if (nenhere == 0) movetho();
+ if (hitme && justin==0) {
+ attack(2);
+ if (alldone) break;
+ if (game.state.galaxy[quadx][quady] == 1000) { // went NOVA!
+ atover(0);
+ hitme = TRUE;
+ continue;
+ }
+ }
+ break;
+ }
+ if (alldone) break;
+ }
+}
+
+
+int main(int argc, char **argv) {
+ int i, option, usecurses = TRUE;
+ while ((option = getopt(argc, argv, "t")) != -1) {
+ switch (option) {
+ case 't':
+ usecurses = FALSE;
+ break;
+ default:
+ fprintf(stderr, "usage: sst [-t] [startcommand...].\n");
+ exit(0);
+ }
+ }
+
+ iostart(usecurses);
+ prelim();
+ line[0] = '\0';
+ for (i = optind; i < argc; i++) {
+ strcat(line, argv[i]);
+ strcat(line, " ");
+ }
+ while (TRUE) { /* Play a game */
+ setup(line[0] == '\0');
+ if (alldone) {
+ score();
+ alldone = 0;
+ }
+ else makemoves();
+ skip(2);
+ stars();
+ skip(1);
+
+ if (tourn && alldone) {
+ proutn("Do you want your score recorded?");
+ if (ja()) {
+ chew2();
+ freeze(FALSE);
+ }
+ }
+ proutn("Do you want to play again? ");
+ if (!ja()) break;
+#ifdef SERGEEV
+ setwnd(0);
+ clrscr();
+#endif /* SERGEEV */
+ }
+ skip(1);
+#ifndef SERGEEV
+ ioend();
+#endif /* SERGEEV */
+ puts("May the Great Bird of the Galaxy roost upon your home planet.");
+ exit(0);
+}
+
+
+void cramen(int i) {
+ /* return an enemy */
+ char *s;
+
+ switch (i) {
+ case IHR: s = "Romulan"; break;
+ case IHK: s = "Klingon"; break;
+ case IHC: s = "Commander"; break;
+ case IHS: s = "Super-commander"; break;
+ case IHSTAR: s = "Star"; break;
+ case IHP: s = "Planet"; break;
+ case IHB: s = "Starbase"; break;
+ case IHBLANK: s = "Black hole"; break;
+ case IHT: s = "Tholian"; break;
+ case IHWEB: s = "Tholian web"; break;
+ case IHQUEST: s = "Stranger"; break;
+ default: s = "Unknown??"; break;
+ }
+ proutn(s);
+}
+
+char *cramlc(enum loctype key, int x, int y) {
+ static char buf[32];
+ buf[0] = '\0';
+ if (key == quadrant) strcpy(buf, "Quadrant ");
+ else if (key == sector) strcpy(buf, "Sector ");
+ sprintf(buf+strlen(buf), "%d-%d", x, y);
+ return buf;
+}
+
+void crmena(int i, int enemy, int key, int x, int y) {
+ if (i == 1) proutn("***");
+ cramen(enemy);
+ proutn(" at ");
+ proutn(cramlc(key, x, y));
+}
+
+void crmshp(void) {
+ char *s;
+ switch (ship) {
+ case IHE: s = "Enterprise"; break;
+ case IHF: s = "Faerie Queene"; break;
+ default: s = "Ship???"; break;
+ }
+ proutn(s);
+}
+
+void stars(void) {
+ prouts("******************************************************");
+ skip(1);
+}
+
+double expran(double avrage) {
+ return -avrage*log(1e-7 + Rand());
+}
+
+double Rand(void) {
+ return rand()/(1.0 + (double)RAND_MAX);
+}
+
+void iran8(int *i, int *j) {
+ *i = Rand()*8.0 + 1.0;
+ *j = Rand()*8.0 + 1.0;
+}
+
+void iran10(int *i, int *j) {
+ *i = Rand()*10.0 + 1.0;
+ *j = Rand()*10.0 + 1.0;
+}
+
+void chew(void) {
+ linep = line;
+ *linep = 0;
+}
+
+void chew2(void) {
+ /* return IHEOL next time */
+ linep = line+1;
+ *linep = 0;
+}
+
+int scan(void) {
+ int i;
+ char *cp;
+
+ // Init result
+ aaitem = 0.0;
+ *citem = 0;
+
+ // Read a line if nothing here
+ if (*linep == 0) {
+ if (linep != line) {
+ chew();
+ return IHEOL;
+ }
+ getline(line, sizeof(line));
+ linep = line;
+ }
+ // Skip leading white space
+ while (*linep == ' ') linep++;
+ // Nothing left
+ if (*linep == 0) {
+ chew();
+ return IHEOL;
+ }
+ if (isdigit(*linep) || *linep=='+' || *linep=='-' || *linep=='.') {
+ // treat as a number
+ i = 0;
+ if (sscanf(linep, "%lf%n", &aaitem, &i) < 1) {
+ linep = line; // Invalid numbers are ignored
+ *linep = 0;
+ return IHEOL;
+ }
+ else {
+ // skip to end
+ linep += i;
+ return IHREAL;
+ }
+ }
+ // Treat as alpha
+ cp = citem;
+ while (*linep && *linep!=' ') {
+ if ((cp - citem) < 9) *cp++ = tolower(*linep);
+ linep++;
+ }
+ *cp = 0;
+ return IHALPHA;
+}
+
+int ja(void) {
+ chew();
+ while (TRUE) {
+ scan();
+ chew();
+ if (*citem == 'y') return TRUE;
+ if (*citem == 'n') return FALSE;
+ proutn("Please answer with \"Y\" or \"N\": ");
+ }
+}
+
+void huh(void) {
+ chew();
+ skip(1);
+ prout("Beg your pardon, Captain?");
+}
+
+int isit(char *s) {
+ /* New function -- compares s to scaned citem and returns true if it
+ matches to the length of s */
+
+ return strncmp(s, citem, max(1, strlen(citem))) == 0;
+
+}
+
+#ifdef DEBUG
+void debugme(void) {
+ proutn("Reset levels? ");
+ if (ja() != 0) {
+ if (energy < inenrg) energy = inenrg;
+ shield = inshld;
+ torps = intorps;
+ lsupres = inlsr;
+ }
+ proutn("Reset damage? ");
+ if (ja() != 0) {
+ int i;
+ for (i=0; i <= NDEVICES; i++) if (damage[i] > 0.0) damage[i] = 0.0;
+ stdamtim = 1e30;
+ }
+ proutn("Toggle idebug? ");
+ if (ja() != 0) {
+ idebug = !idebug;
+ if (idebug) prout("Debug output ON");
+ else prout("Debug output OFF");
+ }
+ proutn("Cause selective damage? ");
+ if (ja() != 0) {
+ int i, key;
+ for (i=1; i <= NDEVICES; i++) {
+ proutn("Kill ");
+ proutn(device[i]);
+ proutn("? ");
+ chew();
+ key = scan();
+ if (key == IHALPHA && isit("y")) {
+ damage[i] = 10.0;
+ if (i == DRADIO) stdamtim = game.state.date;
+ }
+ }
+ }
+ proutn("Examine/change events? ");
+ if (ja() != 0) {
+ int i;
+ for (i = 1; i < NEVENTS; i++) {
+ int key;
+ if (future[i] == 1e30) continue;
+ switch (i) {
+ case FSNOVA: proutn("Supernova "); break;
+ case FTBEAM: proutn("T Beam "); break;
+ case FSNAP: proutn("Snapshot "); break;
+ case FBATTAK: proutn("Base Attack "); break;
+ case FCDBAS: proutn("Base Destroy "); break;
+ case FSCMOVE: proutn("SC Move "); break;
+ case FSCDBAS: proutn("SC Base Destroy "); break;
+ }
+ proutn("%.2f", future[i]-game.state.date);
+ chew();
+ proutn(" ?");
+ key = scan();
+ if (key == IHREAL) {
+ future[i] = game.state.date + aaitem;
+ }
+ }
+ chew();
+ }
+}
+
+
+#endif
-#include <stdio.h>\r
-#include <math.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#ifndef INCLUDED\r
-#define EXTERN extern\r
-#else\r
-#define EXTERN\r
-#endif\r
-\r
-#define min(x, y) ((x)<(y)?(x):(y))\r
-#define max(x, y) ((x)>(y)?(x):(y))\r
-\r
-// #define DEBUG\r
-\r
-#define NDEVICES (15) // Number of devices\r
-#define PHASEFAC (2.0)\r
-#define PLNETMAX (10)\r
-#define NEVENTS (8)\r
-\r
-typedef struct {\r
- int x; /* Quadrant location of planet */\r
- int y;\r
- enum {M=0, N=1, O=2} pclass;\r
- int crystals; /* has crystals */\r
- enum {unknown, known, shuttle_down} known;\r
-} planet;\r
-\r
-#define DESTROY(pl) memset(pl, '\0', sizeof(planet))\r
-\r
-typedef struct {\r
- int snap, // snapshot taken\r
- remkl, // remaining klingons\r
- remcom, // remaining commanders\r
- rembase, // remaining bases\r
- starkl, // destroyed stars\r
- basekl, // destroyed bases\r
- killk, // Klingons killed\r
- killc, // commanders killed\r
- galaxy[9][9], // The Galaxy (subscript 0 not used)\r
- cx[11],cy[11], // Commander quadrant coordinates\r
- baseqx[6], // Base quadrant X\r
- baseqy[6], // Base quadrant Y\r
- newstuf[9][9], // Extended galaxy goodies\r
- isx, isy, // Coordinate of Super Commander\r
- nscrem, // remaining super commanders\r
- nromkl, // Romulans killed\r
- nromrem, // Romulans remaining\r
- nsckill, // super commanders killed\r
- nplankl; // destroyed planets\r
- planet plnets[PLNETMAX]; // Planet information\r
- double date, // stardate\r
- remres, // remaining resources\r
- remtime; // remaining time\r
-} snapshot; // Data that is snapshot\r
-\r
-// Scalar variables that are needed for freezing the game\r
-// are placed in a structure. #defines are used to access by their\r
-// original names. Gee, I could have done this with the d structure,\r
-// but I just didn't think of it back when I started.\r
-\r
-#define SSTMAGIC "SST2.0\n"\r
-\r
-EXTERN struct {\r
- char magic[sizeof(SSTMAGIC)];\r
- snapshot state;\r
- snapshot snapsht;\r
- char quad[11][11]; // contents of our quadrant\r
- double kpower[21]; // enemy energy levels\r
- double kdist[21]; // enemy distances\r
- double kavgd[21]; // average distances\r
- double damage[NDEVICES+1]; // damage encountered\r
- double future[NEVENTS+1]; // future events\r
- char passwd[10]; // Self Destruct password\r
- int kx[21]; // enemy sector locations\r
- int ky[21];\r
- int starch[9][9]; // star chart\r
- /* members with macro definitions start here */\r
- int inkling,\r
- inbase,\r
- incom,\r
- instar,\r
- intorps,\r
- condit,\r
- torps,\r
- ship,\r
- quadx,\r
- quady,\r
- sectx,\r
- secty,\r
- length,\r
- skill,\r
- basex,\r
- basey,\r
- klhere,\r
- comhere,\r
- casual,\r
- nhelp,\r
- nkinks,\r
- ididit,\r
- gamewon,\r
- alive,\r
- justin,\r
- alldone,\r
- shldchg,\r
- thingx,\r
- thingy,\r
- plnetx,\r
- plnety,\r
- inorbit,\r
- landed,\r
- iplnet,\r
- imine,\r
- inplan,\r
- nenhere,\r
- ishere,\r
- neutz,\r
- irhere,\r
- icraft,\r
- ientesc,\r
- iscraft,\r
- isatb,\r
- iscate,\r
-#ifdef DEBUG\r
- idebug,\r
-#endif\r
- iattak,\r
- icrystl,\r
- tourn,\r
- thawed,\r
- batx,\r
- baty,\r
- ithere,\r
- iqhere,\r
- iqengry,\r
- ithx,\r
- ithy,\r
- iseenit,\r
- probecx,\r
- probecy,\r
- proben,\r
- isarmed,\r
- nprobes;\r
- double inresor,\r
- intime,\r
- inenrg,\r
- inshld,\r
- inlsr,\r
- indate,\r
- energy,\r
- shield,\r
- shldup,\r
- warpfac,\r
- wfacsq,\r
- lsupres,\r
- dist,\r
- direc,\r
- Time,\r
- docfac,\r
- resting,\r
- damfac,\r
- stdamtim,\r
- cryprob,\r
- probex,\r
- probey,\r
- probeinx,\r
- probeiny;\r
-} game;\r
-\r
-#define inkling game.inkling // Initial number of klingons\r
-#define inbase game.inbase // Initial number of bases\r
-#define incom game.incom // Initian number of commanders\r
-#define instar game.instar // Initial stars\r
-#define intorps game.intorps // Initial/Max torpedoes\r
-#define condit game.condit // Condition (red, yellow, green docked)\r
-#define torps game.torps // number of torpedoes\r
-#define ship game.ship // Ship type -- 'E' is Enterprise\r
-#define quadx game.quadx // where we are\r
-#define quady game.quady //\r
-#define sectx game.sectx // where we are\r
-#define secty game.secty //\r
-#define length game.length // length of game\r
-#define skill game.skill // skill level\r
-#define basex game.basex // position of base in current quad\r
-#define basey game.basey //\r
-#define klhere game.klhere // klingons here\r
-#define comhere game.comhere // commanders here\r
-#define casual game.casual // causalties\r
-#define nhelp game.nhelp // calls for help\r
-#define nkinks game.nkinks //\r
-#define ididit game.ididit // Action taken -- allows enemy to attack\r
-#define gamewon game.gamewon // Finished!\r
-#define alive game.alive // We are alive (not killed)\r
-#define justin game.justin // just entered quadrant\r
-#define alldone game.alldone // game is now finished\r
-#define shldchg game.shldchg // shield is changing (affects efficiency)\r
-#define thingx game.thingx // location of strange object in galaxy\r
-#define thingy game.thingy //\r
-#define plnetx game.plnetx // location of planet in quadrant\r
-#define plnety game.plnety //\r
-#define inorbit game.inorbit // orbiting\r
-#define landed game.landed // party on planet (1), on ship (-1)\r
-#define iplnet game.iplnet // planet # in quadrant\r
-#define imine game.imine // mining\r
-#define inplan game.inplan // initial planets\r
-#define nenhere game.nenhere // Number of enemies in quadrant\r
-#define ishere game.ishere // Super-commander in quandrant\r
-#define neutz game.neutz // Romulan Neutral Zone\r
-#define irhere game.irhere // Romulans in quadrant\r
-#define iqhere game.iqhere // Thing in quadrant\r
-#define iqengry game.iqengry // Thing attacking\r
-#define icraft game.icraft // Kirk in Galileo\r
-#define ientesc game.ientesc // Attempted escape from supercommander\r
-#define iscraft game.iscraft // =1 if craft on ship, -1 if removed from game\r
-#define isatb game.isatb // =1 if SuperCommander is attacking base\r
-#define iscate game.iscate // Super Commander is here\r
-#ifdef DEBUG\r
-#define idebug game.idebug // Debug mode\r
-#endif\r
-#define iattak game.iattak // attack recursion elimination (was cracks[4])\r
-#define icrystl game.icrystl // dilithium crystals aboard\r
-#define tourn game.tourn // Tournament number\r
-#define thawed game.thawed // Thawed game\r
-#define batx game.batx // Base coordinates being attacked\r
-#define baty game.baty //\r
-#define ithere game.ithere // Tholean is here \r
-#define ithx game.ithx // coordinates of tholean\r
-#define ithy game.ithy\r
-#define iseenit game.iseenit // Seen base attack report\r
-#define inresor game.inresor // initial resources\r
-#define intime game.intime // initial time\r
-#define inenrg game.inenrg // Initial/Max Energy\r
-#define inshld game.inshld // Initial/Max Shield\r
-#define inlsr game.inlsr // initial life support resources\r
-#define indate game.indate // Initial date\r
-#define energy game.energy // Energy level\r
-#define shield game.shield // Shield level\r
-#define shldup game.shldup // Shields are up\r
-#define warpfac game.warpfac // Warp speed\r
-#define wfacsq game.wfacsq // squared warp factor\r
-#define lsupres game.lsupres // life support reserves\r
-#define dist game.dist // movement distance\r
-#define direc game.direc // movement direction\r
-#define Time game.Time // time taken by current operation\r
-#define docfac game.docfac // repair factor when docking (constant?)\r
-#define resting game.resting // rest time\r
-#define damfac game.damfac // damage factor\r
-#define stdamtim game.stdamtim // time that star chart was damaged\r
-#define cryprob game.cryprob // probability that crystal will work\r
-#define probex game.probex // location of probe\r
-#define probey game.probey\r
-#define probecx game.probecx // current probe quadrant\r
-#define probecy game.probecy \r
-#define probeinx game.probeinx // Probe x,y increment\r
-#define probeiny game.probeiny \r
-#define proben game.proben // number of moves for probe\r
-#define isarmed game.isarmed // Probe is armed\r
-#define nprobes game.nprobes // number of probes available\r
-\r
-/* the following global state doesn't need to be saved */\r
-EXTERN char *device[NDEVICES+1];\r
-EXTERN int iscore, iskill; // Common PLAQ\r
-EXTERN double perdate;\r
-EXTERN double aaitem;\r
-EXTERN char citem[10];\r
-\r
-typedef enum {FWON, FDEPLETE, FLIFESUP, FNRG, FBATTLE,\r
- FNEG3, FNOVA, FSNOVAED, FABANDN, FDILITHIUM,\r
- FMATERIALIZE, FPHASER, FLOST, FMINING, FDPLANET,\r
- FPNOVA, FSSC, FSTRACTOR, FDRAY, FTRIBBLE,\r
- FHOLE} FINTYPE ;\r
-enum loctype {neither, quadrant, sector};\r
-\r
-/* Define devices */\r
-#define DSRSENS 1\r
-#define DLRSENS 2\r
-#define DPHASER 3\r
-#define DPHOTON 4\r
-#define DLIFSUP 5\r
-#define DWARPEN 6\r
-#define DIMPULS 7\r
-#define DSHIELD 8\r
-#define DRADIO 9\r
-#define DSHUTTL 10\r
-#define DCOMPTR 11\r
-#define DTRANSP 12\r
-#define DSHCTRL 13\r
-#define DDRAY 14 // Added deathray\r
-#define DDSP 15 // Added deep space probe\r
-\r
-/* Define future events */\r
-#define FSPY 0 // Spy event happens always (no future[] entry)\r
- // can cause SC to tractor beam Enterprise\r
-#define FSNOVA 1 // Supernova\r
-#define FTBEAM 2 // Commander tractor beams Enterprise\r
-#define FSNAP 3 // Snapshot for time warp\r
-#define FBATTAK 4 // Commander attacks base\r
-#define FCDBAS 5 // Commander destroys base\r
-#define FSCMOVE 6 // Supercommander moves (might attack base)\r
-#define FSCDBAS 7 // Supercommander destroys base\r
-#define FDSPROB 8 // Move deep space probe\r
-\r
-#ifdef INCLUDED\r
-char *device[NDEVICES+1] = {\r
- "",\r
- "S. R. Sensors",\r
- "L. R. Sensors",\r
- "Phasers",\r
- "Photon Tubes",\r
- "Life Support",\r
- "Warp Engines",\r
- "Impulse Engines",\r
- "Shields",\r
- "Subspace Radio",\r
- "Shuttle Craft",\r
- "Computer",\r
- "Transporter",\r
- "Shield Control",\r
- "Death Ray",\r
- "D. S. Probe"}; \r
-#endif\r
-\r
-#ifndef TRUE\r
-#define TRUE (1)\r
-#define FALSE (0)\r
-#endif\r
-\r
-#define IHR 'R'\r
-#define IHK 'K'\r
-#define IHC 'C'\r
-#define IHS 'S'\r
-#define IHSTAR '*'\r
-#define IHP 'P'\r
-#define IHB 'B'\r
-#define IHBLANK ' '\r
-#define IHDOT '.'\r
-#define IHQUEST '?'\r
-#define IHE 'E'\r
-#define IHF 'F'\r
-#define IHT 'T'\r
-#define IHWEB '#'\r
-#define IHGREEN 'G'\r
-#define IHYELLOW 'Y'\r
-#define IHRED 'R'\r
-#define IHDOCKED 'D'\r
-#define IHDEAD 'Z'\r
-#define IHMATER0 '-'\r
-#define IHMATER1 'o'\r
-#define IHMATER2 '0'\r
-\r
-\r
-/* Function prototypes */\r
-void prelim(void);\r
-void attack(int);\r
-int choose(int);\r
-void setup(int);\r
-void score(void);\r
-void atover(int);\r
-void srscan(int);\r
-void lrscan(void);\r
-void phasers(void);\r
-void photon(void);\r
-void warp(int);\r
-void doshield(int);\r
-void dock(int);\r
-void dreprt(void);\r
-void chart(int);\r
-void impuls(void);\r
-void wait(void);\r
-void setwrp(void);\r
-void events(void);\r
-void report(int);\r
-void eta(void);\r
-void help(void);\r
-void abandn(void);\r
-void finish(FINTYPE);\r
-void dstrct(void);\r
-void kaboom(void);\r
-void freeze(int);\r
-int thaw(void);\r
-void plaque(void);\r
-int scan(void);\r
-#define IHEOL (0)\r
-#define IHALPHA (1)\r
-#define IHREAL (2)\r
-void chew(void);\r
-void chew2(void);\r
-void skip(int);\r
-void prout(char *, ...);\r
-void proutn(char *, ...);\r
-void stars(void);\r
-void newqad(int);\r
-int ja(void);\r
-void cramen(int);\r
-void crmshp(void);\r
-char *cramlc(enum loctype, int, int);\r
-double expran(double);\r
-double Rand(void);\r
-void iran8(int *, int *);\r
-void iran10(int *, int *);\r
-#define square(i) ((i)*(i))\r
-void dropin(int, int*, int*);\r
-void newcnd(void);\r
-void sortkl(void);\r
-void imove(void);\r
-void ram(int, int, int, int);\r
-void crmena(int, int, int, int, int);\r
-void deadkl(int, int, int, int, int);\r
-void timwrp(void);\r
-void movcom(void);\r
-void torpedo(double, double, int, int, double *, int);\r
-void huh(void);\r
-void pause_game(int);\r
-void nova(int, int);\r
-void snova(int, int);\r
-void scom(int *);\r
-void hittem(double *);\r
-void prouts(char *, ...);\r
-void proutc(char *);\r
-int isit(char *);\r
-void preport(void);\r
-void orbit(void);\r
-void sensor(void);\r
-#ifdef SERGEEV\r
-void drawmaps(short);\r
-#endif /* SERGEEV */\r
-void beam(void);\r
-void mine(void);\r
-void usecrystals(void);\r
-void shuttle(void);\r
-void deathray(void);\r
-void debugme(void);\r
-void attakreport(int);\r
-void movetho(void);\r
-void probe(void);\r
-void clearscreen(void);\r
-void iostart(int);\r
-void ioend(void);\r
-void getline(char *, int);\r
-void commandhook(char *, int);\r
-\r
-#ifdef SERGEEV\r
-typedef struct {\r
- int wndleft,wndtop,wndright,wndbottom;\r
-} wnd;\r
-extern wnd wnds[6];\r
-#endif /* SERGEEV */\r
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef INCLUDED
+#define EXTERN extern
+#else
+#define EXTERN
+#endif
+
+#define min(x, y) ((x)<(y)?(x):(y))
+#define max(x, y) ((x)>(y)?(x):(y))
+
+// #define DEBUG
+
+#define NDEVICES (15) // Number of devices
+#define PHASEFAC (2.0)
+#define PLNETMAX (10)
+#define NEVENTS (8)
+
+typedef struct {
+ int x; /* Quadrant location of planet */
+ int y;
+ enum {M=0, N=1, O=2} pclass;
+ int crystals; /* has crystals */
+ enum {unknown, known, shuttle_down} known;
+} planet;
+
+#define DESTROY(pl) memset(pl, '\0', sizeof(planet))
+
+typedef struct {
+ int snap, // snapshot taken
+ remkl, // remaining klingons
+ remcom, // remaining commanders
+ rembase, // remaining bases
+ starkl, // destroyed stars
+ basekl, // destroyed bases
+ killk, // Klingons killed
+ killc, // commanders killed
+ galaxy[9][9], // The Galaxy (subscript 0 not used)
+ cx[11],cy[11], // Commander quadrant coordinates
+ baseqx[6], // Base quadrant X
+ baseqy[6], // Base quadrant Y
+ newstuf[9][9], // Extended galaxy goodies
+ isx, isy, // Coordinate of Super Commander
+ nscrem, // remaining super commanders
+ nromkl, // Romulans killed
+ nromrem, // Romulans remaining
+ nsckill, // super commanders killed
+ nplankl; // destroyed planets
+ planet plnets[PLNETMAX]; // Planet information
+ double date, // stardate
+ remres, // remaining resources
+ remtime; // remaining time
+} snapshot; // Data that is snapshot
+
+// Scalar variables that are needed for freezing the game
+// are placed in a structure. #defines are used to access by their
+// original names. Gee, I could have done this with the d structure,
+// but I just didn't think of it back when I started.
+
+#define SSTMAGIC "SST2.0\n"
+
+EXTERN struct {
+ char magic[sizeof(SSTMAGIC)];
+ snapshot state;
+ snapshot snapsht;
+ char quad[11][11]; // contents of our quadrant
+ double kpower[21]; // enemy energy levels
+ double kdist[21]; // enemy distances
+ double kavgd[21]; // average distances
+ double damage[NDEVICES+1]; // damage encountered
+ double future[NEVENTS+1]; // future events
+ char passwd[10]; // Self Destruct password
+ int kx[21]; // enemy sector locations
+ int ky[21];
+ int starch[9][9]; // star chart
+ /* members with macro definitions start here */
+ int inkling,
+ inbase,
+ incom,
+ instar,
+ intorps,
+ condit,
+ torps,
+ ship,
+ quadx,
+ quady,
+ sectx,
+ secty,
+ length,
+ skill,
+ basex,
+ basey,
+ klhere,
+ comhere,
+ casual,
+ nhelp,
+ nkinks,
+ ididit,
+ gamewon,
+ alive,
+ justin,
+ alldone,
+ shldchg,
+ thingx,
+ thingy,
+ plnetx,
+ plnety,
+ inorbit,
+ landed,
+ iplnet,
+ imine,
+ inplan,
+ nenhere,
+ ishere,
+ neutz,
+ irhere,
+ icraft,
+ ientesc,
+ iscraft,
+ isatb,
+ iscate,
+#ifdef DEBUG
+ idebug,
+#endif
+ iattak,
+ icrystl,
+ tourn,
+ thawed,
+ batx,
+ baty,
+ ithere,
+ iqhere,
+ iqengry,
+ ithx,
+ ithy,
+ iseenit,
+ probecx,
+ probecy,
+ proben,
+ isarmed,
+ nprobes;
+ double inresor,
+ intime,
+ inenrg,
+ inshld,
+ inlsr,
+ indate,
+ energy,
+ shield,
+ shldup,
+ warpfac,
+ wfacsq,
+ lsupres,
+ dist,
+ direc,
+ Time,
+ docfac,
+ resting,
+ damfac,
+ stdamtim,
+ cryprob,
+ probex,
+ probey,
+ probeinx,
+ probeiny;
+} game;
+
+#define inkling game.inkling // Initial number of klingons
+#define inbase game.inbase // Initial number of bases
+#define incom game.incom // Initian number of commanders
+#define instar game.instar // Initial stars
+#define intorps game.intorps // Initial/Max torpedoes
+#define condit game.condit // Condition (red, yellow, green docked)
+#define torps game.torps // number of torpedoes
+#define ship game.ship // Ship type -- 'E' is Enterprise
+#define quadx game.quadx // where we are
+#define quady game.quady //
+#define sectx game.sectx // where we are
+#define secty game.secty //
+#define length game.length // length of game
+#define skill game.skill // skill level
+#define basex game.basex // position of base in current quad
+#define basey game.basey //
+#define klhere game.klhere // klingons here
+#define comhere game.comhere // commanders here
+#define casual game.casual // causalties
+#define nhelp game.nhelp // calls for help
+#define nkinks game.nkinks //
+#define ididit game.ididit // Action taken -- allows enemy to attack
+#define gamewon game.gamewon // Finished!
+#define alive game.alive // We are alive (not killed)
+#define justin game.justin // just entered quadrant
+#define alldone game.alldone // game is now finished
+#define shldchg game.shldchg // shield is changing (affects efficiency)
+#define thingx game.thingx // location of strange object in galaxy
+#define thingy game.thingy //
+#define plnetx game.plnetx // location of planet in quadrant
+#define plnety game.plnety //
+#define inorbit game.inorbit // orbiting
+#define landed game.landed // party on planet (1), on ship (-1)
+#define iplnet game.iplnet // planet # in quadrant
+#define imine game.imine // mining
+#define inplan game.inplan // initial planets
+#define nenhere game.nenhere // Number of enemies in quadrant
+#define ishere game.ishere // Super-commander in quandrant
+#define neutz game.neutz // Romulan Neutral Zone
+#define irhere game.irhere // Romulans in quadrant
+#define iqhere game.iqhere // Thing in quadrant
+#define iqengry game.iqengry // Thing attacking
+#define icraft game.icraft // Kirk in Galileo
+#define ientesc game.ientesc // Attempted escape from supercommander
+#define iscraft game.iscraft // =1 if craft on ship, -1 if removed from game
+#define isatb game.isatb // =1 if SuperCommander is attacking base
+#define iscate game.iscate // Super Commander is here
+#ifdef DEBUG
+#define idebug game.idebug // Debug mode
+#endif
+#define iattak game.iattak // attack recursion elimination (was cracks[4])
+#define icrystl game.icrystl // dilithium crystals aboard
+#define tourn game.tourn // Tournament number
+#define thawed game.thawed // Thawed game
+#define batx game.batx // Base coordinates being attacked
+#define baty game.baty //
+#define ithere game.ithere // Tholean is here
+#define ithx game.ithx // coordinates of tholean
+#define ithy game.ithy
+#define iseenit game.iseenit // Seen base attack report
+#define inresor game.inresor // initial resources
+#define intime game.intime // initial time
+#define inenrg game.inenrg // Initial/Max Energy
+#define inshld game.inshld // Initial/Max Shield
+#define inlsr game.inlsr // initial life support resources
+#define indate game.indate // Initial date
+#define energy game.energy // Energy level
+#define shield game.shield // Shield level
+#define shldup game.shldup // Shields are up
+#define warpfac game.warpfac // Warp speed
+#define wfacsq game.wfacsq // squared warp factor
+#define lsupres game.lsupres // life support reserves
+#define dist game.dist // movement distance
+#define direc game.direc // movement direction
+#define Time game.Time // time taken by current operation
+#define docfac game.docfac // repair factor when docking (constant?)
+#define resting game.resting // rest time
+#define damfac game.damfac // damage factor
+#define stdamtim game.stdamtim // time that star chart was damaged
+#define cryprob game.cryprob // probability that crystal will work
+#define probex game.probex // location of probe
+#define probey game.probey
+#define probecx game.probecx // current probe quadrant
+#define probecy game.probecy
+#define probeinx game.probeinx // Probe x,y increment
+#define probeiny game.probeiny
+#define proben game.proben // number of moves for probe
+#define isarmed game.isarmed // Probe is armed
+#define nprobes game.nprobes // number of probes available
+
+/* the following global state doesn't need to be saved */
+EXTERN char *device[NDEVICES+1];
+EXTERN int iscore, iskill; // Common PLAQ
+EXTERN double perdate;
+EXTERN double aaitem;
+EXTERN char citem[10];
+
+typedef enum {FWON, FDEPLETE, FLIFESUP, FNRG, FBATTLE,
+ FNEG3, FNOVA, FSNOVAED, FABANDN, FDILITHIUM,
+ FMATERIALIZE, FPHASER, FLOST, FMINING, FDPLANET,
+ FPNOVA, FSSC, FSTRACTOR, FDRAY, FTRIBBLE,
+ FHOLE} FINTYPE ;
+enum loctype {neither, quadrant, sector};
+
+/* Define devices */
+#define DSRSENS 1
+#define DLRSENS 2
+#define DPHASER 3
+#define DPHOTON 4
+#define DLIFSUP 5
+#define DWARPEN 6
+#define DIMPULS 7
+#define DSHIELD 8
+#define DRADIO 9
+#define DSHUTTL 10
+#define DCOMPTR 11
+#define DTRANSP 12
+#define DSHCTRL 13
+#define DDRAY 14 // Added deathray
+#define DDSP 15 // Added deep space probe
+
+/* Define future events */
+#define FSPY 0 // Spy event happens always (no future[] entry)
+ // can cause SC to tractor beam Enterprise
+#define FSNOVA 1 // Supernova
+#define FTBEAM 2 // Commander tractor beams Enterprise
+#define FSNAP 3 // Snapshot for time warp
+#define FBATTAK 4 // Commander attacks base
+#define FCDBAS 5 // Commander destroys base
+#define FSCMOVE 6 // Supercommander moves (might attack base)
+#define FSCDBAS 7 // Supercommander destroys base
+#define FDSPROB 8 // Move deep space probe
+
+#ifdef INCLUDED
+char *device[NDEVICES+1] = {
+ "",
+ "S. R. Sensors",
+ "L. R. Sensors",
+ "Phasers",
+ "Photon Tubes",
+ "Life Support",
+ "Warp Engines",
+ "Impulse Engines",
+ "Shields",
+ "Subspace Radio",
+ "Shuttle Craft",
+ "Computer",
+ "Transporter",
+ "Shield Control",
+ "Death Ray",
+ "D. S. Probe"};
+#endif
+
+#ifndef TRUE
+#define TRUE (1)
+#define FALSE (0)
+#endif
+
+#define IHR 'R'
+#define IHK 'K'
+#define IHC 'C'
+#define IHS 'S'
+#define IHSTAR '*'
+#define IHP 'P'
+#define IHB 'B'
+#define IHBLANK ' '
+#define IHDOT '.'
+#define IHQUEST '?'
+#define IHE 'E'
+#define IHF 'F'
+#define IHT 'T'
+#define IHWEB '#'
+#define IHGREEN 'G'
+#define IHYELLOW 'Y'
+#define IHRED 'R'
+#define IHDOCKED 'D'
+#define IHDEAD 'Z'
+#define IHMATER0 '-'
+#define IHMATER1 'o'
+#define IHMATER2 '0'
+
+
+/* Function prototypes */
+void prelim(void);
+void attack(int);
+int choose(int);
+void setup(int);
+void score(void);
+void atover(int);
+void srscan(int);
+void lrscan(void);
+void phasers(void);
+void photon(void);
+void warp(int);
+void doshield(int);
+void dock(int);
+void dreprt(void);
+void chart(int);
+void impuls(void);
+void wait(void);
+void setwrp(void);
+void events(void);
+void report(int);
+void eta(void);
+void help(void);
+void abandn(void);
+void finish(FINTYPE);
+void dstrct(void);
+void kaboom(void);
+void freeze(int);
+int thaw(void);
+void plaque(void);
+int scan(void);
+#define IHEOL (0)
+#define IHALPHA (1)
+#define IHREAL (2)
+void chew(void);
+void chew2(void);
+void skip(int);
+void prout(char *, ...);
+void proutn(char *, ...);
+void stars(void);
+void newqad(int);
+int ja(void);
+void cramen(int);
+void crmshp(void);
+char *cramlc(enum loctype, int, int);
+double expran(double);
+double Rand(void);
+void iran8(int *, int *);
+void iran10(int *, int *);
+#define square(i) ((i)*(i))
+void dropin(int, int*, int*);
+void newcnd(void);
+void sortkl(void);
+void imove(void);
+void ram(int, int, int, int);
+void crmena(int, int, int, int, int);
+void deadkl(int, int, int, int, int);
+void timwrp(void);
+void movcom(void);
+void torpedo(double, double, int, int, double *, int);
+void huh(void);
+void pause_game(int);
+void nova(int, int);
+void snova(int, int);
+void scom(int *);
+void hittem(double *);
+void prouts(char *, ...);
+void proutc(char *);
+int isit(char *);
+void preport(void);
+void orbit(void);
+void sensor(void);
+#ifdef SERGEEV
+void drawmaps(short);
+#endif /* SERGEEV */
+void beam(void);
+void mine(void);
+void usecrystals(void);
+void shuttle(void);
+void deathray(void);
+void debugme(void);
+void attakreport(int);
+void movetho(void);
+void probe(void);
+void clearscreen(void);
+void iostart(int);
+void ioend(void);
+void getline(char *, int);
+void commandhook(char *, int);
+
+#ifdef SERGEEV
+typedef struct {
+ int wndleft,wndtop,wndright,wndbottom;
+} wnd;
+extern wnd wnds[6];
+#endif /* SERGEEV */